blob: a92ff88c48eae3b17e1d06417e1eb759b6055696 [file] [log] [blame]
Nabin Haitec52db82013-01-22 11:53:14 +05301# ERPNext - web based ERP (http://erpnext.com)
2# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17from __future__ import unicode_literals
18import webnotes
Anand Doshif3096132013-05-21 19:35:06 +053019from webnotes.utils import cint, flt, comma_or
Nabin Haitec52db82013-01-22 11:53:14 +053020from setup.utils import get_company_currency
Nabin Hait0fc24542013-03-25 11:06:00 +053021from webnotes import msgprint, _
Anand Doshi21f4ea32013-05-10 18:08:32 +053022import json
Nabin Haitec52db82013-01-22 11:53:14 +053023
Nabin Haitc3afb252013-03-19 12:01:24 +053024from controllers.stock_controller import StockController
Nabin Haitbf495c92013-01-30 12:49:08 +053025
Nabin Haitc3afb252013-03-19 12:01:24 +053026class SellingController(StockController):
Anand Doshif3096132013-05-21 19:35:06 +053027 def onload_post_render(self):
28 self.set_price_list_currency()
29
30 # contact, address, item details and pos details (if applicable)
31 self.set_missing_values()
32
33 if self.meta.get_field("other_charges"):
34 self.set_taxes()
35
Nabin Haitec52db82013-01-22 11:53:14 +053036 def validate(self):
Saurabh6f753182013-03-20 12:55:28 +053037 super(SellingController, self).validate()
Anand Doshif3096132013-05-21 19:35:06 +053038 # self.calculate_taxes_and_totals()
Nabin Haitec52db82013-01-22 11:53:14 +053039 self.set_total_in_words()
Anand Doshif3096132013-05-21 19:35:06 +053040 self.set_missing_values(for_validate=True)
41
42 def set_price_list_currency(self):
43 if self.doc.price_list_name and not self.doc.price_list_currency:
44 # TODO - change this, since price list now has only one currency allowed
45 from setup.utils import get_price_list_currency
46 self.doc.fields.update(get_price_list_currency(
47 {"price_list_name": self.doc.price_list_name, "use_for": "selling"}))
48
49 def set_missing_values(self, for_validate=False):
50 # set contact and address details for customer, if they are not mentioned
51 if self.doc.customer and not (self.doc.contact_person and self.doc.customer_address):
52 for fieldname, val in self.get_default_address_and_contact("customer").items():
53 if not self.doc.fields.get(fieldname) and self.meta.get_field(fieldname):
54 self.doc.fields[fieldname] = val
55
56 # set missing item values
57 from selling.utils import get_item_details
58 for item in self.doclist.get({"parentfield": "entries"}):
59 if item.fields.get("item_code"):
60 ret = get_item_details(item.fields)
61 for fieldname, value in ret.items():
62 if self.meta.get_field(fieldname, parentfield="entries") and \
63 not item.fields.get(fieldname):
64 item.fields[fieldname] = value
65
66 def set_taxes(self):
67 if not self.doclist.get({"parentfield": "other_charges"}):
68 if not self.doc.charge:
69 # get the default tax master
70 self.doc.charge = webnotes.conn.get_value("Sales Taxes and Charges Master",
71 {"is_default": 1})
72
73 if self.doc.charge:
74 from webnotes.model import default_fields
75 tax_master = webnotes.bean("Sales Taxes and Charges Master", self.doc.charge)
76 for i, tax in enumerate(tax_master.doclist.get({"parentfield": "other_charges"})):
77 for fieldname in default_fields:
78 tax.fields[fieldname] = None
79
80 tax.fields.update({
81 "doctype": "Sales Taxes and Charges",
82 "parentfield": "other_charges",
83 "idx": i+1
84 })
85
86 self.doclist.append(tax)
87
88 def get_other_charges(self):
89 self.doclist = self.doc.clear_table(self.doclist, "other_charges")
90 self.set_taxes()
91
92 def set_customer_defaults(self):
93 self.get_default_customer_address()
Nabin Haitec52db82013-01-22 11:53:14 +053094
95 def set_total_in_words(self):
96 from webnotes.utils import money_in_words
97 company_currency = get_company_currency(self.doc.company)
Nabin Hait6f1a5ec2013-02-20 16:25:05 +053098
99 disable_rounded_total = cint(webnotes.conn.get_value("Global Defaults", None,
100 "disable_rounded_total"))
101
Nabin Haitec52db82013-01-22 11:53:14 +0530102 if self.meta.get_field("in_words"):
Nabin Hait6f1a5ec2013-02-20 16:25:05 +0530103 self.doc.in_words = money_in_words(disable_rounded_total and
104 self.doc.grand_total or self.doc.rounded_total, company_currency)
Nabin Haitec52db82013-01-22 11:53:14 +0530105 if self.meta.get_field("in_words_export"):
Nabin Hait6f1a5ec2013-02-20 16:25:05 +0530106 self.doc.in_words_export = money_in_words(disable_rounded_total and
Nabin Hait8c7234f2013-03-11 16:32:33 +0530107 self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
Nabin Haita0e7c152013-03-21 18:37:06 +0530108
Nabin Hait787c02e2013-03-29 16:42:33 +0530109 def set_buying_amount(self, stock_ledger_entries = None):
Anand Doshi8c5844e2013-03-21 20:24:10 +0530110 from stock.utils import get_buying_amount
Nabin Hait787c02e2013-03-29 16:42:33 +0530111 if not stock_ledger_entries:
112 stock_ledger_entries = self.get_stock_ledger_entries()
Anand Doshi8c5844e2013-03-21 20:24:10 +0530113
114 item_sales_bom = {}
115 for d in self.doclist.get({"parentfield": "packing_details"}):
116 new_d = webnotes._dict(d.fields.copy())
117 new_d.total_qty = -1 * d.qty
118 item_sales_bom.setdefault(d.parent_item, []).append(new_d)
Nabin Haita0e7c152013-03-21 18:37:06 +0530119
120 if stock_ledger_entries:
121 for item in self.doclist.get({"parentfield": self.fname}):
122 if item.item_code in self.stock_items or \
123 (item_sales_bom and item_sales_bom.get(item.item_code)):
124 buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty,
125 self.doc.doctype, self.doc.name, item.name, stock_ledger_entries,
126 item_sales_bom)
Nabin Haitf2d4df92013-05-07 13:12:02 +0530127
128 item.buying_amount = buying_amount >= 0.01 and buying_amount or 0
Nabin Hait0fc24542013-03-25 11:06:00 +0530129 webnotes.conn.set_value(item.doctype, item.name, "buying_amount",
130 item.buying_amount)
131
132 def check_expense_account(self, item):
133 if item.buying_amount and not item.expense_account:
134 msgprint(_("""Expense account is mandatory for item: """) + item.item_code,
Nabin Hait787c02e2013-03-29 16:42:33 +0530135 raise_exception=1)
136
137 if item.buying_amount and not item.cost_center:
138 msgprint(_("""Cost Center is mandatory for item: """) + item.item_code,
Anand Doshi21f4ea32013-05-10 18:08:32 +0530139 raise_exception=1)
140
141 def calculate_taxes_and_totals(self):
142 self.doc.conversion_rate = flt(self.doc.conversion_rate)
143 self.item_doclist = self.doclist.get({"parentfield": self.fname})
144 self.tax_doclist = self.doclist.get({"parentfield": "other_charges"})
145
146 self.calculate_item_values()
147 self.initialize_taxes()
Anand Doshif3096132013-05-21 19:35:06 +0530148 self.determine_exclusive_rate()
Anand Doshi21f4ea32013-05-10 18:08:32 +0530149 self.calculate_net_total()
150 self.calculate_taxes()
151 self.calculate_totals()
Anand Doshif3096132013-05-21 19:35:06 +0530152 self.calculate_commission()
153 self.calculate_contribution()
Anand Doshi21f4ea32013-05-10 18:08:32 +0530154 # self.calculate_outstanding_amount()
Anand Doshi21f4ea32013-05-10 18:08:32 +0530155 self._cleanup()
156
Anand Doshif3096132013-05-21 19:35:06 +0530157 # TODO
158 # print format: show net_total_export instead of net_total
159
160 def determine_exclusive_rate(self):
Anand Doshi21f4ea32013-05-10 18:08:32 +0530161 if not any((cint(tax.included_in_print_rate) for tax in self.tax_doclist)):
162 # no inclusive tax
163 return
164
165 for item in self.item_doclist:
166 item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
167 cumulated_tax_fraction = 0
168 for i, tax in enumerate(self.tax_doclist):
Anand Doshif3096132013-05-21 19:35:06 +0530169 tax.tax_fraction_for_current_item = self.get_current_tax_fraction(tax, item_tax_map)
170
Anand Doshi21f4ea32013-05-10 18:08:32 +0530171 if i==0:
Anand Doshif3096132013-05-21 19:35:06 +0530172 tax.grand_total_fraction_for_current_item = 1 + tax.tax_fraction_for_current_item
Anand Doshi21f4ea32013-05-10 18:08:32 +0530173 else:
174 tax.grand_total_fraction_for_current_item = \
175 self.tax_doclist[i-1].grand_total_fraction_for_current_item \
176 + tax.tax_fraction_for_current_item
177
178 cumulated_tax_fraction += tax.tax_fraction_for_current_item
179
180 if cumulated_tax_fraction:
181 item.basic_rate = flt((item.export_rate * self.doc.conversion_rate) /
Anand Doshi39384d32013-05-11 19:39:53 +0530182 (1 + cumulated_tax_fraction), self.precision("basic_rate", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530183
Anand Doshi39384d32013-05-11 19:39:53 +0530184 item.amount = flt(item.basic_rate * item.qty, self.precision("amount", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530185
Anand Doshif3096132013-05-21 19:35:06 +0530186 if item.adj_rate == 100:
187 item.base_ref_rate = item.basic_rate
188 item.basic_rate = 0.0
189 else:
190 item.base_ref_rate = flt(item.basic_rate / (1 - (item.adj_rate / 100.0)),
191 self.precision("base_ref_rate", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530192
193 def get_current_tax_fraction(self, tax, item_tax_map):
194 """
195 Get tax fraction for calculating tax exclusive amount
196 from tax inclusive amount
197 """
198 current_tax_fraction = 0
199
200 if cint(tax.included_in_print_rate):
201 tax_rate = self._get_tax_rate(tax, item_tax_map)
202
203 if tax.charge_type == "On Net Total":
204 current_tax_fraction = tax_rate / 100.0
205
206 elif tax.charge_type == "On Previous Row Amount":
207 current_tax_fraction = (tax_rate / 100.0) * \
208 self.tax_doclist[cint(tax.row_id) - 1].tax_fraction_for_current_item
209
210 elif tax.charge_type == "On Previous Row Total":
211 current_tax_fraction = (tax_rate / 100.0) * \
212 self.tax_doclist[cint(tax.row_id) - 1].grand_total_fraction_for_current_item
213
214 return current_tax_fraction
215
216 def calculate_item_values(self):
217 def _set_base(item, print_field, base_field):
218 """set values in base currency"""
219 item.fields[base_field] = flt((flt(item.fields[print_field],
Anand Doshi39384d32013-05-11 19:39:53 +0530220 self.precision(print_field, item)) * self.doc.conversion_rate),
221 self.precision(base_field, item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530222
223 for item in self.item_doclist:
Anand Doshi39384d32013-05-11 19:39:53 +0530224 self.round_floats_in(item)
Anand Doshi21f4ea32013-05-10 18:08:32 +0530225
226 if item.adj_rate == 100:
227 item.ref_rate = item.ref_rate or item.export_rate
228 item.export_rate = 0
229 else:
230 if item.ref_rate:
231 item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)),
Anand Doshi39384d32013-05-11 19:39:53 +0530232 self.precision("export_rate", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530233 else:
234 # assume that print rate and discount are specified
235 item.ref_rate = flt(item.export_rate / (1.0 - (item.adj_rate / 100.0)),
Anand Doshi39384d32013-05-11 19:39:53 +0530236 self.precision("ref_rate", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530237
238 item.export_amount = flt(item.export_rate * item.qty,
Anand Doshi39384d32013-05-11 19:39:53 +0530239 self.precision("export_amount", item))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530240
241 _set_base(item, "ref_rate", "base_ref_rate")
242 _set_base(item, "export_rate", "basic_rate")
243 _set_base(item, "export_amount", "amount")
244
245 def initialize_taxes(self):
246 for tax in self.tax_doclist:
247 tax.tax_amount = tax.total = 0.0
Anand Doshif3096132013-05-21 19:35:06 +0530248 tax.item_wise_tax_detail = {}
249
Anand Doshi21f4ea32013-05-10 18:08:32 +0530250 # temporary fields
251 tax.tax_amount_for_current_item = tax.grand_total_for_current_item = 0.0
Anand Doshif3096132013-05-21 19:35:06 +0530252
Anand Doshi21f4ea32013-05-10 18:08:32 +0530253 self.validate_on_previous_row(tax)
254 self.validate_inclusive_tax(tax)
Anand Doshi39384d32013-05-11 19:39:53 +0530255 self.round_floats_in(tax)
Anand Doshi21f4ea32013-05-10 18:08:32 +0530256
257 def calculate_net_total(self):
Anand Doshif3096132013-05-21 19:35:06 +0530258 self.doc.net_total = self.doc.net_total_export = 0.0
Anand Doshi21f4ea32013-05-10 18:08:32 +0530259
260 for item in self.item_doclist:
261 self.doc.net_total += item.amount
262 self.doc.net_total_export += item.export_amount
Anand Doshif3096132013-05-21 19:35:06 +0530263
264 self.round_floats_in(self.doc, ["net_total", "net_total_export"])
Anand Doshi21f4ea32013-05-10 18:08:32 +0530265
266 def calculate_taxes(self):
267 for item in self.item_doclist:
268 item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
269
270 for i, tax in enumerate(self.tax_doclist):
271 # tax_amount represents the amount of tax for the current step
272 current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map)
273
274 # case when net total is 0 but there is an actual type charge
275 # in this case add the actual amount to tax.tax_amount
276 # and tax.grand_total_for_current_item for the first such iteration
Anand Doshif3096132013-05-21 19:35:06 +0530277 if tax.charge_type=="Actual" and \
278 not (current_tax_amount or self.doc.net_total or tax.tax_amount):
Anand Doshi39384d32013-05-11 19:39:53 +0530279 zero_net_total_adjustment = flt(tax.rate, self.precision("tax_amount", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530280 current_tax_amount += zero_net_total_adjustment
281
282 # store tax_amount for current item as it will be used for
283 # charge type = 'On Previous Row Amount'
284 tax.tax_amount_for_current_item = current_tax_amount
285
286 # accumulate tax amount into tax.tax_amount
Anand Doshif3096132013-05-21 19:35:06 +0530287 tax.tax_amount += current_tax_amount
Anand Doshi21f4ea32013-05-10 18:08:32 +0530288
289 # Calculate tax.total viz. grand total till that step
290 # note: grand_total_for_current_item contains the contribution of
291 # item's amount, previously applied tax and the current tax on that item
292 if i==0:
293 tax.grand_total_for_current_item = flt(item.amount +
Anand Doshi39384d32013-05-11 19:39:53 +0530294 current_tax_amount, self.precision("total", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530295
296 else:
297 tax.grand_total_for_current_item = \
298 flt(self.tax_doclist[i-1].grand_total_for_current_item +
Anand Doshi39384d32013-05-11 19:39:53 +0530299 current_tax_amount, self.precision("total", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530300
301 # in tax.total, accumulate grand total of each item
302 tax.total += tax.grand_total_for_current_item
303
Anand Doshif3096132013-05-21 19:35:06 +0530304 # store tax breakup for each item
Anand Doshi21f4ea32013-05-10 18:08:32 +0530305 tax.item_wise_tax_detail[item.item_code] = current_tax_amount
306
307 def calculate_totals(self):
308 self.doc.grand_total = flt(self.tax_doclist and \
Anand Doshi5af812a2013-05-10 19:23:02 +0530309 self.tax_doclist[-1].total or self.doc.net_total, self.precision("grand_total"))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530310 self.doc.grand_total_export = flt(self.doc.grand_total / self.doc.conversion_rate,
Anand Doshi5af812a2013-05-10 19:23:02 +0530311 self.precision("grand_total_export"))
Anand Doshif3096132013-05-21 19:35:06 +0530312
313 self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total,
314 self.precision("other_charges_total"))
315 self.doc.other_charges_total_export = flt(self.doc.grand_total_export - self.doc.net_total_export,
316 self.precision("other_charges_total_export"))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530317
318 self.doc.rounded_total = round(self.doc.grand_total)
319 self.doc.rounded_total_export = round(self.doc.grand_total_export)
320
Anand Doshif3096132013-05-21 19:35:06 +0530321 def calculate_commission(self):
322 if self.doc.commission_rate > 100:
323 msgprint(_(self.meta.get_label("commission_rate")) + " " +
324 _("cannot be greater than 100"), raise_exception=True)
325
326 self.doc.total_commission = flt(self.doc.net_total * self.doc.commission_rate / 100.0,
327 self.precision("total_commission"))
328
329 def calculate_contribution(self):
330 total = 0.0
331 sales_team = self.doclist.get({"parentfield": "sales_team"})
332 for sales_person in sales_team:
333 self.round_floats_in(sales_person)
334
335 sales_person.allocated_amount = flt(
336 self.doc.net_total * sales_person.allocated_percentage / 100.0,
337 self.precision("allocated_amount", sales_person))
338
339 total += sales_person.allocated_percentage
340
341 if sales_team and total != 100.0:
342 msgprint(_("Total") + " " +
343 _(self.meta.get_label("allocated_percentage", parentfield="sales_team")) +
344 " " + _("should be 100%"), raise_exception=True)
345
Anand Doshi21f4ea32013-05-10 18:08:32 +0530346 def get_current_tax_amount(self, item, tax, item_tax_map):
347 tax_rate = self._get_tax_rate(tax, item_tax_map)
Anand Doshif3096132013-05-21 19:35:06 +0530348 current_tax_amount = 0.0
Anand Doshi21f4ea32013-05-10 18:08:32 +0530349
350 if tax.charge_type == "Actual":
351 # distribute the tax amount proportionally to each item row
Anand Doshi39384d32013-05-11 19:39:53 +0530352 actual = flt(tax.rate, self.precision("tax_amount", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530353 current_tax_amount = (self.doc.net_total
354 and ((item.amount / self.doc.net_total) * actual)
355 or 0)
356 elif tax.charge_type == "On Net Total":
357 current_tax_amount = (tax_rate / 100.0) * item.amount
358 elif tax.charge_type == "On Previous Row Amount":
359 current_tax_amount = (tax_rate / 100.0) * \
360 self.tax_doclist[cint(tax.row_id) - 1].tax_amount_for_current_item
361 elif tax.charge_type == "On Previous Row Total":
362 current_tax_amount = (tax_rate / 100.0) * \
363 self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item
364
Anand Doshi39384d32013-05-11 19:39:53 +0530365 return flt(current_tax_amount, self.precision("tax_amount", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530366
367 def validate_on_previous_row(self, tax):
368 """
369 validate if a valid row id is mentioned in case of
370 On Previous Row Amount and On Previous Row Total
371 """
372 if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \
373 (not tax.row_id or cint(tax.row_id) >= tax.idx):
374 msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \
375 _("Please specify a valid") + " %(row_id_label)s") % {
376 "idx": tax.idx,
Anand Doshif3096132013-05-21 19:35:06 +0530377 "taxes_doctype": tax.doctype,
Anand Doshi21f4ea32013-05-10 18:08:32 +0530378 "row_id_label": self.meta.get_label("row_id",
379 parentfield="other_charges")
380 }, raise_exception=True)
381
382 def validate_inclusive_tax(self, tax):
Anand Doshif3096132013-05-21 19:35:06 +0530383 def _on_previous_row_error(row_range):
384 msgprint((_("Row") + " # %(idx)s [%(doctype)s]: " +
385 _("to be included in Item's rate, it is required that: ") +
386 " [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % {
Anand Doshi21f4ea32013-05-10 18:08:32 +0530387 "idx": tax.idx,
Anand Doshif3096132013-05-21 19:35:06 +0530388 "doctype": tax.doctype,
Anand Doshi21f4ea32013-05-10 18:08:32 +0530389 "inclusive_label": self.meta.get_label("included_in_print_rate",
390 parentfield="other_charges"),
391 "charge_type_label": self.meta.get_label("charge_type",
392 parentfield="other_charges"),
393 "charge_type": tax.charge_type,
394 "row_range": row_range
395 }, raise_exception=True)
396
397 if cint(tax.included_in_print_rate):
398 if tax.charge_type == "Actual":
Anand Doshif3096132013-05-21 19:35:06 +0530399 # inclusive tax cannot be of type Actual
Anand Doshi21f4ea32013-05-10 18:08:32 +0530400 msgprint((_("Row")
Anand Doshif3096132013-05-21 19:35:06 +0530401 + " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" "
Anand Doshi21f4ea32013-05-10 18:08:32 +0530402 + "cannot be included in Item's rate") % {
403 "idx": tax.idx,
Anand Doshif3096132013-05-21 19:35:06 +0530404 "doctype": tax.doctype,
Anand Doshi21f4ea32013-05-10 18:08:32 +0530405 "charge_type_label": self.meta.get_label("charge_type",
406 parentfield="other_charges"),
407 "charge_type": tax.charge_type,
408 }, raise_exception=True)
409 elif tax.charge_type == "On Previous Row Amount" and \
410 not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate):
411 # referred row should also be inclusive
Anand Doshif3096132013-05-21 19:35:06 +0530412 _on_previous_row_error(tax.row_id)
Anand Doshi21f4ea32013-05-10 18:08:32 +0530413 elif tax.charge_type == "On Previous Row Total" and \
Anand Doshif3096132013-05-21 19:35:06 +0530414 not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:tax.row_id - 1]]):
415 # all rows about the reffered tax should be inclusive
416 _on_previous_row_error("1 - %d" % (tax.row_id,))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530417
418 def _load_item_tax_rate(self, item_tax_rate):
Anand Doshif3096132013-05-21 19:35:06 +0530419 return json.loads(item_tax_rate) if item_tax_rate else {}
Anand Doshi21f4ea32013-05-10 18:08:32 +0530420
421 def _get_tax_rate(self, tax, item_tax_map):
422 if item_tax_map.has_key(tax.account_head):
Anand Doshi39384d32013-05-11 19:39:53 +0530423 return flt(item_tax_map.get(tax.account_head), self.precision("rate", tax))
Anand Doshi21f4ea32013-05-10 18:08:32 +0530424 else:
425 return tax.rate
426
427 def _cleanup(self):
428 for tax in self.tax_doclist:
Anand Doshif3096132013-05-21 19:35:06 +0530429 for fieldname in ("grand_total_for_current_item",
430 "tax_amount_for_current_item",
431 "tax_fraction_for_current_item",
Anand Doshi21f4ea32013-05-10 18:08:32 +0530432 "grand_total_fraction_for_current_item"):
433 if fieldname in tax.fields:
434 del tax.fields[fieldname]
435
436 tax.item_wise_tax_detail = json.dumps(tax.item_wise_tax_detail)
Anand Doshi1dde46a2013-05-15 21:15:57 +0530437
438 def validate_order_type(self):
439 valid_types = ["Sales", "Maintenance"]
440 if self.doc.order_type not in valid_types:
441 msgprint(_(self.meta.get_label("order_type")) + " " +
442 _("must be one of") + ": " + comma_or(valid_types),
443 raise_exception=True)