Commit Graph

413 Commits

Author SHA1 Message Date
Ali dda35f6f75 push from mvp 2026-06-08 10:36:43 +00:00
Ali af9d1322ab refactor(property-tax): replace property_tax_return_ai doctypes with property_tax_gov
Rename/retire the property_tax_return_ai doctype family in favour of the
property_tax_gov pilot (page-based, no-auth calc), and update property_tax_return.py
accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:15:30 +00:00
Ali 129a87711f feat(vat-allocation): group SI rows by customer+template with multi tax articles
Sales Invoice moved its single tax_article (Link) to a multi-select child table,
which inflated VAT Allocation: one line citing N articles produced N rows of the
full amount (e.g. 1500 -> 6000), so a 1500 payment only covered one article.

Group sales-invoice rows by (customer, item_tax_template) and union the cited
articles into a JSON tax_articles list, summing the amount once (the article
aggregation is computed separately so the JOIN can no longer multiply amounts).
The tax-articles report parses the list and replicates each row's amount/odenis
into every cited maddE column (same turnover under several articles, as on e-taxes).

The grid shows a translatable "N articles" cell that opens a read-only pill popup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:15:15 +00:00
Ali 7478d4d66c feat(reports): tax articles via SI child-table join; drop Tax Article Items Report
Revenue and VAT-allocation reports now resolve tax articles by JOINing the
Sales Invoice Tax Article child table (each article carries the full line
amount) instead of the single sii.tax_article; add 302.x/303.x mappings.
Remove the obsolete Tax Article Items Report doctype.

Also stop tracking .etaxes_notes/cabinet_internals.md (contains live
secrets) and broaden .gitignore to the whole .etaxes_notes/ folder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 12:25:24 +00:00
Ali 7f772fcb34 feat(property-tax-return-ai-fill): autofill elavə 1/2 + 507 from Asset accounting
Adds two parallel DocType families that don't touch the existing
`Property tax return` family:

- Property Tax Return AI (parent + 10 children): cabinet-verified port
  of the property-tax formulas (501/503/504 mirrors, 506=1, 509.1/509.2,
  511.x) with parity 3/3 vs. the original.

- Property Tax Return AI Fill (parent + 10 children): same formulas plus
  auto-fill from ERPNext Asset records. On form open the seeded grid is
  populated from the single Company's Assets, routed by
  `taxable_asset_type` (→ elavə 2 rows 1.1–1.6, 2–5) and
  `tax_exempt_tax_article` (→ elavə 1 rows by article-code regex).
  Residuals at year boundaries come from Depreciation Schedule;
  Company.date_of_establishment drives 507 ayla when il_erzinde=1.

Coverage: 16/16 smoke (seeding + formulas + 11 autofill scenarios) and
3/3 parity vs. original Property tax return pass.

Also adds .etaxes_notes/cabinet_internals.md (sanitised cabinet probe
notes) and gitignores .etaxes_notes/scratch/ which holds live JWTs and
HAR-like dumps.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 11:36:43 +00:00
Ali d90e56eb29 feat(tax-article): add 0% and VAT-exempt declaration articles (302.x/303.x)
Add 8 articles under "ƏDV-yə 0% dərəcə ilə tutulan əməliyyatlar" (302.x)
and 6 under "ƏDV-dən azad olunan əməliyyatlar" (303.x), sourced from the
Declaration of value added tax client scripts (Elave 4 / Elave 5).

Keep declaration-code prefixes in article_name to avoid docname collisions
between the 0% and exempt sections (e.g. 302.12 vs 303.42 share identical text).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 11:19:40 +00:00
Ali bdbe0b9dc1 push from mvp 2026-06-01 08:21:44 +00:00
Ali d11d15220c added new folder locale 2026-05-25 12:11:27 +00:00
Ali cd74b2ba85 feat(vat-allocation-report): split each tax article into amount + ödəniş columns
Per-article column now shows invoice amount; a paired Ödəniş column shows
allocated_amount from VAT allocation sales invoice. Row filter widened to
include unpaid lines (amount > 0 OR allocated_amount > 0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:39:24 +00:00
Ali ae162adc0c fix(tax-article): clean curly quotes at the source instead of every migrate
The tax_article.json fixture itself contained typographic curly quotes (“ ”),
so every migrate the fixture import wrote dirty data and the after_migrate
hook normalize_on_migrate() cleaned it back — a permanent ping-pong ("4 curly
quotes fixed" in every migrate log).

Fix the source: straighten the quotes in the fixture file once. The
normalize_on_migrate hook, the normalize_tax_articles.py module and its doc
are now redundant — removed. Existing databases need a one-time cleanup of
already-imported dirty rows (rename_doc on the affected names).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:35:29 +00:00
Ali b963422bca fix(master-data): drop file-hash fast-path so sync always reconciles DB
The hash fast-path compared the JSON file hash to a stored value and exited
early when unchanged. But it only tracked the *file*, not the *table*: if rows
went missing from the DB (manual delete, restore from an older dump) while the
JSON stayed the same, the sync skipped entirely and never restored them — so
`bench migrate` silently failed to recreate missing master-data rows.

Always run the full diff now. It costs one SELECT plus an in-memory compare —
measured at ~0.1s for 13k rows — so there's no reason to skip it. The diff is
driven by DB state, making the sync self-healing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 16:14:50 +00:00
Ali 34adb643ee perf(master-data): sync Item Groups via hash-diff instead of after_migrate loop
create_item_groups() ran a 26-record exists-check loop on every migrate
(the "Группа X уже существует, пропускаем" spam in migrate logs). Replace
with the master_data hash-diff sync: fast-paths via stored file hash, applies
only the delta otherwise.

Item Group is a tree doctype shared with ERPNext/user groups, so the sync
gains two options: is_tree=True (insert via db_insert, rebuild lft/rgt once
at the end) and manage_deletes=False (never delete rows absent from the JSON,
since the JSON is only the AZ tax-specific subset).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 15:30:03 +00:00
Ali 1f43e8e037 feat(master-data): make Main type of activity read-only
This doctype is now populated exclusively from master_data JSON via the
hash-diff sync, so block create/write/delete in the UI and API by dropping
those permissions. The sync writes at the DB level so it is unaffected.
Also marks option_name read_only and drops allow_rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:23:47 +00:00
Ali eb392640cd push from mvp 2026-05-20 10:05:43 +00:00
Ali 29a40a7dc6 push from mvp 2026-05-20 09:59:40 +00:00
Ali a5fbff78eb perf(master-data): remove zombie fixture file and add bulk-insert fast path
The previous commit moved Main type of activity data to master_data/ but left
the original fixture file in place — Frappe's sync_fixtures reads every .json
in app/fixtures/ regardless of the hooks.py fixtures list, so the file was
still being imported on every migrate (3499 DELETE+INSERTs). Delete it.

Also adds a bulk-insert fast path (db_insert chunks of 500) to sync_master_data
for the large first-run case on fresh sites, so the new sync is faster than
the legacy fixture import even when populating an empty table.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:48:42 +00:00
Ali 7e372f6f36 perf(master-data): sync Main type of activity via hash-diff instead of fixture
Fixture import does DELETE+INSERT for every row on every migrate (force=True
in frappe's import_doc), so 3499 rows of Main type of activity added minutes
to each migrate. Replace with a hash-diff sync that fast-paths via stored
file hash and otherwise applies only the delta (insert new, update changed,
smart-delete removed with disabled-fallback).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 12:44:06 +00:00
Ali 4a0c1519db push from mvp 2026-05-18 20:52:56 +00:00
Ali 0bdd885719 chore: use native Azərbaycan spelling in user-facing strings
Replaces "Azerbaijan" with "Azərbaycan" in app description, README, and
the descriptions of the Tax Period Closing Settings fields. Country
master Link values (e.g. country_of_origin: Azerbaijan in item fixtures)
are kept as-is to preserve references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 10:57:14 +00:00
Ali 8389e8502a fix(employee-payroll-register): base "cəlb edilən gəlirdən" columns on ƏH
Bookkeeper clarified the contribution net-of-exemption columns should be
computed from Əsas əmək haqqı minus the exemption amount, not from
gross_pay. With no exemption the column equals the existing (ƏH) column.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 16:48:39 +00:00
Ali 671b2195fe feat(employee-payroll-register): add per-contribution columns net of exemption
For each social contribution (DSMF, İcbari tibbi sığorta, İşsizlikdən
sığorta — işçi and şirkət, everything except Gəlir vergisi) add a column
per month that recomputes the amount on gross_pay minus that
contribution's "cəlb olunmayan gəlir" amount, using the Salary Component
formula. Sits next to the original column. 18 new columns total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:52:28 +00:00
Ali 4e8bb96669 chore(single-declaration): remove temporary tax debug logging
Bookkeeper review confirmed the gəlir vergisi numbers are correct;
drop the tax_debug payload and the browser-console breakdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 15:44:30 +00:00
Ali dacbd980dd chore(single-declaration): rewrite tax debug log as a single shareable block
Replaces the console.group/console.table layout with one structured
text block per request: shows source fields (gross_pay, custom_vergi_amount),
formula, per-slip breakdown with bracket explanation, and per-month sum
arithmetic. Easy to select-all and forward to the bookkeeper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:18:55 +00:00
Ali 27cbad46a8 chore(single-declaration): log gəlir vergisi breakdown to browser console
Server returns a tax_debug payload (per-slip, per (employee, month), and
monthly totals) and the client logs it via console.group + console.table
when payroll data is loaded. Temporary aid for the bookkeeper review —
will be removed once formulas are signed off.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 18:36:32 +00:00
Ali cecb6c255c fix(single-declaration): exclude income-tax-exempt amount before bracket
Apply gəlir vergisi brackets to (gross_pay − custom_vergi_amount), not raw
gross. Slips marked azadolma drop to 0 contribution, matching how the
formula editor fills the tax-base column. Affects bölmə 3 hissə 1 and
əlavə 1 hissə 1 vergi məbləği.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 18:16:12 +00:00
Ali caedd576b1 feat(single-declaration): fill vergi məbləği in əlavə 1 hissə 1
Per-employee quarterly income tax: brackets applied to each month's
gross pay, then summed for the quarter. Reuses the same per-month
gross helper as bölmə 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:14:37 +00:00
Ali 2e15e9dae4 feat(single-declaration): compute bölmə 3 income tax from payroll
Apply AZ progressive tax brackets (3%/10%/14%) per employee per month
on gross pay, then sum for monthly and quarterly tax amounts in
bölmə_3 hissə 1. Formula Editor stays responsible for the tax base
columns; this fills vergiməbləği* independently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:39:26 +00:00
Ali 3b54639022 push from mvp 2026-05-05 16:17:53 +00:00
Ali 72b256b17f push from mvp 2026-05-05 16:07:52 +00:00
Ali 4ba9ea385f feat(single-declaration): auto-fill elave4 deduction tables from payroll
Group salary slips by tax-free indicator over the quarter and populate
vergi_, mdss_, issizlik, its child tables on il/rüb change. Convert the
göstəricilər field in those four child doctypes from Select to a Link
to Tax Free Indicator so values match what payroll already stores.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 12:40:28 +00:00
Ali 02973690aa feat(employee-payroll-register): add ƏH and MK base deduction columns
Duplicates the 7 deduction columns twice per month: once with the formula
evaluated at base=ƏH amount (LE=0), and once at base=0/LE=MK amount with
the formula(0,0) baseline subtracted. The sum of (ƏH-part + MK-part) for
each row equals the slip's actual deduction — serves as a built-in sanity
check. Baseline subtraction keeps Gəlir vergisi correct across the
threshold (200 AZN) without special-casing it.

Formulas are read from Salary Component at runtime via _safe_eval — no
hardcoded rates, so the report stays correct when tax law changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 12:45:03 +00:00
Ali 24c8205193 push from mvp 2026-04-28 09:14:07 +00:00
Ali 16329bb5e5 refactor: drop auto-fill for bölmə 2 hissə 2 in single declaration
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 12:36:35 +00:00
Ali 46977b3427 feat: restore slip id, dates and tax-free indicators per month in payroll register
Bring back salary_slip_id, start_date, end_date and the four tax-free
Göstərici Link fields that were dropped in the numeric-only pass, each
split into per-month columns so the formula editor can pick a specific
month's value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:57:23 +00:00
Ali ec95dda8c2 fix: keep from_date/to_date as source of truth in payroll register
Add visible year/quarter selectors that sync hidden from_date/to_date
filters so the formula editor (which injects from_date via $AyIlSpecial)
keeps working without knowing about the quarter UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:22:23 +00:00
Ali f609d8064d feat: restructure employee payroll register for quarterly per-month breakdown
Replace from/to date filters with year + quarter selectors and aggregate
one row per employee with numeric columns split per month (ay_1_, ay_2_,
ay_3_) so the formula editor can pick a specific month instead of
dividing the quarter total by 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 10:13:41 +00:00
Ali 5c007ef408 fix: bind reload handler to rüb field in single declaration
Event and checks referenced a non-existent hesabatdövrü field, so
selecting year + quarter never triggered populate_declaration_tables.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 08:29:34 +00:00
Ali c42e7518b9 fix: set precision 2 on Float fields in single declaration bolme4 tables
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 10:46:14 +00:00
Ali 8c4ade656a push from mvp 2026-04-17 10:28:24 +00:00
Ali 4ddfec12db feat: add Tax Free indicator columns alongside amounts in payroll register
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 10:03:49 +00:00
Ali 95a1126139 feat: add Tax Free amount columns to employee payroll register
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:25:47 +00:00
Ali d8539ecdc1 feat: add Gəlir vergisi deduction to employee payroll register
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:33:58 +00:00
Ali 92d7ac6875 fix: bolme2_hisse2 last column is sum of 3 months, not average
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:21:11 +04:00
Ali 19d1a66b87 feat: add bolme2_hisse2 row 4 (məzuniyyət kompensasiyası) and auto-sum row 1
Row 4 sums Məzuniyyət Kompensasiyası per month from Salary Detail.
Row 1 Gəlirlər, cəmi now sums rows 2 + 4.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:44:20 +04:00
Ali 7b9cb7130a feat: add bolme2_hisse2 (monthly əmək haqqı), Monthly Present Report
- bolme2_hisse2 row 2: sum of Əsas əmək haqqı per month from Salary Detail
- bolme2_hisse2 row 1: auto-sum of rows 2-5
- hissə_1 gəlirlərcəmi: switched from gross_pay to Əsas əmək haqqı
- New Monthly Present Report (Present + Half Day attendance)
- bolme2_hisse1 row 2: unique employees with Present/Half Day per month

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:48:07 +04:00
Ali 6ed4c94213 feat: add Monthly Present Report and bolme2_hisse1 row 2 (actual headcount)
New report counts days present (Present + Half Day) per employee.
bolme2_hisse1 row 2 counts unique employees who showed up per month.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:29:36 +04:00
Ali 86b219a31e fix: round bolme2_hisse1 quarterly average to nearest integer
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:10:43 +04:00
Ali ed92176ce4 fix: guard accounting_method queries with has_column check
Prevents migration failure when jey_erp custom fields are not yet
synced (Unknown column 'accounting_method' error).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:10:04 +04:00
Ali 2b0426de0b feat: auto-populate bolme2_hisse1 row 1 (employee count per month)
Count employees per month using date_of_joining + relieving_date logic.
Safety net: status=Left without relieving_date excluded from count.
Updates existing pre-created rows by matching göstəricilər field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:50:19 +04:00
Ceyhun 6afb8ca3d3 add cash method 2026-04-02 15:41:26 +00:00