Merge pull request #883 from akhileshdarjee/master

[feature] pos view added in all sales & purchase cycle
This commit is contained in:
Nabin Hait 2013-09-27 00:05:15 -07:00
commit 164d39d12f
20 changed files with 248 additions and 159 deletions

View File

@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
wn.provide("erpnext.accounts"); wn.provide("erpnext.accounts");
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); 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/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
onload: function() { onload: function() {

View File

@ -62,19 +62,20 @@ class DocType(BuyingController):
"purchase_receipt_details") "purchase_receipt_details")
def get_credit_to(self): def get_credit_to(self):
acc_head = sql("""select name, credit_days from `tabAccount`
where (name = %s or (master_name = %s and master_type = 'supplier'))
and docstatus != 2 and company = %s""",
(cstr(self.doc.supplier) + " - " + self.company_abbr,
self.doc.supplier, self.doc.company))
ret = {} ret = {}
if acc_head and acc_head[0][0]: if self.doc.supplier:
ret['credit_to'] = acc_head[0][0] acc_head = sql("""select name, credit_days from `tabAccount`
if not self.doc.due_date: where (name = %s or (master_name = %s and master_type = 'supplier'))
ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0) and docstatus != 2 and company = %s""",
elif not acc_head: (cstr(self.doc.supplier) + " - " + self.company_abbr,
msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company)) self.doc.supplier, self.doc.company))
if acc_head and acc_head[0][0]:
ret['credit_to'] = acc_head[0][0]
if not self.doc.due_date:
ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0)
elif not acc_head:
msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
return ret return ret
def set_supplier_defaults(self): def set_supplier_defaults(self):

View File

@ -7,7 +7,7 @@ erpnext.POS = Class.extend({
this.frm = frm; this.frm = frm;
this.wrapper.html('<div class="container">\ this.wrapper.html('<div class="container">\
<div class="row">\ <div class="row">\
<div class="customer-area col-sm-3 col-xs-6"></div>\ <div class="party-area col-sm-3 col-xs-6"></div>\
<div class="barcode-area col-sm-3 col-xs-6"></div>\ <div class="barcode-area col-sm-3 col-xs-6"></div>\
<div class="search-area col-sm-3 col-xs-6"></div>\ <div class="search-area col-sm-3 col-xs-6"></div>\
<div class="item-group-area col-sm-3 col-xs-6"></div>\ <div class="item-group-area col-sm-3 col-xs-6"></div>\
@ -71,7 +71,18 @@ erpnext.POS = Class.extend({
</div>\ </div>\
</div>\ </div>\
</div></div>'); </div></div>');
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(); this.make();
var me = this; var me = this;
@ -88,28 +99,29 @@ erpnext.POS = Class.extend({
}); });
}, },
make: function() { make: function() {
this.make_customer(); this.make_party();
this.make_item_group(); this.make_item_group();
this.make_search(); this.make_search();
this.make_barcode(); this.make_barcode();
this.make_item_list(); this.make_item_list();
}, },
make_customer: function() { make_party: function() {
var me = this; var me = this;
this.customer = wn.ui.form.make_control({ this.party_field = wn.ui.form.make_control({
df: { df: {
"fieldtype": "Link", "fieldtype": "Link",
"options": "Customer", "options": this.party,
"label": "Customer", "label": this.party,
"fieldname": "pos_customer", "fieldname": "pos_party",
"placeholder": "Customer" "placeholder": this.party
}, },
parent: this.wrapper.find(".customer-area") parent: this.wrapper.find(".party-area")
}); });
this.customer.make_input(); this.party_field.make_input();
this.customer.$input.on("change", function() { this.party_field.$input.on("change", function() {
if(!me.customer.autocomplete_open) if(!me.party_field.autocomplete_open)
wn.model.set_value("Sales Invoice", me.frm.docname, "customer", this.value); wn.model.set_value(me.frm.doctype, me.frm.docname,
me.party.toLowerCase(), this.value);
}); });
}, },
make_item_group: function() { make_item_group: function() {
@ -120,7 +132,7 @@ erpnext.POS = Class.extend({
"options": "Item Group", "options": "Item Group",
"label": "Item Group", "label": "Item Group",
"fieldname": "pos_item_group", "fieldname": "pos_item_group",
"placeholder": "Filter by Item Group" "placeholder": "Item Group"
}, },
parent: this.wrapper.find(".item-group-area") parent: this.wrapper.find(".item-group-area")
}); });
@ -138,7 +150,7 @@ erpnext.POS = Class.extend({
"options": "Item", "options": "Item",
"label": "Item", "label": "Item",
"fieldname": "pos_item", "fieldname": "pos_item",
"placeholder": "Select Item" "placeholder": "Item"
}, },
parent: this.wrapper.find(".search-area") parent: this.wrapper.find(".search-area")
}); });
@ -155,7 +167,7 @@ erpnext.POS = Class.extend({
"fieldtype": "Data", "fieldtype": "Data",
"label": "Barcode", "label": "Barcode",
"fieldname": "pos_barcode", "fieldname": "pos_barcode",
"placeholder": "Select Barcode" "placeholder": "Barcode"
}, },
parent: this.wrapper.find(".barcode-area") parent: this.wrapper.find(".barcode-area")
}); });
@ -171,7 +183,8 @@ erpnext.POS = Class.extend({
wn.call({ wn.call({
method: 'accounts.doctype.sales_invoice.pos.get_items', method: 'accounts.doctype.sales_invoice.pos.get_items',
args: { 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_group: this.item_group.$input.val(),
item: this.search.$input.val() item: this.search.$input.val()
}, },
@ -200,13 +213,16 @@ erpnext.POS = Class.extend({
}); });
// if form is local then allow this function // if form is local then allow this function
if (cur_frm.doc.docstatus===0) { if (me.frm.doc.docstatus===0) {
$("div.pos-item").on("click", function() { $("div.pos-item").on("click", function() {
if(!cur_frm.doc.customer) { if(!me.frm.doc[me.party.toLowerCase()] && ((me.frm.doctype == "Quotation" &&
msgprint("Please select customer first."); me.frm.doc.quotation_to == "Customer")
|| me.frm.doctype != "Quotation")) {
msgprint("Please select " + me.party + " first.");
return; return;
} }
me.add_to_cart($(this).attr("data-item_code")); else
me.add_to_cart($(this).attr("data-item_code"));
}); });
} }
} }
@ -217,12 +233,12 @@ erpnext.POS = Class.extend({
var caught = false; var caught = false;
// get no_of_items // 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 // check whether the item is already added
if (no_of_items != 0) { if (no_of_items != 0) {
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
"Sales Invoice"), function(i, d) { this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (d.item_code == item_code) if (d.item_code == item_code)
caught = true; caught = true;
}); });
@ -233,15 +249,16 @@ erpnext.POS = Class.extend({
me.update_qty(item_code, 1); me.update_qty(item_code, 1);
} }
else { 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; child.item_code = item_code;
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name); me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
} }
}, },
update_qty: function(item_code, qty, textbox_qty) { update_qty: function(item_code, qty, textbox_qty) {
var me = this; var me = this;
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
"Sales Invoice"), function(i, d) { this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (d.item_code == item_code) { if (d.item_code == item_code) {
if (textbox_qty) { if (textbox_qty) {
if (qty == 0 && d.item_code == item_code) if (qty == 0 && d.item_code == item_code)
@ -259,14 +276,24 @@ erpnext.POS = Class.extend({
}, },
refresh: function() { refresh: function() {
var me = this; 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(""); this.barcode.set_input("");
// add items // add items
var $items = me.wrapper.find("#cart tbody").empty(); var $items = me.wrapper.find("#cart tbody").empty();
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", $.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
"Sales Invoice"), function(i, d) { this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (me.sales_or_purchase == "Sales") {
item_amount = d.export_amount;
rate = d.export_rate;
}
else {
item_amount = d.import_amount;
rate = d.import_rate;
}
$(repl('<tr id="%(item_code)s" data-selected="false">\ $(repl('<tr id="%(item_code)s" data-selected="false">\
<td>%(item_code)s%(item_name)s</td>\ <td>%(item_code)s%(item_name)s</td>\
<td><input type="text" value="%(qty)s" \ <td><input type="text" value="%(qty)s" \
@ -277,15 +304,15 @@ erpnext.POS = Class.extend({
item_code: d.item_code, item_code: d.item_code,
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name), item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
qty: d.qty, qty: d.qty,
rate: format_currency(d.ref_rate, cur_frm.doc.price_list_currency), rate: format_currency(rate, me.frm.doc.currency),
amount: format_currency(d.export_amount, cur_frm.doc.price_list_currency) amount: format_currency(item_amount, me.frm.doc.currency)
} }
)).appendTo($items); )).appendTo($items);
}); });
// taxes // taxes
var taxes = wn.model.get_children("Sales Taxes and Charges", this.frm.doc.name, "other_charges", var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
"Sales Invoice"); this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
$(".tax-table") $(".tax-table")
.toggle((taxes && taxes.length) ? true : false) .toggle((taxes && taxes.length) ? true : false)
.find("tbody").empty(); .find("tbody").empty();
@ -297,18 +324,27 @@ erpnext.POS = Class.extend({
<tr>', { <tr>', {
description: d.description, description: d.description,
rate: d.rate, rate: d.rate,
tax_amount: format_currency(d.tax_amount, me.frm.doc.price_list_currency) tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
me.frm.doc.currency)
})).appendTo(".tax-table tbody"); })).appendTo(".tax-table tbody");
}); });
// set totals // set totals
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export, if (this.sales_or_purchase == "Sales") {
cur_frm.doc.price_list_currency)); this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export, me.frm.doc.currency));
cur_frm.doc.price_list_currency)); this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
me.frm.doc.currency));
}
else {
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_import,
me.frm.doc.currency));
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_import,
me.frm.doc.currency));
}
// if form is local then only run all these functions // if form is local then only run all these functions
if (cur_frm.doc.docstatus===0) { if (this.frm.doc.docstatus===0) {
$("input.qty").on("focus", function() { $("input.qty").on("focus", function() {
$(this).select(); $(this).select();
}); });
@ -320,7 +356,7 @@ erpnext.POS = Class.extend({
}); });
// on td click toggle the highlighting of row // 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"); var row = $(this).closest("tr");
if (row.attr("data-selected") == "false") { if (row.attr("data-selected") == "false") {
row.attr("class", "warning"); row.attr("class", "warning");
@ -335,17 +371,28 @@ erpnext.POS = Class.extend({
}); });
me.refresh_delete_btn(); me.refresh_delete_btn();
cur_frm.pos.barcode.$input.focus(); this.frm.pos.barcode.$input.focus();
} }
// if form is submitted & cancelled then disable all input box & buttons // if form is submitted & cancelled then disable all input box & buttons
if (cur_frm.doc.docstatus>=1 && cint(cur_frm.doc.is_pos)) { if (this.frm.doc.docstatus>=1) {
me.wrapper.find('input, button').each(function () { me.wrapper.find('input, button').each(function () {
$(this).prop('disabled', true); $(this).prop('disabled', true);
}); });
$(".delete-items").hide(); $(".delete-items").hide();
$(".make-payment").hide(); $(".make-payment").hide();
} }
// Show Make Payment button only in Sales Invoice
if (this.frm.doctype != "Sales Invoice")
$(".make-payment").hide();
// If quotation to is not Customer then remove party
if (this.frm.doctype == "Quotation") {
this.party_field.$wrapper.remove();
if (this.frm.doc.quotation_to == "Customer")
this.make_party();
}
}, },
refresh_delete_btn: function() { refresh_delete_btn: function() {
$(".delete-items").toggle($(".item-cart .warning").length ? true : false); $(".delete-items").toggle($(".item-cart .warning").length ? true : false);
@ -370,32 +417,32 @@ erpnext.POS = Class.extend({
remove_selected_item: function() { remove_selected_item: function() {
var me = this; var me = this;
var selected_items = []; 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++) { 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") { if(row.attr("data-selected") == "true") {
selected_items.push(row.attr("id")); selected_items.push(row.attr("id"));
} }
} }
var child = wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries", var child = wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
"Sales Invoice"); this.frm.cscript.fname, this.frm.doctype);
$.each(child, function(i, d) { $.each(child, function(i, d) {
for (var i in selected_items) { for (var i in selected_items) {
if (d.item_code == selected_items[i]) { 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); wn.model.clear_doc(d.doctype, d.name);
} }
} }
}); });
cur_frm.fields_dict["entries"].grid.refresh(); this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
cur_frm.script_manager.trigger("calculate_taxes_and_totals"); this.frm.script_manager.trigger("calculate_taxes_and_totals");
me.frm.dirty(); me.frm.dirty();
me.refresh(); me.refresh();
}, },
make_payment: function() { make_payment: function() {
var me = this; 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 = []; var mode_of_payment = [];
if (no_of_items == 0) if (no_of_items == 0)
@ -423,15 +470,15 @@ erpnext.POS = Class.extend({
"total_amount": $(".grand-total").text() "total_amount": $(".grand-total").text()
}); });
dialog.show(); dialog.show();
cur_frm.pos.barcode.$input.focus(); me.frm.pos.barcode.$input.focus();
dialog.get_input("total_amount").prop("disabled", true); dialog.get_input("total_amount").prop("disabled", true);
dialog.fields_dict.pay.input.onclick = function() { dialog.fields_dict.pay.input.onclick = function() {
cur_frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment); me.frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
cur_frm.set_value("paid_amount", dialog.get_values().total_amount); me.frm.set_value("paid_amount", dialog.get_values().total_amount);
cur_frm.cscript.mode_of_payment(cur_frm.doc); me.frm.cscript.mode_of_payment(me.frm.doc);
cur_frm.save(); me.frm.save();
dialog.hide(); dialog.hide();
me.refresh(); me.refresh();
}; };

View File

@ -3,17 +3,21 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import msgprint
@webnotes.whitelist() @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 = "" 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": 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: 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, return webnotes.conn.sql("""select i.name, i.item_name, i.image,
pl_items.ref_rate, pl_items.currency pl_items.ref_rate, pl_items.currency
@ -24,13 +28,18 @@ def get_items(price_list, item=None, item_group=None):
ON ON
pl_items.item_code=i.name pl_items.item_code=i.name
where where
i.is_sales_item='Yes'%s""" % ('%s', condition), (price_list), as_dict=1) %s""" % ('%s', condition), (price_list), as_dict=1)
@webnotes.whitelist() @webnotes.whitelist()
def get_item_from_barcode(barcode): def get_item_from_barcode(barcode):
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""", return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
(barcode), as_dict=1) (barcode), as_dict=1)
@webnotes.whitelist()
def get_item_from_serial_no(serial_no):
return webnotes.conn.sql("""select name, item_code from `tabSerial No` where
name=%s""", (serial_no), as_dict=1)
@webnotes.whitelist() @webnotes.whitelist()
def get_mode_of_payment(): def get_mode_of_payment():
return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1) return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1)

View File

@ -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);
}

View File

@ -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); 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.sales_order_btn();
cur_frm.cscript.delivery_note_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() { 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() { tc_name: function() {
this.get_terms(); this.get_terms();
@ -179,7 +128,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
is_pos: function() { is_pos: function() {
cur_frm.cscript.hide_fields(this.frm.doc); cur_frm.cscript.hide_fields(this.frm.doc);
if(cint(this.frm.doc.is_pos)) { if(cint(this.frm.doc.is_pos)) {
if(!this.frm.doc.company) { if(!this.frm.doc.company) {
this.frm.set_value("is_pos", 0); this.frm.set_value("is_pos", 0);
@ -197,6 +145,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}); });
} }
} }
}, },
debit_to: function() { debit_to: function() {

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-05-24 19:29:05", "creation": "2013-05-24 19:29:05",
"docstatus": 0, "docstatus": 0,
"modified": "2013-09-01 05:26:13", "modified": "2013-09-19 11:42:13",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -180,6 +180,7 @@
"search_index": 1 "search_index": 1
}, },
{ {
"default": "Today",
"description": "Enter the date by which payments from customer is expected against this invoice.", "description": "Enter the date by which payments from customer is expected against this invoice.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "due_date", "fieldname": "due_date",
@ -411,7 +412,7 @@
"doctype": "DocField", "doctype": "DocField",
"fieldname": "other_charges", "fieldname": "other_charges",
"fieldtype": "Table", "fieldtype": "Table",
"label": "Taxes and Charges1", "label": "Sales Taxes and Charges",
"oldfieldname": "other_charges", "oldfieldname": "other_charges",
"oldfieldtype": "Table", "oldfieldtype": "Table",
"options": "Sales Taxes and Charges", "options": "Sales Taxes and Charges",

View File

@ -108,8 +108,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
var item = wn.model.get_doc(cdt, cdn); var item = wn.model.get_doc(cdt, cdn);
if(item.item_code) { if(item.item_code) {
if(!this.validate_company_and_party("supplier")) { if(!this.validate_company_and_party("supplier")) {
item.item_code = null; cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
refresh_field("item_code", item.name, item.parentfield);
} else { } else {
return this.frm.call({ return this.frm.call({
method: "buying.utils.get_item_details", method: "buying.utils.get_item_details",

View File

@ -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/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/utilities/doctype/sms_control/sms_control.js');
wn.require('app/buying/doctype/purchase_common/purchase_common.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({ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
refresh: function(doc, cdt, cdn) { refresh: function(doc, cdt, cdn) {

View File

@ -9,6 +9,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
// attach required files // attach required files
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js'); 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/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({ erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
refresh: function() { refresh: function() {

View File

@ -65,7 +65,7 @@ def _get_basic_details(args, item_bean):
out = webnotes._dict({ out = webnotes._dict({
"description": item.description_html or item.description, "description": item.description_html or item.description,
"qty": 0.0, "qty": 1.0,
"uom": item.stock_uom, "uom": item.stock_uom,
"conversion_factor": 1.0, "conversion_factor": 1.0,
"warehouse": args.warehouse or item.default_warehouse, "warehouse": args.warehouse or item.default_warehouse,

View File

@ -29,4 +29,21 @@ span, div, td, input, textarea, button, select {
width: 32px; width: 32px;
height: 32px; height: 32px;
margin: -10px auto; 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);
} }

View File

@ -62,6 +62,56 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
erpnext.hide_company(); erpnext.hide_company();
this.show_item_wise_taxes(); this.show_item_wise_taxes();
this.set_dynamic_labels(); 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() { validate: function() {
@ -182,6 +232,29 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
tax_rate: function(doc, cdt, cdn) { tax_rate: function(doc, cdt, cdn) {
this.calculate_taxes_and_totals(); this.calculate_taxes_and_totals();
}, },
// serial_no: function(doc, cdt, cdn) {
// var me = this;
// var item = wn.model.get_doc(cdt, cdn);
// if (!item.item_code) {
// wn.call({
// method: 'accounts.doctype.sales_invoice.pos.get_item_from_serial_no',
// args: {serial_no: this.serial_no.$input.val()},
// callback: function(r) {
// if (r.message) {
// var item_code = r.message[0].item_code;
// 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);
// }
// else
// msgprint(wn._("Invalid Serial No."));
// me.refresh();
// }
// });
// }
// },
row_id: function(doc, cdt, cdn) { row_id: function(doc, cdt, cdn) {
var tax = wn.model.get_doc(cdt, cdn); var tax = wn.model.get_doc(cdt, cdn);
@ -418,10 +491,10 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
(this.frm.doc.currency != company_currency && this.frm.doc.conversion_rate != 1.0)) : (this.frm.doc.currency != company_currency && this.frm.doc.conversion_rate != 1.0)) :
false; false;
// if(!valid_conversion_rate) { if(!valid_conversion_rate) {
// wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) + wn.throw(wn._("Please enter valid") + " " + wn._(conversion_rate_label) +
// " 1 " + this.frm.doc.currency + " = [?] " + company_currency); " 1 " + this.frm.doc.currency + " = [?] " + company_currency);
// } }
}, },
calculate_taxes_and_totals: function() { calculate_taxes_and_totals: function() {

View File

@ -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/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/utilities/doctype/sms_control/sms_control.js');
wn.require('app/selling/doctype/sales_common/sales_common.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({ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
onload: function(doc, dt, dn) { onload: function(doc, dt, dn) {
@ -82,12 +83,12 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
}, },
validate_company_and_party: function(party_field) { validate_company_and_party: function(party_field) {
if(this.frm.doc.quotation_to == "Lead") { if(!this.frm.doc.quotation_to) {
return true;
} else if(!this.frm.doc.quotation_to) {
msgprint(wn._("Please select a value for" + " " + wn.meta.get_label(this.frm.doc.doctype, msgprint(wn._("Please select a value for" + " " + wn.meta.get_label(this.frm.doc.doctype,
"quotation_to", this.frm.doc.name))); "quotation_to", this.frm.doc.name)));
return false; return false;
} else if (this.frm.doc.quotation_to == "Lead") {
return true;
} else { } else {
return this._super(party_field); return this._super(party_field);
} }

View File

@ -162,8 +162,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
var item = wn.model.get_doc(cdt, cdn); var item = wn.model.get_doc(cdt, cdn);
if(item.item_code || item.barcode) { if(item.item_code || item.barcode) {
if(!this.validate_company_and_party("customer")) { if(!this.validate_company_and_party("customer")) {
item.item_code = null; cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
refresh_field("item_code", item.name, item.parentfield);
} else { } else {
return this.frm.call({ return this.frm.call({
method: "selling.utils.get_item_details", method: "selling.utils.get_item_details",

View File

@ -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/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/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/utilities/doctype/sms_control/sms_control.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
refresh: function(doc, dt, dn) { refresh: function(doc, dt, dn) {

View File

@ -34,6 +34,7 @@ def get_item_details(args):
"plc_conversion_rate": 1.0 "plc_conversion_rate": 1.0
} }
""" """
if isinstance(args, basestring): if isinstance(args, basestring):
args = json.loads(args) args = json.loads(args)
args = webnotes._dict(args) args = webnotes._dict(args)

View File

@ -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/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/utilities/doctype/sms_control/sms_control.js');
wn.require('app/selling/doctype/sales_common/sales_common.js'); wn.require('app/selling/doctype/sales_common/sales_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
wn.provide("erpnext.stock"); wn.provide("erpnext.stock");
erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend({

View File

@ -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/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/utilities/doctype/sms_control/sms_control.js');
wn.require('app/buying/doctype/purchase_common/purchase_common.js'); wn.require('app/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
wn.provide("erpnext.stock"); wn.provide("erpnext.stock");
erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend({

View File

@ -426,6 +426,7 @@ def get_address_territory(address_doc):
def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company): def validate_conversion_rate(currency, conversion_rate, conversion_rate_label, company):
"""common validation for currency and price list currency""" """common validation for currency and price list currency"""
if conversion_rate == 0: if conversion_rate == 0:
msgprint(conversion_rate_label + _(' cannot be 0'), raise_exception=True) msgprint(conversion_rate_label + _(' cannot be 0'), raise_exception=True)