From df07c964f74e5527d2ab1a0aaffb2cdd96807619 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 2 Jan 2014 17:42:01 +0600 Subject: [PATCH 01/19] bumped to version 3.4.4 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index c09c2afac9..e8955b178c 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.3", + "app_version": "3.4.4", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.4.2" + "requires_framework_version": "==3.4.3" } \ No newline at end of file From b0a9581e59c6d7c8c1148afefb26c528bd464c2d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 3 Jan 2014 12:44:00 +0530 Subject: [PATCH 02/19] fixed accounts receivable for customer name --- .../accounts_receivable.py | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index 945bae434a..1c76f9baf1 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -18,16 +18,23 @@ class AccountsReceivableReport(object): return self.get_columns(), self.get_data() def get_columns(self): - return [ + 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" + "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100" ] + naming_by = self.get_selling_settings() + if naming_by[0].value == "Naming Series": + columns += ["Customer:Link/Customer:200"] + + columns += ["Customer Name::110", "Territory:Link/Territory:80", "Remarks::200"] + + return columns + def get_data(self): data = [] future_vouchers = self.get_entries_after(self.filters.report_date) @@ -42,10 +49,15 @@ 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] + + naming_by = self.get_selling_settings() + if naming_by[0].value == "Naming Series": + row += [self.get_customer(gle.account)] + + row += [self.get_customer_name(gle.account), self.get_territory(gle.account), gle.remarks] data.append(row) for i in range(0,len(data)): @@ -53,7 +65,11 @@ class AccountsReceivableReport(object): % ("/".join(["#Form", data[i][2], data[i][3]]),)) return data - + + def get_selling_settings(self): + return webnotes.conn.sql("""select value from `tabSingles` where + doctype='Selling Settings' and field='cust_master_name'""", as_dict=1) + 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() @@ -77,18 +93,21 @@ class AccountsReceivableReport(object): 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 @@ -164,4 +183,4 @@ def get_ageing_data(age_as_on, entry_date, outstanding_amount): if index is None: index = 3 outstanding_range[index] = outstanding_amount - return [age] + outstanding_range + return [age] + outstanding_range \ No newline at end of file From b4eba77f7b00d92a25335d6cfc2adf454763601d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 3 Jan 2014 12:58:04 +0530 Subject: [PATCH 03/19] fixed accounts receivable --- .../accounts_receivable/accounts_receivable.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index 1c76f9baf1..0407039e41 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -26,9 +26,8 @@ class AccountsReceivableReport(object): "Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100" ] - - naming_by = self.get_selling_settings() - if naming_by[0].value == "Naming Series": + + if self.get_customer_naming() == "Naming Series": columns += ["Customer:Link/Customer:200"] columns += ["Customer Name::110", "Territory:Link/Territory:80", "Remarks::200"] @@ -53,8 +52,7 @@ class AccountsReceivableReport(object): else gle.posting_date row += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) - naming_by = self.get_selling_settings() - if naming_by[0].value == "Naming Series": + if self.get_customer_naming() == "Naming Series": row += [self.get_customer(gle.account)] row += [self.get_customer_name(gle.account), self.get_territory(gle.account), gle.remarks] @@ -66,9 +64,8 @@ class AccountsReceivableReport(object): return data - def get_selling_settings(self): - return webnotes.conn.sql("""select value from `tabSingles` where - doctype='Selling Settings' and field='cust_master_name'""", as_dict=1) + def get_customer_naming(self): + return webnotes.conn.get_value("Selling Settings", None, "cust_master_name") def get_entries_after(self, report_date): # returns a distinct list From 8a0b7cece13a46b1f62f1dc7a70002f24a3f6731 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 3 Jan 2014 13:21:38 +0530 Subject: [PATCH 04/19] accounts receivable fixed --- .../accounts_receivable.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index 0407039e41..781db2aaf3 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -15,26 +15,28 @@ 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): + 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" + "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100", + "Customer:Link/Customer:200" ] - if self.get_customer_naming() == "Naming Series": - columns += ["Customer:Link/Customer:200"] + if customer_naming_by == "Naming Series": + columns += ["Customer Name::110"] - columns += ["Customer Name::110", "Territory:Link/Territory:80", "Remarks::200"] + columns += ["Territory:Link/Territory:80", "Remarks::200"] return columns - def get_data(self): + def get_data(self, customer_naming_by): data = [] future_vouchers = self.get_entries_after(self.filters.report_date) for gle in self.get_entries_till(self.filters.report_date): @@ -50,23 +52,21 @@ class AccountsReceivableReport(object): outstanding_amount] 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 += get_ageing_data(self.age_as_on, entry_date, outstanding_amount) + \ + [self.get_customer(gle.account)] - if self.get_customer_naming() == "Naming Series": - row += [self.get_customer(gle.account)] + if customer_naming_by == "Naming Series": + row += [self.get_customer_name(gle.account)] - row += [self.get_customer_name(gle.account), self.get_territory(gle.account), gle.remarks] + 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_customer_naming(self): - return webnotes.conn.get_value("Selling Settings", None, "cust_master_name") - 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() @@ -163,7 +163,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] From 866103bf666cd6bec9e96e478f8bf701207fb614 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 3 Jan 2014 13:57:06 +0600 Subject: [PATCH 05/19] bumped to version 3.4.5 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index e8955b178c..89c1332005 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.4", + "app_version": "3.4.5", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From a83337a2dd0102f26fd17e2d2d7da51cf059b843 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 3 Jan 2014 19:10:11 +0600 Subject: [PATCH 06/19] bumped to version 3.4.6 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 89c1332005..536e5af1ba 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.5", + "app_version": "3.4.6", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From b882fa14f4de7b7cc1ac8d5e946093b3ce78aa5d Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 6 Jan 2014 12:48:58 +0600 Subject: [PATCH 07/19] bumped to version 3.4.7 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 536e5af1ba..26fc50dbb8 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.6", + "app_version": "3.4.7", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From 7e79f300a144a704a8f21f418aef641dbd7fcd68 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Mon, 6 Jan 2014 12:23:29 +0530 Subject: [PATCH 08/19] accounts payable fixed --- .../accounts_payable/accounts_payable.py | 61 ++++++++++++------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/accounts/report/accounts_payable/accounts_payable.py b/accounts/report/accounts_payable/accounts_payable.py index f9266dc9ea..1bd8a9f323 100644 --- a/accounts/report/accounts_payable/accounts_payable.py +++ b/accounts/report/accounts_payable/accounts_payable.py @@ -9,18 +9,20 @@ from accounts.report.accounts_receivable.accounts_receivable import get_ageing_d 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 = [] @@ -102,10 +119,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(): From a11e14424c7e608b15c078be3547785c938b8202 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 7 Jan 2014 12:02:45 +0530 Subject: [PATCH 09/19] fix branching, pip version and mysql-python version pinning in install_erpnext --- install_erpnext.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/install_erpnext.py b/install_erpnext.py index c95a03d3e5..01de4575b9 100644 --- a/install_erpnext.py +++ b/install_erpnext.py @@ -19,7 +19,7 @@ requirements = [ "jinja2", "markdown2", "markupsafe", - "mysql-python", + "mysql-python==1.2.4", "pygeoip", "python-dateutil", "python-memcached", @@ -148,13 +148,13 @@ 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") + if not exec_in_shell("which pip-2.7"): + 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("pip-2.7 install --upgrade pip") + exec_in_shell("pip-2.7 install --upgrade setuptools") + exec_in_shell("pip-2.7 install --upgrade virtualenv") + exec_in_shell("pip-2.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" From 777bff6e8df41ff6575141c54fc6d96ec5469a0e Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 7 Jan 2014 14:17:44 +0600 Subject: [PATCH 10/19] bumped to version 3.4.8 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 26fc50dbb8..078ca16188 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.7", + "app_version": "3.4.8", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.4.3" + "requires_framework_version": "==3.4.4" } \ No newline at end of file From 69951e5d1ca6e42f3ec735c60f525add22680f43 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 7 Jan 2014 18:24:40 +0530 Subject: [PATCH 11/19] fix installer python packages issue --- install_erpnext.py | 60 ++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/install_erpnext.py b/install_erpnext.py index 01de4575b9..e285d4bbfe 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 @@ -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-2.7"): + try: + exec_in_shell("which pip2.7") + except subprocess.CalledProcessError: exec_in_shell("easy_install-2.7 pip") - exec_in_shell("pip-2.7 install --upgrade pip") - exec_in_shell("pip-2.7 install --upgrade setuptools") - exec_in_shell("pip-2.7 install --upgrade virtualenv") - exec_in_shell("pip-2.7 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 @@ -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(): From 806017c92ab7b0bc2d0f5671dc55d16c88f0766d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 7 Jan 2014 18:37:38 +0530 Subject: [PATCH 12/19] Price List and Item Price : Validfor Buying and Selling as separate check box --- accounts/doctype/pos_setting/pos_setting.js | 2 +- .../purchase_common/purchase_common.js | 2 +- buying/doctype/supplier/supplier.js | 2 +- buying/utils.py | 12 +-- controllers/accounts_controller.py | 18 ++-- .../p03_buying_selling_for_price_list.py | 21 +--- ...ice_list_and_item_details_in_item_price.py | 4 +- patches/patch_list.py | 1 + public/js/transaction.js | 9 +- selling/doctype/customer/customer.js | 2 +- selling/sales_common.js | 2 +- selling/utils/__init__.py | 14 ++- setup/page/setup_wizard/setup_wizard.py | 3 +- stock/doctype/item_price/item_price.js | 5 +- stock/doctype/item_price/item_price.py | 11 ++- stock/doctype/item_price/item_price.txt | 40 +++++--- stock/doctype/price_list/price_list.css | 7 -- stock/doctype/price_list/price_list.py | 15 ++- stock/doctype/price_list/price_list.txt | 19 ++-- stock/doctype/price_list/test_price_list.py | 8 +- stock/report/item_prices/item_prices.py | 4 +- utilities/demo/demo_docs/Item_Price.csv | 98 +++++++++---------- 22 files changed, 147 insertions(+), 152 deletions(-) delete mode 100644 stock/doctype/price_list/price_list.css diff --git a/accounts/doctype/pos_setting/pos_setting.js b/accounts/doctype/pos_setting/pos_setting.js index 8c5f254a52..dc13bb50ca 100755 --- a/accounts/doctype/pos_setting/pos_setting.js +++ b/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/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js index 9661f6edaf..14b8279245 100644 --- a/buying/doctype/purchase_common/purchase_common.js +++ b/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 } } }); } diff --git a/buying/doctype/supplier/supplier.js b/buying/doctype/supplier/supplier.js index 061861643d..ec4d3e606f 100644 --- a/buying/doctype/supplier/supplier.js +++ b/buying/doctype/supplier/supplier.js @@ -95,6 +95,6 @@ cur_frm.cscript.make_contact = function() { 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/buying/utils.py b/buying/utils.py index 0d9c8fa838..35d89c559d 100644 --- a/buying/utils.py +++ b/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 @@ -90,7 +90,7 @@ 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'""", + where price_list=%s and item_code=%s and buying=1""", (args.buying_price_list, args.item_code), as_dict=1) if price_list_rate: @@ -122,14 +122,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/controllers/accounts_controller.py b/controllers/accounts_controller.py index 1a399219e4..6660a93e4e 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import _, msgprint +from webnotes import _, msgprint, throw from webnotes.utils import flt, cint, today, cstr from webnotes.model.code import get_obj from setup.utils import get_company_currency @@ -50,8 +50,8 @@ class AccountsController(TransactionBase): 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) + throw(_("Account for this ") + fieldname + _(" has been freezed. ") + + self.doc.doctype + _(" can not be made.")) def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("currency"): @@ -179,17 +179,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 +200,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,7 +213,7 @@ 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): # referred row should also be inclusive diff --git a/patches/june_2013/p03_buying_selling_for_price_list.py b/patches/june_2013/p03_buying_selling_for_price_list.py index 2f92fe6a9e..15da085e53 100644 --- a/patches/june_2013/p03_buying_selling_for_price_list.py +++ b/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/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py b/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py index 3b4ca833f1..b92f7d052a 100644 --- a/patches/october_2013/p02_update_price_list_and_item_details_in_item_price.py +++ b/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/patches/patch_list.py b/patches/patch_list.py index 608ba77168..d291d762c5 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -263,4 +263,5 @@ patch_list = [ "patches.1311.p08_email_digest_recipients", "execute:webnotes.delete_doc('DocType', 'Warehouse Type')", "patches.1312.p02_update_item_details_in_item_price", + "patches.1401.p01_make_buying_selling_as_check_box_in_price_list", ] \ No newline at end of file diff --git a/public/js/transaction.js b/public/js/transaction.js index 4c4a810ed2..0fe0535c6b 100644 --- a/public/js/transaction.js +++ b/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)) { diff --git a/selling/doctype/customer/customer.js b/selling/doctype/customer/customer.js index 5e0ccc98f2..5d046904d3 100644 --- a/selling/doctype/customer/customer.js +++ b/selling/doctype/customer/customer.js @@ -122,6 +122,6 @@ cur_frm.fields_dict.lead_name.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/selling/sales_common.js b/selling/sales_common.js index dddc2b568d..f4f643015e 100644 --- a/selling/sales_common.js +++ b/selling/sales_common.js @@ -48,7 +48,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 } }; }); } diff --git a/selling/utils/__init__.py b/selling/utils/__init__.py index 5974da7d8b..85c20e86d8 100644 --- a/selling/utils/__init__.py +++ b/selling/utils/__init__.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 flt, cint, comma_and import json @@ -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,14 +111,12 @@ 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 @@ -147,7 +145,7 @@ def _get_basic_details(args, item_bean, warehouse_fieldname): 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'""", + where price_list=%s and item_code=%s and selling=1""", (args.selling_price_list, args.item_code), as_dict=1) if not ref_rate: diff --git a/setup/page/setup_wizard/setup_wizard.py b/setup/page/setup_wizard/setup_wizard.py index c1d3571ea5..ededd472a8 100644 --- a/setup/page/setup_wizard/setup_wizard.py +++ b/setup/page/setup_wizard/setup_wizard.py @@ -98,7 +98,8 @@ def create_price_lists(args): { "doctype": "Price List", "price_list_name": "Standard " + pl_type, - "buying_or_selling": pl_type, + "buying": 1 if pl_type == "Buying" else 0, + "selling": 1 if pl_type == "Selling" else 0, "currency": args["currency"] }, { diff --git a/stock/doctype/item_price/item_price.js b/stock/doctype/item_price/item_price.js index bece26c6b5..9f38fdb18e 100644 --- a/stock/doctype/item_price/item_price.js +++ b/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/stock/doctype/item_price/item_price.py b/stock/doctype/item_price/item_price.py index 072d70096e..9a8e3d35fb 100644 --- a/stock/doctype/item_price/item_price.py +++ b/stock/doctype/item_price/item_price.py @@ -1,7 +1,5 @@ # 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 @@ -19,8 +17,11 @@ class DocType: 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"]) + if not self.doc.selling and not self.doc.buying: + self.doc.buying, self.doc.selling = webnotes.conn.get_value("Price List", + self.doc.price_list, ["buying", "selling"]) + + self.doc.currency = webnotes.conn.get_value("Price List", self.doc.price_list, "currency") def update_item_details(self): self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item", diff --git a/stock/doctype/item_price/item_price.txt b/stock/doctype/item_price/item_price.txt index fc411eb1d6..b25fd30812 100644 --- a/stock/doctype/item_price/item_price.txt +++ b/stock/doctype/item_price/item_price.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-02 16:29:48", "docstatus": 0, - "modified": "2013-10-31 12:59:02", + "modified": "2014-01-07 18:11:10", "modified_by": "Administrator", "owner": "Administrator" }, @@ -43,6 +43,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", @@ -52,6 +59,27 @@ "options": "Price List", "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "buying", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Buying" + }, + { + "doctype": "DocField", + "fieldname": "selling", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Selling" + }, + { + "doctype": "DocField", + "fieldname": "item_details", + "fieldtype": "Section Break", + "label": "Item", + "options": "icon-tag" + }, { "doctype": "DocField", "fieldname": "item_code", @@ -83,16 +111,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/stock/doctype/price_list/price_list.css b/stock/doctype/price_list/price_list.css deleted file mode 100644 index 61b069442f..0000000000 --- a/stock/doctype/price_list/price_list.css +++ /dev/null @@ -1,7 +0,0 @@ -.table-grid tbody tr { - cursor: pointer; -} - -.table-grid thead tr { - height: 50px; -} \ No newline at end of file diff --git a/stock/doctype/price_list/price_list.py b/stock/doctype/price_list/price_list.py index d0e5d2b6d4..569e759159 100644 --- a/stock/doctype/price_list/price_list.py +++ b/stock/doctype/price_list/price_list.py @@ -3,16 +3,15 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _ +from webnotes import msgprint, _, throw from webnotes.utils import comma_or, 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 self.doc.buying and not self.doc.selling: + throw(_("Price List must be one of Buying or Selling")) if not self.doclist.get({"parentfield": "valid_for_territories"}): # if no territory, set default territory @@ -34,15 +33,15 @@ class DocType(DocListController): cart_settings.validate_price_lists() def set_default_if_missing(self): - if self.doc.buying_or_selling=="Selling": + if 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 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, self.doc.buying, self.doc.selling, self.doc.name)) \ No newline at end of file diff --git a/stock/doctype/price_list/price_list.txt b/stock/doctype/price_list/price_list.txt index d43076bcc8..69c3ecbc4c 100644 --- a/stock/doctype/price_list/price_list.txt +++ b/stock/doctype/price_list/price_list.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-25 11:35:09", "docstatus": 0, - "modified": "2013-10-31 19:24:33", + "modified": "2014-01-06 18:28:23", "modified_by": "Administrator", "owner": "Administrator" }, @@ -61,14 +61,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", diff --git a/stock/doctype/price_list/test_price_list.py b/stock/doctype/price_list/test_price_list.py index 86dcd1a594..bdcacc3452 100644 --- a/stock/doctype/price_list/test_price_list.py +++ b/stock/doctype/price_list/test_price_list.py @@ -12,7 +12,7 @@ test_records = [ "doctype": "Price List", "price_list_name": "_Test Price List", "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -25,7 +25,7 @@ test_records = [ "doctype": "Price List", "price_list_name": "_Test Price List 2", "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -38,7 +38,7 @@ test_records = [ "doctype": "Price List", "price_list_name": "_Test Price List India", "currency": "INR", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", @@ -51,7 +51,7 @@ test_records = [ "doctype": "Price List", "price_list_name": "_Test Price List Rest of the World", "currency": "USD", - "buying_or_selling": "Selling" + "selling": 1 }, { "doctype": "Applicable Territory", diff --git a/stock/report/item_prices/item_prices.py b/stock/report/item_prices/item_prices.py index da8b5007d5..e744cc73e4 100644 --- a/stock/report/item_prices/item_prices.py +++ b/stock/report/item_prices/item_prices.py @@ -65,13 +65,13 @@ def get_price_list(): rate = {} - price_list = webnotes.conn.sql("""select item_code, buying_or_selling, + price_list = webnotes.conn.sql("""select item_code, buying, selling, concat(price_list, " - ", currency, " ", ref_rate) as price from `tabItem Price`""", 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/utilities/demo/demo_docs/Item_Price.csv b/utilities/demo/demo_docs/Item_Price.csv index d70b7b3e67..cd7a13937f 100644 --- a/utilities/demo/demo_docs/Item_Price.csv +++ b/utilities/demo/demo_docs/Item_Price.csv @@ -1,49 +1,49 @@ -Data Import Template,,,,,,, -Table:,Item Price,,,,,, -,,,,,,, -,,,,,,, -Notes:,,,,,,, -Please do not change the template headings.,,,,,,, -First data column must be blank.,,,,,,, -"If you are uploading new records, leave the ""name"""" (ID) column blank.""",,,,,,, -"If you are uploading new records, ""Naming Series"""" becomes mandatory"," if present.""",,,,,, -Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.,,,,,,, -"For updating, you can update only selective columns.",,,,,,, -You can only upload upto 5000 records in one go. (may be less in some cases),,,,,,, -,,,,,,, -DocType:,Item Price,,,,,, -Column Labels:,ID,Price List,Item Code,Rate,Valid for Buying or Selling?,Item Name,Item Description -Column Name:,name,price_list,item_code,ref_rate,buying_or_selling,item_name,item_description -Mandatory:,Yes,Yes,Yes,Yes,No,No,No -Type:,Data (text),Link,Link,Currency,Select,Data,Text -Info:,,Valid Price List,Valid Item,,"One of: Selling, Buying",, -Start entering data below this line,,,,,,, -,,Standard Buying,Base Bearing Plate,15,Buying,, -,,Standard Buying,Base Plate,20,Buying,, -,,Standard Buying,Bearing Block,10,Buying,, -,,Standard Buying,Bearing Collar,20,Buying,, -,,Standard Buying,Bearing Pipe,15,Buying,, -,,Standard Buying,Blade Rib,10,Buying,, -,,Standard Buying,Disc Collars,74,Buying,, -,,Standard Buying,External Disc,45,Buying,, -,,Standard Buying,Internal Disc,33,Buying,, -,,Standard Buying,Shaft,30,Buying,, -,,Standard Buying,Stand,40,Buying,, -,,Standard Buying,Upper Bearing Plate,50,Buying,, -,,Standard Buying,Wing Sheet,22,Buying,, -,,Standard Selling,Wind Turbine,21,Selling,, -,,Standard Selling,Wind Mill A Series,28,Selling,, -,,Standard Selling,Wind MIll C Series,14,Selling,, -,,Standard Selling,Base Bearing Plate,28,Selling,, -,,Standard Selling,Base Plate,21,Selling,, -,,Standard Selling,Bearing Block,14,Selling,, -,,Standard Selling,Bearing Collar,103.6,Selling,, -,,Standard Selling,Bearing Pipe,63,Selling,, -,,Standard Selling,Blade Rib,46.2,Selling,, -,,Standard Selling,Disc Collars,42,Selling,, -,,Standard Selling,External Disc,56,Selling,, -,,Standard Selling,Internal Disc,70,Selling,, -,,Standard Selling,Shaft,340,Selling,, -,,Standard Selling,Stand,400,Selling,, -,,Standard Selling,Upper Bearing Plate,300,Selling,, -,,Standard Selling,Wing Sheet,30.8,Selling,, \ No newline at end of file +Data Import Template,,,,,,,, +Table:,Item Price,,,,,,, +,,,,,,,, +,,,,,,,, +Notes:,,,,,,,, +Please do not change the template headings.,,,,,,,, +First data column must be blank.,,,,,,,, +"If you are uploading new records, leave the ""name"" (ID) column blank.",,,,,,,, +"If you are uploading new records, ""Naming Series"" becomes mandatory, if present.",,,,,,,, +Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.,,,,,,,, +"For updating, you can update only selective columns.",,,,,,,, +You can only upload upto 5000 records in one go. (may be less in some cases),,,,,,,, +,,,,,,,, +DocType:,Item Price,,,,,,, +Column Labels:,ID,Price List,Item Code,Rate,Buying,Selling,Item Name,Item Description +Column Name:,name,price_list,item_code,ref_rate,buying,selling,item_name,item_description +Mandatory:,Yes,Yes,Yes,Yes,No,No,No,No +Type:,Data (text),Link,Link,Currency,Check,Check,Data,Text +Info:,,Valid Price List,Valid Item,,0 or 1,0 or 1,, +Start entering data below this line,,,,,,,, +,,Standard Buying,Base Bearing Plate,15,1,,, +,,Standard Buying,Base Plate,20,1,,, +,,Standard Buying,Bearing Block,10,1,,, +,,Standard Buying,Bearing Collar,20,1,,, +,,Standard Buying,Bearing Pipe,15,1,,, +,,Standard Buying,Blade Rib,10,1,,, +,,Standard Buying,Disc Collars,74,1,,, +,,Standard Buying,External Disc,45,1,,, +,,Standard Buying,Internal Disc,33,1,,, +,,Standard Buying,Shaft,30,1,,, +,,Standard Buying,Stand,40,1,,, +,,Standard Buying,Upper Bearing Plate,50,1,,, +,,Standard Buying,Wing Sheet,22,1,,, +,,Standard Selling,Wind Turbine,21,,1,, +,,Standard Selling,Wind Mill A Series,28,,1,, +,,Standard Selling,Wind MIll C Series,14,,1,, +,,Standard Selling,Base Bearing Plate,28,,1,, +,,Standard Selling,Base Plate,21,,1,, +,,Standard Selling,Bearing Block,14,,1,, +,,Standard Selling,Bearing Collar,103.6,,1,, +,,Standard Selling,Bearing Pipe,63,,1,, +,,Standard Selling,Blade Rib,46.2,,1,, +,,Standard Selling,Disc Collars,42,,1,, +,,Standard Selling,External Disc,56,,1,, +,,Standard Selling,Internal Disc,70,,1,, +,,Standard Selling,Shaft,340,,1,, +,,Standard Selling,Stand,400,,1,, +,,Standard Selling,Upper Bearing Plate,300,,1,, +,,Standard Selling,Wing Sheet,30.8,,1,, From 029f698c657bfef53456403e920f8ab5514b4871 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 7 Jan 2014 19:43:35 +0530 Subject: [PATCH 13/19] patch for item price and price list --- .../Print Format/POS Invoice/POS Invoice.txt | 4 +-- patches/1401/__init__.py | 0 ...ying_selling_as_check_box_in_price_list.py | 29 +++++++++++++++++++ stock/doctype/item_price/item_price.py | 7 ++--- stock/doctype/item_price/item_price.txt | 8 +++-- stock/doctype/price_list/price_list.py | 16 +++++----- .../item_wise_price_list_rate/__init__.py | 0 .../item_wise_price_list_rate.txt | 22 ++++++++++++++ 8 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 patches/1401/__init__.py create mode 100644 patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py create mode 100644 stock/report/item_wise_price_list_rate/__init__.py create mode 100644 stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt diff --git a/accounts/Print Format/POS Invoice/POS Invoice.txt b/accounts/Print Format/POS Invoice/POS Invoice.txt index aab8e18491..4f1b20a945 100644 --- a/accounts/Print Format/POS Invoice/POS Invoice.txt +++ b/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-07 18:46:29", "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\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", "module": "Accounts", "name": "__common__", "print_format_type": "Client", diff --git a/patches/1401/__init__.py b/patches/1401/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py b/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py new file mode 100644 index 0000000000..d5eb3e8d36 --- /dev/null +++ b/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("""udpate `tabItem Price` set selling=1 where ifnull(selling, 0)=0 and + ifnull(buying, 0)=0""") \ No newline at end of file diff --git a/stock/doctype/item_price/item_price.py b/stock/doctype/item_price/item_price.py index 9a8e3d35fb..e2c9f2fcb0 100644 --- a/stock/doctype/item_price/item_price.py +++ b/stock/doctype/item_price/item_price.py @@ -17,11 +17,8 @@ class DocType: self.update_item_details() def update_price_list_details(self): - if not self.doc.selling and not self.doc.buying: - self.doc.buying, self.doc.selling = webnotes.conn.get_value("Price List", - self.doc.price_list, ["buying", "selling"]) - - self.doc.currency = webnotes.conn.get_value("Price List", self.doc.price_list, "currency") + self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List", + self.doc.price_list, ["buying", "selling", "currency"]) def update_item_details(self): self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item", diff --git a/stock/doctype/item_price/item_price.txt b/stock/doctype/item_price/item_price.txt index b25fd30812..f329a5ff07 100644 --- a/stock/doctype/item_price/item_price.txt +++ b/stock/doctype/item_price/item_price.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-02 16:29:48", "docstatus": 0, - "modified": "2014-01-07 18:11:10", + "modified": "2014-01-07 19:16:49", "modified_by": "Administrator", "owner": "Administrator" }, @@ -64,14 +64,16 @@ "fieldname": "buying", "fieldtype": "Check", "in_list_view": 1, - "label": "Buying" + "label": "Buying", + "read_only": 1 }, { "doctype": "DocField", "fieldname": "selling", "fieldtype": "Check", "in_list_view": 1, - "label": "Selling" + "label": "Selling", + "read_only": 1 }, { "doctype": "DocField", diff --git a/stock/doctype/price_list/price_list.py b/stock/doctype/price_list/price_list.py index 569e759159..40841cfaac 100644 --- a/stock/doctype/price_list/price_list.py +++ b/stock/doctype/price_list/price_list.py @@ -4,14 +4,14 @@ from __future__ import unicode_literals import webnotes from webnotes import msgprint, _, throw -from webnotes.utils import comma_or, cint +from webnotes.utils import cint from webnotes.model.controller import DocListController import webnotes.defaults class DocType(DocListController): def validate(self): - if not self.doc.buying and not self.doc.selling: - throw(_("Price List must be one of Buying or Selling")) + 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 @@ -24,24 +24,24 @@ 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() cart_settings = webnotes.get_obj("Shopping Cart Settings") if cint(cart_settings.doc.enabled): cart_settings.validate_price_lists() - + def set_default_if_missing(self): - if self.doc.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: + 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=%s, selling=%s, modified=NOW() where price_list=%s""", - (self.doc.currency, self.doc.buying, self.doc.selling, self.doc.name)) \ No newline at end of file + (self.doc.currency, cint(self.doc.buying), cint(self.doc.selling), self.doc.name)) \ No newline at end of file diff --git a/stock/report/item_wise_price_list_rate/__init__.py b/stock/report/item_wise_price_list_rate/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt b/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt new file mode 100644 index 0000000000..f4d1d67ca4 --- /dev/null +++ b/stock/report/item_wise_price_list_rate/item_wise_price_list_rate.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-09-25 10:21:15", + "docstatus": 0, + "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\",\"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", + "report_type": "Report Builder" + }, + { + "doctype": "Report", + "name": "Item-wise Price List Rate" + } +] \ No newline at end of file From 8d0ef21911df9cc4daba5a10bf94f588941d4e69 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 7 Jan 2014 19:45:33 +0530 Subject: [PATCH 14/19] pos invoice print format changes --- accounts/Print Format/POS Invoice/POS Invoice.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/Print Format/POS Invoice/POS Invoice.txt b/accounts/Print Format/POS Invoice/POS Invoice.txt index 4f1b20a945..4710a4e562 100644 --- a/accounts/Print Format/POS Invoice/POS Invoice.txt +++ b/accounts/Print Format/POS Invoice/POS Invoice.txt @@ -2,14 +2,14 @@ { "creation": "2011-12-21 11:08:55", "docstatus": 0, - "modified": "2014-01-07 18:46:29", + "modified": "2014-01-07 19:44:47", "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\n\n\n\n\n\n\n\t\n\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t
RECEIPT NO: DATE:
M/s
\n\t\n\t
\n\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", From 9e2358c54473501bdb6e6b0baee22ee797319c01 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 7 Jan 2014 22:15:04 +0600 Subject: [PATCH 15/19] bumped to version 3.4.9 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 078ca16188..d88d22438b 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.8", + "app_version": "3.4.9", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From f7a102ffe334876fb481219a764529f318aee52d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 8 Jan 2014 19:35:01 +0530 Subject: [PATCH 16/19] POS print format fixed --- accounts/Print Format/POS Invoice/POS Invoice.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/Print Format/POS Invoice/POS Invoice.txt b/accounts/Print Format/POS Invoice/POS Invoice.txt index aab8e18491..7f1bba4c96 100644 --- a/accounts/Print Format/POS Invoice/POS Invoice.txt +++ b/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-08 19:32:16", "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", From 102b417b52f6781e7959e5aa8849d63ba78d4fd6 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 9 Jan 2014 11:39:06 +0530 Subject: [PATCH 17/19] Fix: Typo on patch --- .../1401/p01_make_buying_selling_as_check_box_in_price_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py b/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py index d5eb3e8d36..b764a7f935 100644 --- a/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py +++ b/patches/1401/p01_make_buying_selling_as_check_box_in_price_list.py @@ -25,5 +25,5 @@ def execute(): set ip.buying=pl.buying, ip.selling=pl.selling where ip.price_list=pl.name""") - webnotes.conn.sql("""udpate `tabItem Price` set selling=1 where ifnull(selling, 0)=0 and + 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 From 11bf06ad76a6c510eafa2b9d4c6066ccd9f893cd Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 9 Jan 2014 16:22:09 +0600 Subject: [PATCH 18/19] bumped to version 3.5.0 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index d88d22438b..65fa55c02d 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.4.9", + "app_version": "3.5.0", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.4.4" + "requires_framework_version": "==3.5.0" } \ No newline at end of file From 3e846d19d44fb46579b8ff42d5913651bc21cbf5 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 9 Jan 2014 16:26:53 +0600 Subject: [PATCH 19/19] bumped to version 3.5.1 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 65fa55c02d..8499ee84d3 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.5.0", + "app_version": "3.5.1", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": {