Modifying Sales Invoice through App

I am trying to develop excise module under an app. (https://github.com/revant/kiratplastics_erpnext)

I have excise chapter doctype where Chapter name, head and rate is stored.

Item master has custom link field for Excise Chapter which pulls the percent rate in another read only custom field in Item master.

There is also a custom field for price declared to excise dept in Item master which is to be set.

In Sales Invoice when Item is selected these new fields are successfully overridden and added in child row, override is done using hooks.py

override_whitelisted_methods = {
	"erpnext.stock.get_item_details.get_item_details" : "kiratplastics_erpnext.kirat_plastics_erpnext.kp_api.kp_get_item_details" 
}

Now I am stuck at calculating amount. Is there a way to override the calculation done in taxes_and_totals.js line #73 and taxes_and_totals.py line #63:

taxes_and_totals.js

	calculate_item_values: function() {
		var me = this;

		if (!this.discount_amount_applied) {
			$.each(this.frm.doc["items"] || [], function(i, item) {
				frappe.model.round_floats_in(item);
				item.net_rate = item.rate;
				item.amount = flt(item.rate * item.qty, precision("amount", item));
				item.net_amount = item.amount;
				item.item_tax_amount = 0.0;

				me.set_in_company_currency(item, ["price_list_rate", "rate", "amount", "net_rate", "net_amount"]);
			});
		}
	},

taxes_and_totals.py

	def calculate_item_values(self):
		if not self.discount_amount_applied:
			for item in self.doc.get("items"):
				self.doc.round_floats_in(item)

				if item.discount_percentage == 100:
					item.rate = 0.0
				elif not item.rate:
					item.rate = flt(item.price_list_rate *
						(1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))

				item.net_rate = item.rate
				item.amount = flt(item.rate * item.qty,	item.precision("amount"))
				item.net_amount = item.amount

				self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])

				item.item_tax_amount = 0.0

I need

item.amount = (item.rate * item.qty) + exciseDutyAmt;

Later I’ll user doc_events in hooks.py to pass relevant GL Entry.

What should be the ideal approach?

related topics :

1 Like

@revant_one Is ERPNext Tax not suitable for you?

You can use existing Structure.

Also if you want to do some calculation, then you can add your custom fields and calculate amount.
Based on that amount back-calculate item rate and set it in Sales Order Item.

1 Like

I’ll consider this approach. Thanks.

@revant_one We use same approach and It will work for us.
Like if we want to add two discount in Sales Order Item.

  1. We add Two custom fields Discount One, Discount Two.
  2. We write custom script to calculate standard discount(in sales order item) as discount = discount_one + discount_two.
  3. Rest part of calculating net_total is handled by erpnext, as we added our discount in standard discount.

My case example :

  1. Calculate excise duty amount:
    exciseDutyAmt = (quantity * price_disclosed_to_excise_dept) * (excise_duty_rate / 100)
  2. Then calculate amount and add excise price
    amount = (qty * price) + exciseDutyAmt

We tried this and it works. The only problem is it is not reflecting in while further calculating net_total, grand_total etc.

Why do we need to override amount (re-thinking on this)? As per requirement : Sales Taxes and charges are to be applied on the price inclusive of excise duty amount

my final GL Entry expected is :

  1. Debtors A/c Dr grand_total_in_company_currency
  2. To Sales total
  3. To Excise Payable exiseDutyAmtTotal
  4. To Taxes (applied on Sales+exiseDutyAmtTotal)
  5. To Charge (Actual)

Can Back-calculate item rate work in my case?

One of the simplest Solution :

  1. Do not override amount.
  2. Calculate and add an Actual charge in Sales Taxes and Charges for Excise Payable depending on ExciseDutyAmtTotal,
  3. Add VAT, CST etc. On Previous Row Total