Merge pull request #5788 from rohitwaghchaure/clean_timesheet
billable field access from grid and create timesheet without employee
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index c6191da..f986eea 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -114,12 +114,28 @@
item.cost_center = pos_profile.get('cost_center') or item_doc.selling_cost_center
item.actual_qty = frappe.db.get_value('Bin', {'item_code': item.name,
'warehouse': item.default_warehouse}, 'actual_qty') or 0
- item.serial_nos = frappe.db.sql_list("""select name from `tabSerial No` where warehouse= %(warehouse)s
- and item_code = %(item_code)s""", {'warehouse': item.default_warehouse, 'item_code': item.item_code})
+ item.serial_nos = get_serial_nos(item, pos_profile)
+ item.batch_nos = frappe.db.sql_list("""select name from `tabBatch` where expiry_date > curdate()
+ and item = %(item_code)s""", {'item_code': item.item_code})
+
item_list.append(item)
return item_list
+def get_serial_nos(item, pos_profile):
+ cond = "1=1"
+ if pos_profile.get('update_stock') and pos_profile.get('warehouse'):
+ cond = "warehouse = '{0}'".format(pos_profile.get('warehouse'))
+
+ serial_nos = frappe.db.sql("""select name, warehouse from `tabSerial No` where {0}
+ and item_code = %(item_code)s""".format(cond), {'item_code': item.item_code}, as_dict=1)
+
+ serial_no_list = {}
+ for serial_no in serial_nos:
+ serial_no_list[serial_no.name] = serial_no.warehouse
+
+ return serial_no_list
+
def get_customers(pos_profile, doc):
filters = {'disabled': 0}
customer_list = []
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index 351cd56..28964bb 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -12,8 +12,9 @@
valdiate_taxes_and_charges_template(self)
def valdiate_taxes_and_charges_template(doc):
- if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
- doc.is_default = 1
+ # default should not be disabled
+ # if not doc.is_default and not frappe.get_all(doc.doctype, filters={"is_default": 1}):
+ # doc.is_default = 1
if doc.is_default == 1:
frappe.db.sql("""update `tab{0}` set is_default = 0
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 9211657..bc07aca 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -400,7 +400,8 @@
// To search item as per the key enter
var me = this;
- this.item_serial_no = {}
+ this.item_serial_no = {};
+ this.item_batch_no = {};
if(item_code){
return $.grep(window.items, function(item){
@@ -417,11 +418,13 @@
if( (item.item_code.toLowerCase().match(key)) ||
(item.item_name.toLowerCase().match(key)) || (item.item_group.toLowerCase().match(key)) ){
return true
- }else if(item.barcode){
- return item.barcode == me.search.$input.val()
- } else if (in_list(item.serial_nos, me.search.$input.val())){
- me.item_serial_no[item.item_code] = me.search.$input.val()
+ }else if(item.barcode == me.search.$input.val()){
+ return item.barcode == me.search.$input.val();
+ } else if (in_list(Object.keys(item.serial_nos), me.search.$input.val())){
+ me.item_serial_no[item.item_code] = [me.search.$input.val(), item.serial_nos[me.search.$input.val()]]
return true
+ } else if(in_list(item.batch_nos, me.search.$input.val())){
+ return me.item_batch_no[item.item_code] = me.search.$input.val()
}
})
}else{
@@ -467,6 +470,13 @@
this.remove_item = []
$.each(this.frm.doc["items"] || [], function(i, d) {
+ if (d.item_code == item_code && d.serial_no
+ && field == 'qty' && cint(value) != value) {
+ d.qty = 0.0;
+ me.refresh();
+ frappe.throw(__("Serial no item cannot be a fraction"))
+ }
+
if (d.item_code == item_code) {
d[field] = flt(value);
d.amount = flt(d.rate) * flt(d.qty);
@@ -536,7 +546,9 @@
var caught = false;
var no_of_items = me.wrapper.find(".pos-bill-item").length;
- this.validate_serial_no()
+ this.customer_validate();
+ this.mandatory_batch_no();
+ this.validate_serial_no();
this.validate_warehouse();
if (no_of_items != 0) {
@@ -544,9 +556,14 @@
if (d.item_code == me.items[0].item_code) {
caught = true;
d.qty += 1;
- d.amount = flt(d.rate) * flt(d.qty)
- if(me.item_serial_no.length){
- d.serial_no += '\n' + me.item_serial_no[d.item_code]
+ d.amount = flt(d.rate) * flt(d.qty);
+ if(me.item_serial_no[d.item_code]){
+ d.serial_no += '\n' + me.item_serial_no[d.item_code][0]
+ d.warehouse = me.item_serial_no[d.item_code][1]
+ }
+
+ if(me.item_batch_no.length){
+ d.batch_no = me.item_batch_no[d.item_code]
}
}
});
@@ -570,12 +587,15 @@
this.child.item_group = this.items[0].item_group;
this.child.cost_center = this.items[0].cost_center;
this.child.income_account = this.items[0].income_account;
- this.child.warehouse = this.items[0].default_warehouse;
+ this.child.warehouse = (this.item_serial_no[this.child.item_code]
+ ? this.item_serial_no[this.child.item_code][1] : this.items[0].default_warehouse);
this.child.price_list_rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
this.child.rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
this.child.actual_qty = this.items[0].actual_qty;
this.child.amount = flt(this.child.qty) * flt(this.child.rate);
- this.child.serial_no = this.item_serial_no[this.child.item_code];
+ this.child.batch_no = this.item_batch_no[this.child.item_code];
+ this.child.serial_no = (this.item_serial_no[this.child.item_code]
+ ? this.item_serial_no[this.child.item_code][0] : '');
},
refresh: function() {
@@ -759,7 +779,7 @@
$(this.wrapper).find('input').attr("disabled", false);
if(this.frm.doc.docstatus == 1){
- pointer_events = 'none'
+ pointer_events = 'none';
$(this.wrapper).find('input').attr("disabled", true);
}
@@ -789,7 +809,7 @@
$.each(this.si_docs, function(index, data){
for(key in data){
if(key == me.name){
- me.si_docs[index][key] = me.frm.doc
+ me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
}
}
@@ -821,7 +841,7 @@
sync_sales_invoice: function(){
var me = this;
- this.si_docs = this.get_submitted_invoice()
+ this.si_docs = this.get_submitted_invoice();
if(this.si_docs.length){
frappe.call({
@@ -860,12 +880,12 @@
remove_doc_from_localstorage: function(){
var me = this;
this.si_docs = this.get_doc_from_localstorage();
- this.new_si_docs = []
+ this.new_si_docs = [];
if(this.removed_items){
$.each(this.si_docs, function(index, data){
for(key in data){
if(!in_list(me.removed_items, key)){
- me.new_si_docs.push(data)
+ me.new_si_docs.push(data);
}
}
})
@@ -878,7 +898,7 @@
var me = this;
this.customer_validate();
this.item_validate();
- this.validate_mode_of_payments()
+ this.validate_mode_of_payments();
},
item_validate: function(){
@@ -898,7 +918,7 @@
var item_code = serial_no = '';
for (key in this.item_serial_no){
item_code = key;
- serial_no = me.item_serial_no[key]
+ serial_no = me.item_serial_no[key][0];
}
if(item_code && serial_no){
@@ -912,6 +932,21 @@
}
})
}
+
+ if(this.items[0].has_serial_no && serial_no == ""){
+ frappe.throw(__(repl("Error: Serial no is mandatory for item %(item)s", {
+ 'item': this.items[0].item_code
+ })))
+ }
+ },
+
+ mandatory_batch_no: function(){
+ var me = this;
+ if(this.items[0].has_batch_no && !this.item_batch_no[this.items[0].item_code]){
+ frappe.throw(__(repl("Error: Batch no is mandatory for item %(item)s", {
+ 'item': this.items[0].item_code
+ })))
+ }
},
apply_pricing_rule: function(){