diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.js b/accounts/doctype/purchase_invoice/purchase_invoice.js index 2428a7dae91..fb5569a5f0c 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details"; wn.provide("erpnext.accounts"); wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); wn.require('app/buying/doctype/purchase_common/purchase_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ onload: function() { diff --git a/accounts/doctype/sales_invoice/pos.js b/accounts/doctype/sales_invoice/pos.js index 8837aed14b0..4ef239744b6 100644 --- a/accounts/doctype/sales_invoice/pos.js +++ b/accounts/doctype/sales_invoice/pos.js @@ -7,7 +7,7 @@ erpnext.POS = Class.extend({ this.frm = frm; this.wrapper.html('
\
\ -
\ +
\
\
\
\ @@ -71,7 +71,18 @@ erpnext.POS = Class.extend({
\
\ '); - + + if (wn.meta.has_field(cur_frm.doc.doctype, "customer")) { + this.party = "Customer"; + this.price_list = this.frm.doc.selling_price_list; + this.sales_or_purchase = "Sales"; + } + else if (wn.meta.has_field(cur_frm.doc.doctype, "supplier")) { + this.party = "Supplier"; + this.price_list = this.frm.doc.buying_price_list; + this.sales_or_purchase = "Purchase"; + } + this.make(); var me = this; @@ -88,28 +99,29 @@ erpnext.POS = Class.extend({ }); }, make: function() { - this.make_customer(); + this.make_party(); this.make_item_group(); this.make_search(); this.make_barcode(); this.make_item_list(); }, - make_customer: function() { + make_party: function() { var me = this; - this.customer = wn.ui.form.make_control({ + this.party_field = wn.ui.form.make_control({ df: { "fieldtype": "Link", - "options": "Customer", - "label": "Customer", - "fieldname": "pos_customer", - "placeholder": "Customer" + "options": this.party, + "label": this.party, + "fieldname": "pos_party", + "placeholder": this.party }, - parent: this.wrapper.find(".customer-area") + parent: this.wrapper.find(".party-area") }); - this.customer.make_input(); - this.customer.$input.on("change", function() { - if(!me.customer.autocomplete_open) - wn.model.set_value("Sales Invoice", me.frm.docname, "customer", this.value); + this.party_field.make_input(); + this.party_field.$input.on("change", function() { + if(!me.party_field.autocomplete_open) + wn.model.set_value(me.frm.doctype, me.frm.docname, + me.party.toLowerCase(), this.value); }); }, make_item_group: function() { @@ -171,7 +183,8 @@ erpnext.POS = Class.extend({ wn.call({ method: 'accounts.doctype.sales_invoice.pos.get_items', args: { - price_list: cur_frm.doc.selling_price_list, + sales_or_purchase: this.sales_or_purchase, + price_list: this.price_list, item_group: this.item_group.$input.val(), item: this.search.$input.val() }, @@ -202,11 +215,12 @@ erpnext.POS = Class.extend({ // if form is local then allow this function if (cur_frm.doc.docstatus===0) { $("div.pos-item").on("click", function() { - if(!cur_frm.doc.customer) { - msgprint("Please select customer first."); + if(!cur_frm.doc[me.party.toLowerCase()]) { + msgprint("Please select " + me.party + " first."); return; } - me.add_to_cart($(this).attr("data-item_code")); + else + me.add_to_cart($(this).attr("data-item_code")); }); } } @@ -217,12 +231,12 @@ erpnext.POS = Class.extend({ var caught = false; // get no_of_items - no_of_items = me.wrapper.find("#cart tbody").length; - + var no_of_items = me.wrapper.find("#cart tbody tr").length; + // check whether the item is already added if (no_of_items != 0) { - $.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", - "Sales Invoice"), function(i, d) { + $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name, + this.frm.cscript.fname, this.frm.doctype), function(i, d) { if (d.item_code == item_code) caught = true; }); @@ -233,15 +247,16 @@ erpnext.POS = Class.extend({ me.update_qty(item_code, 1); } else { - var child = wn.model.add_child(me.frm.doc, "Sales Invoice Item", "entries"); + var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item", + this.frm.cscript.fname); child.item_code = item_code; me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name); } }, update_qty: function(item_code, qty, textbox_qty) { var me = this; - $.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", - "Sales Invoice"), function(i, d) { + $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name, + this.frm.cscript.fname, this.frm.doctype), function(i, d) { if (d.item_code == item_code) { if (textbox_qty) { if (qty == 0 && d.item_code == item_code) @@ -259,14 +274,14 @@ erpnext.POS = Class.extend({ }, refresh: function() { var me = this; - this.customer.set_input(this.frm.doc.customer); + this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]); this.barcode.set_input(""); // add items var $items = me.wrapper.find("#cart tbody").empty(); - $.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", - "Sales Invoice"), function(i, d) { + $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name, + this.frm.cscript.fname, this.frm.doctype), function(i, d) { $(repl('\ %(item_code)s%(item_name)s\ " + d.item_name), qty: d.qty, - rate: format_currency(d.ref_rate, cur_frm.doc.price_list_currency), - amount: format_currency(d.export_amount, cur_frm.doc.price_list_currency) + rate: format_currency(d.ref_rate, cur_frm.doc.currency), + amount: format_currency(d.export_amount, cur_frm.doc.currency) } )).appendTo($items); }); // taxes - var taxes = wn.model.get_children("Sales Taxes and Charges", this.frm.doc.name, "other_charges", - "Sales Invoice"); + var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges", + this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype); $(".tax-table") .toggle((taxes && taxes.length) ? true : false) .find("tbody").empty(); @@ -297,15 +312,15 @@ erpnext.POS = Class.extend({ ', { description: d.description, rate: d.rate, - tax_amount: format_currency(d.tax_amount, me.frm.doc.price_list_currency) + tax_amount: format_currency(d.tax_amount, me.frm.doc.currency) })).appendTo(".tax-table tbody"); }); // set totals this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export, - cur_frm.doc.price_list_currency)); + cur_frm.doc.currency)); this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export, - cur_frm.doc.price_list_currency)); + cur_frm.doc.currency)); // if form is local then only run all these functions if (cur_frm.doc.docstatus===0) { @@ -320,7 +335,7 @@ erpnext.POS = Class.extend({ }); // on td click toggle the highlighting of row - $("#cart tbody tr td").on("click", function() { + me.wrapper.find("#cart tbody tr td").on("click", function() { var row = $(this).closest("tr"); if (row.attr("data-selected") == "false") { row.attr("class", "warning"); @@ -339,13 +354,21 @@ erpnext.POS = Class.extend({ } // if form is submitted & cancelled then disable all input box & buttons - if (cur_frm.doc.docstatus>=1 && cint(cur_frm.doc.is_pos)) { + if (cur_frm.doc.docstatus>=1) { me.wrapper.find('input, button').each(function () { $(this).prop('disabled', true); }); $(".delete-items").hide(); $(".make-payment").hide(); } + + // Show Make Payment button only in Sales Invoice + if (this.frm.doctype != "Sales Invoice") + $(".make-payment").hide(); + + if (this.frm.doctype == "Quotation") + if (cur_frm.doc.quotation_to=="Customer") + this.party_field.remove(); }, refresh_delete_btn: function() { $(".delete-items").toggle($(".item-cart .warning").length ? true : false); @@ -370,32 +393,32 @@ erpnext.POS = Class.extend({ remove_selected_item: function() { var me = this; var selected_items = []; - var no_of_items = $("#cart tbody tr").length; + var no_of_items = me.wrapper.find("#cart tbody tr").length; for(var x=0; x<=no_of_items - 1; x++) { - var row = $("#cart tbody tr:eq(" + x + ")"); + var row = me.wrapper.find("#cart tbody tr:eq(" + x + ")"); if(row.attr("data-selected") == "true") { selected_items.push(row.attr("id")); } } - - var child = wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", - "Sales Invoice"); + + var child = wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name, + this.frm.cscript.fname, this.frm.doctype); + $.each(child, function(i, d) { for (var i in selected_items) { if (d.item_code == selected_items[i]) { - // cur_frm.fields_dict["entries"].grid.grid_rows[d.idx].remove(); wn.model.clear_doc(d.doctype, d.name); } } }); - cur_frm.fields_dict["entries"].grid.refresh(); + cur_frm.fields_dict[this.frm.cscript.fname].grid.refresh(); cur_frm.script_manager.trigger("calculate_taxes_and_totals"); me.frm.dirty(); me.refresh(); }, make_payment: function() { var me = this; - var no_of_items = $("#cart tbody tr").length; + var no_of_items = me.wrapper.find("#cart tbody tr").length; var mode_of_payment = []; if (no_of_items == 0) diff --git a/accounts/doctype/sales_invoice/pos.py b/accounts/doctype/sales_invoice/pos.py index 08340f76c5e..d919c1b548c 100644 --- a/accounts/doctype/sales_invoice/pos.py +++ b/accounts/doctype/sales_invoice/pos.py @@ -3,17 +3,22 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint +from webnotes import msgprint, errprint @webnotes.whitelist() -def get_items(price_list, item=None, item_group=None): +def get_items(price_list, sales_or_purchase, item=None, item_group=None): condition = "" + if sales_or_purchase == "Sales": + condition = "i.is_sales_item='Yes'" + else: + condition = "i.is_purchase_item='Yes'" + if item_group and item_group != "All Item Groups": - condition = "and i.item_group='%s'" % item_group + condition += " and i.item_group='%s'" % item_group if item: - condition = "and i.name='%s'" % item + condition += " and i.name='%s'" % item return webnotes.conn.sql("""select i.name, i.item_name, i.image, pl_items.ref_rate, pl_items.currency @@ -24,7 +29,7 @@ def get_items(price_list, item=None, item_group=None): ON pl_items.item_code=i.name where - i.is_sales_item='Yes'%s""" % ('%s', condition), (price_list), as_dict=1) + %s""" % ('%s', condition), (price_list), as_dict=1) @webnotes.whitelist() def get_item_from_barcode(barcode): diff --git a/accounts/doctype/sales_invoice/sales_invoice.css b/accounts/doctype/sales_invoice/sales_invoice.css deleted file mode 100644 index e4b61b66ca8..00000000000 --- a/accounts/doctype/sales_invoice/sales_invoice.css +++ /dev/null @@ -1,15 +0,0 @@ -.pos-item { - height: 200px; - overflow: hidden; - cursor: pointer; - padding-left: 5px !important; - padding-right: 5px !important; -} - -.pos-bill { - padding: 20px 5px; - font-family: Monospace; - border: 1px solid #eee; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); -} \ No newline at end of file diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js index 60f73b5a191..13cbc634dd2 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.js +++ b/accounts/doctype/sales_invoice/sales_invoice.js @@ -78,14 +78,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte cur_frm.add_custom_button('Make Payment Entry', cur_frm.cscript.make_bank_voucher); } - if (doc.docstatus===0) { + // Show buttons only when pos view is active + if (doc.docstatus===0 && !this.pos_active) { cur_frm.cscript.sales_order_btn(); cur_frm.cscript.delivery_note_btn(); } - - // Show POS button only if it enabled from features setup - if(cint(sys_defaults.fs_pos_view)===1) - cur_frm.cscript.pos_btn(); }, sales_order_btn: function() { @@ -124,54 +121,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte }); }); }, - - pos_btn: function() { - if(cur_frm.$pos_btn) - cur_frm.$pos_btn.remove(); - - if(!cur_frm.pos_active) { - var btn_label = wn._("POS View"), - icon = "icon-desktop"; - - cur_frm.cscript.sales_order_btn(); - cur_frm.cscript.delivery_note_btn(); - } else { - var btn_label = wn._("Invoice View"), - icon = "icon-file-text"; - - if (cur_frm.doc.docstatus===0) { - this.$delivery_note_btn.remove(); - this.$sales_order_btn.remove(); - } - } - - cur_frm.$pos_btn = cur_frm.add_custom_button(btn_label, function() { - cur_frm.cscript.toggle_pos(); - cur_frm.cscript.pos_btn(); - }, icon); - }, - - toggle_pos: function(show) { - if (!this.frm.doc.selling_price_list) - msgprint(wn._("Please select Price List")) - else { - if((show===true && cur_frm.pos_active) || (show===false && !cur_frm.pos_active)) return; - - // make pos - if(!cur_frm.pos) { - cur_frm.layout.add_view("pos"); - cur_frm.pos = new erpnext.POS(cur_frm.layout.views.pos, cur_frm); - } - - // toggle view - cur_frm.layout.set_view(cur_frm.pos_active ? "" : "pos"); - cur_frm.pos_active = !cur_frm.pos_active; - - // refresh - if(cur_frm.pos_active) - cur_frm.pos.refresh(); - } - }, tc_name: function() { this.get_terms(); @@ -179,7 +128,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte is_pos: function() { cur_frm.cscript.hide_fields(this.frm.doc); - if(cint(this.frm.doc.is_pos)) { if(!this.frm.doc.company) { this.frm.set_value("is_pos", 0); @@ -197,6 +145,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte }); } } + }, debit_to: function() { diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt index f921f242234..00c6c2cc5c5 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.txt +++ b/accounts/doctype/sales_invoice/sales_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:05", "docstatus": 0, - "modified": "2013-09-01 05:26:13", + "modified": "2013-09-19 11:42:13", "modified_by": "Administrator", "owner": "Administrator" }, @@ -180,6 +180,7 @@ "search_index": 1 }, { + "default": "Today", "description": "Enter the date by which payments from customer is expected against this invoice.", "doctype": "DocField", "fieldname": "due_date", @@ -411,7 +412,7 @@ "doctype": "DocField", "fieldname": "other_charges", "fieldtype": "Table", - "label": "Taxes and Charges1", + "label": "Sales Taxes and Charges", "oldfieldname": "other_charges", "oldfieldtype": "Table", "options": "Sales Taxes and Charges", diff --git a/buying/doctype/purchase_order/purchase_order.js b/buying/doctype/purchase_order/purchase_order.js index a960046b75c..9967f15a50b 100644 --- a/buying/doctype/purchase_order/purchase_order.js +++ b/buying/doctype/purchase_order/purchase_order.js @@ -10,6 +10,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details"; wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); wn.require('app/utilities/doctype/sms_control/sms_control.js'); wn.require('app/buying/doctype/purchase_common/purchase_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({ refresh: function(doc, cdt, cdn) { diff --git a/buying/doctype/supplier_quotation/supplier_quotation.js b/buying/doctype/supplier_quotation/supplier_quotation.js index cd6127d2355..3fba931f995 100644 --- a/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/buying/doctype/supplier_quotation/supplier_quotation.js @@ -9,6 +9,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details"; // attach required files wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); wn.require('app/buying/doctype/purchase_common/purchase_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({ refresh: function() { diff --git a/buying/utils.py b/buying/utils.py index f4fb2f3ff87..179db9bf464 100644 --- a/buying/utils.py +++ b/buying/utils.py @@ -65,7 +65,7 @@ def _get_basic_details(args, item_bean): out = webnotes._dict({ "description": item.description_html or item.description, - "qty": 0.0, + "qty": 1.0, "uom": item.stock_uom, "conversion_factor": 1.0, "warehouse": args.warehouse or item.default_warehouse, diff --git a/public/js/startup.css b/public/js/startup.css index ab70ee44147..c3b7276de4e 100644 --- a/public/js/startup.css +++ b/public/js/startup.css @@ -29,4 +29,21 @@ span, div, td, input, textarea, button, select { width: 32px; height: 32px; margin: -10px auto; +} + +/* pos */ +.pos-item { + height: 200px; + overflow: hidden; + cursor: pointer; + padding-left: 5px !important; + padding-right: 5px !important; +} + +.pos-bill { + padding: 20px 5px; + font-family: Monospace; + border: 1px solid #eee; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); } \ No newline at end of file diff --git a/public/js/transaction.js b/public/js/transaction.js index 387140472c7..1a1c98ca6bf 100644 --- a/public/js/transaction.js +++ b/public/js/transaction.js @@ -62,6 +62,56 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ erpnext.hide_company(); this.show_item_wise_taxes(); this.set_dynamic_labels(); + + // Show POS button only if it is enabled from features setup + if(cint(sys_defaults.fs_pos_view)===1 && this.frm.doctype!="Material Request") + this.pos_btn(); + }, + + pos_btn: function() { + if(this.$pos_btn) + this.$pos_btn.remove(); + + if(!this.pos_active) { + var btn_label = wn._("POS View"), + icon = "icon-desktop"; + } else { + var btn_label = wn._(this.frm.doctype) + wn._(" View"), + icon = "icon-file-text"; + } + var me = this; + + this.$pos_btn = this.frm.add_custom_button(btn_label, function() { + me.toggle_pos(); + me.pos_btn(); + }, icon); + }, + + toggle_pos: function(show) { + // Check whether it is Selling or Buying cycle + var price_list = wn.meta.has_field(cur_frm.doc.doctype, "selling_price_list") ? + this.frm.doc.selling_price_list : this.frm.doc.buying_price_list; + + if (!price_list) + msgprint(wn._("Please select Price List")) + else { + if((show===true && this.pos_active) || (show===false && !this.pos_active)) return; + + // make pos + if(!this.frm.pos) { + this.frm.layout.add_view("pos"); + this.frm.pos = new erpnext.POS(this.frm.layout.views.pos, this.frm); + } + + // toggle view + this.frm.layout.set_view(this.pos_active ? "" : "pos"); + this.pos_active = !this.pos_active; + + // refresh + if(this.pos_active) + this.frm.pos.refresh(); + this.frm.refresh(); + } }, validate: function() { @@ -418,10 +468,10 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ (this.frm.doc.currency != company_currency && this.frm.doc.conversion_rate != 1.0)) : false; - // if(!valid_conversion_rate) { - // wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) + - // " 1 " + this.frm.doc.currency + " = [?] " + company_currency); - // } + if(!valid_conversion_rate) { + wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) + + " 1 " + this.frm.doc.currency + " = [?] " + company_currency); + } }, calculate_taxes_and_totals: function() { diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index ea1b62aa0a7..33ba0933bb2 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -11,6 +11,7 @@ cur_frm.cscript.sales_team_fname = "sales_team"; wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js'); wn.require('app/utilities/doctype/sms_control/sms_control.js'); wn.require('app/selling/doctype/sales_common/sales_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ onload: function(doc, dt, dn) { diff --git a/selling/doctype/sales_order/sales_order.js b/selling/doctype/sales_order/sales_order.js index 33699f05d84..161e10fe4e5 100644 --- a/selling/doctype/sales_order/sales_order.js +++ b/selling/doctype/sales_order/sales_order.js @@ -12,6 +12,7 @@ cur_frm.cscript.sales_team_fname = "sales_team"; wn.require('app/selling/doctype/sales_common/sales_common.js'); wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js'); wn.require('app/utilities/doctype/sms_control/sms_control.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({ refresh: function(doc, dt, dn) { diff --git a/stock/doctype/delivery_note/delivery_note.js b/stock/doctype/delivery_note/delivery_note.js index 80c26463ff8..0413b72f51a 100644 --- a/stock/doctype/delivery_note/delivery_note.js +++ b/stock/doctype/delivery_note/delivery_note.js @@ -10,6 +10,7 @@ cur_frm.cscript.sales_team_fname = "sales_team"; wn.require('app/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js'); wn.require('app/utilities/doctype/sms_control/sms_control.js'); wn.require('app/selling/doctype/sales_common/sales_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); wn.provide("erpnext.stock"); erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({ diff --git a/stock/doctype/purchase_receipt/purchase_receipt.js b/stock/doctype/purchase_receipt/purchase_receipt.js index 8775140a8bd..5333c21be05 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/stock/doctype/purchase_receipt/purchase_receipt.js @@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details"; wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); wn.require('app/utilities/doctype/sms_control/sms_control.js'); wn.require('app/buying/doctype/purchase_common/purchase_common.js'); +wn.require('app/accounts/doctype/sales_invoice/pos.js'); wn.provide("erpnext.stock"); erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({