Multi currency GL entry fixes

This commit is contained in:
Nabin Hait 2015-08-19 19:22:34 +05:30
parent 69c1401764
commit c561a499d7
10 changed files with 441 additions and 68 deletions

View File

@ -106,16 +106,15 @@ class GLEntry(Document):
if not self.currency:
self.currency = company_currency
if account_currency != self.currency:
frappe.throw(_("Accounting Entry for {0} can only be made in currency: {1}")
.format(self.account, (account_currency or company_currency)))
if self.party_type and self.party:
existing_gle = frappe.db.get_value("GL Entry",
{"party_type": self.party_type, "party": self.party}, ["name", "currency"])
existing_gle = frappe.db.get_value("GL Entry", {"party_type": self.party_type,
"party": self.party, "company": self.company}, ["name", "currency"], as_dict=1)
if not existing_gle:
party_currency = frappe.db.get_value(self.party_type, self.party, "currency") or company_currency
party_currency = frappe.db.get_value(self.party_type, self.party, "default_currency") or company_currency
if party_currency != account_currency:
frappe.throw(_("Invalid Account {0}. Account Currency must be {1}, same as {2}: {3}")
.format(self.account, party_currency, self.party_type, self.party))

View File

@ -298,7 +298,8 @@ class PurchaseInvoice(BuyingController):
"account": item.expense_account,
"against": self.supplier,
"debit": item.base_net_amount,
"debit_in_account_currency": item.net_amount,
"debit_in_account_currency": item.base_net_amount \
if account_currency==self.company_currency else item.net_amount,
"cost_center": item.cost_center
}, account_currency)
)

View File

@ -27,14 +27,25 @@ def process_gl_map(gl_map, merge_entries=True):
gl_map = merge_similar_entries(gl_map)
for entry in gl_map:
# toggle debit, credit if negative entry
# toggle debit, credit if negative entry
if flt(entry.debit) < 0:
entry.credit = flt(entry.credit) - flt(entry.debit)
entry.debit = 0.0
if flt(entry.debit_in_account_currency) < 0:
entry.credit_in_account_currency = \
flt(entry.credit_in_account_currency) - flt(entry.debit_in_account_currency)
entry.debit_in_account_currency = 0.0
if flt(entry.credit) < 0:
entry.debit = flt(entry.debit) - flt(entry.credit)
entry.credit = 0.0
if flt(entry.credit_in_account_currency) < 0:
entry.debit_in_account_currency = \
flt(entry.debit_in_account_currency) - flt(entry.credit_in_account_currency)
entry.credit_in_account_currency = 0.0
return gl_map
def merge_similar_entries(gl_map):
@ -45,7 +56,11 @@ def merge_similar_entries(gl_map):
same_head = check_if_in_list(entry, merged_gl_map)
if same_head:
same_head.debit = flt(same_head.debit) + flt(entry.debit)
same_head.debit_in_account_currency = \
flt(same_head.debit_in_account_currency) + flt(entry.debit_in_account_currency)
same_head.credit = flt(same_head.credit) + flt(entry.credit)
same_head.credit_in_account_currency = \
flt(same_head.credit_in_account_currency) + flt(entry.credit_in_account_currency)
else:
merged_gl_map.append(entry)

View File

@ -143,13 +143,16 @@ def set_account_and_due_date(party, account, party_type, company, posting_date,
return out
def validate_party_account(party):
party_account_defined_for_companies = [d.company for d in party.get("party_accounts")]
party_account_defined_for_companies = [d.company for d in party.get("accounts")]
party_account_required_for_companies = []
for company, company_currency in frappe.db.sql("select name, default_currency from `tabCompany`"):
if party.currency and party.currency != company_currency \
if party.default_currency and party.default_currency != company_currency \
and company not in party_account_defined_for_companies:
frappe.throw(_("Please mention Party Account for company {0}, as party currency is different than company's default currency")
.format(company))
party_account_required_for_companies.append(company)
if party_account_required_for_companies:
frappe.msgprint(_("Please mention Party Account for the following companies, as party currency is different from company's default currency: {0}")
.format("\n" + "\n".join(party_account_required_for_companies)))
@frappe.whitelist()
def get_party_account(company, party, party_type):

View File

@ -1,254 +1,601 @@
{
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "naming_series:",
"creation": "2013-01-10 16:34:11",
"custom": 0,
"description": "Supplier of Goods or Services.",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"document_type": "Setup",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "basic_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "",
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "icon-user",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Series",
"no_copy": 1,
"oldfieldname": "naming_series",
"oldfieldtype": "Select",
"options": "SUPP-",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "supplier_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Supplier Name",
"no_copy": 1,
"oldfieldname": "supplier_name",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 1
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "supplier_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Supplier Type",
"no_copy": 0,
"oldfieldname": "supplier_type",
"oldfieldtype": "Link",
"options": "Supplier Type",
"permlevel": 0,
"reqd": 1
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "is_frozen",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Is Frozen",
"no_copy": 0,
"permlevel": 0,
"precision": ""
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "address_contacts",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Address & Contacts",
"no_copy": 0,
"oldfieldtype": "Column Break",
"options": "icon-map-marker",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "address_html",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Address HTML",
"no_copy": 0,
"permlevel": 0,
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "contact_html",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Contact HTML",
"no_copy": 0,
"permlevel": 0,
"read_only": 1
"print_hide": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_payable_accounts",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Default Payable Accounts",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"depends_on": "eval:!doc.__islocal",
"allow_on_submit": 0,
"depends_on": "",
"description": "Mention if non-standard receivable account applicable",
"fieldname": "accounts",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Accounts",
"no_copy": 0,
"options": "Party Account",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "More Info",
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "icon-file-text",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_currency",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Default Currency",
"no_copy": 1,
"options": "Currency",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_price_list",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Price List",
"no_copy": 0,
"options": "Price List",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "default_taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"in_filter": 0,
"in_list_view": 0,
"label": "Taxes and Charges",
"no_copy": 0,
"options": "Purchase Taxes and Charges Template",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "credit_days",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Credit Days",
"permlevel": 0
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_on_submit": 0,
"fieldname": "website",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Website",
"no_copy": 0,
"oldfieldname": "website",
"oldfieldtype": "Data",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"description": "Statutory info and other general information about your Supplier",
"fieldname": "supplier_details",
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Supplier Details",
"no_copy": 0,
"oldfieldname": "supplier_details",
"oldfieldtype": "Code",
"permlevel": 0
"permlevel": 0,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"fieldname": "communications",
"fieldtype": "Table",
"hidden": 1,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Communications",
"no_copy": 0,
"options": "Communication",
"permlevel": 0,
"print_hide": 1
"print_hide": 1,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-user",
"idx": 1,
"modified": "2015-07-17 09:39:05.318826",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-08-19 16:50:48.078108",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",
"owner": "Administrator",
"permissions": [
{
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase User"
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase Manager",
"role": "Purchase User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Purchase Master Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"role": "Stock User"
"report": 0,
"role": "Stock User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Stock Manager"
"role": "Stock Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"role": "Accounts User"
"report": 0,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager"
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
}
],
"read_only": 0,
"read_only_onload": 0,
"search_fields": "supplier_name, supplier_type",
"title_field": "supplier_name"
}

View File

@ -18,8 +18,8 @@ class CustomerFrozen(frappe.ValidationError): pass
class AccountsController(TransactionBase):
def __init__(self, arg1, arg2=None):
super(AccountsController, self).__init__(arg1, arg2)
self.company_currency = get_company_currency(self.company)
if self.get("company"):
self.company_currency = get_company_currency(self.company)
def validate(self):
if self.get("_action") and self._action != "update_after_submit":
@ -211,20 +211,30 @@ class AccountsController(TransactionBase):
})
gl_dict.update(args)
gl_dict = self.set_balance_in_account_currency(gl_dict, account_currency)
return gl_dict
def set_balance_in_account_currency(self, gl_dict, account_currency=None):
if not account_currency:
account_currency = frappe.db.get_value("Account", gl_dict.account, "currency")
gl_dict["currency"] = self.company_currency if account_currency==self.company_currency else self.currency
if not self.get("conversion_rate") and account_currency!=self.company_currency:
frappe.throw(_("Account: {0} with currency: {1} can not be selected")
.format(gl_dict.account, account_currency))
gl_dict["currency"] = self.company_currency if account_currency==self.company_currency \
else account_currency
# set debit/credit in account currency if not provided
if flt(gl_dict.debit) and not flt(gl_dict.debit_in_account_currency):
gl_dict.debit_in_account_currency = gl_dict.debit if account_currency==self.company_currency \
else flt(gl_dict.debit / (self.get("conversion_rate") or 1), 2)
else flt(gl_dict.debit / (self.get("conversion_rate")), 2)
if flt(gl_dict.credit) and not flt(gl_dict.credit_in_account_currency):
gl_dict.credit_in_account_currency = gl_dict.credit if account_currency==self.company_currency \
else flt(gl_dict.credit / (self.get("conversion_rate") or 1), 2)
else flt(gl_dict.credit / (self.get("conversion_rate")), 2)
return gl_dict
def clear_unallocated_advances(self, childtype, parentfield):

View File

@ -71,7 +71,7 @@ class StockController(AccountsController):
if warehouse_with_no_account:
msgprint(_("No accounting entries for the following warehouses") + ": \n" +
"\n".join(warehouse_with_no_account))
return process_gl_map(gl_list)
def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):

View File

@ -299,7 +299,7 @@
},
{
"allow_on_submit": 0,
"depends_on": "eval:!doc.__islocal",
"depends_on": "",
"description": "Mention if non-standard receivable account applicable",
"fieldname": "accounts",
"fieldtype": "Table",
@ -739,7 +739,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-08-13 16:41:28.805471",
"modified": "2015-08-19 16:01:33.347348",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",

View File

@ -10,17 +10,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
this._super();
if (!doc.is_return) {
if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1) {
// show Make Invoice button only if Delivery Note is not created from Sales Invoice
var from_sales_invoice = false;
from_sales_invoice = cur_frm.doc.items.some(function(item) {
return item.against_sales_invoice ? true : false;
});
if(!from_sales_invoice)
cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
}
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
cur_frm.add_custom_button(__('Installation Note'), this.make_installation_note);
@ -59,7 +48,16 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
}
}
if(doc.__onload && !doc.__onload.billing_complete && doc.docstatus==1 && !doc.is_return) {
// show Make Invoice button only if Delivery Note is not created from Sales Invoice
var from_sales_invoice = false;
from_sales_invoice = cur_frm.doc.items.some(function(item) {
return item.against_sales_invoice ? true : false;
});
if(!from_sales_invoice)
cur_frm.add_custom_button(__('Invoice'), this.make_sales_invoice).addClass("btn-primary");
}
erpnext.stock.delivery_note.set_print_hide(doc, dt, dn);

View File

@ -313,7 +313,7 @@ class PurchaseReceipt(BuyingController):
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(d.base_net_amount, d.precision("base_net_amount")),
"credit_in_account_currency": flt(d.base_net_amount, d.precision("base_net_amount")) \
if stock_rbnb_currency==self.currency else flt(d.net_amount, d.precision("net_amount"))
if stock_rbnb_currency==self.company_currency else flt(d.net_amount, d.precision("net_amount"))
}, stock_rbnb_currency))
negative_expense_to_be_booked += flt(d.item_tax_amount)