diff --git a/erpnext/accounts/search_criteria/itemwise_sales_register/itemwise_sales_register.js b/erpnext/accounts/search_criteria/itemwise_sales_register/itemwise_sales_register.js index 2fb121328fa..b6e3dab255e 100755 --- a/erpnext/accounts/search_criteria/itemwise_sales_register/itemwise_sales_register.js +++ b/erpnext/accounts/search_criteria/itemwise_sales_register/itemwise_sales_register.js @@ -16,9 +16,9 @@ report.customize_filters = function() { this.hide_all_filters(); - filter_list = ['From Voucher Date', 'To Voucher Date', 'Debit To', 'From Posting Date', 'To Posting Date'] - for(var i=0;i 0 and (opening_qty + actual_qty) > 0 and is_cancelled == 'No' and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0: + if actual_qty > 0 and (opening_qty + actual_qty) > 0 and is_cancelled == 'No' and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0: + opening_qty = opening_qty > 0 and opening_qty or 0 val_rate = ((opening_qty *val_rate) + (actual_qty * in_rate)) / (opening_qty + actual_qty) + elif (opening_qty + actual_qty) <= 0: + val_rate = 0 stock_val = val_rate return val_rate, stock_val @@ -245,8 +247,10 @@ class DocType: # get stock value # ---------------- def get_stock_value(self, val_method, cqty, stock_val, serial_nos): - if val_method == 'Moving Average' or serial_nos: + if serial_nos: stock_val = flt(stock_val) * flt(cqty) + elif val_method == 'Moving Average': + stock_val = flt(cqty) > 0 and flt(stock_val) * flt(cqty) or 0 elif val_method == 'FIFO': stock_val = sum([flt(d[0])*flt(d[1]) for d in self.fcfs_bal]) return stock_val @@ -274,6 +278,11 @@ class DocType: # get valuation method val_method = get_obj('Valuation Control').get_valuation_method(self.doc.item_code) + # allow negative stock (only for moving average method) + from webnotes.utils import get_defaults + allow_negative_stock = get_defaults().get('allow_negative_stock', 0) + + # recalculate the balances for all stock ledger entries # after the prev sle sll = sql(""" @@ -286,10 +295,10 @@ class DocType: order by timestamp(posting_date, posting_time) asc, name asc""", \ (self.doc.item_code, self.doc.warehouse, \ prev_sle.get('posting_date','1900-01-01'), prev_sle.get('posting_time', '12:00')), as_dict = 1) - for sle in sll: # block if stock level goes negative on any date - self.validate_negative_stock(cqty, sle) + if val_method != 'Moving Average' or flt(allow_negative_stock) == 0: + self.validate_negative_stock(cqty, sle) stock_val, in_rate = 0, sle['incoming_rate'] # IN serial_nos = sle["serial_no"] and ("'"+"', '".join(cstr(sle["serial_no"]).split('\n')) \ diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index ffa656231f5..51c123c9365 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -322,7 +322,6 @@ class DocType(TransactionBase): def on_submit(self): self.validate_packed_qty() set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name)) - self.check_qty_in_stock() # Check for Approving Authority get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self) sl_obj = get_obj("Stock Ledger") @@ -361,14 +360,6 @@ class DocType(TransactionBase): webnotes.msgprint("Packing Error:\n" + err_msg, raise_exception=1) - # *********** Checks whether actual quantity is present in warehouse ************* - def check_qty_in_stock(self): - for d in getlist(self.doclist, 'packing_details'): - is_stock_item = sql("select is_stock_item from `tabItem` where name = '%s'" % d.item_code)[0][0] - if is_stock_item == 'Yes' and d.warehouse and flt(d.qty) > flt(d.actual_qty): - msgprint("For Item: " + cstr(d.item_code) + " at Warehouse: " + cstr(d.warehouse) + " Quantity: " + cstr(d.qty) +" is not Available. (Must be less than or equal to " + cstr(d.actual_qty) + " )") - raise Exception, "Validation Error" - # ON CANCEL diff --git a/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py b/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py index fbeb4a51f4e..fcf909ca90e 100644 --- a/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py +++ b/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py @@ -42,9 +42,9 @@ class DocType : def pull_item_details(self): if self.doc.return_type == 'Sales Return': if self.doc.delivery_note_no: - det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.uom, t2.basic_rate, t3.customer, t3.customer_name, t3.customer_address, t2.serial_no, t2.batch_no from `tabDelivery Note Packing Item` t1, `tabDelivery Note Item` t2, `tabDelivery Note` t3 where t1.parent = t3.name and t2.parent = t3.name and t1.parent_detail_docname = t2.name and t3.name = '%s' and t3.docstatus = 1" % self.doc.delivery_note_no) + det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.uom, t2.export_rate * t3.conversion_rate, t3.customer, t3.customer_name, t3.customer_address, t2.serial_no, t2.batch_no from `tabDelivery Note Packing Detail` t1, `tabDelivery Note Detail` t2, `tabDelivery Note` t3 where t1.parent = t3.name and t2.parent = t3.name and t1.parent_detail_docname = t2.name and t3.name = '%s' and t3.docstatus = 1" % self.doc.delivery_note_no) elif self.doc.sales_invoice_no: - det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.stock_uom, t1.basic_rate, t2.customer, t2.customer_name, t2.customer_address, t1.serial_no from `tabSales Invoice Item` t1, `tabSales Invoice` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.sales_invoice_no) + det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.stock_uom, t1.export_rate * t2.conversion_rate, t2.customer, t2.customer_name, t2.customer_address, t1.serial_no from `tabRV Detail` t1, `tabReceivable Voucher` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.sales_invoice_no) elif self.doc.return_type == 'Purchase Return' and self.doc.purchase_receipt_no: det = sql("select t1.name, t1.item_code, t1.description, t1.received_qty, t1.uom, t1.purchase_rate, t2.supplier, t2.supplier_name, t2.supplier_address, t1.serial_no, t1.batch_no from `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.purchase_receipt_no) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 34ec9eb9fd8..dee8790adc8 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -265,9 +265,6 @@ class DocType(TransactionBase): if flt(d.transfer_qty) <= 0: msgprint("Transfer Quantity can not be less than or equal to zero at Row No " + cstr(d.idx)) raise Exception - if d.s_warehouse and flt(d.transfer_qty) > flt(d.actual_qty): - msgprint("Transfer Quantity is more than Available Qty at Row No " + cstr(d.idx)) - raise Exception def calc_amount(self): diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt index d5ea870b433..275cf303d46 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt @@ -418,4 +418,4 @@ 'search_index': 0, 'width': u'100px' } -] \ No newline at end of file +]