From b2206d11554f45dc811b42a7121c91d40a49b5b1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jan 2016 15:43:12 +0530 Subject: [PATCH 1/3] [fix] Multi currency advance payment against Order --- .../doctype/payment_tool/payment_tool.js | 4 +++ .../doctype/payment_tool/payment_tool.py | 4 ++- .../purchase_order/purchase_order.json | 28 ++++++++++++++- erpnext/controllers/accounts_controller.py | 34 ++++++++++++------- .../doctype/sales_order/sales_order.json | 29 ++++++++++++++-- 5 files changed, 83 insertions(+), 16 deletions(-) diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.js b/erpnext/accounts/doctype/payment_tool/payment_tool.js index ec15b47eb1b..e15694c9317 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.js +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.js @@ -42,6 +42,10 @@ frappe.ui.form.on("Payment Tool", "refresh", function(frm) { frappe.ui.form.trigger("Payment Tool", "party_type"); }); +frappe.ui.form.on("Payment Tool", "party_type", function(frm) { + frm.set_value("received_or_paid", frm.doc.party_type=="Customer" ? "Received" : "Paid"); +}); + frappe.ui.form.on("Payment Tool", "party", function(frm) { if(frm.doc.party_type && frm.doc.party) { return frappe.call({ diff --git a/erpnext/accounts/doctype/payment_tool/payment_tool.py b/erpnext/accounts/doctype/payment_tool/payment_tool.py index 19527d3a1d9..36483067a13 100644 --- a/erpnext/accounts/doctype/payment_tool/payment_tool.py +++ b/erpnext/accounts/doctype/payment_tool/payment_tool.py @@ -71,7 +71,9 @@ class PaymentTool(Document): d2.account = self.payment_account d2.account_currency = bank_account_currency d2.account_type = bank_account_type - d2.exchange_rate = get_exchange_rate(self.payment_account, self.company) + d2.exchange_rate = get_exchange_rate(self.payment_account, bank_account_currency, self.company, + debit=(abs(total_payment_amount) if total_payment_amount < 0 else 0), + credit=(total_payment_amount if total_payment_amount > 0 else 0)) d2.account_balance = get_balance_on(self.payment_account) amount_field_bank = 'debit_in_account_currency' if total_payment_amount < 0 \ diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 277229a3be1..69e518539d7 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1610,6 +1610,7 @@ "label": "Advance Paid", "length": 0, "no_copy": 1, + "options": "party_account_currency", "permlevel": 0, "print_hide": 1, "print_hide_if_no_value": 0, @@ -1968,6 +1969,31 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "party_account_currency", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Party Account Currency", + "length": 0, + "no_copy": 1, + "options": "Currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -2508,7 +2534,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-15 04:13:35.179163", + "modified": "2016-01-27 15:15:05.213016", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 81e5f9e1da4..b8acf68ddf5 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -386,27 +386,37 @@ class AccountsController(TransactionBase): def set_total_advance_paid(self): if self.doctype == "Sales Order": dr_or_cr = "credit_in_account_currency" + party = self.customer else: dr_or_cr = "debit_in_account_currency" + party = self.supplier - advance_paid = frappe.db.sql(""" + advance = frappe.db.sql(""" select - sum({dr_or_cr}) + account_currency, sum({dr_or_cr}) as amount from `tabJournal Entry Account` where - reference_type = %s and reference_name = %s + reference_type = %s and reference_name = %s and party=%s and docstatus = 1 and is_advance = "Yes" - """.format(dr_or_cr=dr_or_cr), (self.doctype, self.name)) + """.format(dr_or_cr=dr_or_cr), (self.doctype, self.name, party), as_dict=1) - if advance_paid: - advance_paid = flt(advance_paid[0][0], self.precision("advance_paid")) - if flt(self.base_grand_total) >= advance_paid: - frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid) - else: - frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater \ - than the Grand Total ({2})") - .format(advance_paid, self.name, self.base_grand_total)) + if advance: + advance_paid = flt(advance[0].amount, self.precision("advance_paid")) + + frappe.db.set_value(self.doctype, self.name, "party_account_currency", + advance[0].account_currency) + + if advance[0].account_currency == self.currency: + order_total = self.grand_total + else: + order_total = self.base_grand_total + + if order_total >= advance_paid: + frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid) + else: + frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})") + .format(advance_paid, self.name, order_total)) @property def company_abbr(self): diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index ee97334ad20..fa21f0eafff 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1569,7 +1569,7 @@ "label": "Advance Paid", "length": 0, "no_copy": 1, - "options": "Company:company:default_currency", + "options": "party_account_currency", "permlevel": 0, "print_hide": 1, "print_hide_if_no_value": 0, @@ -1959,6 +1959,31 @@ "unique": 0, "width": "150px" }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "party_account_currency", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Party Account Currency", + "length": 0, + "no_copy": 1, + "options": "Currency", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -2802,7 +2827,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-12-29 12:32:45.649349", + "modified": "2016-01-27 15:16:00.560261", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order", From ee8f88d6414efff4edc1d4a70017fa1f95561f45 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jan 2016 16:01:31 +0530 Subject: [PATCH 2/3] [patch] Set party account currency in existing orders --- erpnext/patches.txt | 1 + erpnext/patches/v6_20/__init__.py | 0 .../set_party_account_currency_in_orders.py | 24 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 erpnext/patches/v6_20/__init__.py create mode 100644 erpnext/patches/v6_20/set_party_account_currency_in_orders.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 7b079974d01..f0e12e0c85b 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -245,3 +245,4 @@ erpnext.patches.v6_12.set_overdue_tasks erpnext.patches.v6_16.update_billing_status_in_dn_and_pr erpnext.patches.v6_16.create_manufacturer_records execute:frappe.db.sql("update `tabPricing Rule` set title=name where title='' or title is null") #2016-01-27 +erpnext.patches.v6_20.set_party_account_currency_in_orders \ No newline at end of file diff --git a/erpnext/patches/v6_20/__init__.py b/erpnext/patches/v6_20/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/patches/v6_20/set_party_account_currency_in_orders.py b/erpnext/patches/v6_20/set_party_account_currency_in_orders.py new file mode 100644 index 00000000000..ae7ad9592df --- /dev/null +++ b/erpnext/patches/v6_20/set_party_account_currency_in_orders.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 + +def execute(): + for doctype in ("Sales Order", "Purchase Order"): + frappe.reload_doctype(doctype) + + for order in frappe.db.sql("""select name, {0} as party from `tab{1}` + where advance_paid > 0 and docstatus=1""" + .format(("customer" if doctype=="Sales Order" else "supplier"), doctype), as_dict=1): + + party_account_currency = frappe.db.get_value("Journal Entry Account", { + "reference_type": doctype, + "reference_name": order.name, + "party": order.party, + "docstatus": 1, + "is_advance": "Yes" + }, "account_currency") + + frappe.db.set_value(doctype, order.name, "party_account_currency", party_account_currency) + \ No newline at end of file From 7c0a58ac3f1af3e1dde950c835fc16032a0f9807 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jan 2016 12:16:24 +0530 Subject: [PATCH 3/3] [fix] show formatted currency value in advance paid validation --- .../doctype/journal_entry/journal_entry.py | 12 +++-- .../purchase_order/purchase_order.json | 50 +++++++++---------- erpnext/controllers/accounts_controller.py | 25 ++++++---- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 25b05cb1d94..55e846be524 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -209,9 +209,7 @@ class JournalEntry(AccountsController): account = self.reference_accounts[reference_name] if reference_type in ("Sales Order", "Purchase Order"): - order = frappe.db.get_value(reference_type, reference_name, - ["docstatus", "per_billed", "status", "advance_paid", - "base_grand_total", "grand_total", "currency"], as_dict=1) + order = frappe.get_doc(reference_type, reference_name) if order.docstatus != 1: frappe.throw(_("{0} {1} is not submitted").format(reference_type, reference_name)) @@ -225,12 +223,16 @@ class JournalEntry(AccountsController): account_currency = get_account_currency(account) if account_currency == self.company_currency: voucher_total = order.base_grand_total + formatted_voucher_total = fmt_money(voucher_total, order.precision("base_grand_total"), + currency=account_currency) else: voucher_total = order.grand_total + formatted_voucher_total = fmt_money(voucher_total, order.precision("grand_total"), + currency=account_currency) if flt(voucher_total) < (flt(order.advance_paid) + total): frappe.throw(_("Advance paid against {0} {1} cannot be greater \ - than Grand Total {2}").format(reference_type, reference_name, voucher_total)) + than Grand Total {2}").format(reference_type, reference_name, formatted_voucher_total)) def validate_invoices(self): """Validate totals and docstatus for invoices""" @@ -797,7 +799,7 @@ def get_exchange_rate(account, account_currency=None, company=None, company_currency = get_company_currency(company) if account_currency != company_currency: - if reference_type in ("Sales Invoice", "Purchase Invoice") and reference_name: + if reference_type and reference_name and frappe.get_meta(reference_type).get_field("conversion_rate"): exchange_rate = frappe.db.get_value(reference_type, reference_name, "conversion_rate") elif account_details and account_details.account_type == "Bank" and \ diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 69e518539d7..2cf67c1641c 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1597,30 +1597,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "fieldname": "advance_paid", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Advance Paid", - "length": 0, - "no_copy": 1, - "options": "party_account_currency", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -1695,6 +1671,30 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "advance_paid", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Advance Paid", + "length": 0, + "no_copy": 1, + "options": "party_account_currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -2534,7 +2534,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-01-27 15:15:05.213016", + "modified": "2016-01-29 01:41:08.478575", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index b8acf68ddf5..99166138758 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _, throw -from frappe.utils import today, flt, cint +from frappe.utils import today, flt, cint, fmt_money from erpnext.setup.utils import get_company_currency, get_exchange_rate from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year, get_account_currency from erpnext.utilities.transaction_base import TransactionBase @@ -402,21 +402,28 @@ class AccountsController(TransactionBase): """.format(dr_or_cr=dr_or_cr), (self.doctype, self.name, party), as_dict=1) if advance: - advance_paid = flt(advance[0].amount, self.precision("advance_paid")) - - frappe.db.set_value(self.doctype, self.name, "party_account_currency", - advance[0].account_currency) - - if advance[0].account_currency == self.currency: + advance = advance[0] + advance_paid = flt(advance.amount, self.precision("advance_paid")) + formatted_advance_paid = fmt_money(advance_paid, precision=self.precision("advance_paid"), + currency=advance.account_currency) + + frappe.db.set_value(self.doctype, self.name, "party_account_currency", + advance.account_currency) + + if advance.account_currency == self.currency: order_total = self.grand_total + formatted_order_total = fmt_money(order_total, precision=self.precision("grand_total"), + currency=advance.account_currency) else: order_total = self.base_grand_total - + formatted_order_total = fmt_money(order_total, precision=self.precision("base_grand_total"), + currency=advance.account_currency) + if order_total >= advance_paid: frappe.db.set_value(self.doctype, self.name, "advance_paid", advance_paid) else: frappe.throw(_("Total advance ({0}) against Order {1} cannot be greater than the Grand Total ({2})") - .format(advance_paid, self.name, order_total)) + .format(formatted_advance_paid, self.name, formatted_order_total)) @property def company_abbr(self):