Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions erpnext/accounts/doctype/account/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from frappe.utils import cint, cstr
from frappe.utils.nestedset import NestedSet, get_ancestors_of, get_descendants_of

import erpnext


class RootNotEditable(frappe.ValidationError): pass
class BalanceMismatchError(frappe.ValidationError): pass
Expand Down Expand Up @@ -196,7 +198,7 @@ def create_account_for_child_company(self, parent_acc_name_map, descendants, par
"company": company,
# parent account's currency should be passed down to child account's curreny
# if it is None, it picks it up from default company currency, which might be unintended
"account_currency": self.account_currency,
"account_currency": erpnext.get_company_currency(company),
"parent_account": parent_acc_name_map[company]
})

Expand All @@ -207,8 +209,7 @@ def create_account_for_child_company(self, parent_acc_name_map, descendants, par
# update the parent company's value in child companies
doc = frappe.get_doc("Account", child_account)
parent_value_changed = False
for field in ['account_type', 'account_currency',
'freeze_account', 'balance_must_be']:
for field in ['account_type', 'freeze_account', 'balance_must_be']:
if doc.get(field) != self.get(field):
parent_value_changed = True
doc.set(field, self.get(field))
Expand Down
61 changes: 43 additions & 18 deletions erpnext/accounts/doctype/account/account_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,49 @@ frappe.treeview_settings["Account"] = {
],
root_label: "Accounts",
get_tree_nodes: 'erpnext.accounts.utils.get_children',
on_get_node: function(nodes, deep=false) {
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;

let accounts = [];
if (deep) {
// in case of `get_all_nodes`
accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
} else {
accounts = nodes;
}

const get_balances = frappe.call({
method: 'erpnext.accounts.utils.get_account_balances',
args: {
accounts: accounts,
company: cur_tree.args.company
},
});

get_balances.then(r => {
if (!r.message || r.message.length == 0) return;

for (let account of r.message) {

const node = cur_tree.nodes && cur_tree.nodes[account.value];
if (!node || node.is_root) continue;

// show Dr if positive since balance is calculated as debit - credit else show Cr
const balance = account.balance_in_account_currency || account.balance;
const dr_or_cr = balance > 0 ? "Dr": "Cr";
const format = (value, currency) => format_currency(Math.abs(value), currency);

if (account.balance!==undefined) {
$('<span class="balance-area pull-right">'
+ (account.balance_in_account_currency ?
(format(account.balance_in_account_currency, account.account_currency) + " / ") : "")
+ format(account.balance, account.company_currency)
+ " " + dr_or_cr
+ '</span>').insertBefore(node.$ul);
}
}
});
},
add_tree_node: 'erpnext.accounts.utils.add_ac',
menu_items:[
{
Expand Down Expand Up @@ -122,24 +165,6 @@ frappe.treeview_settings["Account"] = {
}
}, "add");
},
onrender: function(node) {
if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {

// show Dr if positive since balance is calculated as debit - credit else show Cr
let balance = node.data.balance_in_account_currency || node.data.balance;
let dr_or_cr = balance > 0 ? "Dr": "Cr";

if (node.data && node.data.balance!==undefined) {
$('<span class="balance-area pull-right">'
+ (node.data.balance_in_account_currency ?
(format_currency(Math.abs(node.data.balance_in_account_currency),
node.data.account_currency) + " / ") : "")
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
+ " " + dr_or_cr
+ '</span>').insertBefore(node.$ul);
}
}
},
toolbar: [
{
label:__("Add Child"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from unidecode import unidecode


def create_charts(company, chart_template=None, existing_company=None, custom_chart=None):
def create_charts(company, chart_template=None, existing_company=None, custom_chart=None, from_coa_importer=None):
chart = custom_chart or get_chart(chart_template, existing_company)
if chart:
accounts = []
Expand All @@ -22,7 +22,7 @@ def _import_accounts(children, parent, root_type, root_account=False):
if root_account:
root_type = child.get("root_type")

if account_name not in ["account_number", "account_type",
if account_name not in ["account_name", "account_number", "account_type",
"root_type", "is_group", "tax_rate"]:

account_number = cstr(child.get("account_number")).strip()
Expand All @@ -35,7 +35,7 @@ def _import_accounts(children, parent, root_type, root_account=False):

account = frappe.get_doc({
"doctype": "Account",
"account_name": account_name,
"account_name": child.get('account_name') if from_coa_importer else account_name,
"company": company,
"parent_account": parent,
"is_group": is_group,
Expand Down Expand Up @@ -213,7 +213,7 @@ def _get_account_names(account_master):
return (bank_account in accounts)

@frappe.whitelist()
def build_tree_from_json(chart_template, chart_data=None):
def build_tree_from_json(chart_template, chart_data=None, from_coa_importer=False):
''' get chart template from its folder and parse the json to be rendered as tree '''
chart = chart_data or get_chart(chart_template)

Expand All @@ -226,9 +226,12 @@ def _import_accounts(children, parent):
''' recursively called to form a parent-child based list of dict from chart template '''
for account_name, child in iteritems(children):
account = {}
if account_name in ["account_number", "account_type",\
if account_name in ["account_name", "account_number", "account_type",\
"root_type", "is_group", "tax_rate"]: continue

if from_coa_importer:
account_name = child['account_name']

account['parent_account'] = parent
account['expandable'] = True if identify_is_group(child) else False
account['value'] = (cstr(child.get('account_number')).strip() + ' - ' + account_name) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ frappe.ui.form.on('Chart of Accounts Importer', {
if (!frm.doc.import_file) {
frm.page.set_indicator("");
$(frm.fields_dict['chart_tree'].wrapper).empty(); // empty wrapper on removing file
} else {
frappe.run_serially([
() => validate_coa(frm),
() => generate_tree_preview(frm),
() => create_import_button(frm),
() => frm.set_df_property('chart_preview', 'hidden', 0),
]);
}
},

Expand All @@ -105,24 +112,26 @@ frappe.ui.form.on('Chart of Accounts Importer', {
});

var create_import_button = function(frm) {
frm.page.set_primary_action(__("Import"), function () {
return frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
args: {
file_name: frm.doc.import_file,
company: frm.doc.company
},
freeze: true,
freeze_message: __("Creating Accounts..."),
callback: function(r) {
if (!r.exc) {
clearInterval(frm.page["interval"]);
frm.page.set_indicator(__('Import Successful'), 'blue');
create_reset_button(frm);
if (frm.page.show_import_button) {
frm.page.set_primary_action(__("Import"), function () {
return frappe.call({
method: "erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.import_coa",
args: {
file_name: frm.doc.import_file,
company: frm.doc.company
},
freeze: true,
freeze_message: __("Creating Accounts..."),
callback: function(r) {
if (!r.exc) {
clearInterval(frm.page["interval"]);
frm.page.set_indicator(__('Import Successful'), 'blue');
create_reset_button(frm);
}
}
}
});
}).addClass('btn btn-primary');
});
}).addClass('btn btn-primary');
}
};

var create_reset_button = function(frm) {
Expand All @@ -136,6 +145,7 @@ var create_reset_button = function(frm) {
var validate_coa = function(frm) {
if (frm.doc.import_file) {
let parent = __('All Accounts');

return frappe.call({
'method': 'erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.get_coa',
'args': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def import_coa(file_name, company):

frappe.local.flags.ignore_root_company_validation = True
forest = build_forest(data)
create_charts(company, custom_chart=forest)
create_charts(company, custom_chart=forest, from_coa_importer=True)

# trigger on_update for company to reset default accounts
set_default_accounts(company)
Expand Down Expand Up @@ -148,7 +148,7 @@ def get_coa(doctype, parent, is_root=False, file_name=None, for_validate=0):

if not for_validate:
forest = build_forest(data)
accounts = build_tree_from_json("", chart_data=forest) # returns a list of dict in a tree render-able form
accounts = build_tree_from_json("", chart_data=forest, from_coa_importer=True) # returns a list of dict in a tree render-able form

# filter out to show data for the selected node only
accounts = [d for d in accounts if d['parent_account']==parent]
Expand Down Expand Up @@ -212,11 +212,14 @@ def return_parent(data, child):
if not account_name:
error_messages.append("Row {0}: Please enter Account Name".format(line_no))

name = account_name
if account_number:
account_number = cstr(account_number).strip()
account_name = "{} - {}".format(account_number, account_name)

charts_map[account_name] = {}
charts_map[account_name]['account_name'] = name
if account_number: charts_map[account_name]["account_number"] = account_number
if cint(is_group) == 1: charts_map[account_name]["is_group"] = is_group
if account_type: charts_map[account_name]["account_type"] = account_type
if root_type: charts_map[account_name]["root_type"] = root_type
Expand Down
9 changes: 8 additions & 1 deletion erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ def update_payment_schedule(self, cancel=0):
invoice_paid_amount_map[invoice_key]['discounted_amt'] = ref.total_amount * (term.discount / 100)

for key, allocated_amount in iteritems(invoice_payment_amount_map):
if not invoice_paid_amount_map.get(key):
frappe.throw(_('Payment term {0} not used in {1}').format(key[0], key[1]))

outstanding = flt(invoice_paid_amount_map.get(key, {}).get('outstanding'))
discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get('discounted_amt'))

Expand Down Expand Up @@ -709,10 +712,14 @@ def add_party_gl_entries(self, gl_entries):
dr_or_cr = "credit" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit"

for d in self.get("references"):
cost_center = self.cost_center
if d.reference_doctype == "Sales Invoice" and not cost_center:
cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
gle = party_gl_dict.copy()
gle.update({
"against_voucher_type": d.reference_doctype,
"against_voucher": d.reference_name
"against_voucher": d.reference_name,
"cost_center": cost_center
})

allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
Expand Down
13 changes: 8 additions & 5 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,15 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
},

currency() {
var me = this;
this._super();
$.each(cur_frm.doc.timesheets, function(i, d) {
let row = frappe.get_doc(d.doctype, d.name)
set_timesheet_detail_rate(row.doctype, row.name, cur_frm.doc.currency, row.timesheet_detail)
});
calculate_total_billing_amount(cur_frm)
if (this.frm.doc.timesheets) {
this.frm.doc.timesheets.forEach((d) => {
let row = frappe.get_doc(d.doctype, d.name)
set_timesheet_detail_rate(row.doctype, row.name, me.frm.doc.currency, row.timesheet_detail)
});
frm.trigger("calculate_timesheet_totals");
}
}
});

Expand Down
18 changes: 9 additions & 9 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.json
Original file line number Diff line number Diff line change
Expand Up @@ -1996,14 +1996,6 @@
"label": "Additional Discount Account",
"options": "Account"
},
{
"default": "0",
"fieldname": "ignore_default_payment_terms_template",
"fieldtype": "Check",
"hidden": 1,
"label": "Ignore Default Payment Terms Template",
"read_only": 1
},
{
"allow_on_submit": 1,
"fieldname": "dispatch_address_name",
Expand All @@ -2019,6 +2011,14 @@
"label": "Dispatch Address",
"read_only": 1
},
{
"default": "0",
"fieldname": "ignore_default_payment_terms_template",
"fieldtype": "Check",
"hidden": 1,
"label": "Ignore Default Payment Terms Template",
"read_only": 1
},
{
"fieldname": "total_billing_hours",
"fieldtype": "Float",
Expand All @@ -2037,7 +2037,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2022-02-25 11:51:44.271169",
"modified": "2022-02-26 11:51:44.271169",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
"column_break_9",
"billing_amount",
"section_break_11",
"time_sheet",
"timesheet_detail",
"column_break_5",
"time_sheet",
"project_name"
],
"fields": [
Expand Down Expand Up @@ -91,7 +91,6 @@
"fieldtype": "Column Break"
},
{

"fieldname": "section_break_7",
"fieldtype": "Section Break",
"label": "Totals"
Expand All @@ -110,11 +109,15 @@
"fieldtype": "Data",
"label": "Project Name",
"read_only": 1
},
{
"fieldname": "column_break_13",
"fieldtype": "Column Break"
}
],
"istable": 1,
"links": [],
"modified": "2021-08-15 18:37:08.084930",
"modified": "2021-08-16 18:37:08.084930",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
column.is_tree = true;
}

value = default_formatter(value, row, column, data);
if (data && data.account && column.apply_currency_formatter) {
data.currency = erpnext.get_currency(column.company_name);
}

value = default_formatter(value, row, column, data);
if (!data.parent_account) {
value = $(`<span>${value}</span>`);

Expand Down
Loading