From 0788ee62c1a4a092b15d100a35520fde0c5e1456 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 25 Aug 2016 12:46:34 +0530 Subject: [PATCH 1/5] Fixed patch, 'SalesInvoice' object has no attribute 'account_for_change_amount' --- erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py b/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py index ebc1e694f0..f0874a18cd 100644 --- a/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py +++ b/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py @@ -9,6 +9,8 @@ from erpnext.controllers.stock_controller import get_warehouse_account, update_g def execute(): if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): return + + frappe.reload_doc('accounts', 'doctype', 'sales_invoice') frappe.reload_doctype("Purchase Invoice") wh_account = get_warehouse_account() From efb5bf2cfccb0608ba32d6fc1b0983f55a72236f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 25 Aug 2016 02:09:53 +0530 Subject: [PATCH 2/5] [POS] Fixed payment gl entry for sales return --- .../doctype/sales_invoice/sales_invoice.py | 71 ++++++++++--------- erpnext/controllers/taxes_and_totals.py | 14 ++-- erpnext/patches.txt | 3 +- .../v7_0/repost_gle_for_pos_sales_return.py | 24 +++++++ .../public/js/controllers/taxes_and_totals.js | 15 ++-- 5 files changed, 79 insertions(+), 48 deletions(-) create mode 100644 erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 35df29955d..49af1c0c2c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -65,8 +65,8 @@ class SalesInvoice(SellingController): self.validate_fixed_asset() self.set_income_account_for_fixed_assets() - # if cint(self.is_pos): - # self.validate_pos() + if cint(self.is_pos): + self.validate_pos() if cint(self.update_stock): self.validate_dropship_item() @@ -219,6 +219,13 @@ class SalesInvoice(SellingController): timesheet.set_status() timesheet.save() + def on_update(self): + self.set_paid_amount() + + def set_paid_amount(self): + for data in self.payments: + data.base_amount = flt(data.amount*self.conversion_rate, self.precision("base_paid_amount")) + def validate_time_sheets_are_submitted(self): for data in self.timesheets: if data.time_sheet: @@ -356,11 +363,8 @@ class SalesInvoice(SellingController): throw(_("Customer {0} does not belong to project {1}").format(self.customer,self.project)) def validate_pos(self): - if not self.cash_bank_account and flt(self.paid_amount): - frappe.throw(_("Cash or Bank Account is mandatory for making payment entry")) - if flt(self.paid_amount) + flt(self.write_off_amount) \ - - flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)): + - flt(self.grand_total) > 1/(10**(self.precision("grand_total") + 1)) and self.is_return: frappe.throw(_("""Paid amount + Write Off Amount can not be greater than Grand Total""")) @@ -588,35 +592,34 @@ class SalesInvoice(SellingController): gl_entries += super(SalesInvoice, self).get_gl_entries() def make_pos_gl_entries(self, gl_entries): - if cint(self.is_pos) and self.paid_amount: + if cint(self.is_pos): for payment_mode in self.payments: - if payment_mode.base_amount > 0: - # POS, make payment entries - gl_entries.append( - self.get_gl_dict({ - "account": self.debit_to, - "party_type": "Customer", - "party": self.customer, - "against": payment_mode.account, - "credit": payment_mode.base_amount, - "credit_in_account_currency": payment_mode.base_amount \ - if self.party_account_currency==self.company_currency \ - else payment_mode.amount, - "against_voucher": self.return_against if cint(self.is_return) else self.name, - "against_voucher_type": self.doctype, - }, self.party_account_currency) - ) - - payment_mode_account_currency = get_account_currency(payment_mode.account) - gl_entries.append( - self.get_gl_dict({ - "account": payment_mode.account, - "against": self.customer, - "debit": payment_mode.base_amount, - "debit_in_account_currency": payment_mode.base_amount \ - if payment_mode_account_currency==self.company_currency else payment_mode.amount - }, payment_mode_account_currency) - ) + # POS, make payment entries + gl_entries.append( + self.get_gl_dict({ + "account": self.debit_to, + "party_type": "Customer", + "party": self.customer, + "against": payment_mode.account, + "credit": payment_mode.base_amount, + "credit_in_account_currency": payment_mode.base_amount \ + if self.party_account_currency==self.company_currency \ + else payment_mode.amount, + "against_voucher": self.return_against if cint(self.is_return) else self.name, + "against_voucher_type": self.doctype, + }, self.party_account_currency) + ) + + payment_mode_account_currency = get_account_currency(payment_mode.account) + gl_entries.append( + self.get_gl_dict({ + "account": payment_mode.account, + "against": self.customer, + "debit": payment_mode.base_amount, + "debit_in_account_currency": payment_mode.base_amount \ + if payment_mode_account_currency==self.company_currency else payment_mode.amount + }, payment_mode_account_currency) + ) def make_gle_for_change_amount(self, gl_entries): if cint(self.is_pos) and self.change_amount: diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index da803cf75e..30e21ceff1 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -420,8 +420,10 @@ class calculate_taxes_and_totals(object): # NOTE: # write_off_amount is only for POS Invoice # total_advance is only for non POS Invoice - if self.doc.is_return: - return + if self.doc.doctype == "Sales Invoice": + self.calculate_paid_amount() + + if self.doc.is_return: return self.doc.round_floats_in(self.doc, ["grand_total", "total_advance", "write_off_amount"]) self._set_in_company_currency(self.doc, ['write_off_amount']) @@ -435,7 +437,6 @@ class calculate_taxes_and_totals(object): - flt(self.doc.base_write_off_amount), self.doc.precision("grand_total")) if self.doc.doctype == "Sales Invoice": - self.calculate_paid_amount() self.doc.round_floats_in(self.doc, ["paid_amount"]) paid_amount = self.doc.paid_amount \ if self.doc.party_account_currency == self.doc.currency else self.doc.base_paid_amount @@ -452,10 +453,9 @@ class calculate_taxes_and_totals(object): def calculate_paid_amount(self): paid_amount = base_paid_amount = 0.0 for payment in self.doc.get('payments'): - if flt(payment.amount) > 0: - payment.base_amount = flt(payment.amount * self.doc.conversion_rate) - paid_amount += payment.amount - base_paid_amount += payment.base_amount + payment.base_amount = flt(payment.amount * self.doc.conversion_rate) + paid_amount += payment.amount + base_paid_amount += payment.base_amount self.doc.paid_amount = flt(paid_amount, self.doc.precision("paid_amount")) self.doc.base_paid_amount = flt(base_paid_amount, self.doc.precision("base_paid_amount")) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ef9f4da5ab..76a2409351 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -310,4 +310,5 @@ erpnext.patches.v7_0.set_material_request_type_in_item erpnext.patches.v7_0.rename_examination_to_assessment erpnext.patches.v7_0.set_portal_settings erpnext.patches.v7_0.repost_future_gle_for_purchase_invoice -erpnext.patches.v7_0.fix_duplicate_icons \ No newline at end of file +erpnext.patches.v7_0.fix_duplicate_icons +erpnext.patches.v7_0.repost_gle_for_pos_sales_return \ No newline at end of file diff --git a/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py new file mode 100644 index 0000000000..3d7b43cebb --- /dev/null +++ b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py @@ -0,0 +1,24 @@ +# 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 frappe.utils import cint + +def execute(): + frappe.reload_doctype("Sales Invoice") + + for si in frappe.get_all("Sales Invoice", fields = ["name"], + filters={"docstatus": 1, "is_pos": 1, "is_return": 1}): + si_doc = frappe.get_doc("Sales Invoice", si.name) + if len(si_doc.payments) > 0: + delete_gle_for_voucher(si_doc.name) + si_doc.set_paid_amount() + si_doc.flags.ignore_validate_update_after_submit = True + si_doc.save() + si_doc.run_method("make_gl_entries") + +def delete_gle_for_voucher(voucher_no): + frappe.db.sql("""delete from `tabGL Entry` where voucher_no = %(voucher_no)s""", + {'voucher_no': voucher_no}) + \ No newline at end of file diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index c3f4b70043..06c2b3b4b6 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -532,6 +532,11 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ // NOTE: // paid_amount and write_off_amount is only for POS Invoice // total_advance is only for non POS Invoice + + if(this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.is_return){ + this.calculate_paid_amount() + } + if(this.frm.doc.is_return || this.frm.doc.docstatus > 0) return; frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]); @@ -594,11 +599,9 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ var me = this; var paid_amount = base_paid_amount = 0.0; $.each(this.frm.doc['payments'] || [], function(index, data){ - if(data.amount > -1){ - data.base_amount = flt(data.amount * me.frm.doc.conversion_rate); - paid_amount += data.amount; - base_paid_amount += data.base_amount; - } + data.base_amount = flt(data.amount * me.frm.doc.conversion_rate); + paid_amount += data.amount; + base_paid_amount += data.base_amount; }) this.frm.doc.paid_amount = flt(paid_amount, precision("paid_amount")); @@ -607,7 +610,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ calculate_change_amount: function(){ this.frm.doc.change_amount = 0.0; - if(this.frm.doc.paid_amount > this.frm.doc.grand_total){ + if(this.frm.doc.paid_amount > this.frm.doc.grand_total && !this.frm.doc.is_return){ this.frm.doc.change_amount = flt(this.frm.doc.paid_amount - this.frm.doc.grand_total + this.frm.doc.write_off_amount, precision("change_amount")); } From 47a3f639ed4f94834786424dd0872e6f2734e285 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 26 Aug 2016 11:39:23 +0530 Subject: [PATCH 3/5] Ignore validating billed amount against order if order item amount is zero --- .../doctype/purchase_invoice/purchase_invoice.json | 14 +++++++------- erpnext/controllers/status_updater.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 930f25f070..836a2e0b49 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -252,17 +252,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "bill_date", + "fieldname": "due_date", "fieldtype": "Date", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 1, "in_list_view": 0, - "label": "Supplier Invoice Date", + "label": "Due Date", "length": 0, "no_copy": 0, - "oldfieldname": "bill_date", + "oldfieldname": "due_date", "oldfieldtype": "Date", "permlevel": 0, "print_hide": 1, @@ -278,17 +278,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "due_date", + "fieldname": "bill_date", "fieldtype": "Date", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 1, "in_list_view": 0, - "label": "Due Date", + "label": "Supplier Invoice Date", "length": 0, "no_copy": 0, - "oldfieldname": "due_date", + "oldfieldname": "bill_date", "oldfieldtype": "Date", "permlevel": 0, "print_hide": 1, @@ -3032,7 +3032,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2016-08-10 02:45:28.746569", + "modified": "2016-08-24 12:50:15.777689", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 2c25f5cd74..ccbf377901 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -142,7 +142,7 @@ class StatusUpdater(Document): if item['reduce_by'] > .01: self.limits_crossed_error(args, item) - else: + elif item[args['target_ref_field']]: self.check_overflow_with_tolerance(item, args) def check_overflow_with_tolerance(self, item, args): From e21e1ebae2987f6dd60510a586d1e2f852d50249 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 26 Aug 2016 12:06:27 +0530 Subject: [PATCH 4/5] [Sales Return] Minor fix in patch --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 7 +++++++ erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 49af1c0c2c..b28911edef 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -223,8 +223,15 @@ class SalesInvoice(SellingController): self.set_paid_amount() def set_paid_amount(self): + paid_amount = 0.0 + base_paid_amount = 0.0 for data in self.payments: data.base_amount = flt(data.amount*self.conversion_rate, self.precision("base_paid_amount")) + paid_amount += data.amount + base_paid_amount += data.base_amount + + self.paid_amount = paid_amount + self.base_paid_amount = base_paid_amount def validate_time_sheets_are_submitted(self): for data in self.timesheets: diff --git a/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py index 3d7b43cebb..d3dd2e9aa6 100644 --- a/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py +++ b/erpnext/patches/v7_0/repost_gle_for_pos_sales_return.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cint +from frappe.utils import cint, flt def execute(): frappe.reload_doctype("Sales Invoice") @@ -12,13 +12,13 @@ def execute(): filters={"docstatus": 1, "is_pos": 1, "is_return": 1}): si_doc = frappe.get_doc("Sales Invoice", si.name) if len(si_doc.payments) > 0: - delete_gle_for_voucher(si_doc.name) si_doc.set_paid_amount() si_doc.flags.ignore_validate_update_after_submit = True si_doc.save() - si_doc.run_method("make_gl_entries") + if si_doc.grand_total <= si_doc.paid_amount and si_doc.paid_amount < 0: + delete_gle_for_voucher(si_doc.name) + si_doc.run_method("make_gl_entries") def delete_gle_for_voucher(voucher_no): frappe.db.sql("""delete from `tabGL Entry` where voucher_no = %(voucher_no)s""", {'voucher_no': voucher_no}) - \ No newline at end of file From 6592899741bfcd5c8553802b28e40064c8128066 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 26 Aug 2016 13:07:19 +0600 Subject: [PATCH 5/5] bumped to version 7.0.33 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 6b59a1891b..5bb93cbeff 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import frappe -__version__ = '7.0.32' +__version__ = '7.0.33' def get_default_company(user=None): '''Get default company for user'''