From 621f4cd7c90dd241a8c788b3312cf78a474fe468 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 30 Nov 2015 12:23:22 +0530 Subject: [PATCH 1/2] [fix] Invoicing against drop-ship Purchase Order --- .../purchase_invoice/purchase_invoice.py | 10 +++++--- .../doctype/purchase_order/purchase_order.js | 15 +++++------ .../purchase_order/purchase_order.json | 25 +------------------ .../doctype/purchase_order/purchase_order.py | 7 +++--- erpnext/patches.txt | 1 + .../fix_billed_amount_in_drop_ship_po.py | 18 +++++++++++++ 6 files changed, 38 insertions(+), 38 deletions(-) create mode 100644 erpnext/patches/v6_10/fix_billed_amount_in_drop_ship_po.py diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 12934a1b45..d916b61152 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -150,10 +150,14 @@ class PurchaseInvoice(BuyingController): against_accounts = [] stock_items = self.get_stock_items() for item in self.get("items"): + # in case of auto inventory accounting, + # against expense account is always "Stock Received But Not Billed" + # for a stock item and if not epening entry and not drop-ship entry + if auto_accounting_for_stock and item.item_code in stock_items \ - and self.is_opening == 'No': - # in case of auto inventory accounting, against expense account is always - # Stock Received But Not Billed for a stock item + and self.is_opening == 'No' and (not item.po_detail or + not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): + item.expense_account = stock_not_billed_account item.cost_center = None diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 9ee8062440..f1179eec1d 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -47,14 +47,14 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( cur_frm.add_custom_button(__('Close'), this.close_purchase_order); } - if(is_drop_ship && doc.status!="Delivered"){ - cur_frm.add_custom_button(__('Mark as Delivered'), this.delivered_by_supplier); - } - if(flt(doc.per_billed)==0) { cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_bank_entry); } - + + if(is_drop_ship && doc.status!="Delivered"){ + cur_frm.add_custom_button(__('Mark as Delivered'), + this.delivered_by_supplier).addClass("btn-primary"); + } } else if(doc.docstatus===0) { cur_frm.cscript.add_from_mappers(); } @@ -70,12 +70,13 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( } if(flt(doc.per_billed, 2) < 100) - cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice); + cur_frm.add_custom_button(__('Invoice'), + this.make_purchase_invoice).addClass("btn-primary"); } if(doc.docstatus == 1 && in_list(["Stopped", "Closed", "Delivered"], doc.status)) { if (this.frm.has_perm("submit")) { - cur_frm.add_custom_button(__('Re-open'), this.unstop_purchase_order); + cur_frm.add_custom_button(__('Re-open'), this.unstop_purchase_order).addClass("btn-primary"); } } }, diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index bd3f6fbfab..e52081bf9c 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -414,29 +414,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "delivered_by_supplier", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "To be delivered to customer", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -2406,7 +2383,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-11-20 15:51:09.314885", + "modified": "2015-11-20 15:51:09.314888", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 2f155d288b..12128998a2 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -48,7 +48,7 @@ class PurchaseOrder(BuyingController): self.validate_for_subcontracting() self.validate_minimum_order_qty() self.create_raw_materials_supplied("supplied_items") - self.set_received_qty_and_billed_amount_for_drop_ship_items() + self.set_received_qty_for_drop_ship_items() def validate_with_previous_doc(self): super(PurchaseOrder, self).validate_with_previous_doc({ @@ -253,11 +253,10 @@ class PurchaseOrder(BuyingController): return is_drop_ship - def set_received_qty_and_billed_amount_for_drop_ship_items(self): + def set_received_qty_for_drop_ship_items(self): for item in self.items: if item.delivered_by_supplier == 1: item.received_qty = item.qty - item.billed_amt = item.amount @frappe.whitelist() def stop_or_unstop_purchase_orders(names, status): @@ -342,7 +341,7 @@ def make_purchase_invoice(source_name, target_doc=None): "parent": "purchase_order", }, "postprocess": update_item, - "condition": lambda doc: (doc.base_amount==0 or doc.billed_amt < doc.amount) and doc.delivered_by_supplier!=1 + "condition": lambda doc: (doc.base_amount==0 or doc.billed_amt < doc.amount) }, "Purchase Taxes and Charges": { "doctype": "Purchase Taxes and Charges", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 3675924cdb..aa57ba3509 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -237,3 +237,4 @@ erpnext.patches.v6_8.move_drop_ship_to_po_items erpnext.patches.v6_10.fix_ordered_received_billed erpnext.patches.v6_10.fix_jv_total_amount #2015-11-28 erpnext.patches.v6_10.email_digest_default_quote +erpnext.patches.v6_10.fix_billed_amount_in_drop_ship_po \ No newline at end of file diff --git a/erpnext/patches/v6_10/fix_billed_amount_in_drop_ship_po.py b/erpnext/patches/v6_10/fix_billed_amount_in_drop_ship_po.py new file mode 100644 index 0000000000..4aecaa7c84 --- /dev/null +++ b/erpnext/patches/v6_10/fix_billed_amount_in_drop_ship_po.py @@ -0,0 +1,18 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.db.sql("""update `tabPurchase Order Item` set billed_amt = 0 + where delivered_by_supplier=1 and docstatus=1""") + + drop_ship_pos = frappe.db.sql("""select distinct parent from `tabPurchase Order Item` + where delivered_by_supplier=1 and docstatus=1""") + + for po in drop_ship_pos: + invoices = frappe.db.sql("""select distinct parent from `tabPurchase Invoice Item` + where purchase_order=%s and docstatus=1""", po[0]) + if invoices: + for inv in invoices: + frappe.get_doc("Purchase Invoice", inv[0]).update_qty(change_modified=False) + else: + frappe.db.sql("""update `tabPurchase Order` set per_billed=0 where name=%s""", po[0]) \ No newline at end of file From ddc295b4b3467fbeb655dd9ba870542e70b8c7ee Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 30 Nov 2015 18:40:06 +0530 Subject: [PATCH 2/2] [minor] Set expense account as Stock RBNB for perpetual inventory after mapping --- erpnext/controllers/accounts_controller.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 65f39aa46f..861ec8e942 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -133,6 +133,14 @@ class AccountsController(TransactionBase): def set_missing_item_details(self): """set missing item values""" from erpnext.stock.get_item_details import get_item_details + + if self.doctype == "Purchase Invoice": + auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) + + if auto_accounting_for_stock: + stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") + + stock_items = self.get_stock_items() if hasattr(self, "items"): parent_dict = {} @@ -170,6 +178,15 @@ class AccountsController(TransactionBase): if item.price_list_rate: item.rate = flt(item.price_list_rate * (1.0 - (flt(item.discount_percentage) / 100.0)), item.precision("rate")) + + if self.doctype == "Purchase Invoice": + if auto_accounting_for_stock and item.item_code in stock_items \ + and self.is_opening == 'No' \ + and (not item.po_detail or not frappe.db.get_value("Purchase Order Item", + item.po_detail, "delivered_by_supplier")): + + item.expense_account = stock_not_billed_account + item.cost_center = None def set_taxes(self): if not self.meta.get_field("taxes"):