feat: SCR return
This commit is contained in:
parent
323bdf85ce
commit
e9b28452e4
@ -77,7 +77,7 @@ def validate_returned_items(doc):
|
||||
if doc.doctype != "Purchase Invoice":
|
||||
select_fields += ",serial_no, batch_no"
|
||||
|
||||
if doc.doctype in ["Purchase Invoice", "Purchase Receipt"]:
|
||||
if doc.doctype in ["Purchase Invoice", "Purchase Receipt", "Subcontracting Receipt"]:
|
||||
select_fields += ",rejected_qty, received_qty"
|
||||
|
||||
for d in frappe.db.sql(
|
||||
@ -161,7 +161,7 @@ def validate_returned_items(doc):
|
||||
|
||||
def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
fields = ["stock_qty"]
|
||||
if doc.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
if doc.doctype in ["Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"]:
|
||||
fields.extend(["received_qty", "rejected_qty"])
|
||||
|
||||
already_returned_data = already_returned_items.get(args.item_code) or {}
|
||||
@ -224,7 +224,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
if ref_item_row.get("rate", 0) > item_dict["rate"]:
|
||||
item_dict["rate"] = ref_item_row.get("rate", 0)
|
||||
|
||||
if ref_item_row.parenttype in ["Purchase Invoice", "Purchase Receipt"]:
|
||||
if ref_item_row.parenttype in ["Purchase Invoice", "Purchase Receipt", "Subcontracting Receipt"]:
|
||||
item_dict["received_qty"] += ref_item_row.received_qty
|
||||
item_dict["rejected_qty"] += ref_item_row.rejected_qty
|
||||
|
||||
@ -239,7 +239,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
|
||||
def get_already_returned_items(doc):
|
||||
column = "child.item_code, sum(abs(child.qty)) as qty, sum(abs(child.stock_qty)) as stock_qty"
|
||||
if doc.doctype in ["Purchase Invoice", "Purchase Receipt"]:
|
||||
if doc.doctype in ["Purchase Invoice", "Purchase Receipt", "Subcontracting Receipt"]:
|
||||
column += """, sum(abs(child.rejected_qty) * child.conversion_factor) as rejected_qty,
|
||||
sum(abs(child.received_qty) * child.conversion_factor) as received_qty"""
|
||||
|
||||
@ -281,17 +281,21 @@ def get_returned_qty_map_for_row(return_against, party, row_name, doctype):
|
||||
child_doctype = doctype + " Item"
|
||||
reference_field = "dn_detail" if doctype == "Delivery Note" else frappe.scrub(child_doctype)
|
||||
|
||||
if doctype in ("Purchase Receipt", "Purchase Invoice"):
|
||||
if doctype in ("Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"):
|
||||
party_type = "supplier"
|
||||
else:
|
||||
party_type = "customer"
|
||||
|
||||
fields = [
|
||||
"sum(abs(`tab{0}`.qty)) as qty".format(child_doctype),
|
||||
"sum(abs(`tab{0}`.stock_qty)) as stock_qty".format(child_doctype),
|
||||
]
|
||||
|
||||
if doctype in ("Purchase Receipt", "Purchase Invoice"):
|
||||
if doctype != "Subcontracting Receipt":
|
||||
fields += [
|
||||
"sum(abs(`tab{0}`.stock_qty)) as stock_qty".format(child_doctype),
|
||||
]
|
||||
|
||||
if doctype in ("Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"):
|
||||
fields += [
|
||||
"sum(abs(`tab{0}`.rejected_qty)) as rejected_qty".format(child_doctype),
|
||||
"sum(abs(`tab{0}`.received_qty)) as received_qty".format(child_doctype),
|
||||
@ -397,7 +401,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
if serial_nos:
|
||||
target_doc.serial_no = "\n".join(serial_nos)
|
||||
|
||||
if doctype == "Purchase Receipt":
|
||||
if doctype in ["Purchase Receipt", "Subcontracting Receipt"]:
|
||||
returned_qty_map = get_returned_qty_map_for_row(
|
||||
source_parent.name, source_parent.supplier, source_doc.name, doctype
|
||||
)
|
||||
@ -409,15 +413,24 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
)
|
||||
target_doc.qty = -1 * flt(source_doc.qty - (returned_qty_map.get("qty") or 0))
|
||||
|
||||
target_doc.stock_qty = -1 * flt(source_doc.stock_qty - (returned_qty_map.get("stock_qty") or 0))
|
||||
target_doc.received_stock_qty = -1 * flt(
|
||||
source_doc.received_stock_qty - (returned_qty_map.get("received_stock_qty") or 0)
|
||||
)
|
||||
if hasattr(target_doc, "stock_qty"):
|
||||
target_doc.stock_qty = -1 * flt(
|
||||
source_doc.stock_qty - (returned_qty_map.get("stock_qty") or 0)
|
||||
)
|
||||
target_doc.received_stock_qty = -1 * flt(
|
||||
source_doc.received_stock_qty - (returned_qty_map.get("received_stock_qty") or 0)
|
||||
)
|
||||
|
||||
target_doc.purchase_order = source_doc.purchase_order
|
||||
target_doc.purchase_order_item = source_doc.purchase_order_item
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
target_doc.purchase_receipt_item = source_doc.name
|
||||
if doctype == "Subcontracting Receipt":
|
||||
target_doc.subcontracting_order = source_doc.subcontracting_order
|
||||
target_doc.subcontracting_order_item = source_doc.subcontracting_order_item
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
target_doc.subcontracting_receipt_item = source_doc.name
|
||||
else:
|
||||
target_doc.purchase_order = source_doc.purchase_order
|
||||
target_doc.purchase_order_item = source_doc.purchase_order_item
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
target_doc.purchase_receipt_item = source_doc.name
|
||||
|
||||
elif doctype == "Purchase Invoice":
|
||||
returned_qty_map = get_returned_qty_map_for_row(
|
||||
@ -529,7 +542,7 @@ def get_rate_for_return(
|
||||
item_row,
|
||||
)
|
||||
|
||||
if voucher_type in ("Purchase Receipt", "Purchase Invoice"):
|
||||
if voucher_type in ("Purchase Receipt", "Purchase Invoice", "Subcontracting Receipt"):
|
||||
select_field = "incoming_rate"
|
||||
else:
|
||||
select_field = "abs(stock_value_difference / actual_qty)"
|
||||
@ -564,6 +577,7 @@ def get_return_against_item_fields(voucher_type):
|
||||
"Purchase Invoice": "purchase_invoice_item",
|
||||
"Delivery Note": "dn_detail",
|
||||
"Sales Invoice": "sales_invoice_item",
|
||||
"Subcontracting Receipt": "subcontracting_receipt_item",
|
||||
}
|
||||
return return_against_item_fields[voucher_type]
|
||||
|
||||
|
@ -76,7 +76,7 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
||||
}, __("View"));
|
||||
}
|
||||
|
||||
if (!frm.doc.is_return && frm.doc.docstatus == 1) {
|
||||
if (!frm.doc.is_return && frm.doc.docstatus == 1 && frm.doc.per_returned < 100) {
|
||||
frm.add_custom_button('Subcontract Return', function () {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_subcontract_return',
|
||||
|
@ -21,6 +21,7 @@ from erpnext.controllers.tests.test_subcontracting_controller import (
|
||||
set_backflush_based_on,
|
||||
)
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import make_subcontracting_receipt
|
||||
|
||||
@ -272,6 +273,64 @@ class TestSubcontractingReceipt(FrappeTestCase):
|
||||
for row in scr.supplied_items:
|
||||
self.assertEqual(transferred_batch.get(row.batch_no), row.consumed_qty)
|
||||
|
||||
def test_subcontracting_order_partial_return(self):
|
||||
sco = get_subcontracting_order()
|
||||
rm_items = get_rm_items(sco.supplied_items)
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
make_stock_transfer_entry(
|
||||
sco_no=sco.name,
|
||||
rm_items=rm_items,
|
||||
itemwise_details=copy.deepcopy(itemwise_details),
|
||||
)
|
||||
scr1 = make_subcontracting_receipt(sco.name)
|
||||
scr1.save()
|
||||
scr1.submit()
|
||||
|
||||
scr1_return = make_return_subcontracting_receipt(scr_name=scr1.name, qty=-3)
|
||||
scr1.load_from_db()
|
||||
self.assertEqual(scr1_return.status, "Return")
|
||||
self.assertEqual(scr1.items[0].returned_qty, 3)
|
||||
|
||||
scr2_return = make_return_subcontracting_receipt(scr_name=scr1.name, qty=-7)
|
||||
scr1.load_from_db()
|
||||
self.assertEqual(scr2_return.status, "Return")
|
||||
self.assertEqual(scr1.status, "Return Issued")
|
||||
self.assertEqual(scr1.items[0].returned_qty, 10)
|
||||
|
||||
def test_subcontracting_order_over_return(self):
|
||||
sco = get_subcontracting_order()
|
||||
rm_items = get_rm_items(sco.supplied_items)
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
make_stock_transfer_entry(
|
||||
sco_no=sco.name,
|
||||
rm_items=rm_items,
|
||||
itemwise_details=copy.deepcopy(itemwise_details),
|
||||
)
|
||||
scr1 = make_subcontracting_receipt(sco.name)
|
||||
scr1.save()
|
||||
scr1.submit()
|
||||
|
||||
from erpnext.controllers.status_updater import OverAllowanceError
|
||||
args = frappe._dict(scr_name=scr1.name, qty=-15)
|
||||
self.assertRaises(OverAllowanceError, make_return_subcontracting_receipt, **args)
|
||||
|
||||
|
||||
def make_return_subcontracting_receipt(**args):
|
||||
args = frappe._dict(args)
|
||||
return_doc = make_return_doc("Subcontracting Receipt", args.scr_name)
|
||||
return_doc.supplier_warehouse = args.supplier_warehouse or args.warehouse or "_Test Warehouse 1 - _TC"
|
||||
|
||||
if args.qty:
|
||||
for item in return_doc.items:
|
||||
item.qty = args.qty
|
||||
|
||||
if not args.do_not_save:
|
||||
return_doc.save()
|
||||
if not args.do_not_submit:
|
||||
return_doc.submit()
|
||||
|
||||
return_doc.load_from_db()
|
||||
return return_doc
|
||||
|
||||
def get_items(**args):
|
||||
args = frappe._dict(args)
|
||||
|
Loading…
x
Reference in New Issue
Block a user