Commit Graph

382 Commits

Author SHA1 Message Date
Ali 7505f286bd chore(report): remove temporary source-document tracing
Drop the temporary Source type / Source document columns and the per-voucher
detail rows used for tracing; the report returns the single summary row again.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:13:45 +00:00
Ali 70cb6da547 fix(report): count sale price only for stock-moving agricultural sales
Sold in period (sale price) now sums Sales Invoice items only when the
sale produced an outgoing Stock Ledger entry, so it stays consistent with
COGS/closing. A sale that does not update stock contributes 0 instead of
inflating the sale figure with no matching cost.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:04:07 +00:00
Ali bd61196c84 feat(report): add temporary source-document rows to agricultural stock report
Append detail rows listing the Stock Ledger entries (with a clickable link
to each source voucher) and sale prices behind opening/purchased/COGS/
closing, for tracing. The summary stays the first row. Also decide stock
direction by stock_value_difference so opening-stock reconciliations
(actual_qty = 0) are counted correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:31:18 +00:00
Ali beec3f4416 fix(report): Purchase YGB VAT report only lists documents with YGB
Replace the purchase_type/agricultural_goods gate with a YGB-presence
filter: a Purchase Invoice is included only when at least one of its YGB
fields (ygb / line_code) is filled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:19:10 +00:00
Ali 2d743f2878 refactor(report): source agricultural stock report from Stock Ledger
Rebuild the report on Stock Ledger Entry instead of custom FIFO over
invoices. Opening/closing balances and COGS now come from ERPNext's stock
valuation (which already applies the company's method and includes opening
stock entered via Stock Reconciliation); sale price still comes from Sales
Invoices. Filtering is now item-level (Item.agricultural_goods) and all
amounts are net of VAT, so the trade-markup VAT is not double-counted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:43:09 +00:00
Ali f906536b7f fix(report): cost-based opening balance in agricultural stock report
Opening balance now subtracts sales before the period at their COGS
(via the company's FIFO/Moving Average method) instead of at sale price.
This keeps it consistent with the cost-based closing balance, so each
period's opening equals the previous period's closing and the value can
no longer go negative while stock remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:27:26 +00:00
Ali 18e55b7421 feat(report): add trade markup and its VAT to agricultural stock report
Closing balance is now cost-based (opening + purchased - COGS) so the
trade-markup identity holds. Adds two columns:
- Trade markup on goods sold = sold(sale) - (opening + purchased - closing)
- VAT on trade markup = trade markup * 18%

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 16:52:23 +00:00
Ali 72f8292bfe feat(report): add Purchase YGB VAT report
Per-document purchase report (Cədvəl 21 — ƏDV - YGB hesabat). A Purchase
Invoice qualifies when submitted and at least one of purchase_type /
agricultural_goods is set (items are not filtered). Columns: document,
date, line code, YGB, amount without VAT (net_total) and VAT amount.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:24:41 +00:00
Ali 97b8b4ed56 feat(report): item-level agricultural filter, FIFO/Average COGS column
Agricultural goods stock report now filters by the per-item agricultural
flag (only agro items inside agro documents count) and grosses up rows to
include VAT. Adds a single "Sold in period (purchase price)" column whose
costing method follows the company's Default Stock Valuation Method
(Moving Average -> weighted average, otherwise FIFO).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 14:45:00 +00:00
Ali 878d2bac83 feat(report): add Agricultural goods stock report
Period-based VAT agricultural goods movement report (Cədvəl 18(1)):
opening balance, purchased (Purchase Invoices), sold (Sales Invoices)
and closing balance for agricultural_goods documents. Amounts incl. VAT
(grand_total); closing = opening + purchased - sold. Formula-editor
friendly with Company/From/To filters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:52:28 +00:00
Ali cd34b4ca87 fix(report): filter Purchase invoice info report by agricultural_goods
Switch the inclusion condition from purchase_type=1 to the newly added
agricultural_goods=1 flag on Purchase Invoice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 10:41:37 +00:00
Ali 5d2a218087 feat(report): add Purchase invoice info report
New Script Report grouping purchase-type Purchase Invoices by Act Type,
showing counterparty (ФИО/company/country), VOEN/FIN, and amount.
Includes a link column to the source Purchase Invoice and optional
date-range filters; formula-editor friendly (no total row).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 09:47:04 +00:00
Ali aaa352098c push from mvp 2026-06-23 09:09:16 +00:00
Ali 19f82f7f8e refactor(company): drop dead E-Taxes profile/auth code from company.js
Remove the now-unreachable profile-fetch and Asan inline-auth machinery
(checkAuthAndFetchProfile, showProfileDialog, startInlineAuthentication,
poll/complete/select cert, profile parsing/formatting helpers and the
dictionary cache) left orphaned after the E-Taxes buttons were removed.
Keeps gambling-activity handling, declaration defaults and tax wizards.
1797 -> 313 lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 11:37:14 +00:00
Ali 1fff9d13a1 feat(company): remove E-Taxes profile and Set Main Activity buttons
Drop the "Get E-Taxes Profile" and "Set Main Activity" custom buttons
from the Company form. main_activity stays read-only (Custom Field
read_only=1) and can no longer be overridden via the dialog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 11:34:19 +00:00
Ali d370d74e32 feat(property-tax-gov): rework property_tax_gov client script; add RU architecture doc
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 17:52:03 +00:00
Ali 6d6ff50afe feat(vat-allocation-report): add Əlavə 3 tax articles to the report
Add the 45 new tax articles to VAT Allocation Tax Articles Report, following
the report's hardcoded mapping standard:
- 36 from "ƏDV tutulan dövriyyə barədə məlumat" (301.x)
- 9 from "ƏDV tutulan əməliyyat sayılmayan dövriyyə" (328–336)
extending both get_tax_articles_mapping() and get_field_to_label_mapping().

Resolve the 301.1 vs 301-1 key collision (both -> vm_301_1 under the
separator->underscore convention): dash codes stay vm_301_N (consistent with
existing 302/303), the CƏMİ total line 301.1 -> vm_301_1_cemi.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 17:39:51 +00:00
Ali 4c566a1a00 feat(tax-article): split legacy mixed-VAT group into two Əlavə 3 groups
Add the two Əlavə 3 declaration tables as prefixed Tax Article groups:
- "ƏDV tutulan dövriyyə barədə məlumat" (301.x, 36 articles)
- "ƏDV tutulan əməliyyat sayılmayan dövriyyə barədə məlumat" (328–336, 9)
mirroring the client scripts that populate Declaration of value added tax Əlavə 3.

Remove the legacy "ƏDV tutulan və tutulmayan əməliyyatlar" group (6 unused,
unprefixed articles) from the fixture, and add a post_model_sync patch to delete
it on other sites before fixtures import (fixture import never deletes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:44:38 +00:00
Ali 0187a86f5a push from ali 2026-06-08 11:18:28 +00:00
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