Commit Graph

59065 Commits

Author SHA1 Message Date
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
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
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
Nabin Hait
0b1d06d46d fix: handle percent-sign commission rates in migration patch
Values like "20%" or "20 %" parse to 0 via flt, which would wipe a real
rate. Strip a trailing percent sign before parsing so they migrate as 20.
2026-06-22 14:28:29 +05:30
Nabin Hait
2fe0601a2e fix(selling): make commission_rate a Percent field on Sales Person and Sales Team
commission_rate was a free-text Data field on the Sales Person master and the
Sales Team child, storing percentages as strings. Convert both to Percent.

A pre_model_sync patch sanitizes the existing values first (empty / NULL /
non-numeric -> 0, others normalised via flt) so the Data -> Percent column
change casts cleanly under strict SQL mode, where Percent is a NOT NULL
decimal column. The patch is idempotent and avoids db-specific SQL so it works
on both MariaDB and Postgres.
2026-06-22 14:28:28 +05:30
Nabin Hait
c5ff32aa2f refactor: tidy update_coupon_code_count
Drop the dead 'if coupon:' guard (get_doc would have thrown) and collapse the
duplicate increment branches into a single exhausted-check plus increment.
No behaviour change.
2026-06-22 14:27:16 +05:30
Mihir Kandoi
7d205c89ea test: add test case 2026-06-22 14:26:28 +05:30
Nabin Hait
8cb94ebedb test: avoid needless submit in SCO validation tests
Use do_not_submit=1 for the service-item and reserve-warehouse validation
tests; they only exercise in-memory validation methods, so submitting the
Subcontracting Order is unnecessary.
2026-06-22 14:25:34 +05:30
Nabin Hait
bcd850c808 Merge pull request #56240 from nabinhait/test-sales-commission-contribution
test(sales_order): cover sales partner commission and sales-team contribution
2026-06-22 14:20:47 +05:30
Nabin Hait
eaab71a99e test(coupon_code): cover coupon validation and usage-count edges
Add tests for the previously-untested branches of validate_coupon_code
(not-yet-valid, expired, maximum-use exhausted) and update_coupon_code_count
(releasing a use on cancel, and rejecting use beyond the maximum). Both
functions are now fully covered.
2026-06-22 14:20:41 +05:30
Nabin Hait
324f72ce4d Merge pull request #56156 from nabinhait/refactor-so-reservation
refactor(sales_order): simplify create_stock_reservation_entries
2026-06-22 14:18:08 +05:30
Mihir Kandoi
98f5116a09 fix: party specific item doesnt work if there are 2 suppliers with same item 2026-06-22 14:10:45 +05:30
Nabin Hait
b4c9827318 Merge pull request #56295 from nabinhait/test-lead-coverage
test(lead): cover lead details and prospect sync/unlink
2026-06-22 14:05:35 +05:30
Nabin Hait
95b82eeba8 Merge pull request #56290 from nabinhait/test-opportunity-lost-flow
test(opportunity): improve coverage (lost flow, auto-close, item details, prospect sync)
2026-06-22 14:05:06 +05:30
Nabin Hait
b26c09ce8a Merge pull request #56238 from frappe/chore/supplier-scorecard-test-coverage
test: Supplier Scorecard coverage + fix standing/on-time shipment bugs
2026-06-22 14:04:18 +05:30
Nabin Hait
19ba681e16 Merge pull request #56296 from nabinhait/opportunity-auto-close-default-days
fix(crm): drive opportunity auto-close days from CRM Settings, not a hardcoded fallback
2026-06-22 14:04:00 +05:30
Nabin Hait
1b3cde9d44 fix: minor fix in test
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-22 13:23:02 +05:30
Nabin Hait
daee9cc89c test(sales_order): cover sales partner commission and sales-team contribution
The parent Commission section (Sales Partner commission) and the Sales Team
table (Sales Person contribution) drive separate logic in
SellingController.calculate_commission / calculate_contribution. Add
integration tests on Sales Order:
- sales partner commission: total_commission = eligible amount * rate / 100,
  and the commission-rate 0..100 bound;
- sales-person allocated_amount tracks amount_eligible_for_commission
  (grant_commission gated), not gross net_total, plus the incentive math;
- the allocated-percentage must-total-100 throw;
- rejection of a disabled sales person.
2026-06-22 13:23:02 +05:30
Nabin Hait
ee0635246f refactor(sales_order): simplify create_stock_reservation_entries
The method (cyclomatic complexity C/14) mixed packed-item separation, SRE
creation and packed-item reservation. Extract _extract_packed_item_details,
_packed_items_to_reserve and _reserve_packed_items (verbatim moves). Drops
C/14 -> A/3; no C-rank function remains in the module. No behaviour change
(stock-reservation, product-bundle and pick-list reservation suites green).
2026-06-22 13:21:31 +05:30
ruthra kumar
4ba1f5214e Merge pull request #55488 from Shllokkk/authorise-set-status
fix: add validation and tests for set_status
2026-06-22 13:19:52 +05:30
Nabin Hait
fc0dee5730 Merge pull request #56291 from frappe/chore/rfq-sq-test-coverage
test: RFQ + Supplier Quotation coverage; fix broken SQ expiry task
2026-06-22 13:10:19 +05:30
Nabin Hait
f1b6a7d690 fix(crm): drive opportunity auto-close days from CRM Settings, not a hardcoded fallback
auto_close_opportunity fell back to 15 days in code when the CRM Setting was
blank (and its docstring still said 7). The field already defaults to 15, so
read the value straight from CRM Settings and add a patch to backfill 15 for
existing sites that left it blank, keeping the same auto-close schedule.
2026-06-22 13:05:50 +05:30
Nabin Hait
ef81caeb3d test: address review feedback on Supplier Scorecard tests
- assert cost-of-shipments against the PO base_amount instead of a
  hardcoded total, so it holds when conversion_rate != 1
- guard the idempotency test's fixed scorecard name against leftovers
- clarify that the eval-statement zero/None substitution is a truthiness check
2026-06-22 13:00:59 +05:30
Nabin Hait
d68f7ea9d1 fix: match Subcontracting Order service cost by purchase order item
calculate_service_costs paired the service_items and items child tables
by list index, which breaks if the tables are not index-aligned (e.g.
populate_items_table skips a service item with zero available qty),
assigning the wrong service cost or raising IndexError. Match by
purchase_order_item instead, and guard against division by zero qty.

Adds a regression test asserting service costs follow purchase_order_item
regardless of table ordering.
2026-06-22 12:56:26 +05:30
Nabin Hait
4c6b030a4b test(lead): cover lead details fetch and prospect sync/unlink
Add tests for get_lead_details and the Lead <-> Prospect lifecycle: editing a
lead syncs into its Prospect Lead row, and deleting the only lead of a
prospect removes the prospect. Lead controller coverage 65% -> 74%.
2026-06-22 12:50:25 +05:30
Nabin Hait
bbb7384ea5 test: add Subcontracting Order validation and process-loss coverage
Covers previously untested Subcontracting Order paths:
- a Subcontracting Order requires a subcontracting Purchase Order
- service items must be non-stock items
- a supplied item's reserve warehouse must differ from the supplier warehouse
- the Subcontracting Receipt mapper applies BOM process-loss to the received qty
2026-06-22 12:48:14 +05:30
Nabin Hait
017e09eaac test(opportunity): cover item details, auto-close and prospect sync
Add tests for get_item_details, auto_close_opportunity (a stale Replied
opportunity is closed, a recent one is not) and the Opportunity -> Prospect
opportunity sync. Opportunity controller coverage 62% -> 80%.
2026-06-22 12:45:12 +05:30
Mihir Kandoi
14b1250ea7 Merge pull request #56284 from mihir-kandoi/party-alias
feat: party aliases
2026-06-22 12:43:48 +05:30
Nabin Hait
dd4371e35b fix: repair broken Supplier Quotation expiry scheduled task
set_expired_status passed filters= and fieldname= kwargs that
frappe.db.set_value does not accept, so the daily scheduled task threw
TypeError on every run and quotations were never marked Expired. Pass
the filter dict as the positional docname argument, and scope it to
submitted documents so draft quotations aren't wrongly expired (matching
the selling Quotation behaviour).

Adds coverage for valid-till validation, the expiry task, and the
RFQ quote-status round-trip on submit/cancel.
2026-06-22 12:38:32 +05:30
Nabin Hait
618ee6ddeb test: add RFQ duplicate-supplier, scorecard-block and status coverage 2026-06-22 12:38:31 +05:30
Nabin Hait
61c2e7ad6e test(opportunity): cover the mark-as-lost flow
declare_enquiry_lost had almost no coverage. Add tests that marking an
Opportunity as lost records the lost reasons, competitors and detailed
reason and sets status to Lost, and that it is blocked when an active
(submitted) Quotation exists.
2026-06-22 12:33:19 +05:30
Ankush Menat
7256fc98e9 ci: Wait for processes to die (#56288) 2026-06-22 12:25:16 +05:30
Mihir Kandoi
5e16d41387 feat: party aliases 2026-06-22 12:23:44 +05:30
Mihir Kandoi
73459af908 Merge pull request #56283 from frappe/revert-56261-qcs-uae-regional
revert: "feat: Enhance UAE VAT Reports, UAE FTA Audit File and Add VAT Register"
2026-06-22 11:03:17 +05:30
Mihir Kandoi
cfaaf43381 Revert "feat: Enhance UAE VAT Reports, UAE FTA Audit File and Add VAT Register" 2026-06-22 10:42:57 +05:30
Bibin
7b84478c70 Merge pull request #56261 from bibinqcs/qcs-uae-regional
feat: Enhance UAE VAT Reports, UAE FTA Audit File and Add VAT Register
2026-06-22 10:32:38 +05:30
Mihir Kandoi
bae0263990 Merge pull request #56281 from mihir-kandoi/pg-greptile-config
ci(greptile): enforce MariaDB↔PostgreSQL parity in PR review
2026-06-22 09:54:53 +05:30
Mihir Kandoi
c1a3685d14 Merge pull request #56279 from mihir-kandoi/subcontracting-inward-controller-cleanup
fix(subcontracting): correct FG-warehouse validation message + controller cleanup
2026-06-22 09:38:48 +05:30
Mihir Kandoi
3e2d61262a ci(greptile): widen guide scope to SQL-bearing non-Python files; fix HAVING-alias wording
Address Greptile review:
- customContext.files scope was **/*.py only, so Query Report SQL in .js/.sql/report .json
  files didn't get the guide attached as context (the global instructions still applied).
  Widen to .py/.js/.sql/report **/*.json.
- The guide's HAVING-alias rule said "with no GROUP BY"; PostgreSQL rejects a SELECT-alias in
  HAVING regardless of GROUP BY. Reworded to match (repeat the expression, or move a
  non-aggregate predicate to WHERE).
2026-06-22 09:34:23 +05:30
Mihir Kandoi
4a690c86d2 ci(greptile): teach the review bot to enforce MariaDB↔PostgreSQL parity
The PostgreSQL server-test job is label-gated, so until it is required the Greptile
PR-review bot is the always-on guard against cross-engine breaks. Extend
.greptile/config.json with `instructions` (and a `customContext` reference to a new
guide) so every review flags new/changed queries that would error on PostgreSQL or
silently diverge from MariaDB, under the prime rule that MariaDB output must not change.

- .github/POSTGRES_COMPATIBILITY.md — the catalogue the bot (and contributors) follow:
  hard breaks (loose GROUP BY, MySQL-only funcs, UPDATE..JOIN, HAVING-on-alias,
  DISTINCT+ORDER BY, single-quoted alias, varchar bitwise OR, capital identifiers,
  set_value(Check,bool)), silent divergences (text case-sensitivity, name-lookup case,
  empty-string↔NULL, NULL ordering, ORDER BY..LIMIT 1 tiebreakers, integer division,
  distinct-drops-ORDER-BY-on-PG + casefold sorting, function-rewrite parity, UnixTimestamp
  TZ), the GROUP BY row-count trap (Max()-wrap vs add-to-GROUP-BY; FD-by-source-table),
  the InFailedSqlTransaction/savepoint rule, and the false positives NOT to flag
  (.like→ILIKE, ifnull/backtick/LOCATE/REGEXP auto-translation, MariaDB-changing tiebreakers).
- Existing disabledLabels and frappe/frappe context are preserved.
2026-06-22 09:29:19 +05:30
Mihir Kandoi
b129daedc8 refactor(subcontracting): dedup validate_manufacture consumption checks
The `skip_transfer` and transfer branches of `validate_manufacture` ran the
same per-item validation loop — look the row up or throw "not a part of",
check overconsumption, guard against duplicates, record — differing only in
the data source (SCIO Received Item vs Work Order Item), the available-qty
basis, the source-warehouse check (skip_transfer only) and the message text.

Split each branch into a small method that builds a normalised
`{item_code: {consumed_qty, available_qty}}` lookup, and share the loop via
`_validate_customer_provided_consumption`. Branch-specific throw messages are
passed as callbacks so the user-facing strings (and their translations) are
unchanged, and the order in which checks fire is preserved. Also drops the
unused `name` column from the skip_transfer query.

Adds a test for the non-skip-transfer manufacture flow (Material Transfer for
Manufacture -> Manufacture), which exercises the Work Order branch that the
existing suite — all of whose manufacture tests set skip_transfer=1 — never
covered. Full subcontracting-inward suite passes on MariaDB and PostgreSQL.
2026-06-22 09:18:45 +05:30
Mihir Kandoi
23f1fc6235 refactor(subcontracting): use f-string for fg reference search filter
`get_fg_reference_names` built its LIKE filter with old-style
`"%%%s%%" % txt`. Use an f-string (`f"%{txt}%"`) for readability; the value
is still passed as a parameterised filter, so behaviour is unchanged.
2026-06-22 08:00:15 +05:30
Mihir Kandoi
19466b24b0 perf(subcontracting): compute child idx once per insert loop
Each new child row was given `idx=frappe.db.count(...) + 1`, issuing a count
query per inserted row across three insert loops (received items on receipt,
self-procured RM on manufacture, secondary items on manufacture). Compute the
starting index once before each loop and increment a local counter, producing
the same idx sequence with a single count query.
2026-06-22 08:00:15 +05:30
Mihir Kandoi
63c5dccb4b fix(subcontracting): guard empty raw-material list before strict zip
`update_inward_order_received_items_for_manufacture` unpacks
`zip(*item_code_wh.keys(), strict=True)`. When the manufacture entry has no
raw-material rows (all rows are finished/secondary/scrap), `item_code_wh` is
empty and the unpack raises `ValueError: not enough values to unpack`.

Return early when there are no such rows, mirroring the `if secondary_items:`
guard already present in `update_inward_order_secondary_items`.
2026-06-22 08:00:15 +05:30