diff --git a/erpnext/accounts/doctype/gl_control/gl_control.py b/erpnext/accounts/doctype/gl_control/gl_control.py index 84fea75a90..2edd2dc2d3 100644 --- a/erpnext/accounts/doctype/gl_control/gl_control.py +++ b/erpnext/accounts/doctype/gl_control/gl_control.py @@ -198,10 +198,17 @@ class DocType: # ---------------- def save_entries(self, cancel, adv_adj, update_outstanding): for le in self.entries: - # cancel - if cancel or flt(le.debit) < 0 or flt(le.credit) < 0: + #toggle debit, credit if negative entry + if flt(le.debit) < 0 or flt(le.credit) < 0: tmp=le.debit le.debit, le.credit = abs(flt(le.credit)), abs(flt(tmp)) + + # toggled debit/credit in two separate condition because both should be executed at the + # time of cancellation when there is negative amount (tax discount) + if cancel: + tmp=le.debit + le.debit, le.credit = abs(flt(le.credit)), abs(flt(tmp)) + le_obj = get_obj(doc=le) # validate except on_cancel diff --git a/erpnext/accounts/doctype/multi_ledger_report/multi_ledger_report.py b/erpnext/accounts/doctype/multi_ledger_report/multi_ledger_report.py index 88a31f2226..79ccfa9d2d 100755 --- a/erpnext/accounts/doctype/multi_ledger_report/multi_ledger_report.py +++ b/erpnext/accounts/doctype/multi_ledger_report/multi_ledger_report.py @@ -49,14 +49,14 @@ class DocType: def add_header(self): title = 'Ledger Balances Between ' + getdate(self.doc.from_date).strftime('%d-%m-%Y') + ' and ' + getdate(self.doc.to_date).strftime('%d-%m-%Y') - return [[title], ['Account', 'Opening(Dr)', 'Opening (Cr)', 'Debit', 'Credit', 'Closing(Dr)', 'Closing(Cr)'], ['', '', '', '', '', '', '', 'Posting Date', 'Voucher Type', 'Voucher No', 'Debit', 'Credit', 'Remarks']] + return [[title], ['Account', 'Posting Date', 'Voucher Type', 'Voucher No', 'Debit', 'Credit', 'Remarks']] def get_account_subtree(self, acc): return sql(""" SELECT - CONCAT(REPEAT(' ', COUNT(parent.name) - (sub_tree.depth + 1)), node.name) as account, + CONCAT(REPEAT(' ', COUNT(parent.name) - (sub_tree.depth + 1)), node.name) as account, node.lft AS lft, node.rgt AS rgt, node.debit_or_credit as dr_or_cr, node.group_or_ledger as group_or_ledger, node.is_pl_account as is_pl_account FROM tabAccount AS node, @@ -78,7 +78,7 @@ class DocType: - def show_acc_summary(self, glc, acc_det): + def get_acc_summary(self, glc, acc_det): from_date_year = self.get_year(add_days(self.doc.from_date, -1)) to_date_year = self.get_year(self.doc.to_date) acc = acc_det['account'].strip() @@ -104,8 +104,8 @@ class DocType: if acc_det['dr_or_cr'] == 'Credit': opening, closing = -1*opening, -1*closing - return [acc_det['account'], flt(opening>0 and opening or 0), flt(opening<0 and -opening or 0), - debit, credit, flt(closing>0.01 and closing or 0), flt(closing<-0.01 and -closing or 0)] + return flt(opening>0 and opening or 0), flt(opening<0 and -opening or 0), \ + debit, credit, flt(closing>0.01 and closing or 0), flt(closing<-0.01 and -closing or 0) def show_gl_entries(self, acc): @@ -113,7 +113,7 @@ class DocType: gle = sql("select posting_date, voucher_type, voucher_no, debit, credit, remarks from `tabGL Entry` WHERE account = %s and posting_date >= %s AND posting_date <= %s and ifnull(is_opening, 'No') = 'No' and ifnull(is_cancelled, 'No') = 'No'", (acc, self.doc.from_date, self.doc.to_date), as_dict=1) entries, dr, cr = [], 0, 0 for d in gle: - entries.append(['', '', '', '', '', '', '', d['posting_date'], d['voucher_type'], d['voucher_no'], d['debit'], d['credit'], d['remarks']]) + entries.append(['', d['posting_date'], d['voucher_type'], d['voucher_no'], d['debit'], d['credit'], d['remarks']]) return entries @@ -133,13 +133,17 @@ class DocType: sub_tree = self.get_account_subtree(d.account) for acc_det in sub_tree: - acc_summary = self.show_acc_summary(glc, acc_det) - res.append(acc_summary) - - # Show gl entries if account is ledger - if acc_det['group_or_ledger'] == 'Ledger' and (acc_summary[3] or acc_summary[4]): - gle = self.show_gl_entries(acc_det['account'].strip()) - res += gle - + acc_summary = self.get_acc_summary(glc, acc_det) + if acc_summary[0] or acc_summary[1] or acc_summary[2] or acc_summary[3] or acc_summary[4] or acc_summary[5]: + res.append([acc_det['account']]) + # Show gl entries if account is ledger + if acc_det['group_or_ledger'] == 'Ledger' and (acc_summary[2] or acc_summary[3]): + gle = self.show_gl_entries(acc_det['account'].strip()) + res += gle + + # Totals + res.append(['', '', '', 'Total Debit/Credit', acc_summary[2], acc_summary[3]]) + res.append(['', '', '', 'Opening Balance', acc_summary[0], acc_summary[1]]) + res.append(['', '', '', 'Closing Balance', acc_summary[4], acc_summary[5]]) return res diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 33dc481776..096fec8310 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -60,22 +60,10 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) { if (!cur_frm.cscript.is_onload) cur_frm.cscript.dynamic_label(doc, cdt, cdn); if(doc.docstatus == 1 && doc.status != 'Stopped'){ - var ch = getchildren('Purchase Order Item',doc.name,'po_details'); - var allow_billing = 0; var allow_receipt = 0; - cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); - - for(var i in ch){ - if(ch[i].qty > ch[i].received_qty) allow_receipt = 1; - if(ch[i].qty > ch[i].billed_qty) allow_billing = 1; - } - if(allow_receipt) - cur_frm.add_custom_button('Make Purchase Receipt', cur_frm.cscript['Make Purchase Receipt']); - - if(allow_billing) - cur_frm.add_custom_button('Make Invoice', cur_frm.cscript['Make Purchase Invoice']); - - if(allow_billing || allow_receipt) - cur_frm.add_custom_button('Stop', cur_frm.cscript['Stop Purchase Order']); + cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']); + if(doc.per_received < 100) cur_frm.add_custom_button('Make Purchase Receipt', cur_frm.cscript['Make Purchase Receipt']); + if(doc.per_billed < 100) cur_frm.add_custom_button('Make Invoice', cur_frm.cscript['Make Purchase Invoice']); + if(doc.per_billed < 100 || doc.per_received < 100) cur_frm.add_custom_button('Stop', cur_frm.cscript['Stop Purchase Order']); } if(doc.docstatus == 1 && doc.status == 'Stopped') diff --git a/erpnext/buying/doctype/purchase_request/purchase_request.js b/erpnext/buying/doctype/purchase_request/purchase_request.js index d20d50aeea..8e6654376a 100644 --- a/erpnext/buying/doctype/purchase_request/purchase_request.js +++ b/erpnext/buying/doctype/purchase_request/purchase_request.js @@ -46,19 +46,10 @@ cur_frm.cscript.get_item_defaults = function(doc) { //======================= Refresh ===================================== cur_frm.cscript.refresh = function(doc, cdt, cdn) { - - // Unhide Fields in Next Steps - // --------------------------------- - cur_frm.clear_custom_buttons(); if(doc.docstatus == 1 && doc.status != 'Stopped'){ - var ch = getchildren('Purchase Request Item',doc.name,'indent_details'); - var is_closed = 1; - for(var i in ch){ - if(flt(ch[i].qty) > flt(ch[i].ordered_qty)) is_closed = 0; - } - if(!is_closed) { + if(doc.per_ordered < 100) { cur_frm.add_custom_button('Make Purchase Order', cur_frm.cscript['Make Purchase Order']) cur_frm.add_custom_button('Stop Purchase Request', cur_frm.cscript['Stop Purchase Request']) } diff --git a/erpnext/patches/april_2012/after_sync_cleanup.py b/erpnext/patches/april_2012/after_sync_cleanup.py index ab9e70e2ff..33840a00e8 100644 --- a/erpnext/patches/april_2012/after_sync_cleanup.py +++ b/erpnext/patches/april_2012/after_sync_cleanup.py @@ -1,5 +1,5 @@ def execute(): import webnotes from webnotes.model import delete_doc - + webnotes.conn.sql("update `tabDocType` set module = 'Utilities' where name in ('Question', 'Answer')") delete_doc('Module Def', 'Knowledge Base') diff --git a/erpnext/patches/april_2012/change_cacheitem_schema.py b/erpnext/patches/april_2012/change_cacheitem_schema.py index ab127e3396..dc3c253689 100644 --- a/erpnext/patches/april_2012/change_cacheitem_schema.py +++ b/erpnext/patches/april_2012/change_cacheitem_schema.py @@ -1,3 +1,5 @@ def execute(): import webnotes + webnotes.conn.commit() webnotes.conn.sql("alter table __CacheItem modify `value` longtext") + webnotes.conn.begin() diff --git a/erpnext/patches/april_2012/remove_default_from_rv_detail.py b/erpnext/patches/april_2012/remove_default_from_rv_detail.py new file mode 100644 index 0000000000..cf81f6d2a7 --- /dev/null +++ b/erpnext/patches/april_2012/remove_default_from_rv_detail.py @@ -0,0 +1,3 @@ +def execute(): + import webnotes + webnotes.conn.sql("update `tabDocField` set `default` = '' where fieldname = 'cost_center' and parent = 'RV Detail' and `default` = 'Purchase - TC'") diff --git a/erpnext/patches/april_2012/serial_no_fixes.py b/erpnext/patches/april_2012/serial_no_fixes.py new file mode 100644 index 0000000000..b4fcf759bd --- /dev/null +++ b/erpnext/patches/april_2012/serial_no_fixes.py @@ -0,0 +1,6 @@ +def execute(): + import webnotes + from webnotes.modules.module_manager import reload_doc + reload_doc('stock', 'doctype', 'serial_no') + + webnotes.conn.sql("update `tabSerial No` set sle_exists = 1") diff --git a/erpnext/patches/april_2012/update_appraisal_permission.py b/erpnext/patches/april_2012/update_appraisal_permission.py new file mode 100644 index 0000000000..bd4578f5e4 --- /dev/null +++ b/erpnext/patches/april_2012/update_appraisal_permission.py @@ -0,0 +1,14 @@ +def execute(): + import webnotes + from webnotes.model.doc import addchild + from webnotes.model.code import get_obj + + webnotes.conn.sql("delete from `tabDocPerm` where role = 'All' and permlevel = 0 and parent in ('Appraisal', 'Ticket', 'Project')") + + appr = get_obj('DocType', 'Appraisal', with_children=1) + ch = addchild(appr.doc, 'permissions', 'DocPerm', 0) + ch.permlevel = 0 + ch.role = 'Employee' + ch.read = 1 + ch.write = 1 + ch.save() diff --git a/erpnext/patches/april_2012/update_permlevel_in_address.py b/erpnext/patches/april_2012/update_permlevel_in_address.py new file mode 100644 index 0000000000..f8deb2c4c3 --- /dev/null +++ b/erpnext/patches/april_2012/update_permlevel_in_address.py @@ -0,0 +1,3 @@ +def execute(): + import webnotes + webnotes.conn.sql("update `tabDocPerm` set permlevel = 0 where parent = 'Address'") diff --git a/erpnext/patches/april_2012/update_role_in_address.py b/erpnext/patches/april_2012/update_role_in_address.py new file mode 100644 index 0000000000..6917da422b --- /dev/null +++ b/erpnext/patches/april_2012/update_role_in_address.py @@ -0,0 +1,21 @@ +def execute(): + import webnotes + from webnotes.model.doc import addchild + from webnotes.model.code import get_obj + + webnotes.conn.sql("delete from `tabDocPerm` where role = 'All' and parent = 'Address'") + + role1 = ['Sales User', 'Purchase User', 'Accounts User', 'Maintenance User'] + role2 = ['Sales Manager', 'Sales Master Manager', 'Purchase Manager', 'Purchase Master Manager', 'Accounts Manager', 'Maintenance Manager'] + + addr = get_obj('DocType', 'Address', with_children=1) + for d in role1+role2: + ch = addchild(addr.doc, 'permissions', 'DocPerm', 0) + ch.role = d + ch.read = 1 + ch.write = 1 + ch.create = 1 + if d in role2: + ch.cancel = 1 + + ch.save() diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 7d8a0951bb..e0f9ea33a7 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -282,4 +282,30 @@ patch_list = [ 'patch_file': 'change_cacheitem_schema', 'description': 'Modified datatype of `value` column from text to longtext' }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'remove_default_from_rv_detail', + 'description': '' + }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'update_role_in_address', + 'description': 'updated roles in address' + }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'update_permlevel_in_address', + 'description': 'updated permlevel in address' + }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'update_appraisal_permission', + 'description': 'updated permission in appraisal' + }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'serial_no_fixes', + 'description': 'fixes for sle creation while import' + }, + ] diff --git a/erpnext/setup/doctype/notification_control/notification_control.js b/erpnext/setup/doctype/notification_control/notification_control.js index 32919b6f9c..551269789e 100644 --- a/erpnext/setup/doctype/notification_control/notification_control.js +++ b/erpnext/setup/doctype/notification_control/notification_control.js @@ -14,19 +14,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -cur_frm.cscript.select_transaction = function(doc, dt, dn) { +cur_frm.cscript.select_transaction = function(doc, cdt, cdn) { if(doc.select_transaction) { var callback = function(r,rt) { - var doc = locals[dt][dn]; + var doc = locals[cdt][cdn]; doc.custom_message = r.message; refresh_field('custom_message'); } - $c_obj('Notification Control','get_message',doc.select_transaction, callback) + $c_obj(make_doclist(cdt, cdn),'get_message',doc.select_transaction, callback) } } cur_frm.cscript.notify = function(doc, args) { - $c_obj('Notification Control', 'get_formatted_message', { + $c_obj(make_doclist(doc.doctype, doc.name), 'get_formatted_message', { type: args['type'], doctype: args['doctype'], contact_name: args['contact_name'] || doc.contact_display diff --git a/erpnext/setup/doctype/notification_control/notification_control.py b/erpnext/setup/doctype/notification_control/notification_control.py index 650486ece7..2a21e80615 100644 --- a/erpnext/setup/doctype/notification_control/notification_control.py +++ b/erpnext/setup/doctype/notification_control/notification_control.py @@ -39,7 +39,7 @@ class DocType: # set custom text # --------------- - def set_message(self, arg=''): + def set_message(self, arg = ''): fn = self.doc.select_transaction.lower().replace(' ', '_') + '_message' webnotes.conn.set(self.doc, fn, self.doc.custom_message) msgprint("Custom Message for %s updated!" % self.doc.select_transaction) diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py index a6fc1c4386..f645e8fa42 100644 --- a/erpnext/stock/doctype/bin/bin.py +++ b/erpnext/stock/doctype/bin/bin.py @@ -44,6 +44,7 @@ class DocType: def update_stock(self, actual_qty=0, reserved_qty=0, ordered_qty=0, indented_qty=0, planned_qty=0, dt=None, sle_id='', posting_time='', serial_no = '', is_cancelled = 'No',doc_type='',doc_name='',is_amended='No'): if not dt: dt = nowdate() + # update the stock values (for current quantities) self.doc.actual_qty = flt(self.doc.actual_qty) + flt(actual_qty) self.doc.ordered_qty = flt(self.doc.ordered_qty) + flt(ordered_qty) @@ -295,7 +296,7 @@ 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: + for sle in sll: # block if stock level goes negative on any date if val_method != 'Moving Average' or flt(allow_negative_stock) == 0: self.validate_negative_stock(cqty, sle) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 8761881b67..e32439ce3b 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -63,13 +63,8 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) { if(doc.docstatus == 1){ - var ch = getchildren('Purchase Receipt Item',doc.name,'purchase_receipt_details'); - allow_billing = 0; - for(var i in ch){ - if(ch[i].qty > ch[i].billed_qty) allow_billing = 1; - } - cur_frm.add_custom_button('Make Purchase Invoice', cur_frm.cscript['Make Purchase Invoice']); - cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms); + if (doc.per_billed < 100) cur_frm.add_custom_button('Make Purchase Invoice', cur_frm.cscript['Make Purchase Invoice']); + cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']); } } diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 2384171f6a..88f1bf21a6 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -71,10 +71,13 @@ class DocType(TransactionBase): self.validate_warehouse() self.validate_item() + def on_update(self): + if self.doc.warehouse and self.doc.status == 'In Store' and cint(self.doc.sle_exists) == 0 and \ + not sql("select name from `tabStock Ledger Entry` where serial_no = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name): + self.make_stock_ledger_entry(1) + webnotes.conn.set(self.doc, 'sle_exists', 1) + - # ------------------------ - # make stock ledger entry - # ------------------------ def make_stock_ledger_entry(self, qty): from webnotes.model.code import get_obj values = [{ @@ -91,21 +94,13 @@ class DocType(TransactionBase): 'incoming_rate' : self.doc.purchase_rate, 'company' : self.doc.company, 'fiscal_year' : self.doc.fiscal_year, - 'is_cancelled' : 'No', # is_cancelled is always 'No' because while deleted it can not find creation entry if it not created directly, voucher no != serial no. + 'is_cancelled' : 'No', # is_cancelled is always 'No' because while deleted it can not find creation entry if it not created directly, voucher no != serial no 'batch_no' : '', 'serial_no' : self.doc.name }] get_obj('Stock Ledger', 'Stock Ledger').update_stock(values) - # ---------- - # on update - # ---------- - def on_update(self): - if self.doc.localname and self.doc.warehouse and self.doc.status == 'In Store' and not sql("select name from `tabStock Ledger Entry` where serial_no = '%s' and ifnull(is_cancelled, 'No') = 'No'" % (self.doc.name)): - self.make_stock_ledger_entry(1) - - # --------- # on trash # --------- diff --git a/erpnext/stock/doctype/serial_no/serial_no.txt b/erpnext/stock/doctype/serial_no/serial_no.txt index aa0ea667c8..8e32243307 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.txt +++ b/erpnext/stock/doctype/serial_no/serial_no.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:37', + 'creation': '2012-04-23 16:00:23', 'docstatus': 0, - 'modified': '2012-03-27 14:36:37', + 'modified': '2012-04-26 13:01:57', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -13,6 +13,7 @@ # These values are common for all DocType { '_last_update': u'1325570647', + 'allow_attach': 1, 'allow_trash': 1, 'autoname': u'field:serial_no', 'colour': u'White:FFF', @@ -27,7 +28,7 @@ 'show_in_menu': 0, 'subject': u'Item Code: %(item_code)s, Warehouse: %(warehouse)s', 'tag_fields': u'status', - 'version': 191 + 'version': 1 }, # These values are common for all DocField @@ -55,6 +56,54 @@ 'name': u'Serial No' }, + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Material Manager', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Material Manager', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Material User', + 'submit': 0, + 'write': 0 + }, + + # DocPerm + { + 'amend': 0, + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Material User', + 'submit': 0, + 'write': 0 + }, + # DocPerm { 'cancel': 1, @@ -89,54 +138,6 @@ 'role': u'Sales Master Manager' }, - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Material Manager', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Material Manager', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Material User', - 'submit': 0, - 'write': 0 - }, - - # DocPerm - { - 'amend': 0, - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Material User', - 'submit': 0, - 'write': 0 - }, - # DocField { 'doctype': u'DocField', @@ -700,5 +701,30 @@ 'oldfieldname': u'trash_reason', 'oldfieldtype': u'Small Text', 'permlevel': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'file_list', + 'fieldtype': u'Text', + 'hidden': 1, + 'label': u'File List', + 'no_copy': 1, + 'permlevel': 0, + 'print_hide': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'sle_exists', + 'fieldtype': u'Check', + 'hidden': 1, + 'label': u'SLE Exists', + 'no_copy': 1, + 'permlevel': 1, + 'print_hide': 1, + 'report_hide': 1 } ] \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py index 577d2ef6e9..1d3aabe57f 100644 --- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py +++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py @@ -128,6 +128,7 @@ class DocType: s.modified = nowdate() s.modified_by = session['user'] s.serial_no = serial_no + s.sle_exists = 1 s.fiscal_year = obj.doc.fiscal_year s.company = obj.doc.company s.save(new_rec) @@ -211,7 +212,7 @@ class DocType: import datetime for d in getlist(obj.doclist, fname): if d.serial_no: - serial_nos = self.get_sr_no_list(d.serial_no, d.qty) + serial_nos = self.get_sr_no_list(d.serial_no) for a in serial_nos: serial_no = a.strip() if is_incoming: diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index bb23226ee8..cf3bd2fa39 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -35,11 +35,14 @@ class DocType: def actual_amt_check(self): if self.doc.batch_no: batch_bal = flt(sql("select sum(actual_qty) from `tabStock Ledger Entry` where warehouse = '%s' and item_code = '%s' and batch_no = '%s'"%(self.doc.warehouse,self.doc.item_code,self.doc.batch_no))[0][0]) - + self.doc.fields.update({'batch_bal': batch_bal}) + if (batch_bal + self.doc.actual_qty) < 0: msgprint("""Not enough quantity (requested: %(actual_qty)s, current: %(batch_bal)s in Batch %(batch_no)s for Item %(item_code)s at Warehouse%(warehouse)s - as on %(posting_date)s %(posting_time)s""" % self.doc.fields.update({'batch_bal': batch_bal}), raise_exception = 1) + as on %(posting_date)s %(posting_time)s""" % self.doc.fields, raise_exception = 1) + + self.doc.fields.pop('batch_bal') # mandatory @@ -89,9 +92,17 @@ class DocType: if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) + def validate_posting_time(self): + """ Validate posting time format""" + if self.doc.posting_time and len(cstr(self.doc.posting_time)) == 8 and cstr(self.doc.posting_time)[-2:] != '00': + msgprint("Wrong format of posting time, can not complete the transaction. If you think \ + you entered posting time correctly, please contact ERPNext support team.") + raise Exception + def validate(self): self.validate_mandatory() + self.validate_posting_time() self.validate_item() self.actual_amt_check() self.check_stock_frozen_date()