feat: Tax deduction against advance payments

This commit is contained in:
Deepesh Garg 2020-10-01 13:56:55 +05:30
parent c9aa726818
commit 61c5e478af
6 changed files with 607 additions and 210 deletions

View File

@ -3,6 +3,8 @@
{% include "erpnext/public/js/controllers/accounts.js" %}
frappe.provide("erpnext.accounts.dimensions");
cur_frm.cscript.tax_table = "Advance Taxes and Charges";
frappe.ui.form.on('Payment Entry', {
onload: function(frm) {
if(frm.doc.__islocal) {
@ -182,6 +184,8 @@ frappe.ui.form.on('Payment Entry', {
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
(frm.doc.paid_from_account_currency != company_currency));
frm.toggle_display("base_received_amount", (
frm.doc.paid_to_account_currency != company_currency
@ -843,12 +847,12 @@ frappe.ui.form.on('Payment Entry', {
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
unallocated_amount = (frm.doc.base_received_amount + total_deductions
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
unallocated_amount = (frm.doc.base_received_amount + total_deductions + frm.doc.base_total_taxes_and_charges
+ frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
&& frm.doc.total_allocated_amount < frm.doc.received_amount + (total_deductions / frm.doc.target_exchange_rate)) {
unallocated_amount = (frm.doc.base_paid_amount - (total_deductions
unallocated_amount = (frm.doc.base_paid_amount + frm.doc.base_total_taxes_and_charges - (total_deductions
+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
}
}
@ -874,7 +878,8 @@ frappe.ui.form.on('Payment Entry', {
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
frm.set_value("difference_amount", difference_amount - total_deductions);
frm.set_value("difference_amount", difference_amount - total_deductions +
frm.doc.base_total_taxes_and_charges);
frm.events.hide_unhide_fields(frm);
},
@ -1002,7 +1007,107 @@ frappe.ui.form.on('Payment Entry', {
}
});
}
}
},
sales_taxes_and_charges_template: function(frm) {
frm.trigger('fetch_taxes_from_template');
},
purchase_taxes_and_charges_template: function(frm) {
frm.trigger('fetch_taxes_from_template');
},
fetch_taxes_from_template: function(frm) {
let master_doctype = '';
let taxes_and_charges = '';
if (frm.doc.party_type == 'Supplier') {
master_doctype = 'Purchase Taxes and Charges Template';
taxes_and_charges = frm.doc.purchase_taxes_and_charges_template;
} else if (frm.doc.party_type == 'Customer') {
master_doctype = 'Sales Taxes and Charges Template';
taxes_and_charges = frm.doc.sales_taxes_and_charges_template;
}
if (!taxes_and_charges) {
return;
}
frappe.call({
method: "erpnext.controllers.accounts_controller.get_taxes_and_charges",
args: {
"master_doctype": master_doctype,
"master_name": taxes_and_charges
},
callback: function(r) {
if(!r.exc && r.message) {
// set taxes table
if(r.message) {
for (let tax of r.message) {
if (tax.charge_type === 'On Net Total') {
tax.charge_type = 'On Paid Amount';
}
me.frm.add_child("taxes", tax);
}
frm.trigger('calculate_taxes');
frm.events.set_unallocated_amount(frm);
}
}
}
});
},
calculate_taxes: function(frm) {
frm.doc.total_taxes_and_charges = 0.0;
frm.doc.base_total_taxes_and_charges = 0.0;
$.each(me.frm.doc["taxes"] || [], function(i, tax) {
let tax_rate = tax.rate;
let current_tax_amount = 0.0;
// To set row_id by default as previous row.
if(["On Previous Row Amount", "On Previous Row Total"].includes(tax.charge_type)) {
if (tax.idx === 1) {
frappe.throw(__("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"));
}
if (!tax.row_id) {
tax.row_id = tax.idx - 1;
}
}
if(tax.charge_type == "Actual") {
current_tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
} else if(tax.charge_type == "On Paid Amount") {
current_tax_amount = (tax_rate / 100.0) * frm.doc.paid_amount;
} else if(tax.charge_type == "On Previous Row Amount") {
current_tax_amount = (tax_rate / 100.0) *
frm.doc["taxes"][cint(tax.row_id) - 1].tax_amount;
} else if(tax.charge_type == "On Previous Row Total") {
current_tax_amount = (tax_rate / 100.0) *
frm.doc["taxes"][cint(tax.row_id) - 1].total;
}
tax.tax_amount = current_tax_amount;
tax.base_tax_amount = tax.tax_amount * frm.doc.source_exchange_rate;
current_tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
if(i==0) {
tax.total = flt(frm.doc.paid_amount + current_tax_amount, precision("total", tax));
} else {
tax.total = flt(frm.doc["taxes"][i-1].total + current_tax_amount, precision("total", tax));
}
tax.base_total = tax.total * frm.doc.source_exchange_rate;
frm.doc.total_taxes_and_charges += current_tax_amount;
frm.doc.base_total_taxes_and_charges += current_tax_amount * frm.doc.source_exchange_rate;
frm.refresh_field('taxes');
frm.refresh_field('total_taxes_and_charges');
frm.refresh_field('base_total_taxes_and_charges');
});
},
});
@ -1049,6 +1154,28 @@ frappe.ui.form.on('Payment Entry Reference', {
}
})
frappe.ui.form.on('Advance Taxes and Charges', {
rate: function(frm) {
frm.events.calculate_taxes(frm);
frm.events.set_unallocated_amount(frm);
},
tax_amount : function(frm) {
frm.events.calculate_taxes(frm);
frm.events.set_unallocated_amount(frm);
},
row_id: function(frm) {
frm.events.calculate_taxes(frm);
frm.events.set_unallocated_amount(frm);
},
taxes_remove: function(frm) {
frm.events.calculate_taxes(frm);
frm.events.set_unallocated_amount(frm);
}
})
frappe.ui.form.on('Payment Entry Deduction', {
amount: function(frm) {
frm.events.set_unallocated_amount(frm);

View File

@ -24,6 +24,10 @@
"party_bank_account",
"contact_person",
"contact_email",
"tds_details_section",
"tax_withholding_category",
"column_break_20",
"apply_tax_withholding_amount",
"payment_accounts_section",
"party_balance",
"paid_from",
@ -52,6 +56,12 @@
"unallocated_amount",
"difference_amount",
"write_off_difference_amount",
"taxes_and_charges_section",
"purchase_taxes_and_charges_template",
"sales_taxes_and_charges_template",
"taxes",
"base_total_taxes_and_charges",
"total_taxes_and_charges",
"deductions_or_loss_section",
"deductions",
"transaction_references",
@ -82,7 +92,9 @@
{
"fieldname": "type_of_payment",
"fieldtype": "Section Break",
"label": "Type of Payment"
"label": "Type of Payment",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -92,7 +104,9 @@
"options": "ACC-PAY-.YYYY.-",
"print_hide": 1,
"reqd": 1,
"set_only_once": 1
"set_only_once": 1,
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -103,11 +117,15 @@
"label": "Payment Type",
"options": "Receive\nPay\nInternal Transfer",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_5",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -116,7 +134,9 @@
"fieldtype": "Date",
"in_list_view": 1,
"label": "Posting Date",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "company",
@ -125,26 +145,34 @@
"options": "Company",
"print_hide": 1,
"remember_last_selected_value": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
"options": "Cost Center",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Mode of Payment",
"options": "Mode of Payment"
"options": "Mode of Payment",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
"fieldname": "party_section",
"fieldtype": "Section Break",
"label": "Payment From / To"
"label": "Payment From / To",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.docstatus==0",
@ -154,7 +182,9 @@
"label": "Party Type",
"options": "DocType",
"print_hide": 1,
"search_index": 1
"search_index": 1,
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -163,7 +193,9 @@
"fieldtype": "Dynamic Link",
"in_standard_filter": 1,
"label": "Party",
"options": "party_type"
"options": "party_type",
"show_days": 1,
"show_seconds": 1
},
{
"allow_on_submit": 1,
@ -171,18 +203,24 @@
"fieldname": "party_name",
"fieldtype": "Data",
"in_global_search": 1,
"label": "Party Name"
"label": "Party Name",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "party",
"fieldname": "contact_person",
"fieldtype": "Link",
"label": "Contact",
"options": "Contact"
"options": "Contact",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "contact_person",
@ -190,13 +228,17 @@
"fieldtype": "Data",
"label": "Email",
"options": "Email",
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"collapsible": 1,
"fieldname": "payment_accounts_section",
"fieldtype": "Section Break",
"label": "Accounts"
"label": "Accounts",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "party",
@ -204,7 +246,9 @@
"fieldtype": "Currency",
"label": "Party Balance",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -215,7 +259,9 @@
"label": "Account Paid From",
"options": "Account",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "paid_from",
@ -225,7 +271,9 @@
"options": "Currency",
"print_hide": 1,
"read_only": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "paid_from",
@ -234,11 +282,15 @@
"label": "Account Balance",
"options": "paid_from_account_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_18",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:(in_list([\"Internal Transfer\", \"Receive\"], doc.payment_type) || doc.party)",
@ -248,7 +300,9 @@
"label": "Account Paid To",
"options": "Account",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "paid_to",
@ -258,7 +312,9 @@
"options": "Currency",
"print_hide": 1,
"read_only": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "paid_to",
@ -267,13 +323,17 @@
"label": "Account Balance",
"options": "paid_to_account_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:(doc.paid_to && doc.paid_from)",
"fieldname": "payment_amounts_section",
"fieldtype": "Section Break",
"label": "Amount"
"label": "Amount",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -281,14 +341,18 @@
"fieldtype": "Currency",
"label": "Paid Amount",
"options": "paid_from_account_currency",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "source_exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_paid_amount",
@ -297,11 +361,15 @@
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_21",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -310,14 +378,18 @@
"label": "Received Amount",
"options": "paid_to_account_currency",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "target_exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate",
"print_hide": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_received_amount",
@ -326,30 +398,40 @@
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1,
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
"fieldname": "section_break_14",
"fieldtype": "Section Break",
"label": "Reference"
"label": "Reference",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:doc.docstatus==0",
"fieldname": "get_outstanding_invoice",
"fieldtype": "Button",
"label": "Get Outstanding Invoice"
"label": "Get Outstanding Invoice",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "references",
"fieldtype": "Table",
"label": "Payment References",
"options": "Payment Entry Reference"
"options": "Payment Entry Reference",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "section_break_34",
"fieldtype": "Section Break",
"label": "Writeoff"
"label": "Writeoff",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -358,7 +440,9 @@
"fieldtype": "Currency",
"label": "Total Allocated Amount",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_total_allocated_amount",
@ -366,23 +450,31 @@
"label": "Total Allocated Amount (Company Currency)",
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "set_exchange_gain_loss",
"fieldtype": "Button",
"label": "Set Exchange Gain / Loss"
"label": "Set Exchange Gain / Loss",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_36",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:(doc.paid_amount && doc.received_amount && doc.references)",
"fieldname": "unallocated_amount",
"fieldtype": "Currency",
"label": "Unallocated Amount",
"print_hide": 1
"print_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -392,13 +484,17 @@
"label": "Difference Amount (Company Currency)",
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "difference_amount",
"fieldname": "write_off_difference_amount",
"fieldtype": "Button",
"label": "Write Off Difference Amount"
"label": "Write Off Difference Amount",
"show_days": 1,
"show_seconds": 1
},
{
"collapsible": 1,
@ -406,29 +502,39 @@
"depends_on": "eval:(doc.paid_amount && doc.received_amount)",
"fieldname": "deductions_or_loss_section",
"fieldtype": "Section Break",
"label": "Deductions or Loss"
"label": "Deductions or Loss",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "deductions",
"fieldtype": "Table",
"label": "Payment Deductions or Loss",
"options": "Payment Entry Deduction"
"options": "Payment Entry Deduction",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "transaction_references",
"fieldtype": "Section Break",
"label": "Transaction ID"
"label": "Transaction ID",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
"depends_on": "eval:(doc.paid_from && doc.paid_to)",
"fieldname": "reference_no",
"fieldtype": "Data",
"label": "Cheque/Reference No"
"label": "Cheque/Reference No",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_23",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"bold": 1,
@ -436,7 +542,9 @@
"fieldname": "reference_date",
"fieldtype": "Date",
"label": "Cheque/Reference Date",
"search_index": 1
"search_index": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:doc.docstatus==1",
@ -445,21 +553,27 @@
"label": "Clearance Date",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"collapsible": 1,
"depends_on": "eval:(doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
"fieldname": "section_break_12",
"fieldtype": "Section Break",
"label": "More Information"
"label": "More Information",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project",
"print_hide": 1
"print_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "remarks",
@ -470,33 +584,43 @@
},
{
"fieldname": "column_break_16",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "letter_head",
"fieldtype": "Link",
"label": "Letter Head",
"options": "Letter Head",
"print_hide": 1
"print_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "print_heading",
"fieldtype": "Link",
"label": "Print Heading",
"options": "Print Heading",
"print_hide": 1
"print_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fetch_from": "bank_account.bank",
"fieldname": "bank",
"fieldtype": "Read Only",
"label": "Bank"
"label": "Bank",
"show_days": 1,
"show_seconds": 1
},
{
"fetch_from": "bank_account.bank_account_no",
"fieldname": "bank_account_no",
"fieldtype": "Read Only",
"label": "Bank Account No"
"label": "Bank Account No",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "payment_order",
@ -505,12 +629,16 @@
"no_copy": 1,
"options": "Payment Order",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"label": "Subscription Section"
"label": "Subscription Section",
"show_days": 1,
"show_seconds": 1
},
{
"allow_on_submit": 1,
@ -520,7 +648,9 @@
"no_copy": 1,
"options": "Auto Repeat",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "amended_from",
@ -529,7 +659,9 @@
"no_copy": 1,
"options": "Payment Entry",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "title",
@ -544,14 +676,18 @@
"fieldname": "bank_account",
"fieldtype": "Link",
"label": "Company Bank Account",
"options": "Bank Account"
"options": "Bank Account",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "party",
"fieldname": "party_bank_account",
"fieldtype": "Link",
"label": "Party Bank Account",
"options": "Bank Account"
"options": "Bank Account",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "payment_order_status",
@ -559,17 +695,23 @@
"hidden": 1,
"label": "Payment Order Status",
"options": "Initiated\nPayment Ordered",
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
"label": "Accounting Dimensions",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"default": "Draft",
@ -584,12 +726,94 @@
"fieldname": "custom_remarks",
"fieldtype": "Check",
"label": "Custom Remarks"
},
{
"depends_on": "eval: doc.payment_type == 'Pay' && doc.party_type == 'Supplier'",
"fieldname": "tds_details_section",
"fieldtype": "Section Break",
"label": "TDS Details",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"label": "Tax Withholding Category",
"options": "Tax Withholding Category",
"show_days": 1,
"show_seconds": 1
},
{
"default": "0",
"fieldname": "apply_tax_withholding_amount",
"fieldtype": "Check",
"label": "Apply Tax Withholding Amount",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"collapsible": 1,
"fieldname": "taxes_and_charges_section",
"fieldtype": "Section Break",
"label": "Taxes and Charges",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:doc.party_type == 'Supplier'",
"fieldname": "purchase_taxes_and_charges_template",
"fieldtype": "Link",
"label": "Taxes and Charges Template",
"options": "Purchase Taxes and Charges Template",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval: doc.party_type == 'Customer'",
"fieldname": "sales_taxes_and_charges_template",
"fieldtype": "Link",
"label": "Taxes and Charges Template",
"options": "Sales Taxes and Charges Template",
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval: doc.party_type == 'Supplier' || doc.party_type == 'Customer'",
"fieldname": "taxes",
"fieldtype": "Table",
"label": "Advance Taxes and Charges",
"options": "Advance Taxes and Charges",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"label": "Total Taxes and Charges (Company Currency)",
"options": "Company:company:default_currency",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"label": "Total Taxes and Charges",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-03-08 13:05:16.958866",
"modified": "2020-09-13 22:33:59.860146",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@ -5,7 +5,7 @@
from __future__ import unicode_literals
import frappe, erpnext, json
from frappe import _, scrub, ValidationError
from frappe.utils import flt, comma_or, nowdate, getdate
from frappe.utils import flt, comma_or, nowdate, getdate, cint
from erpnext.accounts.utils import get_outstanding_invoices, get_account_currency, get_balance_on
from erpnext.accounts.party import get_party_account
from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
@ -15,6 +15,7 @@ from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amo
from erpnext.accounts.doctype.bank_account.bank_account import get_party_bank_account, get_bank_account_details
from erpnext.controllers.accounts_controller import AccountsController, get_supplier_block_status
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
from six import string_types, iteritems
@ -52,6 +53,8 @@ class PaymentEntry(AccountsController):
self.set_exchange_rate()
self.validate_mandatory()
self.validate_reference_documents()
self.set_tax_withholding()
self.calculate_taxes()
self.set_amounts()
self.clear_unallocated_reference_document_rows()
self.validate_payment_against_negative_invoice()
@ -386,6 +389,43 @@ class PaymentEntry(AccountsController):
else:
self.status = 'Draft'
def set_tax_withholding(self):
if not self.party_type == 'Supplier':
return
if not self.apply_tax_withholding_amount:
return
if self.references:
return
args = frappe._dict({
'company': self.company,
'supplier': self.party,
'posting_date': self.posting_date,
'net_total': self.paid_amount
})
tax_withholding_details = get_party_tax_withholding_details(args, self.tax_withholding_category)
if not tax_withholding_details:
return
accounts = []
for d in self.taxes:
if d.account_head == tax_withholding_details.get("account_head"):
d.update(tax_withholding_details)
accounts.append(d.account_head)
if not accounts or tax_withholding_details.get("account_head") not in accounts:
self.append("taxes", tax_withholding_details)
to_remove = [d for d in self.taxes
if not d.tax_amount and d.account_head == tax_withholding_details.get("account_head")]
for d in to_remove:
self.remove(d)
def set_amounts(self):
self.set_amounts_in_company_currency()
self.set_total_allocated_amount()
@ -423,12 +463,12 @@ class PaymentEntry(AccountsController):
if self.payment_type == "Receive" \
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
self.unallocated_amount = (self.base_received_amount + total_deductions -
self.unallocated_amount = (self.base_received_amount + self.base_total_taxes_and_charges + total_deductions -
self.base_total_allocated_amount) / self.source_exchange_rate
elif self.payment_type == "Pay" \
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
self.unallocated_amount = (self.base_paid_amount + self.base_total_taxes_and_charges - (total_deductions +
self.base_total_allocated_amount)) / self.target_exchange_rate
def set_difference_amount(self):
@ -446,7 +486,7 @@ class PaymentEntry(AccountsController):
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
self.difference_amount = flt(self.difference_amount - total_deductions,
self.difference_amount = flt(self.difference_amount - total_deductions + self.base_total_taxes_and_charges,
self.precision("difference_amount"))
# Paid amount is auto allocated in the reference document by default.
@ -532,6 +572,7 @@ class PaymentEntry(AccountsController):
self.add_party_gl_entries(gl_entries)
self.add_bank_gl_entries(gl_entries)
self.add_deductions_gl_entries(gl_entries)
self.add_tax_gl_entries(gl_entries)
make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj)
@ -607,6 +648,26 @@ class PaymentEntry(AccountsController):
}, item=self)
)
def add_tax_gl_entries(self, gl_entries):
for d in self.get('taxes'):
account_currency = get_account_currency(d.account_head)
if account_currency != self.company_currency:
frappe.throw(_("Currency for {0} must be {1}").format(d.account_head, self.company_currency))
dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
gl_entries.append(
self.get_gl_dict({
"account": d.account_head,
"against": self.party if self.payment_type=="Receive" else self.paid_from,
dr_or_cr: d.base_tax_amount,
dr_or_cr + "_in_account_currency": d.base_tax_amount \
if account_currency==self.company_currency \
else d.tax_amount,
"cost_center": d.cost_center
}, account_currency, item=d)
)
def add_deductions_gl_entries(self, gl_entries):
for d in self.get("deductions"):
if d.amount:
@ -671,6 +732,51 @@ class PaymentEntry(AccountsController):
self.append('deductions', row)
self.set_unallocated_amount()
def calculate_taxes(self):
self.total_taxes_and_charges = 0.0
self.base_total_taxes_and_charges = 0.0
for i, tax in enumerate(self.taxes):
tax_rate = tax.rate
current_tax_rate = 0.0
# To set row_id by default as previous row.
if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"]:
if tax.idx == 1:
frappe.throw(_("Cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for first row"))
if not tax.row_id:
tax.row_id = tax.idx - 1
if tax.charge_type == "Actual":
current_tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax))
elif tax.charge_type == "On Paid Amount":
current_tax_amount = (tax_rate / 100.0) * self.paid_amount
elif tax.charge_type == "On Previous Row Amount":
current_tax_amount = (tax_rate / 100.0) * \
self.taxes[cint(tax.row_id) - 1].tax_amount
elif tax.charge_type == "On Previous Row Total":
current_tax_amount = (tax_rate / 100.0) * \
self.taxes[cint(tax.row_id) - 1].total
tax.tax_amount = current_tax_amount
tax.base_tax_amount = tax.tax_amount * self.source_exchange_rate
if tax.add_deduct_tax == "Deduct":
current_tax_amount *= -1.0
else:
current_tax_amount *= 1.0
if i == 0:
tax.total = flt(self.paid_amount + current_tax_amount, self.precision("total", tax))
else:
tax.total = flt(self.taxes[i-1].total + current_tax_amount, self.precision("total", tax))
tax.base_total = tax.total * self.source_exchange_rate
self.total_taxes_and_charges += current_tax_amount
self.base_total_taxes_and_charges += current_tax_amount * self.source_exchange_rate
@frappe.whitelist()
def get_outstanding_reference_documents(args):

View File

@ -1,140 +1,70 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2016-06-15 15:56:30.815503",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"actions": [],
"creation": "2016-06-15 15:56:30.815503",
"doctype": "DocType",
"editable_grid": 1,
"field_order": [
"account",
"cost_center",
"amount",
"column_break_2",
"description"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Account",
"options": "Account",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Cost Center",
"length": 0,
"no_copy": 0,
"options": "Cost Center",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "cost_center",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Cost Center",
"options": "Cost Center",
"print_hide": 1,
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description",
"show_days": 1,
"show_seconds": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2019-01-07 16:52:07.040146",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Deduction",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2020-09-12 20:38:08.110674",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Deduction",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -617,6 +617,10 @@ class AccountsController(TransactionBase):
payment_entries = get_advance_payment_entries(party_type, party, party_account,
order_doctype, order_list, include_unallocated)
payment_entry_list = [d.reference_name for d in payment_entries]
payment_entry_taxes = get_payment_entry_taxes(payment_entry_list)
res = journal_entries + payment_entries
return res
@ -1241,6 +1245,12 @@ def get_advance_payment_entries(party_type, party, party_account, order_doctype,
return list(payment_entries_against_order) + list(unallocated_payment_entries)
def get_payment_entry_taxes(payment_entry_list):
taxes = frappe.db.sql("""
SELECT t.parent, t.add_deduct_tax, t.charge_type, t.account_head, t.cost_center,
t.tax_amount FROM `tabAdvance Taxes and Charges` where t.parent in %s"""
,(payment_entry_list, ), as_dict=1)
def update_invoice_status():
# Daily update the status of the invoices

View File

@ -165,7 +165,7 @@ cur_frm.cscript.validate_taxes_and_charges = function(cdt, cdn) {
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.row_id) {
} 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) {