diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 0701435dfc7..b844f7419b6 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -1,10 +1,12 @@ // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt -{% include "erpnext/public/js/controllers/accounts.js" %} frappe.provide("erpnext.accounts.dimensions"); cur_frm.cscript.tax_table = "Advance Taxes and Charges"; +erpnext.accounts.taxes.setup_tax_validations("Payment Entry"); +erpnext.accounts.taxes.setup_tax_filters("Advance Taxes and Charges"); + frappe.ui.form.on('Payment Entry', { onload: function(frm) { frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', "Repost Payment Ledger"]; @@ -106,12 +108,11 @@ frappe.ui.form.on('Payment Entry', { }); frm.set_query("reference_doctype", "references", function() { + let doctypes = ["Journal Entry"]; if (frm.doc.party_type == "Customer") { - var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"]; + doctypes = ["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"]; } else if (frm.doc.party_type == "Supplier") { - var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; - } else { - var doctypes = ["Journal Entry"]; + doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"]; } return { @@ -165,6 +166,7 @@ frappe.ui.form.on('Payment Entry', { }, company: function(frm) { + frm.trigger('party'); frm.events.hide_unhide_fields(frm); frm.events.set_dynamic_labels(frm); erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); @@ -287,6 +289,13 @@ frappe.ui.form.on('Payment Entry', { } }, + mode_of_payment: function(frm) { + erpnext.accounts.pos.get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ + let payment_account_field = frm.doc.payment_type == "Receive" ? "paid_to" : "paid_from"; + frm.set_value(payment_account_field, account); + }) + }, + party_type: function(frm) { let party_types = Object.keys(frappe.boot.party_account_types); @@ -319,10 +328,6 @@ frappe.ui.form.on('Payment Entry', { } }, - company: function(frm){ - frm.trigger('party'); - }, - party: function(frm) { if (frm.doc.contact_email || frm.doc.contact_person) { frm.set_value("contact_email", ""); @@ -1106,7 +1111,7 @@ frappe.ui.form.on('Payment Entry', { if (tax.charge_type === 'On Net Total') { tax.charge_type = 'On Paid Amount'; } - me.frm.add_child("taxes", tax); + frm.add_child("taxes", tax); } frm.events.apply_taxes(frm); frm.events.set_unallocated_amount(frm); @@ -1222,7 +1227,7 @@ frappe.ui.form.on('Payment Entry', { tax.grand_total_fraction_for_current_item = 1 + tax.tax_fraction_for_current_item; } else { tax.grand_total_fraction_for_current_item = - me.frm.doc["taxes"][i-1].grand_total_fraction_for_current_item + + frm.doc["taxes"][i-1].grand_total_fraction_for_current_item + tax.tax_fraction_for_current_item; } @@ -1269,7 +1274,7 @@ frappe.ui.form.on('Payment Entry', { } }); - $.each(me.frm.doc["taxes"] || [], function(i, tax) { + $.each(frm.doc["taxes"] || [], function(i, tax) { let current_tax_amount = frm.events.get_current_tax_amount(frm, tax); // Adjust divisional loss to the last item diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js index 32e267f33c8..30c841e02bc 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.js +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.js @@ -4,6 +4,7 @@ {% include 'erpnext/selling/sales_common.js' %}; frappe.provide("erpnext.accounts"); +erpnext.accounts.pos.setup("POS Invoice"); erpnext.selling.POSInvoiceController = class POSInvoiceController extends erpnext.selling.SellingController { settings = {}; diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js index 813d20dbf93..0a89aee8e9c 100755 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.js +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js @@ -1,8 +1,6 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -{% include "erpnext/public/js/controllers/accounts.js" %} - frappe.ui.form.on('POS Profile', { setup: function(frm) { frm.set_query("selling_price_list", function() { @@ -148,4 +146,4 @@ frappe.ui.form.on('POS Profile', { frm.toggle_display('expense_account', erpnext.is_perpetual_inventory_enabled(frm.doc.company)); } -}); +}); \ No newline at end of file diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 6a558ca606b..0f581e20da6 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -4,6 +4,10 @@ frappe.provide("erpnext.accounts"); {% include 'erpnext/public/js/controllers/buying.js' %}; +erpnext.accounts.payment_triggers.setup("Purchase Invoice"); +erpnext.accounts.taxes.setup_tax_filters("Purchase Taxes and Charges"); +erpnext.accounts.taxes.setup_tax_validations("Purchase Invoice"); + erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.BuyingController { setup(doc) { this.setup_posting_date_time_check(); @@ -506,7 +510,8 @@ frappe.ui.form.on("Purchase Invoice", { setup: function(frm) { frm.custom_make_buttons = { 'Purchase Invoice': 'Return / Debit Note', - 'Payment Entry': 'Payment' + 'Payment Entry': 'Payment', + 'Landed Cost Voucher': function () { frm.trigger('create_landed_cost_voucher') }, } frm.set_query("additional_discount_account", function() { @@ -544,6 +549,26 @@ frappe.ui.form.on("Purchase Invoice", { frm.events.add_custom_buttons(frm); }, + mode_of_payment: function(frm) { + get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ + frm.set_value('cash_bank_account', account); + }) + }, + + create_landed_cost_voucher: function (frm) { + let lcv = frappe.model.get_new_doc('Landed Cost Voucher'); + lcv.company = frm.doc.company; + + let lcv_receipt = frappe.model.get_new_doc('Landed Cost Purchase Invoice'); + lcv_receipt.receipt_document_type = 'Purchase Invoice'; + lcv_receipt.receipt_document = frm.doc.name; + lcv_receipt.supplier = frm.doc.supplier; + lcv_receipt.grand_total = frm.doc.grand_total; + lcv.purchase_receipts = [lcv_receipt]; + + frappe.set_route("Form", lcv.doctype, lcv.name); + }, + add_custom_buttons: function(frm) { if (frm.doc.docstatus == 1 && frm.doc.per_received < 100) { frm.add_custom_button(__('Purchase Receipt'), () => { diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js index eb0ea7fef81..78dc4bee1a6 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js @@ -1,30 +1,31 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -cur_frm.cscript.tax_table = "Purchase Taxes and Charges"; +erpnext.accounts.taxes.setup_tax_validations("Purchase Taxes and Charges Template"); +erpnext.accounts.taxes.setup_tax_filters("Purchase Taxes and Charges"); -{% include "erpnext/public/js/controllers/accounts.js" %} +frappe.ui.form.on("Purchase Taxes and Charges", { + add_deduct_tax(doc, cdt, cdn) { + let d = locals[cdt][cdn]; -frappe.ui.form.on("Purchase Taxes and Charges", "add_deduct_tax", function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; + if(!d.category && d.add_deduct_tax) { + frappe.msgprint(__("Please select Category first")); + d.add_deduct_tax = ''; + } + else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') { + frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Valuation and Total'")); + d.add_deduct_tax = ''; + } + refresh_field('add_deduct_tax', d.name, 'taxes'); + }, - if(!d.category && d.add_deduct_tax) { - frappe.msgprint(__("Please select Category first")); - d.add_deduct_tax = ''; + category(doc, cdt, cdn) { + let d = locals[cdt][cdn]; + + if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') { + frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Valuation and Total'")); + d.add_deduct_tax = ''; + } + refresh_field('add_deduct_tax', d.name, 'taxes'); } - else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') { - frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Valuation and Total'")); - d.add_deduct_tax = ''; - } - refresh_field('add_deduct_tax', d.name, 'taxes'); -}); - -frappe.ui.form.on("Purchase Taxes and Charges", "category", function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - - if (d.category != 'Total' && d.add_deduct_tax == 'Deduct') { - frappe.msgprint(__("Cannot deduct when category is for 'Valuation' or 'Vaulation and Total'")); - d.add_deduct_tax = ''; - } - refresh_field('add_deduct_tax', d.name, 'taxes'); }); diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 8753ebc3baf..389c1644b2a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -4,6 +4,10 @@ {% include 'erpnext/selling/sales_common.js' %}; frappe.provide("erpnext.accounts"); +erpnext.accounts.taxes.setup_tax_validations("Sales Invoice"); +erpnext.accounts.payment_triggers.setup("Sales Invoice"); +erpnext.accounts.pos.setup("Sales Invoice"); +erpnext.accounts.taxes.setup_tax_filters("Sales Taxes and Charges"); erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends erpnext.selling.SellingController { setup(doc) { diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js index 066c4eae436..00e8b621c0d 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js @@ -1,6 +1,5 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -cur_frm.cscript.tax_table = "Sales Taxes and Charges"; - -{% include "erpnext/public/js/controllers/accounts.js" %} +erpnext.accounts.taxes.setup_tax_validations("Sales Taxes and Charges Template"); +erpnext.accounts.taxes.setup_tax_filters("Sales Taxes and Charges"); \ No newline at end of file diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 8fa8f305549..97b7cf874c5 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -5,6 +5,10 @@ frappe.provide("erpnext.buying"); frappe.provide("erpnext.accounts.dimensions"); {% include 'erpnext/public/js/controllers/buying.js' %}; +erpnext.accounts.taxes.setup_tax_filters("Purchase Taxes and Charges"); +erpnext.accounts.taxes.setup_tax_validations("Purchase Order"); + + frappe.ui.form.on("Purchase Order", { setup: function(frm) { diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js index 47b88a002bc..d03a07cf035 100644 --- a/erpnext/public/js/controllers/accounts.js +++ b/erpnext/public/js/controllers/accounts.js @@ -3,319 +3,267 @@ // get tax rate frappe.provide("erpnext.taxes"); -frappe.provide("erpnext.taxes.flags"); -frappe.ui.form.on(cur_frm.doctype, { - setup: function(frm) { - // set conditional display for rate column in taxes - $(frm.wrapper).on('grid-row-render', function(e, grid_row) { - if(in_list(['Sales Taxes and Charges', 'Purchase Taxes and Charges'], grid_row.doc.doctype)) { - erpnext.taxes.set_conditional_mandatory_rate_or_amount(grid_row); +erpnext.accounts.taxes = { + setup_tax_validations: function(doctype) { + let me = this; + frappe.ui.form.on(doctype, { + setup: function(frm) { + // set conditional display for rate column in taxes + $(frm.wrapper).on('grid-row-render', function(e, grid_row) { + if(in_list(['Sales Taxes and Charges', 'Purchase Taxes and Charges'], grid_row.doc.doctype)) { + me.set_conditional_mandatory_rate_or_amount(grid_row); + } + }); + }, + onload: function(frm) { + if(frm.get_field("taxes")) { + frm.set_query("account_head", "taxes", function(doc) { + if(frm.cscript.tax_table == "Sales Taxes and Charges") { + var account_type = ["Tax", "Chargeable", "Expense Account"]; + } else { + var account_type = ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation"]; + } + + return { + query: "erpnext.controllers.queries.tax_account_query", + filters: { + "account_type": account_type, + "company": doc.company, + "disabled": 0 + } + } + }); + frm.set_query("cost_center", "taxes", function(doc) { + return { + filters: { + "company": doc.company, + "is_group": 0 + } + }; + }); + } + }, + validate: function(frm) { + // neither is absolutely mandatory + if(frm.get_docfield("taxes")) { + frm.get_docfield("taxes", "rate").reqd = 0; + frm.get_docfield("taxes", "tax_amount").reqd = 0; + } + + }, + taxes_on_form_rendered: function(frm) { + me.set_conditional_mandatory_rate_or_amount(frm.open_grid_row()); + }, + }); + }, + + set_conditional_mandatory_rate_or_amount: function(grid_row) { + if(grid_row) { + if(grid_row.doc.charge_type==="Actual") { + grid_row.toggle_editable("tax_amount", true); + grid_row.toggle_reqd("tax_amount", true); + grid_row.toggle_editable("rate", false); + grid_row.toggle_reqd("rate", false); + } else { + grid_row.toggle_editable("rate", true); + grid_row.toggle_reqd("rate", true); + grid_row.toggle_editable("tax_amount", false); + grid_row.toggle_reqd("tax_amount", false); + } + } + }, + + validate_taxes_and_charges: function(cdt, cdn) { + let d = locals[cdt][cdn]; + let msg = ""; + + if (d.account_head && !d.description) { + // set description from account head + d.description = d.account_head.split(' - ').slice(0, -1).join(' - '); + } + + if (!d.charge_type && (d.row_id || d.rate || d.tax_amount)) { + msg = __("Please select Charge Type first"); + d.row_id = ""; + d.rate = d.tax_amount = 0.0; + } else if ((d.charge_type == 'Actual' || d.charge_type == 'On Net Total' || d.charge_type == 'On Paid Amount') && d.row_id) { + msg = __("Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'"); + d.row_id = ""; + } else if ((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id) { + if (d.idx == 1) { + msg = __("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"); + d.charge_type = ''; + } else if (!d.row_id) { + msg = __("Please specify a valid Row ID for row {0} in table {1}", [d.idx, __(d.doctype)]); + d.row_id = ""; + } else if (d.row_id && d.row_id >= d.idx) { + msg = __("Cannot refer row number greater than or equal to current row number for this Charge type"); + d.row_id = ""; + } + } + if (msg) { + frappe.validated = false; + refresh_field("taxes"); + frappe.throw(msg); + } + + }, + + setup_tax_filters: function(doctype) { + let me = this; + frappe.ui.form.on(doctype, { + account_head: function(frm, cdt, cdn) { + let d = locals[cdt][cdn]; + + if (doc.docstatus == 1) { + // Should not trigger any changes on change post submit + return; + } + + if(!d.charge_type && d.account_head){ + frappe.msgprint(__("Please select Charge Type first")); + frappe.model.set_value(cdt, cdn, "account_head", ""); + } else if (d.account_head) { + frappe.call({ + type:"GET", + method: "erpnext.controllers.accounts_controller.get_tax_rate", + args: {"account_head":d.account_head}, + callback: function(r) { + if (d.charge_type!=="Actual") { + frappe.model.set_value(cdt, cdn, "rate", r.message.tax_rate || 0); + } + frappe.model.set_value(cdt, cdn, "description", r.message.account_name); + } + }) + } + }, + row_id: function(frm, cdt, cdn) { + me.validate_taxes_and_charges(cdt, cdn); + }, + rate: function(frm, cdt, cdn) { + me.validate_taxes_and_charges(cdt, cdn); + }, + tax_amount: function(frm, cdt, cdn) { + me.validate_taxes_and_charges(cdt, cdn); + }, + charge_type: function(frm, cdt, cdn) { + me.validate_taxes_and_charges(cdt, cdn); + let open_form = frm.open_grid_row(); + if(open_form) { + me.set_conditional_mandatory_rate_or_amount(open_form); + } else { + // apply in current row + me.set_conditional_mandatory_rate_or_amount(frm.get_field('taxes').grid.get_row(cdn)); + } + }, + included_in_print_rate: function(frm, cdt, cdn) { + let tax = frappe.get_doc(cdt, cdn); + try { + me.validate_taxes_and_charges(cdt, cdn); + me.validate_inclusive_tax(tax); + } catch(e) { + tax.included_in_print_rate = 0; + refresh_field("included_in_print_rate", tax.name, tax.parentfield); + throw e; + } } }); }, - onload: function(frm) { - if(frm.get_field("taxes")) { - frm.set_query("account_head", "taxes", function(doc) { - if(frm.cscript.tax_table == "Sales Taxes and Charges") { - var account_type = ["Tax", "Chargeable", "Expense Account"]; - } else { - var account_type = ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation"]; + + validate_inclusive_tax: function(tax) { + let actual_type_error = function() { + var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx]) + frappe.throw(msg); + }; + + let on_previous_row_error = function(row_range) { + var msg = __("For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included", + [tax.idx, __(tax.doctype), tax.charge_type, row_range]) + frappe.throw(msg); + }; + + if(cint(tax.included_in_print_rate)) { + if(tax.charge_type == "Actual") { + // inclusive tax cannot be of type Actual + actual_type_error(); + } else if(tax.charge_type == "On Previous Row Amount" && + !cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate) + ) { + // referred row should also be an inclusive tax + on_previous_row_error(tax.row_id); + } else if(tax.charge_type == "On Previous Row Total") { + var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id), + function(t) { return cint(t.included_in_print_rate) ? null : t; }); + if(taxes_not_included.length > 0) { + // all rows above this tax should be inclusive + on_previous_row_error(tax.row_id == 1 ? "1" : "1 - " + tax.row_id); } - - return { - query: "erpnext.controllers.queries.tax_account_query", - filters: { - "account_type": account_type, - "company": doc.company, - "disabled": 0 - } - } - }); - frm.set_query("cost_center", "taxes", function(doc) { - return { - filters: { - "company": doc.company, - "is_group": 0 - } - }; - }); - } - }, - validate: function(frm) { - // neither is absolutely mandatory - if(frm.get_docfield("taxes")) { - frm.get_docfield("taxes", "rate").reqd = 0; - frm.get_docfield("taxes", "tax_amount").reqd = 0; - } - - }, - taxes_on_form_rendered: function(frm) { - erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm.open_grid_row()); - }, - - allocate_advances_automatically: function(frm) { - frm.trigger('fetch_advances'); - }, - - only_include_allocated_payments: function(frm) { - frm.trigger('fetch_advances'); - }, - - fetch_advances: function(frm) { - if(frm.doc.allocate_advances_automatically) { - frappe.call({ - doc: frm.doc, - method: "set_advances", - callback: function(r, rt) { - refresh_field("advances"); - } - }) - } - } -}); - -frappe.ui.form.on('Sales Invoice Payment', { - mode_of_payment: function(frm, cdt, cdn) { - var d = locals[cdt][cdn]; - get_payment_mode_account(frm, d.mode_of_payment, function(account){ - frappe.model.set_value(cdt, cdn, 'account', account) - }) - } -}); - -frappe.ui.form.on("Sales Invoice", { - payment_terms_template: function() { - cur_frm.trigger("disable_due_date"); - } -}); - -frappe.ui.form.on('Purchase Invoice', { - setup: (frm) => { - frm.make_methods = { - 'Landed Cost Voucher': function () { frm.trigger('create_landedcost_voucher') }, - } - }, - - mode_of_payment: function(frm) { - get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ - frm.set_value('cash_bank_account', account); - }) - }, - - payment_terms_template: function() { - cur_frm.trigger("disable_due_date"); - }, - - create_landedcost_voucher: function (frm) { - let lcv = frappe.model.get_new_doc('Landed Cost Voucher'); - lcv.company = frm.doc.company; - - let lcv_receipt = frappe.model.get_new_doc('Landed Cost Purchase Invoice'); - lcv_receipt.receipt_document_type = 'Purchase Invoice'; - lcv_receipt.receipt_document = frm.doc.name; - lcv_receipt.supplier = frm.doc.supplier; - lcv_receipt.grand_total = frm.doc.grand_total; - lcv.purchase_receipts = [lcv_receipt]; - - frappe.set_route("Form", lcv.doctype, lcv.name); - } -}); - -frappe.ui.form.on("Payment Schedule", { - payment_schedule_remove: function() { - cur_frm.trigger("disable_due_date"); - }, - -}); - -frappe.ui.form.on('Payment Entry', { - mode_of_payment: function(frm) { - get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ - var payment_account_field = frm.doc.payment_type == "Receive" ? "paid_to" : "paid_from"; - frm.set_value(payment_account_field, account); - }) - } -}) - -frappe.ui.form.on('Salary Structure', { - mode_of_payment: function(frm) { - get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ - frm.set_value("payment_account", account); - }) - } -}) - -var get_payment_mode_account = function(frm, mode_of_payment, callback) { - if(!frm.doc.company) { - frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")}); - } - - if(!mode_of_payment) { - return; - } - - return frappe.call({ - method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account", - args: { - "mode_of_payment": mode_of_payment, - "company": frm.doc.company - }, - callback: function(r, rt) { - if(r.message) { - callback(r.message.account) + } else if(tax.category == "Valuation") { + frappe.throw(__("Valuation type charges can not marked as Inclusive")); } } - }); + } } -cur_frm.cscript.account_head = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; +erpnext.accounts.payment_triggers = { + setup: function(doctype) { + frappe.form.ui.on(doctype, { + allocate_advances_automatically(frm) { + frm.trigger('fetch_advances'); + }, - if (doc.docstatus == 1) { - // Should not trigger any changes on change post submit - return; - } + only_include_allocated_payments(frm) { + frm.trigger('fetch_advances'); + }, - if(!d.charge_type && d.account_head){ - frappe.msgprint(__("Please select Charge Type first")); - frappe.model.set_value(cdt, cdn, "account_head", ""); - } else if (d.account_head) { - frappe.call({ - type:"GET", - method: "erpnext.controllers.accounts_controller.get_tax_rate", - args: {"account_head":d.account_head}, - callback: function(r) { - if (d.charge_type!=="Actual") { - frappe.model.set_value(cdt, cdn, "rate", r.message.tax_rate || 0); + fetch_advances(frm) { + if(frm.doc.allocate_advances_automatically) { + frappe.call({ + doc: frm.doc, + method: "set_advances", + callback: function(r, rt) { + refresh_field("advances"); + } + }) } - frappe.model.set_value(cdt, cdn, "description", r.message.account_name); } - }) - } + }); + }, } -cur_frm.cscript.validate_taxes_and_charges = function(cdt, cdn) { - var d = locals[cdt][cdn]; - var msg = ""; - - if (d.account_head && !d.description) { - // set description from account head - d.description = d.account_head.split(' - ').slice(0, -1).join(' - '); - } - - if (!d.charge_type && (d.row_id || d.rate || d.tax_amount)) { - msg = __("Please select Charge Type first"); - d.row_id = ""; - d.rate = d.tax_amount = 0.0; - } else if ((d.charge_type == 'Actual' || d.charge_type == 'On Net Total' || d.charge_type == 'On Paid Amount') && d.row_id) { - msg = __("Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'"); - d.row_id = ""; - } else if ((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id) { - if (d.idx == 1) { - msg = __("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"); - d.charge_type = ''; - } else if (!d.row_id) { - msg = __("Please specify a valid Row ID for row {0} in table {1}", [d.idx, __(d.doctype)]); - d.row_id = ""; - } else if (d.row_id && d.row_id >= d.idx) { - msg = __("Cannot refer row number greater than or equal to current row number for this Charge type"); - d.row_id = ""; - } - } - if (msg) { - frappe.validated = false; - refresh_field("taxes"); - frappe.throw(msg); - } - -} - -cur_frm.cscript.validate_inclusive_tax = function(tax) { - var actual_type_error = function() { - var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx]) - frappe.throw(msg); - }; - - var on_previous_row_error = function(row_range) { - var msg = __("For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included", - [tax.idx, __(tax.doctype), tax.charge_type, row_range]) - frappe.throw(msg); - }; - - if(cint(tax.included_in_print_rate)) { - if(tax.charge_type == "Actual") { - // inclusive tax cannot be of type Actual - actual_type_error(); - } else if(tax.charge_type == "On Previous Row Amount" && - !cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate) - ) { - // referred row should also be an inclusive tax - on_previous_row_error(tax.row_id); - } else if(tax.charge_type == "On Previous Row Total") { - var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id), - function(t) { return cint(t.included_in_print_rate) ? null : t; }); - if(taxes_not_included.length > 0) { - // all rows above this tax should be inclusive - on_previous_row_error(tax.row_id == 1 ? "1" : "1 - " + tax.row_id); +erpnext.accounts.pos = { + setup: function(doctype) { + frappe.ui.form.on(doctype, { + mode_of_payment: function(frm, cdt, cdn) { + var d = locals[cdt][cdn]; + get_payment_mode_account(frm, d.mode_of_payment, function(account){ + frappe.model.set_value(cdt, cdn, 'account', account) + }) } - } else if(tax.category == "Valuation") { - frappe.throw(__("Valuation type charges can not marked as Inclusive")); - } - } -} - -if(!erpnext.taxes.flags[cur_frm.cscript.tax_table]) { - erpnext.taxes.flags[cur_frm.cscript.tax_table] = true; - - frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) { - cur_frm.cscript.validate_taxes_and_charges(cdt, cdn); - }); - - frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) { - cur_frm.cscript.validate_taxes_and_charges(cdt, cdn); - }); - - frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) { - cur_frm.cscript.validate_taxes_and_charges(cdt, cdn); - }); - - frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) { - frm.cscript.validate_taxes_and_charges(cdt, cdn); - var open_form = frm.open_grid_row(); - if(open_form) { - erpnext.taxes.set_conditional_mandatory_rate_or_amount(open_form); - } else { - // apply in current row - erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm.get_field('taxes').grid.get_row(cdn)); - } - }); - - frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) { - var tax = frappe.get_doc(cdt, cdn); - try { - cur_frm.cscript.validate_taxes_and_charges(cdt, cdn); - cur_frm.cscript.validate_inclusive_tax(tax); - } catch(e) { - tax.included_in_print_rate = 0; - refresh_field("included_in_print_rate", tax.name, tax.parentfield); - throw e; - } - }); -} - -erpnext.taxes.set_conditional_mandatory_rate_or_amount = function(grid_row) { - if(grid_row) { - if(grid_row.doc.charge_type==="Actual") { - grid_row.toggle_editable("tax_amount", true); - grid_row.toggle_reqd("tax_amount", true); - grid_row.toggle_editable("rate", false); - grid_row.toggle_reqd("rate", false); - } else { - grid_row.toggle_editable("rate", true); - grid_row.toggle_reqd("rate", true); - grid_row.toggle_editable("tax_amount", false); - grid_row.toggle_reqd("tax_amount", false); + }); + }, + + get_payment_mode_account: function(frm, mode_of_payment, callback) { + if(!frm.doc.company) { + frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")}); } + + if(!mode_of_payment) { + return; + } + + return frappe.call({ + method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account", + args: { + "mode_of_payment": mode_of_payment, + "company": frm.doc.company + }, + callback: function(r, rt) { + if(r.message) { + callback(r.message.account) + } + } + }); } } diff --git a/erpnext/public/js/erpnext.bundle.js b/erpnext/public/js/erpnext.bundle.js index 85a2e242dbf..0f4a65017ca 100644 --- a/erpnext/public/js/erpnext.bundle.js +++ b/erpnext/public/js/erpnext.bundle.js @@ -24,5 +24,6 @@ import "./bulk_transaction_processing"; import "./utils/crm_activities"; import "./templates/crm_activities.html"; import "./templates/crm_notes.html"; +import "./controllers/accounts.js" // import { sum } from 'frappe/public/utils/util.js' diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 5d43a07d96c..2707ded5e3a 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -3,6 +3,9 @@ {% include 'erpnext/selling/sales_common.js' %} +erpnext.accounts.taxes.setup_tax_filters("Sales Taxes and Charges"); +erpnext.accounts.taxes.setup_tax_validations("Sales Order"); + frappe.ui.form.on("Sales Order", { setup: function(frm) { frm.custom_make_buttons = { diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index a648195933b..1df797301e4 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -9,6 +9,10 @@ frappe.provide("erpnext.stock"); frappe.provide("erpnext.stock.delivery_note"); frappe.provide("erpnext.accounts.dimensions"); +erpnext.accounts.taxes.setup_tax_filters("Sales Taxes and Charges"); +erpnext.accounts.taxes.setup_tax_validations("Delivery Note"); + + frappe.ui.form.on("Delivery Note", { setup: function(frm) { frm.custom_make_buttons = { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 35aad78c1a3..5eb7c55087b 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -5,6 +5,9 @@ frappe.provide("erpnext.stock"); +erpnext.accounts.taxes.setup_tax_filters("Purchase Taxes and Charges"); +erpnext.accounts.taxes.setup_tax_validations("Purchase Receipt"); + frappe.ui.form.on("Purchase Receipt", { setup: (frm) => { frm.make_methods = {