fix: TDS against Purhase Orders

This commit is contained in:
Deepesh Garg 2020-11-02 19:57:27 +05:30
parent 61c5e478af
commit c26de28613
10 changed files with 635 additions and 209 deletions

View File

@ -33,7 +33,7 @@
"label": "Type",
"oldfieldname": "charge_type",
"oldfieldtype": "Select",
"options": "\nActual\nOn Paid Amount\nOn Previous Row Amount\nOn Previous Row Total",
"options": "\nActual\nOn Paid Amount\nIncluded In Paid Amount\nOn Previous Row Amount\nOn Previous Row Total",
"reqd": 1,
"show_days": 1,
"show_seconds": 1
@ -190,7 +190,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2020-09-12 22:30:36.150935",
"modified": "2020-10-27 20:02:34.734260",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Advance Taxes and Charges",

View File

@ -220,7 +220,7 @@ frappe.ui.form.on('Payment Entry', {
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
frm.set_currency_labels(["base_paid_amount", "base_received_amount", "base_total_allocated_amount",
"difference_amount"], company_currency);
"difference_amount", "base_paid_amount_after_tax"], company_currency);
frm.set_currency_labels(["paid_amount"], frm.doc.paid_from_account_currency);
frm.set_currency_labels(["received_amount"], frm.doc.paid_to_account_currency);
@ -368,6 +368,16 @@ frappe.ui.form.on('Payment Entry', {
}
},
apply_tax_withholding_amount: function(frm) {
if (!frm.doc.apply_tax_withholding_amount) {
frm.set_value("tax_withholding_category", '');
} else {
frappe.db.get_value('Supplier', frm.doc.party, 'tax_withholding_category', (values) => {
frm.set_value("tax_withholding_category", values.tax_withholding_category);
});
}
},
paid_from: function(frm) {
if(frm.set_party_account_based_on_party) return;

View File

@ -25,9 +25,9 @@
"contact_person",
"contact_email",
"tds_details_section",
"tax_withholding_category",
"column_break_20",
"apply_tax_withholding_amount",
"column_break_20",
"tax_withholding_category",
"payment_accounts_section",
"party_balance",
"paid_from",
@ -39,8 +39,10 @@
"paid_to_account_balance",
"payment_amounts_section",
"paid_amount",
"paid_amount_after_tax",
"source_exchange_rate",
"base_paid_amount",
"base_paid_amount_after_tax",
"column_break_21",
"received_amount",
"target_exchange_rate",
@ -580,7 +582,9 @@
"fieldtype": "Small Text",
"label": "Remarks",
"no_copy": 1,
"read_only_depends_on": "eval:doc.custom_remarks == 0"
"read_only_depends_on": "eval:doc.custom_remarks == 0",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_16",
@ -736,6 +740,7 @@
"show_seconds": 1
},
{
"depends_on": "eval:doc.apply_tax_withholding_amount",
"fieldname": "tax_withholding_category",
"fieldtype": "Link",
"label": "Tax Withholding Category",
@ -808,12 +813,30 @@
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "paid_amount_after_tax",
"fieldtype": "Currency",
"hidden": 1,
"label": "Paid Amount After Tax",
"options": "paid_from_account_currency",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_paid_amount_after_tax",
"fieldtype": "Currency",
"label": "Paid Amount After Tax (Company Currency)",
"options": "Company:company:default_currency",
"show_days": 1,
"show_seconds": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2020-09-13 22:33:59.860146",
"modified": "2020-10-25 20:50:14.896628",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@ -396,9 +396,6 @@ class PaymentEntry(AccountsController):
if not self.apply_tax_withholding_amount:
return
if self.references:
return
args = frappe._dict({
'company': self.company,
'supplier': self.party,
@ -427,11 +424,18 @@ class PaymentEntry(AccountsController):
self.remove(d)
def set_amounts(self):
self.set_amounts_after_tax()
self.set_amounts_in_company_currency()
self.set_total_allocated_amount()
self.set_unallocated_amount()
self.set_difference_amount()
def set_amounts_after_tax(self):
self.paid_amount_after_tax = flt(flt(self.paid_amount) + flt(self.total_taxes_and_charges),
self.precision("paid_amount_after_tax"))
self.base_paid_amount_after_tax = flt(flt(self.paid_amount_after_tax) * flt(self.source_exchange_rate),
self.precision("base_paid_amount_after_tax"))
def set_amounts_in_company_currency(self):
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
if self.paid_amount:
@ -463,12 +467,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 + self.base_total_taxes_and_charges + total_deductions -
self.unallocated_amount = (self.base_received_amount + 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 + self.base_total_taxes_and_charges - (total_deductions +
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
self.base_total_allocated_amount)) / self.target_exchange_rate
def set_difference_amount(self):
@ -486,7 +490,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.base_total_taxes_and_charges,
self.difference_amount = flt(self.difference_amount - total_deductions,
self.precision("difference_amount"))
# Paid amount is auto allocated in the reference document by default.
@ -631,8 +635,8 @@ class PaymentEntry(AccountsController):
"account": self.paid_from,
"account_currency": self.paid_from_account_currency,
"against": self.party if self.payment_type=="Pay" else self.paid_to,
"credit_in_account_currency": self.paid_amount,
"credit": self.base_paid_amount,
"credit_in_account_currency": self.paid_amount_after_tax,
"credit": self.base_paid_amount_after_tax,
"cost_center": self.cost_center
}, item=self)
)
@ -654,7 +658,10 @@ class PaymentEntry(AccountsController):
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"
if self.payment_type == 'Pay':
dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
elif self.payment_type == 'Receive':
dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
gl_entries.append(
self.get_gl_dict({

View File

@ -1088,9 +1088,10 @@ class PurchaseInvoice(BuyingController):
accounts = []
for d in self.taxes:
if d.account_head == tax_withholding_details.get("account_head"):
if d.account_head == tax_withholding_details.get("account_head") and not d.is_advance_tax:
d.update(tax_withholding_details)
accounts.append(d.account_head)
if not d.is_advance_tax:
accounts.append(d.account_head)
if not accounts or tax_withholding_details.get("account_head") not in accounts:
self.append("taxes", tax_withholding_details)

View File

@ -28,7 +28,8 @@
"base_tax_amount",
"base_total",
"base_tax_amount_after_discount_amount",
"item_wise_tax_detail"
"item_wise_tax_detail",
"is_advance_tax"
],
"fields": [
{
@ -39,7 +40,9 @@
"oldfieldname": "category",
"oldfieldtype": "Select",
"options": "Valuation and Total\nValuation\nTotal",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"default": "Add",
@ -49,7 +52,9 @@
"oldfieldname": "add_deduct_tax",
"oldfieldtype": "Select",
"options": "Add\nDeduct",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
@ -61,7 +66,9 @@
"oldfieldname": "charge_type",
"oldfieldtype": "Select",
"options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total\nOn Item Quantity",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"depends_on": "eval:[\"On Previous Row Amount\", \"On Previous Row Total\"].indexOf(doc.charge_type)!==-1",
@ -69,7 +76,9 @@
"fieldtype": "Data",
"label": "Reference Row #",
"oldfieldname": "row_id",
"oldfieldtype": "Data"
"oldfieldtype": "Data",
"show_days": 1,
"show_seconds": 1
},
{
"default": "0",
@ -77,11 +86,15 @@
"fieldname": "included_in_print_rate",
"fieldtype": "Check",
"label": "Is this Tax included in Basic Rate?",
"report_hide": 1
"report_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "col_break1",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
@ -92,7 +105,9 @@
"oldfieldname": "account_head",
"oldfieldtype": "Link",
"options": "Account",
"reqd": 1
"reqd": 1,
"show_days": 1,
"show_seconds": 1
},
{
"default": ":Company",
@ -101,7 +116,9 @@
"label": "Cost Center",
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center"
"options": "Cost Center",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "description",
@ -111,11 +128,15 @@
"oldfieldtype": "Small Text",
"print_width": "300px",
"reqd": 1,
"show_days": 1,
"show_seconds": 1,
"width": "300px"
},
{
"fieldname": "section_break_10",
"fieldtype": "Section Break"
"fieldtype": "Section Break",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
@ -124,11 +145,15 @@
"in_list_view": 1,
"label": "Rate",
"oldfieldname": "rate",
"oldfieldtype": "Currency"
"oldfieldtype": "Currency",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "section_break_9",
"fieldtype": "Section Break"
"fieldtype": "Section Break",
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
@ -138,7 +163,9 @@
"label": "Amount",
"oldfieldname": "tax_amount",
"oldfieldtype": "Currency",
"options": "currency"
"options": "currency",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "tax_amount_after_discount_amount",
@ -146,7 +173,9 @@
"label": "Tax Amount After Discount Amount",
"options": "currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"columns": 2,
@ -157,11 +186,15 @@
"oldfieldname": "total",
"oldfieldtype": "Currency",
"options": "currency",
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_14",
"fieldtype": "Column Break"
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_tax_amount",
@ -169,7 +202,9 @@
"label": "Amount (Company Currency)",
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_total",
@ -177,7 +212,9 @@
"hidden": 1,
"label": "Total (Company Currency)",
"options": "Company:company:default_currency",
"print_hide": 1
"print_hide": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "base_tax_amount_after_discount_amount",
@ -185,7 +222,9 @@
"label": "Tax Amount After Discount Amount",
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "item_wise_tax_detail",
@ -195,22 +234,38 @@
"oldfieldname": "item_wise_tax_detail",
"oldfieldtype": "Small Text",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"show_days": 1,
"show_seconds": 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": "0",
"fieldname": "is_advance_tax",
"fieldtype": "Check",
"hidden": 1,
"label": "Is Advance Tax",
"read_only": 1,
"show_days": 1,
"show_seconds": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2020-09-18 17:26:09.703215",
"modified": "2020-10-25 18:24:43.487567",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",

View File

@ -617,10 +617,6 @@ 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
@ -1245,13 +1241,6 @@ 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

@ -40,6 +40,7 @@ class calculate_taxes_and_totals(object):
self.validate_conversion_rate()
self.calculate_item_values()
self.validate_item_tax_template()
self.apply_advance_taxes()
self.initialize_taxes()
self.determine_exclusive_rate()
self.calculate_net_total()
@ -683,6 +684,32 @@ class calculate_taxes_and_totals(object):
self.calculate_paid_amount()
def apply_advance_taxes(self):
if cint(self.doc.get('adjust_advance_taxes')):
if self.doc.get('advances'):
payment_entry_list = [d.reference_name for d in self.doc.get('advances')]
advance_taxes = get_advance_taxes(payment_entry_list)
accounts = []
# Remove already added advance taxes if any
for tax in self.doc.get('taxes'):
if tax.is_advance_tax:
self.doc.remove(tax)
else:
accounts.append(tax.account_head)
for tax in advance_taxes:
# Reverse add deduct from payment entry in invoice
if tax.account_head in accounts:
add_deduct_tax = 'Deduct' if tax.add_deduct_tax == 'Add' else 'Add'
tax.update({
'add_deduct_tax': add_deduct_tax,
'category': tax.get('category') or 'Total',
'is_advance_tax': 1,
'charge_type': 'On Net Total' if tax.charge_type == 'On Paid Amount' else tax.charge_type
})
self.doc.append('taxes', tax)
def get_itemised_tax_breakup_html(doc):
if not doc.taxes:
@ -820,3 +847,16 @@ class init_landed_taxes_and_totals(object):
for d in self.doc.get(self.tax_field):
d.amount = flt(d.amount, d.precision("amount"))
d.base_amount = flt(d.amount * flt(d.exchange_rate), d.precision("base_amount"))
def get_advance_taxes(payment_entry_list):
taxes = []
if payment_entry_list:
taxes = frappe.db.sql(
"""
SELECT t.parent, t.add_deduct_tax, t.charge_type, t.rate,
t.account_head, t.cost_center, t.tax_amount, t.description
FROM `tabAdvance Taxes and Charges` t, `tabPayment Entry` p
WHERE t.parent = p.name AND t.parent in %s
""", (payment_entry_list, ), as_dict=1)
return taxes

View File

@ -8,7 +8,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
this.dialog = new frappe.ui.Dialog({
title: 'Payment'
});
this.dialog.show();
this.$body = this.dialog.body;
this.set_payment_primary_action();
@ -25,7 +25,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
set_payment_primary_action: function(){
var me = this;
this.dialog.set_primary_action(__("Submit"), function() {
// Allow no ZERO payment
$.each(me.frm.doc.payments, function (index, data) {
@ -100,7 +100,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
this.selected_mode.select()
this.bind_amount_change_event();
},
bind_keyboard_event: function(){
var me = this;
this.payment_val = '';
@ -114,17 +114,17 @@ erpnext.payments = erpnext.stock.StockController.extend({
me.idx = $(this).attr("idx");
me.set_outstanding_amount()
})
$(this.$body).find('.form-control').click(function(){
me.idx = $(this).attr("idx");
me.set_outstanding_amount();
me.update_paid_amount(true);
})
$(this.$body).find('.write_off_amount').change(function(){
me.write_off_amount(flt($(this).val()), precision("write_off_amount"));
})
$(this.$body).find('.change_amount').change(function(){
me.change_amount(flt($(this).val()), precision("change_amount"));
})
@ -138,7 +138,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
$(this.$body).find('.amount').attr('disabled', true);
this.selected_mode.attr('disabled', false);
},
bind_numeric_keys_event: function(){
var me = this;
$(this.$body).find('.pos-keyboard-key').click(function(){
@ -147,7 +147,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
me.idx = me.selected_mode.attr("idx")
me.update_paid_amount()
})
$(this.$body).find('.delete-btn').click(function(){
me.payment_val = cstr(flt(me.selected_mode.val())).slice(0, -1);
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
@ -156,7 +156,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
})
},
bind_amount_change_event: function(){
var me = this;
this.selected_mode.change(function(){