fix: Add tds in PO and code cleanup
This commit is contained in:
parent
c26de28613
commit
d18dde7757
@ -12,6 +12,7 @@
|
||||
"account_head",
|
||||
"col_break_1",
|
||||
"description",
|
||||
"included_in_paid_amount",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"dimension_col_break",
|
||||
@ -20,9 +21,11 @@
|
||||
"section_break_9",
|
||||
"tax_amount",
|
||||
"total",
|
||||
"allocated_amount",
|
||||
"column_break_13",
|
||||
"base_tax_amount",
|
||||
"base_total"
|
||||
"base_total",
|
||||
"base_allocated_amount"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -185,12 +188,36 @@
|
||||
"reqd": 1,
|
||||
"show_days": 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,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-27 20:02:34.734260",
|
||||
"modified": "2020-11-29 19:06:14.666460",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Advance Taxes and Charges",
|
||||
|
@ -24,15 +24,12 @@
|
||||
"party_bank_account",
|
||||
"contact_person",
|
||||
"contact_email",
|
||||
"tds_details_section",
|
||||
"apply_tax_withholding_amount",
|
||||
"column_break_20",
|
||||
"tax_withholding_category",
|
||||
"payment_accounts_section",
|
||||
"party_balance",
|
||||
"paid_from",
|
||||
"paid_from_account_currency",
|
||||
"paid_from_account_balance",
|
||||
"advance_tax_account",
|
||||
"column_break_18",
|
||||
"paid_to",
|
||||
"paid_to_account_currency",
|
||||
@ -45,8 +42,10 @@
|
||||
"base_paid_amount_after_tax",
|
||||
"column_break_21",
|
||||
"received_amount",
|
||||
"received_amount_after_tax",
|
||||
"target_exchange_rate",
|
||||
"base_received_amount",
|
||||
"base_received_amount_after_tax",
|
||||
"section_break_14",
|
||||
"get_outstanding_invoice",
|
||||
"references",
|
||||
@ -61,6 +60,10 @@
|
||||
"taxes_and_charges_section",
|
||||
"purchase_taxes_and_charges_template",
|
||||
"sales_taxes_and_charges_template",
|
||||
"column_break_55",
|
||||
"apply_tax_withholding_amount",
|
||||
"tax_withholding_category",
|
||||
"section_break_56",
|
||||
"taxes",
|
||||
"base_total_taxes_and_charges",
|
||||
"total_taxes_and_charges",
|
||||
@ -731,14 +734,6 @@
|
||||
"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
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.apply_tax_withholding_amount",
|
||||
"fieldname": "tax_withholding_category",
|
||||
@ -750,18 +745,13 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.party_type == 'Supplier'",
|
||||
"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",
|
||||
@ -829,6 +819,44 @@
|
||||
"fieldtype": "Currency",
|
||||
"label": "Paid Amount After Tax (Company 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_seconds": 1
|
||||
}
|
||||
@ -836,7 +864,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-25 20:50:14.896628",
|
||||
"modified": "2020-11-29 20:03:57.772062",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
@ -65,6 +65,7 @@ class PaymentEntry(AccountsController):
|
||||
self.validate_allocated_amount()
|
||||
self.validate_paid_invoices()
|
||||
self.ensure_supplier_is_not_blocked()
|
||||
self.validate_advance_tax_account()
|
||||
self.set_status()
|
||||
|
||||
def on_submit(self):
|
||||
@ -310,6 +311,9 @@ class PaymentEntry(AccountsController):
|
||||
+ "<br><br>" + _("If this is undesirable please cancel the corresponding Payment Entry."),
|
||||
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):
|
||||
for d in self.get("references"):
|
||||
@ -396,11 +400,29 @@ class PaymentEntry(AccountsController):
|
||||
if not self.apply_tax_withholding_amount:
|
||||
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({
|
||||
'company': self.company,
|
||||
'supplier': self.party,
|
||||
'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)
|
||||
@ -408,6 +430,8 @@ class PaymentEntry(AccountsController):
|
||||
if not tax_withholding_details:
|
||||
return
|
||||
|
||||
tax_withholding_details.update({'included_in_paid_amount': included_in_paid_amount})
|
||||
|
||||
accounts = []
|
||||
for d in self.taxes:
|
||||
if d.account_head == tax_withholding_details.get("account_head"):
|
||||
@ -424,18 +448,37 @@ class PaymentEntry(AccountsController):
|
||||
self.remove(d)
|
||||
|
||||
def set_amounts(self):
|
||||
self.set_amounts_after_tax()
|
||||
self.set_received_amount()
|
||||
self.set_amounts_in_company_currency()
|
||||
self.set_amounts_after_tax()
|
||||
self.set_total_allocated_amount()
|
||||
self.set_unallocated_amount()
|
||||
self.set_difference_amount()
|
||||
|
||||
def set_received_amount(self):
|
||||
self.base_received_amount = self.base_paid_amount
|
||||
|
||||
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.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.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):
|
||||
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
|
||||
if self.paid_amount:
|
||||
@ -465,14 +508,14 @@ class PaymentEntry(AccountsController):
|
||||
if self.party:
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
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 -
|
||||
and self.base_total_allocated_amount < self.base_received_amount_after_tax + total_deductions \
|
||||
and self.total_allocated_amount < self.paid_amount_after_tax + (total_deductions / self.source_exchange_rate):
|
||||
self.unallocated_amount = (self.received_amount_after_tax + 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 +
|
||||
and self.base_total_allocated_amount < (self.base_paid_amount_after_tax - total_deductions) \
|
||||
and self.total_allocated_amount < self.received_amount_after_tax + (total_deductions / self.target_exchange_rate):
|
||||
self.unallocated_amount = (self.base_paid_amount_after_tax - (total_deductions +
|
||||
self.base_total_allocated_amount)) / self.target_exchange_rate
|
||||
|
||||
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)
|
||||
|
||||
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":
|
||||
self.difference_amount = self.base_paid_amount - base_party_amount
|
||||
self.difference_amount = self.base_paid_amount_after_tax - base_party_amount
|
||||
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")])
|
||||
|
||||
@ -616,7 +659,7 @@ class PaymentEntry(AccountsController):
|
||||
gl_entries.append(gle)
|
||||
|
||||
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)
|
||||
|
||||
gle = party_gl_dict.copy()
|
||||
@ -646,8 +689,8 @@ class PaymentEntry(AccountsController):
|
||||
"account": self.paid_to,
|
||||
"account_currency": self.paid_to_account_currency,
|
||||
"against": self.party if self.payment_type=="Receive" else self.paid_from,
|
||||
"debit_in_account_currency": self.received_amount,
|
||||
"debit": self.base_received_amount,
|
||||
"debit_in_account_currency": self.received_amount_after_tax,
|
||||
"debit": self.base_received_amount_after_tax,
|
||||
"cost_center": self.cost_center
|
||||
}, item=self)
|
||||
)
|
||||
@ -660,8 +703,10 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
if self.payment_type == 'Pay':
|
||||
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':
|
||||
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(
|
||||
self.get_gl_dict({
|
||||
@ -672,8 +717,18 @@ class PaymentEntry(AccountsController):
|
||||
if account_currency==self.company_currency \
|
||||
else d.tax_amount,
|
||||
"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):
|
||||
for d in self.get("deductions"):
|
||||
|
@ -456,6 +456,8 @@ class PurchaseInvoice(BuyingController):
|
||||
self.make_tax_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 = merge_similar_entries(gl_entries)
|
||||
@ -899,6 +901,46 @@ class PurchaseInvoice(BuyingController):
|
||||
"cost_center": self.cost_center
|
||||
}, 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):
|
||||
# Make Cash GL Entries
|
||||
if cint(self.is_paid) and self.cash_bank_account and self.paid_amount:
|
||||
@ -1088,10 +1130,10 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
accounts = []
|
||||
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)
|
||||
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:
|
||||
self.append("taxes", tax_withholding_details)
|
||||
|
@ -28,8 +28,7 @@
|
||||
"base_tax_amount",
|
||||
"base_total",
|
||||
"base_tax_amount_after_discount_amount",
|
||||
"item_wise_tax_detail",
|
||||
"is_advance_tax"
|
||||
"item_wise_tax_detail"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -250,22 +249,12 @@
|
||||
"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-10-25 18:24:43.487567",
|
||||
"modified": "2020-11-29 19:11:58.826078",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Taxes and Charges",
|
||||
|
@ -842,6 +842,8 @@ class SalesInvoice(SellingController):
|
||||
self.make_tax_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)
|
||||
|
||||
# merge gl entries before adding pos entries
|
||||
@ -911,6 +913,46 @@ class SalesInvoice(SellingController):
|
||||
"cost_center": self.cost_center
|
||||
}, 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):
|
||||
# income account gl entries
|
||||
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);
|
||||
},
|
||||
|
||||
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 erpnext.stock.doctype.item.item import get_item_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,\
|
||||
unlink_inter_company_doc
|
||||
|
||||
@ -39,11 +40,18 @@ class PurchaseOrder(BuyingController):
|
||||
'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):
|
||||
super(PurchaseOrder, self).validate()
|
||||
|
||||
self.set_status()
|
||||
|
||||
# apply tax withholding only if checked and applicable
|
||||
self.set_tax_withholding()
|
||||
|
||||
self.validate_supplier()
|
||||
self.validate_schedule_date()
|
||||
validate_for_items(self)
|
||||
@ -87,6 +95,33 @@ class PurchaseOrder(BuyingController):
|
||||
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"]])
|
||||
|
||||
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):
|
||||
prevent_po = frappe.db.get_value("Supplier", self.supplier, 'prevent_pos')
|
||||
if prevent_po:
|
||||
|
@ -700,6 +700,7 @@ class AccountsController(TransactionBase):
|
||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||
|
||||
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'):
|
||||
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'):
|
||||
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):
|
||||
from erpnext.controllers.status_updater import get_allowance_for
|
||||
item_allowance = {}
|
||||
|
@ -40,7 +40,6 @@ 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()
|
||||
@ -684,33 +683,6 @@ 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:
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user