Commit Graph

59604 Commits

Author SHA1 Message Date
Nabin Hait
e5c0bd7931 Merge pull request #56516 from frappe/chore/test-product-bundle-balance
test: Product Bundle Balance report coverage
2026-07-01 19:25:40 +05:30
Nabin Hait
705f308ef7 Merge pull request #56514 from frappe/chore/test-total-stock-summary
test: Total Stock Summary report coverage
2026-07-01 19:25:30 +05:30
Nabin Hait
f8ce46f127 Merge pull request #56517 from frappe/chore/test-item-wise-consumption
test: Item-wise Consumption report coverage
2026-07-01 19:24:43 +05:30
Nabin Hait
f42198fb3c Merge pull request #56522 from frappe/chore/test-negative-batch-report
test: Negative Batch Report report coverage
2026-07-01 19:21:59 +05:30
Nabin Hait
7139639e77 Merge pull request #56525 from frappe/chore/test-stock-qty-vs-batch-qty
test: Stock Qty vs Batch Qty report coverage
2026-07-01 19:21:04 +05:30
Nabin Hait
f4ad1541bd Merge pull request #56529 from frappe/chore/test-warehouse-wise-item-balance-age-and-value
test: Warehouse Wise Item Balance Age and Value report coverage
2026-07-01 19:20:51 +05:30
Nabin Hait
49ecab6514 Merge pull request #56540 from frappe/chore/test-serial-no-and-batch-traceability
test: Serial No and Batch Traceability report coverage
2026-07-01 19:18:56 +05:30
Nabin Hait
3104369d79 Merge pull request #56542 from frappe/chore/test-cogs-by-item-group
test: COGS By Item Group report coverage
2026-07-01 19:18:42 +05:30
ruthra kumar
c482a3b699 Merge pull request #56706 from ruthra-kumar/rename_synced_to_snapshot
refactor: rename synced to snapshot report
2026-07-01 17:42:58 +05:30
Mihir Kandoi
bfe01476be Merge pull request #56708 from frappe/fix-redundant-cast
chore: remove redundant type cast
2026-07-01 17:35:18 +05:30
ruthra kumar
981e90e4da refactor: rename feature toggle in report master 2026-07-01 17:32:33 +05:30
Mihir Kandoi
9cf356f6f5 chore: remove redundant type case 2026-07-01 17:23:19 +05:30
Nikhil Kothari
bbc4d2ccab feat: capture user persona during setup (#56705) 2026-07-01 11:51:15 +00:00
Mihir Kandoi
f493417c3d Merge pull request #56702 from mihir-kandoi/fix/normalize-ctx-input-py314
fix: keep normalize_ctx_input's ctx annotation on Python 3.14
2026-07-01 17:18:54 +05:30
Mihir Kandoi
8271b29e42 style: apply ruff formatter
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 17:04:11 +05:30
Nabin Hait
9738228d9c Merge pull request #56526 from frappe/chore/test-stock-qty-vs-serial-no-count
test: Stock Qty vs Serial No Count report coverage
2026-07-01 16:46:30 +05:30
Mihir Kandoi
c00e5050cc Merge pull request #56703 from mihir-kandoi/fix/supplier-scorecard-recursion
fix: prevent max recursion on supplier scorecard save
2026-07-01 16:34:32 +05:30
Mihir Kandoi
e6f8f8f7e9 refactor: use frappe._dict in importers of ItemDetailsCtx
Extend the boundary rule to callers: non-decorated code that built or
annotated with ItemDetailsCtx now uses frappe._dict directly, and drops
the now-unused import. asset_capitalization keeps ItemDetailsCtx for its
own normalize_ctx_input-decorated functions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:30:16 +05:30
Mihir Kandoi
9406ec49de refactor: use frappe._dict directly in non-decorated helpers
ItemDetailsCtx signals the normalize_ctx_input boundary, so keep it only
on the decorator and the ctx param of decorated functions. Every other
annotation/constructor in non-decorated code becomes plain frappe._dict.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:27:42 +05:30
Mihir Kandoi
603404775b fix: reset in_rescore flag after re-save
Ensure the recursion guard only applies to the nested save() and is cleared
afterwards, so a later save() on the same doc instance still creates periods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:19:52 +05:30
Mihir Kandoi
f26cb793b1 fix: restore | dict + normalization on non-decorated helpers
get_item_price is an internal, non-decorated helper: the "| dict" and
"pctx = frappe._dict(pctx)" were load-bearing (callers may pass a plain
dict; the body does attribute access). Restore both. Also restore the
"| dict" on set_valuation_rate/update_party_blanket_order out params
(these are not normalize_ctx_input-decorated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:19:07 +05:30
Mihir Kandoi
31e2d4ac5a fix: prevent max recursion on supplier scorecard save
on_update() called self.save(), which re-enters on_update() via
run_post_save_methods(), recursing indefinitely when make_all_scorecards()
keeps returning newly created periods. Guard the re-save with an in_rescore
flag so the nested on_update() short-circuits, while still running the full
validate() once to refresh score and standings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:15:59 +05:30
Mihir Kandoi
6eeadbdbef fix: keep normalize_ctx_input's ctx annotation on Python 3.14
Python 3.14 (PEP 649/749) replaced "__annotations__" with "__annotate__"
in functools.WRAPPER_ASSIGNMENTS. normalize_ctx_input excluded only
"__annotations__" when wrapping, so functools.wraps copied the wrapped
function's __annotate__ and the wrapper's permissive ctx annotation
(_dict | Document | dict | str) was overwritten by the narrow
ItemDetailsCtx | str. Now that Frappe casts whitelisted args via
typing_validations, a dict ctx failed the isinstance-only frappe._dict
check and raised FrappeTypeError. Exclude "__annotate__" too.

Cleanup while here:
- Merge the three identical frappe._dict aliases (ItemDetails,
  ItemDetailsCtx, ItemPriceCtx) into ItemDetailsCtx.
- Drop the now-redundant "| str" from decorated signatures; the
  decorator's wrapper union is what typing_validations enforces.
- Decorate get_batch_based_item_price with normalize_ctx_input instead
  of a manual parse_json, renaming its arg pctx -> ctx (JS caller
  updated) so a dict/string payload is normalized to frappe._dict.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:07:45 +05:30
Nabin Hait
a2f8063804 Merge pull request #56543 from frappe/chore/test-landed-cost-report
test: Landed Cost Report report coverage
2026-07-01 15:54:32 +05:30
rohitwaghchaure
adae0bd732 feat: weekly auto-repost of incorrect stock valuation entries (#56637) 2026-07-01 15:47:46 +05:30
rohitwaghchaure
58e5755780 fix: manufacturing variance for standard cost valuation (#56684) 2026-07-01 14:04:14 +05:30
Mihir Kandoi
04cbb5da75 Merge pull request #56691 from mihir-kandoi/pg-ci-warmup-test-data
ci(postgres): warm up test data before baking the datadir
2026-07-01 13:55:38 +05:30
Nikhil Kothari
300471da12 fix(banking): handle blank password protected PDFs and negative amounts in CR/DR columns (#56690)
* fix(banking): strip signs from amount if column has CR/DR values

* fix(banking): try decrypting PDF with a blank password
2026-07-01 13:41:37 +05:30
Mihir Kandoi
3c067502f3 Merge pull request #56688 from mihir-kandoi/pg-greptile-over-rollback
ci(postgres): flag the over-broad-rollback trap in txn-abort review
2026-07-01 13:34:41 +05:30
Mihir Kandoi
63325cb976 ci(postgres): match MariaDB test job name (drop "(PG)")
Both server-test workflows now name the test job "Python Unit Tests" so the
check appears under the same name regardless of engine.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:32:53 +05:30
ruthra kumar
ba7b6a47c5 refactor: rename execute_synced_report to execute_snapshot_report
Match the framework rename of the standard report entry point in the
trial balance, P&L, balance sheet, and general ledger reports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 13:27:21 +05:30
Mihir Kandoi
e36e6bbb96 ci(postgres): warm up test data before baking the datadir
Mirror frappe/erpnext#56655 for the Postgres CI. Run the
bootstrap_test_data module in the setup job while Postgres is still up, so
the BootStrapTestData records are baked into the PGDATA artifact every shard
hydrates from — the shards start on already-warmed data instead of each
building it.

Unlike the MariaDB step, no `su -m` wrapper: the Postgres CI is
GitHub-hosted ubuntu-latest running as the runner user directly, matching
its own "Run Tests" step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:22:30 +05:30
Mihir Kandoi
b6382dce52 ci(postgres): add the return-contract note to the over-rollback bullet
Mirror the config.json guidance in POSTGRES_COMPATIBILITY.md: when scoping a rollback, keep the function's
success/None return contract -- don't return the doc that was just rolled back. (greptile #56688)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:21:18 +05:30
Nikhil Kothari
26583ae357 chore: update dependencies in banking app (#56685)
chore: update deps in banking app
2026-07-01 07:42:52 +00:00
Mihir Kandoi
06fb20d02d ci(greptile): flag over-broad full rollbacks in catch-and-continue handlers
Mirror the POSTGRES_COMPATIBILITY.md rule into the greptile instructions: prefer a scoped savepoint over a
full frappe.db.rollback() when recovering a poisoned txn; 'owns the txn' is not safe in a loop handler; and
keep the success/None return contract when scoping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:05:57 +05:30
Mihir Kandoi
c976b86714 ci(postgres): teach the parity guide the over-broad-rollback trap
Recovering a poisoned Postgres txn with a full frappe.db.rollback() discards rows the handler already
created before the failure -- which MariaDB keeps (no statement-abort) -- so it's a silent MariaDB
regression. 'Owns the txn' does not make a full rollback safe in a loop handler. Document the safe cases
(re-raise / single op / atomic batch) and the per-iteration/per-record savepoint alternative.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:05:56 +05:30
Mihir Kandoi
a98474cab0 Merge pull request #56686 from mihir-kandoi/pg-d3-serial-no-fixture-case
test(stock): fix Available Serial No fixture item-code case for Postgres
2026-07-01 13:04:01 +05:30
Mihir Kandoi
9f229d614e test(stock): fix Available Serial No fixture item-code case for Postgres
setUp creates/receives/delivers the item as '_Test Item with Serial No' (lowercase w) but the report
filter used '_Test Item With Serial No' (capital W). MariaDB's case-insensitive collation resolved it,
but Postgres (case-sensitive) matched no item, so the report's 'if items:' guard dropped the item
filter and returned serial-no rows for every item in the window -- an order-dependent, flaky count on
Postgres. Align the filter to the created item's case (a no-op on MariaDB).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:51:54 +05:30
Mihir Kandoi
cb1642c7f6 Merge pull request #56683 from mihir-kandoi/pg-c1-txn-abort-followup
fix: scope three more Postgres txn-abort savepoints (fiscal year, Plaid sync, CRM customer)
2026-07-01 12:44:19 +05:30
Mihir Kandoi
59b49120b7 fix(crm): keep returning None from create_customer on a linking failure
Preserve the pre-existing contract: create_customer returned None when contact/address linking failed.
The savepoint fix kept the Customer (good) but started returning its name in that case, so a CRM caller
treating a non-None return as full success could skip its retry/error handling. Return None on a linking
failure while still keeping the Customer. (greptile #56683)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:28:36 +05:30
Mihir Kandoi
76b31d9269 fix(crm): scope create_customer rollback so a contact/address failure keeps the Customer
create_customer wrapped customer.insert() + create_contacts() + create_address() in one try whose except
did a full frappe.db.rollback(), so a failure while linking contacts/address discarded the Customer just
created (MariaDB kept it pre-migration). Split the try: the customer insert keeps its full rollback (safe
-- nothing precedes it), and contact/address linking runs under a savepoint so its failure rolls back only
the links, preserving the Customer and healing the Postgres txn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 11:55:42 +05:30
Mihir Kandoi
c58a4026a7 fix(integrations): per-transaction savepoint in Plaid sync_transactions
new_bank_transaction inserts+submits Bank Transactions in a loop within one transaction. On a failed
insert/submit, Postgres poisons the transaction so the except's log_error dies with InFailedSqlTransaction;
MariaDB keeps the Bank Transactions synced before the failure. A full rollback would discard those on
MariaDB too, so wrap each iteration in a savepoint + rollback(save_point=) and re-raise -- preserves
MariaDB's partial-sync behaviour and heals the Postgres txn. The sibling handlers add_institution /
add_bank_accounts were already fixed; this closes the third.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 11:55:41 +05:30
Mihir Kandoi
b926b846b1 fix(accounts): savepoint auto_create_fiscal_year loop to survive a duplicate year on Postgres
The daily scheduler loops creating next-year Fiscal Years (autoname=field:year). A duplicate-year
INSERT aborts the statement; on Postgres that poisons the whole transaction, so the next iteration's
get_doc/insert dies with InFailedSqlTransaction. MariaDB statement-rolls-back and continues. Wrap each
iteration in a savepoint + rollback(save_point=) in the DuplicateEntryError branch -- a strict no-op on
MariaDB (same INSERT, same skip), recovers the txn on Postgres.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 11:55:40 +05:30
Mihir Kandoi
36e0b71602 Merge pull request #56681 from mihir-kandoi/pg-b4-orderby-tiebreakers
fix: add unique tiebreakers to ORDER BY … LIMIT 1 picks for MariaDB↔Postgres parity
2026-07-01 09:30:17 +05:30
Mihir Kandoi
8f3eb6cb31 fix(selling): tie-break POS customer contact pick for cross-engine parity
The contact lookup orders only by is_primary_contact desc then takes contacts[0]; contacts commonly
tie (the no-primary case), so MariaDB and Postgres could pick a different contact. Add a parent
(contact name) tiebreaker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:10:19 +05:30
Mihir Kandoi
7a798dcba9 fix(stock): tie-break pick-list lookup in update_packed_item_with_pick_list_info
The Pick List Item get_value orders only by qty desc; a pick list can hold multiple rows for the same
SO item split across warehouses/batches/serials that tie on qty, so MariaDB and Postgres could stamp a
different warehouse/batch/serial onto the packed item. Add a name tiebreaker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:10:18 +05:30
Mihir Kandoi
813dcca29a fix(accounts): tie-break open Payment Request ordering for cross-engine parity
get_open_payment_requests_for_references orders by Coalesce(transaction_date, creation); when
transaction_date is set the coalesce never falls back to creation, so PRs sharing a transaction_date
have no tiebreaker and MariaDB/Postgres can allocate a different PR first. Append creation, name keys.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:10:18 +05:30
Mihir Kandoi
7f6a234cf7 fix(stock): pin get_item_price tie-break so MariaDB and Postgres agree
get_item_price ORDER BYs valid_from/batch_no/uom/party then LIMIT 1 with no unique key. Two Item
Price rows tied on all of those but differing price_list_rate would be picked arbitrarily -- MariaDB
and Postgres can return a different rate. Append a name tiebreaker; for exact ties MariaDB's pick was
already undefined, so its output is preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:10:16 +05:30
Diptanil Saha
85853fce12 Merge pull request #56678 from diptanilsaha/fix/gross_profit_debit_note
fix(gross_profit): correct GP calculation for rate adjustment debit notes
2026-07-01 08:32:05 +05:30
diptanilsaha
17ef5d6034 test(gross_profit): added test cases for rate adjustment entry 2026-07-01 08:17:42 +05:30