Commit Graph

59564 Commits

Author SHA1 Message Date
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
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
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
diptanilsaha
b9f330a158 fix: gross profit calculation with rate adjustment entries 2026-07-01 08:02:45 +05:30
Shllokkk
35de9deb0a fix: use live source warehouse valuation for internal transfer purchase receipts (#56431)
fix: anchor incoming SLE rate to DN rate for intra-company PR transfers
2026-07-01 06:54:26 +05:30
Mihir Kandoi
94a0c102a3 Merge pull request #56446 from aerele/fix/support-#72225
fix: support quality inspection for stock entry by purpose
2026-06-30 22:37:26 +05:30
Sudharsanan11
847fd8aa33 fix(stock): exclude consumption from outgoing quality inspection
The QI-by-purpose check required an inspection on every outgoing
(s_warehouse) row for any purpose that was not incoming. Material
Consumption for Manufacture rows are source-only and the Work Order
mapper copies inspection_required from the BOM, so this silently
blocked submission. An inspection_required BOM inspects the finished
good, not each consumed raw material.

Replace the "anything not incoming" fallthrough with an explicit
QI_OUTGOING_PURPOSES allow-list (mirrored in transaction.js) so a new
purpose cannot silently start requiring a QI. Consumption and Return
Raw Material to Customer now need no QI; Issue, Transfer, Transfer for
Manufacture, Send to Subcontractor, Subcontracting Delivery and
Disassemble keep their outgoing checks. Scope item_query to the same
set and add a regression test.
2026-06-30 21:32:30 +05:30
Mihir Kandoi
5afabb089d Merge pull request #56665 from mihir-kandoi/pg-greptile-audit-learnings
ci(greptile): DISTINCT row-count trap + refactor/conversion row-set faithfulness
2026-06-30 21:08:43 +05:30
Shllokkk
6425b9afaf Merge pull request #56661 from Shllokkk/fix-bulk-transaction-method
fix: handle None args in transaction_processing
2026-06-30 21:02:05 +05:30
Mihir Kandoi
f560767eb0 ci(postgres): include §6 in the How-to-review closing summary
The closing paragraph named only the §2/§3 semantic divergences as static-checker-invisible;
§6 (refactor/conversion row-set changes) is equally invisible and belongs there too. (greptile nit.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:58:52 +05:30
Mihir Kandoi
e79c24791f ci(greptile): flag the DISTINCT row-count trap and refactor-smuggled row-set changes
Mirror the two new POSTGRES_COMPATIBILITY.md rules into the greptile instructions so the bot flags
them on changed queries: (1) adding an ORDER BY column to a SELECT DISTINCT grows the distinct key
and the MariaDB row count unless it is functionally dependent; (2) a refactor / raw-frappe.db.sql->qb
conversion can silently change the WHERE/row set on both engines -- review the predicate, not just
the query shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:41:35 +05:30
Mihir Kandoi
a26329b2a0 ci(postgres): teach the parity guide the DISTINCT row-count trap + refactor faithfulness
Two review lessons from the post-merge net-diff/whole-repo re-audit of the SQL-dialect classes:

- Section 3 (row-count trap) now covers SELECT DISTINCT too: adding the ORDER BY column to the
  select to satisfy Postgres grows the DISTINCT key and changes the MariaDB row count when the
  column is not single-valued per distinct row -- sort in Python instead.
- New section 6: a 'refactor' / raw-SQL->qb conversion is not automatically 1:1. Diff the
  WHERE/predicate and the resulting row set, not just the SELECT shape -- a conversion that widens
  a filter (e.g. posting_datetime > X gaining an OR (== X AND creation > ...) branch under a
  sql->qb refactor) changes the rows touched on both engines and hides under a refactor label.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:41:34 +05:30
Mihir Kandoi
78a64cd79b Merge pull request #56662 from mihir-kandoi/st72149
fix: use correct variable to fetch valuation method
2026-06-30 20:33:48 +05:30
Mihir Kandoi
1492c9fbc3 fix: use correct variable to fetch valuation method 2026-06-30 20:23:14 +05:30
Diptanil Saha
5b3e6e4714 Revert "chore: remove unused whitelisted method from project" (#56660) 2026-06-30 20:12:03 +05:30
Shllokkk
0db4af22e0 fix: handle None args in transaction_processing 2026-06-30 20:11:28 +05:30
Venkatesh
3b0e1fbb79 fix: remove translation for filter (#56629)
Co-authored-by: SowmyaArunachalam <sowmyaarunachalam57@gmail.com>
2026-06-30 14:52:11 +02:00
Mihir Kandoi
1c92dac274 Merge pull request #56450 from aerele/fix/support-#70387
fix(selling): update sales order per billed on credit note submission
2026-06-30 17:54:09 +05:30
ruthra kumar
d389a03c15 Merge pull request #56655 from ruthra-kumar/bootstrap_test_data_in_warmed_db
ci: warmup test data along with DB
2026-06-30 17:44:45 +05:30
ruthra kumar
dcdbf9df17 ci: warmup test data along with DB 2026-06-30 17:30:36 +05:30
rohitwaghchaure
b8be1c8efd refactor: frappe.db.sql to frappe.qb for update_qty_in_future_sle (#56609) 2026-06-30 15:40:10 +05:30
Nikhil Kothari
8447f551e7 fix(banking): use custom renderer for translated strings and parser for rules (#56643)
fix(banking): use custom renderer for translated strings and parser for formula evaluation
2026-06-30 09:21:42 +00:00
Sudharsanan Ashok
6184c057db fix(stock): value batch/serial return from ledger when original receipt has no bundle (#56631)
* fix(stock): value batch/serial return from ledger when original receipt has no bundle

* test(stock): add test to validate the valuation of serial/batch for return when original receipt has no bundle
2026-06-30 14:28:04 +05:30
Mihir Kandoi
3d7bcd1f6a Merge pull request #56630 from mihir-kandoi/pg-convergence-fixes
fix: Postgres transaction-abort savepoints + div0/tiebreaker convergence fixes
2026-06-30 13:40:07 +05:30
Sudharsanan11
710d0667fa test(selling): add test to validate the per billed after credit note submission 2026-06-30 13:03:07 +05:30
Mihir Kandoi
460bb9e5d0 fix(crm): scope create_address rollback to a savepoint (review)
create_address is a helper called by create_prospect/create_customer AFTER they insert the Prospect/Customer. Its full frappe.db.rollback() on an address-save failure rolled back the caller's just-inserted parent doc, then swallowed the exception, so the caller returned a Prospect/Customer name that no longer existed. Scope the rollback to savepoint('crm_create_address') so only the address work is undone; the parent doc survives and the failed address is just logged.
2026-06-30 13:01:32 +05:30