From 756dbe7ce89838a9cbff2e13e03c67f6f7c6e0ff Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 21 Jun 2023 17:40:48 +0530 Subject: [PATCH] refactor: return against rejected warehouse --- .../controllers/sales_and_purchase_return.py | 13 +++++- .../purchase_receipt/purchase_receipt.js | 46 +++++++++++++++++-- .../purchase_receipt/purchase_receipt.py | 7 +++ .../purchase_receipt/test_purchase_receipt.py | 27 +++++++++++ 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 818c7894b7..954668055e 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -320,7 +320,9 @@ def get_returned_qty_map_for_row(return_against, party, row_name, doctype): return data[0] -def make_return_doc(doctype: str, source_name: str, target_doc=None): +def make_return_doc( + doctype: str, source_name: str, target_doc=None, return_against_rejected_qty=False +): from frappe.model.mapper import get_mapped_doc company = frappe.db.get_value("Delivery Note", source_name, "company") @@ -471,7 +473,7 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None): target_doc.qty = -1 * flt(source_doc.qty - (returned_qty_map.get("qty") or 0)) - if hasattr(target_doc, "stock_qty"): + if hasattr(target_doc, "stock_qty") and not return_against_rejected_qty: target_doc.stock_qty = -1 * flt( source_doc.stock_qty - (returned_qty_map.get("stock_qty") or 0) ) @@ -490,6 +492,13 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None): target_doc.rejected_warehouse = source_doc.rejected_warehouse target_doc.purchase_receipt_item = source_doc.name + if doctype == "Purchase Receipt" and return_against_rejected_qty: + target_doc.qty = -1 * flt(source_doc.rejected_qty - (returned_qty_map.get("qty") or 0)) + target_doc.rejected_qty = 0.0 + target_doc.rejected_warehouse = "" + target_doc.warehouse = source_doc.rejected_warehouse + target_doc.received_qty = target_doc.qty + elif doctype == "Purchase Invoice": returned_qty_map = get_returned_qty_map_for_row( source_parent.name, source_parent.supplier, source_doc.name, doctype diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 312c166f8b..dc3e0d9935 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -209,10 +209,43 @@ erpnext.stock.PurchaseReceiptController = class PurchaseReceiptController extend } make_purchase_return() { - frappe.model.open_mapped_doc({ - method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return", - frm: cur_frm + let me = this; + + let has_rejected_items = cur_frm.doc.items.filter((item) => { + if (item.rejected_qty > 0) { + return true; + } }) + + if (has_rejected_items && has_rejected_items.length > 0) { + frappe.prompt([ + { + label: __("Return Qty from Rejected Warehouse"), + fieldtype: "Check", + fieldname: "return_for_rejected_warehouse", + default: 1 + }, + ], function(values){ + if (values.return_for_rejected_warehouse) { + frappe.call({ + method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return_against_rejected_warehouse", + args: { + source_name: cur_frm.doc.name + }, + callback: function(r) { + if(r.message) { + frappe.model.sync(r.message); + frappe.set_route("Form", r.message.doctype, r.message.name); + } + } + }) + } else { + cur_frm.cscript._make_purchase_return(); + } + }, __("Return Qty"), __("Make Return Entry")); + } else { + cur_frm.cscript._make_purchase_return(); + } } close_purchase_receipt() { @@ -322,6 +355,13 @@ frappe.ui.form.on('Purchase Receipt Item', { }, }); +cur_frm.cscript._make_purchase_return = function() { + frappe.model.open_mapped_doc({ + method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return", + frm: cur_frm + }); +} + cur_frm.cscript['Make Stock Entry'] = function() { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_stock_entry", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 387f031380..0b5dc05c3a 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -1136,6 +1136,13 @@ def get_returned_qty_map(purchase_receipt): return returned_qty_map +@frappe.whitelist() +def make_purchase_return_against_rejected_warehouse(source_name): + from erpnext.controllers.sales_and_purchase_return import make_return_doc + + return make_return_doc("Purchase Receipt", source_name, return_against_rejected_qty=True) + + @frappe.whitelist() def make_purchase_return(source_name, target_doc=None): from erpnext.controllers.sales_and_purchase_return import make_return_doc diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index ddc055656f..1986722587 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1827,6 +1827,33 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertEqual(abs(data["stock_value_difference"]), 400.00) + def test_return_from_rejected_warehouse(self): + from erpnext.stock.doctype.purchase_receipt.purchase_receipt import ( + make_purchase_return_against_rejected_warehouse, + ) + + item_code = "_Test Item Return from Rejected Warehouse" + create_item(item_code) + + warehouse = create_warehouse("_Test Warehouse Return Qty Warehouse") + rejected_warehouse = create_warehouse("_Test Rejected Warehouse Return Qty Warehouse") + + # Step 1: Create Purchase Receipt with valuation rate 100 + pr = make_purchase_receipt( + item_code=item_code, + warehouse=warehouse, + qty=10, + rate=100, + rejected_qty=2, + rejected_warehouse=rejected_warehouse, + ) + + pr_return = make_purchase_return_against_rejected_warehouse(pr.name) + self.assertEqual(pr_return.items[0].warehouse, rejected_warehouse) + self.assertEqual(pr_return.items[0].qty, 2.0 * -1) + self.assertEqual(pr_return.items[0].rejected_qty, 0.0) + self.assertEqual(pr_return.items[0].rejected_warehouse, "") + def prepare_data_for_internal_transfer(): from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier