Commit Graph

58837 Commits

Author SHA1 Message Date
Mihir Kandoi
d2678902ec Merge pull request #57937 from frappe/mergify/bp/version-16-hotfix/pr-57689
feat(job_card): print quantities with their stock uom (backport #57689)
2026-08-09 23:14:13 +05:30
Mihir Kandoi
94c81965a7 test(manufacturing): cover job card UOM backfill 2026-08-09 23:02:58 +05:30
Mihir Kandoi
8310b56f32 chore: resolve conflict 2026-08-09 22:56:02 +05:30
Mihir Kandoi
6e4a7fba7e Merge pull request #57930 from frappe/mergify/bp/version-16-hotfix/pr-57895
fix: track semi finished goods production flow (backport #57895)
2026-08-09 22:47:52 +05:30
Mihir Kandoi
5c38e43758 chore: update backport after dependent merges 2026-08-09 22:36:10 +05:30
Mihir Kandoi
b4fbbe51e8 Merge pull request #57934 from frappe/mergify/bp/version-16-hotfix/pr-57688
refactor(job_card): make the completion dialog say what it asks for (backport #57688)
2026-08-09 22:32:25 +05:30
Mihir Kandoi
e42a59c5d4 Merge pull request #57933 from frappe/mergify/bp/version-16-hotfix/pr-57687
fix(job_card): reject a completion split that cannot add up (backport #57687)
2026-08-09 22:31:48 +05:30
Mihir Kandoi
cc07918f06 Merge pull request #57936 from frappe/mergify/bp/version-16-hotfix/pr-57686
fix(job_card): leave the pending qty out of the job card's own output (backport #57686)
2026-08-09 22:12:24 +05:30
Mihir Kandoi
66aa97f7fe chore: update backport after dependent merges 2026-08-09 22:02:11 +05:30
Mihir Kandoi
4e8c2c7d37 Merge pull request #57935 from frappe/mergify/bp/version-16-hotfix/pr-57685
fix(job_card): apply the completion dialog's qty to manufacture (backport #57685)
2026-08-09 21:59:06 +05:30
Mihir Kandoi
816e21cf60 Merge pull request #57931 from frappe/mergify/bp/version-16-hotfix/pr-57684
fix(job_card): require the previous operation to be manufactured (backport #57684)
2026-08-09 21:58:48 +05:30
Mihir Kandoi
317dd18ce5 fix(manufacturing): align quantity split rounding 2026-08-09 21:43:00 +05:30
Mihir Kandoi
eb90186d3f feat(job_card): print quantities with their stock uom (#57689)
* feat(job_card): carry the stock uom on the job card

Every quantity the job card reports belongs to the item it produces, but the
document had no unit of its own, so messages could only print bare numbers.

Add the Stock UOM field, set from the finished good or the final product, and
backfill the job cards that already exist.

* fix(job_card): print quantities with their unit

A bare 5 in an error says nothing about what was counted. Every message that
reports a quantity now names its unit, taking it from the job card's stock uom,
from the previous operation's finished good when the message compares two
operations, and from the item itself for a raw material transfer.

The completion dialogs read the same unit off the job card.

* refactor(job_card): move the stock uom next to the qty it measures

* fix(job_card): keep the stock uom backfill atomic

Drop the auto commit toggle so the backfill is a single transaction with no
connection flag left behind when it raises, and select the job cards to fill
with an explicit unset filter instead of a value list.

(cherry picked from commit 07ac4d83ef)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.js
#	erpnext/manufacturing/doctype/job_card/job_card.json
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
#	erpnext/manufacturing/page/shop_floor/shop_floor.py
#	erpnext/patches.txt
#	erpnext/public/js/shop_floor/shop_floor.js
2026-08-09 16:04:55 +00:00
Mihir Kandoi
a8060d5e99 fix(manufacturing): adapt version 16 compatibility 2026-08-09 21:22:17 +05:30
Mihir Kandoi
87b456faa2 fix(manufacturing): type whitelisted BOM arguments 2026-08-09 21:10:08 +05:30
Mihir Kandoi
beed05ac18 test(manufacturing): isolate quantity split validation 2026-08-09 21:08:57 +05:30
Mihir Kandoi
a5e4bbd436 chore: resolve conflict 2026-08-09 21:07:17 +05:30
Mihir Kandoi
1ededb70f4 chore: resolve conflict 2026-08-09 20:53:27 +05:30
Mihir Kandoi
c955f80675 chore: resolve conflict 2026-08-09 20:50:50 +05:30
Mihir Kandoi
fab480af98 chore: resolve conflict 2026-08-09 20:48:19 +05:30
Mihir Kandoi
f176a46722 chore: resolve conflict 2026-08-09 20:43:30 +05:30
Mihir Kandoi
7fcfea6db2 chore: resolve conflict 2026-08-09 20:42:02 +05:30
Mihir Kandoi
0c7919429e fix(job_card): leave the pending qty out of the job card's own output (#57686)
* fix(job_card): leave the pending qty out of the job card's own output

Pending qty is the part of a job card handed over to another job card, but the
status and the manufacturing entry still measured the card against its full
for_quantity. A card submitted with 3 completed and 2 pending was stuck at Work
In Progress with no way to change it, and its manufacturing entry was built for
the full 5.

Measure both against for_quantity minus pending qty, so the card reaches To
Manufacture on submission, its manufacturing entry covers the completed qty, and
it is Completed once that qty is manufactured.

* test(job_card): cover a job card completed with a pending qty

(cherry picked from commit 970039d8ec)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
2026-08-09 15:03:18 +00:00
Mihir Kandoi
d97cf131a1 fix(job_card): apply the completion dialog's qty to manufacture (#57685)
* fix(job_card): apply the completion dialog's qty to manufacture

Both the desk dialog and the shop floor session dialog send for_quantity when
completing a job card, but complete_job_card dropped it. Reducing Qty to
Manufacture to 3 on a job card of 5 left for_quantity at 5, so set_process_loss
turned the untouched 2 into process loss on the next save.

The dialog qty covers the current cycle, so add it to the qty already completed
by the earlier cycles of the job card instead of overwriting for_quantity, and
validate the pending qty against the result.

* test(job_card): cover qty to manufacture from the completion dialog

Reducing the dialog qty resizes the job card without inventing process loss, and
a pending qty split across two cycles leaves for_quantity untouched.

(cherry picked from commit 0e1bc58b2e)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
2026-08-09 15:02:47 +00:00
Mihir Kandoi
3f2e0c177b refactor(job_card): make the completion dialog say what it asks for (#57688)
* refactor(job_card): drop the unused make_finished_good handler

Nothing triggered it and Job Card has no make_finished_good method to call.

* refactor(job_card): make the completion dialog say what it asks for

The dialog qty shares the Qty to Manufacture label with the field on the form
while it means the current cycle only, its title fell back to the generic Enter
Value because frappe.prompt takes four arguments and it was passed five, and
nothing on it stated that the three quantities have to add up.

Name the cycle in the label, title the dialog after the button that opens it,
and describe the split on the fields. Same wording in the shop floor dialog.

(cherry picked from commit 0ddf72dae9)

# Conflicts:
#	erpnext/public/js/shop_floor/shop_floor.js
2026-08-09 15:02:15 +00:00
Mihir Kandoi
3907d93f9f fix(job_card): reject a completion split that cannot add up (#57687)
* fix(job_card): reject a completion split that cannot add up

The completion dialogs silently dropped a recalculation whose result went
negative, so entering a pending qty larger than what is left of the qty to
manufacture kept the contradiction (3 to manufacture, 3 completed, 2 pending)
and the job card only failed much later, on submission.

Keep the split consistent while it is entered: reset the pending qty when the
qty to manufacture changes, and refuse a completed, pending or process loss qty
that leaves the others negative. complete_job_card validates the same rule, so
the shop floor and the API cannot store a split that will never submit.

Also name the three parts in the submission error instead of calling their sum
the Total Completed Qty, which read as a contradiction of the field itself.

* test(job_card): cover the completion qty split guard

(cherry picked from commit 7bffd84482)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
#	erpnext/public/js/shop_floor/shop_floor.js
2026-08-09 15:01:38 +00:00
Mihir Kandoi
a22a7fddba fix(job_card): require the previous operation to be manufactured (#57684)
* fix(job_card): block next operation until previous operation is manufactured

With track semi finished goods, Work Order Operation completed_qty is set from
the submitted job cards' total completed qty, so a job card of the next
operation could be started and completed even when no Manufacture entry existed
for the previous operation. The semi-finished goods it consumes were never
produced.

Validate the sequence against the qty actually manufactured against the previous
operations' job cards (Manufacture entries / Subcontracting Receipts) when the
work order tracks semi finished goods.

* test(job_card): cover manufactured qty check across previous operations

Work order with operations A and B at sequence 1 and C at sequence 2, tracking
semi finished goods. C stays blocked while A's job card is submitted but its
Manufacture entry is missing, and once A is manufactured for 3, C can only be
completed for 3.

(cherry picked from commit 3bd3354152)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
2026-08-09 14:42:47 +00:00
pandiyan
27625a6f1f test: work order process loss for semi finished goods
Cover both shapes: a single operation that books the loss itself, and a
chain where an earlier operation books it and the final operation loses
nothing, so the sum over the operations is the only correct source.

(cherry picked from commit 24de81f9fa)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
2026-08-09 14:42:16 +00:00
pandiyan
27130d8e49 fix: roll up process loss to the work order for semi finished goods
update_work_order_qty() returns early when track_semi_finished_goods is
enabled, so set_process_loss_qty() never ran and Work Order.process_loss_qty
stayed at zero even though the job cards and the work order operations had
booked the loss. The work order also never reached the Completed status,
since that needs produced_qty + process_loss_qty to cover the ordered qty.

Calling set_process_loss_qty() from that early return is not enough: the
final operation has no semi finished good bom, so its manufacture entry is
not from a bom, remove_fg_completed_qty() zeroes fg_completed_qty and
update_work_order_qty() is never reached at all.

The manufacture entries cannot be summed either. Each one is reset to
MAX(Work Order Operation.process_loss_qty), so every entry of a multi
operation chain carries the running maximum instead of the loss of its own
operation. Aggregate the operations instead, and refresh the work order from
the job card, which is where the operation loss is written.

(cherry picked from commit 0eb61c9fac)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/work_order/services/status.py
2026-08-09 14:42:15 +00:00
Mihir Kandoi
ae00a09cdf test: transfer qty exemption only applies when material transfer is skipped
(cherry picked from commit 1478e2a4cb)
2026-08-09 14:42:14 +00:00
Mihir Kandoi
f810d780c0 fix: keep the transfer qty check for legacy semi FG cards without an FG item
Existing submitted BOMs may carry operations without a finished good,
and no migration repairs them. Exempting every semi FG job card from
the transfer check let such a card submit after a partial transfer.
Exempt only cards that skip material transfer; legacy cards with
transfer enabled keep the strict transferred qty check.

(cherry picked from commit 1deae664ce)
2026-08-09 14:42:14 +00:00
Mihir Kandoi
5f391a2531 test: partial entries consume exactly the job card's material requirement
(cherry picked from commit 8f0617c834)
2026-08-09 14:42:14 +00:00
Mihir Kandoi
acba9945b0 fix: scale generated raw materials to the manufacture entry's production share
Every generated entry copied each Job Card Item's full required_qty in
the skip-transfer and BOM-backflush paths, so two entries for one job
card consumed the requirement twice. Scale the rows to the share of
production this entry accounts for and cap them at the requirement
still unconsumed, dropping rows that have nothing left. An entry whose
materials are exhausted then fails the existing at-least-one-raw-material
check instead of minting finished goods from nothing.

(cherry picked from commit 0428cddf5b)
2026-08-09 14:42:14 +00:00
Mihir Kandoi
a815a756b7 test: update-after-submit save keeps the manufacture entry intact
(cherry picked from commit 424a1dfa87)
2026-08-09 14:42:13 +00:00
Mihir Kandoi
491f9fa3fe fix: skip the pending production check on update-after-submit saves
Saving a submitted manufacture entry to change an allowed field re-ran
the pending production cap with a manufactured aggregate that already
includes the entry itself, so the save was rejected against the
post-entry remainder. Quantities are not editable after submit, so the
check has nothing to protect there.

(cherry picked from commit bed957fa67)
2026-08-09 14:42:13 +00:00
Mihir Kandoi
e252329df4 test: target warehouse stays optional for semi FG work orders
(cherry picked from commit db99657c47)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order/test_work_order.py
2026-08-09 14:42:13 +00:00
Mihir Kandoi
c598cf9010 fix: keep Target Warehouse optional for work orders tracking semi finished goods
The WIP warehouse change also removed the Target Warehouse exemption
for semi FG orders, but those may validly carry the target on each
operation instead. Restore the exemption in the form and the submit
check; the WIP warehouse requirement stays.

(cherry picked from commit 9df527bf3f)
2026-08-09 14:42:12 +00:00
Mihir Kandoi
e885902864 test: partial manufacture entry then finishing the job card
(cherry picked from commit eb7537c8df)
2026-08-09 14:42:12 +00:00
Mihir Kandoi
2548751673 fix: generate the next manufacture entry net of booked process loss
After a partial entry booked the job card's full process loss, the
next generated entry was sized qty-to-produce minus manufactured only.
It exceeded the pending production cap, so Make Stock Entry could not
finish the card. Subtract the consumed loss when sizing the entry.

(cherry picked from commit b8dd886cd4)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
2026-08-09 14:42:12 +00:00
Mihir Kandoi
f25c54e9d7 test: stale manufacture draft cannot over-produce without an operation BOM
(cherry picked from commit 7157e4357b)
2026-08-09 14:42:11 +00:00
Mihir Kandoi
79ad410cc1 fix: cap a manufacture entry at the job card's pending production
Entries from operations without their own BOM carry no For Quantity,
so the finished-good reconciliation cannot run for them and a draft
created before other entries were submitted could still over-produce.

Validate every job-card manufacture entry against the job card
directly: finished goods plus process loss must fit in what the job
card still has left to produce after earlier submitted entries.

(cherry picked from commit 94cd27ce5d)
2026-08-09 14:42:11 +00:00
Mihir Kandoi
605821f04c test: operation BOM materials expand on single-pass submit, final FG must match the BOM item
(cherry picked from commit 9ef386dfd2)
2026-08-09 14:42:11 +00:00
Mihir Kandoi
3e0d0b2d68 fix: derive operation FG items before material expansion, keep the final one the BOM's item
The finished_good derivation ran in validate_semi_finished_goods,
after set_materials_based_on_operation_bom had already expanded
operation BOM materials. A single-pass insert-and-submit (API or
import) with bom_no set but finished_good empty skipped the expansion,
persisting a submitted BOM without the referenced components. The
derivation also let a final operation inherit another item from its
bom_no, so downstream job cards would produce the wrong item.

Move the derivation into set_operation_finished_goods, called before
the expansion, prefer the BOM's own item for the final operation, and
reject a final operation whose FG item is not the BOM's item.

(cherry picked from commit 1e2e87daac)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/bom.py
2026-08-09 14:42:10 +00:00
Mihir Kandoi
b4eceeda2d test: raw material dialog adds a row for its operation despite duplicates
(cherry picked from commit 0aec62a8dd)
2026-08-09 14:42:10 +00:00
Mihir Kandoi
35f9bec988 fix: add raw material to its operation even when another operation uses the item
get_item_details returns the whole Item document, so the dialog row's
name became the item code. get_item_data then matched that item code
against every Components row regardless of operation, so adding an item
already used by another operation silently updated that row's qty
instead of appending one for the target operation — which stayed empty
and failed 'please add raw materials or set a BOM' on submit.

Match the existing row by item code within the same operation: same
operation updates the qty, any other match appends a new row.

(cherry picked from commit 24f1f3dea8)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/bom.py
2026-08-09 14:42:10 +00:00
Mihir Kandoi
0de97159ea test: manufacture entry keeps process loss scoped to its own operation
(cherry picked from commit 5e0f056284)
2026-08-09 14:42:09 +00:00
Mihir Kandoi
a0b370b2e9 fix: scope manufacture entry process loss to its own job card
set_process_loss_qty stamped MAX(process_loss_qty) across every
operation of the work order onto each manufacture entry. With semi
finished goods tracking, one operation's process loss leaked into the
entries of every other operation: validate_fg_completed_qty then
rejected the entry when it had a BOM, or the wrong loss was recorded
silently when it did not, double-counting the loss across operations.

When the entry belongs to a job card, use that job card's loss net of
what its earlier entries already booked. The MAX fallback stays for
work-order level entries without a job card.

Fixes frappe/erpnext#57892

(cherry picked from commit 1b335973b7)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/stock_entry.py
2026-08-09 14:42:09 +00:00
Mihir Kandoi
f58c0adbf5 test: previous operation shortfall from process loss gets the right message
(cherry picked from commit 335dbdaca4)
2026-08-09 14:42:09 +00:00
Mihir Kandoi
104c8df765 fix: stop asking for a manufacturing entry when process loss explains the shortfall
When a previous operation manufactured less than the current job card
is completing, the error always said 'Submit the manufacturing entry
for the operation first' — even when the entry was already submitted
and the missing quantity was booked as process loss, which made the
advice a dead end.

Sum the process loss of the previous operation's job cards alongside
the manufactured quantity. When manufactured + process loss covers the
requested quantity, say the shortfall is process loss so the user
knows to reduce the completed quantity; keep the submit-first message
for genuinely pending manufacturing entries.

(cherry picked from commit 1e22695eae)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py
2026-08-09 14:42:08 +00:00
Mihir Kandoi
e822efe6a1 test: WIP warehouse required for work orders tracking semi finished goods
(cherry picked from commit f61f6523b9)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order/test_work_order.py
2026-08-09 14:42:08 +00:00