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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>