* fix: keep source rate on re-fetch when maintain same rate is enabled (#57479)
* fix: type-annotate get_item_details arguments
---------
Co-authored-by: test <test@test.com>
* test: cover both repost branches and the no-repost case
* fix: queue repost for entries backdated by a concurrent submit
---------
(cherry picked from commit 399ff463cc)
Co-authored-by: nareshkannasln <nareshkannashanmugam@gmail.com>
* 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
* 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
* 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
* 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
* 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
* 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
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
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
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)
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)