fix: Add tds in PO and code cleanup
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
"account_head",
|
"account_head",
|
||||||
"col_break_1",
|
"col_break_1",
|
||||||
"description",
|
"description",
|
||||||
|
"included_in_paid_amount",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
@@ -20,9 +21,11 @@
|
|||||||
"section_break_9",
|
"section_break_9",
|
||||||
"tax_amount",
|
"tax_amount",
|
||||||
"total",
|
"total",
|
||||||
|
"allocated_amount",
|
||||||
"column_break_13",
|
"column_break_13",
|
||||||
"base_tax_amount",
|
"base_tax_amount",
|
||||||
"base_total"
|
"base_total",
|
||||||
|
"base_allocated_amount"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -185,12 +188,36 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"show_days": 1,
|
"show_days": 1,
|
||||||
"show_seconds": 1
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "included_in_paid_amount",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Included In Paid Amount",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "allocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Allocated Amount",
|
||||||
|
"options": "currency",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_allocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Allocated Amount (Company Currency)",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-27 20:02:34.734260",
|
"modified": "2020-11-29 19:06:14.666460",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Advance Taxes and Charges",
|
"name": "Advance Taxes and Charges",
|
||||||
|
|||||||
@@ -24,15 +24,12 @@
|
|||||||
"party_bank_account",
|
"party_bank_account",
|
||||||
"contact_person",
|
"contact_person",
|
||||||
"contact_email",
|
"contact_email",
|
||||||
"tds_details_section",
|
|
||||||
"apply_tax_withholding_amount",
|
|
||||||
"column_break_20",
|
|
||||||
"tax_withholding_category",
|
|
||||||
"payment_accounts_section",
|
"payment_accounts_section",
|
||||||
"party_balance",
|
"party_balance",
|
||||||
"paid_from",
|
"paid_from",
|
||||||
"paid_from_account_currency",
|
"paid_from_account_currency",
|
||||||
"paid_from_account_balance",
|
"paid_from_account_balance",
|
||||||
|
"advance_tax_account",
|
||||||
"column_break_18",
|
"column_break_18",
|
||||||
"paid_to",
|
"paid_to",
|
||||||
"paid_to_account_currency",
|
"paid_to_account_currency",
|
||||||
@@ -45,8 +42,10 @@
|
|||||||
"base_paid_amount_after_tax",
|
"base_paid_amount_after_tax",
|
||||||
"column_break_21",
|
"column_break_21",
|
||||||
"received_amount",
|
"received_amount",
|
||||||
|
"received_amount_after_tax",
|
||||||
"target_exchange_rate",
|
"target_exchange_rate",
|
||||||
"base_received_amount",
|
"base_received_amount",
|
||||||
|
"base_received_amount_after_tax",
|
||||||
"section_break_14",
|
"section_break_14",
|
||||||
"get_outstanding_invoice",
|
"get_outstanding_invoice",
|
||||||
"references",
|
"references",
|
||||||
@@ -61,6 +60,10 @@
|
|||||||
"taxes_and_charges_section",
|
"taxes_and_charges_section",
|
||||||
"purchase_taxes_and_charges_template",
|
"purchase_taxes_and_charges_template",
|
||||||
"sales_taxes_and_charges_template",
|
"sales_taxes_and_charges_template",
|
||||||
|
"column_break_55",
|
||||||
|
"apply_tax_withholding_amount",
|
||||||
|
"tax_withholding_category",
|
||||||
|
"section_break_56",
|
||||||
"taxes",
|
"taxes",
|
||||||
"base_total_taxes_and_charges",
|
"base_total_taxes_and_charges",
|
||||||
"total_taxes_and_charges",
|
"total_taxes_and_charges",
|
||||||
@@ -731,14 +734,6 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Custom Remarks"
|
"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
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.apply_tax_withholding_amount",
|
"depends_on": "eval:doc.apply_tax_withholding_amount",
|
||||||
"fieldname": "tax_withholding_category",
|
"fieldname": "tax_withholding_category",
|
||||||
@@ -750,18 +745,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.party_type == 'Supplier'",
|
||||||
"fieldname": "apply_tax_withholding_amount",
|
"fieldname": "apply_tax_withholding_amount",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Apply Tax Withholding Amount",
|
"label": "Apply Tax Withholding Amount",
|
||||||
"show_days": 1,
|
"show_days": 1,
|
||||||
"show_seconds": 1
|
"show_seconds": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "column_break_20",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"show_days": 1,
|
|
||||||
"show_seconds": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "taxes_and_charges_section",
|
"fieldname": "taxes_and_charges_section",
|
||||||
@@ -829,6 +819,44 @@
|
|||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Paid Amount After Tax (Company Currency)",
|
"label": "Paid Amount After Tax (Company Currency)",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
|
"read_only": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_55",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_56",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hide_border": 1,
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "advance_tax_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Advance Tax Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "received_amount_after_tax",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Received Amount After Tax",
|
||||||
|
"options": "paid_to_account_currency",
|
||||||
|
"show_days": 1,
|
||||||
|
"show_seconds": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_received_amount_after_tax",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Received Amount After Tax (Company Currency)",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
"show_days": 1,
|
"show_days": 1,
|
||||||
"show_seconds": 1
|
"show_seconds": 1
|
||||||
}
|
}
|
||||||
@@ -836,7 +864,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-25 20:50:14.896628",
|
"modified": "2020-11-29 20:03:57.772062",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class PaymentEntry(AccountsController):
|
|||||||
self.validate_allocated_amount()
|
self.validate_allocated_amount()
|
||||||
self.validate_paid_invoices()
|
self.validate_paid_invoices()
|
||||||
self.ensure_supplier_is_not_blocked()
|
self.ensure_supplier_is_not_blocked()
|
||||||
|
self.validate_advance_tax_account()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
@@ -310,6 +311,9 @@ class PaymentEntry(AccountsController):
|
|||||||
+ "<br><br>" + _("If this is undesirable please cancel the corresponding Payment Entry."),
|
+ "<br><br>" + _("If this is undesirable please cancel the corresponding Payment Entry."),
|
||||||
title=_("Warning"), indicator="orange")
|
title=_("Warning"), indicator="orange")
|
||||||
|
|
||||||
|
def validate_advance_tax_account(self):
|
||||||
|
if self.get('taxes') and not self.advance_tax_account:
|
||||||
|
frappe.throw(_('Please select advance tax account'))
|
||||||
|
|
||||||
def validate_journal_entry(self):
|
def validate_journal_entry(self):
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
@@ -396,11 +400,29 @@ class PaymentEntry(AccountsController):
|
|||||||
if not self.apply_tax_withholding_amount:
|
if not self.apply_tax_withholding_amount:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
reference_doclist = []
|
||||||
|
net_total = self.paid_amount
|
||||||
|
included_in_paid_amount = 0
|
||||||
|
|
||||||
|
if self.get('references'):
|
||||||
|
for doc in self.get('references'):
|
||||||
|
if doc.reference_doctype == 'Purchase Order':
|
||||||
|
reference_doclist.append(doc.reference_name)
|
||||||
|
|
||||||
|
if reference_doclist:
|
||||||
|
order_amount = frappe.db.get_all('Purchase Order', fields=['sum(net_total)'],
|
||||||
|
filters = {'name': ('in', reference_doclist), 'docstatus': 1,
|
||||||
|
'apply_tds': 1}, as_list=1)
|
||||||
|
|
||||||
|
if order_amount:
|
||||||
|
net_total = order_amount[0][0]
|
||||||
|
included_in_paid_amount = 1
|
||||||
|
|
||||||
args = frappe._dict({
|
args = frappe._dict({
|
||||||
'company': self.company,
|
'company': self.company,
|
||||||
'supplier': self.party,
|
'supplier': self.party,
|
||||||
'posting_date': self.posting_date,
|
'posting_date': self.posting_date,
|
||||||
'net_total': self.paid_amount
|
'net_total': net_total
|
||||||
})
|
})
|
||||||
|
|
||||||
tax_withholding_details = get_party_tax_withholding_details(args, self.tax_withholding_category)
|
tax_withholding_details = get_party_tax_withholding_details(args, self.tax_withholding_category)
|
||||||
@@ -408,6 +430,8 @@ class PaymentEntry(AccountsController):
|
|||||||
if not tax_withholding_details:
|
if not tax_withholding_details:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
tax_withholding_details.update({'included_in_paid_amount': included_in_paid_amount})
|
||||||
|
|
||||||
accounts = []
|
accounts = []
|
||||||
for d in self.taxes:
|
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"):
|
||||||
@@ -424,18 +448,37 @@ class PaymentEntry(AccountsController):
|
|||||||
self.remove(d)
|
self.remove(d)
|
||||||
|
|
||||||
def set_amounts(self):
|
def set_amounts(self):
|
||||||
self.set_amounts_after_tax()
|
self.set_received_amount()
|
||||||
self.set_amounts_in_company_currency()
|
self.set_amounts_in_company_currency()
|
||||||
|
self.set_amounts_after_tax()
|
||||||
self.set_total_allocated_amount()
|
self.set_total_allocated_amount()
|
||||||
self.set_unallocated_amount()
|
self.set_unallocated_amount()
|
||||||
self.set_difference_amount()
|
self.set_difference_amount()
|
||||||
|
|
||||||
|
def set_received_amount(self):
|
||||||
|
self.base_received_amount = self.base_paid_amount
|
||||||
|
|
||||||
def set_amounts_after_tax(self):
|
def set_amounts_after_tax(self):
|
||||||
self.paid_amount_after_tax = flt(flt(self.paid_amount) + flt(self.total_taxes_and_charges),
|
applicable_tax = 0
|
||||||
|
base_applicable_tax = 0
|
||||||
|
for tax in self.get('taxes'):
|
||||||
|
if not tax.included_in_paid_amount:
|
||||||
|
amount = -1 * tax.tax_amount if tax.add_deduct_tax == 'Deduct' else tax.tax_amount
|
||||||
|
base_amount = -1 * tax.base_tax_amount if tax.add_deduct_tax == 'Deduct' else tax.base_tax_amount
|
||||||
|
|
||||||
|
applicable_tax += amount
|
||||||
|
base_applicable_tax += base_amount
|
||||||
|
|
||||||
|
self.paid_amount_after_tax = flt(flt(self.paid_amount) + flt(applicable_tax),
|
||||||
self.precision("paid_amount_after_tax"))
|
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.base_paid_amount_after_tax = flt(flt(self.paid_amount_after_tax) * flt(self.source_exchange_rate),
|
||||||
self.precision("base_paid_amount_after_tax"))
|
self.precision("base_paid_amount_after_tax"))
|
||||||
|
|
||||||
|
self.received_amount_after_tax = flt(flt(self.received_amount) + flt(applicable_tax),
|
||||||
|
self.precision("paid_amount_after_tax"))
|
||||||
|
self.base_received_amount_after_tax = flt(flt(self.received_amount_after_tax) * flt(self.source_exchange_rate),
|
||||||
|
self.precision("base_paid_amount_after_tax"))
|
||||||
|
|
||||||
def set_amounts_in_company_currency(self):
|
def set_amounts_in_company_currency(self):
|
||||||
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
|
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
|
||||||
if self.paid_amount:
|
if self.paid_amount:
|
||||||
@@ -465,14 +508,14 @@ class PaymentEntry(AccountsController):
|
|||||||
if self.party:
|
if self.party:
|
||||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||||
if self.payment_type == "Receive" \
|
if self.payment_type == "Receive" \
|
||||||
and self.base_total_allocated_amount < self.base_received_amount + total_deductions \
|
and self.base_total_allocated_amount < self.base_received_amount_after_tax + total_deductions \
|
||||||
and self.total_allocated_amount < self.paid_amount + (total_deductions / self.source_exchange_rate):
|
and self.total_allocated_amount < self.paid_amount_after_tax + (total_deductions / self.source_exchange_rate):
|
||||||
self.unallocated_amount = (self.base_received_amount + total_deductions -
|
self.unallocated_amount = (self.received_amount_after_tax + total_deductions -
|
||||||
self.base_total_allocated_amount) / self.source_exchange_rate
|
self.base_total_allocated_amount) / self.source_exchange_rate
|
||||||
elif self.payment_type == "Pay" \
|
elif self.payment_type == "Pay" \
|
||||||
and self.base_total_allocated_amount < (self.base_paid_amount - total_deductions) \
|
and self.base_total_allocated_amount < (self.base_paid_amount_after_tax - total_deductions) \
|
||||||
and self.total_allocated_amount < self.received_amount + (total_deductions / self.target_exchange_rate):
|
and self.total_allocated_amount < self.received_amount_after_tax + (total_deductions / self.target_exchange_rate):
|
||||||
self.unallocated_amount = (self.base_paid_amount - (total_deductions +
|
self.unallocated_amount = (self.base_paid_amount_after_tax - (total_deductions +
|
||||||
self.base_total_allocated_amount)) / self.target_exchange_rate
|
self.base_total_allocated_amount)) / self.target_exchange_rate
|
||||||
|
|
||||||
def set_difference_amount(self):
|
def set_difference_amount(self):
|
||||||
@@ -482,11 +525,11 @@ class PaymentEntry(AccountsController):
|
|||||||
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
|
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
|
||||||
|
|
||||||
if self.payment_type == "Receive":
|
if self.payment_type == "Receive":
|
||||||
self.difference_amount = base_party_amount - self.base_received_amount
|
self.difference_amount = base_party_amount - self.base_received_amount_after_tax
|
||||||
elif self.payment_type == "Pay":
|
elif self.payment_type == "Pay":
|
||||||
self.difference_amount = self.base_paid_amount - base_party_amount
|
self.difference_amount = self.base_paid_amount_after_tax - base_party_amount
|
||||||
else:
|
else:
|
||||||
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
|
self.difference_amount = self.base_paid_amount_after_tax - flt(self.base_received_amount_after_tax)
|
||||||
|
|
||||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||||
|
|
||||||
@@ -616,7 +659,7 @@ class PaymentEntry(AccountsController):
|
|||||||
gl_entries.append(gle)
|
gl_entries.append(gle)
|
||||||
|
|
||||||
if self.unallocated_amount:
|
if self.unallocated_amount:
|
||||||
base_unallocated_amount = base_unallocated_amount = self.unallocated_amount * \
|
base_unallocated_amount = self.unallocated_amount * \
|
||||||
(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
|
(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
|
||||||
|
|
||||||
gle = party_gl_dict.copy()
|
gle = party_gl_dict.copy()
|
||||||
@@ -646,8 +689,8 @@ class PaymentEntry(AccountsController):
|
|||||||
"account": self.paid_to,
|
"account": self.paid_to,
|
||||||
"account_currency": self.paid_to_account_currency,
|
"account_currency": self.paid_to_account_currency,
|
||||||
"against": self.party if self.payment_type=="Receive" else self.paid_from,
|
"against": self.party if self.payment_type=="Receive" else self.paid_from,
|
||||||
"debit_in_account_currency": self.received_amount,
|
"debit_in_account_currency": self.received_amount_after_tax,
|
||||||
"debit": self.base_received_amount,
|
"debit": self.base_received_amount_after_tax,
|
||||||
"cost_center": self.cost_center
|
"cost_center": self.cost_center
|
||||||
}, item=self)
|
}, item=self)
|
||||||
)
|
)
|
||||||
@@ -660,8 +703,10 @@ class PaymentEntry(AccountsController):
|
|||||||
|
|
||||||
if self.payment_type == 'Pay':
|
if self.payment_type == 'Pay':
|
||||||
dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
|
dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
|
||||||
|
rev_dr_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
|
||||||
elif self.payment_type == 'Receive':
|
elif self.payment_type == 'Receive':
|
||||||
dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
|
dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit"
|
||||||
|
rev_dr_cr = "debit" if d.add_deduct_tax == "Add" else "credit"
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
@@ -672,8 +717,18 @@ class PaymentEntry(AccountsController):
|
|||||||
if account_currency==self.company_currency \
|
if account_currency==self.company_currency \
|
||||||
else d.tax_amount,
|
else d.tax_amount,
|
||||||
"cost_center": d.cost_center
|
"cost_center": d.cost_center
|
||||||
}, account_currency, item=d)
|
}, account_currency, item=d))
|
||||||
)
|
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": self.advance_tax_account,
|
||||||
|
"against": self.party if self.payment_type=="Receive" else self.paid_from,
|
||||||
|
rev_dr_cr: d.base_tax_amount,
|
||||||
|
rev_dr_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):
|
def add_deductions_gl_entries(self, gl_entries):
|
||||||
for d in self.get("deductions"):
|
for d in self.get("deductions"):
|
||||||
|
|||||||
@@ -456,6 +456,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
self.make_internal_transfer_gl_entries(gl_entries)
|
self.make_internal_transfer_gl_entries(gl_entries)
|
||||||
|
|
||||||
|
self.allocate_advance_taxes(gl_entries)
|
||||||
|
|
||||||
gl_entries = make_regional_gl_entries(gl_entries, self)
|
gl_entries = make_regional_gl_entries(gl_entries, self)
|
||||||
|
|
||||||
gl_entries = merge_similar_entries(gl_entries)
|
gl_entries = merge_similar_entries(gl_entries)
|
||||||
@@ -899,6 +901,46 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"cost_center": self.cost_center
|
"cost_center": self.cost_center
|
||||||
}, account_currency, item=self))
|
}, account_currency, item=self))
|
||||||
|
|
||||||
|
def allocate_advance_taxes(self, gl_entries):
|
||||||
|
tax_map = self.get_tax_map()
|
||||||
|
for pe in self.get('advances'):
|
||||||
|
pe = frappe.get_doc('Payment Entry', pe.reference_name)
|
||||||
|
for tax in pe.get('taxes'):
|
||||||
|
account_currency = get_account_currency(tax.account_head)
|
||||||
|
dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
|
||||||
|
rev_dr_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
|
||||||
|
|
||||||
|
unallocated_amount = tax.tax_amount - tax.allocated_amount
|
||||||
|
if tax_map.get(tax.account_head):
|
||||||
|
amount = tax_map.get(tax.account_head)
|
||||||
|
if amount < unallocated_amount:
|
||||||
|
unallocated_amount = amount
|
||||||
|
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": tax.account_head,
|
||||||
|
"against": self.supplier,
|
||||||
|
dr_or_cr: unallocated_amount,
|
||||||
|
dr_or_cr + "_in_account_currency": unallocated_amount \
|
||||||
|
if account_currency==self.company_currency \
|
||||||
|
else unallocated_amount,
|
||||||
|
'cost_center': tax.cost_center
|
||||||
|
}, account_currency, item=tax))
|
||||||
|
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": pe.advance_tax_account,
|
||||||
|
"against": self.supplier,
|
||||||
|
rev_dr_cr: unallocated_amount,
|
||||||
|
rev_dr_cr + "_in_account_currency": unallocated_amount \
|
||||||
|
if account_currency==self.company_currency \
|
||||||
|
else unallocated_amount,
|
||||||
|
'cost_center': tax.cost_center
|
||||||
|
}, account_currency, item=tax))
|
||||||
|
|
||||||
|
frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount + unallocated_amount)
|
||||||
|
tax_map[tax.account_head] -= unallocated_amount
|
||||||
|
|
||||||
def make_payment_gl_entries(self, gl_entries):
|
def make_payment_gl_entries(self, gl_entries):
|
||||||
# Make Cash GL Entries
|
# Make Cash GL Entries
|
||||||
if cint(self.is_paid) and self.cash_bank_account and self.paid_amount:
|
if cint(self.is_paid) and self.cash_bank_account and self.paid_amount:
|
||||||
@@ -1088,9 +1130,9 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
accounts = []
|
accounts = []
|
||||||
for d in self.taxes:
|
for d in self.taxes:
|
||||||
if d.account_head == tax_withholding_details.get("account_head") and not d.is_advance_tax:
|
if d.account_head == tax_withholding_details.get("account_head"):
|
||||||
d.update(tax_withholding_details)
|
d.update(tax_withholding_details)
|
||||||
if not d.is_advance_tax:
|
|
||||||
accounts.append(d.account_head)
|
accounts.append(d.account_head)
|
||||||
|
|
||||||
if not accounts or tax_withholding_details.get("account_head") not in accounts:
|
if not accounts or tax_withholding_details.get("account_head") not in accounts:
|
||||||
|
|||||||
@@ -28,8 +28,7 @@
|
|||||||
"base_tax_amount",
|
"base_tax_amount",
|
||||||
"base_total",
|
"base_total",
|
||||||
"base_tax_amount_after_discount_amount",
|
"base_tax_amount_after_discount_amount",
|
||||||
"item_wise_tax_detail",
|
"item_wise_tax_detail"
|
||||||
"is_advance_tax"
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -250,22 +249,12 @@
|
|||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"show_days": 1,
|
"show_days": 1,
|
||||||
"show_seconds": 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,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-25 18:24:43.487567",
|
"modified": "2020-11-29 19:11:58.826078",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges",
|
"name": "Purchase Taxes and Charges",
|
||||||
|
|||||||
@@ -842,6 +842,8 @@ class SalesInvoice(SellingController):
|
|||||||
self.make_tax_gl_entries(gl_entries)
|
self.make_tax_gl_entries(gl_entries)
|
||||||
self.make_internal_transfer_gl_entries(gl_entries)
|
self.make_internal_transfer_gl_entries(gl_entries)
|
||||||
|
|
||||||
|
self.allocate_advance_taxes(gl_entries)
|
||||||
|
|
||||||
self.make_item_gl_entries(gl_entries)
|
self.make_item_gl_entries(gl_entries)
|
||||||
|
|
||||||
# merge gl entries before adding pos entries
|
# merge gl entries before adding pos entries
|
||||||
@@ -911,6 +913,46 @@ class SalesInvoice(SellingController):
|
|||||||
"cost_center": self.cost_center
|
"cost_center": self.cost_center
|
||||||
}, account_currency, item=self))
|
}, account_currency, item=self))
|
||||||
|
|
||||||
|
def allocate_advance_taxes(self, gl_entries):
|
||||||
|
tax_map = self.get_tax_map()
|
||||||
|
for pe in self.get('advances'):
|
||||||
|
pe = frappe.get_doc('Payment Entry', pe.reference_name)
|
||||||
|
for tax in pe.get('taxes'):
|
||||||
|
account_currency = get_account_currency(tax.account_head)
|
||||||
|
dr_or_cr = "debit" if tax.add_deduct_tax == "Add" else "credit"
|
||||||
|
rev_dr_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
|
||||||
|
|
||||||
|
unallocated_amount = tax.tax_amount - tax.allocated_amount
|
||||||
|
if tax_map.get(tax.account_head):
|
||||||
|
amount = tax_map.get(tax.account_head)
|
||||||
|
if amount < unallocated_amount:
|
||||||
|
unallocated_amount = amount
|
||||||
|
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": tax.account_head,
|
||||||
|
"against": self.customer,
|
||||||
|
dr_or_cr: unallocated_amount,
|
||||||
|
dr_or_cr + "_in_account_currency": unallocated_amount \
|
||||||
|
if account_currency==self.company_currency \
|
||||||
|
else unallocated_amount,
|
||||||
|
'cost_center': tax.cost_center
|
||||||
|
}, account_currency, item=tax))
|
||||||
|
|
||||||
|
gl_entries.append(
|
||||||
|
self.get_gl_dict({
|
||||||
|
"account": pe.advance_tax_account,
|
||||||
|
"against": self.customer,
|
||||||
|
rev_dr_cr: unallocated_amount,
|
||||||
|
rev_dr_cr + "_in_account_currency": unallocated_amount \
|
||||||
|
if account_currency==self.company_currency \
|
||||||
|
else unallocated_amount,
|
||||||
|
'cost_center': tax.cost_center
|
||||||
|
}, account_currency, item=tax))
|
||||||
|
|
||||||
|
frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount + unallocated_amount)
|
||||||
|
tax_map[tax.account_head] -= unallocated_amount
|
||||||
|
|
||||||
def make_item_gl_entries(self, gl_entries):
|
def make_item_gl_entries(self, gl_entries):
|
||||||
# income account gl entries
|
# income account gl entries
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ frappe.ui.form.on("Purchase Order", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
|
||||||
|
},
|
||||||
|
|
||||||
|
apply_tds: function(frm) {
|
||||||
|
if (!frm.doc.apply_tds) {
|
||||||
|
frm.set_value("tax_withholding_category", '');
|
||||||
|
} else {
|
||||||
|
frm.set_value("tax_withholding_category", frm.supplier_tds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@ from erpnext.accounts.party import get_party_account_currency
|
|||||||
from six import string_types
|
from six import string_types
|
||||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||||
|
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import get_party_tax_withholding_details
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
|
||||||
unlink_inter_company_doc
|
unlink_inter_company_doc
|
||||||
|
|
||||||
@@ -39,11 +40,18 @@ class PurchaseOrder(BuyingController):
|
|||||||
'percent_join_field': 'material_request'
|
'percent_join_field': 'material_request'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
def onload(self):
|
||||||
|
supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category")
|
||||||
|
self.set_onload("supplier_tds", supplier_tds)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
super(PurchaseOrder, self).validate()
|
super(PurchaseOrder, self).validate()
|
||||||
|
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
|
# apply tax withholding only if checked and applicable
|
||||||
|
self.set_tax_withholding()
|
||||||
|
|
||||||
self.validate_supplier()
|
self.validate_supplier()
|
||||||
self.validate_schedule_date()
|
self.validate_schedule_date()
|
||||||
validate_for_items(self)
|
validate_for_items(self)
|
||||||
@@ -87,6 +95,33 @@ class PurchaseOrder(BuyingController):
|
|||||||
if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')):
|
if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')):
|
||||||
self.validate_rate_with_reference_doc([["Supplier Quotation", "supplier_quotation", "supplier_quotation_item"]])
|
self.validate_rate_with_reference_doc([["Supplier Quotation", "supplier_quotation", "supplier_quotation_item"]])
|
||||||
|
|
||||||
|
def set_tax_withholding(self):
|
||||||
|
if not self.apply_tds:
|
||||||
|
return
|
||||||
|
|
||||||
|
tax_withholding_details = get_party_tax_withholding_details(self, 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)
|
||||||
|
|
||||||
|
# calculate totals again after applying TDS
|
||||||
|
self.calculate_taxes_and_totals()
|
||||||
|
|
||||||
def validate_supplier(self):
|
def validate_supplier(self):
|
||||||
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
||||||
if prevent_po:
|
if prevent_po:
|
||||||
|
|||||||
@@ -700,6 +700,7 @@ class AccountsController(TransactionBase):
|
|||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||||
|
|
||||||
if self.doctype in ["Sales Invoice", "Purchase Invoice"]:
|
if self.doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||||
|
self.update_allocated_advance_taxes()
|
||||||
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
|
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
|
||||||
unlink_ref_doc_from_payment_entries(self)
|
unlink_ref_doc_from_payment_entries(self)
|
||||||
|
|
||||||
@@ -707,6 +708,35 @@ class AccountsController(TransactionBase):
|
|||||||
if frappe.db.get_single_value('Accounts Settings', 'unlink_advance_payment_on_cancelation_of_order'):
|
if frappe.db.get_single_value('Accounts Settings', 'unlink_advance_payment_on_cancelation_of_order'):
|
||||||
unlink_ref_doc_from_payment_entries(self)
|
unlink_ref_doc_from_payment_entries(self)
|
||||||
|
|
||||||
|
def get_tax_map(self):
|
||||||
|
tax_map = {}
|
||||||
|
for tax in self.get('taxes'):
|
||||||
|
tax_map.setdefault(tax.account_head, 0.0)
|
||||||
|
tax_map[tax.account_head] += tax.tax_amount
|
||||||
|
|
||||||
|
return tax_map
|
||||||
|
|
||||||
|
def update_allocated_advance_taxes(self):
|
||||||
|
if self.get('advances'):
|
||||||
|
tax_accounts = [d.account_head for d in self.get('taxes')]
|
||||||
|
allocated_tax_map = frappe._dict(frappe.get_all('GL Entry', fields=['account', 'sum(credit - debit)'],
|
||||||
|
filters={'voucher_no': self.name, 'account': ('in', tax_accounts)},
|
||||||
|
group_by='account', as_list=1))
|
||||||
|
|
||||||
|
tax_map = self.get_tax_map()
|
||||||
|
|
||||||
|
for pe in self.get('advances'):
|
||||||
|
pe = frappe.get_doc('Payment Entry', pe.reference_name)
|
||||||
|
for tax in pe.get('taxes'):
|
||||||
|
allocated_amount = tax_map.get(tax.account_head) - allocated_tax_map.get(tax.account_head)
|
||||||
|
if allocated_amount > tax.tax_amount:
|
||||||
|
allocated_amount = tax.tax_amount
|
||||||
|
|
||||||
|
if allocated_amount:
|
||||||
|
frappe.db.set_value('Advance Taxes and Charges', tax.name, 'allocated_amount', tax.allocated_amount - allocated_amount)
|
||||||
|
tax_map[tax.account_head] -= allocated_amount
|
||||||
|
allocated_tax_map[tax.account_head] -= allocated_amount
|
||||||
|
|
||||||
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
|
||||||
from erpnext.controllers.status_updater import get_allowance_for
|
from erpnext.controllers.status_updater import get_allowance_for
|
||||||
item_allowance = {}
|
item_allowance = {}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.validate_conversion_rate()
|
self.validate_conversion_rate()
|
||||||
self.calculate_item_values()
|
self.calculate_item_values()
|
||||||
self.validate_item_tax_template()
|
self.validate_item_tax_template()
|
||||||
self.apply_advance_taxes()
|
|
||||||
self.initialize_taxes()
|
self.initialize_taxes()
|
||||||
self.determine_exclusive_rate()
|
self.determine_exclusive_rate()
|
||||||
self.calculate_net_total()
|
self.calculate_net_total()
|
||||||
@@ -684,33 +683,6 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
self.calculate_paid_amount()
|
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):
|
def get_itemised_tax_breakup_html(doc):
|
||||||
if not doc.taxes:
|
if not doc.taxes:
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user