diff --git a/accounts/doctype/sales_invoice/pos.js b/accounts/doctype/sales_invoice/pos.js
index 5045530aa9..c27adc3a57 100644
--- a/accounts/doctype/sales_invoice/pos.js
+++ b/accounts/doctype/sales_invoice/pos.js
@@ -5,10 +5,63 @@ erpnext.POS = Class.extend({
init: function(wrapper, frm) {
this.wrapper = wrapper;
this.frm = frm;
- this.wrapper.html('
');
-
+ this.wrapper.html('
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+ \
+ Item | \
+ # | \
+ Rate | \
+ Amount | \
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
\
+
');
+
this.make();
var me = this;
@@ -16,10 +69,20 @@ erpnext.POS = Class.extend({
me.refresh();
});
+ this.wrapper.find(".delete-items").on("click", function() {
+ me.remove_selected_item();
+ });
+
+ this.wrapper.find(".make-payment").on("click", function() {
+ me.make_payment();
+ });
},
make: function() {
this.make_customer();
- this.make_items();
+ this.make_item_group();
+ this.make_search();
+ this.make_barcode();
+ this.make_item_list();
},
make_customer: function() {
var me = this;
@@ -36,25 +99,272 @@ erpnext.POS = Class.extend({
this.customer.$input.on("change", function() {
if(!me.customer.autocomplete_open)
wn.model.set_value("Sales Invoice", me.frm.docname, "customer", this.value);
- });
- },
- make_items: function() {
- var me = this;
- this.wrapper.find(".btn-add").click(function() {
- var child = wn.model.add_child(me.frm.doc, "Sales Invoice Item", "entries");
- child.item_code = "Test Item";
- me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
});
},
+ make_item_group: function() {
+ var me = this;
+ this.item_group = wn.ui.form.make_control({
+ df: {
+ "fieldtype": "Link",
+ "options": "Item Group",
+ "label": "Item Group",
+ "fieldname": "pos_item_group"
+ },
+ parent: this.wrapper.find(".item-group-area")
+ });
+ this.item_group.make_input();
+ this.item_group.$input.on("change", function() {
+ if(!me.item_group.autocomplete_open)
+ me.make_item_list();
+ });
+ },
+ make_search: function() {
+ var me = this;
+ this.search = wn.ui.form.make_control({
+ df: {
+ "fieldtype": "Link",
+ "options": "Item",
+ "label": "Item",
+ "fieldname": "pos_item"
+ },
+ parent: this.wrapper.find(".search-area")
+ });
+ this.search.make_input();
+ this.search.$input.on("change", function() {
+ if(!me.search.autocomplete_open)
+ me.make_item_list();
+ });
+ },
+ make_barcode: function() {
+ var me = this;
+ this.barcode = wn.ui.form.make_control({
+ df: {
+ "fieldtype": "Data",
+ "label": "Barcode",
+ "fieldname": "pos_barcode"
+ },
+ parent: this.wrapper.find(".barcode-area")
+ });
+ this.barcode.make_input();
+ this.barcode.$input.on("change", function() {
+ me.add_item_thru_barcode();
+ });
+ },
+ make_item_list: function() {
+ var me = this;
+ wn.call({
+ method: 'accounts.doctype.sales_invoice.pos.get_items',
+ args: {
+ price_list: cur_frm.doc.selling_price_list,
+ item_group: this.item_group.$input.val(),
+ item: this.search.$input.val()
+ },
+ callback: function(r) {
+ var $wrap = me.wrapper.find(".item-list");
+ me.wrapper.find(".item-list").empty();
+ $.each(r.message, function(index, obj) {
+ if (obj.image)
+ image = "
";
+ else
+ image = "
";
+
+ $(repl('
\
+
\
+ \
+ %(item_image)s |
\
+ %(item_code)s | \
+ %(item_price)s |
\
+ %(item_name)s | \
+
',
+ {
+ item_code: obj.name,
+ item_price: format_currency(obj.ref_rate, obj.ref_currency),
+ item_name: obj.item_name,
+ item_image: image
+ })).appendTo($wrap);
+ });
+
+ $("div.item").on("click", function() {
+ me.add_to_cart($(this).find("a").attr("data-item_code"));
+ });
+ }
+ });
+ },
+ add_to_cart: function(item_code) {
+ var me = this;
+ var caught = false;
+
+ // get no_of_items
+ no_of_items = me.wrapper.find("#cart 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) {
+ if (d.item_code == item_code)
+ caught = true;
+ });
+ }
+
+ // if duplicate row then append the qty
+ if (caught) {
+ me.update_qty(item_code, 1);
+ }
+ else {
+ var child = wn.model.add_child(me.frm.doc, "Sales Invoice Item", "entries");
+ child.item_code = item_code;
+ me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
+ me.refresh();
+ }
+ },
+ update_qty: function(item_code, qty) {
+ var me = this;
+ $.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
+ "Sales Invoice"), function(i, d) {
+ if (d.item_code == item_code) {
+ if (qty == 1)
+ d.qty += 1;
+ else
+ d.qty = qty;
+
+ me.frm.cscript.qty(me.frm.doc, d.doctype, d.name);
+ }
+ });
+ me.refresh();
+ },
refresh: function() {
var me = this;
this.customer.set_input(this.frm.doc.customer);
-
+ this.barcode.set_input("");
+
// add items
- var $items = me.wrapper.find(".item-area").empty();
+ var $items = me.wrapper.find("#cart").empty();
+
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
- "Sales Invoice"), function(i, d) {
- $(repl("
%(item_code)s
", d)).appendTo($items);
+ "Sales Invoice"), function(i, d) {
+ $(repl('
\
+ %(item_code)s %(item_name)s | \
+ | \
+ %(rate)s | \
+ %(amount)s |
',
+ {
+ item_code: d.item_code,
+ item_name: 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)
+ }
+ )).appendTo($items);
+ });
+
+ // set totals
+ this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
+ cur_frm.doc.price_list_currency));
+ this.wrapper.find(".tax").text(format_currency(this.frm.doc.other_charges_total_export,
+ cur_frm.doc.price_list_currency));
+ this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
+ cur_frm.doc.price_list_currency));
+
+ // append quantity to the respective item after change from input box
+ $("input.qty").on("change", function() {
+ var item_code = $(this).closest("tr")[0].id;
+ me.update_qty(item_code, $(this).val());
+ });
+
+ // on td click highlight the respective row
+ $("td").on("click", function() {
+ var row = $(this).closest("tr");
+ if (row.attr("data-selected") == "false") {
+ row.attr("class", "warning");
+ row.attr("data-selected", "true");
+ }
+ else {
+ row.prop("class", null);
+ row.attr("data-selected", "false");
+ }
+ });
+ },
+ add_item_thru_barcode: function() {
+ var me = this;
+ wn.call({
+ method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode',
+ args: {barcode: this.barcode.$input.val()},
+ callback: function(r) {
+ if (r.message) {
+ me.add_to_cart(r.message[0].name);
+ me.refresh();
+ }
+ else
+ msgprint(wn._("Invalid Barcode"));
+ }
+ });
+ },
+ remove_selected_item: function() {
+ var me = this;
+ var selected_items = [];
+ var no_of_items = $("#cart tr").length;
+ for(var x=0; x<=no_of_items - 1; x++) {
+ var row = $("#cart tr:eq(" + x + ")");
+ if(row.attr("data-selected") == "true") {
+ selected_items.push(row.attr("id"));
+ }
+ }
+
+ if (!selected_items[0])
+ msgprint(wn._("Please select any item to remove it"));
+
+ var child = wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
+ "Sales Invoice");
+ $.each(child, function(i, d) {
+ for (var i in selected_items) {
+ if (d.item_code == selected_items[i]) {
+ wn.model.clear_doc(d.doctype, d.name);
+ }
+ }
+ });
+ cur_frm.fields_dict["entries"].grid.refresh();
+ me.refresh();
+ },
+ make_payment: function() {
+ var me = this;
+ var no_of_items = $("#cart tr").length;
+ var mode_of_payment = [];
+
+ if (no_of_items == 0)
+ msgprint(wn._("Payment cannot be made for empty cart"));
+ else {
+ wn.call({
+ method: 'accounts.doctype.sales_invoice.pos.get_mode_of_payment',
+ callback: function(r) {
+ for (x=0; x<=r.message.length - 1; x++) {
+ mode_of_payment.push(r.message[x].name);
+ }
+
+ // show payment wizard
+ var dialog = new wn.ui.Dialog({
+ width: 400,
+ title: 'Payment',
+ fields: [
+ {fieldtype:'Data', fieldname:'total_amount', label:'Total Amount', read_only:1},
+ {fieldtype:'Select', fieldname:'mode_of_payment', label:'Mode of Payment',
+ options:mode_of_payment.join('\n'), reqd: 1},
+ {fieldtype:'Button', fieldname:'pay', label:'Pay'}
+ ]
+ });
+ dialog.set_values({
+ "total_amount": $(".grand-total").text()
+ });
+ dialog.show();
+
+ dialog.fields_dict.pay.input.onclick = function() {
+ cur_frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
+ cur_frm.set_value("paid_amount", dialog.get_values().total_amount);
+ cur_frm.save();
+ dialog.hide();
+ me.refresh();
+ };
+ }
});
- }
-})
\ No newline at end of file
+ }
+ },
+});
\ No newline at end of file
diff --git a/accounts/doctype/sales_invoice/pos.py b/accounts/doctype/sales_invoice/pos.py
new file mode 100644
index 0000000000..f7dacf19a6
--- /dev/null
+++ b/accounts/doctype/sales_invoice/pos.py
@@ -0,0 +1,28 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+@webnotes.whitelist()
+def get_items(price_list, item=None, item_group=None):
+ condition = ""
+
+ if item_group and item_group != "All Item Groups":
+ condition = "where i.item_group='%s'" % item_group
+
+ if item:
+ condition = "where i.name='%s'" % item
+
+ return webnotes.conn.sql("""select i.name, i.item_name, i.image, ip.ref_rate,
+ ip.ref_currency from `tabItem` i LEFT JOIN `tabItem Price` ip ON ip.parent=i.name
+ and ip.price_list=%s %s""" % ('%s', condition), (price_list), as_dict=1)
+
+@webnotes.whitelist()
+def get_item_from_barcode(barcode):
+ return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
+ (barcode), as_dict=1)
+
+@webnotes.whitelist()
+def get_mode_of_payment():
+ return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1)
\ 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 0b25a683f9..3baa226884 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/accounts/doctype/sales_invoice/sales_invoice.js
@@ -12,7 +12,7 @@ cur_frm.pformat.print_heading = 'Invoice';
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.require('app/accounts/doctype/sales_invoice/pos.js');
wn.provide("erpnext.accounts");
erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.extend({
@@ -25,9 +25,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
this.frm.set_df_property("debit_to", "print_hide", 0);
}
}
- // if(this.frm.doc.is_pos && this.frm.doc.docstatus===0) {
- // cur_frm.cscript.toggle_pos(true);
- // }
+
+ pos_view = cint(sys_defaults.fs_pos_view);
+ if(this.frm.doc.is_pos && this.frm.doc.docstatus===0 && pos_view===1) {
+ cur_frm.cscript.toggle_pos(true);
+ }
},
refresh: function(doc, dt, dn) {
@@ -92,32 +94,52 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}
});
});
-
- // cur_frm.add_custom_button(wn._("POS View"), function() {
- // cur_frm.cscript.toggle_pos();
- // }, 'icon-desktop');
-
+
+ if (cint(sys_defaults.fs_pos_view)===1)
+ cur_frm.cscript.pos_btn();
}
},
+ 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";
+ } else {
+ var btn_label = wn._("Invoice View"),
+ icon = "icon-file-text";
+ }
+
+ cur_frm.add_custom_button(btn_label, function() {
+ cur_frm.$pos_btn = $(this);
+ cur_frm.cscript.toggle_pos();
+ cur_frm.cscript.pos_btn();
+ }, icon);
+ },
+
toggle_pos: function(show) {
- 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);
+ 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();
}
-
- // 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();
},
diff --git a/setup/doctype/features_setup/features_setup.txt b/setup/doctype/features_setup/features_setup.txt
index e1a4c08acf..89c9dd310b 100644
--- a/setup/doctype/features_setup/features_setup.txt
+++ b/setup/doctype/features_setup/features_setup.txt
@@ -2,7 +2,7 @@
{
"creation": "2012-12-20 12:50:49",
"docstatus": 0,
- "modified": "2013-07-05 14:37:59",
+ "modified": "2013-08-22 15:36:43",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -184,6 +184,13 @@
"fieldtype": "Check",
"label": "Point of Sale"
},
+ {
+ "description": "To enable
Point of Sale view",
+ "doctype": "DocField",
+ "fieldname": "fs_pos_view",
+ "fieldtype": "Check",
+ "label": "POS View"
+ },
{
"doctype": "DocField",
"fieldname": "production",