From 29997e26316816cd292c63671be797acb447c338 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 15 Apr 2019 21:02:16 +0530 Subject: [PATCH] fix: Invoice against partially returned DN/PR --- .../doctype/delivery_note/delivery_note.py | 26 ++++------------- .../delivery_note/test_delivery_note.py | 2 +- .../purchase_receipt/purchase_receipt.py | 29 ++++--------------- .../purchase_receipt/test_purchase_receipt.py | 2 +- 4 files changed, 14 insertions(+), 45 deletions(-) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 90d1d0a401..cd69dd43b0 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -396,19 +396,7 @@ def get_invoiced_qty_map(delivery_note): return invoiced_qty_map -def get_returned_qty_map_against_so(sales_orders): - """returns a map: {so_detail: returned_qty}""" - returned_qty_map = {} - - for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"], - filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1): - if not returned_qty_map.get(name): - returned_qty_map[name] = 0 - returned_qty_map[name] += returned_qty - - return returned_qty_map - -def get_returned_qty_map_against_dn(delivery_note): +def get_returned_qty_map(delivery_note): """returns a map: {so_detail: returned_qty}""" returned_qty_map = frappe._dict(frappe.db.sql("""select dn_item.item_code, sum(abs(dn_item.qty)) as qty from `tabDelivery Note Item` dn_item, `tabDelivery Note` dn @@ -425,8 +413,7 @@ def get_returned_qty_map_against_dn(delivery_note): def make_sales_invoice(source_name, target_doc=None): doc = frappe.get_doc('Delivery Note', source_name) sales_orders = [d.against_sales_order for d in doc.items] - returned_qty_map_against_so = get_returned_qty_map_against_so(sales_orders) - returned_qty_map_against_dn = get_returned_qty_map_against_dn(source_name) + returned_qty_map = get_returned_qty_map(source_name) invoiced_qty_map = get_invoiced_qty_map(source_name) def set_missing_values(source, target): @@ -447,17 +434,16 @@ def make_sales_invoice(source_name, target_doc=None): def update_item(source_doc, target_doc, source_parent): target_doc.qty, returned_qty = get_pending_qty(source_doc) - if not source_doc.so_detail: - returned_qty_map_against_dn[source_doc.item_code] = returned_qty + returned_qty_map[source_doc.item_code] = returned_qty if source_doc.serial_no and source_parent.per_billed > 0: target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code, target_doc.qty, source_parent.name) def get_pending_qty(item_row): - pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) - returned_qty_map_against_so.get(item_row.so_detail, 0) - returned_qty = flt(returned_qty_map_against_dn.get(item_row.item_code, 0)) - if not item_row.so_detail: + pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) + returned_qty = flt(returned_qty_map.get(item_row.item_code, 0)) + if returned_qty: if returned_qty >= pending_qty: pending_qty = 0 returned_qty -= pending_qty diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index 5c031213d8..bc95c965bc 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -655,7 +655,7 @@ class TestDeliveryNote(unittest.TestCase): si = make_sales_invoice(dn.name) self.assertEquals(si.items[0].qty, 1) - def test_make_sales_invoice_from_dn_with_returned_qty_against_dn(self): + def test_make_sales_invoice_from_dn_with_returned_qty_duplicate_items(self): from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice dn = create_delivery_note(qty=8, do_not_submit=True) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index e3877fb425..71cf1dab79 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -407,10 +407,7 @@ def update_billed_amount_based_on_po(po_detail, update_modified=True): def make_purchase_invoice(source_name, target_doc=None): from frappe.model.mapper import get_mapped_doc doc = frappe.get_doc('Purchase Receipt', source_name) - purchase_orders = [d.purchase_order for d in doc.items] - returned_qty_map_against_po = get_returned_qty_map_against_po(purchase_orders) - returned_qty_map_against_pr = get_returned_qty_map_against_pr(source_name) - + returned_qty_map = get_returned_qty_map(source_name) invoiced_qty_map = get_invoiced_qty_map(source_name) def set_missing_values(source, target): @@ -424,14 +421,12 @@ def make_purchase_invoice(source_name, target_doc=None): def update_item(source_doc, target_doc, source_parent): target_doc.qty, returned_qty = get_pending_qty(source_doc) - if not source_doc.purchase_order_item: - returned_qty_map_against_pr[source_doc.item_code] = returned_qty + returned_qty_map[source_doc.item_code] = returned_qty def get_pending_qty(item_row): - pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) \ - - returned_qty_map_against_po.get(item_row.purchase_order_item, 0) - returned_qty = flt(returned_qty_map_against_pr.get(item_row.item_code, 0)) - if not item_row.purchase_order_item: + pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) + returned_qty = flt(returned_qty_map.get(item_row.item_code, 0)) + if returned_qty: if returned_qty >= pending_qty: pending_qty = 0 returned_qty -= pending_qty @@ -484,19 +479,7 @@ def get_invoiced_qty_map(purchase_receipt): return invoiced_qty_map -def get_returned_qty_map_against_po(purchase_orders): - """returns a map: {so_detail: returned_qty}""" - returned_qty_map = {} - - for name, returned_qty in frappe.get_all('Purchase Order Item', fields = ["name", "returned_qty"], - filters = {'parent': ('in', purchase_orders), 'docstatus': 1}, as_list=1): - if not returned_qty_map.get(name): - returned_qty_map[name] = 0 - returned_qty_map[name] += returned_qty - - return returned_qty_map - -def get_returned_qty_map_against_pr(purchase_receipt): +def get_returned_qty_map(purchase_receipt): """returns a map: {so_detail: returned_qty}""" returned_qty_map = frappe._dict(frappe.db.sql("""select pr_item.item_code, sum(abs(pr_item.qty)) as qty from `tabPurchase Receipt Item` pr_item, `tabPurchase Receipt` pr diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index c5ae838c8f..d124ae4747 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -418,7 +418,7 @@ class TestPurchaseReceipt(unittest.TestCase): pi = make_purchase_invoice(pr.name) self.assertEquals(pi.items[0].qty, 3) - def test_make_purchase_invoice_from_dn_with_returned_qty_against_dn(self): + def test_make_purchase_invoice_from_pr_with_returned_qty_duplicate_items(self): pr1 = make_purchase_receipt(qty=8, do_not_submit=True) pr1.append("items", { "item_code": "_Test Item",