Merge pull request #4067 from anandpdoshi/remove-party-account-currency
Remove party_account_currency from Customer and Supplier, and use currency derived from get_party_account
This commit is contained in:
commit
c320fe541d
@ -207,3 +207,14 @@ def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
and %s like %s order by name limit %s, %s""" %
|
and %s like %s order by name limit %s, %s""" %
|
||||||
("%s", searchfield, "%s", "%s", "%s"),
|
("%s", searchfield, "%s", "%s", "%s"),
|
||||||
(filters["company"], "%%%s%%" % txt, start, page_len), as_list=1)
|
(filters["company"], "%%%s%%" % txt, start, page_len), as_list=1)
|
||||||
|
|
||||||
|
def get_account_currency(account):
|
||||||
|
"""Helper function to get account currency"""
|
||||||
|
def generator():
|
||||||
|
account_currency, company = frappe.db.get_value("Account", account, ["account_currency", "company"])
|
||||||
|
if not account_currency:
|
||||||
|
account_currency = frappe.db.get_value("Company", company, "default_currency")
|
||||||
|
|
||||||
|
return account_currency
|
||||||
|
|
||||||
|
return frappe.local_cache("account_currency", account, generator)
|
||||||
|
|||||||
@ -3,15 +3,13 @@
|
|||||||
|
|
||||||
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 validate_party_gle_currency, get_party_account_currency
|
||||||
class CustomerFrozen(frappe.ValidationError): pass
|
from erpnext.accounts.utils import get_account_currency
|
||||||
class InvalidCurrency(frappe.ValidationError): pass
|
from erpnext.setup.doctype.company.company import get_company_currency
|
||||||
class InvalidAccountCurrency(frappe.ValidationError): pass
|
from erpnext.exceptions import InvalidAccountCurrency, CustomerFrozen
|
||||||
|
|
||||||
class GLEntry(Document):
|
class GLEntry(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -103,24 +101,25 @@ class GLEntry(Document):
|
|||||||
frappe.throw("{0} {1} is frozen".format(self.party_type, self.party), CustomerFrozen)
|
frappe.throw("{0} {1} is frozen".format(self.party_type, self.party), CustomerFrozen)
|
||||||
|
|
||||||
def validate_currency(self):
|
def validate_currency(self):
|
||||||
company_currency = frappe.db.get_value("Company", self.company, "default_currency")
|
company_currency = get_company_currency(self.company)
|
||||||
account_currency = frappe.db.get_value("Account", self.account, "account_currency") or company_currency
|
account_currency = get_account_currency(self.account)
|
||||||
|
|
||||||
if not self.account_currency:
|
if not self.account_currency:
|
||||||
self.account_currency = company_currency
|
self.account_currency = company_currency
|
||||||
|
|
||||||
if account_currency != self.account_currency:
|
if account_currency != self.account_currency:
|
||||||
frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
|
frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
|
||||||
.format(self.account, (account_currency or company_currency)), InvalidAccountCurrency)
|
.format(self.account, (account_currency or company_currency)), InvalidAccountCurrency)
|
||||||
|
|
||||||
|
|
||||||
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}")
|
||||||
.format(self.party_type, self.party, party_account_currency), InvalidAccountCurrency)
|
.format(self.party_type, self.party, party_account_currency), InvalidAccountCurrency)
|
||||||
|
|
||||||
|
validate_party_gle_currency(self.party_type, self.party, self.company)
|
||||||
|
|
||||||
def validate_balance_type(account, adv_adj=False):
|
def validate_balance_type(account, adv_adj=False):
|
||||||
if not adv_adj and account:
|
if not adv_adj and account:
|
||||||
balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
|
balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
|
||||||
|
|||||||
@ -6,7 +6,8 @@ import frappe
|
|||||||
from frappe.utils import cstr, flt, fmt_money, formatdate
|
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, get_account_currency
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
@ -146,7 +147,7 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
self.reference_totals = {}
|
self.reference_totals = {}
|
||||||
self.reference_types = {}
|
self.reference_types = {}
|
||||||
self.reference_parties = {}
|
self.reference_accounts = {}
|
||||||
|
|
||||||
for d in self.get("accounts"):
|
for d in self.get("accounts"):
|
||||||
if not d.reference_type:
|
if not d.reference_type:
|
||||||
@ -169,8 +170,7 @@ class JournalEntry(AccountsController):
|
|||||||
self.reference_totals[d.reference_name] = 0.0
|
self.reference_totals[d.reference_name] = 0.0
|
||||||
self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
|
self.reference_totals[d.reference_name] += flt(d.get(dr_or_cr))
|
||||||
self.reference_types[d.reference_name] = d.reference_type
|
self.reference_types[d.reference_name] = d.reference_type
|
||||||
if d.party_type and d.party:
|
self.reference_accounts[d.reference_name] = d.account
|
||||||
self.reference_parties[d.reference_name] = [d.party_type, d.party]
|
|
||||||
|
|
||||||
against_voucher = frappe.db.get_value(d.reference_type, d.reference_name,
|
against_voucher = frappe.db.get_value(d.reference_type, d.reference_name,
|
||||||
[scrub(dt) for dt in field_dict.get(d.reference_type)])
|
[scrub(dt) for dt in field_dict.get(d.reference_type)])
|
||||||
@ -196,7 +196,7 @@ class JournalEntry(AccountsController):
|
|||||||
"""Validate totals, stopped and docstatus for orders"""
|
"""Validate totals, stopped and docstatus for orders"""
|
||||||
for reference_name, total in self.reference_totals.iteritems():
|
for reference_name, total in self.reference_totals.iteritems():
|
||||||
reference_type = self.reference_types[reference_name]
|
reference_type = self.reference_types[reference_name]
|
||||||
party_type, party = self.reference_parties.get(reference_name)
|
account = self.reference_accounts[reference_name]
|
||||||
|
|
||||||
if reference_type in ("Sales Order", "Purchase Order"):
|
if reference_type in ("Sales Order", "Purchase Order"):
|
||||||
order = frappe.db.get_value(reference_type, reference_name,
|
order = frappe.db.get_value(reference_type, reference_name,
|
||||||
@ -212,8 +212,8 @@ 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")
|
account_currency = get_account_currency(account)
|
||||||
if party_account_currency == self.company_currency:
|
if account_currency == self.company_currency:
|
||||||
voucher_total = order.base_grand_total
|
voucher_total = order.base_grand_total
|
||||||
else:
|
else:
|
||||||
voucher_total = order.grand_total
|
voucher_total = order.grand_total
|
||||||
@ -609,8 +609,8 @@ 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 = get_account_currency(party_account)
|
||||||
|
|
||||||
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,8 +660,8 @@ 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 = get_account_currency(party_account)
|
||||||
|
|
||||||
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 +779,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)
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest, frappe
|
import unittest, frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.accounts.utils import get_actual_expense, BudgetError, get_fiscal_year
|
from erpnext.accounts.utils import get_actual_expense, BudgetError, get_fiscal_year
|
||||||
|
from erpnext.exceptions import InvalidAccountCurrency
|
||||||
|
|
||||||
|
|
||||||
class TestJournalEntry(unittest.TestCase):
|
class TestJournalEntry(unittest.TestCase):
|
||||||
@ -202,8 +203,6 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEquals(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
|
|
||||||
@ -212,6 +211,40 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
|
def test_disallow_change_in_account_currency_for_a_party(self):
|
||||||
|
# create jv in USD
|
||||||
|
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||||
|
"_Test Receivable USD - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
jv.submit()
|
||||||
|
|
||||||
|
# create jv in USD, but account currency in INR
|
||||||
|
jv = make_journal_entry("_Test Bank - _TC",
|
||||||
|
"_Test Receivable - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertRaises(InvalidAccountCurrency, jv.submit)
|
||||||
|
|
||||||
|
# back in USD
|
||||||
|
jv = make_journal_entry("_Test Bank USD - _TC",
|
||||||
|
"_Test Receivable USD - _TC", 100, save=False)
|
||||||
|
|
||||||
|
jv.accounts[1].update({
|
||||||
|
"party_type": "Customer",
|
||||||
|
"party": "_Test Customer USD"
|
||||||
|
})
|
||||||
|
|
||||||
|
jv.submit()
|
||||||
|
|
||||||
def make_journal_entry(account1, account2, amount, cost_center=None, exchange_rate=1, save=True, submit=False):
|
def make_journal_entry(account1, account2, amount, cost_center=None, exchange_rate=1, save=True, submit=False):
|
||||||
jv = frappe.new_doc("Journal Entry")
|
jv = frappe.new_doc("Journal Entry")
|
||||||
jv.posting_date = "2013-02-14"
|
jv.posting_date = "2013-02-14"
|
||||||
@ -231,7 +264,7 @@ def make_journal_entry(account1, account2, amount, cost_center=None, exchange_ra
|
|||||||
"cost_center": cost_center,
|
"cost_center": cost_center,
|
||||||
"credit_in_account_currency": amount if amount > 0 else 0,
|
"credit_in_account_currency": amount if amount > 0 else 0,
|
||||||
"debit_in_account_currency": abs(amount) if amount < 0 else 0,
|
"debit_in_account_currency": abs(amount) if amount < 0 else 0,
|
||||||
exchange_rate: exchange_rate
|
"exchange_rate": exchange_rate
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
if save or submit:
|
if save or submit:
|
||||||
|
|||||||
@ -7,6 +7,7 @@ from frappe import _, scrub
|
|||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
import json
|
import json
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
class PaymentTool(Document):
|
class PaymentTool(Document):
|
||||||
def make_journal_entry(self):
|
def make_journal_entry(self):
|
||||||
@ -59,7 +60,7 @@ def get_outstanding_vouchers(args):
|
|||||||
|
|
||||||
args = json.loads(args)
|
args = json.loads(args)
|
||||||
|
|
||||||
party_account_currency = frappe.db.get_value("Account", args.get("party_account"), "account_currency")
|
party_account_currency = get_account_currency(args.get("party_account"))
|
||||||
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
||||||
|
|
||||||
if args.get("party_type") == "Customer" and args.get("received_or_paid") == "Received":
|
if args.get("party_type") == "Customer" and args.get("received_or_paid") == "Received":
|
||||||
@ -112,7 +113,7 @@ def get_orders_to_be_billed(party_type, party, party_account_currency, company_c
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_against_voucher_amount(against_voucher_type, against_voucher_no, party_account, company):
|
def get_against_voucher_amount(against_voucher_type, against_voucher_no, party_account, company):
|
||||||
party_account_currency = frappe.db.get_value("Account", party_account, "account_currency")
|
party_account_currency = get_account_currency(party_account)
|
||||||
company_currency = frappe.db.get_value("Company", company, "default_currency")
|
company_currency = frappe.db.get_value("Company", company, "default_currency")
|
||||||
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import frappe.defaults
|
|||||||
|
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
from erpnext.accounts.party import get_party_account, get_due_date
|
from erpnext.accounts.party import get_party_account, get_due_date
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -66,7 +67,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)
|
||||||
|
|
||||||
@ -272,7 +273,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
valuation_tax = {}
|
valuation_tax = {}
|
||||||
for tax in self.get("taxes"):
|
for tax in self.get("taxes"):
|
||||||
if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
|
if tax.category in ("Total", "Valuation and Total") and flt(tax.base_tax_amount_after_discount_amount):
|
||||||
account_currency = frappe.db.get_value("Account", tax.account_head, "account_currency")
|
account_currency = get_account_currency(tax.account_head)
|
||||||
|
|
||||||
dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
|
dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
stock_items = self.get_stock_items()
|
stock_items = self.get_stock_items()
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if flt(item.base_net_amount):
|
if flt(item.base_net_amount):
|
||||||
account_currency = frappe.db.get_value("Account", item.expense_account, "account_currency")
|
account_currency = get_account_currency(item.expense_account)
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account,
|
"account": item.expense_account,
|
||||||
@ -363,7 +364,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
# writeoff account includes petty difference in the invoice amount
|
# writeoff account includes petty difference in the invoice amount
|
||||||
# and the amount that is paid
|
# and the amount that is paid
|
||||||
if self.write_off_account and flt(self.write_off_amount):
|
if self.write_off_account and flt(self.write_off_amount):
|
||||||
write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "account_currency")
|
write_off_account_currency = get_account_currency(self.write_off_account)
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from frappe.utils import cint
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||||
test_records as pr_test_records
|
test_records as pr_test_records
|
||||||
from erpnext.controllers.accounts_controller import InvalidCurrency
|
from erpnext.exceptions import InvalidCurrency
|
||||||
|
|
||||||
test_dependencies = ["Item", "Cost Center"]
|
test_dependencies = ["Item", "Cost Center"]
|
||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from erpnext.controllers.stock_controller import update_gl_entries_after
|
|||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
|
||||||
from erpnext.controllers.selling_controller import SellingController
|
from erpnext.controllers.selling_controller import SellingController
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -186,7 +187,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)
|
||||||
|
|
||||||
@ -531,7 +532,7 @@ class SalesInvoice(SellingController):
|
|||||||
def make_tax_gl_entries(self, gl_entries):
|
def make_tax_gl_entries(self, gl_entries):
|
||||||
for tax in self.get("taxes"):
|
for tax in self.get("taxes"):
|
||||||
if flt(tax.base_tax_amount_after_discount_amount):
|
if flt(tax.base_tax_amount_after_discount_amount):
|
||||||
account_currency = frappe.db.get_value("Account", tax.account_head, "account_currency")
|
account_currency = get_account_currency(tax.account_head)
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": tax.account_head,
|
"account": tax.account_head,
|
||||||
@ -547,7 +548,7 @@ class SalesInvoice(SellingController):
|
|||||||
# income account gl entries
|
# income account gl entries
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if flt(item.base_net_amount):
|
if flt(item.base_net_amount):
|
||||||
account_currency = frappe.db.get_value("Account", item.income_account, "account_currency")
|
account_currency = get_account_currency(item.income_account)
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.income_account,
|
"account": item.income_account,
|
||||||
@ -566,7 +567,7 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def make_pos_gl_entries(self, gl_entries):
|
def make_pos_gl_entries(self, gl_entries):
|
||||||
if cint(self.is_pos) and self.cash_bank_account and self.paid_amount:
|
if cint(self.is_pos) and self.cash_bank_account and self.paid_amount:
|
||||||
bank_account_currency = frappe.db.get_value("Account", self.cash_bank_account, "account_currency")
|
bank_account_currency = get_account_currency(self.cash_bank_account)
|
||||||
# POS, make payment entries
|
# POS, make payment entries
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
@ -594,7 +595,7 @@ class SalesInvoice(SellingController):
|
|||||||
def make_write_off_gl_entry(self, gl_entries):
|
def make_write_off_gl_entry(self, gl_entries):
|
||||||
# write off entries, applicable if only pos
|
# write off entries, applicable if only pos
|
||||||
if self.write_off_account and self.write_off_amount:
|
if self.write_off_account and self.write_off_amount:
|
||||||
write_off_account_currency = frappe.db.get_value("Account", self.write_off_account, "account_currency")
|
write_off_account_currency = get_account_currency(self.write_off_account)
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
|
|||||||
@ -7,8 +7,7 @@ import unittest, copy
|
|||||||
from frappe.utils import nowdate, add_days, flt
|
from frappe.utils import nowdate, add_days, flt
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
from erpnext.controllers.accounts_controller import InvalidCurrency
|
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
||||||
from erpnext.accounts.doctype.gl_entry.gl_entry import InvalidAccountCurrency
|
|
||||||
|
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
|
|||||||
@ -10,9 +10,9 @@ from frappe.defaults import get_user_permissions
|
|||||||
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff
|
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff
|
||||||
from erpnext.utilities.doctype.address.address import get_address_display
|
from erpnext.utilities.doctype.address.address import get_address_display
|
||||||
from erpnext.utilities.doctype.contact.contact import get_contact_details
|
from erpnext.utilities.doctype.contact.contact import get_contact_details
|
||||||
|
from erpnext.exceptions import InvalidAccountCurrency
|
||||||
|
|
||||||
class InvalidCurrency(frappe.ValidationError): pass
|
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||||
class InvalidAccountCurrency(frappe.ValidationError): pass
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_party_details(party=None, account=None, party_type="Customer", company=None,
|
def get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||||
@ -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,42 @@ 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)
|
||||||
|
|
||||||
|
def get_party_gle_currency(party_type, party, company):
|
||||||
|
def generator():
|
||||||
|
existing_gle_currency = frappe.db.sql("""select account_currency from `tabGL Entry`
|
||||||
|
where docstatus=1 and company=%(company)s and party_type=%(party_type)s and party=%(party)s
|
||||||
|
limit 1""", { "company": company, "party_type": party_type, "party": party })
|
||||||
|
|
||||||
|
return existing_gle_currency[0][0] if existing_gle_currency else None
|
||||||
|
|
||||||
|
return frappe.local_cache("party_gle_currency", (party_type, party, company), generator)
|
||||||
|
|
||||||
|
def validate_party_gle_currency(party_type, party, company):
|
||||||
|
"""Validate party account currency with existing GL Entry's currency"""
|
||||||
|
party_account_currency = get_party_account_currency(party_type, party, company)
|
||||||
|
existing_gle_currency = get_party_gle_currency(party_type, party, company)
|
||||||
|
|
||||||
|
if existing_gle_currency and party_account_currency != existing_gle_currency:
|
||||||
|
frappe.throw(_("Accounting Entry for {0}: {1} can only be made in currency: {2}")
|
||||||
|
.format(party_type, party, existing_gle_currency), InvalidAccountCurrency)
|
||||||
|
|
||||||
|
def validate_party_accounts(doc):
|
||||||
|
companies = []
|
||||||
|
|
||||||
|
for account in doc.get("accounts"):
|
||||||
|
if account.company in companies:
|
||||||
|
frappe.throw(_("There can only be 1 Account per Company in {0} {1}").format(doc.doctype, doc.name),
|
||||||
|
DuplicatePartyAccountError)
|
||||||
|
else:
|
||||||
|
companies.append(account.company)
|
||||||
|
|
||||||
@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"""
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt, getdate, cstr
|
from frappe.utils import flt, getdate, cstr
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
account_details = {}
|
account_details = {}
|
||||||
@ -55,7 +56,7 @@ def set_account_currency(filters):
|
|||||||
account_currency = None
|
account_currency = None
|
||||||
|
|
||||||
if filters.get("account"):
|
if filters.get("account"):
|
||||||
account_currency = frappe.db.get_value("Account", filters.account, "account_currency")
|
account_currency = get_account_currency(filters.account)
|
||||||
elif filters.get("party"):
|
elif filters.get("party"):
|
||||||
gle_currency = frappe.db.get_value("GL Entry", {"party_type": filters.party_type,
|
gle_currency = frappe.db.get_value("GL Entry", {"party_type": filters.party_type,
|
||||||
"party": filters.party, "company": filters.company}, "account_currency")
|
"party": filters.party, "company": filters.company}, "account_currency")
|
||||||
|
|||||||
@ -9,6 +9,9 @@ from frappe import throw, _
|
|||||||
from frappe.utils import formatdate
|
from frappe.utils import formatdate
|
||||||
import frappe.desk.reportview
|
import frappe.desk.reportview
|
||||||
|
|
||||||
|
# imported to enable erpnext.accounts.utils.get_account_currency
|
||||||
|
from erpnext.accounts.doctype.account.account import get_account_currency
|
||||||
|
|
||||||
class FiscalYearError(frappe.ValidationError): pass
|
class FiscalYearError(frappe.ValidationError): pass
|
||||||
class BudgetError(frappe.ValidationError): pass
|
class BudgetError(frappe.ValidationError): pass
|
||||||
|
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -8,7 +8,7 @@ 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
|
from erpnext.accounts.party import validate_party_accounts
|
||||||
|
|
||||||
class Supplier(TransactionBase):
|
class Supplier(TransactionBase):
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
@ -46,8 +46,7 @@ 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_accounts(self)
|
||||||
validate_party_account(self)
|
|
||||||
|
|
||||||
def get_contacts(self,nm):
|
def get_contacts(self,nm):
|
||||||
if nm:
|
if nm:
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -6,16 +6,15 @@ import frappe
|
|||||||
from frappe import _, throw
|
from frappe import _, throw
|
||||||
from frappe.utils import today, flt, cint
|
from frappe.utils import today, flt, cint
|
||||||
from erpnext.setup.utils import get_company_currency, get_exchange_rate
|
from erpnext.setup.utils import get_company_currency, get_exchange_rate
|
||||||
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year, get_account_currency
|
||||||
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, validate_party_gle_currency
|
||||||
|
from erpnext.exceptions import CustomerFrozen, InvalidCurrency
|
||||||
|
|
||||||
force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
|
force_item_fields = ("item_group", "barcode", "brand", "stock_uom")
|
||||||
|
|
||||||
class CustomerFrozen(frappe.ValidationError): pass
|
|
||||||
class InvalidCurrency(frappe.ValidationError): pass
|
|
||||||
|
|
||||||
class AccountsController(TransactionBase):
|
class AccountsController(TransactionBase):
|
||||||
def __init__(self, arg1, arg2=None):
|
def __init__(self, arg1, arg2=None):
|
||||||
super(AccountsController, self).__init__(arg1, arg2)
|
super(AccountsController, self).__init__(arg1, arg2)
|
||||||
@ -220,7 +219,7 @@ class AccountsController(TransactionBase):
|
|||||||
gl_dict.update(args)
|
gl_dict.update(args)
|
||||||
|
|
||||||
if not account_currency:
|
if not account_currency:
|
||||||
account_currency = frappe.db.get_value("Account", gl_dict.account, "account_currency")
|
account_currency = get_account_currency(gl_dict.account)
|
||||||
|
|
||||||
if self.doctype != "Journal Entry":
|
if self.doctype != "Journal Entry":
|
||||||
self.validate_account_currency(gl_dict.account, account_currency)
|
self.validate_account_currency(gl_dict.account, account_currency)
|
||||||
@ -427,8 +426,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}")
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
7
erpnext/exceptions.py
Normal file
7
erpnext/exceptions.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
# accounts
|
||||||
|
class CustomerFrozen(frappe.ValidationError): pass
|
||||||
|
class InvalidAccountCurrency(frappe.ValidationError): pass
|
||||||
|
class InvalidCurrency(frappe.ValidationError): pass
|
||||||
@ -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()
|
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -7,11 +7,10 @@ from frappe.model.naming import make_autoname
|
|||||||
from frappe import _, msgprint, throw
|
from frappe import _, msgprint, throw
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
from frappe.desk.reportview import build_match_conditions
|
||||||
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 erpnext.accounts.party import validate_party_accounts
|
||||||
from frappe.desk.reportview import build_match_conditions
|
|
||||||
|
|
||||||
class Customer(TransactionBase):
|
class Customer(TransactionBase):
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
@ -33,8 +32,7 @@ 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_accounts(self)
|
||||||
validate_party_account(self)
|
|
||||||
|
|
||||||
def update_lead_status(self):
|
def update_lead_status(self):
|
||||||
if self.lead_name:
|
if self.lead_name:
|
||||||
|
|||||||
@ -7,9 +7,7 @@ import frappe
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from frappe.test_runner import make_test_records
|
from frappe.test_runner import make_test_records
|
||||||
from erpnext.controllers.accounts_controller import CustomerFrozen
|
from erpnext.exceptions import CustomerFrozen
|
||||||
from erpnext.accounts.party import InvalidCurrency
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
|
||||||
|
|
||||||
test_ignore = ["Price List"]
|
test_ignore = ["Price List"]
|
||||||
|
|
||||||
@ -80,13 +78,3 @@ class TestCustomer(unittest.TestCase):
|
|||||||
frappe.db.set_value("Customer", "_Test Customer", "is_frozen", 0)
|
frappe.db.set_value("Customer", "_Test Customer", "is_frozen", 0)
|
||||||
|
|
||||||
so.save()
|
so.save()
|
||||||
|
|
||||||
def test_multi_currency(self):
|
|
||||||
customer = frappe.get_doc("Customer", "_Test Customer USD")
|
|
||||||
|
|
||||||
create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
|
||||||
currency="USD", conversion_rate=50)
|
|
||||||
|
|
||||||
customer.party_account_currency = "EUR"
|
|
||||||
self.assertRaises(InvalidCurrency, customer.save)
|
|
||||||
|
|
||||||
@ -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"
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import frappe.permissions
|
|||||||
import unittest
|
import unittest
|
||||||
from erpnext.selling.doctype.sales_order.sales_order \
|
from erpnext.selling.doctype.sales_order.sales_order \
|
||||||
import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired
|
import make_material_request, make_delivery_note, make_sales_invoice, WarehouseRequired
|
||||||
|
from erpnext.accounts.doctype.journal_entry.test_journal_entry \
|
||||||
|
import make_journal_entry
|
||||||
|
|
||||||
from frappe.tests.test_permissions import set_user_permission_doctypes
|
from frappe.tests.test_permissions import set_user_permission_doctypes
|
||||||
|
|
||||||
|
|||||||
@ -257,3 +257,7 @@ def get_name_with_abbr(name, company):
|
|||||||
parts.append(company_abbr)
|
parts.append(company_abbr)
|
||||||
|
|
||||||
return " - ".join(parts)
|
return " - ".join(parts)
|
||||||
|
|
||||||
|
def get_company_currency(company):
|
||||||
|
return frappe.local_cache("company_currency", company,
|
||||||
|
lambda: frappe.db.get_value("Company", company, "default_currency"))
|
||||||
|
|||||||
@ -10,6 +10,7 @@ from frappe import _
|
|||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
|
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
form_grid_templates = {
|
form_grid_templates = {
|
||||||
"items": "templates/form_grid/item_grid.html"
|
"items": "templates/form_grid/item_grid.html"
|
||||||
@ -319,7 +320,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
}, warehouse_account[d.warehouse]["account_currency"]))
|
}, warehouse_account[d.warehouse]["account_currency"]))
|
||||||
|
|
||||||
# stock received but not billed
|
# stock received but not billed
|
||||||
stock_rbnb_currency = frappe.db.get_value("Account", stock_rbnb, "account_currency")
|
stock_rbnb_currency = get_account_currency(stock_rbnb)
|
||||||
gl_entries.append(self.get_gl_dict({
|
gl_entries.append(self.get_gl_dict({
|
||||||
"account": stock_rbnb,
|
"account": stock_rbnb,
|
||||||
"against": warehouse_account[d.warehouse]["name"],
|
"against": warehouse_account[d.warehouse]["name"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user