diff --git a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt index aab8e18491..09caf556c0 100644 --- a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt +++ b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt @@ -2,14 +2,14 @@ { "creation": "2011-12-21 11:08:55", "docstatus": 0, - "modified": "2013-09-13 17:17:47", + "modified": "2014-01-27 17:26:10", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Invoice", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n \n
RECEIPT NO: DATE:
M/s
\n\n
\n\n\n", + "html": "\n\t\n\n\t\t\n\t\t\n\n\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t
\n\t\t
\n\t\t
\n\t\t
\n\t\t
\n\t\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt b/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt index fc99597766..09fcb91476 100644 --- a/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt +++ b/erpnext/accounts/Print Format/Sales Invoice Classic/Sales Invoice Classic.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:27", "docstatus": 0, - "modified": "2013-08-07 20:14:53", + "modified": "2013-12-26 17:33:08", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Invoice", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt b/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt index 07946f7fcc..a85a11abc8 100644 --- a/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt +++ b/erpnext/accounts/Print Format/Sales Invoice Modern/Sales Invoice Modern.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:27", "docstatus": 0, - "modified": "2013-08-07 20:12:16", + "modified": "2013-12-26 17:33:05", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Invoice", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt b/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt index 57c02fe2ec..e0850e1e9a 100644 --- a/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt +++ b/erpnext/accounts/Print Format/Sales Invoice Spartan/Sales Invoice Spartan.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:27", "docstatus": 0, - "modified": "2013-08-07 19:50:51", + "modified": "2013-12-26 17:34:00", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Invoice", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/accounts/doctype/account/account.txt b/erpnext/accounts/doctype/account/account.txt index 50a6d6da37..e2622155eb 100644 --- a/erpnext/accounts/doctype/account/account.txt +++ b/erpnext/accounts/doctype/account/account.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-30 12:49:46", "docstatus": 0, - "modified": "2013-12-20 19:23:54", + "modified": "2014-01-20 17:48:20", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Account", @@ -254,8 +255,8 @@ "read_only": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -264,8 +265,8 @@ "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -274,8 +275,8 @@ "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -284,8 +285,8 @@ "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -294,16 +295,16 @@ "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 2, "role": "Auditor", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "export": 0, @@ -315,16 +316,16 @@ "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 2, "role": "Accounts Manager", "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 2, "role": "Accounts User", diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index a6e993863d..2475fdaf66 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import webnotes from webnotes import _ +from webnotes.utils import cint class DocType: def __init__(self, d, dl): @@ -14,7 +15,12 @@ class DocType: def on_update(self): webnotes.conn.set_default("auto_accounting_for_stock", self.doc.auto_accounting_for_stock) - if self.doc.auto_accounting_for_stock: + if cint(self.doc.auto_accounting_for_stock): + # set default perpetual account in company + for company in webnotes.conn.sql("select name from tabCompany"): + webnotes.bean("Company", company[0]).save() + + # Create account head for warehouses warehouse_list = webnotes.conn.sql("select name, company from tabWarehouse", as_dict=1) warehouse_with_no_company = [d.name for d in warehouse_list if not d.company] if warehouse_with_no_company: diff --git a/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt b/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt index 992c8bec81..48d6e7b54a 100644 --- a/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt +++ b/erpnext/accounts/doctype/budget_distribution/budget_distribution.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:05", "docstatus": 0, - "modified": "2013-12-20 19:23:58", + "modified": "2014-01-20 17:48:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,6 +24,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Budget Distribution", @@ -79,8 +80,8 @@ }, { "amend": 0, - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -88,6 +89,7 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "permlevel": 2 } diff --git a/erpnext/accounts/doctype/cost_center/cost_center.txt b/erpnext/accounts/doctype/cost_center/cost_center.txt index 3f1fab279d..66864bce4c 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.txt +++ b/erpnext/accounts/doctype/cost_center/cost_center.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-23 19:57:17", "docstatus": 0, - "modified": "2013-12-20 19:24:00", + "modified": "2014-01-20 17:48:30", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -185,15 +186,15 @@ "report_hide": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Accounts User", "write": 0 diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt b/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt index afa4858969..27fac8df25 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-22 16:50:25", "docstatus": 0, - "modified": "2013-12-20 19:24:08", + "modified": "2014-01-20 17:48:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -81,8 +81,9 @@ "reqd": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "report": 1, "role": "System Manager", @@ -90,6 +91,7 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "All" } diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index ff44d555ff..20cd8993bf 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/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 who can create / modify entries against this account")) elif frozen_accounts_modifier not in webnotes.user.get_roles(): diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js index 1eb8b1d730..342fa23afa 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js @@ -120,7 +120,8 @@ cur_frm.cscript.refresh = function(doc) { "voucher_no": doc.name, "from_date": doc.posting_date, "to_date": doc.posting_date, - "company": doc.company + "company": doc.company, + group_by_voucher: 0 }; wn.set_route("query-report", "General Ledger"); }, "icon-table"); diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.txt b/erpnext/accounts/doctype/journal_voucher/journal_voucher.txt index 9de2abb642..73710f935d 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.txt +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-25 10:53:52", "docstatus": 0, - "modified": "2013-12-20 19:24:11", + "modified": "2014-01-20 17:48:51", "modified_by": "Administrator", "owner": "Administrator" }, @@ -474,6 +474,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts User", "submit": 1, @@ -483,6 +484,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "submit": 1, @@ -492,6 +494,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Auditor", "submit": 0, diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py index 0c6cdb6a78..2904c7d695 100644 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py +++ b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py @@ -140,13 +140,13 @@ def gl_entry_details(doctype, txt, searchfield, start, page_len, filters): and ifnull(gle.%(account_type)s, 0) > 0 and (select ifnull(abs(sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))), 0) from `tabGL Entry` - where against_voucher_type = '%(dt)s' + where account = '%(acc)s' + and against_voucher_type = '%(dt)s' and against_voucher = gle.voucher_no and voucher_no != gle.voucher_no) - != abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0) - ) - and if(gle.voucher_type='Sales Invoice', (select is_pos from `tabSales Invoice` - where name=gle.voucher_no), 0)=0 + != abs(ifnull(gle.debit, 0) - ifnull(gle.credit, 0)) + and if(gle.voucher_type='Sales Invoice', ifnull((select is_pos from `tabSales Invoice` + where name=gle.voucher_no), 0), 0)=0 %(mcond)s ORDER BY gle.posting_date desc, gle.voucher_no desc limit %(start)s, %(page_len)s""" % { diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.txt b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.txt index 37a22a0497..170f49f1fa 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.txt +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:07", "docstatus": 0, - "modified": "2013-12-20 19:24:15", + "modified": "2014-01-20 17:48:59", "modified_by": "Administrator", "owner": "jai@webnotestech.com" }, @@ -27,6 +27,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/accounts/doctype/pos_setting/pos_setting.js b/erpnext/accounts/doctype/pos_setting/pos_setting.js index a1ebb59602..5c291b403a 100755 --- a/erpnext/accounts/doctype/pos_setting/pos_setting.js +++ b/erpnext/accounts/doctype/pos_setting/pos_setting.js @@ -7,7 +7,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn){ }); cur_frm.set_query("selling_price_list", function() { - return { filters: { buying_or_selling: "Selling" } }; + return { filters: { selling: 1 } }; }); } diff --git a/erpnext/accounts/doctype/pos_setting/pos_setting.txt b/erpnext/accounts/doctype/pos_setting/pos_setting.txt index 22edcddea3..1c9e0bf844 100755 --- a/erpnext/accounts/doctype/pos_setting/pos_setting.txt +++ b/erpnext/accounts/doctype/pos_setting/pos_setting.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 12:15:51", "docstatus": 0, - "modified": "2013-12-20 19:24:16", + "modified": "2014-01-15 16:23:58", "modified_by": "Administrator", "owner": "Administrator" }, @@ -156,7 +156,7 @@ "reqd": 1 }, { - "depends_on": "eval:sys_defaults.auto_accounting_for_stock", + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", "doctype": "DocField", "fieldname": "expense_account", "fieldtype": "Link", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index aa3b45f899..dda621950c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -35,7 +35,8 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ "voucher_no": doc.name, "from_date": doc.posting_date, "to_date": doc.posting_date, - "company": doc.company + "company": doc.company, + group_by_voucher: 0 }; wn.set_route("query-report", "General Ledger"); }, "icon-table"); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index f6b6ef4035..db42a12753 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -302,6 +302,7 @@ class DocType(BuyingController): self.make_gl_entries() self.update_against_document_in_jv() self.update_prevdoc_status() + self.update_billing_status_for_zero_amount_refdoc("Purchase Order") def make_gl_entries(self): auto_accounting_for_stock = \ @@ -350,7 +351,6 @@ class DocType(BuyingController): # item gl entries stock_item_and_auto_accounting_for_stock = False stock_items = self.get_stock_items() - # rounding_diff = 0.0 for item in self.doclist.get({"parentfield": "entries"}): if auto_accounting_for_stock and item.item_code in stock_items: if flt(item.valuation_rate): @@ -359,12 +359,8 @@ class DocType(BuyingController): # expense will be booked in sales invoice stock_item_and_auto_accounting_for_stock = True - valuation_amt = item.amount + item.item_tax_amount + item.rm_supp_cost - - # rounding_diff += (flt(item.amount, self.precision("amount", item)) + - # flt(item.item_tax_amount, self.precision("item_tax_amount", item)) + - # flt(item.rm_supp_cost, self.precision("rm_supp_cost", item)) - - # valuation_amt) + valuation_amt = flt(item.amount + item.item_tax_amount + item.rm_supp_cost, + self.precision("amount", item)) gl_entries.append( self.get_gl_dict({ @@ -392,12 +388,6 @@ class DocType(BuyingController): # this will balance out valuation amount included in cost of goods sold expenses_included_in_valuation = \ self.get_company_default("expenses_included_in_valuation") - - # if rounding_diff: - # import operator - # cost_center_with_max_value = max(valuation_tax.iteritems(), - # key=operator.itemgetter(1))[0] - # valuation_tax[cost_center_with_max_value] -= flt(rounding_diff) for cost_center, amount in valuation_tax.items(): gl_entries.append( @@ -432,7 +422,7 @@ class DocType(BuyingController): remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_voucher") self.update_prevdoc_status() - + self.update_billing_status_for_zero_amount_refdoc("Purchase Order") self.make_cancel_gl_entries() def on_update(self): diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt index 6df4df40d3..5dbe9f649e 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2013-12-20 19:24:18", + "modified": "2014-01-20 17:49:04", "modified_by": "Administrator", "owner": "Administrator" }, @@ -771,6 +771,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Accounts User", "submit": 0, @@ -780,6 +781,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Purchase User", "submit": 0, @@ -789,6 +791,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Supplier", "submit": 0, @@ -798,6 +801,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "submit": 1, @@ -807,6 +811,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Auditor", "submit": 0, diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt index 1430c43d2e..bdaf00cf03 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:08", "docstatus": 0, - "modified": "2013-12-20 19:24:24", + "modified": "2014-01-20 17:49:14", "modified_by": "Administrator", "owner": "wasim@webnotestech.com" }, @@ -25,6 +25,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -78,15 +79,15 @@ }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Purchase Manager", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Master Manager", "write": 1 diff --git a/erpnext/accounts/doctype/sales_invoice/pos.js b/erpnext/accounts/doctype/sales_invoice/pos.js index c432765981..991dad8b5a 100644 --- a/erpnext/accounts/doctype/sales_invoice/pos.js +++ b/erpnext/accounts/doctype/sales_invoice/pos.js @@ -19,8 +19,10 @@ erpnext.POS = Class.extend({ \ \ \ - \ - \ + \ + \ + \ + \ \ \ \ @@ -30,12 +32,14 @@ erpnext.POS = Class.extend({ \
\
\ -
ItemQtyItemQtyRate
\ - \ - \ - \ - \ -
Net Total
\ +
\ + \ + \ + \ + \ + \ +
Net Total
\ +
\ \ +
\ + \ + \ + \ + \ + \ + \ +
Discount Amount\ + \ +
\ +
\
\ \ \ @@ -60,10 +76,16 @@ erpnext.POS = Class.extend({ \ \

\ - \ - \ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\

\ \
\ @@ -82,7 +104,11 @@ erpnext.POS = Class.extend({ me.refresh(); }); - this.call_function("delete-items", function() {me.remove_selected_item();}); + this.wrapper.find('input.discount-amount').on("change", function() { + wn.model.set_value(me.frm.doctype, me.frm.docname, "discount_amount", this.value); + }); + + this.call_function("remove-items", function() {me.remove_selected_items();}); this.call_function("make-payment", function() {me.make_payment();}); }, check_transaction_type: function() { @@ -101,6 +127,7 @@ erpnext.POS = Class.extend({ this.party = party; this.price_list = (party == "Customer" ? this.frm.doc.selling_price_list : this.frm.doc.buying_price_list); + this.price_list_field = (party == "Customer" ? "selling_price_list" : "buying_price_list"); this.sales_or_purchase = (party == "Customer" ? "Sales" : "Purchase"); this.net_total = "net_total_" + export_or_import; this.grand_total = "grand_total_" + export_or_import; @@ -112,9 +139,9 @@ erpnext.POS = Class.extend({ }, make: function() { this.make_party(); - this.make_item_group(); - this.make_search(); this.make_barcode(); + this.make_search(); + this.make_item_group(); this.make_item_list(); }, make_party: function() { @@ -137,23 +164,23 @@ erpnext.POS = Class.extend({ me.party.toLowerCase(), this.value); }); }, - make_item_group: function() { + make_barcode: function() { var me = this; - this.item_group = wn.ui.form.make_control({ + this.barcode = wn.ui.form.make_control({ df: { - "fieldtype": "Link", - "options": "Item Group", - "label": "Item Group", - "fieldname": "pos_item_group", - "placeholder": "Item Group" + "fieldtype": "Data", + "label": "Barcode", + "fieldname": "pos_barcode", + "placeholder": "Barcode / Serial No" }, - parent: this.wrapper.find(".item-group-area"), + parent: this.wrapper.find(".barcode-area"), only_input: true, }); - this.item_group.make_input(); - this.item_group.$input.on("change", function() { - if(!me.item_group.autocomplete_open) - me.make_item_list(); + this.barcode.make_input(); + this.barcode.$input.on("keypress", function() { + if(me.barcode_timeout) + clearTimeout(me.barcode_timeout); + me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000); }); }, make_search: function() { @@ -176,23 +203,23 @@ erpnext.POS = Class.extend({ me.item_timeout = setTimeout(function() { me.make_item_list(); }, 1000); }); }, - make_barcode: function() { + make_item_group: function() { var me = this; - this.barcode = wn.ui.form.make_control({ + this.item_group = wn.ui.form.make_control({ df: { - "fieldtype": "Data", - "label": "Barcode", - "fieldname": "pos_barcode", - "placeholder": "Barcode / Serial No" + "fieldtype": "Link", + "options": "Item Group", + "label": "Item Group", + "fieldname": "pos_item_group", + "placeholder": "Item Group" }, - parent: this.wrapper.find(".barcode-area"), + parent: this.wrapper.find(".item-group-area"), only_input: true, }); - this.barcode.make_input(); - this.barcode.$input.on("keypress", function() { - if(me.barcode_timeout) - clearTimeout(me.barcode_timeout); - me.barcode_timeout = setTimeout(function() { me.add_item_thru_barcode(); }, 1000); + this.item_group.make_input(); + this.item_group.$input.on("change", function() { + if(!me.item_group.autocomplete_open) + me.make_item_list(); }); }, make_item_list: function() { @@ -261,22 +288,17 @@ erpnext.POS = Class.extend({ this.frm.cscript.fname, this.frm.doctype), function(i, d) { if (d.item_code == item_code) { caught = true; - if (serial_no) { - d.serial_no += '\n' + serial_no; - me.frm.script_manager.trigger("serial_no", d.doctype, d.name); - } - else { - d.qty += 1; - me.frm.script_manager.trigger("qty", d.doctype, d.name); - } + if (serial_no) + wn.model.set_value(d.doctype, d.name, "serial_no", d.serial_no + '\n' + serial_no); + else + wn.model.set_value(d.doctype, d.name, "qty", d.qty + 1); } }); } // if item not found then add new item - if (!caught) { + if (!caught) this.add_new_item_to_grid(item_code, serial_no); - } this.refresh(); this.refresh_search_box(); @@ -311,16 +333,18 @@ erpnext.POS = Class.extend({ wn.model.clear_doc(d.doctype, d.name); me.refresh_grid(); } else { - d.qty = qty; - me.frm.script_manager.trigger("qty", d.doctype, d.name); + wn.model.set_value(d.doctype, d.name, "qty", qty); } } }); - me.refresh(); + this.refresh(); }, refresh: function() { var me = this; + + this.refresh_item_list(); this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]); + this.wrapper.find('input.discount-amount').val(this.frm.doc.discount_amount); this.barcode.set_input(""); this.show_items_in_item_cart(); @@ -333,7 +357,7 @@ erpnext.POS = Class.extend({ } this.disable_text_box_and_button(); - this.make_payment_button(); + this.hide_payment_button(); // If quotation to is not Customer then remove party if (this.frm.doctype == "Quotation") { @@ -342,6 +366,14 @@ erpnext.POS = Class.extend({ this.make_party(); } }, + refresh_item_list: function() { + var me = this; + // refresh item list on change of price list + if (this.frm.doc[this.price_list_field] != this.price_list) { + this.price_list = this.frm.doc[this.price_list_field]; + this.make_item_list(); + } + }, show_items_in_item_cart: function() { var me = this; var $items = this.wrapper.find("#cart tbody").empty(); @@ -351,8 +383,18 @@ erpnext.POS = Class.extend({ $(repl('
\ \ - \ + \ + \ \ ', { @@ -364,27 +406,31 @@ erpnext.POS = Class.extend({ } )).appendTo($items); }); + + this.wrapper.find("input.qty").on("focus", function() { + $(this).select(); + }); }, show_taxes: function() { var me = this; var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges", this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype); $(this.wrapper).find(".tax-table") - .toggle((taxes && taxes.length && - flt(me.frm.doc.other_charges_total_export || - me.frm.doc.other_charges_added_import) != 0.0) ? true : false) + .toggle((taxes && taxes.length) ? true : false) .find("tbody").empty(); $.each(taxes, function(i, d) { - $(repl('\ - \ - \ - ', { - description: d.description, - rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")), - tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate), - me.frm.doc.currency) - })).appendTo(".tax-table tbody"); + if (d.tax_amount) { + $(repl('\ + \ + \ + ', { + description: d.description, + rate: ((d.charge_type == "Actual") ? '' : ("(" + d.rate + "%)")), + tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate), + me.frm.doc.currency) + })).appendTo(".tax-table tbody"); + } }); }, set_totals: function() { @@ -399,10 +445,16 @@ erpnext.POS = Class.extend({ // append quantity to the respective item after change from input box $(this.wrapper).find("input.qty").on("change", function() { - var item_code = $(this).closest("tr")[0].id; + var item_code = $(this).closest("tr").attr("id"); me.update_qty(item_code, $(this).val()); }); + // increase/decrease qty on plus/minus button + $(this.wrapper).find(".increase-qty, .decrease-qty").on("click", function() { + var tr = $(this).closest("tr"); + me.increase_decrease_qty(tr, $(this).attr("class")); + }); + // on td click toggle the highlighting of row $(this.wrapper).find("#cart tbody tr td").on("click", function() { var row = $(this).closest("tr"); @@ -420,6 +472,15 @@ erpnext.POS = Class.extend({ me.refresh_delete_btn(); this.barcode.$input.focus(); }, + increase_decrease_qty: function(tr, operation) { + var item_code = tr.attr("id"); + var item_qty = cint(tr.find("input.qty").val()); + + if (operation == "increase-qty") + this.update_qty(item_code, item_qty + 1); + else if (operation == "decrease-qty" && item_qty != 1) + this.update_qty(item_code, item_qty - 1); + }, disable_text_box_and_button: function() { var me = this; // if form is submitted & cancelled then disable all input box & buttons @@ -427,7 +488,7 @@ erpnext.POS = Class.extend({ $(this.wrapper).find('input, button').each(function () { $(this).prop('disabled', true); }); - $(this.wrapper).find(".delete-items").hide(); + $(this.wrapper).find(".remove-items").hide(); $(this.wrapper).find(".make-payment").hide(); } else { @@ -437,14 +498,14 @@ erpnext.POS = Class.extend({ $(this.wrapper).find(".make-payment").show(); } }, - make_payment_button: function() { + hide_payment_button: function() { var me = this; // Show Make Payment button only in Sales Invoice if (this.frm.doctype != "Sales Invoice") $(this.wrapper).find(".make-payment").hide(); }, refresh_delete_btn: function() { - $(this.wrapper).find(".delete-items").toggle($(".item-cart .warning").length ? true : false); + $(this.wrapper).find(".remove-items").toggle($(".item-cart .warning").length ? true : false); }, add_item_thru_barcode: function() { var me = this; @@ -466,7 +527,7 @@ erpnext.POS = Class.extend({ } }); }, - remove_selected_item: function() { + remove_selected_items: function() { var me = this; var selected_items = []; var no_of_items = $(this.wrapper).find("#cart tbody tr").length; @@ -487,9 +548,11 @@ erpnext.POS = Class.extend({ } } }); + this.refresh_grid(); }, refresh_grid: function() { + this.frm.dirty(); this.frm.fields_dict[this.frm.cscript.fname].grid.refresh(); this.frm.script_manager.trigger("calculate_taxes_and_totals"); this.refresh(); diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 010ef63c0b..17fd48d29a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -25,7 +25,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte } // toggle to pos view if is_pos is 1 in user_defaults - if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || cur_frm.doc.is_pos)) { + if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || this.frm.doc.is_pos)) { if(this.frm.doc.__islocal && !this.frm.doc.amended_from && !this.frm.doc.customer) { this.frm.set_value("is_pos", 1); this.is_pos(function() { @@ -54,7 +54,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte "voucher_no": doc.name, "from_date": doc.posting_date, "to_date": doc.posting_date, - "company": doc.company + "company": doc.company, + group_by_voucher: 0 }; wn.set_route("query-report", "General Ledger"); }, "icon-table"); @@ -145,8 +146,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte me.set_default_values(); me.set_dynamic_labels(); me.calculate_taxes_and_totals(); - - if(callback_fn) callback_fn() + + if(callback_fn) callback_fn(); } } }); @@ -253,8 +254,8 @@ cur_frm.cscript.hide_fields = function(doc) { cur_frm.cscript.mode_of_payment = function(doc) { return cur_frm.call({ - method: "get_bank_cash_account", - args: { mode_of_payment: doc.mode_of_payment } + method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account", + args: { mode_of_payment: doc.mode_of_payment }, }); } @@ -267,9 +268,6 @@ cur_frm.cscript.is_opening = function(doc, dt, dn) { if (doc.is_opening == 'Yes') unhide_field('aging_date'); } -//Make Delivery Note Button -//----------------------------- - cur_frm.cscript['Make Delivery Note'] = function() { wn.model.open_mapped_doc({ method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.make_delivery_note", @@ -347,7 +345,7 @@ cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) { // -------------------------------- cur_frm.set_query("income_account", "entries", function(doc) { return{ - query: "accounts.doctype.sales_invoice.sales_invoice.get_income_account", + query: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_income_account", filters: {'company': doc.company} } }); diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 10255fa4d8..2af744a49c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -88,6 +88,7 @@ class DocType(SellingController): self.update_status_updater_args() self.update_prevdoc_status() + self.update_billing_status_for_zero_amount_refdoc("Sales Order") # this sequence because outstanding may get -ve self.make_gl_entries() @@ -114,6 +115,7 @@ class DocType(SellingController): self.update_status_updater_args() self.update_prevdoc_status() + self.update_billing_status_for_zero_amount_refdoc("Sales Order") self.make_cancel_gl_entries() @@ -270,12 +272,9 @@ class DocType(SellingController): item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% d.item_code) acc = webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account) if not acc: - msgprint("Account: "+d.income_account+" does not exist in the system") - raise Exception + msgprint("Account: "+d.income_account+" does not exist in the system", raise_exception=True) elif item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset Account': - msgprint("Please select income head with account type 'Fixed Asset Account' as Item %s is an asset item" % d.item_code) - raise Exception - + msgprint("Please select income head with account type 'Fixed Asset Account' as Item %s is an asset item" % d.item_code, raise_exception=True) def validate_with_previous_doc(self): super(DocType, self).validate_with_previous_doc(self.tname, { @@ -508,12 +507,12 @@ class DocType(SellingController): def make_tax_gl_entries(self, gl_entries): for tax in self.doclist.get({"parentfield": "other_charges"}): - if flt(tax.tax_amount): + if flt(tax.tax_amount_after_discount_amount): gl_entries.append( self.get_gl_dict({ "account": tax.account_head, "against": self.doc.debit_to, - "credit": flt(tax.tax_amount), + "credit": flt(tax.tax_amount_after_discount_amount), "remarks": self.doc.remarks, "cost_center": tax.cost_center }) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt index 7de68a06ed..a3be27dcf8 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:05", "docstatus": 0, - "modified": "2013-12-20 19:24:29", + "modified": "2014-01-20 17:49:20", "modified_by": "Administrator", "owner": "Administrator" }, @@ -455,6 +455,14 @@ "print_hide": 1, "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "Company:company:default_currency", + "print_hide": 0 + }, { "doctype": "DocField", "fieldname": "totals", @@ -1094,7 +1102,7 @@ "fieldtype": "Select", "label": "Recurring Type", "no_copy": 1, - "options": "Monthly\nQuarterly\nHalf-yearly\nYearly", + "options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly", "print_hide": 1, "read_only": 0 }, @@ -1206,6 +1214,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "submit": 1, @@ -1215,12 +1224,14 @@ "amend": 1, "cancel": 0, "create": 1, + "delete": 0, "doctype": "DocPerm", "role": "Accounts User", "submit": 1, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Customer" } diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index c68b97a3b2..3092477e4f 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -44,7 +44,6 @@ class TestSalesInvoice(unittest.TestCase): def test_sales_invoice_calculation_base_currency(self): si = webnotes.bean(copy=test_records[2]) - si.run_method("calculate_taxes_and_totals") si.insert() expected_values = { @@ -136,7 +135,114 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(si.doc.grand_total, 1627.05) self.assertEquals(si.doc.grand_total_export, 32.54) + + def test_sales_invoice_discount_amount(self): + si = webnotes.bean(copy=test_records[3]) + si.doc.discount_amount = 104.95 + si.doclist.append({ + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "charge_type": "On Previous Row Amount", + "account_head": "_Test Account Service Tax - _TC", + "cost_center": "_Test Cost Center - _TC", + "description": "Service Tax", + "rate": 10, + "row_id": 8, + "idx": 9 + }) + si.insert() + + expected_values = { + "keys": ["ref_rate", "adj_rate", "export_rate", "export_amount", + "base_ref_rate", "basic_rate", "amount"], + "_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 50, 50, 465.37], + "_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 150, 150, 698.08], + } + + # check if children are saved + self.assertEquals(len(si.doclist.get({"parentfield": "entries"})), + len(expected_values)-1) + + # check if item values are calculated + for d in si.doclist.get({"parentfield": "entries"}): + for i, k in enumerate(expected_values["keys"]): + self.assertEquals(d.fields.get(k), expected_values[d.item_code][i]) + + # check net total + self.assertEquals(si.doc.net_total, 1163.45) + self.assertEquals(si.doc.net_total_export, 1578.3) + + # check tax calculation + expected_values = { + "keys": ["tax_amount", "tax_amount_after_discount_amount", "total"], + "_Test Account Excise Duty - _TC": [140, 130.31, 1293.76], + "_Test Account Education Cess - _TC": [2.8, 2.61, 1296.37], + "_Test Account S&H Education Cess - _TC": [1.4, 1.31, 1297.68], + "_Test Account CST - _TC": [27.88, 25.96, 1323.64], + "_Test Account VAT - _TC": [156.25, 145.43, 1469.07], + "_Test Account Customs Duty - _TC": [125, 116.35, 1585.42], + "_Test Account Shipping Charges - _TC": [100, 100, 1685.42], + "_Test Account Discount - _TC": [-180.33, -168.54, 1516.88], + "_Test Account Service Tax - _TC": [-18.03, -16.88, 1500] + } + + for d in si.doclist.get({"parentfield": "other_charges"}): + for i, k in enumerate(expected_values["keys"]): + self.assertEquals(d.fields.get(k), expected_values[d.account_head][i]) + self.assertEquals(si.doc.grand_total, 1500) + self.assertEquals(si.doc.grand_total_export, 1500) + + def test_discount_amount_gl_entry(self): + si = webnotes.bean(copy=test_records[3]) + si.doc.discount_amount = 104.95 + si.doclist.append({ + "doctype": "Sales Taxes and Charges", + "parentfield": "other_charges", + "charge_type": "On Previous Row Amount", + "account_head": "_Test Account Service Tax - _TC", + "cost_center": "_Test Cost Center - _TC", + "description": "Service Tax", + "rate": 10, + "row_id": 8, + "idx": 9 + }) + si.insert() + si.submit() + + gl_entries = webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s + order by account asc""", si.doc.name, as_dict=1) + + self.assertTrue(gl_entries) + + expected_values = sorted([ + [si.doc.debit_to, 1500, 0.0], + [test_records[3][1]["income_account"], 0.0, 1163.45], + [test_records[3][3]["account_head"], 0.0, 130.31], + [test_records[3][4]["account_head"], 0.0, 2.61], + [test_records[3][5]["account_head"], 0.0, 1.31], + [test_records[3][6]["account_head"], 0.0, 25.96], + [test_records[3][7]["account_head"], 0.0, 145.43], + [test_records[3][8]["account_head"], 0.0, 116.35], + [test_records[3][9]["account_head"], 0.0, 100], + [test_records[3][10]["account_head"], 168.54, 0.0], + ["_Test Account Service Tax - _TC", 16.88, 0.0], + ]) + + 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) + + # cancel + si.cancel() + + gle = webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type='Sales Invoice' and voucher_no=%s""", si.doc.name) + + self.assertFalse(gle) + def test_inclusive_rate_validations(self): si = webnotes.bean(copy=test_records[2]) for i, tax in enumerate(si.doclist.get({"parentfield": "other_charges"})): @@ -148,16 +254,15 @@ class TestSalesInvoice(unittest.TestCase): si.doclist[i].included_in_print_rate = 1 # tax type "Actual" cannot be inclusive - self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals") + self.assertRaises(webnotes.ValidationError, si.insert) # taxes above included type 'On Previous Row Total' should also be included si.doclist[3].included_in_print_rate = 0 - self.assertRaises(webnotes.ValidationError, si.run_method, "calculate_taxes_and_totals") + self.assertRaises(webnotes.ValidationError, si.insert) def test_sales_invoice_calculation_base_currency_with_tax_inclusive_price(self): # prepare si = webnotes.bean(copy=test_records[3]) - si.run_method("calculate_taxes_and_totals") si.insert() expected_values = { @@ -195,7 +300,7 @@ class TestSalesInvoice(unittest.TestCase): for d in si.doclist.get({"parentfield": "other_charges"}): for i, k in enumerate(expected_values["keys"]): - self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i]) + self.assertEquals(d.fields.get(k), expected_values[d.account_head][i]) self.assertEquals(si.doc.grand_total, 1622.98) self.assertEquals(si.doc.grand_total_export, 1622.98) @@ -211,7 +316,6 @@ class TestSalesInvoice(unittest.TestCase): si.doclist[2].adj_rate = 20 si.doclist[9].rate = 5000 - si.run_method("calculate_taxes_and_totals") si.insert() expected_values = { @@ -249,7 +353,7 @@ class TestSalesInvoice(unittest.TestCase): for d in si.doclist.get({"parentfield": "other_charges"}): for i, k in enumerate(expected_values["keys"]): - self.assertEquals(flt(d.fields.get(k), 6), expected_values[d.account_head][i]) + self.assertEquals(d.fields.get(k), expected_values[d.account_head][i]) self.assertEquals(si.doc.grand_total, 65205.16) self.assertEquals(si.doc.grand_total_export, 1304.1) @@ -403,7 +507,6 @@ class TestSalesInvoice(unittest.TestCase): pr = webnotes.bean(copy=pr_test_records[0]) pr.doc.naming_series = "_T-Purchase Receipt-" pr.doclist[1].warehouse = "_Test Warehouse No Account - _TC" - pr.run_method("calculate_taxes_and_totals") pr.insert() pr.submit() @@ -448,7 +551,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertFalse(gle) set_perpetual_inventory(0) - def test_sales_invoice_gl_entry_with_aii_no_item_code(self): + def test_sales_invoice_gl_entry_with_aii_no_item_code(self): self.clear_stock_account_balance() set_perpetual_inventory() @@ -508,7 +611,6 @@ class TestSalesInvoice(unittest.TestCase): as pr_test_records pr = webnotes.bean(copy=pr_test_records[0]) pr.doc.naming_series = "_T-Purchase Receipt-" - pr.run_method("calculate_taxes_and_totals") pr.insert() pr.submit() @@ -565,16 +667,17 @@ class TestSalesInvoice(unittest.TestCase): where against_invoice=%s""", si.doc.name)) def test_recurring_invoice(self): - from webnotes.utils import now_datetime, get_first_day, get_last_day, add_to_date - today = now_datetime().date() - + from webnotes.utils import get_first_day, get_last_day, add_to_date, nowdate, getdate + from erpnext.accounts.utils import get_fiscal_year + today = nowdate() base_si = webnotes.bean(copy=test_records[0]) base_si.doc.fields.update({ "convert_into_recurring_invoice": 1, "recurring_type": "Monthly", "notification_email_address": "test@example.com, test1@example.com, test2@example.com", - "repeat_on_day_of_month": today.day, + "repeat_on_day_of_month": getdate(today).day, "posting_date": today, + "fiscal_year": get_fiscal_year(today)[0], "invoice_period_from_date": get_first_day(today), "invoice_period_to_date": get_last_day(today) }) diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt index 49df5f7291..8bb154cb7f 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt +++ b/erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-24 11:39:32", "docstatus": 0, - "modified": "2013-12-31 17:51:47", + "modified": "2014-01-03 15:04:25", "modified_by": "Administrator", "owner": "Administrator" }, @@ -132,12 +132,21 @@ "report_hide": 1, "width": "150px" }, + { + "doctype": "DocField", + "fieldname": "tax_amount_after_discount_amount", + "fieldtype": "Currency", + "hidden": 1, + "label": "Tax Amount After Discount Amount", + "options": "Company:company:default_currency", + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "item_wise_tax_detail", "fieldtype": "Small Text", "hidden": 1, - "label": "Item Wise Tax Detail ", + "label": "Item Wise Tax Detail", "oldfieldname": "item_wise_tax_detail", "oldfieldtype": "Small Text", "read_only": 1 diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js index 0cdead9030..0e9b3db6c0 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js @@ -19,6 +19,10 @@ cur_frm.pformat.net_total_export = function(doc) { return ''; } +cur_frm.pformat.discount_amount = function(doc) { + return ''; +} + cur_frm.pformat.grand_total_export = function(doc) { return ''; } @@ -33,10 +37,10 @@ cur_frm.pformat.in_words_export = function(doc) { cur_frm.pformat.other_charges= function(doc){ //function to make row of table - var make_row = function(title,val,bold){ + var make_row = function(title, val, bold){ var bstart = ''; var bend = ''; - return '' - +'' + return '' + +'' +'' } @@ -52,7 +56,7 @@ cur_frm.pformat.other_charges= function(doc){ out =''; if (!doc.print_without_amount) { - var cl = getchildren('Sales Taxes and Charges',doc.name,'other_charges'); + var cl = getchildren('Sales Taxes and Charges', doc.name, 'other_charges'); // outer table var out='
%(item_code)s%(item_name)s\ +
\ + \ +
\ +
\ +
\ + \ +
\ +
%(amount)s
%(rate)s
%(description)s %(rate)s%(tax_amount)s
%(description)s %(rate)s%(tax_amount)s
'+(bold?bstart:'')+title+(bold?bend:'')+''+format_currency(val, doc.currency)+'
' + (bold?bstart:'') + title + (bold?bend:'') + '' + format_currency(val, doc.currency) + '
'; @@ -60,6 +64,7 @@ cur_frm.pformat.other_charges= function(doc){ // main table out +=''; + if(!print_hide('net_total_export')) { out += make_row('Net Total', doc.net_total_export, 1); } @@ -68,26 +73,31 @@ cur_frm.pformat.other_charges= function(doc){ if(cl.length){ for(var i=0;i' + out += '' } - out +='
' + doc.in_words_export + '
'; + out += ''; } return out; } @@ -99,7 +109,7 @@ cur_frm.cscript.charge_type = function(doc, cdt, cdn) { d.charge_type = ''; } validated = false; - refresh_field('charge_type',d.name,'other_charges'); + refresh_field('charge_type', d.name, 'other_charges'); cur_frm.cscript.row_id(doc, cdt, cdn); cur_frm.cscript.rate(doc, cdt, cdn); cur_frm.cscript.tax_amount(doc, cdt, cdn); @@ -122,7 +132,7 @@ cur_frm.cscript.row_id = function(doc, cdt, cdn) { } } validated = false; - refresh_field('row_id',d.name,'other_charges'); + refresh_field('row_id', d.name, 'other_charges'); } /*---------------------- Get rate if account_head has account_type as TAX or CHARGEABLE-------------------------------------*/ @@ -152,7 +162,7 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) { d.rate = ''; } validated = false; - refresh_field('rate',d.name,'other_charges'); + refresh_field('rate', d.name, 'other_charges'); } cur_frm.cscript.tax_amount = function(doc, cdt, cdn) { @@ -166,5 +176,5 @@ cur_frm.cscript.tax_amount = function(doc, cdt, cdn) { d.tax_amount = ''; } validated = false; - refresh_field('tax_amount',d.name,'other_charges'); + refresh_field('tax_amount', d.name, 'other_charges'); }; \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt index 485aa94ac1..11e3b317e4 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:09", "docstatus": 0, - "modified": "2013-12-20 19:24:34", + "modified": "2014-01-20 17:49:25", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -101,22 +102,22 @@ "reqd": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "write": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.txt b/erpnext/accounts/doctype/shipping_rule/shipping_rule.txt index 082cddcaeb..c1e2e90bb7 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.txt +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-25 11:48:03", "docstatus": 0, - "modified": "2013-12-20 19:24:35", + "modified": "2014-01-20 17:49:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -133,16 +133,19 @@ "reqd": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "write": 1 @@ -150,6 +153,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.py b/erpnext/accounts/report/accounts_payable/accounts_payable.py index adb126b0dd..07cca7385e 100644 --- a/erpnext/accounts/report/accounts_payable/accounts_payable.py +++ b/erpnext/accounts/report/accounts_payable/accounts_payable.py @@ -9,18 +9,20 @@ from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ def execute(filters=None): if not filters: filters = {} - columns = get_columns() + supplier_naming_by = webnotes.conn.get_value("Buying Settings", None, "supp_master_name") + columns = get_columns(supplier_naming_by) entries = get_gl_entries(filters) - account_supplier = dict(webnotes.conn.sql("""select account.name, supplier.supplier_name - from `tabAccount` account, `tabSupplier` supplier - where account.master_type="Supplier" and supplier.name=account.master_name""")) - + account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select acc.name, + supp.supplier_name, supp.name as supplier + from `tabAccount` acc, `tabSupplier` supp + where acc.master_type="Supplier" and supp.name=acc.master_name""", as_dict=1))) + entries_after_report_date = [[gle.voucher_type, gle.voucher_no] for gle in get_gl_entries(filters, before_report_date=False)] - + account_supplier_type_map = get_account_supplier_type_map() voucher_detail_map = get_voucher_details() - + # Age of the invoice on this date age_on = getdate(filters.get("report_date")) > getdate(nowdate()) \ and nowdate() or filters.get("report_date") @@ -37,9 +39,7 @@ def execute(filters=None): if abs(flt(outstanding_amount)) > 0.01: paid_amount = invoiced_amount - outstanding_amount - row = [gle.posting_date, gle.account, account_supplier.get(gle.account, ""), - gle.voucher_type, gle.voucher_no, gle.remarks, - account_supplier_type_map.get(gle.account), + row = [gle.posting_date, gle.account, gle.voucher_type, gle.voucher_no, voucher_details.get("due_date", ""), voucher_details.get("bill_no", ""), voucher_details.get("bill_date", ""), invoiced_amount, paid_amount, outstanding_amount] @@ -50,21 +50,38 @@ def execute(filters=None): else: ageing_based_on_date = gle.posting_date - row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + row += get_ageing_data(age_on, ageing_based_on_date, outstanding_amount) + \ + [account_map.get(gle.account).get("supplier") or ""] + + if supplier_naming_by == "Naming Series": + row += [account_map.get(gle.account).get("supplier_name") or ""] + + row += [account_supplier_type_map.get(gle.account), gle.remarks] data.append(row) - + + for i in range(0, len(data)): + data[i].insert(4, """""" \ + % ("/".join(["#Form", data[i][2], data[i][3]]),)) + return columns, data -def get_columns(): - return [ - "Posting Date:Date:80", "Account:Link/Account:150", "Supplier::150", "Voucher Type::110", - "Voucher No::120", "Remarks::150", "Supplier Type:Link/Supplier Type:120", - "Due Date:Date:80", "Bill No::80", "Bill Date:Date:80", +def get_columns(supplier_naming_by): + columns = [ + "Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110", + "Voucher No::120", "::30", "Due Date:Date:80", "Bill No::80", "Bill Date:Date:80", "Invoiced Amount:Currency:100", "Paid Amount:Currency:100", "Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", - "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100" + "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100", + "Supplier:Link/Supplier:150" ] - + + if supplier_naming_by == "Naming Series": + columns += ["Supplier Name::110"] + + columns += ["Supplier Type:Link/Supplier Type:120", "Remarks::150"] + + return columns + def get_gl_entries(filters, before_report_date=True): conditions, supplier_accounts = get_conditions(filters, before_report_date) gl_entries = [] @@ -101,10 +118,10 @@ def get_conditions(filters, before_report_date=True): def get_account_supplier_type_map(): account_supplier_type_map = {} - for each in webnotes.conn.sql("""select t2.name, t1.supplier_type from `tabSupplier` t1, - `tabAccount` t2 where t1.name = t2.master_name group by t2.name"""): + for each in webnotes.conn.sql("""select acc.name, supp.supplier_type from `tabSupplier` supp, + `tabAccount` acc where supp.name = acc.master_name group by acc.name"""): account_supplier_type_map[each[0]] = each[1] - + return account_supplier_type_map def get_voucher_details(): diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 945bae434a..085595e9cc 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -15,26 +15,37 @@ class AccountsReceivableReport(object): else self.filters.report_date def run(self): - return self.get_columns(), self.get_data() + customer_naming_by = webnotes.conn.get_value("Selling Settings", None, "cust_master_name") + return self.get_columns(customer_naming_by), self.get_data(customer_naming_by) - def get_columns(self): - return [ + def get_columns(self, customer_naming_by): + columns = [ "Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110", "Voucher No::120", "::30", "Due Date:Date:80", "Invoiced Amount:Currency:100", "Payment Received:Currency:100", "Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100", - "Customer:Link/Customer:200", "Territory:Link/Territory:80", "Remarks::200" + "Customer:Link/Customer:200" ] - - def get_data(self): + + if customer_naming_by == "Naming Series": + columns += ["Customer Name::110"] + + columns += ["Territory:Link/Territory:80", "Remarks::200"] + + return columns + + def get_data(self, customer_naming_by): + from erpnext.accounts.utils import get_currency_precision + currency_precision = get_currency_precision() or 2 + data = [] future_vouchers = self.get_entries_after(self.filters.report_date) for gle in self.get_entries_till(self.filters.report_date): if self.is_receivable(gle, future_vouchers): outstanding_amount = self.get_outstanding_amount(gle, self.filters.report_date) - if abs(outstanding_amount) > 0.01: + if abs(outstanding_amount) > 0.1/10**currency_precision: due_date = self.get_due_date(gle) invoiced_amount = gle.debit if (gle.debit > 0) else 0 payment_received = invoiced_amount - outstanding_amount @@ -42,18 +53,23 @@ class AccountsReceivableReport(object): gle.voucher_type, gle.voucher_no, due_date, invoiced_amount, payment_received, outstanding_amount] - entry_date = due_date if self.filters.ageing_based_on=="Due Date" \ + entry_date = due_date if self.filters.ageing_based_on == "Due Date" \ else gle.posting_date - row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) - row += [self.get_customer(gle.account), self.get_territory(gle.account), gle.remarks] + row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \ + [self.get_customer(gle.account)] + + if customer_naming_by == "Naming Series": + row += [self.get_customer_name(gle.account)] + + row += [self.get_territory(gle.account), gle.remarks] data.append(row) - for i in range(0,len(data)): + for i in range(0, len(data)): data[i].insert(4, """""" \ % ("/".join(["#Form", data[i][2], data[i][3]]),)) return data - + def get_entries_after(self, report_date): # returns a distinct list return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries() @@ -65,30 +81,41 @@ class AccountsReceivableReport(object): if getdate(e.posting_date) <= report_date) def is_receivable(self, gle, future_vouchers): - return ((not gle.against_voucher) or (gle.against_voucher==gle.voucher_no) or - ((gle.against_voucher_type, gle.against_voucher) in future_vouchers)) + return ( + # advance + (not gle.against_voucher) or + + # sales invoice + (gle.against_voucher==gle.voucher_no and gle.debit > 0) or + + # entries adjusted with future vouchers + ((gle.against_voucher_type, gle.against_voucher) in future_vouchers) + ) def get_outstanding_amount(self, gle, report_date): payment_received = 0.0 for e in self.get_gl_entries_for(gle.account, gle.voucher_type, gle.voucher_no): if getdate(e.posting_date) <= report_date and e.name!=gle.name: payment_received += (flt(e.credit) - flt(e.debit)) - + return flt(gle.debit) - flt(gle.credit) - payment_received def get_customer(self, account): + return self.get_account_map().get(account).get("customer") or "" + + def get_customer_name(self, account): return self.get_account_map().get(account).get("customer_name") or "" - + def get_territory(self, account): return self.get_account_map().get(account).get("territory") or "" def get_account_map(self): if not hasattr(self, "account_map"): self.account_map = dict(((r.name, r) for r in webnotes.conn.sql("""select - account.name, customer.name as customer_name, customer.territory - from `tabAccount` account, `tabCustomer` customer - where account.master_type="Customer" - and customer.name=account.master_name""", as_dict=True))) + acc.name, cust.name as customer, cust.customer_name, cust.territory + from `tabAccount` acc, `tabCustomer` cust + where acc.master_type="Customer" + and cust.name=acc.master_name""", as_dict=True))) return self.account_map @@ -147,7 +174,7 @@ class AccountsReceivableReport(object): def execute(filters=None): return AccountsReceivableReport(filters).run() - + def get_ageing_data(age_as_on, entry_date, outstanding_amount): # [0-30, 30-60, 60-90, 90-above] outstanding_range = [0.0, 0.0, 0.0, 0.0] diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js index b93f182f31..7f32e261c7 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.js +++ b/erpnext/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/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py index f2a1edda52..646906f907 100644 --- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py +++ b/erpnext/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 erpnext.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] diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index acfe6a0d86..ccdba064b3 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -34,7 +34,7 @@ def validate_filters(filters, account_details): def get_columns(): return ["Posting Date:Date:100", "Account:Link/Account:200", "Debit:Float:100", "Credit:Float:100", "Voucher Type::120", "Voucher No::160", "Link::20", - "Against Account::120", "Cost Center:Link/Cost Center:100", "Remarks::200"] + "Against Account::120", "Cost Center:Link/Cost Center:100", "Remarks::400"] def get_result(filters, account_details): gl_entries = get_gl_entries(filters) @@ -51,7 +51,7 @@ def get_gl_entries(filters): gl_entries = webnotes.conn.sql("""select posting_date, account, sum(ifnull(debit, 0)) as debit, sum(ifnull(credit, 0)) as credit, - voucher_type, voucher_no, cost_center, remarks, is_advance, against + voucher_type, voucher_no, cost_center, remarks, is_opening, against from `tabGL Entry` where company=%(company)s {conditions} {group_by_condition} @@ -72,6 +72,11 @@ def get_conditions(filters): if filters.get("voucher_no"): conditions.append("voucher_no=%(voucher_no)s") + + + from webnotes.widgets.reportview import build_match_conditions + match_conditions = build_match_conditions("GL Entry") + if match_conditions: conditions.append(match_conditions) return "and {}".format(" and ".join(conditions)) if conditions else "" @@ -133,10 +138,10 @@ def get_accountwise_gle(filters, gl_entries, gle_map): for gle in gl_entries: amount = flt(gle.debit) - flt(gle.credit) if filters.get("account") and (gle.posting_date < filters.from_date - or cstr(gle.is_advance) == "Yes"): + or cstr(gle.is_opening) == "Yes"): gle_map[gle.account].opening += amount opening += amount - elif gle.posting_date < filters.to_date: + elif gle.posting_date <= filters.to_date: gle_map[gle.account].entries.append(gle) gle_map[gle.account].total_debit += flt(gle.debit) gle_map[gle.account].total_credit += flt(gle.credit) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 7d81308a80..7d8a358aa1 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -12,7 +12,8 @@ def execute(filters=None): item_list = get_items(filters) aii_account_map = get_aii_accounts() - item_tax, tax_accounts = get_tax_accounts(item_list, columns) + if item_list: + item_tax, tax_accounts = get_tax_accounts(item_list, columns) data = [] for d in item_list: diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index dc5ecda3da..9f1fd87f70 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -11,7 +11,8 @@ def execute(filters=None): last_col = len(columns) item_list = get_items(filters) - item_tax, tax_accounts = get_tax_accounts(item_list, columns) + if item_list: + item_tax, tax_accounts = get_tax_accounts(item_list, columns) data = [] for d in item_list: @@ -39,7 +40,6 @@ def get_columns(): "Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120" ] - def get_conditions(filters): conditions = "" diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index 49b914e4a3..8fab6a9d97 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -79,7 +79,7 @@ def get_columns(invoice_list): tax_accounts = webnotes.conn.sql_list("""select distinct account_head from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice' - and docstatus = 1 and ifnull(tax_amount, 0) != 0 + and docstatus = 1 and ifnull(tax_amount_after_discount_amount, 0) != 0 and parent in (%s) order by account_head""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) @@ -126,7 +126,8 @@ def get_invoice_income_map(invoice_list): return invoice_income_map def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts): - tax_details = webnotes.conn.sql("""select parent, account_head, sum(tax_amount) as tax_amount + tax_details = webnotes.conn.sql("""select parent, account_head, + sum(tax_amount_after_discount_amount) as tax_amount from `tabSales Taxes and Charges` where parent in (%s) group by parent, account_head""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 6d74abd591..d9cb516c31 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import nowdate, nowtime, cstr, flt, now, getdate, add_months +from webnotes.utils import nowdate, cstr, flt, now, getdate, add_months from webnotes.model.doc import addchild from webnotes import msgprint, _ from webnotes.utils import formatdate @@ -31,6 +31,8 @@ def get_fiscal_years(date=None, fiscal_year=None, label="Date", verbose=1): if not fy: error_msg = """%s %s not in any Fiscal Year""" % (label, formatdate(date)) + error_msg = """{msg}: {date}""".format(msg=_("Fiscal Year does not exist for date"), + date=formatdate(date)) if verbose: webnotes.msgprint(error_msg) raise FiscalYearError, error_msg @@ -62,7 +64,6 @@ def get_balance_on(account=None, date=None): try: year_start_date = get_fiscal_year(date, verbose=0)[1] except FiscalYearError, e: - from webnotes.utils import getdate if getdate(date) > getdate(nowdate()): # if fiscal year not found and the date is greater than today # get fiscal year for today's date and its corresponding year start date @@ -220,17 +221,26 @@ def get_cost_center_list(doctype, txt, searchfield, start, page_len, filters): tuple(filter_values + ["%%%s%%" % txt, start, page_len])) def remove_against_link_from_jv(ref_type, ref_no, against_field): - webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null, - modified=%s, modified_by=%s - where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"), - (now(), webnotes.session.user, ref_no)) + linked_jv = webnotes.conn.sql_list("""select parent from `tabJournal Voucher Detail` + where `%s`=%s and docstatus < 2""" % (against_field, "%s"), (ref_no)) + + if linked_jv: + webnotes.conn.sql("""update `tabJournal Voucher Detail` set `%s`=null, + modified=%s, modified_by=%s + where `%s`=%s and docstatus < 2""" % (against_field, "%s", "%s", against_field, "%s"), + (now(), webnotes.session.user, ref_no)) - webnotes.conn.sql("""update `tabGL Entry` - set against_voucher_type=null, against_voucher=null, - modified=%s, modified_by=%s - where against_voucher_type=%s and against_voucher=%s - and voucher_no != ifnull(against_voucher, '')""", - (now(), webnotes.session.user, ref_type, ref_no)) + webnotes.conn.sql("""update `tabGL Entry` + set against_voucher_type=null, against_voucher=null, + modified=%s, modified_by=%s + where against_voucher_type=%s and against_voucher=%s + and voucher_no != ifnull(against_voucher, '')""", + (now(), webnotes.session.user, ref_type, ref_no)) + + webnotes.msgprint("{msg} {linked_jv}".format(msg = _("""Following linked Journal Vouchers \ + made against this transaction has been unlinked. You can link them again with other \ + transactions via Payment Reconciliation Tool."""), linked_jv="\n".join(linked_jv))) + @webnotes.whitelist() def get_company_default(company, fieldname): @@ -369,3 +379,12 @@ def get_account_for(account_for_doctype, account_for): return webnotes.conn.get_value("Account", {account_for_field: account_for_doctype, "master_name": account_for}) + +def get_currency_precision(currency=None): + if not currency: + currency = webnotes.conn.get_value("Company", + webnotes.conn.get_default("company"), "default_currency") + currency_format = webnotes.conn.get_value("Currency", currency, "number_format") + + from webnotes.utils import get_number_format_info + return get_number_format_info(currency_format)[2] diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index cc24925905..d01627a208 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -22,7 +22,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ if(this.frm.fields_dict.buying_price_list) { this.frm.set_query("buying_price_list", function() { return{ - filters: { 'buying_or_selling': "Buying" } + filters: { 'buying': 1 } } }); } @@ -302,11 +302,11 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ calculate_totals: function() { var tax_count = this.frm.tax_doclist.length; - this.frm.doc.grand_total = flt( - tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total, + this.frm.doc.grand_total = flt(tax_count ? + this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total, precision("grand_total")); - this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate, - precision("grand_total_import")); + this.frm.doc.grand_total_import = flt(this.frm.doc.grand_total / + this.frm.doc.conversion_rate, precision("grand_total_import")); this.frm.doc.total_tax = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("total_tax")); @@ -321,20 +321,26 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } // other charges added/deducted + this.frm.doc.other_charges_added = 0.0 + this.frm.doc.other_charges_deducted = 0.0 if(tax_count) { this.frm.doc.other_charges_added = wn.utils.sum($.map(this.frm.tax_doclist, - function(tax) { return (tax.add_deduct_tax == "Add" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; })); + function(tax) { return (tax.add_deduct_tax == "Add" + && in_list(["Valuation and Total", "Total"], tax.category)) ? + tax.tax_amount : 0.0; })); this.frm.doc.other_charges_deducted = wn.utils.sum($.map(this.frm.tax_doclist, - function(tax) { return (tax.add_deduct_tax == "Deduct" && in_list(["Valuation and Total", "Total"], tax.category)) ? tax.tax_amount : 0.0; })); + function(tax) { return (tax.add_deduct_tax == "Deduct" + && in_list(["Valuation and Total", "Total"], tax.category)) ? + tax.tax_amount : 0.0; })); - wn.model.round_floats_in(this.frm.doc, ["other_charges_added", "other_charges_deducted"]); - - this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added / this.frm.doc.conversion_rate, - precision("other_charges_added_import")); - this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted / this.frm.doc.conversion_rate, - precision("other_charges_deducted_import")); + wn.model.round_floats_in(this.frm.doc, + ["other_charges_added", "other_charges_deducted"]); } + this.frm.doc.other_charges_added_import = flt(this.frm.doc.other_charges_added / + this.frm.doc.conversion_rate, precision("other_charges_added_import")); + this.frm.doc.other_charges_deducted_import = flt(this.frm.doc.other_charges_deducted / + this.frm.doc.conversion_rate, precision("other_charges_deducted_import")); }, _cleanup: function() { @@ -360,6 +366,14 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ }); } } + + if(this.frm.tax_doclist.length) { + if(!wn.meta.get_docfield(this.frm.tax_doclist[0].doctype, "tax_amount_after_discount_amount", this.frm.doctype)) { + $.each(this.frm.tax_doclist, function(i, tax) { + delete tax["tax_amount_after_discount_amount"]; + }); + } + } }, calculate_outstanding_amount: function() { diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.txt b/erpnext/buying/doctype/purchase_order/purchase_order.txt index 0266b80e32..2790e41088 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.txt +++ b/erpnext/buying/doctype/purchase_order/purchase_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2013-12-20 19:24:20", + "modified": "2014-01-20 17:49:08", "modified_by": "Administrator", "owner": "Administrator" }, @@ -672,6 +672,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "submit": 0, @@ -681,6 +682,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Manager", "submit": 1, @@ -690,12 +692,14 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase User", "submit": 1, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Supplier" } diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 3659f6ddee..2aede0843c 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -1,7 +1,6 @@ # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt - from __future__ import unicode_literals import unittest import webnotes @@ -22,7 +21,7 @@ class TestPurchaseOrder(unittest.TestCase): pr = make_purchase_receipt(po.doc.name) pr[0]["supplier_warehouse"] = "_Test Warehouse 1 - _TC" - + pr[0]["posting_date"] = "2013-05-12" self.assertEquals(pr[0]["doctype"], "Purchase Receipt") self.assertEquals(len(pr), len(test_records[0])) @@ -52,7 +51,7 @@ class TestPurchaseOrder(unittest.TestCase): self.assertEquals(pr[0]["doctype"], "Purchase Receipt") self.assertEquals(len(pr), len(test_records[0])) - + pr[0]["posting_date"] = "2013-05-12" pr[0].naming_series = "_T-Purchase Receipt-" pr[1].qty = 4.0 pr_bean = webnotes.bean(pr) @@ -66,6 +65,7 @@ class TestPurchaseOrder(unittest.TestCase): pr1 = make_purchase_receipt(po.doc.name) pr1[0].naming_series = "_T-Purchase Receipt-" + pr1[0]["posting_date"] = "2013-05-12" pr1[1].qty = 8 pr1_bean = webnotes.bean(pr1) pr1_bean.insert() @@ -74,7 +74,7 @@ class TestPurchaseOrder(unittest.TestCase): self.assertEquals(flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 0.0) - def test_make_purchase_invocie(self): + def test_make_purchase_invoice(self): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice po = webnotes.bean(copy=test_records[0]).insert() @@ -88,7 +88,7 @@ class TestPurchaseOrder(unittest.TestCase): self.assertEquals(pi[0]["doctype"], "Purchase Invoice") self.assertEquals(len(pi), len(test_records[0])) - + pi[0]["posting_date"] = "2013-05-12" pi[0].bill_no = "NA" webnotes.bean(pi).insert() diff --git a/erpnext/buying/doctype/quality_inspection/quality_inspection.txt b/erpnext/buying/doctype/quality_inspection/quality_inspection.txt index aa8aa18394..899d3f863d 100644 --- a/erpnext/buying/doctype/quality_inspection/quality_inspection.txt +++ b/erpnext/buying/doctype/quality_inspection/quality_inspection.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-30 13:13:03", "docstatus": 0, - "modified": "2013-12-20 19:24:24", + "modified": "2014-01-20 17:49:14", "modified_by": "Administrator", "owner": "Administrator" }, @@ -27,6 +27,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index e1780abee9..4eb04792fc 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -3,7 +3,7 @@ {% include 'setup/doctype/contact_control/contact_control.js' %}; -cur_frm.cscript.refresh = function(doc,dt,dn) { +cur_frm.cscript.refresh = function(doc, dt, dn) { cur_frm.cscript.make_dashboard(doc); erpnext.hide_naming_series(); @@ -93,8 +93,8 @@ cur_frm.cscript.make_contact = function() { cur_frm.contact_list.run(); } -cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) { return{ - filters:{'buying_or_selling': "Buying"} + filters:{'buying': 1} } } \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index ec604289c8..82a526387f 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -214,7 +214,4 @@ def get_supplier_details(supplier): out.currency = supplier.default_currency out.buying_price_list = supplier.default_price_list - return out - - - \ No newline at end of file + return out \ No newline at end of file diff --git a/erpnext/buying/doctype/supplier/supplier.txt b/erpnext/buying/doctype/supplier/supplier.txt index c76eb653cf..5c305f5cd0 100644 --- a/erpnext/buying/doctype/supplier/supplier.txt +++ b/erpnext/buying/doctype/supplier/supplier.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:11", "docstatus": 0, - "modified": "2013-12-20 19:24:36", + "modified": "2014-01-20 17:49:29", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -210,15 +211,15 @@ "print_hide": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Purchase Manager", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Master Manager", "write": 1 diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt index f3bc30c738..e1441e5289 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:45", "docstatus": 0, - "modified": "2013-12-20 19:24:36", + "modified": "2014-01-20 17:49:29", "modified_by": "Administrator", "owner": "Administrator" }, @@ -598,6 +598,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Manufacturing Manager", "submit": 1, @@ -607,6 +608,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Manager", "submit": 1, @@ -616,6 +618,7 @@ "amend": 1, "cancel": 0, "create": 1, + "delete": 0, "doctype": "DocPerm", "role": "Purchase User", "submit": 0, @@ -625,6 +628,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "submit": 0, @@ -634,6 +638,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Supplier", "submit": 0, diff --git a/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.txt b/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.txt index 49c747854a..4d3558ca68 100644 --- a/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.txt +++ b/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-13 16:10:02", "docstatus": 0, - "modified": "2013-05-13 16:21:07", + "modified": "2014-01-24 18:19:11", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,7 +11,7 @@ "doctype": "Report", "is_standard": "Yes", "name": "__common__", - "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tmr_item.qty as \"Qty:Float:100\",\n\tmr_item.ordered_qty as \"Ordered Qty:Float:100\", \n\t(mr_item.qty - ifnull(mr_item.ordered_qty, 0)) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\n\tand ifnull(mr_item.ordered_qty, 0) < ifnull(mr_item.qty, 0)\norder by mr.transaction_date asc", + "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.qty, 0)) as \"Qty:Float:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.qty, 0))\norder by mr.transaction_date asc", "ref_doctype": "Purchase Order", "report_name": "Requested Items To Be Ordered", "report_type": "Query Report" diff --git a/erpnext/buying/utils.py b/erpnext/buying/utils.py index 8a4ae3f304..1bb31544e8 100644 --- a/erpnext/buying/utils.py +++ b/erpnext/buying/utils.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _ +from webnotes import msgprint, _, throw from webnotes.utils import getdate, flt, add_days, cstr import json @@ -89,8 +89,10 @@ def _get_price_list_rate(args, item_bean, meta): # try fetching from price list if args.buying_price_list and args.price_list_currency: - price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price` - where price_list=%s and item_code=%s and buying_or_selling='Buying'""", + price_list_rate = webnotes.conn.sql("""select ip.ref_rate from + `tabItem Price` ip, `tabPrice List` pl + where ip.price_list=pl.name and ip.price_list=%s and + ip.item_code=%s and ip.buying=1 and pl.enabled=1""", (args.buying_price_list, args.item_code), as_dict=1) if price_list_rate: @@ -122,14 +124,12 @@ def _validate_item_details(args, item): # validate if purchase item or subcontracted item if item.is_purchase_item != "Yes": - msgprint(_("Item") + (" %s: " % item.name) + _("not a purchase item"), - raise_exception=True) + throw(_("Item") + (" %s: " % item.name) + _("not a purchase item")) if args.is_subcontracted == "Yes" and item.is_sub_contracted_item != "Yes": - msgprint(_("Item") + (" %s: " % item.name) + + throw(_("Item") + (" %s: " % item.name) + _("not a sub-contracted item.") + - _("Please select a sub-contracted item or do not sub-contract the transaction."), - raise_exception=True) + _("Please select a sub-contracted item or do not sub-contract the transaction.")) def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0): """returns last purchase details in stock uom""" diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index d48a7a6d17..937449c6a2 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint +from webnotes import _, throw from webnotes.utils import flt, cint, today, cstr from webnotes.model.code import get_obj from erpnext.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): - msgprint(_("Account for this ") + fieldname + _(" has been freezed. ") + - self.doc.doctype + _(" can not be made."), raise_exception=1) + from erpnext.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"): @@ -133,6 +132,13 @@ class AccountsController(TransactionBase): self.doclist.append(tax) def calculate_taxes_and_totals(self): + self.discount_amount_applied = False + self._calculate_taxes_and_totals() + + if self.meta.get_field("discount_amount"): + self.apply_discount_amount() + + def _calculate_taxes_and_totals(self): # validate conversion rate company_currency = get_company_currency(self.doc.company) if not self.doc.currency or self.doc.currency == company_currency: @@ -141,7 +147,7 @@ class AccountsController(TransactionBase): else: validate_conversion_rate(self.doc.currency, self.doc.conversion_rate, self.meta.get_label("conversion_rate"), self.doc.company) - + self.doc.conversion_rate = flt(self.doc.conversion_rate) self.item_doclist = self.doclist.get({"parentfield": self.fname}) self.tax_doclist = self.doclist.get({"parentfield": self.other_fname}) @@ -157,17 +163,19 @@ class AccountsController(TransactionBase): self.calculate_totals() self._cleanup() - # TODO - # print format: show net_total_export instead of net_total - def initialize_taxes(self): for tax in self.tax_doclist: tax.item_wise_tax_detail = {} - for fieldname in ["tax_amount", "total", - "tax_amount_for_current_item", "grand_total_for_current_item", - "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]: - tax.fields[fieldname] = 0.0 - + tax_fields = ["total", "tax_amount_after_discount_amount", + "tax_amount_for_current_item", "grand_total_for_current_item", + "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"] + + if not self.discount_amount_applied: + tax_fields.append("tax_amount") + + for fieldname in tax_fields: + tax.fields[fieldname] = 0.0 + self.validate_on_previous_row(tax) self.validate_inclusive_tax(tax) self.round_floats_in(tax) @@ -179,17 +187,17 @@ class AccountsController(TransactionBase): """ if tax.charge_type in ["On Previous Row Amount", "On Previous Row Total"] and \ (not tax.row_id or cint(tax.row_id) >= tax.idx): - msgprint((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \ + throw((_("Row") + " # %(idx)s [%(taxes_doctype)s]: " + \ _("Please specify a valid") + " %(row_id_label)s") % { "idx": tax.idx, "taxes_doctype": tax.doctype, "row_id_label": self.meta.get_label("row_id", parentfield=self.other_fname) - }, raise_exception=True) + }) def validate_inclusive_tax(self, tax): def _on_previous_row_error(row_range): - msgprint((_("Row") + " # %(idx)s [%(doctype)s]: " + + throw((_("Row") + " # %(idx)s [%(doctype)s]: " + _("to be included in Item's rate, it is required that: ") + " [" + _("Row") + " # %(row_range)s] " + _("also be included in Item's rate")) % { "idx": tax.idx, @@ -200,12 +208,12 @@ class AccountsController(TransactionBase): parentfield=self.other_fname), "charge_type": tax.charge_type, "row_range": row_range - }, raise_exception=True) + }) if cint(tax.included_in_print_rate): if tax.charge_type == "Actual": # inclusive tax cannot be of type Actual - msgprint((_("Row") + throw((_("Row") + " # %(idx)s [%(doctype)s]: %(charge_type_label)s = \"%(charge_type)s\" " + "cannot be included in Item's rate") % { "idx": tax.idx, @@ -213,46 +221,49 @@ class AccountsController(TransactionBase): "charge_type_label": self.meta.get_label("charge_type", parentfield=self.other_fname), "charge_type": tax.charge_type, - }, raise_exception=True) + }) elif tax.charge_type == "On Previous Row Amount" and \ - not cint(self.tax_doclist[tax.row_id - 1].included_in_print_rate): + not cint(self.tax_doclist[cint(tax.row_id) - 1].included_in_print_rate): # referred row should also be inclusive _on_previous_row_error(tax.row_id) elif tax.charge_type == "On Previous Row Total" and \ - not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:tax.row_id - 1]]): + not all([cint(t.included_in_print_rate) for t in self.tax_doclist[:cint(tax.row_id) - 1]]): # all rows about the reffered tax should be inclusive _on_previous_row_error("1 - %d" % (tax.row_id,)) def calculate_taxes(self): - for item in self.item_doclist: + # maintain actual tax rate based on idx + actual_tax_dict = dict([[tax.idx, tax.rate] for tax in self.tax_doclist + if tax.charge_type == "Actual"]) + + for n, item in enumerate(self.item_doclist): item_tax_map = self._load_item_tax_rate(item.item_tax_rate) for i, tax in enumerate(self.tax_doclist): # tax_amount represents the amount of tax for the current step current_tax_amount = self.get_current_tax_amount(item, tax, item_tax_map) - - if hasattr(self, "set_item_tax_amount"): - self.set_item_tax_amount(item, tax, current_tax_amount) - # case when net total is 0 but there is an actual type charge - # in this case add the actual amount to tax.tax_amount - # and tax.grand_total_for_current_item for the first such iteration - if tax.charge_type=="Actual" and \ - not (current_tax_amount or self.doc.net_total or tax.tax_amount): - zero_net_total_adjustment = flt(tax.rate, self.precision("tax_amount", tax)) - current_tax_amount += zero_net_total_adjustment + # Adjust divisional loss to the last item + if tax.charge_type == "Actual": + actual_tax_dict[tax.idx] -= current_tax_amount + if n == len(self.item_doclist) - 1: + current_tax_amount += actual_tax_dict[tax.idx] # store tax_amount for current item as it will be used for # charge type = 'On Previous Row Amount' tax.tax_amount_for_current_item = current_tax_amount # accumulate tax amount into tax.tax_amount - tax.tax_amount += current_tax_amount + if not self.discount_amount_applied: + tax.tax_amount += current_tax_amount + + tax.tax_amount_after_discount_amount += current_tax_amount if tax.category: # if just for valuation, do not add the tax amount in total # hence, setting it as 0 for further steps - current_tax_amount = 0.0 if (tax.category == "Valuation") else current_tax_amount + current_tax_amount = 0.0 if (tax.category == "Valuation") \ + else current_tax_amount current_tax_amount *= -1.0 if (tax.add_deduct_tax == "Deduct") else 1.0 @@ -260,17 +271,36 @@ class AccountsController(TransactionBase): # note: grand_total_for_current_item contains the contribution of # item's amount, previously applied tax and the current tax on that item if i==0: - tax.grand_total_for_current_item = flt(item.amount + - current_tax_amount, self.precision("total", tax)) - + tax.grand_total_for_current_item = flt(item.amount + current_tax_amount, + self.precision("total", tax)) else: tax.grand_total_for_current_item = \ - flt(self.tax_doclist[i-1].grand_total_for_current_item + + flt(self.tax_doclist[i-1].grand_total_for_current_item + current_tax_amount, self.precision("total", tax)) # in tax.total, accumulate grand total of each item tax.total += tax.grand_total_for_current_item - + + # set precision in the last item iteration + if n == len(self.item_doclist) - 1: + self.round_off_totals(tax) + + # adjust Discount Amount loss in last tax iteration + if i == (len(self.tax_doclist) - 1) and self.discount_amount_applied: + self.adjust_discount_amount_loss(tax) + + def round_off_totals(self, tax): + tax.total = flt(tax.total, self.precision("total", tax)) + tax.tax_amount = flt(tax.tax_amount, self.precision("tax_amount", tax)) + tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, + self.precision("tax_amount", tax)) + + def adjust_discount_amount_loss(self, tax): + discount_amount_loss = self.doc.grand_total - flt(self.doc.discount_amount) - tax.total + tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount + + discount_amount_loss, self.precision("tax_amount", tax)) + tax.total = flt(tax.total + discount_amount_loss, self.precision("total", tax)) + def get_current_tax_amount(self, item, tax, item_tax_map): tax_rate = self._get_tax_rate(tax, item_tax_map) current_tax_amount = 0.0 @@ -289,9 +319,9 @@ class AccountsController(TransactionBase): elif tax.charge_type == "On Previous Row Total": current_tax_amount = (tax_rate / 100.0) * \ self.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item - + current_tax_amount = flt(current_tax_amount, self.precision("tax_amount", tax)) - + # store tax breakup for each item key = item.item_code or item.item_name if tax.item_wise_tax_detail.get(key): @@ -384,24 +414,45 @@ class AccountsController(TransactionBase): }) def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): + from erpnext.controllers.status_updater import get_tolerance_for + item_tolerance = {} + global_tolerance = None + for item in self.doclist.get({"parentfield": "entries"}): if item.fields.get(item_ref_dn): - already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s` - where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'), - item.fields[item_ref_dn])[0][0] - - max_allowed_amt = flt(webnotes.conn.get_value(ref_dt + " Item", + ref_amt = flt(webnotes.conn.get_value(ref_dt + " Item", item.fields[item_ref_dn], based_on), self.precision(based_on, item)) + if not ref_amt: + webnotes.msgprint(_("As amount for item") + ": " + item.item_code + _(" in ") + + ref_dt + _(" is zero, system will not check for over-billed")) + else: + already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s` + where %s=%s and docstatus=1 and parent != %s""" % + (based_on, self.tname, item_ref_dn, '%s', '%s'), + (item.fields[item_ref_dn], self.doc.name))[0][0] - total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]), - self.precision(based_on, item)) + total_billed_amt = flt(flt(already_billed) + flt(item.fields[based_on]), + self.precision(based_on, item)) + + tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, + item_tolerance, global_tolerance) - if max_allowed_amt and total_billed_amt - max_allowed_amt > 0.02: - webnotes.msgprint(_("Row ")+ cstr(item.idx) + ": " + cstr(item.item_code) + - _(" will be over-billed against mentioned ") + cstr(ref_dt) + - _(". Max allowed " + cstr(based_on) + ": " + cstr(max_allowed_amt)), - raise_exception=1) - + max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100) + + if total_billed_amt - max_allowed_amt > 0.01: + reduce_by = total_billed_amt - max_allowed_amt + + webnotes.throw(_("Row #") + cstr(item.idx) + ": " + + _(" Max amount allowed for Item ") + cstr(item.item_code) + + _(" against ") + ref_dt + " " + + cstr(item.fields[ref_dt.lower().replace(" ", "_")]) + _(" is ") + + cstr(max_allowed_amt) + ". \n" + + _("""If you want to increase your overflow tolerance, please increase \ + tolerance % in Global Defaults or Item master. + Or, you must reduce the amount by """) + cstr(reduce_by) + "\n" + + _("""Also, please check if the order item has already been billed \ + in the Sales Order""")) + def get_company_default(self, fieldname): from erpnext.accounts.utils import get_company_default return get_company_default(self.doc.company, fieldname) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 40de926ea0..83b590994d 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import webnotes from webnotes import _, msgprint from webnotes.utils import flt, _round - from erpnext.buying.utils import get_item_details from erpnext.setup.utils import get_company_currency @@ -122,8 +121,8 @@ class BuyingController(StockController): self.round_floats_in(self.doc, ["net_total", "net_total_import"]) def calculate_totals(self): - self.doc.grand_total = flt(self.tax_doclist and \ - self.tax_doclist[-1].total or self.doc.net_total, self.precision("grand_total")) + self.doc.grand_total = flt(self.tax_doclist[-1].total if self.tax_doclist + else self.doc.net_total, self.precision("grand_total")) self.doc.grand_total_import = flt(self.doc.grand_total / self.doc.conversion_rate, self.precision("grand_total_import")) @@ -135,6 +134,24 @@ class BuyingController(StockController): if self.meta.get_field("rounded_total_import"): self.doc.rounded_total_import = _round(self.doc.grand_total_import) + + if self.meta.get_field("other_charges_added"): + self.doc.other_charges_added = flt(sum([flt(d.tax_amount) for d in self.tax_doclist + if d.add_deduct_tax=="Add" and d.category in ["Valuation and Total", "Total"]]), + self.precision("other_charges_added")) + + if self.meta.get_field("other_charges_deducted"): + self.doc.other_charges_deducted = flt(sum([flt(d.tax_amount) for d in self.tax_doclist + if d.add_deduct_tax=="Deduct" and d.category in ["Valuation and Total", "Total"]]), + self.precision("other_charges_deducted")) + + if self.meta.get_field("other_charges_added_import"): + self.doc.other_charges_added_import = flt(self.doc.other_charges_added / + self.doc.conversion_rate, self.precision("other_charges_added_import")) + + if self.meta.get_field("other_charges_deducted_import"): + self.doc.other_charges_deducted_import = flt(self.doc.other_charges_deducted / + self.doc.conversion_rate, self.precision("other_charges_deducted_import")) def calculate_outstanding_amount(self): if self.doc.doctype == "Purchase Invoice" and self.doc.docstatus < 2: @@ -148,7 +165,7 @@ class BuyingController(StockController): def _cleanup(self): super(BuyingController, self)._cleanup() - # except in purchase invoice, rate field is purchase_rate + # except in purchase invoice, rate field is purchase_rate # reset fieldname of rate if self.doc.doctype != "Purchase Invoice": df = self.meta.get_field("rate", parentfield=self.fname) @@ -162,29 +179,53 @@ class BuyingController(StockController): for item in self.item_doclist: del item.fields["item_tax_amount"] - def set_item_tax_amount(self, item, tax, current_tax_amount): + if not self.meta.get_field("tax_amount_after_discount_amount", + parentfield=self.other_fname): + for tax in self.tax_doclist: + del tax.fields["tax_amount_after_discount_amount"] + + # update valuation rate + def update_valuation_rate(self, parentfield): """ item_tax_amount is the total tax amount applied on that item stored for valuation TODO: rename item_tax_amount to valuation_tax_amount """ - if tax.category in ["Valuation", "Valuation and Total"] and \ - self.meta.get_field("item_tax_amount", parentfield=self.fname): - item.item_tax_amount += flt(current_tax_amount, self.precision("item_tax_amount", item)) - - # update valuation rate - def update_valuation_rate(self, parentfield): - for item in self.doclist.get({"parentfield": parentfield}): - item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value( - "UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom}, - "conversion_factor")) or 1 + stock_items = self.get_stock_items() + + stock_items_qty, stock_items_amount = 0, 0 + last_stock_item_idx = 1 + for d in self.doclist.get({"parentfield": parentfield}): + if d.item_code and d.item_code in stock_items: + stock_items_qty += flt(d.qty) + stock_items_amount += flt(d.amount) + last_stock_item_idx = d.idx - if item.item_code and item.qty: + total_valuation_amount = sum([flt(d.tax_amount) for d in + self.doclist.get({"parentfield": "purchase_tax_details"}) + if d.category in ["Valuation", "Valuation and Total"]]) + + + valuation_amount_adjustment = total_valuation_amount + for i, item in enumerate(self.doclist.get({"parentfield": parentfield})): + if item.item_code and item.qty and item.item_code in stock_items: + item_proportion = flt(item.amount) / stock_items_amount if stock_items_amount \ + else flt(item.qty) / stock_items_qty + + if i == (last_stock_item_idx - 1): + item.item_tax_amount = flt(valuation_amount_adjustment, + self.precision("item_tax_amount", item)) + else: + item.item_tax_amount = flt(item_proportion * total_valuation_amount, + self.precision("item_tax_amount", item)) + valuation_amount_adjustment -= item.item_tax_amount + self.round_floats_in(item) - - # if no item code, which is sometimes the case in purchase invoice, - # then it is not possible to track valuation against it + + item.conversion_factor = item.conversion_factor or flt(webnotes.conn.get_value( + "UOM Conversion Detail", {"parent": item.item_code, "uom": item.uom}, + "conversion_factor")) or 1 qty_in_stock_uom = flt(item.qty * item.conversion_factor) item.valuation_rate = ((item.amount + item.item_tax_amount + item.rm_supp_cost) / qty_in_stock_uom) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 7b1be1859a..aac54820fc 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -122,7 +122,7 @@ class SellingController(StockController): cumulated_tax_fraction += tax.tax_fraction_for_current_item - if cumulated_tax_fraction: + if cumulated_tax_fraction and not self.discount_amount_applied: item.amount = flt((item.export_amount * self.doc.conversion_rate) / (1 + cumulated_tax_fraction), self.precision("amount", item)) @@ -159,22 +159,23 @@ class SellingController(StockController): return current_tax_fraction def calculate_item_values(self): - for item in self.item_doclist: - self.round_floats_in(item) - - if item.adj_rate == 100: - item.export_rate = 0 - elif not item.export_rate: - item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)), - self.precision("export_rate", item)) - - item.export_amount = flt(item.export_rate * item.qty, - self.precision("export_amount", item)) + if not self.discount_amount_applied: + for item in self.item_doclist: + self.round_floats_in(item) + + if item.adj_rate == 100: + item.export_rate = 0 + elif not item.export_rate: + item.export_rate = flt(item.ref_rate * (1.0 - (item.adj_rate / 100.0)), + self.precision("export_rate", item)) + + item.export_amount = flt(item.export_rate * item.qty, + self.precision("export_amount", item)) + + self._set_in_company_currency(item, "ref_rate", "base_ref_rate") + self._set_in_company_currency(item, "export_rate", "basic_rate") + self._set_in_company_currency(item, "export_amount", "amount") - self._set_in_company_currency(item, "ref_rate", "base_ref_rate") - self._set_in_company_currency(item, "export_rate", "basic_rate") - self._set_in_company_currency(item, "export_amount", "amount") - def calculate_net_total(self): self.doc.net_total = self.doc.net_total_export = 0.0 @@ -192,12 +193,42 @@ class SellingController(StockController): self.doc.other_charges_total = flt(self.doc.grand_total - self.doc.net_total, self.precision("other_charges_total")) - self.doc.other_charges_total_export = flt(self.doc.grand_total_export - self.doc.net_total_export, + + self.doc.other_charges_total_export = flt(self.doc.grand_total_export - + self.doc.net_total_export + flt(self.doc.discount_amount), self.precision("other_charges_total_export")) self.doc.rounded_total = _round(self.doc.grand_total) self.doc.rounded_total_export = _round(self.doc.grand_total_export) - + + def apply_discount_amount(self): + if self.doc.discount_amount: + grand_total_for_discount_amount = self.get_grand_total_for_discount_amount() + + if grand_total_for_discount_amount: + # calculate item amount after Discount Amount + for item in self.item_doclist: + distributed_amount = flt(self.doc.discount_amount) * item.amount / grand_total_for_discount_amount + item.amount = flt(item.amount - distributed_amount, self.precision("amount", item)) + + self.discount_amount_applied = True + self._calculate_taxes_and_totals() + + def get_grand_total_for_discount_amount(self): + actual_taxes_dict = {} + + for tax in self.tax_doclist: + if tax.charge_type == "Actual": + actual_taxes_dict.setdefault(tax.idx, tax.tax_amount) + elif tax.row_id in actual_taxes_dict: + actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * \ + flt(tax.rate) / 100 + actual_taxes_dict.setdefault(tax.idx, actual_tax_amount) + + grand_total_for_discount_amount = flt(self.doc.grand_total - sum(actual_taxes_dict.values()), + self.precision("grand_total")) + return grand_total_for_discount_amount + def calculate_outstanding_amount(self): # NOTE: # write_off_amount is only for POS Invoice diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index b2745268f7..1743887bf7 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -151,7 +151,9 @@ class StatusUpdater(DocListController): """ # check if overflow is within tolerance - tolerance = self.get_tolerance_for(item['item_code']) + tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'], + self.tolerance, self.global_tolerance) + overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) / item[args['target_ref_field']]) * 100 @@ -170,23 +172,6 @@ class StatusUpdater(DocListController): Also, please check if the order item has already been billed in the Sales Order""" % item, raise_exception=1) - - def get_tolerance_for(self, item_code): - """ - Returns the tolerance for the item, if not set, returns global tolerance - """ - if self.tolerance.get(item_code): return self.tolerance[item_code] - - tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0) - - if not tolerance: - if self.global_tolerance == None: - self.global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None, - 'tolerance')) - tolerance = self.global_tolerance - - self.tolerance[item_code] = tolerance - return tolerance def update_qty(self, change_modified=True): @@ -245,4 +230,59 @@ class StatusUpdater(DocListController): set %(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001, 'Not %(keyword)s', if(%(target_parent_field)s>=99.99, 'Fully %(keyword)s', 'Partly %(keyword)s')) - where name='%(name)s'""" % args) \ No newline at end of file + where name='%(name)s'""" % args) + + + def update_billing_status_for_zero_amount_refdoc(self, ref_dt): + ref_fieldname = ref_dt.lower().replace(" ", "_") + zero_amount_refdoc = [] + all_zero_amount_refdoc = webnotes.conn.sql_list("""select name from `tab%s` + where docstatus=1 and net_total = 0""" % ref_dt) + + for item in self.doclist.get({"parentfield": "entries"}): + if item.fields.get(ref_fieldname) \ + and item.fields.get(ref_fieldname) in all_zero_amount_refdoc \ + and item.fields.get(ref_fieldname) not in zero_amount_refdoc: + zero_amount_refdoc.append(item.fields[ref_fieldname]) + + if zero_amount_refdoc: + self.update_biling_status(zero_amount_refdoc, ref_dt, ref_fieldname) + + def update_biling_status(self, zero_amount_refdoc, ref_dt, ref_fieldname): + for ref_dn in zero_amount_refdoc: + ref_doc_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0)) from `tab%s Item` + where parent=%s""" % (ref_dt, '%s'), (ref_dn))[0][0]) + + billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0)) + from `tab%s Item` where %s=%s and docstatus=1""" % + (self.doc.doctype, ref_fieldname, '%s'), (ref_dn))[0][0]) + + per_billed = ((ref_doc_qty if billed_qty > ref_doc_qty else billed_qty)\ + / ref_doc_qty)*100 + webnotes.conn.set_value(ref_dt, ref_dn, "per_billed", per_billed) + + from webnotes.model.meta import has_field + if has_field(ref_dt, "billing_status"): + if per_billed < 0.001: billing_status = "Not Billed" + elif per_billed >= 99.99: billing_status = "Fully Billed" + else: billing_status = "Partly Billed" + + webnotes.conn.set_value(ref_dt, ref_dn, "billing_status", billing_status) + +def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None): + """ + Returns the tolerance for the item, if not set, returns global tolerance + """ + if item_tolerance.get(item_code): + return item_tolerance[item_code], item_tolerance, global_tolerance + + tolerance = flt(webnotes.conn.get_value('Item',item_code,'tolerance') or 0) + + if not tolerance: + if global_tolerance == None: + global_tolerance = flt(webnotes.conn.get_value('Global Defaults', None, + 'tolerance')) + tolerance = global_tolerance + + item_tolerance[item_code] = tolerance + return tolerance, item_tolerance, global_tolerance \ No newline at end of file diff --git a/erpnext/hooks.txt b/erpnext/hooks.txt index 9d4291b2e3..a52ea2d29a 100644 --- a/erpnext/hooks.txt +++ b/erpnext/hooks.txt @@ -46,17 +46,14 @@ standard_queries = Customer:erpnext.selling.utils.get_customer_list scheduler_event = all:erpnext.support.doctype.support_ticket.get_support_mails.get_support_mails scheduler_event = all:erpnext.hr.doctype.job_applicant.get_job_applications.get_job_applications scheduler_event = all:erpnext.selling.doctype.lead.get_leads.get_leads -scheduler_event = all:webnotes.utils.email_lib.bulk.flush #### Daily -scheduler_event = daily:webnotes.core.doctype.event.event.send_event_digest -scheduler_event = daily:webnotes.core.doctype.notification_count.notification_count.delete_event_notification_count -scheduler_event = daily:webnotes.utils.email_lib.bulk.clear_outbox scheduler_event = daily:erpnext.accounts.doctype.sales_invoice.sales_invoice.manage_recurring_invoices scheduler_event = daily:erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily scheduler_event = daily:erpnext.stock.utils.reorder_item scheduler_event = daily:erpnext.setup.doctype.email_digest.email_digest.send +scheduler_event = daily:support.doctype.support_ticket.support_ticket.auto_close_tickets #### Weekly diff --git a/erpnext/hr/doctype/appraisal/appraisal.txt b/erpnext/hr/doctype/appraisal/appraisal.txt index c7d9aafbbb..da57097b52 100644 --- a/erpnext/hr/doctype/appraisal/appraisal.txt +++ b/erpnext/hr/doctype/appraisal/appraisal.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:12", "docstatus": 0, - "modified": "2013-12-20 19:23:55", + "modified": "2014-01-22 16:05:34", "modified_by": "Administrator", "owner": "ashwini@webnotestech.com" }, @@ -230,14 +230,17 @@ "width": "150px" }, { + "cancel": 0, + "delete": 0, "doctype": "DocPerm", - "match": "owner", + "restricted": 1, "role": "Employee", "submit": 0 }, { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "System Manager", "submit": 1 @@ -245,6 +248,7 @@ { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "HR User", "submit": 1 diff --git a/erpnext/hr/doctype/attendance/attendance.txt b/erpnext/hr/doctype/attendance/attendance.txt index 7d383fb9e4..894e981860 100644 --- a/erpnext/hr/doctype/attendance/attendance.txt +++ b/erpnext/hr/doctype/attendance/attendance.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:13", "docstatus": 0, - "modified": "2013-12-20 19:23:55", + "modified": "2014-01-20 17:48:23", "modified_by": "Administrator", "owner": "ashwini@webnotestech.com" }, @@ -28,6 +28,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/branch/branch.txt b/erpnext/hr/doctype/branch/branch.txt index 13aa087b24..6ef13e2abb 100644 --- a/erpnext/hr/doctype/branch/branch.txt +++ b/erpnext/hr/doctype/branch/branch.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:13", "docstatus": 0, - "modified": "2013-12-20 19:23:57", + "modified": "2014-01-20 17:48:26", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/deduction_type/deduction_type.txt b/erpnext/hr/doctype/deduction_type/deduction_type.txt index e24064e14d..b70cf35b91 100644 --- a/erpnext/hr/doctype/deduction_type/deduction_type.txt +++ b/erpnext/hr/doctype/deduction_type/deduction_type.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-22 16:50:30", "docstatus": 0, - "modified": "2013-12-20 19:24:02", + "modified": "2014-01-20 17:48:34", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/department/department.txt b/erpnext/hr/doctype/department/department.txt index 4cfdcaf8ca..269afa758f 100644 --- a/erpnext/hr/doctype/department/department.txt +++ b/erpnext/hr/doctype/department/department.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-05 11:48:26", "docstatus": 0, - "modified": "2013-12-20 19:24:04", + "modified": "2014-01-20 17:48:38", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,8 +24,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/designation/designation.txt b/erpnext/hr/doctype/designation/designation.txt index f9b48e46c2..e8debd1b2f 100644 --- a/erpnext/hr/doctype/designation/designation.txt +++ b/erpnext/hr/doctype/designation/designation.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:13", "docstatus": 0, - "modified": "2013-12-20 19:24:04", + "modified": "2014-01-20 17:48:38", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/earning_type/earning_type.txt b/erpnext/hr/doctype/earning_type/earning_type.txt index c5ead6366e..9d3b90f80f 100644 --- a/erpnext/hr/doctype/earning_type/earning_type.txt +++ b/erpnext/hr/doctype/earning_type/earning_type.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-24 11:03:32", "docstatus": 0, - "modified": "2013-12-20 19:24:05", + "modified": "2014-01-20 17:48:38", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js index 23d50670fb..7ee88f7068 100644 --- a/erpnext/hr/doctype/employee/employee.js +++ b/erpnext/hr/doctype/employee/employee.js @@ -4,10 +4,10 @@ wn.provide("erpnext.hr"); erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({ setup: function() { - this.frm.fields_dict.user_id.get_query = function(doc,cdt,cdn) { - return { query:"webnotes.core.doctype.profile.profile.profile_query"} } - this.frm.fields_dict.reports_to.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query"} } + this.frm.fields_dict.user_id.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query"} } + this.frm.fields_dict.reports_to.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query"} } }, onload: function() { @@ -93,4 +93,4 @@ erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({ }); }, }); -cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm}); \ No newline at end of file +cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm}); diff --git a/erpnext/hr/doctype/employee/employee.txt b/erpnext/hr/doctype/employee/employee.txt index f8b08e08d4..16314dba62 100644 --- a/erpnext/hr/doctype/employee/employee.txt +++ b/erpnext/hr/doctype/employee/employee.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 09:04:18", "docstatus": 0, - "modified": "2013-12-23 19:35:27", + "modified": "2014-01-20 17:48:40", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -750,23 +751,23 @@ "read_only": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Employee", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "restrict": 0, "role": "HR User", "write": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "restrict": 1, "role": "HR Manager", diff --git a/erpnext/hr/doctype/employment_type/employment_type.txt b/erpnext/hr/doctype/employment_type/employment_type.txt index a13fd872b7..a91e145a5e 100644 --- a/erpnext/hr/doctype/employment_type/employment_type.txt +++ b/erpnext/hr/doctype/employment_type/employment_type.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:14", "docstatus": 0, - "modified": "2013-12-20 19:24:07", + "modified": "2014-01-20 17:48:43", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,8 +24,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.txt b/erpnext/hr/doctype/expense_claim/expense_claim.txt index 5e65aa8ba6..ac7f78861d 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.txt +++ b/erpnext/hr/doctype/expense_claim/expense_claim.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:14", "docstatus": 0, - "modified": "2013-12-20 19:24:07", + "modified": "2014-01-22 16:05:34", "modified_by": "Administrator", "owner": "harshada@webnotestech.com" }, @@ -221,13 +221,15 @@ "width": "160px" }, { + "delete": 0, "doctype": "DocPerm", - "match": "owner", + "restricted": 1, "role": "Employee" }, { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "Expense Approver", "submit": 1 @@ -235,6 +237,7 @@ { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "HR User", "submit": 1 diff --git a/erpnext/hr/doctype/grade/grade.txt b/erpnext/hr/doctype/grade/grade.txt index 4743bf1ccc..dcadd634a2 100644 --- a/erpnext/hr/doctype/grade/grade.txt +++ b/erpnext/hr/doctype/grade/grade.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:14", "docstatus": 0, - "modified": "2013-12-20 19:24:08", + "modified": "2014-01-20 17:48:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,8 +30,9 @@ "reqd": 1 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py index 1045077e77..9f28e4c6b4 100644 --- a/erpnext/hr/doctype/holiday_list/holiday_list.py +++ b/erpnext/hr/doctype/holiday_list/holiday_list.py @@ -8,9 +8,7 @@ from webnotes.utils import add_days, add_years, cint, getdate from webnotes.model import db_exists from webnotes.model.doc import addchild, make_autoname from webnotes.model.bean import copy_doclist -from webnotes import msgprint - - +from webnotes import msgprint, throw, _ import datetime class DocType: @@ -19,7 +17,7 @@ class DocType: self.doclist = doclist def autoname(self): - self.doc.name = make_autoname(self.doc.fiscal_year +"/"+ self.doc.holiday_list_name+"/.###") + self.doc.name = make_autoname(self.doc.fiscal_year + "/" + self.doc.holiday_list_name + "/.###") def validate(self): self.update_default_holiday_list() @@ -38,11 +36,9 @@ class DocType: def validate_values(self): if not self.doc.fiscal_year: - msgprint("Please select Fiscal Year") - raise Exception + throw(_("Please select Fiscal Year")) if not self.doc.weekly_off: - msgprint("Please select weekly off day") - raise Exception + throw(_("Please select weekly off day")) def get_fy_start_end_dates(self): return webnotes.conn.sql("""select year_start_date, year_end_date diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.txt b/erpnext/hr/doctype/holiday_list/holiday_list.txt index 8f0832b130..3122583866 100644 --- a/erpnext/hr/doctype/holiday_list/holiday_list.txt +++ b/erpnext/hr/doctype/holiday_list/holiday_list.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:14", "docstatus": 0, - "modified": "2013-12-20 19:24:08", + "modified": "2014-01-20 17:48:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -23,8 +23,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/job_applicant/job_applicant.txt b/erpnext/hr/doctype/job_applicant/job_applicant.txt index 8f0d41ae3a..fd463fb7e9 100644 --- a/erpnext/hr/doctype/job_applicant/job_applicant.txt +++ b/erpnext/hr/doctype/job_applicant/job_applicant.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-29 19:25:37", "docstatus": 0, - "modified": "2013-12-20 19:24:10", + "modified": "2014-01-20 17:48:50", "modified_by": "Administrator", "owner": "Administrator" }, @@ -27,6 +27,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/job_opening/job_opening.txt b/erpnext/hr/doctype/job_opening/job_opening.txt index dcf76ddb3a..b118b6a8d1 100644 --- a/erpnext/hr/doctype/job_opening/job_opening.txt +++ b/erpnext/hr/doctype/job_opening/job_opening.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-15 16:13:36", "docstatus": 0, - "modified": "2013-12-20 19:24:11", + "modified": "2014-01-20 17:48:51", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.txt b/erpnext/hr/doctype/leave_allocation/leave_allocation.txt index 6e5fe64019..60f2523941 100644 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.txt +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-20 19:10:38", "docstatus": 0, - "modified": "2013-12-20 19:24:12", + "modified": "2014-01-22 16:05:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -170,7 +171,7 @@ }, { "doctype": "DocPerm", - "match": "owner", + "restricted": 1, "role": "HR User" }, { diff --git a/erpnext/hr/doctype/leave_application/leave_application.txt b/erpnext/hr/doctype/leave_application/leave_application.txt index 24de6a82fc..038c29ddef 100644 --- a/erpnext/hr/doctype/leave_application/leave_application.txt +++ b/erpnext/hr/doctype/leave_application/leave_application.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-20 11:18:11", "docstatus": 0, - "modified": "2013-12-23 19:53:41", + "modified": "2014-01-20 17:48:55", "modified_by": "Administrator", "owner": "Administrator" }, @@ -230,6 +230,7 @@ }, { "create": 1, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -242,6 +243,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "role": "All", @@ -251,6 +253,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -265,6 +268,7 @@ "amend": 1, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -278,6 +282,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "report": 1, @@ -289,6 +294,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "report": 1, diff --git a/erpnext/hr/doctype/leave_type/leave_type.txt b/erpnext/hr/doctype/leave_type/leave_type.txt index adae0d9836..13d7e725be 100644 --- a/erpnext/hr/doctype/leave_type/leave_type.txt +++ b/erpnext/hr/doctype/leave_type/leave_type.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-21 09:55:58", "docstatus": 0, - "modified": "2013-12-20 19:24:13", + "modified": "2014-01-20 17:48:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,8 +24,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.js b/erpnext/hr/doctype/salary_manager/salary_manager.js index 032c29e509..ec485ca671 100644 --- a/erpnext/hr/doctype/salary_manager/salary_manager.js +++ b/erpnext/hr/doctype/salary_manager/salary_manager.js @@ -43,7 +43,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) { jv = locals['Journal Voucher'][jv]; jv.voucher_type = 'Bank Voucher'; jv.user_remark = wn._('Payment of salary for the month: ') + doc.month + - wn._('and fiscal year: ') + doc.fiscal_year; + wn._(' and fiscal year: ') + doc.fiscal_year; jv.fiscal_year = doc.fiscal_year; jv.company = doc.company; jv.posting_date = dateutil.obj_to_str(new Date()); diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.txt b/erpnext/hr/doctype/salary_slip/salary_slip.txt index 1f94aa83e0..e47e8d834e 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.txt +++ b/erpnext/hr/doctype/salary_slip/salary_slip.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:15", "docstatus": 0, - "modified": "2013-12-20 19:24:27", + "modified": "2014-01-20 17:49:18", "modified_by": "Administrator", "owner": "Administrator" }, @@ -390,12 +390,14 @@ }, { "amend": 0, + "delete": 0, "doctype": "DocPerm", "role": "HR User" }, { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "HR Manager" } diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js index 5d3abccde9..32b4ef35fb 100644 --- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js +++ b/erpnext/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/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py index 8bd8f36ac8..42c62e474b 100644 --- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py +++ b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py @@ -50,17 +50,17 @@ def get_columns(salary_slips): where ifnull(d_modified_amount, 0) != 0 and parent in (%s)""" % (', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips])) - columns = columns + [(e + ":Link/Earning Type:120") for e in earning_types] + \ + columns = columns + [(e + ":Currency:120") for e in earning_types] + \ ["Arrear Amount:Currency:120", "Leave Encashment Amount:Currency:150", - "Gross Pay:Currency:120"] + [(d + ":Link/Deduction Type:120") for d in ded_types] + \ + "Gross Pay:Currency:120"] + [(d + ":Currency:120") for d in ded_types] + \ ["Total Deduction:Currency:120", "Net Pay:Currency:120"] return columns, earning_types, ded_types 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")) + @@ -102,6 +102,6 @@ def get_ss_ded_map(salary_slips): ss_ded_map = {} for d in ss_deductions: ss_ded_map.setdefault(d.parent, webnotes._dict()).setdefault(d.d_type, []) - ss_ded_map[d.parent][d.e_type] = flt(d.d_modified_amount) + ss_ded_map[d.parent][d.d_type] = flt(d.d_modified_amount) return ss_ded_map \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/bom/bom.txt b/erpnext/manufacturing/doctype/bom/bom.txt index 505d8d75aa..4afc160fb8 100644 --- a/erpnext/manufacturing/doctype/bom/bom.txt +++ b/erpnext/manufacturing/doctype/bom/bom.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-22 15:11:38", "docstatus": 0, - "modified": "2013-12-20 19:23:57", + "modified": "2014-01-20 17:48:26", "modified_by": "Administrator", "owner": "Administrator" }, @@ -36,6 +36,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/manufacturing/doctype/production_order/production_order.txt b/erpnext/manufacturing/doctype/production_order/production_order.txt index ed1c66886b..41ef1ce639 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.txt +++ b/erpnext/manufacturing/doctype/production_order/production_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:16", "docstatus": 0, - "modified": "2013-12-20 19:24:16", + "modified": "2014-01-20 17:49:01", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index 9b1300f039..e2ff92174e 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -35,6 +35,8 @@ class TestProductionOrder(unittest.TestCase): stock_entry = webnotes.bean(stock_entry) stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013" stock_entry.doc.fg_completed_qty = 4 + stock_entry.doc.posting_date = "2013-05-12" + stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013" stock_entry.run_method("get_items") stock_entry.submit() @@ -51,6 +53,7 @@ class TestProductionOrder(unittest.TestCase): stock_entry = make_stock_entry(pro_order, "Manufacture/Repack") stock_entry = webnotes.bean(stock_entry) + stock_entry.doc.posting_date = "2013-05-12" stock_entry.doc.fiscal_year = "_Test Fiscal Year 2013" stock_entry.doc.fg_completed_qty = 15 stock_entry.run_method("get_items") diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py index 3b529cbe10..ac4b0fab3f 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -243,10 +243,10 @@ class DocType: "item_code": [qty_required, description, stock_uom, min_order_qty] } """ - bom_wise_item_details = {} item_list = [] - + for bom, so_wise_qty in bom_dict.items(): + bom_wise_item_details = {} if self.doc.use_multi_level_bom: # get all raw materials with sub assembly childs for d in webnotes.conn.sql("""select fb.item_code, diff --git a/erpnext/manufacturing/doctype/workstation/workstation.txt b/erpnext/manufacturing/doctype/workstation/workstation.txt index 306ca4ecef..b8355bfe6d 100644 --- a/erpnext/manufacturing/doctype/workstation/workstation.txt +++ b/erpnext/manufacturing/doctype/workstation/workstation.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:17", "docstatus": 0, - "modified": "2013-12-20 19:24:41", + "modified": "2014-01-20 17:49:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,8 +24,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c1ab098298..79644a854e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -1,3 +1,22 @@ +erpnext.patches.1401.enable_all_price_list erpnext.patches.4_0.update_user_properties erpnext.patches.4_0.move_warehouse_user_to_restrictions -erpnext.patches.4_0.new_permissions \ No newline at end of file +erpnext.patches.4_0.new_permissions +erpnext.patches.4_0.update_incharge_name_to_sales_person_in_maintenance_schedule +execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2014-01-03 +execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2014-01-03 +execute:webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') # 2014-01-03 +execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2014-01-03 +execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2014-01-03 +execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2014-01-03 +execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2014-01-03 +execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2014-01-03 +execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2014-01-03 +execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2014-01-03 \ No newline at end of file diff --git a/erpnext/setup/report/__init__.py b/erpnext/patches/1401/__init__.py similarity index 100% rename from erpnext/setup/report/__init__.py rename to erpnext/patches/1401/__init__.py diff --git a/erpnext/patches/1401/enable_all_price_list.py b/erpnext/patches/1401/enable_all_price_list.py new file mode 100644 index 0000000000..9cf141fe67 --- /dev/null +++ b/erpnext/patches/1401/enable_all_price_list.py @@ -0,0 +1,9 @@ +# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.reload_doc("stock", "doctype", "price_list") + webnotes.conn.sql("""update `tabPrice List` set enabled=1""") \ No newline at end of file diff --git a/erpnext/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py b/erpnext/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py new file mode 100644 index 0000000000..b764a7f935 --- /dev/null +++ b/erpnext/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py @@ -0,0 +1,29 @@ +# Copyright (c) 2014, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.reload_doc("stock", "doctype", "price_list") + webnotes.reload_doc("stock", "doctype", "item_price") + + if "buying_or_selling" in webnotes.conn.get_table_columns("Price List"): + webnotes.conn.sql("""update `tabPrice List` set + selling = + case + when buying_or_selling='Selling' + then 1 + end, + buying = + case + when buying_or_selling='Buying' + then 1 + end + """) + webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl + set ip.buying=pl.buying, ip.selling=pl.selling + where ip.price_list=pl.name""") + + webnotes.conn.sql("""update `tabItem Price` set selling=1 where ifnull(selling, 0)=0 and + ifnull(buying, 0)=0""") \ No newline at end of file diff --git a/erpnext/patches/1401/p01_move_related_property_setters_to_custom_field.py b/erpnext/patches/1401/p01_move_related_property_setters_to_custom_field.py new file mode 100644 index 0000000000..cf9221bcfd --- /dev/null +++ b/erpnext/patches/1401/p01_move_related_property_setters_to_custom_field.py @@ -0,0 +1,25 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import webnotes + +def execute(): + webnotes.reload_doc("core", "doctype", "custom_field") + + cf_doclist = webnotes.get_doctype("Custom Field") + + delete_list = [] + 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)) + + delete_list.append(d.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/erpnext/patches/1401/update_billing_status_for_zero_value_order.py b/erpnext/patches/1401/update_billing_status_for_zero_value_order.py new file mode 100644 index 0000000000..afeed55ed4 --- /dev/null +++ b/erpnext/patches/1401/update_billing_status_for_zero_value_order.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import webnotes +from webnotes.utils import flt + +def execute(): + for order_type in ["Sales", "Purchase"]: + for d in webnotes.conn.sql("""select par.name, sum(ifnull(child.qty, 0)) as total_qty + from `tab%s Order` par, `tab%s Order Item` child + where par.name = child.parent and par.docstatus = 1 + and ifnull(par.net_total, 0) = 0 group by par.name""" % + (order_type, order_type), as_dict=1): + + billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0)) + from `tab%s Invoice Item` where %s=%s and docstatus=1""" % + (order_type, "sales_order" if order_type=="Sales" else "purchase_order", '%s'), + (d.name))[0][0]) + + per_billed = ((d.total_qty if billed_qty > d.total_qty else billed_qty)\ + / d.total_qty)*100 + webnotes.conn.set_value(order_type+ " Order", d.name, "per_billed", per_billed) + + if order_type == "Sales": + if per_billed < 0.001: billing_status = "Not Billed" + elif per_billed >= 99.99: billing_status = "Fully Billed" + else: billing_status = "Partly Billed" + + webnotes.conn.set_value("Sales Order", d.name, "billing_status", billing_status) \ No newline at end of file diff --git a/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py new file mode 100644 index 0000000000..2a488f4c8f --- /dev/null +++ b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.reload_doc("support", "doctype", "maintenance_schedule_detail") + webnotes.reload_doc("support", "doctype", "maintenance_schedule_item") + + webnotes.conn.sql("""update `tabMaintenance Schedule Detail` set sales_person=incharge_name""") + webnotes.conn.sql("""update `tabMaintenance Schedule Item` set sales_person=incharge_name""") \ No newline at end of file diff --git a/erpnext/patches/4_0/update_user_properties.py b/erpnext/patches/4_0/update_user_properties.py index 085f2c1883..54aed648a8 100644 --- a/erpnext/patches/4_0/update_user_properties.py +++ b/erpnext/patches/4_0/update_user_properties.py @@ -45,7 +45,11 @@ def update_user_match(): for profile in webnotes.conn.sql_list("""select name from `tabProfile` where enabled=1 and user_type='System User'"""): - perms = webnotes.permissions.get_user_perms(meta, "read", profile) + user_roles = webnotes.get_roles(profile) + + perms = meta.get({"doctype": "DocPerm", "permlevel": 0, + "role": ["in", [["All"] + user_roles]], "read": 1}) + # user does not have required roles if not perms: continue diff --git a/erpnext/patches/june_2013/p03_buying_selling_for_price_list.py b/erpnext/patches/june_2013/p03_buying_selling_for_price_list.py index 2f92fe6a9e..15da085e53 100644 --- a/erpnext/patches/june_2013/p03_buying_selling_for_price_list.py +++ b/erpnext/patches/june_2013/p03_buying_selling_for_price_list.py @@ -8,20 +8,7 @@ from webnotes.utils import cint def execute(): webnotes.reload_doc("stock", "doctype", "price_list") webnotes.reload_doc("stock", "doctype", "item_price") - - try: - for price_list in webnotes.conn.sql_list("""select name from `tabPrice List`"""): - buying, selling = False, False - for b, s in webnotes.conn.sql("""select distinct buying, selling - from `tabItem Price` where price_list_name=%s""", price_list): - buying = buying or cint(b) - selling = selling or cint(s) - - buying_or_selling = "Selling" if selling else "Buying" - webnotes.conn.set_value("Price List", price_list, "buying_or_selling", buying_or_selling) - except webnotes.SQLError, e: - if e.args[0] == 1054: - webnotes.conn.sql("""update `tabPrice List` set buying_or_selling='Selling' - where ifnull(buying_or_selling, '')='' """) - else: - raise \ No newline at end of file + + webnotes.conn.sql("""update `tabPrice List` pl, `tabItem Price` ip + set pl.selling=ip.selling, pl.buying=ip.buying + where pl.name=ip.price_list_name""") \ No newline at end of file diff --git a/erpnext/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py b/erpnext/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py index 3b4ca833f1..b92f7d052a 100644 --- a/erpnext/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py +++ b/erpnext/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py @@ -12,9 +12,7 @@ def execute(): where ip.item_code=i.name""") webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl - set ip.price_list=pl.name, ip.currency=pl.currency, - ip.buying_or_selling=pl.buying_or_selling - where ip.parent=pl.name""") + set ip.price_list=pl.name, ip.currency=pl.currency where ip.parent=pl.name""") webnotes.conn.sql("""update `tabItem Price` set parent=null, parenttype=null, parentfield=null, idx=null""") \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index e455913f59..6e27628732 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -172,18 +172,18 @@ patch_list = [ "patches.july_2013.p05_custom_doctypes_in_list_view", "patches.july_2013.p06_same_sales_rate", "patches.july_2013.p07_repost_billed_amt_in_sales_cycle", - "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2013-07-22", - "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-07-22", - "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-07-22", - "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-07-22", - "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-07-22", - "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-07-22", - "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-07-22", + "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2013-12-26", + "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-12-26", + "execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-12-26", + "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-12-26", + "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-12-26", + "execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-12-26", "patches.july_2013.p08_custom_print_format_net_total_export", "patches.july_2013.p09_remove_website_pyc", "patches.july_2013.p10_change_partner_user_to_website_user", @@ -262,4 +262,13 @@ patch_list = [ "execute:webnotes.delete_doc('DocType', 'Warehouse Type')", "patches.1312.p01_delete_old_stock_reports", "patches.1312.p02_update_item_details_in_item_price", + "patches.1401.p01_move_related_property_setters_to_custom_field", + "patches.1401.p01_make_buying_selling_as_check_box_in_price_list", + "patches.1401.update_billing_status_for_zero_value_order", + "execute:webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') # 2013-12-26", + "execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2013-12-26", + "execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2013-12-26", + "execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2013-12-26", + "patches.1401.enable_all_price_list", ] \ No newline at end of file diff --git a/erpnext/projects/doctype/project/project.txt b/erpnext/projects/doctype/project/project.txt index a1967bb310..4f7e38dcc3 100644 --- a/erpnext/projects/doctype/project/project.txt +++ b/erpnext/projects/doctype/project/project.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 11:55:07", "docstatus": 0, - "modified": "2013-12-20 19:24:17", + "modified": "2014-01-20 17:49:02", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Project", @@ -289,8 +290,8 @@ "search_index": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -299,8 +300,8 @@ "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "role": "All" diff --git a/erpnext/projects/doctype/task/task.txt b/erpnext/projects/doctype/task/task.txt index 7ddd51a494..2dce94f921 100644 --- a/erpnext/projects/doctype/task/task.txt +++ b/erpnext/projects/doctype/task/task.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-29 19:25:50", "docstatus": 0, - "modified": "2013-12-20 19:24:38", + "modified": "2014-01-24 13:01:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -15,7 +15,9 @@ "icon": "icon-check", "max_attachments": 5, "module": "Projects", - "name": "__common__" + "name": "__common__", + "search_fields": "subject", + "title_field": "subject" }, { "doctype": "DocField", @@ -26,8 +28,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/projects/doctype/time_log/time_log.txt b/erpnext/projects/doctype/time_log/time_log.txt index 2ad9d647b9..11fa7d6e6e 100644 --- a/erpnext/projects/doctype/time_log/time_log.txt +++ b/erpnext/projects/doctype/time_log/time_log.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-03 16:38:41", "docstatus": 0, - "modified": "2013-12-20 19:24:39", + "modified": "2014-01-22 16:05:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ { "amend": 1, "cancel": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -204,7 +205,7 @@ { "create": 1, "doctype": "DocPerm", - "match": "owner", + "restricted": 1, "role": "Projects User" }, { diff --git a/erpnext/projects/doctype/time_log_batch/time_log_batch.txt b/erpnext/projects/doctype/time_log_batch/time_log_batch.txt index 458f0ed31b..bc803ea2b6 100644 --- a/erpnext/projects/doctype/time_log_batch/time_log_batch.txt +++ b/erpnext/projects/doctype/time_log_batch/time_log_batch.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-28 17:57:33", "docstatus": 0, - "modified": "2013-12-20 19:24:39", + "modified": "2014-01-20 17:49:34", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js index d902fe1fdc..73099d1f37 100644 --- a/erpnext/public/js/conf.js +++ b/erpnext/public/js/conf.js @@ -24,14 +24,16 @@ $(document).bind('toolbar_setup', function() { wn.provide('wn.ui.misc'); wn.ui.misc.about = function() { if(!wn.ui.misc.about_dialog) { - var d = new wn.ui.Dialog({title: wn._('About ERPNext')}) + var d = new wn.ui.Dialog({title: wn._('About')}) $(d.body).html(repl("
\ -

"+wn._("ERPNext is an open-source web based ERP made by Web Notes Technologies Pvt Ltd. to provide an integrated tool to manage most processes in a small organization. For more information about Web Notes, or to buy hosting servies, go to ")+ - "https://erpnext.com.

\ -

"+wn._("To report an issue, go to ")+"GitHub Issues

\ -
\ +

ERPNext

\ +

"+wn._("An open source ERP made for the web.

") + + "

"+wn._("To report an issue, go to ")+"GitHub Issues

\ +

http://erpnext.org.

\

License: GNU General Public License Version 3

\ +
\ +

© 2014 Web Notes Technologies Pvt. Ltd and contributers

\
", wn.app)); wn.ui.misc.about_dialog = d; diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js index d2fb904419..6a4261c22a 100644 --- a/erpnext/public/js/controllers/stock_controller.js +++ b/erpnext/public/js/controllers/stock_controller.js @@ -28,7 +28,8 @@ erpnext.stock.StockController = wn.ui.form.Controller.extend({ voucher_no: me.frm.doc.name, from_date: me.frm.doc.posting_date, to_date: me.frm.doc.posting_date, - company: me.frm.doc.company + company: me.frm.doc.company, + group_by_voucher: false }; wn.set_route("query-report", "General Ledger"); }, "icon-table"); diff --git a/erpnext/public/js/startup.css b/erpnext/public/js/startup.css index 54c40d4cb0..3777f4c7b6 100644 --- a/erpnext/public/js/startup.css +++ b/erpnext/public/js/startup.css @@ -1,15 +1,3 @@ -h1, h2, h3, h4, h5 { - font-family: Arial, Helvetica, sans-serif; -} - -body { - font-family: Arial, Helvetica, sans-serif; -} - -span, div, td, input, textarea, button, select { - font-family: inherit; -} - .small { font-size: 11.5px; } diff --git a/erpnext/public/js/toolbar.js b/erpnext/public/js/toolbar.js index e0affaf61d..1d6fa919b2 100644 --- a/erpnext/public/js/toolbar.js +++ b/erpnext/public/js/toolbar.js @@ -21,6 +21,6 @@ erpnext.toolbar.setup = function() { '+wn._('Live Chat')+''); } - $("#toolbar-tools").append('
  • \ + $("#toolbar-tools").append('
  • \ Latest Updates
  • '); -} \ No newline at end of file +} diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js index 5b48820c9c..0dfdd07376 100644 --- a/erpnext/public/js/transaction.js +++ b/erpnext/public/js/transaction.js @@ -330,8 +330,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ doctype: tax.doctype, row_id_label: wn.meta.get_label(tax.doctype, "row_id", tax.name) }); - msgprint(msg); - throw msg; + wn.throw(msg); } }, @@ -347,8 +346,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ charge_type_label: wn.meta.get_label(tax.doctype, "charge_type", tax.name), charge_type: tax.charge_type }); - msgprint(msg); - throw msg; + wn.throw(msg); }; var on_previous_row_error = function(row_range) { @@ -363,8 +361,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ row_range: row_range, }); - msgprint(msg); - throw msg; + wn.throw(msg); }; if(cint(tax.included_in_print_rate)) { @@ -511,10 +508,17 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ }, calculate_taxes_and_totals: function() { + this.discount_amount_applied = false; + this._calculate_taxes_and_totals(); + if (wn.meta.get_docfield(this.frm.doc.doctype, "discount_amount")) + this.apply_discount_amount(); + }, + + _calculate_taxes_and_totals: function() { this.validate_conversion_rate(); this.frm.item_doclist = this.get_item_doclist(); this.frm.tax_doclist = this.get_tax_doclist(); - + this.calculate_item_values(); this.initialize_taxes(); this.determine_exclusive_rate && this.determine_exclusive_rate(); @@ -522,18 +526,23 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ this.calculate_taxes(); this.calculate_totals(); this._cleanup(); - + this.show_item_wise_taxes(); }, initialize_taxes: function() { var me = this; + $.each(this.frm.tax_doclist, function(i, tax) { tax.item_wise_tax_detail = {}; - $.each(["tax_amount", "total", + tax_fields = ["total", "tax_amount_after_discount_amount", "tax_amount_for_current_item", "grand_total_for_current_item", - "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"], - function(i, fieldname) { tax[fieldname] = 0.0 }); + "tax_fraction_for_current_item", "grand_total_fraction_for_current_item"] + + if (!me.discount_amount_applied) + tax_fields.push("tax_amount"); + + $.each(tax_fields, function(i, fieldname) { tax[fieldname] = 0.0 }); me.validate_on_previous_row(tax); me.validate_inclusive_tax(tax); @@ -543,31 +552,39 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ calculate_taxes: function() { var me = this; + var actual_tax_dict = {}; + // maintain actual tax rate based on idx + $.each(this.frm.tax_doclist, function(i, tax) { + if (tax.charge_type == "Actual") { + actual_tax_dict[tax.idx] = flt(tax.rate); + } + }); + $.each(this.frm.item_doclist, function(n, item) { var item_tax_map = me._load_item_tax_rate(item.item_tax_rate); - + $.each(me.frm.tax_doclist, function(i, tax) { // tax_amount represents the amount of tax for the current step var current_tax_amount = me.get_current_tax_amount(item, tax, item_tax_map); - me.set_item_tax_amount && me.set_item_tax_amount(item, tax, current_tax_amount); - - // case when net total is 0 but there is an actual type charge - // in this case add the actual amount to tax.tax_amount - // and tax.grand_total_for_current_item for the first such iteration - if(tax.charge_type == "Actual" && - !(current_tax_amount || me.frm.doc.net_total || tax.tax_amount)) { - var zero_net_total_adjustment = flt(tax.rate, precision("tax_amount", tax)); - current_tax_amount += zero_net_total_adjustment; + // Adjust divisional loss to the last item + if (tax.charge_type == "Actual") { + actual_tax_dict[tax.idx] -= current_tax_amount; + if (n == me.frm.item_doclist.length - 1) { + current_tax_amount += actual_tax_dict[tax.idx] } - + } + // store tax_amount for current item as it will be used for // charge type = 'On Previous Row Amount' tax.tax_amount_for_current_item = current_tax_amount; // accumulate tax amount into tax.tax_amount - tax.tax_amount += current_tax_amount; + if (!me.discount_amount_applied) + tax.tax_amount += current_tax_amount; + + tax.tax_amount_after_discount_amount += current_tax_amount; // for buying if(tax.category) { @@ -592,9 +609,32 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ // in tax.total, accumulate grand total for each item tax.total += tax.grand_total_for_current_item; + + // set precision in the last item iteration + if (n == me.frm.item_doclist.length - 1) { + me.round_off_totals(tax); + + // adjust Discount Amount loss in last tax iteration + if ((i == me.frm.tax_doclist.length - 1) && me.discount_amount_applied) + me.adjust_discount_amount_loss(tax); + } }); }); }, + + round_off_totals: function(tax) { + tax.total = flt(tax.total, precision("total", tax)); + tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax)); + tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, + precision("tax_amount", tax)); + }, + + adjust_discount_amount_loss: function(tax) { + var discount_amount_loss = this.frm.doc.grand_total - flt(this.frm.doc.discount_amount) - tax.total; + tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount + + discount_amount_loss, precision("tax_amount", tax)); + tax.total = flt(tax.total + discount_amount_loss, precision("total", tax)); + }, get_current_tax_amount: function(item, tax, item_tax_map) { var tax_rate = this._get_tax_rate(tax, item_tax_map); @@ -617,9 +657,8 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ } else if(tax.charge_type == "On Previous Row Total") { current_tax_amount = (tax_rate / 100.0) * this.frm.tax_doclist[cint(tax.row_id) - 1].grand_total_for_current_item; - } - + current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax)); // store tax breakup for each item diff --git a/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt index e7588c4522..05c3c598ca 100644 --- a/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt +++ b/erpnext/selling/Print Format/Quotation Classic/Quotation Classic.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 19:55:11", + "modified": "2013-12-26 17:45:37", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Quotation", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt index 20d380dcbf..35850e62eb 100644 --- a/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt +++ b/erpnext/selling/Print Format/Quotation Modern/Quotation Modern.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 20:12:11", + "modified": "2013-12-26 17:45:15", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Quotation", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt index c5b4cb92b3..3b4452666b 100644 --- a/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt +++ b/erpnext/selling/Print Format/Quotation Spartan/Quotation Spartan.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 19:53:01", + "modified": "2013-12-26 17:45:50", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Quotation", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt index 7f2748ac0c..7ee19c0f2d 100644 --- a/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt +++ b/erpnext/selling/Print Format/Sales Order Classic/Sales Order Classic.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 19:45:49", + "modified": "2013-12-26 17:35:51", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt index e4102b2359..7cf481d7b8 100644 --- a/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt +++ b/erpnext/selling/Print Format/Sales Order Modern/Sales Order Modern.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 20:12:23", + "modified": "2013-12-26 17:34:24", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt index 105b65b21b..8da27b7d70 100644 --- a/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt +++ b/erpnext/selling/Print Format/Sales Order Spartan/Sales Order Spartan.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:30:51", "docstatus": 0, - "modified": "2013-08-07 19:45:59", + "modified": "2013-12-26 17:35:29", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Selling", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/selling/doctype/campaign/campaign.js b/erpnext/selling/doctype/campaign/campaign.js index 6271a163cb..33479579a5 100644 --- a/erpnext/selling/doctype/campaign/campaign.js +++ b/erpnext/selling/doctype/campaign/campaign.js @@ -1,13 +1,2 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - - - -//--------- ONLOAD ------------- -cur_frm.cscript.onload = function(doc, cdt, cdn) { - -} - -cur_frm.cscript.refresh = function(doc, cdt, cdn) { - -} \ No newline at end of file +// License: GNU General Public License v3. See license.txt \ No newline at end of file diff --git a/erpnext/selling/doctype/campaign/campaign.txt b/erpnext/selling/doctype/campaign/campaign.txt index 07cddd419f..55c459cea3 100644 --- a/erpnext/selling/doctype/campaign/campaign.txt +++ b/erpnext/selling/doctype/campaign/campaign.txt @@ -2,12 +2,13 @@ { "creation": "2013-01-10 16:34:18", "docstatus": 0, - "modified": "2013-12-20 19:23:58", + "modified": "2014-01-20 17:48:27", "modified_by": "Administrator", "owner": "Administrator" }, { "allow_import": 1, + "allow_rename": 1, "autoname": "field:campaign_name", "description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ", "doctype": "DocType", @@ -26,6 +27,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -76,8 +78,8 @@ "width": "300px" }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "import": 0, "report": 0, @@ -85,16 +87,16 @@ "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "report": 1, "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "report": 1, "role": "Sales Master Manager", diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index e8130aec5e..f2568d6854 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -18,7 +18,7 @@ cur_frm.cscript.load_defaults = function(doc, dt, dn) { cur_frm.add_fetch('lead_name', 'company_name', 'customer_name'); cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate'); -cur_frm.cscript.refresh = function(doc,dt,dn) { +cur_frm.cscript.refresh = function(doc, dt, dn) { cur_frm.cscript.setup_dashboard(doc); erpnext.hide_naming_series(); @@ -107,21 +107,21 @@ cur_frm.cscript.make_contact = function() { } -cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) { +cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) { return{ filters:{'is_group': 'No'} } } -cur_frm.fields_dict.lead_name.get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict.lead_name.get_query = function(doc, cdt, cdn) { return{ query: "erpnext.controllers.queries.lead_query" } } -cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) { return{ - filters:{'buying_or_selling': "Selling"} + filters:{'selling': 1} } } diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 05e8112876..06b80bbca6 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes - +from webnotes.utils import cstr from webnotes.model.doc import Document, make_autoname from webnotes import msgprint, _ import webnotes.defaults @@ -225,7 +225,12 @@ def get_customer_details(customer): out[f] = customer.get("default_" + f) # price list - out.selling_price_list = customer.price_list or webnotes.conn.get_value("Customer Group", + from webnotes.defaults import get_defaults_for + user_default_price_list = get_defaults_for(webnotes.session.user).get("selling_price_list") + user_default_price_list = cstr(user_default_price_list) \ + if not isinstance(user_default_price_list, list) else "" + + out.selling_price_list = user_default_price_list or customer.price_list or webnotes.conn.get_value("Customer Group", customer.customer_group, "default_price_list") if out.selling_price_list: @@ -237,5 +242,4 @@ def get_customer_details(customer): "sales_designation": d.sales_designation } for d in customer_bean.doclist.get({"doctype":"Sales Team"})] - return out - \ No newline at end of file + return out \ No newline at end of file diff --git a/erpnext/selling/doctype/customer/customer.txt b/erpnext/selling/doctype/customer/customer.txt index aaf4b9d6d6..6eabaf0a37 100644 --- a/erpnext/selling/doctype/customer/customer.txt +++ b/erpnext/selling/doctype/customer/customer.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-11 14:26:44", "docstatus": 0, - "modified": "2013-12-25 11:15:05", + "modified": "2014-01-20 17:48:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -345,6 +345,7 @@ "amend": 0, "cancel": 0, "create": 1, + "delete": 0, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -355,14 +356,16 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "role": "Sales User" }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -373,6 +376,7 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "role": "Sales Master Manager", diff --git a/erpnext/selling/doctype/installation_note/installation_note.txt b/erpnext/selling/doctype/installation_note/installation_note.txt index d8d8b6dbff..5e519829df 100644 --- a/erpnext/selling/doctype/installation_note/installation_note.txt +++ b/erpnext/selling/doctype/installation_note/installation_note.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-30 13:13:06", "docstatus": 0, - "modified": "2014-01-02 10:25:49", + "modified": "2014-01-20 17:48:47", "modified_by": "Administrator", "owner": "Administrator" }, @@ -265,6 +265,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -276,6 +277,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1, "submit": 0 diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/selling/doctype/lead/lead.js index 41f679e34a..228d790e9e 100644 --- a/erpnext/selling/doctype/lead/lead.js +++ b/erpnext/selling/doctype/lead/lead.js @@ -7,18 +7,18 @@ wn.provide("erpnext"); erpnext.LeadController = wn.ui.form.Controller.extend({ setup: function() { - this.frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { + this.frm.fields_dict.customer.get_query = function(doc, cdt, cdn) { return { query: "erpnext.controllers.queries.customer_query" } } }, onload: function() { if(cur_frm.fields_dict.lead_owner.df.options.match(/^Profile/)) { - cur_frm.fields_dict.lead_owner.get_query = function(doc,cdt,cdn) { + cur_frm.fields_dict.lead_owner.get_query = function(doc, cdt, cdn) { return { query:"webnotes.core.doctype.profile.profile.profile_query" } } } if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) { - cur_frm.fields_dict.contact_by.get_query = function(doc,cdt,cdn) { + cur_frm.fields_dict.contact_by.get_query = function(doc, cdt, cdn) { return { query:"webnotes.core.doctype.profile.profile.profile_query" } } } @@ -90,4 +90,4 @@ erpnext.LeadController = wn.ui.form.Controller.extend({ } }); -$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm})); \ No newline at end of file +$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm})); diff --git a/erpnext/selling/doctype/lead/lead.txt b/erpnext/selling/doctype/lead/lead.txt index dc8bcdbb1a..caf677f524 100644 --- a/erpnext/selling/doctype/lead/lead.txt +++ b/erpnext/selling/doctype/lead/lead.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-10 11:45:37", "docstatus": 0, - "modified": "2013-12-20 19:24:12", + "modified": "2014-01-20 17:48:53", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ }, { "amend": 0, + "cancel": 0, "create": 1, "doctype": "DocPerm", "email": 1, @@ -398,12 +399,12 @@ "print_hide": 1 }, { - "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Manager" }, { - "cancel": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User" } diff --git a/erpnext/selling/doctype/opportunity/opportunity.txt b/erpnext/selling/doctype/opportunity/opportunity.txt index b0fe782a19..8cb0f2531b 100644 --- a/erpnext/selling/doctype/opportunity/opportunity.txt +++ b/erpnext/selling/doctype/opportunity/opportunity.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 18:50:30", "docstatus": 0, - "modified": "2014-01-02 11:10:51", + "modified": "2014-01-20 17:48:58", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt index 3657e4acef..f12a2a738e 100644 --- a/erpnext/selling/doctype/quotation/quotation.txt +++ b/erpnext/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-12-20 19:24:25", + "modified": "2014-01-20 17:49:16", "modified_by": "Administrator", "owner": "Administrator" }, @@ -460,6 +460,13 @@ "print_hide": 1, "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "Company:company:default_currency" + }, { "doctype": "DocField", "fieldname": "totals", @@ -846,6 +853,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Manager", "submit": 1, @@ -855,6 +863,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales User", "submit": 1, @@ -864,6 +873,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Customer", "submit": 0, @@ -873,6 +883,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Maintenance Manager", "submit": 1, @@ -882,6 +893,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Maintenance User", "submit": 1, diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index 00cbd6cd9e..650095c848 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -28,6 +28,7 @@ class TestQuotation(unittest.TestCase): sales_order[0]["delivery_date"] = "2014-01-01" sales_order[0]["naming_series"] = "_T-Quotation-" + sales_order[0]["transaction_date"] = "2013-05-12" webnotes.bean(sales_order).insert() diff --git a/erpnext/selling/doctype/sales_bom/sales_bom.txt b/erpnext/selling/doctype/sales_bom/sales_bom.txt index cd1ea28d85..ae40e10f80 100644 --- a/erpnext/selling/doctype/sales_bom/sales_bom.txt +++ b/erpnext/selling/doctype/sales_bom/sales_bom.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-20 11:53:21", "docstatus": 0, - "modified": "2013-12-20 19:24:28", + "modified": "2014-01-20 17:49:19", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -78,22 +79,22 @@ "reqd": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Manager", "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales User", "write": 1 diff --git a/erpnext/selling/doctype/sales_order/sales_order.txt b/erpnext/selling/doctype/sales_order/sales_order.txt index f9582fb213..d187f67b89 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.txt +++ b/erpnext/selling/doctype/sales_order/sales_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-18 12:39:59", "docstatus": 0, - "modified": "2013-12-20 19:24:32", + "modified": "2014-01-20 17:49:23", "modified_by": "Administrator", "owner": "Administrator" }, @@ -480,6 +480,13 @@ "read_only": 1, "width": "150px" }, + { + "doctype": "DocField", + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "Company:company:default_currency" + }, { "doctype": "DocField", "fieldname": "totals", @@ -902,6 +909,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "report": 1, "role": "Sales User", @@ -912,6 +920,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "report": 1, "role": "Maintenance User", @@ -919,10 +928,12 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Customer" } diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index 68e6775b49..4ee166c35a 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -56,6 +56,7 @@ class TestSalesOrder(unittest.TestCase): self.assertEquals(len([d for d in si if d["doctype"]=="Sales Invoice Item"]), 1) si = webnotes.bean(si) + si.doc.posting_date = "2013-10-10" si.insert() si.submit() diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py index 8671210de5..6eaab482a4 100644 --- a/erpnext/selling/doctype/sms_center/sms_center.py +++ b/erpnext/selling/doctype/sms_center/sms_center.py @@ -10,52 +10,49 @@ from webnotes.model.bean import copy_doclist from webnotes.model.code import get_obj from webnotes import msgprint - -# ---------- - class DocType: - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - def create_receiver_list(self): - rec, where_clause = '', '' - if self.doc.send_to == 'All Customer Contact': - where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(customer, '') != ''" - if self.doc.send_to == 'All Supplier Contact': - where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(supplier, '') != ''" - if self.doc.send_to == 'All Sales Partner Contact': - where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_partner = '%s'" % self.doc.sales_partner or " and ifnull(sales_partner, '') != ''" + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist - if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']: - rec = webnotes.conn.sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause) - elif self.doc.send_to == 'All Lead (Open)': - rec = webnotes.conn.sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") - elif self.doc.send_to == 'All Employee (Active)': - where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" - where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" - rec = webnotes.conn.sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) - elif self.doc.send_to == 'All Sales Person': - rec = webnotes.conn.sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") - rec_list = '' - for d in rec: - rec_list += d[0] + ' - ' + d[1] + '\n' - self.doc.receiver_list = rec_list + def create_receiver_list(self): + rec, where_clause = '', '' + if self.doc.send_to == 'All Customer Contact': + where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(customer, '') != ''" + if self.doc.send_to == 'All Supplier Contact': + where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(supplier, '') != ''" + if self.doc.send_to == 'All Sales Partner Contact': + where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_partner = '%s'" % self.doc.sales_partner or " and ifnull(sales_partner, '') != ''" - def get_receiver_nos(self): - receiver_nos = [] - for d in self.doc.receiver_list.split('\n'): - receiver_no = d - if '-' in d: - receiver_no = receiver_no.split('-')[1] - if receiver_no.strip(): - receiver_nos.append(cstr(receiver_no).strip()) - return receiver_nos + if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']: + rec = webnotes.conn.sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause) + elif self.doc.send_to == 'All Lead (Open)': + rec = webnotes.conn.sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") + elif self.doc.send_to == 'All Employee (Active)': + where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" + where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" + rec = webnotes.conn.sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) + elif self.doc.send_to == 'All Sales Person': + rec = webnotes.conn.sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") + rec_list = '' + for d in rec: + rec_list += d[0] + ' - ' + d[1] + '\n' + self.doc.receiver_list = rec_list - def send_sms(self): - if not self.doc.message: - msgprint("Please enter message before sending") - else: - receiver_list = self.get_receiver_nos() - if receiver_list: - msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message))) + def get_receiver_nos(self): + receiver_nos = [] + for d in self.doc.receiver_list.split('\n'): + receiver_no = d + if '-' in d: + receiver_no = receiver_no.split('-')[1] + if receiver_no.strip(): + receiver_nos.append(cstr(receiver_no).strip()) + return receiver_nos + + def send_sms(self): + if not self.doc.message: + msgprint("Please enter message before sending") + else: + receiver_list = self.get_receiver_nos() + if receiver_list: + msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message))) \ No newline at end of file diff --git a/erpnext/selling/page/sales_browser/sales_browser.py b/erpnext/selling/page/sales_browser/sales_browser.py index 6791ecf751..bb1a094e76 100644 --- a/erpnext/selling/page/sales_browser/sales_browser.py +++ b/erpnext/selling/page/sales_browser/sales_browser.py @@ -7,17 +7,17 @@ import webnotes @webnotes.whitelist() def get_children(): - ctype = webnotes.form_dict.get('ctype') - webnotes.form_dict['parent_field'] = 'parent_' + ctype.lower().replace(' ', '_') + ctype = webnotes.local.form_dict.get('ctype') + webnotes.local.form_dict['parent_field'] = 'parent_' + ctype.lower().replace(' ', '_') if not webnotes.form_dict.get('parent'): - webnotes.form_dict['parent'] = '' + webnotes.local.form_dict['parent'] = '' return webnotes.conn.sql("""select name as value, if(is_group='Yes', 1, 0) as expandable from `tab%(ctype)s` where docstatus < 2 and ifnull(%(parent_field)s,'') = "%(parent)s" - order by name""" % webnotes.form_dict, as_dict=1) + order by name""" % webnotes.local.form_dict, as_dict=1) @webnotes.whitelist() def add_node(): diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 8ca076d755..e2cde557e7 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -49,7 +49,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ if(this.frm.fields_dict.selling_price_list) { this.frm.set_query("selling_price_list", function() { - return { filters: { buying_or_selling: "Selling" } }; + return { filters: { selling: 1 } }; }); } @@ -194,6 +194,10 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.calculate_taxes_and_totals(); }, + + discount_amount: function() { + this.calculate_taxes_and_totals(); + }, commission_rate: function() { this.calculate_commission(); @@ -279,15 +283,17 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ calculate_item_values: function() { var me = this; - $.each(this.frm.item_doclist, function(i, item) { - wn.model.round_floats_in(item); - item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item)); - - me._set_in_company_currency(item, "ref_rate", "base_ref_rate"); - me._set_in_company_currency(item, "export_rate", "basic_rate"); - me._set_in_company_currency(item, "export_amount", "amount"); - }); + if (!this.discount_amount_applied) { + $.each(this.frm.item_doclist, function(i, item) { + wn.model.round_floats_in(item); + item.export_amount = flt(item.export_rate * item.qty, precision("export_amount", item)); + + me._set_in_company_currency(item, "ref_rate", "base_ref_rate"); + me._set_in_company_currency(item, "export_rate", "basic_rate"); + me._set_in_company_currency(item, "export_amount", "amount"); + }); + } }, determine_exclusive_rate: function() { @@ -310,11 +316,11 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ cumulated_tax_fraction += tax.tax_fraction_for_current_item; }); - if(cumulated_tax_fraction) { + if(cumulated_tax_fraction && !me.discount_amount_applied) { item.amount = flt( (item.export_amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction), precision("amount", item)); - + item.basic_rate = flt(item.amount / item.qty, precision("basic_rate", item)); if(item.adj_rate == 100) { @@ -354,18 +360,20 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ calculate_net_total: function() { var me = this; - this.frm.doc.net_total = this.frm.doc.net_total_export = 0.0; + $.each(this.frm.item_doclist, function(i, item) { me.frm.doc.net_total += item.amount; me.frm.doc.net_total_export += item.export_amount; }); - + wn.model.round_floats_in(this.frm.doc, ["net_total", "net_total_export"]); }, calculate_totals: function() { + var me = this; var tax_count = this.frm.tax_doclist.length; + this.frm.doc.grand_total = flt( tax_count ? this.frm.tax_doclist[tax_count - 1].total : this.frm.doc.net_total, precision("grand_total")); @@ -374,13 +382,56 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total, precision("other_charges_total")); - this.frm.doc.other_charges_total_export = flt( - this.frm.doc.grand_total_export - this.frm.doc.net_total_export, + this.frm.doc.other_charges_total_export = flt(this.frm.doc.grand_total_export - + this.frm.doc.net_total_export + flt(this.frm.doc.discount_amount), precision("other_charges_total_export")); this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total); this.frm.doc.rounded_total_export = Math.round(this.frm.doc.grand_total_export); }, + + apply_discount_amount: function() { + var me = this; + var distributed_amount = 0.0; + + if (this.frm.doc.discount_amount) { + var grand_total_for_discount_amount = this.get_grand_total_for_discount_amount(); + // calculate item amount after Discount Amount + if (grand_total_for_discount_amount) { + $.each(this.frm.item_doclist, function(i, item) { + distributed_amount = flt(me.frm.doc.discount_amount) * item.amount / grand_total_for_discount_amount; + item.amount = flt(item.amount - distributed_amount, precision("amount", item)); + }); + + this.discount_amount_applied = true; + this._calculate_taxes_and_totals(); + } + } + }, + + get_grand_total_for_discount_amount: function() { + var me = this; + var total_actual_tax = 0.0; + var actual_taxes_dict = {}; + + $.each(this.frm.tax_doclist, function(i, tax) { + if (tax.charge_type == "Actual") + actual_taxes_dict[tax.idx] = tax.tax_amount; + else if (actual_taxes_dict[tax.row_id] !== null) { + actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100; + actual_taxes_dict[tax.idx] = actual_tax_amount; + } + }); + + $.each(actual_taxes_dict, function(key, value) { + if (value) + total_actual_tax += value; + }); + + grand_total_for_discount_amount = flt(this.frm.doc.grand_total - total_actual_tax, + precision("grand_total")); + return grand_total_for_discount_amount; + }, calculate_outstanding_amount: function() { // NOTE: diff --git a/erpnext/selling/utils.py b/erpnext/selling/utils.py index 7949e472dd..ed3711d32c 100644 --- a/erpnext/selling/utils.py +++ b/erpnext/selling/utils.py @@ -3,8 +3,8 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _ -from webnotes.utils import flt, cint, comma_and +from webnotes import _, throw +from webnotes.utils import flt, cint import json def get_customer_list(doctype, txt, searchfield, start, page_len, filters): @@ -100,7 +100,7 @@ def _get_item_code(barcode=None, serial_no=None): where name=%s""", serial_no) if not item_code: - msgprint(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no), raise_exception=True) + throw(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no)) return item_code[0] @@ -111,22 +111,26 @@ def _validate_item_details(args, item): # validate if sales item or service item if args.order_type == "Maintenance": if item.is_service_item != "Yes": - msgprint(_("Item") + (" %s: " % item.name) + + throw(_("Item") + (" %s: " % item.name) + _("not a service item.") + - _("Please select a service item or change the order type to Sales."), - raise_exception=True) + _("Please select a service item or change the order type to Sales.")) elif item.is_sales_item != "Yes": - msgprint(_("Item") + (" %s: " % item.name) + _("not a sales item"), - raise_exception=True) + throw(_("Item") + (" %s: " % item.name) + _("not a sales item")) def _get_basic_details(args, item_bean, warehouse_fieldname): item = item_bean.doc + from webnotes.defaults import get_user_default_as_list + user_default_warehouse_list = get_user_default_as_list('warehouse') + user_default_warehouse = user_default_warehouse_list[0] \ + if len(user_default_warehouse_list)==1 else "" + out = webnotes._dict({ "item_code": item.name, "description": item.description_html or item.description, - warehouse_fieldname: item.default_warehouse or args.get(warehouse_fieldname), + warehouse_fieldname: user_default_warehouse or item.default_warehouse \ + or args.get(warehouse_fieldname), "income_account": item.default_income_account or args.income_account \ or webnotes.conn.get_value("Company", args.company, "default_income_account"), "expense_account": item.purchase_account or args.expense_account \ @@ -146,8 +150,10 @@ def _get_basic_details(args, item_bean, warehouse_fieldname): return out def _get_price_list_rate(args, item_bean, meta): - ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price` - where price_list=%s and item_code=%s and buying_or_selling='Selling'""", + ref_rate = webnotes.conn.sql("""select ip.ref_rate from + `tabItem Price` ip, `tabPrice List` pl + where ip.price_list=pl.name and ip.price_list=%s and + ip.item_code=%s and ip.selling=1 and pl.enabled=1""", (args.selling_price_list, args.item_code), as_dict=1) if not ref_rate: @@ -207,4 +213,4 @@ def apply_pos_settings(pos_settings, opts): if out.get("warehouse"): out["actual_qty"] = get_available_qty(opts.item_code, out.get("warehouse")).get("actual_qty") - return out \ No newline at end of file + return out diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.js b/erpnext/setup/doctype/authorization_rule/authorization_rule.js index 66b14a85ba..b814965ddd 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.js +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.js @@ -1,114 +1,113 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt - - -//--------- ONLOAD ------------- -cur_frm.cscript.onload = function(doc, cdt, cdn) { - -} - // Settings Module +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if (doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') + hide_field('master_name'); + else + unhide_field('master_name'); -cur_frm.cscript.refresh = function(doc,cdt,cdn){ - + if (doc.based_on == 'Not Applicable') + hide_field('value'); + else + unhide_field('value'); - if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') hide_field('master_name'); - else unhide_field('master_name'); - - if(doc.based_on == 'Not Applicable') hide_field('value'); - else unhide_field('value'); - - if(doc.transaction == 'Appraisal'){ - hide_field(['master_name','system_role', 'system_user']); - unhide_field(['to_emp','to_designation']); - if(doc.transaction == 'Appraisal') hide_field('value'); - else unhide_field('value'); - } - else { - unhide_field(['master_name','system_role', 'system_user','value']); - hide_field(['to_emp','to_designation']); - } + if (doc.transaction == 'Appraisal') { + hide_field(['master_name','system_role', 'system_user']); + unhide_field(['to_emp','to_designation']); + + if (doc.transaction == 'Appraisal') + hide_field('value'); + else + unhide_field('value'); + } + else { + unhide_field(['master_name','system_role', 'system_user','value']); + hide_field(['to_emp','to_designation']); + } } -cur_frm.cscript.based_on = function(doc){ - if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable'){ - doc.master_name = ''; - refresh_field('master_name'); - hide_field('master_name'); - } - else{ - unhide_field('master_name'); - } - - if(doc.based_on == 'Not Applicable') { - doc.value =0; - refresh_field('value'); - hide_field('value'); - } - else unhide_field('value'); +cur_frm.cscript.based_on = function(doc) { + if (doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') { + doc.master_name = ''; + refresh_field('master_name'); + hide_field('master_name'); + } + else + unhide_field('master_name'); + + if (doc.based_on == 'Not Applicable') { + doc.value =0; + refresh_field('value'); + hide_field('value'); + } + else + unhide_field('value'); } -cur_frm.cscript.transaction = function(doc,cdt,cdn){ - if (doc.transaction == 'Appraisal'){ - doc.master_name = doc.system_role = doc.system_user = ''; - refresh_many(['master_name','system_role', 'system_user']); - hide_field(['master_name','system_role', 'system_user']); - unhide_field(['to_emp','to_designation']); - doc.value =0; - refresh_many('value'); - hide_field('value'); - } - else { - unhide_field(['master_name','system_role', 'system_user','value']); - hide_field(['to_emp','to_designation']); - } - - if(doc.transaction == 'Appraisal') doc.based_on == 'Not Applicable'; +cur_frm.cscript.transaction = function(doc, cdt, cdn){ + if (doc.transaction == 'Appraisal') { + doc.based_on == 'Not Applicable'; + doc.master_name = doc.system_role = doc.system_user = ''; + refresh_many(['master_name','system_role', 'system_user', 'based_on']); + hide_field(['master_name','system_role', 'system_user']); + unhide_field(['to_emp','to_designation']); + doc.value = 0; + refresh_many('value'); + hide_field('value'); + } + else { + unhide_field(['master_name','system_role', 'system_user','value']); + hide_field(['to_emp','to_designation']); + } + } +cur_frm.fields_dict.system_user.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query" } +} -cur_frm.fields_dict.system_user.get_query = function(doc,cdt,cdn) { - return{ query:"webnotes.core.doctype.profile.profile.profile_query" } } - -cur_frm.fields_dict.approving_user.get_query = function(doc,cdt,cdn) { - return{ query:"webnotes.core.doctype.profile.profile.profile_query" } } +cur_frm.fields_dict.approving_user.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query" } +} cur_frm.fields_dict['approving_role'].get_query = cur_frm.fields_dict['system_role'].get_query; // System Role Trigger // ----------------------- cur_frm.fields_dict['system_role'].get_query = function(doc) { - return{ - filters:[ - ['Role', 'name', 'not in', 'Administrator, Guest, All'] - ] - } + return { + filters:[ + ['Role', 'name', 'not in', 'Administrator, Guest, All'] + ] + } } // Master Name Trigger // -------------------- -cur_frm.fields_dict['master_name'].get_query = function(doc){ - if(doc.based_on == 'Customerwise Discount') - return { - doctype: "Customer", - filters:[ - ['Customer', 'docstatus', '!=', 2] - ] - } - else if(doc.based_on == 'Itemwise Discount') - return { - doctype: "Item", - query: "erpnext.controllers.queries.item_query" - } - else - return { - filters: [ - ['Item', 'name', '=', 'cheating done to avoid null'] - ] - } +cur_frm.fields_dict['master_name'].get_query = function(doc) { + if (doc.based_on == 'Customerwise Discount') + return { + doctype: "Customer", + filters:[ + ['Customer', 'docstatus', '!=', 2] + ] + } + else if (doc.based_on == 'Itemwise Discount') + return { + doctype: "Item", + query: "erpnext.controllers.queries.item_query" + } + else + return { + filters: [ + ['Item', 'name', '=', 'cheating done to avoid null'] + ] + } } -cur_frm.fields_dict.to_emp.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query" } } \ No newline at end of file +cur_frm.fields_dict.to_emp.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query" } +} diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.txt b/erpnext/setup/doctype/authorization_rule/authorization_rule.txt index 36467f2f4f..24b91d58ab 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.txt +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:22", "docstatus": 0, - "modified": "2013-12-20 19:23:55", + "modified": "2014-01-20 17:48:24", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/setup/doctype/brand/brand.txt b/erpnext/setup/doctype/brand/brand.txt index 3dcb016166..3e67b9ff62 100644 --- a/erpnext/setup/doctype/brand/brand.txt +++ b/erpnext/setup/doctype/brand/brand.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:27:54", "docstatus": 0, - "modified": "2013-12-20 19:23:58", + "modified": "2014-01-20 17:48:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -62,6 +62,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Master Manager", "write": 1 @@ -70,20 +71,24 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "submit": 0, "write": 0 }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" } diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 12281b4415..34e5ca4a59 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/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,24 @@ class DocType: account.insert() def set_default_accounts(self): - accounts = { - "default_income_account": "Sales", - "default_expense_account": "Cost of Goods Sold", + 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({ "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" + }) - 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) + 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" + }) def create_default_cost_center(self): cc_list = [ diff --git a/erpnext/setup/doctype/company/company.txt b/erpnext/setup/doctype/company/company.txt index 1e763ea678..4159c51834 100644 --- a/erpnext/setup/doctype/company/company.txt +++ b/erpnext/setup/doctype/company/company.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-10 08:35:39", "docstatus": 0, - "modified": "2013-12-20 19:23:59", + "modified": "2014-01-20 17:48:28", "modified_by": "Administrator", "owner": "Administrator" }, @@ -351,8 +351,9 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "report": 1, "role": "System Manager", @@ -360,6 +361,7 @@ "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "All" } diff --git a/erpnext/setup/doctype/currency/currency.txt b/erpnext/setup/doctype/currency/currency.txt index 709e360204..6bd2b1ca35 100644 --- a/erpnext/setup/doctype/currency/currency.txt +++ b/erpnext/setup/doctype/currency/currency.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-28 10:06:02", "docstatus": 0, - "modified": "2013-12-20 19:24:00", + "modified": "2014-01-20 17:48:31", "modified_by": "Administrator", "owner": "Administrator" }, @@ -90,8 +90,9 @@ "options": "\n#,###.##\n#.###,##\n# ###.##\n#,###.###\n#,##,###.##\n#.###\n#,###" }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "submit": 0, @@ -99,8 +100,9 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "submit": 0, @@ -110,12 +112,14 @@ "amend": 0, "cancel": 0, "create": 1, + "delete": 0, "doctype": "DocPerm", "role": "Purchase Master Manager", "submit": 0, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "All" } diff --git a/erpnext/setup/doctype/currency_exchange/currency_exchange.txt b/erpnext/setup/doctype/currency_exchange/currency_exchange.txt index f0f5c39cc8..adaf12508a 100644 --- a/erpnext/setup/doctype/currency_exchange/currency_exchange.txt +++ b/erpnext/setup/doctype/currency_exchange/currency_exchange.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-20 15:40:29", "docstatus": 0, - "modified": "2013-12-20 19:24:00", + "modified": "2014-01-20 17:48:31", "modified_by": "Administrator", "owner": "Administrator" }, @@ -63,19 +63,23 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts Manager", "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" } diff --git a/erpnext/setup/doctype/customer_group/customer_group.txt b/erpnext/setup/doctype/customer_group/customer_group.txt index 5b7158fbf6..59f52c6727 100644 --- a/erpnext/setup/doctype/customer_group/customer_group.txt +++ b/erpnext/setup/doctype/customer_group/customer_group.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:23", "docstatus": 0, - "modified": "2013-12-20 19:24:01", + "modified": "2014-01-20 17:48:33", "modified_by": "Administrator", "owner": "Administrator" }, @@ -29,6 +29,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -141,22 +142,22 @@ "report_hide": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/setup/doctype/email_digest/email_digest.txt b/erpnext/setup/doctype/email_digest/email_digest.txt index ca35916437..2ac3998a7d 100644 --- a/erpnext/setup/doctype/email_digest/email_digest.txt +++ b/erpnext/setup/doctype/email_digest/email_digest.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-21 14:15:31", "docstatus": 0, - "modified": "2013-12-20 19:24:05", + "modified": "2014-01-20 17:48:39", "modified_by": "Administrator", "owner": "Administrator" }, @@ -24,6 +24,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Email Digest", @@ -348,8 +349,8 @@ "label": "Stub" }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "permlevel": 0, @@ -359,8 +360,8 @@ }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "permlevel": 1 } diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index 02fe374c13..7e79c95038 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -5,10 +5,8 @@ from __future__ import unicode_literals import webnotes from webnotes.utils.nestedset import DocTypeNestedSet -from webnotes.webutils import WebsiteGenerator -from webnotes.webutils import delete_page_cache -class DocType(DocTypeNestedSet, WebsiteGenerator): +class DocType(DocTypeNestedSet): def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist @@ -16,35 +14,12 @@ class DocType(DocTypeNestedSet, WebsiteGenerator): def on_update(self): DocTypeNestedSet.on_update(self) - WebsiteGenerator.on_update(self) self.validate_name_with_item() - invalidate_cache_for(self.doc.name) - self.validate_one_root() def validate_name_with_item(self): if webnotes.conn.exists("Item", self.doc.name): webnotes.msgprint("An item exists with same name (%s), please change the \ item group name or rename the item" % self.doc.name, raise_exception=1) - -def get_group_item_count(item_group): - child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(item_group)]) - return webnotes.conn.sql("""select count(*) from `tabItem` - where docstatus = 0 and show_in_website = 1 - and (item_group in (%s) - or name in (select parent from `tabWebsite Item Group` - where item_group in (%s))) """ % (child_groups, child_groups))[0][0] - -def get_parent_item_groups(item_group_name): - item_group = webnotes.doc("Item Group", item_group_name) - return webnotes.conn.sql("""select name, page_name from `tabItem Group` - where lft <= %s and rgt >= %s - and ifnull(show_in_website,0)=1 - order by lft asc""", (item_group.lft, item_group.rgt), as_dict=True) - -def invalidate_cache_for(item_group): - for i in get_parent_item_groups(item_group): - if i.page_name: - delete_page_cache(i.page_name) diff --git a/erpnext/setup/doctype/item_group/item_group.txt b/erpnext/setup/doctype/item_group/item_group.txt index 83e32b218b..71be22519c 100644 --- a/erpnext/setup/doctype/item_group/item_group.txt +++ b/erpnext/setup/doctype/item_group/item_group.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-28 10:35:29", "docstatus": 0, - "modified": "2013-12-20 19:24:10", + "modified": "2014-01-20 17:48:49", "modified_by": "Administrator", "owner": "Administrator" }, @@ -184,6 +184,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material Manager", "submit": 0, @@ -193,28 +194,33 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "submit": 0, "write": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Master Manager", "submit": 0, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" } diff --git a/erpnext/setup/doctype/print_heading/print_heading.txt b/erpnext/setup/doctype/print_heading/print_heading.txt index 861e5479ab..d566f8dee2 100644 --- a/erpnext/setup/doctype/print_heading/print_heading.txt +++ b/erpnext/setup/doctype/print_heading/print_heading.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:16", + "modified": "2014-01-20 17:49:01", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.txt b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.txt index 6fccf61dfb..00e9c6ea4e 100644 --- a/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.txt +++ b/erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:26", + "modified": "2014-01-20 17:49:17", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.py b/erpnext/setup/doctype/sales_partner/sales_partner.py index c2309e8a55..cf9a863a86 100644 --- a/erpnext/setup/doctype/sales_partner/sales_partner.py +++ b/erpnext/setup/doctype/sales_partner/sales_partner.py @@ -4,9 +4,8 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint, cstr, filter_strip_join -from webnotes.webutils import WebsiteGenerator, clear_cache -class DocType(WebsiteGenerator): +class DocType(): def __init__(self, doc, doclist=None): self.doc = doc self.doclist = doclist @@ -15,11 +14,6 @@ class DocType(WebsiteGenerator): if self.doc.partner_website and not self.doc.partner_website.startswith("http"): self.doc.partner_website = "http://" + self.doc.partner_website - def on_update(self): - WebsiteGenerator.on_update(self) - if self.doc.page_name: - clear_cache("partners") - def get_contacts(self,nm): if nm: contact_details =webnotes.conn.convert_to_lists(webnotes.conn.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where sales_partner = '%s'"%nm)) diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.txt b/erpnext/setup/doctype/sales_partner/sales_partner.txt index 6ab274cc77..b09b81d572 100644 --- a/erpnext/setup/doctype/sales_partner/sales_partner.txt +++ b/erpnext/setup/doctype/sales_partner/sales_partner.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-12 15:34:06", "docstatus": 0, - "modified": "2013-12-20 19:24:34", + "modified": "2014-01-20 17:49:25", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,6 +28,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -221,22 +222,22 @@ "label": "Description" }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js index 19c13b18a4..22f3f98bf2 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.js +++ b/erpnext/setup/doctype/sales_person/sales_person.js @@ -15,15 +15,10 @@ cur_frm.cscript.set_root_readonly = function(doc) { } } - -cur_frm.cscript.onload = function(){ - -} - //get query select sales person -cur_frm.fields_dict['parent_sales_person'].get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict['parent_sales_person'].get_query = function(doc, cdt, cdn) { return{ - filters:[ + filters: [ ['Sales Person', 'is_group', '=', 'Yes'], ['Sales Person', 'name', '!=', doc.sales_person_name] ] @@ -31,10 +26,11 @@ cur_frm.fields_dict['parent_sales_person'].get_query = function(doc,cdt,cdn) { } cur_frm.fields_dict['target_details'].grid.get_field("item_group").get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'is_group': "No" } + return { + filters: { 'is_group': "No" } } } -cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query" } } +cur_frm.fields_dict.employee.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query" } +} \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py index cf20087e04..41f461be76 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.py +++ b/erpnext/setup/doctype/sales_person/sales_person.py @@ -3,10 +3,8 @@ from __future__ import unicode_literals import webnotes - from webnotes.model.bean import getlist from webnotes.utils import flt - from webnotes.utils.nestedset import DocTypeNestedSet class DocType(DocTypeNestedSet): @@ -18,8 +16,7 @@ class DocType(DocTypeNestedSet): def validate(self): for d in getlist(self.doclist, 'target_details'): if not flt(d.target_qty) and not flt(d.target_amount): - webnotes.msgprint("Either target qty or target amount is mandatory.") - raise Exception + webnotes.throw(_("Either target qty or target amount is mandatory.")) def on_update(self): super(DocType, self).on_update() @@ -28,8 +25,7 @@ class DocType(DocTypeNestedSet): def get_email_id(self): profile = webnotes.conn.get_value("Employee", self.doc.employee, "user_id") if not profile: - webnotes.msgprint("User ID (Profile) no set for Employee %s" % self.doc.employee, - raise_exception=True) + webnotes.throw("User ID (Profile) not set for Employee %s" % self.doc.employee) else: return webnotes.conn.get_value("Profile", profile, "email") or profile \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.txt b/erpnext/setup/doctype/sales_person/sales_person.txt index 76d9811122..724dc4cd0e 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.txt +++ b/erpnext/setup/doctype/sales_person/sales_person.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:34", + "modified": "2014-01-20 17:49:25", "modified_by": "Administrator", "owner": "Administrator" }, @@ -29,6 +29,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -174,22 +175,22 @@ "print_hide": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/setup/doctype/supplier_type/supplier_type.txt b/erpnext/setup/doctype/supplier_type/supplier_type.txt index c7c2b57f62..5154f15a98 100644 --- a/erpnext/setup/doctype/supplier_type/supplier_type.txt +++ b/erpnext/setup/doctype/supplier_type/supplier_type.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:38", + "modified": "2014-01-20 17:49:31", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -61,22 +62,22 @@ "reqd": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Purchase Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Purchase User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Master Manager", "write": 1 diff --git a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt index e3ff486ea9..16493799ca 100644 --- a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt +++ b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:39", + "modified": "2014-01-20 17:49:33", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -72,30 +73,30 @@ }, { "amend": 0, - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "System Manager", "write": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Accounts User", "write": 1 diff --git a/erpnext/setup/doctype/territory/territory.txt b/erpnext/setup/doctype/territory/territory.txt index 00b7aac422..3eb766d4e0 100644 --- a/erpnext/setup/doctype/territory/territory.txt +++ b/erpnext/setup/doctype/territory/territory.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:39", + "modified": "2014-01-20 17:49:33", "modified_by": "Administrator", "owner": "Administrator" }, @@ -31,6 +31,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -177,22 +178,22 @@ "options": "Budget Distribution" }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "write": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "write": 1 diff --git a/erpnext/setup/doctype/uom/uom.txt b/erpnext/setup/doctype/uom/uom.txt index 070c5a4148..edff5b1d7b 100644 --- a/erpnext/setup/doctype/uom/uom.txt +++ b/erpnext/setup/doctype/uom/uom.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:24", "docstatus": 0, - "modified": "2013-12-20 19:24:40", + "modified": "2014-01-20 17:49:34", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,6 +25,7 @@ }, { "amend": 0, + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -58,22 +59,22 @@ "label": "Must be Whole Number" }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Master Manager", "write": 1 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material Manager", "write": 0 }, { - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "write": 0 diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py index 62989736c7..47e22dfc38 100644 --- a/erpnext/setup/page/setup_wizard/setup_wizard.py +++ b/erpnext/setup/page/setup_wizard/setup_wizard.py @@ -98,7 +98,9 @@ def create_price_lists(args): { "doctype": "Price List", "price_list_name": "Standard " + pl_type, - "buying_or_selling": pl_type, + "enabled": 1, + "buying": 1 if pl_type == "Buying" else 0, + "selling": 1 if pl_type == "Selling" else 0, "currency": args["currency"] }, { diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 0571c15a54..68a5a5ab45 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint +from webnotes import _, msgprint, throw import json def get_company_currency(company): @@ -11,8 +11,8 @@ def get_company_currency(company): if not currency: currency = webnotes.conn.get_default("currency") if not currency: - msgprint(_('Please specify Default Currency in Company Master \ - and Global Defaults'), raise_exception=True) + throw(_('Please specify Default Currency in Company Master \ + and Global Defaults')) return currency @@ -32,5 +32,14 @@ def get_ancestors_of(doctype, name): @webnotes.whitelist() def get_price_list_currency(price_list): - return {"price_list_currency": webnotes.conn.get_value("Price List", price_list, - "currency")} \ No newline at end of file + price_list_currency = webnotes.conn.get_value("Price List", {"name": price_list, + "enabled": 1}, "currency") + + if not price_list_currency: + throw("{message}: {price_list} {disabled}".format(**{ + "message": _("Price List"), + "price_list": price_list, + "disabled": _("is disabled.") + })) + else: + return {"price_list_currency": price_list_currency} \ No newline at end of file diff --git a/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt index 163dffaa87..d4c0cc1983 100644 --- a/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt +++ b/erpnext/stock/Print Format/Delivery Note Classic/Delivery Note Classic.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:31:11", "docstatus": 0, - "modified": "2013-08-07 19:44:55", + "modified": "2013-12-26 17:36:51", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Delivery Note", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Stock", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt index f4323a9e1f..3b36f6f1c0 100644 --- a/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt +++ b/erpnext/stock/Print Format/Delivery Note Modern/Delivery Note Modern.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:31:11", "docstatus": 0, - "modified": "2013-08-07 20:12:29", + "modified": "2013-12-26 17:36:26", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Delivery Note", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Stock", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt index 03fbef521e..072d411004 100644 --- a/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt +++ b/erpnext/stock/Print Format/Delivery Note Spartan/Delivery Note Spartan.txt @@ -2,14 +2,14 @@ { "creation": "2013-04-19 13:31:11", "docstatus": 0, - "modified": "2013-08-07 19:44:37", + "modified": "2013-12-26 17:37:14", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Delivery Note", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
    \n\t\n\t\n
    \n", "module": "Stock", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/stock/doctype/batch/batch.txt b/erpnext/stock/doctype/batch/batch.txt index 17145fffa7..c08573b507 100644 --- a/erpnext/stock/doctype/batch/batch.txt +++ b/erpnext/stock/doctype/batch/batch.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-05 14:50:38", "docstatus": 0, - "modified": "2013-12-20 19:23:55", + "modified": "2014-01-20 17:48:24", "modified_by": "Administrator", "owner": "harshada@webnotestech.com" }, @@ -26,8 +26,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt index 36615a28d0..63b62d604c 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.txt +++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:09", "docstatus": 0, - "modified": "2013-12-20 19:24:02", + "modified": "2014-01-20 17:48:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -468,7 +468,7 @@ "fieldname": "other_charges_total_export", "fieldtype": "Currency", "label": "Taxes and Charges Total", - "options": "company", + "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1 }, @@ -490,6 +490,13 @@ "read_only": 1, "width": "150px" }, + { + "doctype": "DocField", + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "Company:company:default_currency" + }, { "doctype": "DocField", "fieldname": "totals", @@ -1028,6 +1035,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material User", "submit": 1, @@ -1037,6 +1045,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Manager", "submit": 1, @@ -1046,6 +1055,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales User", "submit": 1, @@ -1054,12 +1064,14 @@ { "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Accounts User", "submit": 0, "write": 0 }, { + "delete": 0, "doctype": "DocPerm", "role": "Customer" } diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 1ee5e049e4..e894d0db88 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -29,10 +29,7 @@ cur_frm.cscript.make_dashboard = function() { cur_frm.cscript.edit_prices_button = function() { cur_frm.add_custom_button("Add / Edit Prices", function() { - wn.route_options = { - "item_code": cur_frm.doc.name - }; - wn.set_route("Report", "Item Price"); + wn.set_route("Report", "Item Price", {"item_code": cur_frm.doc.name}); }, "icon-money"); } @@ -97,7 +94,8 @@ cur_frm.fields_dict['default_sales_cost_center'].get_query = function(doc) { cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) { return{ filters:[ - ['Account', 'account_type', 'in', 'Tax, Chargeable'], + ['Account', 'account_type', 'in', + 'Tax, Chargeable, Income Account, Expense Account'], ['Account', 'docstatus', '!=', 2] ] } diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 73e8dc2b09..16938b4027 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -8,13 +8,12 @@ from webnotes.utils import cstr, flt from webnotes.model.doc import addchild from webnotes.model.bean import getlist from webnotes import msgprint, _ -from webnotes.webutils import WebsiteGenerator from webnotes.model.controller import DocListController class WarehouseNotSet(Exception): pass -class DocType(DocListController, WebsiteGenerator): +class DocType(DocListController): def onload(self): self.doc.fields["__sle_exists"] = self.check_if_sle_exists() @@ -48,7 +47,6 @@ class DocType(DocListController, WebsiteGenerator): def on_update(self): self.validate_name_with_item_group() - self.update_website() self.update_item_price() def check_warehouse_is_set_for_stock_item(self): @@ -151,8 +149,8 @@ class DocType(DocListController, WebsiteGenerator): if d.tax_type: account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type") - if account_type not in ['Tax', 'Chargeable']: - msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1) + if account_type not in ['Tax', 'Chargeable', 'Income Account', 'Expense Account']: + msgprint("'%s' is not Tax / Chargeable / Income / Expense Account" % d.tax_type, raise_exception=1) else: if d.tax_type in check_list: msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1) @@ -197,14 +195,6 @@ class DocType(DocListController, WebsiteGenerator): please change the item name or rename the item group" % self.doc.name, raise_exception=1) - def update_website(self): - from erpnext.setup.doctype.item_group.item_group import invalidate_cache_for - invalidate_cache_for(self.doc.item_group) - [invalidate_cache_for(d.item_group) for d in \ - self.doclist.get({"doctype":"Website Item Group"})] - - WebsiteGenerator.on_update(self) - def update_item_price(self): webnotes.conn.sql("""update `tabItem Price` set item_name=%s, item_description=%s, modified=NOW() where item_code=%s""", @@ -232,7 +222,6 @@ class DocType(DocListController, WebsiteGenerator): def on_trash(self): webnotes.conn.sql("""delete from tabBin where item_code=%s""", self.doc.item_code) - WebsiteGenerator.on_trash(self) def before_rename(self, olddn, newdn, merge=False): if merge: @@ -250,18 +239,11 @@ class DocType(DocListController, WebsiteGenerator): def after_rename(self, olddn, newdn, merge): webnotes.conn.set_value("Item", newdn, "item_code", newdn) - self.update_website_page_name() if merge: self.set_last_purchase_rate(newdn) self.recalculate_bin_qty(newdn) - def update_website_page_name(self): - if self.doc.page_name: - self.update_website() - from webnotes.webutils import clear_cache - clear_cache(self.doc.page_name) - def set_last_purchase_rate(self, newdn): from erpnext.buying.utils import get_last_purchase_details last_purchase_rate = get_last_purchase_details(newdn).get("purchase_rate", 0) diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt index cc12fdaebf..8da0d4cf33 100644 --- a/erpnext/stock/doctype/item/item.txt +++ b/erpnext/stock/doctype/item/item.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-03 10:45:46", "docstatus": 0, - "modified": "2013-12-20 19:24:09", + "modified": "2014-01-20 17:48:47", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -847,8 +848,8 @@ "read_only": 0 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "import": 1, "role": "Material Master Manager", @@ -856,16 +857,16 @@ }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material Manager", "write": 0 }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "write": 0 diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 3cf1d5ecf6..00ce548567 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -36,6 +36,7 @@ test_records = [ "stock_uom": "_Test UOM", "default_income_account": "Sales - _TC", "default_warehouse": "_Test Warehouse - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC" }, { "doctype": "Item Reorder", "parentfield": "item_reorder", @@ -64,6 +65,7 @@ test_records = [ "stock_uom": "_Test UOM", "default_income_account": "Sales - _TC", "default_warehouse": "_Test Warehouse - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC" }], [{ "doctype": "Item", @@ -73,6 +75,7 @@ test_records = [ "item_group": "_Test Item Group Desktops", "default_warehouse": "_Test Warehouse - _TC", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_stock_item": "Yes", "is_asset_item": "No", "has_batch_no": "No", @@ -99,6 +102,7 @@ test_records = [ "item_group": "_Test Item Group Desktops", "default_warehouse": "_Test Warehouse - _TC", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_stock_item": "Yes", "is_asset_item": "No", "has_batch_no": "No", @@ -119,6 +123,7 @@ test_records = [ "description": "_Test Sales BOM Item", "item_group": "_Test Item Group Desktops", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_stock_item": "No", "is_asset_item": "No", "has_batch_no": "No", @@ -140,6 +145,7 @@ test_records = [ "is_stock_item": "Yes", "default_warehouse": "_Test Warehouse - _TC", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_asset_item": "No", "has_batch_no": "No", "has_serial_no": "No", @@ -216,6 +222,7 @@ test_records = [ "item_group": "_Test Item Group Desktops", "default_warehouse": "_Test Warehouse - _TC", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_stock_item": "Yes", "is_asset_item": "No", "has_batch_no": "No", @@ -238,6 +245,7 @@ test_records = [ "is_stock_item": "Yes", "default_warehouse": "_Test Warehouse - _TC", "default_income_account": "Sales - _TC", + "purchase_account": "_Test Account Cost for Goods Sold - _TC", "is_asset_item": "No", "has_batch_no": "No", "has_serial_no": "No", diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js index bece26c6b5..9f38fdb18e 100644 --- a/erpnext/stock/doctype/item_price/item_price.js +++ b/erpnext/stock/doctype/item_price/item_price.js @@ -2,11 +2,10 @@ // License: GNU General Public License v3. See license.txt $.extend(cur_frm.cscript, { - onload: function () { - // Fetch price list details - cur_frm.add_fetch("price_list", "buying_or_selling", "buying_or_selling"); + cur_frm.add_fetch("price_list", "buying", "buying"); + cur_frm.add_fetch("price_list", "selling", "selling"); cur_frm.add_fetch("price_list", "currency", "currency"); // Fetch item details diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index 072d70096e..cb07e706cf 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -1,11 +1,9 @@ # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -# MIT License. See license.txt - -# For license information, please see license.txt +# License: GNU General Public License v3. See license.txt from __future__ import unicode_literals import webnotes -from webnotes import _ +from webnotes import throw, _ class ItemPriceDuplicateItem(webnotes.ValidationError): pass @@ -14,26 +12,36 @@ class DocType: self.doc, self.doclist = d, dl def validate(self): + self.validate_price_list() self.check_duplicate_item() self.update_price_list_details() self.update_item_details() - def update_price_list_details(self): - self.doc.buying_or_selling, self.doc.currency = webnotes.conn.get_value("Price List", - self.doc.price_list, ["buying_or_selling", "currency"]) - - def update_item_details(self): - self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item", - self.doc.item_code, ["item_name", "description"]) + def validate_price_list(self): + enabled = webnotes.conn.get_value("Price List", self.doc.price_list, "enabled") + if not enabled: + throw("{message}: {price_list} {disabled}".format(**{ + "message": _("Price List"), + "price_list": self.doc.price_list, + "disabled": _("is disabled.") + })) def check_duplicate_item(self): if webnotes.conn.sql("""select name from `tabItem Price` where item_code=%s and price_list=%s and name!=%s""", (self.doc.item_code, self.doc.price_list, self.doc.name)): - webnotes.throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{ + throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{ "duplicate_item": _("Duplicate Item"), "item_code": self.doc.item_code, "already": _("already available in Price List"), "price_list": self.doc.price_list }), ItemPriceDuplicateItem) + + def update_price_list_details(self): + self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List", + {"name": self.doc.price_list, "enabled": 1}, ["buying", "selling", "currency"]) + + def update_item_details(self): + self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item", + self.doc.item_code, ["item_name", "description"]) \ No newline at end of file diff --git a/erpnext/stock/doctype/item_price/item_price.txt b/erpnext/stock/doctype/item_price/item_price.txt index c21f127b7a..338e759b04 100644 --- a/erpnext/stock/doctype/item_price/item_price.txt +++ b/erpnext/stock/doctype/item_price/item_price.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-02 16:29:48", "docstatus": 0, - "modified": "2013-12-20 19:24:10", + "modified": "2014-01-20 17:48:50", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -46,6 +47,13 @@ "doctype": "DocType", "name": "Item Price" }, + { + "doctype": "DocField", + "fieldname": "price_list_details", + "fieldtype": "Section Break", + "label": "Price List", + "options": "icon-tags" + }, { "doctype": "DocField", "fieldname": "price_list", @@ -55,6 +63,29 @@ "options": "Price List", "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "buying", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Buying", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "selling", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Selling", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "item_details", + "fieldtype": "Section Break", + "label": "Item", + "options": "icon-tag" + }, { "doctype": "DocField", "fieldname": "item_code", @@ -86,16 +117,6 @@ "fieldname": "col_br_1", "fieldtype": "Column Break" }, - { - "doctype": "DocField", - "fieldname": "buying_or_selling", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Valid for Buying or Selling?", - "options": "Selling\nBuying", - "reqd": 0 - }, { "doctype": "DocField", "fieldname": "item_name", diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 28ec5084e0..d3262c5888 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -37,16 +37,16 @@ class DocType(BuyingController): for so_no in so_items.keys(): for item in so_items[so_no].keys(): - already_indented = webnotes.conn.sql("""select sum(qty) from `tabMaterial Request Item` + already_indented = webnotes.conn.sql("""select sum(ifnull(qty, 0)) + from `tabMaterial Request Item` where item_code = %s and sales_order_no = %s and docstatus = 1 and parent != %s""", (item, so_no, self.doc.name)) already_indented = already_indented and flt(already_indented[0][0]) or 0 - actual_so_qty = webnotes.conn.sql("""select sum(qty) from `tabSales Order Item` - where parent = %s and item_code = %s and docstatus = 1 - group by parent""", (so_no, item)) + actual_so_qty = webnotes.conn.sql("""select sum(ifnull(qty, 0)) from `tabSales Order Item` + where parent = %s and item_code = %s and docstatus = 1""", (so_no, item)) actual_so_qty = actual_so_qty and flt(actual_so_qty[0][0]) or 0 - + if actual_so_qty and (flt(so_items[so_no][item]) + already_indented > actual_so_qty): webnotes.throw("You can raise indent of maximum qty: %s for item: %s against sales order: %s\ \n Anyway, you can add more qty in new row for the same item." diff --git a/erpnext/stock/doctype/material_request/material_request.txt b/erpnext/stock/doctype/material_request/material_request.txt index 8762c03edd..cb027918bd 100644 --- a/erpnext/stock/doctype/material_request/material_request.txt +++ b/erpnext/stock/doctype/material_request/material_request.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 14:48:38", "docstatus": 0, - "modified": "2013-12-20 19:24:14", + "modified": "2014-01-20 17:48:57", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py index 5266f49257..499fbb0167 100644 --- a/erpnext/stock/doctype/material_request/test_material_request.py +++ b/erpnext/stock/doctype/material_request/test_material_request.py @@ -125,6 +125,7 @@ class TestMaterialRequest(unittest.TestCase): from erpnext.stock.doctype.material_request.material_request import make_purchase_order po_doclist = make_purchase_order(mr.doc.name) po_doclist[0].supplier = "_Test Supplier" + po_doclist[0].transaction_date = "2013-07-07" po_doclist[1].qty = 27.0 po_doclist[2].qty = 1.5 po_doclist[1].schedule_date = "2013-07-09" diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.txt b/erpnext/stock/doctype/packing_slip/packing_slip.txt index 065a056ef5..2f8ccc3fc7 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.txt +++ b/erpnext/stock/doctype/packing_slip/packing_slip.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-11 15:32:24", "docstatus": 0, - "modified": "2013-12-20 19:24:15", + "modified": "2014-01-20 17:48:59", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,6 +30,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/stock/doctype/price_list/price_list.py b/erpnext/stock/doctype/price_list/price_list.py index 7644af5f23..bdcd1df1af 100644 --- a/erpnext/stock/doctype/price_list/price_list.py +++ b/erpnext/stock/doctype/price_list/price_list.py @@ -3,16 +3,15 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _ -from webnotes.utils import comma_or, cint +from webnotes import msgprint, _, throw +from webnotes.utils import cint from webnotes.model.controller import DocListController import webnotes.defaults class DocType(DocListController): def validate(self): - if self.doc.buying_or_selling not in ["Buying", "Selling"]: - msgprint(_(self.meta.get_label("buying_or_selling")) + " " + _("must be one of") + " " + - comma_or(["Buying", "Selling"]), raise_exception=True) + if not cint(self.doc.buying) and not cint(self.doc.selling): + throw(_("Price List must be applicable for Buying or Selling")) if not self.doclist.get({"parentfield": "valid_for_territories"}): # if no territory, set default territory @@ -25,21 +24,21 @@ class DocType(DocListController): else: # at least one territory self.validate_table_has_rows("valid_for_territories") - + def on_update(self): self.set_default_if_missing() self.update_item_price() - + def set_default_if_missing(self): - if self.doc.buying_or_selling=="Selling": + if cint(self.doc.selling): if not webnotes.conn.get_value("Selling Settings", None, "selling_price_list"): webnotes.set_value("Selling Settings", "Selling Settings", "selling_price_list", self.doc.name) - elif self.doc.buying_or_selling=="Buying": + elif cint(self.doc.buying): if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"): webnotes.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.doc.name) def update_item_price(self): webnotes.conn.sql("""update `tabItem Price` set currency=%s, - buying_or_selling=%s, modified=NOW() where price_list=%s""", - (self.doc.currency, self.doc.buying_or_selling, self.doc.name)) \ No newline at end of file + buying=%s, selling=%s, modified=NOW() where price_list=%s""", + (self.doc.currency, cint(self.doc.buying), cint(self.doc.selling), self.doc.name)) diff --git a/erpnext/stock/doctype/price_list/price_list.txt b/erpnext/stock/doctype/price_list/price_list.txt index dabc7e0dc9..7f8b3a192e 100644 --- a/erpnext/stock/doctype/price_list/price_list.txt +++ b/erpnext/stock/doctype/price_list/price_list.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-25 11:35:09", "docstatus": 0, - "modified": "2013-12-20 18:28:50", + "modified": "2014-01-20 17:50:00", "modified_by": "Administrator", "owner": "Administrator" }, @@ -41,6 +41,18 @@ "doctype": "DocType", "name": "Price List" }, + { + "default": "1", + "doctype": "DocField", + "fieldname": "enabled", + "fieldtype": "Check", + "label": "Enabled" + }, + { + "doctype": "DocField", + "fieldname": "sb_1", + "fieldtype": "Section Break" + }, { "doctype": "DocField", "fieldname": "price_list_name", @@ -60,14 +72,19 @@ "reqd": 1 }, { - "default": "Selling", "doctype": "DocField", - "fieldname": "buying_or_selling", - "fieldtype": "Select", + "fieldname": "buying", + "fieldtype": "Check", "in_list_view": 1, - "label": "Valid for Buying or Selling?", - "options": "Buying\nSelling", - "reqd": 1 + "label": "Buying" + }, + { + "doctype": "DocField", + "fieldname": "selling", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Selling", + "reqd": 0 }, { "doctype": "DocField", @@ -87,6 +104,7 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Sales User", "submit": 0, @@ -94,20 +112,23 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager", "submit": 0, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" }, { "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Master Manager", "write": 1 diff --git a/erpnext/stock/doctype/price_list/test_price_list.py b/erpnext/stock/doctype/price_list/test_price_list.py index 86dcd1a594..803be27e5c 100644 --- a/erpnext/stock/doctype/price_list/test_price_list.py +++ b/erpnext/stock/doctype/price_list/test_price_list.py @@ -11,8 +11,9 @@ test_records = [ { "doctype": "Price List", "price_list_name": "_Test Price List", + "enabled": 1, "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -24,8 +25,9 @@ test_records = [ { "doctype": "Price List", "price_list_name": "_Test Price List 2", + "enabled": 1, "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -37,8 +39,9 @@ test_records = [ { "doctype": "Price List", "price_list_name": "_Test Price List India", + "enabled": 1, "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -50,8 +53,9 @@ test_records = [ { "doctype": "Price List", "price_list_name": "_Test Price List Rest of the World", + "enabled": 1, "currency": "USD", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt index fca3e39007..960bb210fa 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2013-12-20 19:24:23", + "modified": "2014-01-20 17:49:12", "modified_by": "Administrator", "owner": "Administrator" }, @@ -809,6 +809,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Manager", "submit": 1, @@ -818,6 +819,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material User", "submit": 1, @@ -827,12 +829,14 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase User", "submit": 1, "write": 1 }, { + "delete": 0, "doctype": "DocPerm", "role": "Supplier" } diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt index 4f5004021c..9bc66a42da 100755 --- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt +++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:10", "docstatus": 0, - "modified": "2013-12-20 19:23:36", + "modified": "2014-01-15 16:00:44", "modified_by": "Administrator", "owner": "Administrator" }, @@ -334,6 +334,16 @@ "report_hide": 0, "reqd": 0 }, + { + "default": ":Company", + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", + "doctype": "DocField", + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center", + "print_hide": 1 + }, { "doctype": "DocField", "fieldname": "project_name", diff --git a/erpnext/stock/doctype/serial_no/serial_no.txt b/erpnext/stock/doctype/serial_no/serial_no.txt index 09995704fa..3588493a20 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.txt +++ b/erpnext/stock/doctype/serial_no/serial_no.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-16 10:59:15", "docstatus": 0, - "modified": "2013-12-20 19:24:34", + "modified": "2014-01-20 17:49:26", "modified_by": "Administrator", "owner": "Administrator" }, @@ -29,6 +29,7 @@ "permlevel": 0 }, { + "cancel": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -451,24 +452,24 @@ "search_index": 1 }, { - "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Master Manager", "write": 1 }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material Manager", "write": 0 }, { "amend": 0, - "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "write": 0 diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.txt b/erpnext/stock/doctype/stock_entry/stock_entry.txt index 84023ab2be..01cfed84b6 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.txt +++ b/erpnext/stock/doctype/stock_entry/stock_entry.txt @@ -2,7 +2,7 @@ { "creation": "2013-04-09 11:43:55", "docstatus": 0, - "modified": "2013-12-20 19:24:35", + "modified": "2014-01-20 17:49:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -38,6 +38,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.txt index 88c08a77b0..25835e0bf3 100644 --- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.txt +++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-29 18:22:12", "docstatus": 0, - "modified": "2013-12-20 19:21:48", + "modified": "2014-01-15 16:08:45", "modified_by": "Administrator", "owner": "Administrator" }, @@ -165,7 +165,7 @@ "read_only": 1 }, { - "depends_on": "eval:sys_defaults.auto_accounting_for_stock", + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", "doctype": "DocField", "fieldname": "expense_account", "fieldtype": "Link", @@ -175,7 +175,7 @@ }, { "default": ":Company", - "depends_on": "eval:sys_defaults.auto_accounting_for_stock", + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", "doctype": "DocField", "fieldname": "cost_center", "fieldtype": "Link", diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt index f95a1dddba..90f5bc8e69 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-28 10:35:31", "docstatus": 0, - "modified": "2013-12-20 16:06:50", + "modified": "2014-01-20 17:49:28", "modified_by": "Administrator", "owner": "Administrator" }, @@ -32,6 +32,7 @@ "amend": 0, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "name": "__common__", "parent": "Stock Reconciliation", @@ -101,7 +102,7 @@ "reqd": 1 }, { - "depends_on": "eval:sys_defaults.auto_accounting_for_stock", + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", "doctype": "DocField", "fieldname": "expense_account", "fieldtype": "Link", @@ -109,6 +110,7 @@ "options": "Account" }, { + "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)", "doctype": "DocField", "fieldname": "cost_center", "fieldtype": "Link", diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 7729b2e59e..0f2d138a06 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint, validate_email_add -from webnotes import msgprint, _ +from webnotes import throw, msgprint, _ class DocType: def __init__(self, doc, doclist=[]): @@ -18,7 +18,7 @@ class DocType: def validate(self): if self.doc.email_id and not validate_email_add(self.doc.email_id): - msgprint("Please enter valid Email Id", raise_exception=1) + throw(_("Please enter valid Email Id")) self.update_parent_account() @@ -76,8 +76,8 @@ class DocType: for d in bins: if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \ d['indented_qty'] or d['projected_qty'] or d['planned_qty']: - msgprint("""Warehouse: %s can not be deleted as qty exists for item: %s""" - % (self.doc.name, d['item_code']), raise_exception=1) + throw("""Warehouse: %s can not be deleted as qty exists for item: %s""" + % (self.doc.name, d['item_code'])) else: webnotes.conn.sql("delete from `tabBin` where name = %s", d['name']) @@ -88,8 +88,8 @@ class DocType: if webnotes.conn.sql("""select name from `tabStock Ledger Entry` where warehouse = %s""", self.doc.name): - msgprint("""Warehouse can not be deleted as stock ledger entry - exists for this warehouse.""", raise_exception=1) + throw(_("""Warehouse can not be deleted as stock ledger entry + exists for this warehouse.""")) def before_rename(self, olddn, newdn, merge=False): # Add company abbr if not provided @@ -97,8 +97,8 @@ class DocType: new_warehouse = get_name_with_abbr(newdn, self.doc.company) if merge: - if not webnotes.conn.exists("Warehouse", newdn): - webnotes.throw(_("Warehouse ") + newdn +_(" does not exists")) + if not webnotes.conn.exists("Warehouse", new_warehouse): + webnotes.throw(_("Warehouse ") + new_warehouse +_(" does not exists")) if self.doc.company != webnotes.conn.get_value("Warehouse", new_warehouse, "company"): webnotes.throw(_("Both Warehouse must belong to same Company")) diff --git a/erpnext/stock/doctype/warehouse/warehouse.txt b/erpnext/stock/doctype/warehouse/warehouse.txt index 629a508d80..dc6a09844d 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.txt +++ b/erpnext/stock/doctype/warehouse/warehouse.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 18:50:32", "docstatus": 0, - "modified": "2013-12-27 17:55:48", + "modified": "2014-01-20 17:49:34", "modified_by": "Administrator", "owner": "Administrator" }, @@ -176,8 +176,9 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "role": "Material Master Manager", "submit": 0, @@ -187,20 +188,24 @@ "amend": 0, "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "role": "Material User", "submit": 0, "write": 0 }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" } diff --git a/erpnext/stock/report/item_prices/item_prices.py b/erpnext/stock/report/item_prices/item_prices.py index da8b5007d5..323277dc0b 100644 --- a/erpnext/stock/report/item_prices/item_prices.py +++ b/erpnext/stock/report/item_prices/item_prices.py @@ -15,8 +15,8 @@ def execute(filters=None): bom_rate = get_item_bom_rate() val_rate_map = get_valuation_rate() - precision = get_currency_precision or 2 - + from erpnext.accounts.utils import get_currency_precision + precision = get_currency_precision() or 2 data = [] for item in sorted(item_map): data.append([item, item_map[item]["item_name"], @@ -30,14 +30,6 @@ def execute(filters=None): ]) return columns, data - -def get_currency_precision(): - company_currency = webnotes.conn.get_value("Company", - webnotes.conn.get_default("company"), "default_currency") - currency_format = webnotes.conn.get_value("Currency", company_currency, "number_format") - - from webnotes.utils import get_number_format_info - return get_number_format_info(currency_format)[2] def get_columns(filters): """return columns based on filters""" @@ -65,13 +57,14 @@ def get_price_list(): rate = {} - price_list = webnotes.conn.sql("""select item_code, buying_or_selling, - concat(price_list, " - ", currency, " ", ref_rate) as price - from `tabItem Price`""", as_dict=1) + price_list = webnotes.conn.sql("""select ip.item_code, ip.buying, ip.selling, + concat(ip.price_list, " - ", ip.currency, " ", ip.ref_rate) as price + from `tabItem Price` ip, `tabPrice List` pl + where ip.price_list=pl.name and pl.enabled=1""", as_dict=1) for j in price_list: if j.price: - rate.setdefault(j.item_code, {}).setdefault(j.buying_or_selling, []).append(j.price) + rate.setdefault(j.item_code, {}).setdefault("Buying" if j.buying else "Selling", []).append(j.price) item_rate_map = {} for item in rate: diff --git a/erpnext/setup/report/item_wise_price_list_rate/__init__.py b/erpnext/stock/report/item_wise_price_list_rate/__init__.py similarity index 100% rename from erpnext/setup/report/item_wise_price_list_rate/__init__.py rename to erpnext/stock/report/item_wise_price_list_rate/__init__.py diff --git a/erpnext/setup/report/item_wise_price_list_rate/item_wise_price_list_rate.txt b/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt similarity index 74% rename from erpnext/setup/report/item_wise_price_list_rate/item_wise_price_list_rate.txt rename to erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt index 888203d2b7..f4d1d67ca4 100644 --- a/erpnext/setup/report/item_wise_price_list_rate/item_wise_price_list_rate.txt +++ b/erpnext/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt @@ -2,14 +2,14 @@ { "creation": "2013-09-25 10:21:15", "docstatus": 0, - "modified": "2013-10-21 16:06:22", + "modified": "2014-01-07 18:35:22", "modified_by": "Administrator", "owner": "Administrator" }, { "doctype": "Report", "is_standard": "Yes", - "json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}", + "json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying\",\"Item Price\"],[\"selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}", "name": "__common__", "ref_doctype": "Price List", "report_name": "Item-wise Price List Rate", diff --git a/erpnext/support/doctype/customer_issue/customer_issue.txt b/erpnext/support/doctype/customer_issue/customer_issue.txt index cee27d57cb..37db518888 100644 --- a/erpnext/support/doctype/customer_issue/customer_issue.txt +++ b/erpnext/support/doctype/customer_issue/customer_issue.txt @@ -2,11 +2,12 @@ { "creation": "2013-01-10 16:34:30", "docstatus": 0, - "modified": "2014-01-02 11:20:49", + "modified": "2014-01-20 17:48:34", "modified_by": "Administrator", "owner": "harshada@webnotestech.com" }, { + "allow_import": 1, "autoname": "naming_series:", "doctype": "DocType", "icon": "icon-bug", @@ -25,8 +26,9 @@ }, { "amend": 0, - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js index 4cdf56f11b..8c34736a84 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js @@ -13,27 +13,29 @@ wn.ui.form.on_change("Maintenance Schedule", "contact_person", // TODO commonify this code erpnext.support.MaintenanceSchedule = wn.ui.form.Controller.extend({ refresh: function() { - if (this.frm.doc.docstatus===0) { - cur_frm.add_custom_button(wn._('From Sales Order'), + var me = this; + + if (this.frm.doc.docstatus === 0) { + this.frm.add_custom_button(wn._('From Sales Order'), function() { wn.model.map_current_doc({ method: "erpnext.selling.doctype.sales_order.sales_order.make_maintenance_schedule", source_doctype: "Sales Order", get_query_filters: { docstatus: 1, - order_type: cur_frm.doc.order_type, - customer: cur_frm.doc.customer || undefined, - company: cur_frm.doc.company + order_type: me.frm.doc.order_type, + customer: me.frm.doc.customer || undefined, + company: me.frm.doc.company } - }) + }); }); - } else if (this.frm.doc.docstatus===1) { - cur_frm.add_custom_button(wn._("Make Maintenance Visit"), function() { + } else if (this.frm.doc.docstatus === 1) { + this.frm.add_custom_button(wn._("Make Maintenance Visit"), function() { wn.model.open_mapped_doc({ method: "erpnext.support.doctype.maintenance_schedule.maintenance_schedule.make_maintenance_visit", - source_name: cur_frm.doc.name + source_name: me.frm.doc.name }) - }) + }); } }, }); @@ -49,57 +51,59 @@ cur_frm.cscript.onload = function(doc, dt, dn) { } cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'customer': doc.customer} - } + return { + filters:{ 'customer': doc.customer } + } } cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'customer': doc.customer} - } + return { + filters:{ 'customer': doc.customer } + } } // cur_frm.fields_dict['item_maintenance_detail'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'is_service_item': "Yes"} - } + return { + filters:{ 'is_service_item': "Yes" } + } } cur_frm.cscript.item_code = function(doc, cdt, cdn) { - var fname = cur_frm.cscript.fname; - var d = locals[cdt][cdn]; - if (d.item_code) { - return get_server_fields('get_item_details',d.item_code, 'item_maintenance_detail',doc,cdt,cdn,1); - } + var fname = cur_frm.cscript.fname; + var d = locals[cdt][cdn]; + if (d.item_code) { + return get_server_fields('get_item_details', d.item_code, 'item_maintenance_detail', + doc, cdt, cdn, 1); + } } cur_frm.cscript.periodicity = function(doc, cdt, cdn){ - var d = locals[cdt][cdn]; - if(d.start_date && d.end_date){ - arg = {} - arg.start_date = d.start_date; - arg.end_date = d.end_date; - arg.periodicity = d.periodicity; - return get_server_fields('get_no_of_visits',docstring(arg),'item_maintenance_detail',doc, cdt, cdn, 1); - } - else{ - msgprint(wn._("Please enter Start Date and End Date")); - } + var d = locals[cdt][cdn]; + if(d.start_date && d.end_date) { + arg = {} + arg.start_date = d.start_date; + arg.end_date = d.end_date; + arg.periodicity = d.periodicity; + return get_server_fields('get_no_of_visits', docstring(arg), + 'item_maintenance_detail', doc, cdt, cdn, 1); + } else { + msgprint(wn._("Please enter Start Date and End Date")); + } } cur_frm.cscript.generate_schedule = function(doc, cdt, cdn) { - if (!doc.__islocal) { - return $c('runserverobj', args={'method':'generate_schedule', 'docs':wn.model.compress(make_doclist(cdt,cdn))}, - function(r,rt){ - refresh_field('maintenance_schedule_detail'); - } - ); - } else { - alert(wn._("Please save the document before generating maintenance schedule")); - } + if (!doc.__islocal) { + return $c('runserverobj', args={'method':'generate_schedule', + 'docs':wn.model.compress(make_doclist(cdt,cdn))}, + function(r, rt) { + refresh_field('maintenance_schedule_detail'); + }); + } else { + msgprint(wn._("Please save the document before generating maintenance schedule")); + } } cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.customer_query" } } + return { query: "erpnext.controllers.queries.customer_query" } +} diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 8263b19667..8f75247d1f 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -4,13 +4,10 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import add_days, cstr, getdate +from webnotes.utils import add_days, cstr, getdate, cint from webnotes.model.doc import addchild from webnotes.model.bean import getlist -from webnotes import msgprint - - - +from webnotes import msgprint, throw, _ from erpnext.utilities.transaction_base import TransactionBase, delete_events class DocType(TransactionBase): @@ -19,7 +16,8 @@ class DocType(TransactionBase): self.doclist = doclist def get_item_details(self, item_code): - item = webnotes.conn.sql("select item_name, description from `tabItem` where name = '%s'" %(item_code), as_dict=1) + item = webnotes.conn.sql("""select item_name, description from `tabItem` + where name=%s""", (item_code), as_dict=1) ret = { 'item_name': item and item[0]['item_name'] or '', 'description' : item and item[0]['description'] or '' @@ -28,13 +26,14 @@ class DocType(TransactionBase): def generate_schedule(self): self.doclist = self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') - count = 0 - webnotes.conn.sql("delete from `tabMaintenance Schedule Detail` where parent='%s'" %(self.doc.name)) + webnotes.conn.sql("""delete from `tabMaintenance Schedule Detail` + where parent=%s""", (self.doc.name)) + count = 1 for d in getlist(self.doclist, 'item_maintenance_detail'): self.validate_maintenance_detail() - s_list =[] - s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits) - for i in range(d.no_of_visits): + s_list = [] + s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits, d.sales_person) + for i in range(d.no_of_visits): child = addchild(self.doc, 'maintenance_schedule_detail', 'Maintenance Schedule Detail', self.doclist) child.item_code = d.item_code @@ -43,40 +42,39 @@ class DocType(TransactionBase): if d.serial_no: child.serial_no = d.serial_no child.idx = count - count = count+1 - child.incharge_name = d.incharge_name + count = count + 1 + child.sales_person = d.sales_person child.save(1) self.on_update() def on_submit(self): if not getlist(self.doclist, 'maintenance_schedule_detail'): - msgprint("Please click on 'Generate Schedule' to get schedule") - raise Exception + throw("Please click on 'Generate Schedule' to get schedule") self.check_serial_no_added() self.validate_serial_no_warranty() self.validate_schedule() - email_map ={} + email_map = {} for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: self.update_amc_date(d.serial_no, d.end_date) - if d.incharge_name not in email_map: - email_map[d.incharge_name] = webnotes.bean("Sales Person", - d.incharge_name).run_method("get_email_id") + if d.sales_person not in email_map: + sp = webnotes.bean("Sales Person", d.sales_person).make_controller() + email_map[d.sales_person] = sp.get_email_id() - scheduled_date =webnotes.conn.sql("select scheduled_date from `tabMaintenance Schedule Detail` \ - where incharge_name='%s' and item_code='%s' and parent='%s' " %(d.incharge_name, \ - d.item_code, self.doc.name), as_dict=1) + scheduled_date = webnotes.conn.sql("""select scheduled_date from + `tabMaintenance Schedule Detail` where sales_person=%s and item_code=%s and + parent=%s""", (d.sales_person, d.item_code, self.doc.name), as_dict=1) for key in scheduled_date: - if email_map[d.incharge_name]: + if email_map[d.sales_person]: description = "Reference: %s, Item Code: %s and Customer: %s" % \ (self.doc.name, d.item_code, self.doc.customer) webnotes.bean({ "doctype": "Event", - "owner": email_map[d.incharge_name] or self.doc.owner, + "owner": email_map[d.sales_person] or self.doc.owner, "subject": description, "description": description, "starts_on": key["scheduled_date"] + " 10:00:00", @@ -89,92 +87,121 @@ class DocType(TransactionBase): #get schedule dates #---------------------- - def create_schedule_list(self, start_date, end_date, no_of_visit): + def create_schedule_list(self, start_date, end_date, no_of_visit, sales_person): schedule_list = [] - start_date1 = start_date + start_date_copy = start_date date_diff = (getdate(end_date) - getdate(start_date)).days - add_by = date_diff/no_of_visit - #schedule_list.append(start_date1) - while(getdate(start_date1) < getdate(end_date)): - start_date1 = add_days(start_date1, add_by) - if len(schedule_list) < no_of_visit: - schedule_list.append(getdate(start_date1)) + add_by = date_diff / no_of_visit + + for visit in range(cint(no_of_visit)): + if (getdate(start_date_copy) < getdate(end_date)): + start_date_copy = add_days(start_date_copy, add_by) + if len(schedule_list) < no_of_visit: + schedule_date = self.validate_schedule_date_for_holiday_list(getdate(start_date_copy), + sales_person) + if schedule_date > getdate(end_date): + schedule_date = getdate(end_date) + schedule_list.append(schedule_date) + return schedule_list - + + def validate_schedule_date_for_holiday_list(self, schedule_date, sales_person): + from erpnext.accounts.utils import get_fiscal_year + validated = False + fy_details = "" + + try: + fy_details = get_fiscal_year(date=schedule_date, verbose=0) + except Exception: + pass + + if fy_details and fy_details[0]: + # check holiday list in employee master + holiday_list = webnotes.conn.sql_list("""select h.holiday_date from `tabEmployee` emp, + `tabSales Person` sp, `tabHoliday` h, `tabHoliday List` hl + where sp.name=%s and emp.name=sp.employee + and hl.name=emp.holiday_list and + h.parent=hl.name and + hl.fiscal_year=%s""", (sales_person, fy_details[0])) + if not holiday_list: + # check global holiday list + holiday_list = webnotes.conn.sql("""select h.holiday_date from + `tabHoliday` h, `tabHoliday List` hl + where h.parent=hl.name and ifnull(hl.is_default, 0) = 1 + and hl.fiscal_year=%s""", fy_details[0]) + + if not validated and holiday_list: + if schedule_date in holiday_list: + schedule_date = add_days(schedule_date, -1) + else: + validated = True + + return schedule_date + #validate date range and periodicity selected #------------------------------------------------- def validate_period(self, arg): - arg1 = eval(arg) - if getdate(arg1['start_date']) >= getdate(arg1['end_date']): - msgprint("Start date should be less than end date ") - raise Exception - - period = (getdate(arg1['end_date'])-getdate(arg1['start_date'])).days+1 - - if (arg1['periodicity']=='Yearly' or arg1['periodicity']=='Half Yearly' or arg1['periodicity']=='Quarterly') and period<365: - msgprint(cstr(arg1['periodicity'])+ " periodicity can be set for period of atleast 1 year or more only") - raise Exception - elif arg1['periodicity']=='Monthly' and period<30: - msgprint("Monthly periodicity can be set for period of atleast 1 month or more") - raise Exception - elif arg1['periodicity']=='Weekly' and period<7: - msgprint("Weekly periodicity can be set for period of atleast 1 week or more") - raise Exception + args = eval(arg) + if getdate(args['start_date']) >= getdate(args['end_date']): + throw(_("Start date should be less than end date.")) + + period = (getdate(args['end_date']) - getdate(args['start_date'])).days + 1 + + if (args['periodicity'] == 'Yearly' or args['periodicity'] == 'Half Yearly' or + args['periodicity'] == 'Quarterly') and period < 365: + throw(cstr(args['periodicity']) + " periodicity can be set for period of atleast 1 year or more only") + elif args['periodicity'] == 'Monthly' and period < 30: + throw("Monthly periodicity can be set for period of atleast 1 month or more") + elif args['periodicity'] == 'Weekly' and period < 7: + throw("Weekly periodicity can be set for period of atleast 1 week or more") def get_no_of_visits(self, arg): - arg1 = eval(arg) + args = eval(arg) self.validate_period(arg) - period = (getdate(arg1['end_date'])-getdate(arg1['start_date'])).days+1 - - count =0 - if arg1['periodicity'] == 'Weekly': + period = (getdate(args['end_date']) - getdate(args['start_date'])).days + 1 + count = 0 + + if args['periodicity'] == 'Weekly': count = period/7 - elif arg1['periodicity'] == 'Monthly': + elif args['periodicity'] == 'Monthly': count = period/30 - elif arg1['periodicity'] == 'Quarterly': + elif args['periodicity'] == 'Quarterly': count = period/91 - elif arg1['periodicity'] == 'Half Yearly': + elif args['periodicity'] == 'Half Yearly': count = period/182 - elif arg1['periodicity'] == 'Yearly': + elif args['periodicity'] == 'Yearly': count = period/365 - ret = {'no_of_visits':count} + ret = {'no_of_visits' : count} return ret - - def validate_maintenance_detail(self): if not getlist(self.doclist, 'item_maintenance_detail'): - msgprint("Please enter Maintaince Details first") - raise Exception + throw(_("Please enter Maintaince Details first")) for d in getlist(self.doclist, 'item_maintenance_detail'): if not d.item_code: - msgprint("Please select item code") - raise Exception + throw(_("Please select item code")) elif not d.start_date or not d.end_date: - msgprint("Please select Start Date and End Date for item "+d.item_code) - raise Exception + throw(_("Please select Start Date and End Date for item") + " " + d.item_code) elif not d.no_of_visits: - msgprint("Please mention no of visits required") - raise Exception - elif not d.incharge_name: - msgprint("Please select Incharge Person's name") - raise Exception + throw(_("Please mention no of visits required")) + elif not d.sales_person: + throw(_("Please select Incharge Person's name")) if getdate(d.start_date) >= getdate(d.end_date): - msgprint("Start date should be less than end date for item "+d.item_code) - raise Exception + throw(_("Start date should be less than end date for item") + " " + d.item_code) #check if maintenance schedule already created against same sales order #----------------------------------------------------------------------------------- def validate_sales_order(self): for d in getlist(self.doclist, 'item_maintenance_detail'): if d.prevdoc_docname: - chk = webnotes.conn.sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", d.prevdoc_docname) + chk = webnotes.conn.sql("""select ms.name from `tabMaintenance Schedule` ms, + `tabMaintenance Schedule Item` msi where msi.parent=ms.name and + msi.prevdoc_docname=%s and ms.docstatus=1""", d.prevdoc_docname) if chk: - msgprint("Maintenance Schedule against "+d.prevdoc_docname+" already exist") - raise Exception + throw("Maintenance Schedule against " + d.prevdoc_docname + " already exist") def validate_serial_no(self): @@ -185,13 +212,13 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - chk = webnotes.conn.sql("select name, status from `tabSerial No` where docstatus!=2 and name=%s", (x)) + chk = webnotes.conn.sql("""select name, status from `tabSerial No` + where docstatus!=2 and name=%s""", (x)) chk1 = chk and chk[0][0] or '' status = chk and chk[0][1] or '' if not chk1: - msgprint("Serial no "+x+" does not exist in system.") - raise Exception + throw("Serial no " + x + " does not exist in system.") def validate(self): self.validate_maintenance_detail() @@ -208,13 +235,13 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - dt = webnotes.conn.sql("select delivery_date from `tabSerial No` where name = %s", x) + dt = webnotes.conn.sql("""select delivery_date from `tabSerial No` + where name=%s""", x) dt = dt and dt[0][0] or '' if dt: if dt > getdate(d.start_date): - msgprint("Maintenance start date can not be before delivery date "+dt.strftime('%Y-%m-%d')+" for serial no "+x) - raise Exception + throw("Maintenance start date can not be before delivery date " + dt.strftime('%Y-%m-%d') + " for serial no " + x) #update amc expiry date in serial no #------------------------------------------ @@ -224,7 +251,8 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - webnotes.conn.sql("update `tabSerial No` set amc_expiry_date = '%s', maintenance_status = 'Under AMC' where name = '%s'"% (amc_end_date,x)) + webnotes.conn.sql("""update `tabSerial No` set amc_expiry_date=%s, + maintenance_status='Under AMC' where name=%s""", (amc_end_date, x)) def on_update(self): webnotes.conn.set(self.doc, 'status', 'Draft') @@ -233,16 +261,16 @@ class DocType(TransactionBase): for d in getlist(self.doclist, 'item_maintenance_detail'): if cstr(d.serial_no).strip(): dt = webnotes.conn.sql("""select warranty_expiry_date, amc_expiry_date - from `tabSerial No` where name = %s""", d.serial_no, as_dict=1) + from `tabSerial No` where name=%s""", d.serial_no, as_dict=1) if dt[0]['warranty_expiry_date'] and dt[0]['warranty_expiry_date'] >= d.start_date: - webnotes.msgprint("""Serial No: %s is already under warranty upto %s. + throw("""Serial No: %s is already under warranty upto %s. Please check AMC Start Date.""" % - (d.serial_no, dt[0]["warranty_expiry_date"]), raise_exception=1) + (d.serial_no, dt[0]["warranty_expiry_date"])) if dt[0]['amc_expiry_date'] and dt[0]['amc_expiry_date'] >= d.start_date: - webnotes.msgprint("""Serial No: %s is already under AMC upto %s. + throw("""Serial No: %s is already under AMC upto %s. Please check AMC Start Date.""" % - (d.serial_no, dt[0]["amc_expiry_date"]), raise_exception=1) + (d.serial_no, dt[0]["amc_expiry_date"])) def validate_schedule(self): item_lst1 =[] @@ -256,13 +284,11 @@ class DocType(TransactionBase): item_lst2.append(m.item_code) if len(item_lst1) != len(item_lst2): - msgprint("Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'") - raise Exception + throw("Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'") else: for x in item_lst1: if x not in item_lst2: - msgprint("Maintenance Schedule is not generated for item "+x+". Please click on 'Generate Schedule'") - raise Exception + throw("Maintenance Schedule is not generated for item "+x+". Please click on 'Generate Schedule'") #check if serial no present in item maintenance table #----------------------------------------------------------- @@ -275,18 +301,15 @@ class DocType(TransactionBase): for m in getlist(self.doclist, 'maintenance_schedule_detail'): if serial_present: if m.item_code in serial_present and not m.serial_no: - msgprint("Please click on 'Generate Schedule' to fetch serial no added for item "+m.item_code) - raise Exception - - - + throw("Please click on 'Generate Schedule' to fetch serial no added for item "+m.item_code) + def on_cancel(self): for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: self.update_amc_date(d.serial_no, '') webnotes.conn.set(self.doc, 'status', 'Cancelled') delete_events(self.doc.doctype, self.doc.name) - + def on_trash(self): delete_events(self.doc.doctype, self.doc.name) @@ -313,7 +336,7 @@ def make_maintenance_visit(source_name, target_doclist=None): "field_map": { "parent": "prevdoc_docname", "parenttype": "prevdoc_doctype", - "incharge_name": "service_person" + "sales_person": "service_person" } } }, target_doclist) diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.txt b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.txt index 6c3508ad9a..56278898aa 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.txt +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:30", "docstatus": 0, - "modified": "2014-01-02 11:24:51", + "modified": "2014-01-20 17:48:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -27,6 +27,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt index 8b52d8b671..8ed6856d24 100644 --- a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt +++ b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:28:05", "docstatus": 0, - "modified": "2013-12-20 19:23:20", + "modified": "2013-12-31 12:13:38", "modified_by": "Administrator", "owner": "Administrator" }, @@ -52,6 +52,7 @@ "search_index": 0 }, { + "allow_on_submit": 0, "doctype": "DocField", "fieldname": "scheduled_date", "fieldtype": "Date", @@ -78,12 +79,13 @@ "report_hide": 1 }, { + "allow_on_submit": 0, "doctype": "DocField", - "fieldname": "incharge_name", + "fieldname": "sales_person", "fieldtype": "Link", "in_filter": 1, "in_list_view": 1, - "label": "Incharge Name", + "label": "Sales Person", "oldfieldname": "incharge_name", "oldfieldtype": "Link", "options": "Sales Person", diff --git a/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt b/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt index f42b48bf55..43d281d9e6 100644 --- a/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt +++ b/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:28:05", "docstatus": 0, - "modified": "2013-12-20 19:23:20", + "modified": "2013-12-31 12:08:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -112,10 +112,10 @@ }, { "doctype": "DocField", - "fieldname": "incharge_name", + "fieldname": "sales_person", "fieldtype": "Link", "in_filter": 1, - "label": "Sales Person Incharge", + "label": "Sales Person", "oldfieldname": "incharge_name", "oldfieldtype": "Link", "options": "Sales Person", diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt b/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt index 314960a843..6a03292dca 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:31", "docstatus": 0, - "modified": "2014-01-02 11:28:44", + "modified": "2014-01-20 17:48:57", "modified_by": "Administrator", "owner": "ashwini@webnotestech.com" }, @@ -27,6 +27,7 @@ "amend": 1, "cancel": 1, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/support/doctype/newsletter/newsletter.txt b/erpnext/support/doctype/newsletter/newsletter.txt index 9482ed712e..0618394f28 100644 --- a/erpnext/support/doctype/newsletter/newsletter.txt +++ b/erpnext/support/doctype/newsletter/newsletter.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:31", "docstatus": 0, - "modified": "2013-12-20 19:24:14", + "modified": "2014-01-24 13:00:11", "modified_by": "Administrator", "owner": "Administrator" }, @@ -13,7 +13,8 @@ "document_type": "Other", "icon": "icon-envelope", "module": "Support", - "name": "__common__" + "name": "__common__", + "title_field": "subject" }, { "doctype": "DocField", @@ -26,6 +27,7 @@ { "cancel": 0, "create": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", diff --git a/erpnext/support/doctype/support_ticket/get_support_mails.py b/erpnext/support/doctype/support_ticket/get_support_mails.py index b50e46ea08..49bd155c38 100644 --- a/erpnext/support/doctype/support_ticket/get_support_mails.py +++ b/erpnext/support/doctype/support_ticket/get_support_mails.py @@ -52,11 +52,6 @@ Original Query: subject = '['+cstr(d.name)+'] ' + cstr(d.subject), \ msg = cstr(response)) - def auto_close_tickets(self): - webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed' - where status = 'Replied' - and date_sub(curdate(),interval 15 Day) > modified""") - def get_support_mails(): if cint(webnotes.conn.get_value('Email Settings', None, 'sync_support_mails')): SupportMailbox() diff --git a/erpnext/support/doctype/support_ticket/support_ticket.py b/erpnext/support/doctype/support_ticket/support_ticket.py index 0b95292c6a..1b14ccc328 100644 --- a/erpnext/support/doctype/support_ticket/support_ticket.py +++ b/erpnext/support/doctype/support_ticket/support_ticket.py @@ -66,4 +66,9 @@ class DocType(TransactionBase): def set_status(name, status): st = webnotes.bean("Support Ticket", name) st.doc.status = status - st.save() \ No newline at end of file + st.save() + +def auto_close_tickets(): + webnotes.conn.sql("""update `tabSupport Ticket` set status = 'Closed' + where status = 'Replied' + and date_sub(curdate(),interval 15 Day) > modified""") diff --git a/erpnext/support/doctype/support_ticket/support_ticket.txt b/erpnext/support/doctype/support_ticket/support_ticket.txt index 59093f772f..2eac196af6 100644 --- a/erpnext/support/doctype/support_ticket/support_ticket.txt +++ b/erpnext/support/doctype/support_ticket/support_ticket.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-01 10:36:25", "docstatus": 0, - "modified": "2013-12-20 19:24:38", + "modified": "2014-01-20 17:49:31", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,6 +25,7 @@ }, { "amend": 0, + "cancel": 0, "create": 1, "doctype": "DocPerm", "email": 1, @@ -273,17 +274,17 @@ "print_hide": 1 }, { - "cancel": 0, + "delete": 0, "doctype": "DocPerm", "role": "Guest" }, { - "cancel": 0, + "delete": 0, "doctype": "DocPerm", "role": "Customer" }, { - "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "Support Team" } diff --git a/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt b/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt index 766eb20151..eec3d7f852 100644 --- a/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt +++ b/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-06 14:25:21", "docstatus": 0, - "modified": "2013-10-09 12:23:27", + "modified": "2013-12-31 12:24:48", "modified_by": "Administrator", "owner": "Administrator" }, @@ -10,7 +10,7 @@ "doctype": "Report", "is_standard": "Yes", "name": "__common__", - "query": "SELECT\n ms_sch.scheduled_date as \"Schedule Date:Date:120\",\n\tms_sch.item_code as \"Item Code:Link/Item:120\",\n\tms_sch.item_name as \"Item Name::120\",\n\tms_sch.serial_no as \"Serial No::120\",\n\tms_sch.incharge_name as \"Incharge::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms_item.prevdoc_docname as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, \n `tabMaintenance Schedule Detail` ms_sch, \n `tabMaintenance Schedule Item` ms_item\nWHERE\n\tms.name = ms_sch.parent and ms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_sch.scheduled_date asc, ms_sch.item_code asc", + "query": "SELECT\n ms_sch.scheduled_date as \"Schedule Date:Date:120\",\n\tms_sch.item_code as \"Item Code:Link/Item:120\",\n\tms_sch.item_name as \"Item Name::120\",\n\tms_sch.serial_no as \"Serial No::120\",\n\tms_sch.sales_person as \"Sales Person::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms_item.prevdoc_docname as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, \n `tabMaintenance Schedule Detail` ms_sch, \n `tabMaintenance Schedule Item` ms_item\nWHERE\n\tms.name = ms_sch.parent and ms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_sch.scheduled_date asc, ms_sch.item_code asc", "ref_doctype": "Maintenance Schedule", "report_name": "Maintenance Schedules", "report_type": "Query Report" diff --git a/erpnext/utilities/doctype/contact/contact.txt b/erpnext/utilities/doctype/contact/contact.txt index 65c22b32a0..5a3e32d650 100644 --- a/erpnext/utilities/doctype/contact/contact.txt +++ b/erpnext/utilities/doctype/contact/contact.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:32", "docstatus": 0, - "modified": "2013-12-20 19:23:59", + "modified": "2014-01-20 17:48:29", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ "permlevel": 0 }, { + "cancel": 0, "create": 1, "doctype": "DocPerm", "email": 1, @@ -242,50 +243,58 @@ "print_hide": 1 }, { - "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "System Manager" }, { "amend": 0, - "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "Sales Master Manager" }, { - "cancel": 1, + "delete": 1, "doctype": "DocPerm", "role": "Purchase Master Manager" }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales Manager" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase Manager" }, { + "delete": 0, "doctype": "DocPerm", "role": "Maintenance Manager" }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts Manager" }, { + "delete": 0, "doctype": "DocPerm", "role": "Sales User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Purchase User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Maintenance User" }, { + "delete": 0, "doctype": "DocPerm", "role": "Accounts User" } diff --git a/erpnext/utilities/doctype/note/note.txt b/erpnext/utilities/doctype/note/note.txt index 055619a550..94e5a0fbb3 100644 --- a/erpnext/utilities/doctype/note/note.txt +++ b/erpnext/utilities/doctype/note/note.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 13:41:00", "docstatus": 0, - "modified": "2013-12-20 19:24:14", + "modified": "2014-01-22 16:05:35", "modified_by": "Administrator", "owner": "Administrator" }, @@ -25,8 +25,9 @@ "permlevel": 0 }, { - "cancel": 1, + "cancel": 0, "create": 1, + "delete": 1, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -36,6 +37,7 @@ "permlevel": 0, "print": 1, "read": 1, + "restricted": 1, "role": "All", "write": 1 }, diff --git a/erpnext/utilities/doctype/sms_control/sms_control.py b/erpnext/utilities/doctype/sms_control/sms_control.py index 8fbb8fe7dc..41ff2a1515 100644 --- a/erpnext/utilities/doctype/sms_control/sms_control.py +++ b/erpnext/utilities/doctype/sms_control/sms_control.py @@ -7,7 +7,7 @@ import webnotes, json from webnotes.utils import nowdate, cstr from webnotes.model.code import get_obj from webnotes.model.doc import Document -from webnotes import msgprint +from webnotes import msgprint, throw, _ from webnotes.model.bean import getlist, copy_doclist class DocType: @@ -26,7 +26,7 @@ class DocType: validated_receiver_list.append(d) if not validated_receiver_list: - msgprint("Please enter valid mobile nos", raise_exception=1) + throw(_("Please enter valid mobile nos")) return validated_receiver_list @@ -37,12 +37,12 @@ class DocType: 'ERPNXT' if len(sender_name) > 6 and \ webnotes.conn.get_value("Control Panel", None, "country") == "India": - msgprint(""" + throw(_(""" As per TRAI rule, sender name must be exactly 6 characters. Kindly change sender name in Setup --> Global Defaults. Note: Hyphen, space, numeric digit, special characters are not allowed. - """, raise_exception=1) + """)) return sender_name def get_contact_number(self, arg): diff --git a/install_erpnext.py b/install_erpnext.py index c95a03d3e5..8e1448362b 100644 --- a/install_erpnext.py +++ b/install_erpnext.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import os, sys import argparse +import subprocess is_redhat = is_debian = None root_password = None @@ -19,7 +20,7 @@ requirements = [ "jinja2", "markdown2", "markupsafe", - "mysql-python", + "mysql-python", "pygeoip", "python-dateutil", "python-memcached", @@ -80,7 +81,7 @@ def validate_install(): return is_redhat, is_debian def install_using_yum(): - packages = "python python-setuptools gcc python-devel MySQL-python git memcached ntp vim-enhanced screen" + packages = "gcc MySQL-python git memcached ntp vim-enhanced screen" print "-"*80 print "Installing Packages: (This may take some time)" @@ -88,7 +89,10 @@ def install_using_yum(): print "-"*80 exec_in_shell("yum install -y %s" % packages) - if not exec_in_shell("which mysql"): + + try: + exec_in_shell("which mysql") + except subprocess.CalledProcessError: packages = "mysql mysql-server mysql-devel" print "Installing Packages:", packages exec_in_shell("yum install -y %s" % packages) @@ -101,26 +105,19 @@ def install_using_yum(): exec_in_shell('mysqladmin -u root password "%s"' % (root_password,)) print "Root password set as", root_password - # install htop - if not exec_in_shell("which htop"): - try: - exec_in_shell("cd /tmp && rpm -i --force http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm && yum install -y htop") - except: - pass - update_config_for_redhat() def update_config_for_redhat(): import re # set to autostart on startup - for service in ("mysqld", "memcached", "ntpd"): + for service in ("mysqld", "memcached"): exec_in_shell("chkconfig --level 2345 %s on" % service) exec_in_shell("service %s restart" % service) def install_using_apt(): exec_in_shell("apt-get update") - packages = "python python-setuptools python-dev build-essential python-pip python-mysqldb git memcached ntp vim screen htop" + packages = "python python-setuptools python-dev build-essential python-mysqldb git memcached ntp vim screen htop" print "-"*80 print "Installing Packages: (This may take some time)" print packages @@ -132,7 +129,9 @@ def install_using_apt(): exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password) exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password) - if not exec_in_shell("which mysql"): + try: + exec_in_shell("which mysql") + except subprocess.CalledProcessError: packages = "mysql-server libmysqlclient-dev" print "Installing Packages:", packages exec_in_shell("apt-get install -y %s" % packages) @@ -140,7 +139,7 @@ def install_using_apt(): update_config_for_debian() def update_config_for_debian(): - for service in ("mysql", "ntpd"): + for service in ("mysql",): exec_in_shell("service %s restart" % service) def install_python_modules(): @@ -148,13 +147,14 @@ def install_python_modules(): print "Installing Python Modules: (This may take some time)" print "-"*80 - if not exec_in_shell("which pip"): - exec_in_shell("easy_install pip") + try: + exec_in_shell("which pip2.7") + except subprocess.CalledProcessError: + exec_in_shell("easy_install-2.7 pip") - exec_in_shell("pip install --upgrade pip") - exec_in_shell("pip install --upgrade setuptools") - exec_in_shell("pip install --upgrade virtualenv") - exec_in_shell("pip install {}".format(' '.join(requirements))) + exec_in_shell("pip2.7 install --upgrade setuptools --no-use-wheel") + exec_in_shell("pip2.7 install --upgrade setuptools") + exec_in_shell("pip2.7 install {}".format(' '.join(requirements))) def install_erpnext(install_path): print @@ -200,7 +200,7 @@ def setup_folders(install_path): app = os.path.join(install_path, "app") if not os.path.exists(app): print "Cloning erpnext" - exec_in_shell("cd %s && git clone https://github.com/webnotes/erpnext.git app" % install_path) + exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/erpnext.git app" % install_path) exec_in_shell("cd app && git config core.filemode false") if not os.path.exists(app): raise Exception, "Couldn't clone erpnext repository" @@ -208,7 +208,7 @@ def setup_folders(install_path): lib = os.path.join(install_path, "lib") if not os.path.exists(lib): print "Cloning wnframework" - exec_in_shell("cd %s && git clone https://github.com/webnotes/wnframework.git lib" % install_path) + exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/wnframework.git lib" % install_path) exec_in_shell("cd lib && git config core.filemode false") if not os.path.exists(lib): raise Exception, "Couldn't clone wnframework repository" @@ -243,28 +243,8 @@ def post_install(install_path): def exec_in_shell(cmd): # using Popen instead of os.system - as recommended by python docs - from subprocess import Popen - import tempfile - - with tempfile.TemporaryFile() as stdout: - with tempfile.TemporaryFile() as stderr: - p = Popen(cmd, shell=True, stdout=stdout, stderr=stderr) - p.wait() - - stdout.seek(0) - out = stdout.read() - if out: out = out.decode('utf-8') - - stderr.seek(0) - err = stderr.read() - if err: err = err.decode('utf-8') - - if err and any((kw in err.lower() for kw in ["traceback", "error", "exception"])): - print out - raise Exception, err - else: - print "." - + import subprocess + out = subprocess.check_output(cmd, shell=True) return out def parse_args():