[fix] Remove party_account_currency from Customer and Supplier, and use currency derived from get_party_account

This commit is contained in:
Anand Doshi 2015-09-25 16:17:50 +05:30
parent d3cf4f1264
commit b20baf894f
14 changed files with 1548 additions and 1687 deletions

View File

@ -3,11 +3,10 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import flt, fmt_money, getdate, formatdate
from frappe import _ from frappe import _
from frappe.utils import flt, fmt_money, getdate, formatdate
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.accounts.party import get_party_account_currency
class CustomerFrozen(frappe.ValidationError): pass class CustomerFrozen(frappe.ValidationError): pass
class InvalidCurrency(frappe.ValidationError): pass class InvalidCurrency(frappe.ValidationError): pass
@ -114,8 +113,7 @@ class GLEntry(Document):
if self.party_type and self.party: if self.party_type and self.party:
party_account_currency = frappe.db.get_value(self.party_type, self.party, "party_account_currency") \ party_account_currency = get_party_account_currency(self.party_type, self.party, self.company)
or company_currency
if party_account_currency != self.account_currency: if party_account_currency != self.account_currency:
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}") frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")

View File

@ -7,6 +7,7 @@ from frappe.utils import cstr, flt, fmt_money, formatdate
from frappe import msgprint, _, scrub from frappe import msgprint, _, scrub
from erpnext.controllers.accounts_controller import AccountsController from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.utils import get_balance_on from erpnext.accounts.utils import get_balance_on
from erpnext.accounts.party import get_party_account_currency
from erpnext.setup.utils import get_company_currency from erpnext.setup.utils import get_company_currency
@ -212,7 +213,7 @@ class JournalEntry(AccountsController):
if cstr(order.status) == "Stopped": if cstr(order.status) == "Stopped":
frappe.throw(_("{0} {1} is stopped").format(reference_type, reference_name)) frappe.throw(_("{0} {1} is stopped").format(reference_type, reference_name))
party_account_currency = frappe.db.get_value(party_type, party, "party_account_currency") party_account_currency = get_party_account_currency(party_type, party, self.company)
if party_account_currency == self.company_currency: if party_account_currency == self.company_currency:
voucher_total = order.base_grand_total voucher_total = order.base_grand_total
else: else:
@ -609,7 +610,7 @@ def get_payment_entry_from_sales_order(sales_order):
jv = get_payment_entry(so) jv = get_payment_entry(so)
jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name) jv.remark = 'Advance payment received against Sales Order {0}.'.format(so.name)
party_account = get_party_account(so.company, so.customer, "Customer") party_account = get_party_account("Customer", so.customer, so.company)
party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") party_account_currency = frappe.db.get_value("Account", party_account, "account_currency")
exchange_rate = get_exchange_rate(party_account, party_account_currency, so.company) exchange_rate = get_exchange_rate(party_account, party_account_currency, so.company)
@ -660,7 +661,7 @@ def get_payment_entry_from_purchase_order(purchase_order):
jv = get_payment_entry(po) jv = get_payment_entry(po)
jv.remark = 'Advance payment made against Purchase Order {0}.'.format(po.name) jv.remark = 'Advance payment made against Purchase Order {0}.'.format(po.name)
party_account = get_party_account(po.company, po.supplier, "Supplier") party_account = get_party_account("Supplier", po.supplier, po.company)
party_account_currency = frappe.db.get_value("Account", party_account, "account_currency") party_account_currency = frappe.db.get_value("Account", party_account, "account_currency")
exchange_rate = get_exchange_rate(party_account, party_account_currency, po.company) exchange_rate = get_exchange_rate(party_account, party_account_currency, po.company)
@ -779,7 +780,7 @@ def get_party_account_and_balance(company, party_type, party):
frappe.msgprint(_("No Permission"), raise_exception=1) frappe.msgprint(_("No Permission"), raise_exception=1)
from erpnext.accounts.party import get_party_account from erpnext.accounts.party import get_party_account
account = get_party_account(company, party, party_type) account = get_party_account(party_type, party, company)
account_balance = get_balance_on(account=account) account_balance = get_balance_on(account=account)
party_balance = get_balance_on(party_type=party_type, party=party) party_balance = get_balance_on(party_type=party_type, party=party)

View File

@ -66,7 +66,7 @@ class PurchaseInvoice(BuyingController):
def set_missing_values(self, for_validate=False): def set_missing_values(self, for_validate=False):
if not self.credit_to: if not self.credit_to:
self.credit_to = get_party_account(self.company, self.supplier, "Supplier") self.credit_to = get_party_account("Supplier", self.supplier, self.company)
if not self.due_date: if not self.due_date:
self.due_date = get_due_date(self.posting_date, "Supplier", self.supplier, self.company) self.due_date = get_due_date(self.posting_date, "Supplier", self.supplier, self.company)

View File

@ -186,7 +186,7 @@ class SalesInvoice(SellingController):
pos = self.set_pos_fields(for_validate) pos = self.set_pos_fields(for_validate)
if not self.debit_to: if not self.debit_to:
self.debit_to = get_party_account(self.company, self.customer, "Customer") self.debit_to = get_party_account("Customer", self.customer, self.company)
if not self.due_date and self.customer: if not self.due_date and self.customer:
self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company) self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company)

View File

@ -142,7 +142,7 @@ def set_account_and_due_date(party, account, party_type, company, posting_date,
} }
if party: if party:
account = get_party_account(company, party, party_type) account = get_party_account(party_type, party, company)
account_fieldname = "debit_to" if party_type=="Customer" else "credit_to" account_fieldname = "debit_to" if party_type=="Customer" else "credit_to"
@ -153,44 +153,6 @@ def set_account_and_due_date(party, account, party_type, company, posting_date,
} }
return out return out
def validate_accounting_currency(party):
party_account_currency_in_db = frappe.db.get_value(party.doctype, party.name, "party_account_currency")
if party_account_currency_in_db != party.party_account_currency:
existing_gle = frappe.db.get_value("GL Entry", {"party_type": party.doctype,
"party": party.name}, ["name", "account_currency"], as_dict=1)
if existing_gle:
if party_account_currency_in_db:
frappe.throw(_("Accounting Currency cannot be changed, as GL Entry exists for this {0}")
.format(party.doctype), InvalidCurrency)
else:
party.party_account_currency = existing_gle.account_currency
def validate_party_account(party):
company_currency = get_company_currency()
if party.party_account_currency:
companies_with_different_currency = []
for company, currency in company_currency.items():
if currency != party.party_account_currency:
companies_with_different_currency.append(company)
for d in party.get("accounts"):
if d.company in companies_with_different_currency:
companies_with_different_currency.remove(d.company)
selected_account_currency = frappe.db.get_value("Account", d.account, "account_currency")
if selected_account_currency != party.party_account_currency:
frappe.throw(_("Account {0} is invalid, account currency must be {1}")
.format(d.account, selected_account_currency), InvalidAccountCurrency)
if companies_with_different_currency:
frappe.msgprint(_("Please mention Default {0} Account for the following companies, as accounting currency is different from company's default currency: {1}")
.format(
"Receivable" if party.doctype=="Customer" else "Payable",
"\n" + "\n".join(companies_with_different_currency)
)
)
def get_company_currency(): def get_company_currency():
company_currency = frappe._dict() company_currency = frappe._dict()
for d in frappe.get_all("Company", fields=["name", "default_currency"]): for d in frappe.get_all("Company", fields=["name", "default_currency"]):
@ -199,13 +161,13 @@ def get_company_currency():
return company_currency return company_currency
@frappe.whitelist() @frappe.whitelist()
def get_party_account(company, party, party_type): def get_party_account(party_type, party, company):
"""Returns the account for the given `party`. """Returns the account for the given `party`.
Will first search in party (Customer / Supplier) record, if not found, Will first search in party (Customer / Supplier) record, if not found,
will search in group (Customer Group / Supplier Type), will search in group (Customer Group / Supplier Type),
finally will return default.""" finally will return default."""
if not company: if not company:
frappe.throw(_("Please select company first.")) frappe.throw(_("Please select a Company"))
if party: if party:
account = frappe.db.get_value("Party Account", account = frappe.db.get_value("Party Account",
@ -223,6 +185,13 @@ def get_party_account(company, party, party_type):
return account return account
def get_party_account_currency(party_type, party, company):
def generator():
party_account = get_party_account(party_type, party, company)
return frappe.db.get_value("Account", party_account, "account_currency")
return frappe.local_cache("party_account_currency", (party_type, party, company), generator)
@frappe.whitelist() @frappe.whitelist()
def get_due_date(posting_date, party_type, party, company): def get_due_date(posting_date, party_type, party, company):
"""Set Due Date = Posting Date + Credit Days""" """Set Due Date = Posting Date + Credit Days"""

View File

@ -385,29 +385,6 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Accounting Currency",
"no_copy": 0,
"options": "Currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -534,7 +511,7 @@
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"modified": "2015-09-17 14:05:24.793609", "modified": "2015-09-25 06:34:56.909099",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Supplier", "name": "Supplier",

View File

@ -8,7 +8,6 @@ from frappe import msgprint, _
from frappe.model.naming import make_autoname from frappe.model.naming import make_autoname
from erpnext.utilities.address_and_contact import load_address_and_contact from erpnext.utilities.address_and_contact import load_address_and_contact
from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import validate_accounting_currency, validate_party_account
class Supplier(TransactionBase): class Supplier(TransactionBase):
def get_feed(self): def get_feed(self):
@ -46,9 +45,6 @@ class Supplier(TransactionBase):
if not self.naming_series: if not self.naming_series:
msgprint(_("Series is mandatory"), raise_exception=1) msgprint(_("Series is mandatory"), raise_exception=1)
validate_accounting_currency(self)
validate_party_account(self)
def get_contacts(self,nm): def get_contacts(self,nm):
if nm: if nm:
contact_details =frappe.db.convert_to_lists(frappe.db.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = %s", nm)) contact_details =frappe.db.convert_to_lists(frappe.db.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = %s", nm))

View File

@ -13,7 +13,6 @@
"doctype": "Supplier", "doctype": "Supplier",
"supplier_name": "_Test Supplier USD", "supplier_name": "_Test Supplier USD",
"supplier_type": "_Test Supplier Type", "supplier_type": "_Test Supplier Type",
"party_account_currency": "USD",
"accounts": [{ "accounts": [{
"company": "_Test Company", "company": "_Test Company",
"account": "_Test Payable USD - _TC" "account": "_Test Payable USD - _TC"

View File

@ -10,6 +10,7 @@ from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.transaction_base import TransactionBase
from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
from erpnext.controllers.sales_and_purchase_return import validate_return from erpnext.controllers.sales_and_purchase_return import validate_return
from erpnext.accounts.party import get_party_account_currency
force_item_fields = ("item_group", "barcode", "brand", "stock_uom") force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
@ -427,8 +428,7 @@ class AccountsController(TransactionBase):
if self.get("currency"): if self.get("currency"):
party_type, party = self.get_party() party_type, party = self.get_party()
if party_type and party: if party_type and party:
party_account_currency = frappe.db.get_value(party_type, party, "party_account_currency") \ party_account_currency = get_party_account_currency(party_type, party, self.company)
or self.company_currency
if party_account_currency != self.company_currency and self.currency != party_account_currency: if party_account_currency != self.company_currency and self.currency != party_account_currency:
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}") frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")

View File

@ -7,8 +7,8 @@ from frappe.utils import cstr, cint
from frappe import msgprint, _ from frappe import msgprint, _
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import get_party_account_currency
subject_field = "title" subject_field = "title"
sender_field = "contact_email" sender_field = "contact_email"
@ -182,7 +182,8 @@ def make_quotation(source_name, target_doc=None):
quotation = frappe.get_doc(target) quotation = frappe.get_doc(target)
company_currency = frappe.db.get_value("Company", quotation.company, "default_currency") company_currency = frappe.db.get_value("Company", quotation.company, "default_currency")
party_account_currency = frappe.db.get_value("Customer", quotation.customer, "party_account_currency") party_account_currency = get_party_account_currency("Customer", quotation.customer, quotation.company)
if company_currency == party_account_currency: if company_currency == party_account_currency:
exchange_rate = 1 exchange_rate = 1
else: else:

View File

@ -63,56 +63,3 @@ def execute():
where where
company=%s company=%s
""", (company.default_currency, company.name)) """, (company.default_currency, company.name))
# Set party account if default currency of party other than company's default currency
for dt in ("Customer", "Supplier"):
parties = frappe.get_all(dt, filters={"docstatus": 0})
for p in parties:
party = frappe.get_doc(dt, p.name)
party_accounts = []
for company in company_list:
# Get party GL Entries
party_gle = frappe.db.get_value("GL Entry", {"party_type": dt, "party": p.name,
"company": company.name}, ["account", "account_currency", "name"], as_dict=True)
# set party account currency
if party_gle:
party.party_account_currency = party_gle.account_currency
elif not party.party_account_currency:
party.party_account_currency = company.default_currency
# Add default receivable /payable account if not exists
# and currency is other than company currency
if party.party_account_currency and party.party_account_currency != company.default_currency:
party_account_exists_for_company = False
for d in party.get("accounts"):
if d.company == company.name:
account_currency = frappe.db.get_value("Account", d.account, "account_currency")
if account_currency == party.party_account_currency:
party_accounts.append({
"company": d.company,
"account": d.account
})
party_account_exists_for_company = True
break
if not party_account_exists_for_company:
party_account = None
if party_gle:
party_account = party_gle.account
else:
default_receivable_account_currency = frappe.db.get_value("Account",
company.default_receivable_account, "account_currency")
if default_receivable_account_currency != company.default_currency:
party_account = company.default_receivable_account
if party_account:
party_accounts.append({
"company": company.name,
"account": party_account
})
party.set("accounts", party_accounts)
party.flags.ignore_mandatory = True
party.save()

View File

@ -459,29 +459,6 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Accounting Currency",
"no_copy": 0,
"options": "Currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -819,7 +796,7 @@
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"modified": "2015-09-17 14:05:38.541266", "modified": "2015-09-25 06:25:13.944742",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Customer", "name": "Customer",

View File

@ -10,7 +10,6 @@ from frappe.utils import flt
from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.transaction_base import TransactionBase
from erpnext.utilities.address_and_contact import load_address_and_contact from erpnext.utilities.address_and_contact import load_address_and_contact
from erpnext.accounts.party import validate_accounting_currency, validate_party_account
from frappe.desk.reportview import build_match_conditions from frappe.desk.reportview import build_match_conditions
class Customer(TransactionBase): class Customer(TransactionBase):
@ -33,8 +32,6 @@ class Customer(TransactionBase):
def validate(self): def validate(self):
self.flags.is_new_doc = self.is_new() self.flags.is_new_doc = self.is_new()
validate_accounting_currency(self)
validate_party_account(self)
def update_lead_status(self): def update_lead_status(self):
if self.lead_name: if self.lead_name:

View File

@ -33,7 +33,6 @@
"customer_type": "Individual", "customer_type": "Individual",
"doctype": "Customer", "doctype": "Customer",
"territory": "_Test Territory", "territory": "_Test Territory",
"party_account_currency": "USD",
"accounts": [{ "accounts": [{
"company": "_Test Company", "company": "_Test Company",
"account": "_Test Receivable USD - _TC" "account": "_Test Receivable USD - _TC"