Commit Graph

59358 Commits

Author SHA1 Message Date
Mihir Kandoi
295dec24db fix(stock): group get_picked_batches by batch and warehouse
get_picked_batches summed Serial-and-Batch-Entry qty while selecting bare
batch_no and warehouse with no GROUP BY. PostgreSQL rejects this outright:

    column "tabSerial and Batch Entry.batch_no" must appear in the GROUP BY clause

MariaDB does not error but collapses every picked row into a single result -
the grand-total qty pinned to one arbitrary batch - so the caller, which keys
the result by (batch_no, warehouse) to subtract already-picked stock, under-counts
whenever more than one batch is picked.

Add GROUP BY batch_no, warehouse so the query returns one correct row per batch
on both engines (this corrects the MariaDB result, not just Postgres validity).
2026-06-23 08:58:29 +05:30
Mihir Kandoi
edf1341f42 Merge pull request #56340 from mihir-kandoi/pg-mr-supplier-distinct-orderby
fix(stock): keep supplier-based Material Request picker valid on Postgres
2026-06-23 07:59:47 +05:30
Mihir Kandoi
90ef4f4776 fix(stock): keep supplier-based Material Request picker valid on Postgres
get_material_requests_based_on_supplier deduplicated requests with
SELECT DISTINCT (name, transaction_date, company) while ordering by
mr_item.item_code, which is not in the select list. MariaDB allows this;
PostgreSQL rejects it:

    psycopg2.errors.InvalidColumnReference: for SELECT DISTINCT,
    ORDER BY expressions must appear in select list

so the picker errored out there.

Group by the three selected columns (equivalent to the DISTINCT, so the
same set of requests is returned) and order by Min(item_code). The order
key stays item_code but is now a well-defined aggregate, making the query
valid - and the ordering deterministic and identical - on both engines.
2026-06-23 07:41:39 +05:30
Shllokkk
3251b40365 fix: show contextual balance label on party dashboard for net balances 2026-06-23 01:44:42 +05:30
Mihir Kandoi
ff737df55f Merge pull request #56336 from mihir-kandoi/pg-lint-distinct-orderby
ci(postgres): flag get_all(distinct=True, order_by=...) in the static checker
2026-06-22 23:42:11 +05:30
Mihir Kandoi
50c4ee4ccb Merge pull request #56334 from mihir-kandoi/pg-irs1099-payer-tiebreak
fix(regional): deterministic IRS-1099 payer-address pick across engines
2026-06-22 23:32:53 +05:30
Mihir Kandoi
ad237e5ec5 ci(postgres): flag get_all(distinct=True, order_by=...) in the static checker
frappe's db_query SILENTLY drops ORDER BY for distinct queries on Postgres (the ORDER BY
column must appear in the SELECT-DISTINCT list), so `get_all/get_list(distinct=True,
order_by="<col>")` is a no-op there and the result comes back unordered — the root cause of
the Sales Register, Purchase Register and Sales Analytics ordering fixes. Add an AST rule to
.github/helper/postgres_compat.py that flags this (literal order_by only; an empty order_by=""
suppression and a dynamic/variable order_by are not flagged). `# pg-ok` escape hatch as usual.

Grandfather the three pre-existing low-impact sites the rule surfaces (paging/iteration order
only, not data): job_card operation autocomplete, inventory_dimension config list, and a
work_order test loop.
2026-06-22 23:22:52 +05:30
Mihir Kandoi
fadad2d1c4 fix(regional): deterministic IRS-1099 payer-address pick across engines
get_payer_address_html picks one company address with ORDER BY (Postal DESC, Billing DESC)
LIMIT 1 and no column tie-break. When a company has two addresses of the same address_type
the two CASE keys tie, so the LIMIT-1 row is implementation-defined and MariaDB and PostgreSQL
can return a different address.name — i.e. a different payer address on the rendered IRS-1099
form for identical data.

Add a final .orderby(address.name), mirroring the sibling get_street_address_html in the same
file (which already carries the "deterministic LIMIT-1 tie-break across engines" order). The
pick is now the lexicographically-smallest name on both engines.
2026-06-22 23:13:29 +05:30
Mihir Kandoi
f026d1dac8 Merge pull request #56329 from mihir-kandoi/pg-sales-analytics-order
fix(selling): deterministic Sales Analytics order-type row order on both engines
2026-06-22 20:02:27 +05:30
Mihir Kandoi
a1ed913eba fix(selling): deterministic order-type row order in Sales Analytics on both engines
get_teams fetched distinct order_types with get_all(distinct=True, order_by="order_type").
frappe drops ORDER BY for distinct queries on postgres (db_query), so the order_by is a
no-op there and the report's order-type leaf rows are not guaranteed any order on PG
(PostgreSQL only sorts them incidentally via its DISTINCT plan). Sort in python with
key=str.casefold instead, matching MariaDB's case-insensitive collation and guaranteeing
an identical, stable order on both engines (same pattern as the Sales/Purchase Register
account-column fix). Add a test locking the sorted order-type row order.
2026-06-22 19:42:37 +05:30
Mihir Kandoi
3ed305c75c Merge pull request #56330 from mihir-kandoi/pg-queries-locate-case
fix(controllers): case-insensitive employee/lead/bom search ranking on Postgres
2026-06-22 19:30:02 +05:30
Mihir Kandoi
da4cf77d97 Merge pull request #56328 from mihir-kandoi/pg-pos-item-group-escape
fix(pos): restore item-group filtering broken by double-escaped names
2026-06-22 19:23:58 +05:30
Raffael Meyer
13f9130d42 fix: hide redundant company currency fields on transactions (#54691) 2026-06-22 15:37:29 +02:00
Mihir Kandoi
98e8d5690e fix(controllers): case-insensitive search ranking in employee/lead/bom queries on Postgres
employee_query, lead_query and bom() ranked autocomplete results with a bare
Locate(txt, col) in ORDER BY. frappe maps Locate -> strpos on Postgres, which is
case-sensitive, while MariaDB's LOCATE against a column uses the column's
case-insensitive collation. So the search-dropdown ordering diverged between engines for
mixed-case matches (row count/membership unchanged — the WHERE .like() is already ILIKE).

Wrap both Locate operands in Lower(), matching the sibling item_query/get_project_name
handlers in the same file: a no-op on MariaDB, and case-insensitive (MariaDB-faithful) on
Postgres. The existing test_queries suite stays green on both engines.
2026-06-22 19:01:18 +05:30
Mihir Kandoi
32216bd75b fix(pos): return raw Item Group names from get_item_groups (double-escape regression)
The Postgres-portability change moved the POS item-group filters to the query builder
(item.item_group.isin(...)) and frappe.get_all(["name","in",...]), which escape values
once. get_item_groups() still pre-escaped each name with frappe.db.escape(), so the
names were escaped TWICE -> `item_group IN ('''Products''')`, matching nothing. Any POS
Profile that restricts item groups returned ZERO items, on both MariaDB and Postgres.

Return raw names; the parameterized callers escape them correctly. (get_parent_item_group
also returned the quoted literal before this fix.) Add a regression test: a POS Profile
restricted to an item group must still surface that group's items — it returns 0 before
the fix and passes after, on both engines.
2026-06-22 19:00:35 +05:30
Nabin Hait
0602a22e4b test(project): cover costing and billing roll-ups
Covers the sales/billing roll-up (total_sales_amount, total_billed_amount,
gross margin) via the whitelisted update_costing_and_billing, and
consumed-material cost from a project-linked Stock Entry issue. The
purchase-cost roll-up is already covered by the Purchase Invoice tests.
2026-06-22 18:38:51 +05:30
Nabin Hait
b90a364c31 test: add Cash Flow report correctness coverage
The Cash Flow report only had a smoke test. Add correctness tests for the
indirect method: a cash sale increases net change in cash by its amount,
and a cash purchase of a fixed asset is an investing outflow that reduces
it. Both measure the delta around a single transaction so they are
independent of existing company data.
2026-06-22 18:35:35 +05:30
Nabin Hait
b82461bf0f test: add General Ledger report filter coverage
The General Ledger report's everyday filters were untested (existing tests
only covered exchange-rate revaluation and the ignore-journals/cr-dr-notes
filters). Add coverage for opening/total/closing balance rows, group/
categorize by account subtotals, and the party filter.
2026-06-22 18:30:37 +05:30
Nabin Hait
b2bae839ac test(activity-cost): cover default-cost title and duplication
Covers the no-employee path (title set to the activity type and the
default-cost duplication guard) and employee_name being fetched for the
title. Brings activity_cost.py to full coverage.
2026-06-22 18:27:00 +05:30
Nabin Hait
6ef8b41c3c test(project-template): cover dependency-task validation
A template task that depends on another task requires that dependency to
also be present in the template's task list; covers both the rejection
and the valid case.
2026-06-22 18:25:17 +05:30
Nabin Hait
674157767a test: cover Trial Balance report filters and closing-balance setting
Extend Trial Balance coverage across its filters: show zero values, show
group accounts, show net values, period closing entry for current period,
show unclosed FY P&L balances, include default finance book entries, and
the ignore_account_closing_balance setting (cached Account Closing Balance
vs recomputed-from-GL opening).
2026-06-22 18:23:29 +05:30
Nabin Hait
d694ad9428 Merge pull request #56293 from nabinhait/fix-lead-name-none-email
fix(lead): don't crash deriving lead name when only ignore_mandatory is set
2026-06-22 18:17:16 +05:30
Nabin Hait
bab97aaad0 test(timesheet): cover activity cost and billing-rate helpers
Covers get_activity_cost falling back to the Activity Type rates (and the
empty result for an unknown type), plus get_timesheet_data and
get_timesheet_detail_rate for a billable timesheet detail.
2026-06-22 18:14:40 +05:30
Nabin Hait
14b83b46ac test(task): cover bulk actions, template deps, and delete guards
Covers the whitelisted set_multiple_status and add_multiple_tasks helpers
(including the blank-subject skip), the template-task dependency
validation, the on_trash child-exists guard, and a child task
registering itself in its parent's depends_on.
2026-06-22 18:14:38 +05:30
Nabin Hait
ecfc8cc400 test: add correctness coverage for Trial Balance report
The report previously had a single dimension-filter test. Add tests using
fresh accounts: a posted journal entry lands in the period debit/credit
columns with the grand total balanced, and an entry before the from-date
rolls into the opening-balance columns.
2026-06-22 18:06:21 +05:30
Nabin Hait
eee1fdf276 fix: reset grant_commission to default 1 after tests
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-22 18:05:20 +05:30
Nabin Hait
53f0049e75 test(project): cover create_duplicate_project and set_project_status
Both are whitelisted, UI-triggered functions that had no server tests.
Covers duplicating a project with its tasks (and the same-name guard),
and bulk-setting a project plus its tasks to a terminal status (and the
invalid-status guard).
2026-06-22 18:04:53 +05:30
Nabin Hait
e59b772c36 test: add coverage for Stock Projected Qty report
The Stock Projected Qty report had no test file. Add tests for projected
qty rolling up actual + ordered, shortage qty derived from the warehouse
reorder level, and item filtering.
2026-06-22 18:00:36 +05:30
Nabin Hait
76b0123778 test(project): cover update_percent_complete for all methods
Adds assertions for the four percent_complete_method paths (Manual is
already covered), plus the status transitions: 100% flips a project to
Completed, reopening a task flips it back to Open, and a Cancelled
project keeps its status. The method was previously unasserted.
2026-06-22 17:38:23 +05:30
Nabin Hait
8955a1edb4 test: add correctness coverage for Stock Ledger report
The Stock Ledger report had a test stub with no assertions. Add tests for
in/out quantity split and running balance, opening-balance roll-up from
movements before the period, and item filtering, sharing a small
make_movements/run_report helper.
2026-06-22 17:34:31 +05:30
Nabin Hait
a120bf8363 Merge pull request #56286 from nabinhait/ci-patch-test-no-workers-during-migrate
ci: don't run background workers during patch-test migrate
2026-06-22 17:05:15 +05:30
Nabin Hait
d48cffd1a5 Merge pull request #56303 from nabinhait/test-blanket-order-multirow
test(blanket_order): cover over-ordering aggregated across rows
2026-06-22 17:04:35 +05:30
Nabin Hait
92047e896c fix(selling): carry commission_rate through Make Delivery Note / Sales Invoice
commission_rate is no_copy so it is not carried on Duplicate/amend, but the
mapper also skips no_copy fields, leaving the mapped Delivery Note / Sales
Invoice showing 0 commission until saved (it only re-fetched from the sales
partner on save). Map commission_rate explicitly in the SO->DN, SO->SI and
DN->SI mappers so it carries over immediately; Duplicate still does not copy
it.
2026-06-22 17:01:40 +05:30
Mihir Kandoi
624844d52f Merge pull request #56308 from mihir-kandoi/gh55802
fix: submittable product bundle issues
2026-06-22 16:15:59 +05:30
Nishka Gosalia
c24fc063fc Merge pull request #56309 from nishkagosalia/migrating-document-naming-setting
fix: Removing the document naming series dialog and moving to framework
2026-06-22 16:07:08 +05:30
Nabin Hait
43d2c7335d refactor(lead): name the loops in remove_link_from_prospect
The outer and inner loops both used 'd'; name them linked_prospect and lead
so the prospect/lead iteration reads clearly. No behaviour change.
2026-06-22 15:59:26 +05:30
Nabin Hait
8f69697212 fix(lead): don't crash deriving lead name when only ignore_mandatory is set
set_lead_name fell through to email_id.split('@') when a lead had no name,
company or email but ignore_mandatory was set (e.g. data import), raising
AttributeError on a None email. Only derive from email when one exists; the
lead name is then left blank, as intended for that path.
2026-06-22 15:59:25 +05:30
Nabin Hait
3f832d4ee0 Merge pull request #56247 from nabinhait/commission-rate-data-to-percent
fix(selling): make commission_rate a Percent field on Sales Person and Sales Team
2026-06-22 15:56:30 +05:30
Mihir Kandoi
d48a1e0d16 fix: address product bundle review comments 2026-06-22 15:53:52 +05:30
nishkagosalia
aa7402b1e3 fix: removing the document naming series dialog and moving to framework 2026-06-22 15:46:15 +05:30
Mihir Kandoi
a218b8db8c fix: submittable product bundle issues 2026-06-22 15:40:16 +05:30
rohitwaghchaure
9b8c363bed feat: capitalize full actual charge on stock items only for Purchase Invoice (#56223)
* feat: capitalize full actual charge on stock items only for Purchase Invoice

Extends #56102 (Purchase Receipt) to the Purchase Invoice GL: an actual
valuation charge (e.g. Freight) flagged 'Allocate Full Amount to Stock Items'
is fully capitalized onto stock/asset items only; when unchecked, only the
stock items' share of a spread-across-all-items charge is capitalized.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: aggregate GL rows per account in PI freight test

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 15:39:10 +05:30
Mihir Kandoi
23bbcca97e Merge pull request #56306 from frappe/codex/fix-address-portal-row
fix: link portal address rows to web form
2026-06-22 15:29:20 +05:30
Mihir Kandoi
5008b82f90 fix: link portal address rows to web form 2026-06-22 15:19:40 +05:30
Nabin Hait
9436ab7f19 Merge pull request #56294 from frappe/chore/subcontracting-test-coverage
test: Subcontracting coverage; fix service-cost mismatch by PO item
2026-06-22 15:08:34 +05:30
Nabin Hait
c38bab7e5e Merge pull request #56302 from nabinhait/test-coupon-code-validation
test(coupon_code): cover coupon validation and usage-count edges
2026-06-22 15:07:10 +05:30
Mihir Kandoi
eafb0019bf Merge pull request #56300 from mihir-kandoi/fix-party-specific-item
fix: party specific item doesnt work if there are 2 suppliers with sa…
2026-06-22 14:57:09 +05:30
Nabin Hait
2d54f651cd fix: restore apply_permission value after running test
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-22 14:32:28 +05:30
Nabin Hait
d0184e07b3 fix(selling): hide commission fields without a sales partner and stop copying them
Across Sales Order, Delivery Note, Sales Invoice and POS Invoice, the
Commission section's commission_rate, total_commission and
amount_eligible_for_commission are sales-partner commission fields:
- depends_on eval:doc.sales_partner so they only show when a Sales Partner
  is set;
- no_copy so a duplicated/amended document does not carry a stale commission
  rate or computed commission amount (the sales partner itself still copies).

depends_on is client-only, so the server-side commission calculation is
unchanged. Add a Sales Order test for the no_copy behaviour.
2026-06-22 14:32:28 +05:30
Nabin Hait
943c6d210a fix: only rewrite commission_rate rows the column change can't cast
The previous string comparison (str(raw) != str(cleaned)) rewrote every
whole-number row ('20' vs '20.0'), turning a targeted cleanup into a
full-table rewrite on Sales Team. Skip rows already holding a plain numeric
string and only fix NULL / empty / non-numeric / percent-sign values.
2026-06-22 14:28:29 +05:30