From b3b059b0ea9fe350a4c9862cfb81261a2d740005 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jul 2015 10:49:34 +0530 Subject: [PATCH 1/7] [fix] payment reconciliation --- .../doctype/payment_reconciliation/payment_reconciliation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index ecbf78ce37..bcca0f2da1 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -192,9 +192,9 @@ class PaymentReconciliation(Document): .format(p.idx, p.allocated_amount, p.amount)) invoice_outstanding = unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number) - if abs(flt(p.allocated_amount) - invoice_outstanding) > 0.009: + if flt(p.allocated_amount) - invoice_outstanding > 0.009: frappe.throw(_("Row {0}: Allocated amount {1} must be less than or equals to invoice outstanding amount {2}") - .format(p.idx, p.allocated_amount, unreconciled_invoices.get(p.invoice_type, {}).get(p.invoice_number))) + .format(p.idx, p.allocated_amount, invoice_outstanding)) if not invoices_to_reconcile: frappe.throw(_("Please select Allocated Amount, Invoice Type and Invoice Number in atleast one row")) From 1755a5f298468ef0e61e45aee605d64a5a19ccdd Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jul 2015 11:01:39 +0530 Subject: [PATCH 2/7] [fix] get items from bom in material request --- erpnext/stock/doctype/material_request/material_request.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 4bc8fc059b..a7b9df4ec1 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -115,7 +115,7 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten d.get_input("fetch").on("click", function() { var values = d.get_values(); if(!values) return; - + values["company"] = cur_frm.doc.company; frappe.call({ method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items", args: values, From 4f2832ecd23b5e972d232d21efbbc6a6437f522b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jul 2015 11:43:50 +0530 Subject: [PATCH 3/7] [fix] Allow against purchase invoice against credit amount row --- erpnext/accounts/doctype/journal_entry/journal_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index dc620edcf0..655f718ce9 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -183,10 +183,10 @@ class JournalEntry(AccountsController): if d.get(against_field): dr_or_cr = "credit" if against_field in ["against_invoice", "against_sales_order"] \ else "debit" - if against_field in ["against_invoice", "against_sales_order"] and flt(d.debit) > 0: + if against_field == "against_sales_order" and flt(d.debit) > 0: frappe.throw(_("Row {0}: Debit entry can not be linked with a {1}").format(d.idx, doctype)) - if against_field in ["against_voucher", "against_purchase_order"] and flt(d.credit) > 0: + if against_field == "against_purchase_order" and flt(d.credit) > 0: frappe.throw(_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, doctype)) against_voucher = frappe.db.get_value(doctype, d.get(against_field), From 433cdc960d5c7a3c01ea9329c8264e73a774a4fa Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jul 2015 15:10:37 +0530 Subject: [PATCH 4/7] Update outstanding in original invoice from return invoice --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index f581faab13..6d76b5322f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -439,7 +439,7 @@ class SalesInvoice(SellingController): if gl_entries: from erpnext.accounts.general_ledger import make_gl_entries - # if POS and amount is written off, there's no outstanding and hence no need to update it + # if POS and amount is written off, updating outstanding amt after posting all gl entries update_outstanding = "No" if (cint(self.is_pos) or self.write_off_account) else "Yes" make_gl_entries(gl_entries, cancel=(self.docstatus == 2), @@ -447,7 +447,8 @@ class SalesInvoice(SellingController): if update_outstanding == "No": from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt - update_outstanding_amt(self.debit_to, "Customer", self.customer, self.doctype, self.name) + update_outstanding_amt(self.debit_to, "Customer", self.customer, + self.doctype, self.return_against if cint(self.is_return) else self.name) if repost_future_gle and cint(self.update_stock) \ and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): From 893db7a5c30cfaca9fff2a62f229fae0977897c3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jul 2015 15:11:09 +0530 Subject: [PATCH 5/7] Allow payment against invoice with negative outstanding --- .../doctype/journal_entry/journal_entry.js | 2 +- .../doctype/journal_entry/journal_entry.py | 24 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index 1ecde6493e..ec17e34bb5 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -58,7 +58,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({ filters: [ [opts[1], opts[2], "=", jvd.party], [opts[1], "docstatus", "=", 1], - [opts[1], "outstanding_amount", ">", 0] + [opts[1], "outstanding_amount", "!=", 0] ] }; }); diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 655f718ce9..4847718602 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -156,12 +156,10 @@ class JournalEntry(AccountsController): .format(d.against_jv, dr_or_cr)) def validate_against_sales_invoice(self): - payment_against_voucher = self.validate_account_in_against_voucher("against_invoice", "Sales Invoice") - self.validate_against_invoice_fields("Sales Invoice", payment_against_voucher) + self.validate_account_in_against_voucher("against_invoice", "Sales Invoice") def validate_against_purchase_invoice(self): - payment_against_voucher = self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice") - self.validate_against_invoice_fields("Purchase Invoice", payment_against_voucher) + self.validate_account_in_against_voucher("against_voucher", "Purchase Invoice") def validate_against_sales_order(self): payment_against_voucher = self.validate_account_in_against_voucher("against_sales_order", "Sales Order") @@ -210,7 +208,7 @@ class JournalEntry(AccountsController): def validate_against_invoice_fields(self, doctype, payment_against_voucher): for voucher_no, payment_list in payment_against_voucher.items(): - voucher_properties = frappe.db.get_value(doctype, voucher_no, + voucher_properties = frappe.db.get_value(doctype, voucher_no, ["docstatus", "outstanding_amount"]) if voucher_properties[0] != 1: @@ -555,18 +553,18 @@ def get_outstanding(args): and ifnull(against_jv, '')=''""".format(condition), args) against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 - if against_jv_amount > 0: - return {"credit": against_jv_amount} - else: - return {"debit": -1* against_jv_amount} - - elif args.get("doctype") == "Sales Invoice": return { - "credit": flt(frappe.db.get_value("Sales Invoice", args["docname"], "outstanding_amount")) + "credit" if against_jv_amount > 0 else "debit": abs(against_jv_amount) + } + elif args.get("doctype") == "Sales Invoice": + outstanding_amount = flt(frappe.db.get_value("Sales Invoice", args["docname"], "outstanding_amount")) + return { + "credit" if outstanding_amount > 0 else "debit": abs(outstanding_amount) } elif args.get("doctype") == "Purchase Invoice": + outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", args["docname"], "outstanding_amount")) return { - "debit": flt(frappe.db.get_value("Purchase Invoice", args["docname"], "outstanding_amount")) + "debit" if outstanding_amount > 0 else "credit": abs(outstanding_amount) } @frappe.whitelist() From ad44b00f3320350eefd91d1e7245c25a6cfc137b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 3 Aug 2015 17:43:58 +0530 Subject: [PATCH 6/7] [patch] Fix outstanding amount for original invoice for return entry --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index de26ff3f71..961d97e652 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -186,3 +186,4 @@ execute:frappe.reload_doctype("Leave Type") execute:frappe.db.sql("update `tabLeave Type` set include_holiday=0") erpnext.patches.v5_4.set_root_and_report_type erpnext.patches.v5_4.notify_system_managers_regarding_wrong_tax_calculation +erpnext.patches.v5_4.fix_invoice_outstanding From 5bbe823106eb032be4dfbc7924735e77d24a83ca Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 3 Aug 2015 18:59:25 +0530 Subject: [PATCH 7/7] [patch] Fix outstanding amount for original invoice for return entry --- .../accounts/doctype/journal_entry/journal_entry.py | 6 +++--- erpnext/controllers/sales_and_purchase_return.py | 4 +++- erpnext/patches/v5_4/fix_invoice_outstanding.py | 12 ++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/v5_4/fix_invoice_outstanding.py diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 4847718602..f0630ce91c 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -554,17 +554,17 @@ def get_outstanding(args): against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0 return { - "credit" if against_jv_amount > 0 else "debit": abs(against_jv_amount) + ("credit" if against_jv_amount > 0 else "debit"): abs(against_jv_amount) } elif args.get("doctype") == "Sales Invoice": outstanding_amount = flt(frappe.db.get_value("Sales Invoice", args["docname"], "outstanding_amount")) return { - "credit" if outstanding_amount > 0 else "debit": abs(outstanding_amount) + ("credit" if outstanding_amount > 0 else "debit"): abs(outstanding_amount) } elif args.get("doctype") == "Purchase Invoice": outstanding_amount = flt(frappe.db.get_value("Purchase Invoice", args["docname"], "outstanding_amount")) return { - "debit" if outstanding_amount > 0 else "credit": abs(outstanding_amount) + ("debit" if outstanding_amount > 0 else "credit"): abs(outstanding_amount) } @frappe.whitelist() diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 6e88bfb0d5..46a5e22dec 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -136,7 +136,9 @@ def make_return_doc(doctype, source_name, target_doc=None): "doctype": doctype + " Item", "fields": { "purchase_order": "purchase_order", - "purchase_receipt": "purchase_receipt" + "purchase_receipt": "purchase_receipt", + "serial_no": "serial_no", + "batch_no": "batch_no" }, "postprocess": update_item }, diff --git a/erpnext/patches/v5_4/fix_invoice_outstanding.py b/erpnext/patches/v5_4/fix_invoice_outstanding.py new file mode 100644 index 0000000000..81b8f2c2df --- /dev/null +++ b/erpnext/patches/v5_4/fix_invoice_outstanding.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt + +def execute(): + return_entries = frappe.get_list("Sales Invoice", filters={"is_return": 1, "docstatus": 1}, + fields=["debit_to", "customer", "return_against"]) + for d in return_entries: + update_outstanding_amt(d.debit_to, "Customer", d.customer, "Sales Invoice", d.return_against) \ No newline at end of file