blob: 04dd5804d2ff480b2a89cf32b26b84588b630cb1 [file] [log] [blame]
Rohit Waghchaure6087fe12016-04-09 14:31:09 +05301frappe.provide("erpnext.pos");
2{% include "erpnext/public/js/controllers/taxes_and_totals.js" %}
3
Rushabh Mehta06fa46f2015-01-29 18:09:11 +05304frappe.pages['pos'].on_page_load = function(wrapper) {
Rushabh Mehta4c36d732015-01-01 15:59:34 +05305 var page = frappe.ui.make_app_page({
Rushabh Mehta72e17192014-08-08 15:30:49 +05306 parent: wrapper,
Rohit Waghchaure6087fe12016-04-09 14:31:09 +05307 title: 'Point of Sale',
Rushabh Mehta72e17192014-08-08 15:30:49 +05308 single_column: true
9 });
Rohit Waghchaure6087fe12016-04-09 14:31:09 +053010
11 wrapper = $(wrapper).find('.page-content')
12 new erpnext.pos.PointOfSale(page, wrapper)
Rushabh Mehta72e17192014-08-08 15:30:49 +053013}
Rohit Waghchaure6087fe12016-04-09 14:31:09 +053014
15erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
16 init: function(page, wrapper){
17 this.page = page;
18 this.wrapper = wrapper;
19 this.set_indicator();
20 this.onload();
21 this.make_menu_list();
22 this.set_interval_for_si_sync();
23 this.si_docs = this.get_doc_from_localstorage();
24 },
25
26 check_internet_connection: function(){
27 var me = this;
28 //Check Internet connection after every 30 seconds
29 setInterval(function(){
30 me.set_indicator();
31 }, 30000)
32 },
33
34 set_indicator: function(){
35 var me = this;
36 // navigator.onLine
37 this.page.set_indicator("Offline", "grey")
38 frappe.call({
39 method:"frappe.handler.ping",
40 callback: function(r){
41 if(r.message){
42 me.connection_status = true;
43 me.page.set_indicator("Online", "green")
44 }
45 }
46 })
47 },
48
49 onload: function(){
50 var me = this;
51
52 this.get_data_from_server(function(){
53 me.create_new();
54 });
55
56 this.check_internet_connection();
57 },
58
59 make_menu_list: function(){
60 var me = this;
61
62 this.page.add_menu_item(__("Unsync Records"), function(){
63 me.show_unsync_invoice_list()
64 });
65
66 this.page.add_menu_item(__("Sync Master Data"), function(){
67 me.get_data_from_server()
68 });
69
70 this.page.add_menu_item(__("New Sales Invoice"), function() {
71 me.create_new()
72 })
73 },
74
75 show_unsync_invoice_list: function(){
76 var me = this;
77 this.si_docs = this.get_doc_from_localstorage();
78
79 this.list_dialog = new frappe.ui.Dialog({
80 title: 'Invoice List'
81 });
82
83 this.list_dialog.show();
84 this.list_body = this.list_dialog.body;
85 $(this.list_body).append('<div class="row list-row list-row-head pos-invoice-list">\
86 <div class="col-xs-6">Customer</div>\
87 <div class="col-xs-3 text-right">Grand Total</div>\
88 <div class="col-xs-3 text-right">Status</div>\
89 </div>')
90
91 $.each(this.si_docs, function(index, data){
92 for(key in data) {
93 $(frappe.render_template("pos_invoice_list", {
94 name: key,
95 customer: data[key].customer,
96 grand_total: data[key].grand_total,
97 status: (data[key].docstatus == 1) ? 'Submitted' : 'Draft'
98 })).appendTo($(me.list_body));
99 }
100 })
101
102 $(this.list_body).find('.list-row').click(function() {
103 me.name = $(this).attr('invoice-name')
104 doc_data = me.get_invoice_doc(me.si_docs)
105 if(doc_data){
106 me.frm.doc = doc_data[0][me.name];
107 me.refresh();
108 me.disable_input_field();
109 me.list_dialog.hide();
110 }
111 })
112 },
113
114 get_invoice_doc: function(si_docs){
115 var me = this;
116 this.si_docs = this.get_doc_from_localstorage();
117
118 return $.grep(this.si_docs, function(data){
119 for(key in data){
120 return key == me.name
121 }
122 })
123 },
124
125 get_data_from_server: function(callback){
126 var me = this;
127 frappe.call({
128 method: "erpnext.accounts.doctype.sales_invoice.pos.get_pos_data",
129 freeze: true,
130 callback: function(r){
131 window.items = r.message.items;
132 window.customers = r.message.customers;
133 window.pricing_rules = r.message.pricing_rules;
134 window.meta = r.message.meta;
135 window.print_template = r.message.print_template;
136 localStorage.setItem('doc', JSON.stringify(r.message.doc));
137 if(callback){
138 callback();
139 }
140 }
141 })
142 },
143
144 create_new: function(){
145 this.frm = {}
146 var me = this;
147 this.name = '';
148 this.frm.doc = JSON.parse(localStorage.getItem('doc'))
149 this.load_data();
150 this.setup();
151 },
152
153 load_data: function(){
154 this.items = window.items;
155 this.customers = window.customers;
156 this.pricing_rules = window.pricing_rules;
157
158 $.each(window.meta, function(i, data){
159 frappe.meta.sync(data)
160 })
161
162 this.print_template = frappe.render_template("print_template",
163 {content: window.print_template, title:"POS"})
164 },
165
166 setup: function(){
167 this.wrapper.html(frappe.render_template("pos", this.frm.doc));
168 this.set_transaction_defaults("Customer");
169 this.make();
170 this.set_primary_action();
171 },
172
173 set_transaction_defaults: function(party) {
174 var me = this;
175 this.party = party;
176 this.price_list = (party == "Customer" ?
177 this.frm.doc.selling_price_list : this.frm.doc.buying_price_list);
178 this.price_list_field = (party == "Customer" ? "selling_price_list" : "buying_price_list");
179 this.sales_or_purchase = (party == "Customer" ? "Sales" : "Purchase");
180 },
181
182 make: function() {
183 this.make_search();
184 this.make_customer();
185 this.make_item_list();
186 this.make_discount_field()
187 },
188
189 make_search: function() {
190 var me = this;
191 this.search = frappe.ui.form.make_control({
192 df: {
193 "fieldtype": "Data",
194 "label": "Item",
195 "fieldname": "pos_item",
196 "placeholder": "Search Item"
197 },
198 parent: this.wrapper.find(".search-area"),
199 only_input: true,
200 });
201
202 this.search.make_input();
203 this.search.$input.on("keyup", function() {
204 setTimeout(function() {
205 me.items = me.get_items();
206 me.make_item_list();
207 }, 1000);
208 });
209
210 this.party_field = frappe.ui.form.make_control({
211 df: {
212 "fieldtype": "Data",
213 "options": this.party,
214 "label": this.party,
215 "fieldname": this.party.toLowerCase(),
216 "placeholder": this.party
217 },
218 parent: this.wrapper.find(".party-area"),
219 only_input: true,
220 });
221
222 this.party_field.make_input();
223 },
224
225 make_customer: function() {
226 var me = this;
227
228 if(this.customers.length == 1){
229 this.party_field.$input.val(this.customers[0].name);
230 this.frm.doc.customer = this.customers[0].name;
231 }
232
233 this.party_field.$input.autocomplete({
234 source: function (request, response) {
235 me.customer_data = me.get_customers(request.term)
236 response($.map(me.customer_data, function(data){
237 return {label: data.name, value: data.name,
238 customer_group: data.customer_group, territory: data.territory}
239 }))
240 },
241 change: function(event, ui){
242 if(ui.item){
243 me.frm.doc.customer = ui.item.label;
244 me.frm.doc.customer_name = ui.item.customer_name;
245 me.frm.doc.customer_group = ui.item.customer_group;
246 me.frm.doc.territory = ui.item.territory;
247 }else{
248 me.frm.doc.customer = me.party_field.$input.val();
249 }
250 me.refresh();
251 }
252 })
253 },
254
255 get_customers: function(key){
256 var me = this;
257 key = key.toLowerCase()
258 return $.grep(this.customers, function(data) {
259 if(data.name.toLowerCase().match(key) || data.customer_name.toLowerCase().match(key)
260 || data.customer_group.toLowerCase().match(key)){
261 return data
262 }
263 })
264 },
265
266 make_item_list: function() {
267 var me = this;
268 if(!this.price_list) {
269 msgprint(__("Price List not found or disabled"));
270 return;
271 }
272
273 me.item_timeout = null;
274
275 var $wrap = me.wrapper.find(".item-list");
276 me.wrapper.find(".item-list").empty();
277
278 if (this.items) {
279 $.each(this.items, function(index, obj) {
280 if(index < 16){
281 $(frappe.render_template("pos_item", {
282 item_code: obj.name,
283 item_price: format_currency(obj.price_list_rate, obj.currency),
284 item_name: obj.name===obj.item_name ? "" : obj.item_name,
285 item_image: obj.image ? "url('" + obj.image + "')" : null,
286 color: frappe.get_palette(obj.item_name),
287 abbr: frappe.get_abbr(obj.item_name)
288 })).tooltip().appendTo($wrap);
289 }
290 });
291 }
292
293 if(this.items.length == 1){
294 this.search.$input.val("");
295 this.add_to_cart();
296 }
297
298 // if form is local then allow this function
299 $(me.wrapper).find("div.pos-item").on("click", function() {
300 me.customer_validate();
301 if(me.frm.doc.docstatus==0) {
302 me.items = me.get_items($(this).attr("data-item-code"))
303 me.add_to_cart();
304 }
305 });
306 },
307
308 get_items: function(item_code){
309 // To search item as per the key enter
310
311 var me = this;
312 this.item_serial_no = {}
313
314 if(item_code){
315 return $.grep(window.items, function(item){
316 if(item.item_code == item_code ){
317 return true
318 }
319 })
320 }
321
322 key = this.search.$input.val().toLowerCase();
323
324 if(key){
325 return $.grep(window.items, function(item){
326 if( (item.item_code.toLowerCase().match(key)) ||
327 (item.item_name.toLowerCase().match(key)) || (item.item_group.toLowerCase().match(key)) ){
328 return true
329 }else if(item.barcode){
330 return item.barcode == me.search.$input.val()
331 } else if (in_list(item.serial_nos, me.search.$input.val())){
332 me.item_serial_no[item.item_code] = me.search.$input.val()
333 return true
334 }
335 })
336 }else{
337 return window.items;
338 }
339 },
340
341 update_qty: function() {
342 var me = this;
343
344 $(this.wrapper).find(".pos-item-qty").on("change", function(){
345 var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
346 me.update_qty_against_item_code(item_code, $(this).val());
347 })
348
349 $(this.wrapper).find("[data-action='increase-qty']").on("click", function(){
350 var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
351 var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) + 1;
352 me.update_qty_against_item_code(item_code, qty);
353 })
354
355 $(this.wrapper).find("[data-action='decrease-qty']").on("click", function(){
356 var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
357 var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1;
358 me.update_qty_against_item_code(item_code, qty);
359 })
360 },
361
362 update_qty_against_item_code: function(item_code, qty){
363 var me = this;
364 if(qty < 0){
365 frappe.throw(__("Quantity must be positive"));
366 }
367
368 this.remove_item = []
369 $.each(this.frm.doc["items"] || [], function(i, d) {
370 if (d.item_code == item_code) {
371 d.qty = flt(qty);
372 d.amount = flt(d.rate) * flt(d.qty);
373 if(d.qty==0){
374 me.remove_item.push(d.idx)
375 }
376 }
377 });
378 this.remove_zero_qty_item();
379 this.refresh();
380 },
381
382 remove_zero_qty_item: function(){
383 var me = this;
384 idx = 0
385 this.items = []
386 idx = 0
387 $.each(this.frm.doc["items"] || [], function(i, d) {
388 if(!in_list(me.remove_item, d.idx)){
389 d.idx = idx;
390 me.items.push(d);
391 idx++;
392 }
393 });
394
395 this.frm.doc["items"] = this.items;
396 },
397
398 make_discount_field: function(){
399 var me = this;
400
401 this.wrapper.find('input.discount-percentage').on("change", function() {
402 me.frm.doc.additional_discount_percentage = flt($(this).val(), precision("additional_discount_percentage"));
403 total = me.frm.doc.grand_total
404
405 if(me.frm.doc.apply_discount_on == 'Net Total'){
406 total = me.frm.doc.net_total
407 }
408
409 me.frm.doc.discount_amount = flt(total*flt(me.frm.doc.additional_discount_percentage) / 100, precision("discount_amount"));
410 me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount)
411 me.refresh();
412 });
413
414 this.wrapper.find('input.discount-amount').on("change", function() {
415 me.frm.doc.discount_amount = flt($(this).val(), precision("discount_amount"));
416 me.frm.doc.additional_discount_percentage = 0.0;
417 me.wrapper.find('input.discount-percentage').val(0);
418 me.refresh();
419 });
420 },
421
422 customer_validate: function(){
423 var me = this;
424
425 if(!this.frm.doc.customer){
426 frappe.throw(__("Please select customer"))
427 }
428 },
429
430 add_to_cart: function() {
431 var me = this;
432 var caught = false;
433 var no_of_items = me.wrapper.find(".pos-bill-item").length;
434
435 this.validate_serial_no()
436 this.validate_warehouse();
437
438 if (no_of_items != 0) {
439 $.each(this.frm.doc["items"] || [], function(i, d) {
440 if (d.item_code == me.items[0].item_code) {
441 caught = true;
442 d.qty += 1;
443 d.amount = flt(d.rate) * flt(d.qty)
444 if(me.item_serial_no.length){
445 d.serial_no += '\n' + me.item_serial_no[d.item_code]
446 }
447 }
448 });
449 }
450
451 // if item not found then add new item
452 if (!caught)
453 this.add_new_item_to_grid();
454
455 this.refresh();
456 },
457
458 add_new_item_to_grid: function() {
459 var me = this;
460 this.child = frappe.model.add_child(this.frm.doc, this.frm.doc.doctype + " Item", "items");
461 this.child.item_code = this.items[0].item_code;
462 this.child.item_name = this.items[0].item_name;
463 this.child.stock_uom = this.items[0].stock_uom;
464 this.child.description = this.items[0].description;
465 this.child.qty = 1;
466 this.child.item_group = this.items[0].item_group;
467 this.child.cost_center = this.items[0].cost_center;
468 this.child.income_account = this.items[0].income_account;
469 this.child.warehouse = this.items[0].default_warehouse;
470 this.child.price_list_rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
471 this.child.rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
472 this.child.actual_qty = this.items[0].actual_qty;
473 this.child.amount = flt(this.child.qty) * flt(this.child.rate);
474 this.child.serial_no = this.item_serial_no[this.child.item_code];
475 },
476
477 refresh: function() {
478 var me = this;
479 this.refresh_fields();
480 this.update_qty();
481 this.set_primary_action();
482 },
483 refresh_fields: function() {
484 this.apply_pricing_rule();
485 this.discount_amount_applied = false;
486 this._calculate_taxes_and_totals();
487 this.calculate_discount_amount();
488 this.show_items_in_item_cart();
489 this.set_taxes();
490 this.calculate_outstanding_amount();
491 this.set_totals();
492 },
493
494 get_company_currency: function() {
495 return erpnext.get_currency(this.frm.doc.company);
496 },
497
498 show_item_wise_taxes: function(){
499 return null;
500 },
501
502 show_items_in_item_cart: function() {
503 var me = this;
504 var $items = this.wrapper.find(".items").empty();
505 me.frm.doc.net_total = 0.0
506 $.each(this.frm.doc.items|| [], function(i, d) {
507 $(frappe.render_template("pos_bill_item", {
508 item_code: d.item_code,
509 item_name: (d.item_name===d.item_code || !d.item_name) ? "" : ("<br>" + d.item_name),
510 qty: d.qty,
511 actual_qty: d.actual_qty,
512 projected_qty: d.projected_qty,
513 rate: format_currency(d.rate, me.frm.doc.currency),
514 amount: format_currency(d.amount, me.frm.doc.currency)
515 })).appendTo($items);
516 });
517
518 this.wrapper.find("input.pos-item-qty").on("focus", function() {
519 $(this).select();
520 });
521 },
522
523 set_taxes: function(){
524 var me = this;
525 me.frm.doc.total_taxes_and_charges = 0.0
526
527 var taxes = this.frm.doc.taxes || [];
528 $(this.wrapper)
529 .find(".tax-area").toggleClass("hide", (taxes && taxes.length) ? false : true)
530 .find(".tax-table").empty();
531
532 $.each(taxes, function(i, d) {
533 if (d.tax_amount && cint(d.included_in_print_rate) == 0) {
534 $(frappe.render_template("pos_tax_row", {
535 description: d.description,
536 tax_amount: format_currency(flt(d.tax_amount_after_discount_amount),
537 me.frm.doc.currency)
538 })).appendTo(me.wrapper.find(".tax-table"));
539 }
540 });
541 },
542
543 set_totals: function() {
544 var me = this;
545 this.wrapper.find(".net-total").text(format_currency(me.frm.doc.total, me.frm.doc.currency));
546 this.wrapper.find(".grand-total").text(format_currency(me.frm.doc.grand_total, me.frm.doc.currency));
547 },
548
549 set_primary_action: function() {
550 var me = this;
551
552 if (this.frm.doc.docstatus==0 && this.frm.doc.outstanding_amount > 0) {
553 this.page.set_primary_action(__("Pay"), function() {
554 me.validate()
555 me.create_invoice();
556 me.make_payment();
557 });
558 }else if(this.frm.doc.docstatus == 0){
559 this.page.set_primary_action(__("Submit"), function() {
560 frappe.confirm(__("Do you really want to submit the invoice?"), function () {
561 me.write_off_amount()
562 })
563 })
564 }else if(this.frm.doc.docstatus == 1){
565 this.page.set_primary_action(__("Print"), function() {
566 html = frappe.render(me.print_template, me.frm.doc)
567 frappe.require("/assets/js/print_format_v3.min.js", function() {
568 w = _p.preview(html);
569 setTimeout(function(){
570 w.print();
571 }, 1000)
572 });
573 })
574 }
575 },
576
577 write_off_amount: function(){
578 var me = this;
579 var value = 0.0;
580
581 if(this.frm.doc.outstanding_amount > 0){
582 dialog = new frappe.ui.Dialog({
583 title: 'Write Off Amount',
584 fields: [
585 {fieldtype: "Currency", fieldname: "write_off_amount", label: __("Amount"), reqd: 1},
586 ]
587 });
588
589 dialog.show();
590
591 dialog.fields_dict.write_off_amount.$input.change(function(){
592 value = dialog.get_values()
593 })
594
595 dialog.set_primary_action(__("Submit"), function(){
596 me.frm.doc.write_off_amount = value.write_off_amount;
597 me.calculate_outstanding_amount();
598 dialog.hide();
599 me.change_status();
600 })
601 }else{
602 me.change_status();
603 }
604 },
605
606 change_status: function(){
607 if(this.frm.doc.docstatus == 0){
608 this.frm.doc.docstatus = 1;
609 this.update_invoice();
610 this.disable_input_field();
611 }
612 },
613
614 disable_input_field: function(){
615 var pointer_events = 'inherit'
616 $(this.wrapper).find('input').attr("disabled", false);
617
618 if(this.frm.doc.docstatus == 1){
619 pointer_events = 'none'
620 $(this.wrapper).find('input').attr("disabled", true);
621 }
622
623 $(this.wrapper).find('.pos-bill-wrapper').css('pointer-events', pointer_events);
624 $(this.wrapper).find('.pos-items-section').css('pointer-events', pointer_events);
625 this.set_primary_action();
626 },
627
628 create_invoice: function(){
629 var me = this;
630 var invoice_data = {}
631 this.si_docs = this.get_doc_from_localstorage();
632 if(this.name){
633 this.update_invoice()
634 }else{
635 this.name = $.now();
636 invoice_data[this.name] = this.frm.doc
637 this.si_docs.push(invoice_data)
638 this.update_localstorage();
639 this.set_primary_action();
640 }
641 },
642
643 update_invoice: function(){
644 var me = this;
645 this.si_docs = this.get_doc_from_localstorage();
646 $.each(this.si_docs, function(index, data){
647 for(key in data){
648 if(key == me.name){
649 me.si_docs[index][key] = me.frm.doc
650 me.update_localstorage();
651 }
652 }
653 })
654 },
655
656 update_localstorage: function(){
657 try{
658 localStorage.setItem('sales_invoice_doc', JSON.stringify(this.si_docs));
659 }catch(e){
660 frappe.throw(__("LocalStorage is full , did not save"))
661 }
662 },
663
664 get_doc_from_localstorage: function(){
665 return JSON.parse(localStorage.getItem('sales_invoice_doc')) || [];
666 },
667
668 set_interval_for_si_sync: function(){
669 var me = this;
670 setInterval(function(){
671 me.sync_sales_invoice()
672 }, 6000)
673 },
674
675 sync_sales_invoice: function(){
676 var me = this;
677 this.si_docs = this.get_submitted_invoice()
678
679 if(this.connection_status && this.si_docs.length){
680 frappe.call({
681 method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
682 args: {
683 doc_list: me.si_docs
684 },
685 callback: function(r){
686 if(r.message){
687 me.removed_items = r.message;
688 me.remove_doc_from_localstorage();
689 }
690 }
691 })
692 }
693 },
694
695 get_submitted_invoice: function(){
696 invoices = []
697 docs = this.get_doc_from_localstorage()
698 if(docs){
699 invoices = $.map(docs, function(data){
700 for(key in data){
701 if(data[key].docstatus == 1){
702 return data
703 }
704 }
705 });
706 }
707
708 return invoices
709 },
710
711 remove_doc_from_localstorage: function(){
712 var me = this;
713 this.si_docs = this.get_doc_from_localstorage();
714 if(this.removed_items){
715 $.each(this.si_docs, function(index, data){
716 for(key in data){
717 if(in_list(me.removed_items, key)){
718 me.si_docs.splice(index)
719 }
720 }
721 })
722 this.update_localstorage();
723 }
724 },
725
726 validate: function(){
727 var me = this;
728 this.customer_validate();
729 this.item_validate();
730 },
731
732 item_validate: function(){
733 if(this.frm.doc.items.length == 0){
734 frappe.throw(__("Select items to save the invoice"))
735 }
736 },
737
738 validate_serial_no: function(){
739 var me = this;
740 var item_code = serial_no = '';
741 for (key in this.item_serial_no){
742 item_code = key;
743 serial_no = me.item_serial_no[key]
744 }
745
746 if(item_code && serial_no){
747 $.each(this.frm.doc.items, function(index, data){
748 if(data.item_code == item_code){
749 if(in_list(data.serial_no.split('\n'), serial_no)){
750 frappe.throw(__(repl("Serial no %(serial_no)s is already taken", {
751 'serial_no': serial_no
752 })))
753 }
754 }
755 })
756 }
757 },
758
759 apply_pricing_rule: function(){
760 var me = this;
761 $.each(this.frm.doc["items"], function(n, item) {
762 pricing_rule = me.get_pricing_rule(item)
763 me.validate_pricing_rule(pricing_rule)
764 if(pricing_rule.length){
765 item.margin_type = pricing_rule[0].margin_type;
766 item.price_list_rate = pricing_rule[0].price || item.price_list_rate;
767 item.margin_rate_or_amount = pricing_rule[0].margin_rate_or_amount;
768 item.discount_percentage = pricing_rule[0].discount_percentage || 0.0;
769 me.apply_pricing_rule_on_item(item)
770 }
771 })
772 },
773
774 get_pricing_rule: function(item){
775 var me = this;
776 return $.grep(this.pricing_rules, function(data){
777 if(data.item_code == item.item_code || in_list(['All Item Groups', item.item_group], data.item_group)) {
778 if(in_list(['Customer', 'Customer Group', 'Territory'], data.applicable_for)){
779 return me.validate_condition(data)
780 }else{
781 return true
782 }
783 }
784 })
785 },
786
787 validate_condition: function(data){
788 //This method check condition based on applicable for
789 condition = this.get_mapper_for_pricing_rule(data)[data.applicable_for]
790 if(in_list(condition[1], condition[0])){
791 return true
792 }
793 },
794
795 get_mapper_for_pricing_rule: function(data){
796 return {
797 'Customer': [data.customer, [this.doc.customer]],
798 'Customer Group': [data.customer_group, [this.doc.customer_group, 'All Customer Groups']],
799 'Territory': [data.territory, [this.doc.territory, 'All Territories']],
800 }
801 },
802
803 validate_pricing_rule: function(pricing_rule){
804 //This method validate duplicate pricing rule
805 var pricing_rule_name = '';
806 var priority = 0;
807 var pricing_rule_list = [];
808 var priority_list = []
809
810 if(pricing_rule.length > 1){
811
812 $.each(pricing_rule, function(index, data){
813 pricing_rule_name += data.name + ','
814 priority_list.push(data.priority)
815 if(priority <= data.priority){
816 priority = data.priority
817 pricing_rule_list.push(data)
818 }
819 })
820
821 count = 0
822 $.each(priority_list, function(index, value){
823 if(value == priority){
824 count++
825 }
826 })
827
828 if(priority == 0 || count > 1){
829 frappe.throw(__(repl("Multiple Price Rules exists with same criteria, please resolve conflict by assigning priority. Price Rules: %(pricing_rule)s", {
830 'pricing_rule': pricing_rule_name
831 })))
832 }
833
834 return pricing_rule_list
835 }
836 },
837
838 validate_warehouse: function(){
839 if(!this.items[0].default_warehouse){
840 frappe.throw(__("Deafault warehouse is required for selected item"))
841 }
842 }
843})