From 68b0d54b4b814dd3781fad07c1a2bd43b46ad59f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 9 Jan 2014 17:25:55 +0530 Subject: [PATCH 1/6] Set default accounts in company related to perpetual inventory, only it is enabled --- setup/doctype/company/company.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py index 12281b4415..88d9dcaaa5 100644 --- a/setup/doctype/company/company.py +++ b/setup/doctype/company/company.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import webnotes from webnotes import _, msgprint -from webnotes.utils import cstr +from webnotes.utils import cstr, cint import webnotes.defaults @@ -237,21 +237,28 @@ class DocType: account.insert() def set_default_accounts(self): - accounts = { + def _set_default_accounts(accounts): + for a in accounts: + account_name = accounts[a] + " - " + self.doc.abbr + if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name): + webnotes.conn.set(self.doc, a, account_name) + + _set_default_accounts({ "default_income_account": "Sales", "default_expense_account": "Cost of Goods Sold", "receivables_group": "Accounts Receivable", "payables_group": "Accounts Payable", - "default_cash_account": "Cash", - "stock_received_but_not_billed": "Stock Received But Not Billed", - "stock_adjustment_account": "Stock Adjustment", - "expenses_included_in_valuation": "Expenses Included In Valuation" - } + "default_cash_account": "Cash" + }) + + if cint(webnotes.conn.get_value("Accounts Settings", None, "auto_accounting_for_stock")): + _set_default_accounts({ + "stock_received_but_not_billed": "Stock Received But Not Billed", + "stock_adjustment_account": "Stock Adjustment", + "expenses_included_in_valuation": "Expenses Included In Valuation" + }) + - for a in accounts: - account_name = accounts[a] + " - " + self.doc.abbr - if not self.doc.fields.get(a) and webnotes.conn.exists("Account", account_name): - webnotes.conn.set(self.doc, a, account_name) def create_default_cost_center(self): cc_list = [ From f3ded044e0686164f7271c130d8b2ad05bef7809 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 9 Jan 2014 17:38:50 +0530 Subject: [PATCH 2/6] Monthly Salary Register: Month is now optional --- hr/report/monthly_salary_register/monthly_salary_register.js | 2 +- hr/report/monthly_salary_register/monthly_salary_register.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hr/report/monthly_salary_register/monthly_salary_register.js b/hr/report/monthly_salary_register/monthly_salary_register.js index 5d3abccde9..32b4ef35fb 100644 --- a/hr/report/monthly_salary_register/monthly_salary_register.js +++ b/hr/report/monthly_salary_register/monthly_salary_register.js @@ -7,7 +7,7 @@ wn.query_reports["Monthly Salary Register"] = { "fieldname":"month", "label": wn._("Month"), "fieldtype": "Select", - "options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec", + "options": "\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec", "default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()], }, diff --git a/hr/report/monthly_salary_register/monthly_salary_register.py b/hr/report/monthly_salary_register/monthly_salary_register.py index 8bd8f36ac8..9b8a84fd91 100644 --- a/hr/report/monthly_salary_register/monthly_salary_register.py +++ b/hr/report/monthly_salary_register/monthly_salary_register.py @@ -59,8 +59,8 @@ def get_columns(salary_slips): def get_salary_slips(filters): conditions, filters = get_conditions(filters) - salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s""" % - conditions, filters, as_dict=1) + salary_slips = webnotes.conn.sql("""select * from `tabSalary Slip` where docstatus = 1 %s + order by employee, month""" % conditions, filters, as_dict=1) if not salary_slips: msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) + From 03463ef73bf373af5a2415b093018c1e978f6a9a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 10 Jan 2014 16:28:41 +0530 Subject: [PATCH 3/6] Move related property setters to custom field property --- patches/1401/__init__.py | 0 ...elated_property_setters_to_custom_field.py | 35 +++++++++++++++++++ patches/patch_list.py | 1 + 3 files changed, 36 insertions(+) create mode 100644 patches/1401/__init__.py create mode 100644 patches/1401/p01_move_related_property_setters_to_custom_field.py diff --git a/patches/1401/__init__.py b/patches/1401/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/patches/1401/p01_move_related_property_setters_to_custom_field.py b/patches/1401/p01_move_related_property_setters_to_custom_field.py new file mode 100644 index 0000000000..6b28553977 --- /dev/null +++ b/patches/1401/p01_move_related_property_setters_to_custom_field.py @@ -0,0 +1,35 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import webnotes +from webnotes.model.meta import get_field + +def execute(): + webnotes.reload_doc("core", "doctype", "custom_field") + + custom_fields = {} + for cf in webnotes.conn.sql("""select dt, fieldname from `tabCustom Field`""", as_dict=1): + custom_fields.setdefault(cf.dt, []).append(cf.fieldname) + + delete_list = [] + for ps in webnotes.conn.sql("""select * from `tabProperty Setter`""", as_dict=1): + if ps.field_name in custom_fields.get(ps.doc_type, []): + + if ps.property == "previous_field": + property_name = "insert_after" + + field_meta = get_field(ps.doc_type, ps.value) + property_value = field_meta.label if field_meta else "" + else: + property_name = ps.property + property_value =ps.value + + webnotes.conn.sql("""update `tabCustom Field` + set %s=%s where dt=%s and fieldname=%s""" % (property_name, '%s', '%s', '%s'), + (property_value, ps.doc_type, ps.field_name)) + + delete_list.append(ps.name) + + if delete_list: + webnotes.conn.sql("""delete from `tabProperty Setter` where name in (%s)""" % + ', '.join(['%s']*len(delete_list)), tuple(delete_list)) \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 608ba77168..e4d2975ea3 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -263,4 +263,5 @@ patch_list = [ "patches.1311.p08_email_digest_recipients", "execute:webnotes.delete_doc('DocType', 'Warehouse Type')", "patches.1312.p02_update_item_details_in_item_price", + "patches.1401.p01_move_related_property_setters_to_custom_field", ] \ No newline at end of file From 35a9d585b4f767c0b8447dafb6dc2b96819707bb Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 13 Jan 2014 12:24:27 +0530 Subject: [PATCH 4/6] Bank Reconciliation Statement: Show balance in debit or credit column based on account type --- .../bank_reconciliation_statement.js | 4 +- .../bank_reconciliation_statement.py | 53 ++++++++----------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js b/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js index b93f182f31..7f32e261c7 100644 --- a/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js +++ b/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js @@ -8,6 +8,7 @@ wn.query_reports["Bank Reconciliation Statement"] = { "label": wn._("Bank Account"), "fieldtype": "Link", "options": "Account", + "reqd": 1, "get_query": function() { return { "query": "accounts.utils.get_account_list", @@ -22,7 +23,8 @@ wn.query_reports["Bank Reconciliation Statement"] = { "fieldname":"report_date", "label": wn._("Date"), "fieldtype": "Date", - "default": get_today() + "default": get_today(), + "reqd": 1 }, ] } \ No newline at end of file diff --git a/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py b/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py index 431a6496d2..5672497189 100644 --- a/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py +++ b/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py @@ -3,13 +3,14 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint from webnotes.utils import flt def execute(filters=None): if not filters: filters = {} - - columns = get_columns() + + debit_or_credit = webnotes.conn.get_value("Account", filters["account"], "debit_or_credit") + + columns = get_columns() data = get_entries(filters) from accounts.utils import get_balance_on @@ -20,47 +21,39 @@ def execute(filters=None): total_debit += flt(d[4]) total_credit += flt(d[5]) - if webnotes.conn.get_value("Account", filters["account"], "debit_or_credit") == 'Debit': + if debit_or_credit == 'Debit': bank_bal = flt(balance_as_per_company) - flt(total_debit) + flt(total_credit) else: bank_bal = flt(balance_as_per_company) + flt(total_debit) - flt(total_credit) data += [ - ["", "", "", "Balance as per company books", balance_as_per_company, ""], + get_balance_row("Balance as per company books", balance_as_per_company, debit_or_credit), ["", "", "", "Amounts not reflected in bank", total_debit, total_credit], - ["", "", "", "Balance as per bank", bank_bal, ""] + get_balance_row("Balance as per bank", bank_bal, debit_or_credit) ] - - return columns, data + return columns, data def get_columns(): return ["Journal Voucher:Link/Journal Voucher:140", "Posting Date:Date:100", "Clearance Date:Date:110", "Against Account:Link/Account:200", "Debit:Currency:120", "Credit:Currency:120" ] - -def get_conditions(filters): - conditions = "" - if not filters.get("account"): - msgprint(_("Please select Bank Account"), raise_exception=1) - else: - conditions += " and jvd.account = %(account)s" - - if not filters.get("report_date"): - msgprint(_("Please select Date on which you want to run the report"), raise_exception=1) - else: - conditions += """ and jv.posting_date <= %(report_date)s - and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s""" - - return conditions def get_entries(filters): - conditions = get_conditions(filters) - entries = webnotes.conn.sql("""select jv.name, jv.posting_date, jv.clearance_date, - jvd.against_account, jvd.debit, jvd.credit - from `tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv - where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= '' %s - order by jv.name DESC""" % conditions, filters, as_list=1) + entries = webnotes.conn.sql("""select + jv.name, jv.posting_date, jv.clearance_date, jvd.against_account, jvd.debit, jvd.credit + from + `tabJournal Voucher Detail` jvd, `tabJournal Voucher` jv + where jvd.parent = jv.name and jv.docstatus=1 and ifnull(jv.cheque_no, '')!= '' + and jvd.account = %(account)s and jv.posting_date <= %(report_date)s + and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s + order by jv.name DESC""", filters, as_list=1) - return entries \ No newline at end of file + return entries + +def get_balance_row(label, amount, debit_or_credit): + if debit_or_credit == "Debit": + return ["", "", "", label, amount, 0] + else: + return ["", "", "", label, 0, amount] \ No newline at end of file From 14bf711d04e31cc5cb45ab0799ed6dab3a8ebcf5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 13 Jan 2014 13:28:07 +0530 Subject: [PATCH 5/6] Fixes in frozen accounts validation --- accounts/doctype/gl_entry/gl_entry.py | 3 ++- controllers/accounts_controller.py | 15 +++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py index d3c6317787..694917ffcd 100644 --- a/accounts/doctype/gl_entry/gl_entry.py +++ b/accounts/doctype/gl_entry/gl_entry.py @@ -146,11 +146,12 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" % (against_voucher_type, bal, against_voucher)) -def validate_frozen_account(account, adv_adj): +def validate_frozen_account(account, adv_adj=None): frozen_account = webnotes.conn.get_value("Account", account, "freeze_account") if frozen_account == 'Yes' and not adv_adj: frozen_accounts_modifier = webnotes.conn.get_value( 'Accounts Settings', None, 'frozen_accounts_modifier') + if not frozen_accounts_modifier: webnotes.throw(account + _(" is a frozen account. \ Either make the account active or assign role in Accounts Settings \ diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index a65bf260ee..8d33327569 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint, throw +from webnotes import _, throw from webnotes.utils import flt, cint, today, cstr from webnotes.model.code import get_obj from setup.utils import get_company_currency @@ -44,14 +44,13 @@ class AccountsController(TransactionBase): def validate_for_freezed_account(self): for fieldname in ["customer", "supplier"]: if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname): - accounts = webnotes.conn.get_values("Account", {"master_type": fieldname.title(), - "master_name": self.doc.fields[fieldname], "company": self.doc.company}, - "freeze_account", as_dict=1) - + accounts = webnotes.conn.get_values("Account", + {"master_type": fieldname.title(), "master_name": self.doc.fields[fieldname], + "company": self.doc.company}, "name") if accounts: - if not filter(lambda x: cstr(x.freeze_account) in ["", "No"], accounts): - throw(_("Account for this ") + fieldname + _(" has been freezed. ") + - self.doc.doctype + _(" can not be made.")) + from accounts.doctype.gl_entry.gl_entry import validate_frozen_account + for account in accounts: + validate_frozen_account(account[0]) def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("currency"): From c43d58ac79d6144eb6252ff611cc9605f290006d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 13 Jan 2014 17:55:24 +0530 Subject: [PATCH 6/6] Delete Property Setters for Custom Fields, and set them inside Custom Field --- ...elated_property_setters_to_custom_field.py | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/patches/1401/p01_move_related_property_setters_to_custom_field.py b/patches/1401/p01_move_related_property_setters_to_custom_field.py index 6b28553977..cf9221bcfd 100644 --- a/patches/1401/p01_move_related_property_setters_to_custom_field.py +++ b/patches/1401/p01_move_related_property_setters_to_custom_field.py @@ -2,34 +2,24 @@ # License: GNU General Public License v3. See license.txt import webnotes -from webnotes.model.meta import get_field def execute(): webnotes.reload_doc("core", "doctype", "custom_field") - custom_fields = {} - for cf in webnotes.conn.sql("""select dt, fieldname from `tabCustom Field`""", as_dict=1): - custom_fields.setdefault(cf.dt, []).append(cf.fieldname) - + cf_doclist = webnotes.get_doctype("Custom Field") + delete_list = [] - for ps in webnotes.conn.sql("""select * from `tabProperty Setter`""", as_dict=1): - if ps.field_name in custom_fields.get(ps.doc_type, []): - - if ps.property == "previous_field": - property_name = "insert_after" + for d in webnotes.conn.sql("""select cf.name as cf_name, ps.property, + ps.value, ps.name as ps_name + from `tabProperty Setter` ps, `tabCustom Field` cf + where ps.doctype_or_field = 'DocField' and ps.property != 'previous_field' + and ps.doc_type=cf.dt and ps.field_name=cf.fieldname""", as_dict=1): + if cf_doclist.get_field(d.property): + webnotes.conn.sql("""update `tabCustom Field` + set `%s`=%s where name=%s""" % (d.property, '%s', '%s'), (d.value, d.cf_name)) - field_meta = get_field(ps.doc_type, ps.value) - property_value = field_meta.label if field_meta else "" - else: - property_name = ps.property - property_value =ps.value + delete_list.append(d.ps_name) - webnotes.conn.sql("""update `tabCustom Field` - set %s=%s where dt=%s and fieldname=%s""" % (property_name, '%s', '%s', '%s'), - (property_value, ps.doc_type, ps.field_name)) - - delete_list.append(ps.name) - if delete_list: webnotes.conn.sql("""delete from `tabProperty Setter` where name in (%s)""" % ', '.join(['%s']*len(delete_list)), tuple(delete_list)) \ No newline at end of file