From 72d9c5b724449bc3a1e7be14c4f584d4454e5266 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 11:54:40 +0530 Subject: [PATCH 01/17] fixed floating point issue in jv --- .../journal_voucher/journal_voucher.js | 6 ++--- .../journal_voucher/journal_voucher.py | 26 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/accounts/doctype/journal_voucher/journal_voucher.js b/accounts/doctype/journal_voucher/journal_voucher.js index 82322c89ec..78956bf11e 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.js +++ b/accounts/doctype/journal_voucher/journal_voucher.js @@ -84,13 +84,13 @@ cur_frm.cscript.update_totals = function(doc) { var td=0.0; var tc =0.0; var el = getchildren('Journal Voucher Detail', doc.name, 'entries'); for(var i in el) { - td += flt(el[i].debit); - tc += flt(el[i].credit); + td += flt(el[i].debit, 2); + tc += flt(el[i].credit, 2); } var doc = locals[doc.doctype][doc.name]; doc.total_debit = td; doc.total_credit = tc; - doc.difference = flt(td - tc); + doc.difference = flt((td - tc), 2); refresh_many(['total_debit','total_credit','difference']); } diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 812ab7d0be..8b54f0fec2 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -114,8 +114,8 @@ class DocType(AccountsController): debit, credit = 0.0, 0.0 debit_list, credit_list = [], [] for d in getlist(self.doclist, 'entries'): - debit += flt(d.debit) - credit += flt(d.credit) + debit += flt(d.debit, 2) + credit += flt(d.credit, 2) if flt(d.debit)>0 and (d.account not in debit_list): debit_list.append(d.account) if flt(d.credit)>0 and (d.account not in credit_list): credit_list.append(d.account) @@ -289,32 +289,32 @@ class DocType(AccountsController): if not getlist(self.doclist,'entries'): msgprint("Please enter atleast 1 entry in 'GL Entries' table") else: - flag, self.doc.total_debit, self.doc.total_credit = 0,0,0 - diff = flt(self.doc.difference) + flag, self.doc.total_debit, self.doc.total_credit = 0, 0, 0 + diff = flt(self.doc.difference, 2) # If any row without amount, set the diff on that row for d in getlist(self.doclist,'entries'): - if not d.credit and not d.debit and flt(diff) != 0: + if not d.credit and not d.debit and diff != 0: if diff>0: - d.credit = flt(diff) + d.credit = diff elif diff<0: - d.debit = flt(diff) + d.debit = diff flag = 1 # Set the diff in a new row - if flag == 0 and (flt(diff) != 0): + if flag == 0 and diff != 0: jd = addchild(self.doc, 'entries', 'Journal Voucher Detail', self.doclist) if diff>0: - jd.credit = flt(abs(diff)) + jd.credit = abs(diff) elif diff<0: - jd.debit = flt(abs(diff)) + jd.debit = abs(diff) # Set the total debit, total credit and difference for d in getlist(self.doclist,'entries'): - self.doc.total_debit += flt(d.debit) - self.doc.total_credit += flt(d.credit) + self.doc.total_debit += flt(d.debit, 2) + self.doc.total_credit += flt(d.credit, 2) - self.doc.difference = flt(self.doc.total_debit) - flt(self.doc.total_credit) + self.doc.difference = flt(self.doc.total_debit, 2) - flt(self.doc.total_credit, 2) def get_outstanding_invoices(self): self.doclist = self.doc.clear_table(self.doclist, 'entries') From fc33ef6bfbd117c078efb49af8b1f1582e0c8f38 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:13:14 +0530 Subject: [PATCH 02/17] fixes in purchase invoice --- accounts/doctype/purchase_invoice/purchase_invoice.py | 4 +++- accounts/doctype/sales_invoice/sales_invoice.py | 1 - setup/doctype/email_settings/email_settings.txt | 8 +++----- stock/doctype/delivery_note/delivery_note.py | 1 - stock/doctype/stock_entry/stock_entry.py | 2 -- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index fb9977c486..85fdb47866 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -306,7 +306,9 @@ class DocType(BuyingController): def set_against_expense_account(self): auto_inventory_accounting = \ cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) - stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") + + if auto_inventory_accounting: + stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") against_accounts = [] for item in self.doclist.get({"parentfield": "entries"}): diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index a46e299879..a8f76856e2 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -641,7 +641,6 @@ class DocType(SellingController): self.values.append({ 'item_code' : d['item_code'], 'warehouse' : wh, - 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'posting_date' : self.doc.posting_date, 'posting_time' : self.doc.posting_time, 'voucher_type' : 'Sales Invoice', diff --git a/setup/doctype/email_settings/email_settings.txt b/setup/doctype/email_settings/email_settings.txt index 1de2c93045..5547c2e74c 100644 --- a/setup/doctype/email_settings/email_settings.txt +++ b/setup/doctype/email_settings/email_settings.txt @@ -1,10 +1,10 @@ [ { - "creation": "2012-07-12 23:29:44", + "creation": "2013-03-25 17:53:21", "docstatus": 0, - "modified": "2013-03-25 17:32:05", + "modified": "2013-03-25 18:41:27", "modified_by": "Administrator", - "owner": "harshada@webnotestech.com" + "owner": "Administrator" }, { "allow_copy": 1, @@ -34,9 +34,7 @@ "parenttype": "DocType", "permlevel": 0, "read": 1, - "report": 0, "role": "System Manager", - "submit": 0, "write": 1 }, { diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 16d1795fb6..ded689734f 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -377,7 +377,6 @@ class DocType(SellingController): self.values.append({ 'item_code' : d['item_code'], 'warehouse' : wh, - 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'posting_date' : self.doc.posting_date, 'posting_time' : self.doc.posting_time, 'voucher_type' : 'Delivery Note', diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index c3739ced43..d89d95b272 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -776,8 +776,6 @@ def make_return_jv(stock_entry): from accounts.utils import get_balance_on for r in result: - if not r.get("account"): - print result jv_list.append({ "__islocal": 1, "doctype": "Journal Voucher Detail", From 9f91053201ad1e95a5bd6d48c30956078a2a7605 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:25:11 +0530 Subject: [PATCH 03/17] patch to set user type as System User if user has a role and if previous user type is Partner --- patches/march_2013/p09_unset_user_type_partner.py | 6 ++++++ patches/patch_list.py | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 patches/march_2013/p09_unset_user_type_partner.py diff --git a/patches/march_2013/p09_unset_user_type_partner.py b/patches/march_2013/p09_unset_user_type_partner.py new file mode 100644 index 0000000000..cc5cdce5c2 --- /dev/null +++ b/patches/march_2013/p09_unset_user_type_partner.py @@ -0,0 +1,6 @@ +import webnotes + +def execute(): + webnotes.conn.sql("""update `tabProfile` set user_type='System User' + where user_type='Partner' and exists (select name from `tabUserRole` + where parent=`tabProfile`.name)""") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 00dd5da200..0c5427b52b 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -217,5 +217,6 @@ patch_list = [ "execute:webnotes.bean('Global Defaults').save()", "patches.march_2013.p07_update_project_in_stock_ledger", "execute:webnotes.bean('Style Settings').save() #2013-03-25", - "execute:webnotes.conn.set_value('Email Settings', None, 'send_print_in_body_and_attachment', 1)" + "execute:webnotes.conn.set_value('Email Settings', None, 'send_print_in_body_and_attachment', 1)", + "patches.march_2013.p09_unset_user_type_partner", ] \ No newline at end of file From acec0227c5b9e9a629ee614642ab03d11c657f9e Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:33:43 +0530 Subject: [PATCH 04/17] fixes in stock entry --- .../Purchase Order-Purchase Receipt.txt | 144 ++++++++---------- stock/doctype/stock_entry/stock_entry.py | 6 + stock/doctype/stock_entry/stock_entry.txt | 22 +-- stock/doctype/stock_entry/test_stock_entry.py | 2 +- utilities/transaction_base.py | 3 +- 5 files changed, 83 insertions(+), 94 deletions(-) diff --git a/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt b/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt index 8d7fab1235..0833aaa849 100644 --- a/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt +++ b/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt @@ -1,189 +1,169 @@ [ { - "owner": "Administrator", + "creation": "2013-02-22 01:28:05", "docstatus": 0, - "creation": "2010-08-08 17:09:35", + "modified": "2013-03-26 07:58:20", "modified_by": "Administrator", - "modified": "2012-04-02 14:03:39" + "owner": "Administrator" }, { + "doctype": "Table Mapper Detail", "name": "__common__", "parent": "Purchase Order-Purchase Receipt", - "doctype": "Table Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "table_mapper_details" + "parentfield": "table_mapper_details", + "parenttype": "DocType Mapper" }, { + "doctype": "Field Mapper Detail", "map": "Yes", "name": "__common__", "parent": "Purchase Order-Purchase Receipt", - "doctype": "Field Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "field_mapper_details" + "parentfield": "field_mapper_details", + "parenttype": "DocType Mapper" }, { - "name": "__common__", - "to_doctype": "Purchase Receipt", - "module": "Stock", "doctype": "DocType Mapper", + "from_doctype": "Purchase Order", + "module": "Stock", + "name": "__common__", "ref_doc_submitted": 1, - "from_doctype": "Purchase Order" + "to_doctype": "Purchase Receipt" }, { - "name": "Purchase Order-Purchase Receipt", - "doctype": "DocType Mapper" + "doctype": "DocType Mapper", + "name": "Purchase Order-Purchase Receipt" }, { - "match_id": 0, - "to_field": "supplier", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "supplier", - "checking_operator": "=" + "match_id": 0, + "to_field": "supplier" }, { - "match_id": 0, - "to_field": "company", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "company", - "checking_operator": "=" + "match_id": 0, + "to_field": "company" }, { - "match_id": 0, - "to_field": "currency", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "currency", - "checking_operator": "=" + "match_id": 0, + "to_field": "currency" }, { - "to_field": "prevdoc_detail_docname", "doctype": "Field Mapper Detail", + "from_field": "name", "match_id": 1, - "from_field": "name" + "to_field": "prevdoc_detail_docname" }, { - "to_field": "prevdoc_docname", "doctype": "Field Mapper Detail", + "from_field": "parent", "match_id": 1, - "from_field": "parent" + "to_field": "prevdoc_docname" }, { - "to_field": "prevdoc_doctype", "doctype": "Field Mapper Detail", + "from_field": "parenttype", "match_id": 1, - "from_field": "parenttype" + "to_field": "prevdoc_doctype" }, { - "match_id": 1, - "to_field": "item_code", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "item_code", - "checking_operator": "=" - }, - { - "to_field": "received_qty", - "doctype": "Field Mapper Detail", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) " + "to_field": "item_code" }, { - "to_field": "qty", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) ", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) " + "to_field": "received_qty" }, { - "to_field": "stock_qty", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) ", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)" + "to_field": "qty" }, { - "to_field": "import_amount", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.import_rate)" + "to_field": "stock_qty" }, { - "to_field": "amount", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.import_rate)", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.purchase_rate)" + "to_field": "import_amount" }, { - "to_field": "schedule_date", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.purchase_rate)", "match_id": 1, - "from_field": "schedule_date" + "to_field": "amount" }, { - "to_field": "net_total", "doctype": "Field Mapper Detail", + "from_field": "schedule_date", + "match_id": 1, + "to_field": "schedule_date" + }, + { + "doctype": "Field Mapper Detail", + "from_field": "net_total", "match_id": 0, - "from_field": "net_total" + "to_field": "net_total" }, { - "to_field": "grand_total", "doctype": "Field Mapper Detail", + "from_field": "grand_total", "match_id": 0, - "from_field": "grand_total" + "to_field": "grand_total" }, { - "to_field": "total_tax", "doctype": "Field Mapper Detail", + "from_field": "total_tax", "match_id": 0, - "from_field": "total_tax" + "to_field": "total_tax" }, { - "to_field": "conversion_rate", "doctype": "Field Mapper Detail", + "from_field": "conversion_rate", "match_id": 0, - "from_field": "conversion_rate" + "to_field": "conversion_rate" }, { - "reference_key": "prevdoc_detail_docname", - "match_id": 1, - "reference_doctype_key": "prevdoc_doctype", - "to_field": "purchase_receipt_details", "doctype": "Table Mapper Detail", "from_field": "po_details", "from_table": "Purchase Order Item", + "match_id": 1, + "reference_doctype_key": "prevdoc_doctype", + "reference_key": "prevdoc_detail_docname", + "to_field": "purchase_receipt_details", "to_table": "Purchase Receipt Item", "validation_logic": "docstatus=1 and qty > ifnull(received_qty,0)" }, { - "reference_key": "prevdoc_detail_docname", - "match_id": 1, - "reference_doctype_key": "prevdoc_doctype", - "to_field": "purchase_receipt_details", - "doctype": "Table Mapper Detail", - "from_field": "po_details", - "from_table": "Purchase Order Item", - "to_table": "Purchase Receipt Item", - "validation_logic": "docstatus=1 and qty > ifnull(received_qty,0)" - }, - { - "reference_key": "prevdoc_docname", - "match_id": 0, "doctype": "Table Mapper Detail", "from_table": "Purchase Order", + "match_id": 0, + "reference_key": "prevdoc_docname", "to_table": "Purchase Receipt", "validation_logic": "docstatus = 1" }, { - "match_id": 2, - "to_field": "purchase_tax_details", "doctype": "Table Mapper Detail", "from_field": "purchase_tax_details", "from_table": "Purchase Taxes and Charges", - "to_table": "Purchase Taxes and Charges", - "validation_logic": "docstatus = 1" - }, - { "match_id": 2, "to_field": "purchase_tax_details", - "doctype": "Table Mapper Detail", - "from_field": "purchase_tax_details", - "from_table": "Purchase Taxes and Charges", "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus = 1" } diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index d89d95b272..c437135ad6 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -55,6 +55,7 @@ class DocType(StockController): self.validate_finished_goods() self.validate_return_reference_doc() self.validate_with_material_request() + self.validate_fiscal_year() def on_submit(self): self.update_serial_no(1) @@ -68,6 +69,11 @@ class DocType(StockController): self.update_production_order(0) self.make_gl_entries() + def validate_fiscal_year(self): + import accounts.utils + accounts.utils.validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, + self.meta.get_label("posting_date")) + def validate_purpose(self): valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Manufacture/Repack", "Subcontract", "Sales Return", "Purchase Return"] diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index df5b613baf..91f9bb4fc0 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-11 12:34:40", + "creation": "2013-03-26 06:51:17", "docstatus": 0, - "modified": "2013-03-19 17:48:29", + "modified": "2013-03-26 07:24:53", "modified_by": "Administrator", "owner": "Administrator" }, @@ -542,6 +542,16 @@ "reqd": 0, "search_index": 0 }, + { + "doctype": "DocField", + "fieldname": "fiscal_year", + "fieldtype": "Select", + "in_filter": 0, + "label": "Fiscal Year", + "options": "link:Fiscal Year", + "print_hide": 1, + "reqd": 1 + }, { "allow_on_submit": 0, "doctype": "DocField", @@ -610,13 +620,5 @@ { "doctype": "DocPerm", "role": "Manufacturing User" - }, - { - "doctype": "DocPerm", - "role": "Manufacturing Manager" - }, - { - "doctype": "DocPerm", - "role": "Material Manager" } ] \ No newline at end of file diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 25018930dd..3f8012a726 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -490,7 +490,7 @@ class TestStockEntry(unittest.TestCase): def test_make_return_jv_for_purchase_receipt(self): se, pr_name = self.test_purchase_receipt_return() self._test_purchase_return_jv(se) - + se, pr_name = self._test_purchase_return_return_against_purchase_order() self._test_purchase_return_jv(se) diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 2dc8c6a2d7..c43a456687 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -250,4 +250,5 @@ class TransactionBase(DocListController): def validate_posting_time(self): if not self.doc.posting_time: - self.doc.posting_time = now_datetime().strftime('%H:%M:%S') \ No newline at end of file + self.doc.posting_time = now_datetime().strftime('%H:%M:%S') + \ No newline at end of file From 4731fb999cd07c22f959a797be26151be7f3c298 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 12:47:19 +0530 Subject: [PATCH 05/17] [feature] [fix] utilities/rename tool upgraded to upload multiple items --- .../upload_attendance/upload_attendance.js | 12 +--- setup/page/setup/setup.js | 6 ++ .../stock_reconciliation.js | 9 ++- utilities/doctype/rename_tool/__init__.py | 0 utilities/doctype/rename_tool/rename_tool.js | 47 +++++++++++++ utilities/doctype/rename_tool/rename_tool.py | 49 +++++++++++++ utilities/doctype/rename_tool/rename_tool.txt | 69 +++++++++++++++++++ 7 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 utilities/doctype/rename_tool/__init__.py create mode 100644 utilities/doctype/rename_tool/rename_tool.js create mode 100644 utilities/doctype/rename_tool/rename_tool.py create mode 100644 utilities/doctype/rename_tool/rename_tool.txt diff --git a/hr/doctype/upload_attendance/upload_attendance.js b/hr/doctype/upload_attendance/upload_attendance.js index 0c1d7b2574..35a00ed69d 100644 --- a/hr/doctype/upload_attendance/upload_attendance.js +++ b/hr/doctype/upload_attendance/upload_attendance.js @@ -44,20 +44,17 @@ erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({ show_upload: function() { var me = this; var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty(); - var upload_area = $('
').appendTo($wrapper); // upload wn.upload.make({ - parent: $('#dit-upload-area'), + parent: $wrapper, args: { method: 'hr.doctype.upload_attendance.upload_attendance.upload' }, sample_url: "e.g. http://example.com/somefile.csv", callback: function(r) { var $log_wrapper = $(cur_frm.fields_dict.import_log.wrapper).empty(); - var log_area = $('
').appendTo($log_wrapper); - $wrapper.find(".dit-progress-area").toggle(false); if(!r.messages) r.messages = []; // replace links if error has occured if(r.exc || r.error) { @@ -81,7 +78,7 @@ erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({ console.log(r.messages); $.each(r.messages, function(i, v) { - var $p = $('

').html(v).appendTo('#dit-output'); + var $p = $('

').html(v).appendTo($log_wrapper); if(v.substr(0,5)=='Error') { $p.css('color', 'red'); } else if(v.substr(0,8)=='Inserted') { @@ -96,11 +93,8 @@ erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({ }); // rename button - $('#dit-upload-area form input[type="submit"]') + $wrapper.find('form input[type="submit"]') .attr('value', 'Upload and Import') - .click(function() { - $wrapper.find(".dit-progress-area").toggle(true); - }); } }) diff --git a/setup/page/setup/setup.js b/setup/page/setup/setup.js index a9df4592f9..e59a18ab99 100644 --- a/setup/page/setup/setup.js +++ b/setup/page/setup/setup.js @@ -76,6 +76,12 @@ wn.module_page["Setup"] = [ label: wn._("Manage numbering series"), "description":wn._("Set multiple numbering series for transactions") }, + { + "route":"Form/Rename Tool", + doctype: "Rename Tool", + label: wn._("Rename Tool"), + "description":wn._("Rename multiple items in one go") + }, ] }, { diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.js b/stock/doctype/stock_reconciliation/stock_reconciliation.js index 372166eaac..9229e14df8 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -101,22 +101,25 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({ show_upload: function() { var me = this; var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty(); - var upload_area = $('

').appendTo($wrapper); // upload wn.upload.make({ - parent: $('#dit-upload-area'), + parent: $wrapper, args: { method: 'stock.doctype.stock_reconciliation.stock_reconciliation.upload' }, sample_url: "e.g. http://example.com/somefile.csv", callback: function(r) { - $wrapper.find(".dit-progress-area").toggle(false); me.frm.set_value("reconciliation_json", JSON.stringify(r)); me.show_reconciliation_data(); me.frm.save(); } }); + + // rename button + $wrapper.find('form input[type="submit"]') + .attr('value', 'Upload') + }, show_download_reconciliation_data: function() { diff --git a/utilities/doctype/rename_tool/__init__.py b/utilities/doctype/rename_tool/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/utilities/doctype/rename_tool/rename_tool.js b/utilities/doctype/rename_tool/rename_tool.js new file mode 100644 index 0000000000..9c93622185 --- /dev/null +++ b/utilities/doctype/rename_tool/rename_tool.js @@ -0,0 +1,47 @@ +cur_frm.cscript.refresh = function(doc) { + wn.call({ + method:"utilities.doctype.rename_tool.rename_tool.get_doctypes", + callback: function(r) { + cur_frm.set_df_property("select_doctype", "options", r.message); + cur_frm.cscript.setup_upload(); + } + }); +} + +cur_frm.cscript.select_doctype = function() { + cur_frm.cscript.setup_upload(); +} + +cur_frm.cscript.setup_upload = function() { + var me = this; + var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty() + .html("
" + + wn._("Upload a .csv file with two columns: the old name and the new name. Max 500 rows.") + + "
"); + var $log = $(cur_frm.fields_dict.rename_log.wrapper).empty(); + + // upload + wn.upload.make({ + parent: $wrapper, + args: { + method: 'utilities.doctype.rename_tool.rename_tool.upload', + select_doctype: cur_frm.doc.select_doctype + }, + sample_url: "e.g. http://example.com/somefile.csv", + callback: function(r) { + $log.empty().html("
"); + $.each(r, function(i, v) { + $("
" + v + "
").appendTo($log); + }); + } + }); + + // rename button + $wrapper.find('form input[type="submit"]') + .click(function() { + $log.html("Working..."); + }) + .addClass("btn-info") + .attr('value', 'Upload and Rename') + +} \ No newline at end of file diff --git a/utilities/doctype/rename_tool/rename_tool.py b/utilities/doctype/rename_tool/rename_tool.py new file mode 100644 index 0000000000..2e368ced70 --- /dev/null +++ b/utilities/doctype/rename_tool/rename_tool.py @@ -0,0 +1,49 @@ +# For license information, please see license.txt + +from __future__ import unicode_literals +import webnotes +from webnotes import _ + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + +@webnotes.whitelist() +def get_doctypes(): + return webnotes.conn.sql_list("""select name from tabDocType + where ifnull(allow_rename,0)=1 and module!='Core' order by name""") + +@webnotes.whitelist(allow_roles=["System Manager"]) +def upload(select_doctype=None, rows=None): + from webnotes.utils.datautils import read_csv_content_from_uploaded_file + from webnotes.modules import scrub + from webnotes.model.rename_doc import rename_doc + + if not select_doctype: + select_doctype = webnotes.form_dict.select_doctype + + if not rows: + rows = read_csv_content_from_uploaded_file() + if not rows: + webnotes.msgprint(_("Please select a valid csv file with data.")) + raise Exception + + if len(rows) > 500: + webnotes.msgprint(_("Max 500 rows only.")) + raise Exception + + rename_log = [] + for row in rows: + if len(row) > 2: + try: + if rename_doc(select_doctype, row[0], row[1]): + rename_log.append(_("Successful: ") + row[0] + " -> " + row[1]) + webnotes.conn.commit() + else: + rename_log.append(_("Ignored: ") + row[0] + " -> " + row[1]) + except Exception, e: + rename_log.append("" + \ + _("Failed: ") + row[0] + " -> " + row[1] + "") + rename_log.append("" + repr(e) + "") + + return rename_log \ No newline at end of file diff --git a/utilities/doctype/rename_tool/rename_tool.txt b/utilities/doctype/rename_tool/rename_tool.txt new file mode 100644 index 0000000000..20c2561556 --- /dev/null +++ b/utilities/doctype/rename_tool/rename_tool.txt @@ -0,0 +1,69 @@ +[ + { + "creation": "2012-12-03 10:25:59", + "docstatus": 0, + "modified": "2013-03-26 12:46:07", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "allow_attach": 0, + "allow_email": 1, + "allow_print": 1, + "doctype": "DocType", + "hide_heading": 0, + "hide_toolbar": 1, + "issingle": 1, + "max_attachments": 1, + "module": "Utilities", + "name": "__common__" + }, + { + "doctype": "DocField", + "name": "__common__", + "parent": "Rename Tool", + "parentfield": "fields", + "parenttype": "DocType", + "permlevel": 0 + }, + { + "create": 1, + "doctype": "DocPerm", + "name": "__common__", + "parent": "Rename Tool", + "parentfield": "permissions", + "parenttype": "DocType", + "permlevel": 0, + "read": 1, + "report": 0, + "role": "System Manager", + "submit": 0, + "write": 1 + }, + { + "doctype": "DocType", + "name": "Rename Tool" + }, + { + "description": "Type of document to rename.", + "doctype": "DocField", + "fieldname": "select_doctype", + "fieldtype": "Select", + "label": "Select DocType" + }, + { + "doctype": "DocField", + "fieldname": "upload_html", + "fieldtype": "HTML", + "label": "Upload HTML" + }, + { + "doctype": "DocField", + "fieldname": "rename_log", + "fieldtype": "HTML", + "label": "Rename Log" + }, + { + "doctype": "DocPerm" + } +] \ No newline at end of file From fd606afcb9c6d7f529c801c90379f7316c4a4bde Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 12:50:03 +0530 Subject: [PATCH 06/17] expense account optional mandatory in pos sett --- accounts/doctype/pos_setting/pos_setting.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/accounts/doctype/pos_setting/pos_setting.txt b/accounts/doctype/pos_setting/pos_setting.txt index a625ad8c0b..4e30b57593 100755 --- a/accounts/doctype/pos_setting/pos_setting.txt +++ b/accounts/doctype/pos_setting/pos_setting.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-24 11:03:29", + "creation": "2013-03-26 11:03:07", "docstatus": 0, - "modified": "2013-03-25 15:27:52", + "modified": "2013-03-26 12:48:18", "modified_by": "Administrator", "owner": "Administrator" }, @@ -18,7 +18,8 @@ "parent": "POS Setting", "parentfield": "fields", "parenttype": "DocType", - "permlevel": 0 + "permlevel": 0, + "read_only": 0 }, { "doctype": "DocPerm", @@ -141,12 +142,15 @@ "reqd": 1 }, { + "depends_on": "eval:sys_defaults.auto_inventory_accounting", "doctype": "DocField", "fieldname": "expense_account", "fieldtype": "Link", + "hidden": 0, "label": "Expense Account", "options": "Account", - "reqd": 1 + "print_hide": 1, + "reqd": 0 }, { "doctype": "DocField", From 4a4ae0840af5c2ebcfc6be72d8c819fc3a534642 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 13:00:53 +0530 Subject: [PATCH 07/17] expense account optional mandatory in pos setting --- accounts/doctype/pos_setting/pos_setting.py | 33 +++++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/accounts/doctype/pos_setting/pos_setting.py b/accounts/doctype/pos_setting/pos_setting.py index 0e68e2aced..a024f6eb46 100755 --- a/accounts/doctype/pos_setting/pos_setting.py +++ b/accounts/doctype/pos_setting/pos_setting.py @@ -16,30 +16,37 @@ from __future__ import unicode_literals import webnotes - -from webnotes.model import db_exists -from webnotes.model.bean import copy_doclist -from webnotes import msgprint - -sql = webnotes.conn.sql - - +from webnotes import msgprint, _ +from webnotes.utils import cint class DocType: def __init__(self,doc,doclist=[]): self.doc, self.doclist = doc,doclist - #--------------------get naming series from sales invoice----------------- def get_series(self): import webnotes.model.doctype docfield = webnotes.model.doctype.get('Sales Invoice') - series = [d.options for d in docfield if d.doctype == 'DocField' and d.fieldname == 'naming_series'] + series = [d.options for d in docfield + if d.doctype == 'DocField' and d.fieldname == 'naming_series'] return series and series[0] or '' def validate(self): - res = sql("select name, user from `tabPOS Setting` where ifnull(user, '') = '%s' and name != '%s' and company = '%s'" % (self.doc.user, self.doc.name, self.doc.company)) + self.check_for_duplicate() + self.validate_expense_account() + + def check_for_duplicate(self): + res = webnotes.conn.sql("""select name, user from `tabPOS Setting` + where ifnull(user, '') = %s and name != %s and company = %s""", + (self.doc.user, self.doc.name, self.doc.company)) if res: if res[0][1]: - msgprint("POS Setting '%s' already created for user: '%s' and company: '%s'"%(res[0][0], res[0][1], self.doc.company), raise_exception=1) + msgprint("POS Setting '%s' already created for user: '%s' and company: '%s'" % + (res[0][0], res[0][1], self.doc.company), raise_exception=1) else: - msgprint("Global POS Setting already created - %s for this company: '%s'" % (res[0][0], self.doc.company), raise_exception=1) + msgprint("Global POS Setting already created - %s for this company: '%s'" % + (res[0][0], self.doc.company), raise_exception=1) + + def validate_expense_account(self): + if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \ + and not self.doc.expense_account: + msgprint(_("Expense Account is mandatory"), raise_exception=1) \ No newline at end of file From b6c117957fa4996a8d36d6c40eecda63e65cce08 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 13:02:22 +0530 Subject: [PATCH 08/17] [fields, project] [fix] NaN bug, project gantt refresh bug --- home/page/latest_updates/latest_updates.js | 1 + projects/doctype/project/project.js | 3 +++ selling/doctype/sales_common/sales_common.js | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js index 183352ce04..a7a148a662 100644 --- a/home/page/latest_updates/latest_updates.js +++ b/home/page/latest_updates/latest_updates.js @@ -1,4 +1,5 @@ erpnext.updates = [ + ["27th March", ["Rename multiple items together. Go to Setup > Rename Tool"]], ["19th March", ["Sales and Purchase Return Tool deprecated. Use Stock Entry instead."]], ["12th March", ["Updates to website module. Added more options in Style Settings and Website Settings."]], ["5th March", ["Refactored Upload Attendance Tool"]], diff --git a/projects/doctype/project/project.js b/projects/doctype/project/project.js index 7f847b97f8..d4a034fd76 100644 --- a/projects/doctype/project/project.js +++ b/projects/doctype/project/project.js @@ -26,6 +26,9 @@ cur_frm.cscript.refresh = function(doc) { .appendTo(cur_frm.fields_dict.project_tasks.wrapper); cur_frm.gantt_area.empty(); erpnext.show_task_gantt(cur_frm.gantt_area, cur_frm.docname); + } else { + if(cur_frm.gantt_area) + cur_frm.gantt_area.empty(); } } diff --git a/selling/doctype/sales_common/sales_common.js b/selling/doctype/sales_common/sales_common.js index e15565aa74..8a8d8d0a6c 100644 --- a/selling/doctype/sales_common/sales_common.js +++ b/selling/doctype/sales_common/sales_common.js @@ -860,9 +860,9 @@ cur_frm.cscript.commission_rate = function(doc, cdt, cdn) { alert("Commision rate cannot be greater than 100."); doc.total_commission = 0; doc.commission_rate = 0; - } - else + } else { doc.total_commission = doc.net_total * doc.commission_rate / 100; + } refresh_many(['total_commission','commission_rate']); } @@ -874,9 +874,9 @@ cur_frm.cscript.total_commission = function(doc, cdt, cdn) { alert("Total commission cannot be greater than net total."); doc.total_commission = 0; doc.commission_rate = 0; - } - else + } else { doc.commission_rate = doc.total_commission * 100 / doc.net_total; + } refresh_many(['total_commission','commission_rate']); } } From 988bca04f2ff1260c9b590f329a067f93098d93e Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 13:07:49 +0530 Subject: [PATCH 09/17] [selling] [usability] rearranged lead --- selling/doctype/lead/lead.txt | 122 +++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 38 deletions(-) diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt index 40d2f1b5ae..ae8c6c4c15 100644 --- a/selling/doctype/lead/lead.txt +++ b/selling/doctype/lead/lead.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-28 10:06:01", + "creation": "2013-01-28 17:07:01", "docstatus": 0, - "modified": "2013-01-28 15:28:49", + "modified": "2013-03-26 13:07:11", "modified_by": "Administrator", "owner": "Administrator" }, @@ -23,18 +23,13 @@ "permlevel": 0 }, { - "amend": 0, - "create": 1, "doctype": "DocPerm", "name": "__common__", "parent": "Lead", "parentfield": "permissions", "parenttype": "DocType", - "permlevel": 0, "read": 1, - "report": 1, - "submit": 0, - "write": 1 + "submit": 0 }, { "doctype": "DocType", @@ -64,6 +59,19 @@ "reqd": 1, "search_index": 1 }, + { + "description": "Name of organization from where lead has come", + "doctype": "DocField", + "fieldname": "company_name", + "fieldtype": "Data", + "in_filter": 1, + "in_list_view": 1, + "label": "Company Name", + "oldfieldname": "company_name", + "oldfieldtype": "Data", + "reqd": 0, + "search_index": 0 + }, { "doctype": "DocField", "fieldname": "email_id", @@ -105,10 +113,22 @@ "no_copy": 1, "oldfieldname": "source", "oldfieldtype": "Select", - "options": "\nAdvertisement\nBlog\nCampaign\nCall\nCustomer\nExhibition\nSupplier\nWebsite\nEmail", + "options": "\nAdvertisement\nBlog Post\nCampaign\nCall\nCustomer\nExhibition\nSupplier\nWebsite\nEmail", "reqd": 0, "search_index": 0 }, + { + "depends_on": "eval:doc.source == 'Campaign'", + "description": "Enter campaign name if the source of lead is campaign.", + "doctype": "DocField", + "fieldname": "campaign_name", + "fieldtype": "Link", + "hidden": 0, + "label": "Campaign Name", + "oldfieldname": "campaign_name", + "oldfieldtype": "Link", + "options": "Campaign" + }, { "doctype": "DocField", "fieldname": "communication_history", @@ -129,19 +149,6 @@ "fieldtype": "Section Break", "label": "Lead Details" }, - { - "description": "Name of organization from where lead has come", - "doctype": "DocField", - "fieldname": "company_name", - "fieldtype": "Data", - "in_filter": 1, - "in_list_view": 1, - "label": "Company Name", - "oldfieldname": "company_name", - "oldfieldtype": "Data", - "reqd": 0, - "search_index": 0 - }, { "depends_on": "eval:doc.source == 'Existing Customer'", "description": "Source of th", @@ -154,18 +161,6 @@ "oldfieldtype": "Link", "options": "Customer" }, - { - "depends_on": "eval:doc.source == 'Campaign'", - "description": "Enter campaign name if the source of lead is campaign.", - "doctype": "DocField", - "fieldname": "campaign_name", - "fieldtype": "Link", - "hidden": 0, - "label": "Campaign Name", - "oldfieldname": "campaign_name", - "oldfieldtype": "Link", - "options": "Campaign" - }, { "doctype": "DocField", "fieldname": "column_break1", @@ -462,18 +457,69 @@ "label": "Blog Subscriber" }, { - "cancel": 0, + "create": 1, "doctype": "DocPerm", - "role": "Sales User" + "permlevel": 0, + "report": 1, + "role": "Guest", + "write": 1 }, { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "report": 0, + "role": "Sales User", + "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "report": 0, + "role": "Sales Manager", + "write": 0 + }, + { + "amend": 0, "cancel": 1, + "create": 1, "doctype": "DocPerm", - "role": "Sales Manager" + "permlevel": 0, + "report": 1, + "role": "Sales Manager", + "write": 1 }, { + "amend": 0, "cancel": 0, + "create": 1, "doctype": "DocPerm", - "role": "System Manager" + "permlevel": 0, + "report": 1, + "role": "Sales User", + "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "permlevel": 1, + "role": "All" + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "doctype": "DocPerm", + "permlevel": 0, + "report": 1, + "role": "System Manager", + "write": 1 } ] \ No newline at end of file From 265c1947e3b7d1944e271707556a2596553780b9 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 14:16:20 +0530 Subject: [PATCH 10/17] [form] [usability] change z-index only if in form --- selling/doctype/lead/lead.txt | 64 ++++++++++++++--------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt index ae8c6c4c15..e162551607 100644 --- a/selling/doctype/lead/lead.txt +++ b/selling/doctype/lead/lead.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-28 17:07:01", "docstatus": 0, - "modified": "2013-03-26 13:07:11", + "modified": "2013-03-26 14:05:01", "modified_by": "Administrator", "owner": "Administrator" }, @@ -117,6 +117,18 @@ "reqd": 0, "search_index": 0 }, + { + "depends_on": "eval:doc.source == 'Customer'", + "description": "Source of th", + "doctype": "DocField", + "fieldname": "customer", + "fieldtype": "Link", + "hidden": 0, + "label": "From Customer", + "oldfieldname": "customer", + "oldfieldtype": "Link", + "options": "Customer" + }, { "depends_on": "eval:doc.source == 'Campaign'", "description": "Enter campaign name if the source of lead is campaign.", @@ -145,37 +157,10 @@ }, { "doctype": "DocField", - "fieldname": "sb8", + "fieldname": "contact_info", "fieldtype": "Section Break", - "label": "Lead Details" - }, - { - "depends_on": "eval:doc.source == 'Existing Customer'", - "description": "Source of th", - "doctype": "DocField", - "fieldname": "customer", - "fieldtype": "Link", - "hidden": 0, - "label": "From Customer", - "oldfieldname": "customer", - "oldfieldtype": "Link", - "options": "Customer" - }, - { - "doctype": "DocField", - "fieldname": "column_break1", - "fieldtype": "Column Break", - "width": "50%" - }, - { - "doctype": "DocField", - "fieldname": "type", - "fieldtype": "Select", - "in_filter": 1, - "label": "Lead Type", - "oldfieldname": "type", - "oldfieldtype": "Select", - "options": "\nClient\nChannel Partner\nConsultant" + "label": "Contact Info", + "oldfieldtype": "Column Break" }, { "doctype": "DocField", @@ -185,13 +170,6 @@ "oldfieldname": "remark", "oldfieldtype": "Text" }, - { - "doctype": "DocField", - "fieldname": "contact_info", - "fieldtype": "Section Break", - "label": "Contact Info", - "oldfieldtype": "Column Break" - }, { "doctype": "DocField", "fieldname": "phone", @@ -307,6 +285,16 @@ "label": "More Info", "oldfieldtype": "Section Break" }, + { + "doctype": "DocField", + "fieldname": "type", + "fieldtype": "Select", + "in_filter": 1, + "label": "Lead Type", + "oldfieldname": "type", + "oldfieldtype": "Select", + "options": "\nClient\nChannel Partner\nConsultant" + }, { "default": "__user", "doctype": "DocField", From 86f5e2e5641b3e53f2b26a37d9e5194149dece54 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 14:25:25 +0530 Subject: [PATCH 11/17] aii: gl entries for serial no --- stock/doctype/item/test_item.py | 19 +++ stock/doctype/serial_no/serial_no.py | 42 +++--- stock/doctype/serial_no/test_serial_no.py | 173 ++++++++++++---------- 3 files changed, 131 insertions(+), 103 deletions(-) diff --git a/stock/doctype/item/test_item.py b/stock/doctype/item/test_item.py index f31f245e81..dbbeecc85b 100644 --- a/stock/doctype/item/test_item.py +++ b/stock/doctype/item/test_item.py @@ -146,4 +146,23 @@ test_records = [ "is_sub_contracted_item": "No", "stock_uom": "_Test UOM" }], + [{ + "doctype": "Item", + "item_code": "_Test Serialized Item", + "item_name": "_Test Serialized Item", + "description": "_Test Serialized Item", + "item_group": "_Test Item Group Desktops", + "is_stock_item": "Yes", + "is_asset_item": "No", + "has_batch_no": "No", + "has_serial_no": "Yes", + "is_purchase_item": "Yes", + "is_sales_item": "Yes", + "is_service_item": "No", + "is_sample_item": "No", + "inspection_required": "No", + "is_pro_applicable": "No", + "is_sub_contracted_item": "No", + "stock_uom": "_Test UOM" + }], ] \ No newline at end of file diff --git a/stock/doctype/serial_no/serial_no.py b/stock/doctype/serial_no/serial_no.py index 00f2de7e40..5b15977635 100644 --- a/stock/doctype/serial_no/serial_no.py +++ b/stock/doctype/serial_no/serial_no.py @@ -19,14 +19,11 @@ import webnotes from webnotes.utils import cint, getdate, nowdate import datetime - -sql = webnotes.conn.sql -msgprint = webnotes.msgprint +from webnotes import msgprint, _ +from controllers.stock_controller import StockController -from utilities.transaction_base import TransactionBase - -class DocType(TransactionBase): +class DocType(StockController): def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist @@ -54,21 +51,14 @@ class DocType(TransactionBase): """ Validate whether serial no is required for this item """ - item = sql("select name, has_serial_no from tabItem where name = '%s'" % self.doc.item_code) + item = webnotes.conn.sql("select name, has_serial_no from tabItem where name = '%s'" % self.doc.item_code) if not item: msgprint("Item is not exists in the system", raise_exception=1) elif item[0][1] == 'No': msgprint("To proceed please select 'Yes' in 'Has Serial No' in Item master: '%s'" % self.doc.item_code, raise_exception=1) - # --------- - # validate - # --------- def validate(self): - # import utilities - # utilities.validate_status(self.doc.status, ["In Store", "Delivered", - # "Not in Use", "Purchase Returned"]) - self.validate_warranty_status() self.validate_amc_status() self.validate_warehouse() @@ -77,10 +67,12 @@ class DocType(TransactionBase): 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): + not webnotes.conn.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) + + self.make_gl_entries() def make_stock_ledger_entry(self, qty): from webnotes.model.code import get_obj @@ -105,15 +97,13 @@ class DocType(TransactionBase): get_obj('Stock Ledger').update_stock(values) - # --------- - # on trash - # --------- def on_trash(self): if self.doc.status == 'Delivered': msgprint("Cannot trash Serial No : %s as it is already Delivered" % (self.doc.name), raise_exception = 1) elif self.doc.status == 'In Store': webnotes.conn.set(self.doc, 'status', 'Not in Use') self.make_stock_ledger_entry(-1) + self.make_gl_entries(cancel=True) def on_cancel(self): @@ -121,6 +111,7 @@ class DocType(TransactionBase): def on_restore(self): self.make_stock_ledger_entry(1) + self.make_gl_entries() def on_rename(self, new, old): """rename serial_no text fields""" @@ -135,7 +126,16 @@ class DocType(TransactionBase): where name=%s""" % (dt[0], '%s', '%s'), ('\n'.join(serial_nos), item[0])) + def make_gl_entries(self, cancel=False): + if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")): + return - + from accounts.general_ledger import make_gl_entries + against_stock_account = self.get_company_default("stock_adjustment_account") + gl_entries = self.get_gl_entries_for_stock(against_stock_account, self.doc.purchase_rate) + + for entry in gl_entries: + entry["posting_date"] = self.doc.purchase_date - \ No newline at end of file + if gl_entries: + make_gl_entries(gl_entries, cancel) \ No newline at end of file diff --git a/stock/doctype/serial_no/test_serial_no.py b/stock/doctype/serial_no/test_serial_no.py index ef20de8f47..fb27aa9329 100644 --- a/stock/doctype/serial_no/test_serial_no.py +++ b/stock/doctype/serial_no/test_serial_no.py @@ -1,93 +1,102 @@ # ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - +# For license information, please see license.txt from __future__ import unicode_literals -import unittest -import webnotes -from webnotes.tests import insert_test_data - -company = webnotes.conn.get_default("company") +import webnotes, unittest class TestSerialNo(unittest.TestCase): - def setUp(self): - webnotes.conn.begin() - self.insert_test_data() - - def tearDown(self): - # print "Message Log:", "\n--\n".join(webnotes.message_log) - # print "Debug Log:", "\n--\n".join(webnotes.debug_log) - webnotes.conn.rollback() + def test_aii_gl_entries_for_serial_no_in_store(self): + webnotes.defaults.set_global_default("auto_inventory_accounting", 1) - def test_serialized_stock_entry(self): - data = [["2012-01-01", "01:00", "10001", 400, 400], - ["2012-01-01", "03:00", "10002", 500, 700], - ["2012-01-01", "04:00", "10003", 700, 700], - ["2012-01-01", "05:00", "10004", 1200, 800], - ["2012-01-01", "05:00", "10005", 800, 800], - ["2012-01-01", "02:00", "10006", 1200, 800], - ["2012-01-01", "06:00", "10007", 1500, 900]] - for d in data: - webnotes.bean([{ - "doctype": "Serial No", - "item_code": "Nebula 8", - "warehouse": "Default Warehouse", - "status": "In Store", - "sle_exists": 0, - "purchase_date": d[0], - "purchase_time": d[1], - "serial_no": d[2], - "purchase_rate": d[3], - "company": company, - }]).insert() + sr = webnotes.bean(copy=test_records[0]) + sr.doc.serial_no = "_Test Serial No 1" + sr.insert() + + stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company", + "stock_in_hand_account") + against_stock_account = webnotes.conn.get_value("Company", "_Test Company", + "stock_adjustment_account") + + # check stock ledger entries + sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` + where voucher_type = 'Serial No' and voucher_no = %s""", sr.doc.name, as_dict=1)[0] + self.assertTrue(sle) + self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty], + ["_Test Serialized Item", "_Test Warehouse", 1.0]) - for d in data: - res = webnotes.conn.sql("""select valuation_rate from `tabStock Ledger Entry` - where posting_date=%s and posting_time=%s and actual_qty=1 and serial_no=%s""", - (d[0], d[1], d[2])) - self.assertEquals(res[0][0], d[4]) + # check gl entries + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s + order by account desc""", sr.doc.name, as_dict=1) + self.assertTrue(gl_entries) - print "deleted" - webnotes.delete_doc("Serial No", "10002") + expected_values = [ + [stock_in_hand_account, 1000.0, 0.0], + [against_stock_account, 0.0, 1000.0] + ] - test_data = [["10001", 400, 400], - ["10003", 700, 766.666667], - ["10004", 1200, 875], - ["10005", 800, 860], - ["10006", 1200, 800], - ["10007", 1500, 966.666667]] + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[i][0], gle.account) + self.assertEquals(expected_values[i][1], gle.debit) + self.assertEquals(expected_values[i][2], gle.credit) - for d in test_data: - res = webnotes.conn.sql("""select valuation_rate from `tabStock Ledger Entry` - where actual_qty=1 and serial_no=%s""", (d[0],)) - self.assertEquals(res[0][0], d[2]) + sr.load_from_db() + self.assertEquals(sr.doc.sle_exists, 1) + + # save again + sr.save() + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s + order by account desc""", sr.doc.name, as_dict=1) + + for i, gle in enumerate(gl_entries): + self.assertEquals(expected_values[i][0], gle.account) + self.assertEquals(expected_values[i][1], gle.debit) + self.assertEquals(expected_values[i][2], gle.credit) + + # trash/cancel + sr.submit() + sr.cancel() + + gl_count = webnotes.conn.sql("""select count(name) from `tabGL Entry` + where voucher_type='Serial No' and voucher_no=%s and ifnull(is_cancelled, 'No') = 'Yes' + order by account asc, name asc""", sr.doc.name) + + self.assertEquals(gl_count[0][0], 4) + + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + + + def test_aii_gl_entries_for_serial_no_delivered(self): + webnotes.defaults.set_global_default("auto_inventory_accounting", 1) + + sr = webnotes.bean(copy=test_records[0]) + sr.doc.serial_no = "_Test Serial No 2" + sr.doc.status = "Delivered" + sr.insert() + + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Serial No' and voucher_no=%s + order by account desc""", sr.doc.name, as_dict=1) + self.assertFalse(gl_entries) + + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) - def insert_test_data(self): - # create default warehouse - if not webnotes.conn.exists("Warehouse", "Default Warehouse"): - webnotes.insert({"doctype": "Warehouse", - "warehouse_name": "Default Warehouse", - "warehouse_type": "Stores"}) - - # create UOM: Nos. - if not webnotes.conn.exists("UOM", "Nos"): - webnotes.insert({"doctype": "UOM", "uom_name": "Nos"}) - - # create item groups and items - insert_test_data("Item Group", - sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name'))) - - insert_test_data("Item") \ No newline at end of file + +test_records = [ + [ + { + "company": "_Test Company", + "doctype": "Serial No", + "serial_no": "_Test Serial No", + "status": "In Store", + "item_code": "_Test Serialized Item", + "item_group": "_Test Item Group", + "warehouse": "_Test Warehouse", + "purchase_rate": 1000.0, + "purchase_time": "11:37:39", + "purchase_date": "2013-02-26", + 'fiscal_year': "_Test Fiscal Year 2013" + } + ] +] \ No newline at end of file From f5784e785a67b7fcd30e8330fbc7560046e42a39 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 14:41:09 +0530 Subject: [PATCH 12/17] [accounts] [fix] aganist_jv query error --- accounts/doctype/journal_voucher/journal_voucher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 8b54f0fec2..15976b851e 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -375,7 +375,7 @@ def get_against_sales_invoice(doctype, txt, searchfield, start, page_len, filter (filters["account"], "%%%s%%" % txt, start, page_len)) def get_against_jv(doctype, txt, searchfield, start, page_len, filters): - return webnotes.conn.sql("""select name, posting_date, user_remark + return webnotes.conn.sql("""select jv.name, jv.posting_date, jv.user_remark from `tabJournal Voucher` jv, `tabJournal Voucher Detail` jv_detail where jv_detail.parent = jv.name and jv_detail.account = %s and docstatus = 1 and jv.%s like %s order by jv.name desc limit %s, %s""" % From 08c33bd6bcdc4d72dafe3e216cff4c7967ab3d9c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 26 Mar 2013 14:43:41 +0530 Subject: [PATCH 13/17] [accounts] [fix] aganist_jv query error --- accounts/doctype/journal_voucher/journal_voucher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 15976b851e..9b1ca7a105 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -377,7 +377,7 @@ def get_against_sales_invoice(doctype, txt, searchfield, start, page_len, filter def get_against_jv(doctype, txt, searchfield, start, page_len, filters): return webnotes.conn.sql("""select jv.name, jv.posting_date, jv.user_remark from `tabJournal Voucher` jv, `tabJournal Voucher Detail` jv_detail - where jv_detail.parent = jv.name and jv_detail.account = %s and docstatus = 1 + where jv_detail.parent = jv.name and jv_detail.account = %s and jv.docstatus = 1 and jv.%s like %s order by jv.name desc limit %s, %s""" % ("%s", searchfield, "%s", "%s", "%s"), (filters["account"], "%%%s%%" % txt, start, page_len)) \ No newline at end of file From 40dc9e83a5b6b5ee705cb16c03dd8db90d72ffb5 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 14:49:25 +0530 Subject: [PATCH 14/17] fixes in test cases and added fiscal year field to stock reco --- .../doctype/fiscal_year/test_fiscal_year.py | 5 +++ .../march_2013/p03_update_buying_amount.py | 4 +- .../march_2013/p07_update_valuation_rate.py | 2 +- patches/march_2013/p08_create_aii_accounts.py | 43 +++++++++++++++++-- stock/doctype/stock_entry/stock_entry.py | 3 +- stock/doctype/stock_entry/test_stock_entry.py | 7 +++ .../stock_ledger_entry/stock_ledger_entry.py | 22 +++++----- .../stock_reconciliation.py | 3 +- .../stock_reconciliation.txt | 23 +++++++--- .../test_stock_reconciliation.py | 15 ++++--- 10 files changed, 96 insertions(+), 31 deletions(-) diff --git a/accounts/doctype/fiscal_year/test_fiscal_year.py b/accounts/doctype/fiscal_year/test_fiscal_year.py index b209b39b96..456b15a89c 100644 --- a/accounts/doctype/fiscal_year/test_fiscal_year.py +++ b/accounts/doctype/fiscal_year/test_fiscal_year.py @@ -1,6 +1,11 @@ from __future__ import unicode_literals test_records = [ + [{ + "doctype": "Fiscal Year", + "year": "_Test Fiscal Year 2012", + "year_start_date": "2012-01-01" + }], [{ "doctype": "Fiscal Year", "year": "_Test Fiscal Year 2013", diff --git a/patches/march_2013/p03_update_buying_amount.py b/patches/march_2013/p03_update_buying_amount.py index e45a3dbd1c..ae0c5eab0b 100644 --- a/patches/march_2013/p03_update_buying_amount.py +++ b/patches/march_2013/p03_update_buying_amount.py @@ -3,8 +3,8 @@ import webnotes def execute(): dn_list = webnotes.conn.sql("""select name from `tabDelivery Note` where docstatus < 2""") for dn in dn_list: - webnotes.bean("Delivery Note", dn[0]).set_buying_amount() + webnotes.bean("Delivery Note", dn[0]).run_method("set_buying_amount") si_list = webnotes.conn.sql("""select name from `tabSales Invoice` where docstatus < 2""") for si in si_list: - webnotes.bean("Sales Invoice", si[0]).set_buying_amount() \ No newline at end of file + webnotes.bean("Sales Invoice", si[0]).run_method("set_buying_amount") \ No newline at end of file diff --git a/patches/march_2013/p07_update_valuation_rate.py b/patches/march_2013/p07_update_valuation_rate.py index 0bce8a47ec..51e556b328 100644 --- a/patches/march_2013/p07_update_valuation_rate.py +++ b/patches/march_2013/p07_update_valuation_rate.py @@ -1,7 +1,7 @@ import webnotes def execute(): - for purchase_invoice in webnotes.conn.sql("""select distinct parent + for purchase_invoice in webnotes.conn.sql_list("""select distinct parent from `tabPurchase Invoice Item` where docstatus = 1 and ifnull(valuation_rate, 0)=0"""): pi = webnotes.get_obj("Purchase Invoice", purchase_invoice) pi.calculate_taxes_and_totals() diff --git a/patches/march_2013/p08_create_aii_accounts.py b/patches/march_2013/p08_create_aii_accounts.py index c39c206c84..ff53d8b45a 100644 --- a/patches/march_2013/p08_create_aii_accounts.py +++ b/patches/march_2013/p08_create_aii_accounts.py @@ -1,24 +1,59 @@ import webnotes def execute(): + add_group_accounts() + add_ledger_accounts() + +def _check(parent_account, company): + def _get_root(is_pl_account, debit_or_credit): + res = webnotes.conn.sql("""select name from `tabAccount` + where company=%s and is_pl_account = %s and debit_or_credit = %s + and ifnull(parent_account, "") ="" """, (company, is_pl_account, debit_or_credit)) + return res and res[0][0] or None + + if not webnotes.conn.exists("Account", parent_account): + if parent_account.startswith("Current Assets"): + parent_account = _get_root("No", "Debit") + elif parent_account.startswith("Direct Expenses"): + parent_account = _get_root("Yes", "Debit") + elif parent_account.startswith("Current Liabilities"): + parent_account = _get_root("No", "Credit") + + return parent_account + + +def add_group_accounts(): accounts_to_add = [ ["Stock Assets", "Current Assets", "Group", ""], + ["Stock Expenses", "Direct Expenses", "Group", "Expense Account"], + ["Stock Liabilities", "Current Liabilities", "Group", ""], + ] + + add_accounts(accounts_to_add, _check) + + +def add_ledger_accounts(): + accounts_to_add = [ ["Stock In Hand", "Stock Assets", "Ledger", ""], ["Stock Debit But Not Billed", "Stock Assets", "Ledger", ""], - ["Stock Expenses", "Direct Expenses", "Group", "Expense Account"], ["Cost of Goods Sold", "Stock Expenses", "Ledger", "Expense Account"], ["Stock Adjustment", "Stock Expenses", "Ledger", "Expense Account"], ["Expenses Included In Valuation", "Stock Expenses", "Ledger", "Expense Account"], - ["Stock Liabilities", "Current Liabilities", "Group", ""], ["Stock Received But Not Billed", "Stock Liabilities", "Ledger", ""], ] + add_accounts(accounts_to_add) - for company, abbr in webnotes.conn.sql_list("""select name, abbr from `tabCompany`"""): + +def add_accounts(accounts_to_add, check_fn=None): + for company, abbr in webnotes.conn.sql("""select name, abbr from `tabCompany`"""): for account_name, parent_account_name, group_or_ledger, account_type in accounts_to_add: if not webnotes.conn.exists("Account", "%s - %s" % (account_name, abbr)): + parent_account = "%s - %s" % (parent_account_name, abbr) + if check_fn: + parent_account = check_fn(parent_account, company) account = webnotes.bean({ "doctype": "Account", "account_name": account_name, - "parent_account": "%s - %s" % (parent_account_name, abbr), + "parent_account": parent_account, "group_or_ledger": group_or_ledger, "account_type": account_type, "company": company diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index c437135ad6..a176188546 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -610,7 +610,8 @@ class DocType(StockController): 'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No', 'batch_no': cstr(d.batch_no).strip(), 'serial_no': cstr(d.serial_no).strip(), - "project": self.doc.project_name + "project": self.doc.project_name, + "fiscal_year": self.doc.fiscal_year, }) def get_cust_values(self): diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 3f8012a726..7c406f8e8c 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -230,6 +230,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Sales Return" se.doc.sales_invoice_no = si.doc.name se.doc.posting_date = "2013-03-10" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].item_code = "_Test Item Home Desktop 200" se.doclist[1].qty = returned_qty se.doclist[1].transfer_qty = returned_qty @@ -241,6 +242,7 @@ class TestStockEntry(unittest.TestCase): se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" se.doc.posting_date = "2013-03-10" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doc.sales_invoice_no = si.doc.name se.doclist[1].qty = returned_qty se.doclist[1].transfer_qty = returned_qty @@ -300,6 +302,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Sales Return" se.doc.delivery_note_no = dn.doc.name se.doc.posting_date = "2013-03-10" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty se.insert() @@ -399,6 +402,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Sales Return" se.doc.delivery_note_no = dn.doc.name se.doc.posting_date = "2013-03-10" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty se.insert() @@ -449,6 +453,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Purchase Return" se.doc.purchase_receipt_no = pr.doc.name se.doc.posting_date = "2013-03-01" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = 5 se.doclist[1].s_warehouse = "_Test Warehouse" se.insert() @@ -471,6 +476,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Purchase Return" se.doc.purchase_receipt_no = pr_docname se.doc.posting_date = "2013-03-01" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = 6 se.doclist[1].s_warehouse = "_Test Warehouse" @@ -547,6 +553,7 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Purchase Return" se.doc.purchase_receipt_no = pr.doc.name se.doc.posting_date = "2013-03-01" + se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = 5 se.doclist[1].s_warehouse = "_Test Warehouse" se.insert() diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 5ca7dd5bed..42621130d5 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -16,17 +16,13 @@ from __future__ import unicode_literals import webnotes -from webnotes import _ - +from webnotes import _, msgprint from webnotes.utils import cint, flt, getdate - -sql = webnotes.conn.sql -msgprint = webnotes.msgprint -from accounts.utils import get_fiscal_year +from webnotes.model.controller import DocListController class InvalidWarehouseCompany(Exception): pass -class DocType: +class DocType(DocListController): def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist @@ -39,12 +35,14 @@ class DocType: self.actual_amt_check() self.check_stock_frozen_date() self.scrub_posting_time() - self.doc.fiscal_year = get_fiscal_year(self.doc.posting_date)[0] + + from accounts.utils import validate_fiscal_year + validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date")) #check for item quantity available in stock 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]) + batch_bal = flt(webnotes.conn.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: @@ -77,11 +75,11 @@ class DocType: if self.doc.fields.get(k)==None: msgprint("Stock Ledger Entry: '%s' is mandatory" % k, raise_exception = 1) elif k == 'warehouse': - if not sql("select name from tabWarehouse where name = '%s'" % self.doc.fields.get(k)): + if not webnotes.conn.sql("select name from tabWarehouse where name = '%s'" % self.doc.fields.get(k)): msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1) def validate_item(self): - item_det = sql("""select name, has_batch_no, docstatus, + item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, ifnull(is_stock_item, 'No') from tabItem where name=%s""", self.doc.item_code) @@ -106,7 +104,7 @@ class DocType: raise Exception # check if batch belongs to item - if not sql("select name from `tabBatch` where item='%s' and name ='%s' and docstatus != 2" % (self.doc.item_code, self.doc.batch_no)): + if not webnotes.conn.sql("select name from `tabBatch` where item='%s' and name ='%s' and docstatus != 2" % (self.doc.item_code, self.doc.batch_no)): msgprint("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code), raise_exception = 1) # Nobody can do SL Entries where posting date is before freezing date except authorized person diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py index 13c8ee4880..56041797d5 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -252,7 +252,8 @@ class DocType(StockController): "voucher_no": self.doc.name, "company": self.doc.company, "is_cancelled": "No", - "voucher_detail_no": row.voucher_detail_no + "voucher_detail_no": row.voucher_detail_no, + "fiscal_year": self.doc.fiscal_year, }) args.update(opts) # create stock ledger entry diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/stock/doctype/stock_reconciliation/stock_reconciliation.txt index 9137cae972..760620bb73 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.txt +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-22 16:50:41", + "creation": "2013-03-26 06:51:17", "docstatus": 0, - "modified": "2013-03-18 12:48:42", + "modified": "2013-03-26 08:32:03", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,7 +30,6 @@ "permlevel": 0 }, { - "amend": 1, "cancel": 1, "create": 1, "doctype": "DocPerm", @@ -41,7 +40,6 @@ "permlevel": 0, "read": 1, "report": 1, - "role": "Material Manager", "submit": 1, "write": 1 }, @@ -81,6 +79,15 @@ "print_hide": 1, "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "fiscal_year", + "fieldtype": "Select", + "label": "Fiscal Year", + "options": "link:Fiscal Year", + "print_hide": 1, + "reqd": 1 + }, { "doctype": "DocField", "fieldname": "company", @@ -145,6 +152,12 @@ "print_hide": 1 }, { - "doctype": "DocPerm" + "amend": 0, + "doctype": "DocPerm", + "role": "Material Manager" + }, + { + "doctype": "DocPerm", + "role": "System Manager" } ] \ No newline at end of file diff --git a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index cebc6ffc53..1e7e716f1b 100644 --- a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -228,35 +228,40 @@ class TestStockReconciliation(unittest.TestCase): "voucher_type": "Stock Entry", "voucher_no": "TEST", "item_code": "_Test Item", "warehouse": "_Test Warehouse", "posting_date": "2012-12-12", "posting_time": "01:00", - "actual_qty": 20, "incoming_rate": 1000, "company": "_Test Company" + "actual_qty": 20, "incoming_rate": 1000, "company": "_Test Company", + "fiscal_year": "_Test Fiscal Year 2012", }, { "doctype": "Stock Ledger Entry", "__islocal": 1, "voucher_type": "Stock Entry", "voucher_no": "TEST", "item_code": "_Test Item", "warehouse": "_Test Warehouse", "posting_date": "2012-12-15", "posting_time": "02:00", - "actual_qty": 10, "incoming_rate": 700, "company": "_Test Company" + "actual_qty": 10, "incoming_rate": 700, "company": "_Test Company", + "fiscal_year": "_Test Fiscal Year 2012", }, { "doctype": "Stock Ledger Entry", "__islocal": 1, "voucher_type": "Stock Entry", "voucher_no": "TEST", "item_code": "_Test Item", "warehouse": "_Test Warehouse", "posting_date": "2012-12-25", "posting_time": "03:00", - "actual_qty": -15, "company": "_Test Company" + "actual_qty": -15, "company": "_Test Company", + "fiscal_year": "_Test Fiscal Year 2012", }, { "doctype": "Stock Ledger Entry", "__islocal": 1, "voucher_type": "Stock Entry", "voucher_no": "TEST", "item_code": "_Test Item", "warehouse": "_Test Warehouse", "posting_date": "2012-12-31", "posting_time": "08:00", - "actual_qty": -20, "company": "_Test Company" + "actual_qty": -20, "company": "_Test Company", + "fiscal_year": "_Test Fiscal Year 2012", }, { "doctype": "Stock Ledger Entry", "__islocal": 1, "voucher_type": "Stock Entry", "voucher_no": "TEST", "item_code": "_Test Item", "warehouse": "_Test Warehouse", "posting_date": "2013-01-05", "posting_time": "07:00", - "actual_qty": 15, "incoming_rate": 1200, "company": "_Test Company" + "actual_qty": 15, "incoming_rate": 1200, "company": "_Test Company", + "fiscal_year": "_Test Fiscal Year 2013", }, ] From b3b335c89e37da972222f2b668582189a24b6ee1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 15:03:13 +0530 Subject: [PATCH 15/17] fixes: make payment entry from sales invoice --- .../doctype/sales_invoice/sales_invoice.js | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js index 5cc09a0c10..31a7ce8de0 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.js +++ b/accounts/doctype/sales_invoice/sales_invoice.js @@ -307,35 +307,27 @@ cur_frm.cscript['Make Delivery Note'] = function() { ); } - - -// Make Bank Voucher Button -// ------------------------- -cur_frm.cscript.make_bank_voucher = function(doc, dt, dn) { - $c('accounts.get_default_bank_account', { company: cur_frm.doc.company }, function(r, rt) { - if(!r.exc) { - cur_frm.cscript.make_jv(cur_frm.doc, null, null, r.message); +cur_frm.cscript.make_bank_voucher = function() { + wn.call({ + method: "accounts.doctype.journal_voucher.journal_voucher.get_default_bank_cash_account", + args: { + "company": cur_frm.doc.company, + "voucher_type": "Bank Voucher" + }, + callback: function(r) { + cur_frm.cscript.make_jv(cur_frm.doc, null, null, r.message); } }); } - -/* ***************************** Get Query Functions ************************** */ - -// Debit To -// --------- cur_frm.fields_dict.debit_to.get_query = function(doc) { return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Debit" AND tabAccount.is_pl_account = "No" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"' } -// Cash/bank account -//------------------ cur_frm.fields_dict.cash_bank_account.get_query = function(doc) { return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Debit" AND tabAccount.is_pl_account = "No" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"' } -// Write off account -//------------------ cur_frm.fields_dict.write_off_account.get_query = function(doc) { return 'SELECT tabAccount.name FROM tabAccount WHERE tabAccount.debit_or_credit="Debit" AND tabAccount.is_pl_account = "Yes" AND tabAccount.group_or_ledger="Ledger" AND tabAccount.docstatus!=2 AND tabAccount.company="'+doc.company+'" AND tabAccount.%(key)s LIKE "%s"' } @@ -488,8 +480,9 @@ cur_frm.cscript.make_jv = function(doc, dt, dn, bank_account) { // credit to bank var d1 = wn.model.add_child(jv, 'Journal Voucher Detail', 'entries'); - d1.account = bank_account; + d1.account = bank_account.account; d1.debit = doc.outstanding_amount; + d1.balance = bank_account.balance; loaddoc('Journal Voucher', jv.name); } From 495db08104d6fc00e66dea58d88d96f71e4f6f29 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 15:24:56 +0530 Subject: [PATCH 16/17] copy expense account to all row if entered in one --- accounts/doctype/sales_invoice/sales_invoice.js | 17 ++++++++++------- stock/doctype/delivery_note/delivery_note.js | 11 +++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js index 31a7ce8de0..9532a54087 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.js +++ b/accounts/doctype/sales_invoice/sales_invoice.js @@ -421,17 +421,24 @@ cur_frm.fields_dict.delivery_note_main.get_query = function(doc) { cur_frm.cscript.income_account = function(doc, cdt, cdn){ + cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "income_account"); +} + +cur_frm.cscript.expense_account = function(doc, cdt, cdn){ + cur_frm.cscript.copy_account_in_all_row(doc, cdt, cdn, "expense_account"); +} + +cur_frm.cscript.copy_account_in_all_row = function(doc, cdt, cdn, fieldname) { var d = locals[cdt][cdn]; - if(d.income_account){ + if(d[fieldname]){ var cl = getchildren('Sales Invoice Item', doc.name, cur_frm.cscript.fname, doc.doctype); for(var i = 0; i < cl.length; i++){ - if(!cl[i].income_account) cl[i].income_account = d.income_account; + if(!cl[i][fieldname]) cl[i][fieldname] = d[fieldname]; } } refresh_field(cur_frm.cscript.fname); } - cur_frm.cscript.cost_center = function(doc, cdt, cdn){ var d = locals[cdt][cdn]; if(d.cost_center){ @@ -443,10 +450,6 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn){ refresh_field(cur_frm.cscript.fname); } -/* **************************************** Utility Functions *************************************** */ - -// Details Calculation -// -------------------- cur_frm.cscript.calc_adjustment_amount = function(doc,cdt,cdn) { var doc = locals[doc.doctype][doc.name]; var el = getchildren('Sales Invoice Advance',doc.name,'advance_adjustment_details'); diff --git a/stock/doctype/delivery_note/delivery_note.js b/stock/doctype/delivery_note/delivery_note.js index c7feb1b88e..61df6b0464 100644 --- a/stock/doctype/delivery_note/delivery_note.js +++ b/stock/doctype/delivery_note/delivery_note.js @@ -310,6 +310,17 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) { } } +cur_frm.cscript.expense_account = function(doc, cdt, cdn){ + var d = locals[cdt][cdn]; + if(d.expense_account) { + var cl = getchildren('Delivery Note Item', doc.name, cur_frm.cscript.fname, doc.doctype); + for(var i = 0; i < cl.length; i++){ + if(!cl[i].expense_account) cl[i].expense_account = d.expense_account; + } + } + refresh_field(cur_frm.cscript.fname); +} + // expense account cur_frm.fields_dict['delivery_note_details'].grid.get_field('expense_account').get_query = function(doc) { return { From 7483485ac06a3d1b3d08a4f682dceb05d118533b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 15:43:18 +0530 Subject: [PATCH 17/17] fixes: fetching from pos setting --- accounts/doctype/sales_invoice/sales_invoice.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index a8f76856e2..246dadad32 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -318,9 +318,8 @@ class DocType(SellingController): @property def pos_details(self): if not hasattr(self, "_pos_details"): - dtl = webnotes.conn.sql("""select income_account, warehouse, cost_center, - expense_account from `tabPOS Setting` where user = %s and company = %s""", - (webnotes.session['user'], self.doc.company), as_dict=1) + dtl = webnotes.conn.sql("""select * from `tabPOS Setting` where user = %s + and company = %s""", (webnotes.session['user'], self.doc.company), as_dict=1) if not dtl: dtl = webnotes.conn.sql("""select income_account, warehouse, cost_center, expense_account from `tabPOS Setting` where ifnull(user,'') = ''