Fixed conflict

This commit is contained in:
Nabin Hait 2014-01-10 16:31:48 +05:30
commit 55387aa931
30 changed files with 300 additions and 242 deletions

File diff suppressed because one or more lines are too long

View File

@ -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 } };
});
}

View File

@ -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, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
% ("/".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():

View File

@ -15,20 +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):
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):
data = []
future_vouchers = self.get_entries_after(self.filters.report_date)
for gle in self.get_entries_till(self.filters.report_date):
@ -42,18 +50,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, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
% ("/".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()
@ -85,18 +98,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
@ -155,7 +171,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]

View File

@ -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 }
}
});
}

View File

@ -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}
}
}

View File

@ -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"""

View File

@ -1,6 +1,6 @@
{
"app_name": "ERPNext",
"app_version": "3.4.3",
"app_version": "3.5.1",
"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.5.0"
}

View File

@ -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

View File

@ -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==1.2.4",
"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():

View File

@ -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""")

View File

@ -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
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""")

View File

@ -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""")

View File

@ -264,4 +264,5 @@ patch_list = [
"execute:webnotes.delete_doc('DocType', 'Warehouse Type')",
"patches.1312.p02_update_item_details_in_item_price",
"patches.1401.p01_move_related_property_setters_to_custom_field",
"patches.1401.p01_make_buying_selling_as_check_box_in_price_list",
]

View File

@ -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)) {

View File

@ -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}
}
}

View File

@ -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 } };
});
}

View File

@ -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:

View File

@ -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"]
},
{

View File

@ -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

View File

@ -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,8 @@ 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"])
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",

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-02 16:29:48",
"docstatus": 0,
"modified": "2013-10-31 12:59:02",
"modified": "2014-01-07 19:16:49",
"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,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",
@ -83,16 +113,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",

View File

@ -1,7 +0,0 @@
.table-grid tbody tr {
cursor: pointer;
}
.table-grid thead tr {
height: 50px;
}

View File

@ -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,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.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))
buying=%s, selling=%s, modified=NOW() where price_list=%s""",
(self.doc.currency, cint(self.doc.buying), cint(self.doc.selling), self.doc.name))

View File

@ -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",

View File

@ -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",

View File

@ -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:

View File

@ -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"
}
]

View File

@ -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,,
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,,

1 Data Import Template
2 Table: Item Price
3
4
5 Notes:
6 Please do not change the template headings.
7 First data column must be blank.
8 If you are uploading new records, leave the "name"" (ID) column blank." If you are uploading new records, leave the "name" (ID) column blank.
9 If you are uploading new records, "Naming Series"" becomes mandatory If you are uploading new records, "Naming Series" becomes mandatory, if present. if present."
10 Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.
11 For updating, you can update only selective columns.
12 You can only upload upto 5000 records in one go. (may be less in some cases)
13
14 DocType: Item Price
15 Column Labels: ID Price List Item Code Rate Valid for Buying or Selling? Buying Item Name Selling Item Description Item Name Item Description
16 Column Name: name price_list item_code ref_rate buying_or_selling buying item_name selling item_description item_name item_description
17 Mandatory: Yes Yes Yes Yes No No No No
18 Type: Data (text) Link Link Currency Select Check Data Check Text Data Text
19 Info: Valid Price List Valid Item One of: Selling, Buying 0 or 1 0 or 1
20 Start entering data below this line
21 Standard Buying Base Bearing Plate 15 Buying 1
22 Standard Buying Base Plate 20 Buying 1
23 Standard Buying Bearing Block 10 Buying 1
24 Standard Buying Bearing Collar 20 Buying 1
25 Standard Buying Bearing Pipe 15 Buying 1
26 Standard Buying Blade Rib 10 Buying 1
27 Standard Buying Disc Collars 74 Buying 1
28 Standard Buying External Disc 45 Buying 1
29 Standard Buying Internal Disc 33 Buying 1
30 Standard Buying Shaft 30 Buying 1
31 Standard Buying Stand 40 Buying 1
32 Standard Buying Upper Bearing Plate 50 Buying 1
33 Standard Buying Wing Sheet 22 Buying 1
34 Standard Selling Wind Turbine 21 Selling 1
35 Standard Selling Wind Mill A Series 28 Selling 1
36 Standard Selling Wind MIll C Series 14 Selling 1
37 Standard Selling Base Bearing Plate 28 Selling 1
38 Standard Selling Base Plate 21 Selling 1
39 Standard Selling Bearing Block 14 Selling 1
40 Standard Selling Bearing Collar 103.6 Selling 1
41 Standard Selling Bearing Pipe 63 Selling 1
42 Standard Selling Blade Rib 46.2 Selling 1
43 Standard Selling Disc Collars 42 Selling 1
44 Standard Selling External Disc 56 Selling 1
45 Standard Selling Internal Disc 70 Selling 1
46 Standard Selling Shaft 340 Selling 1
47 Standard Selling Stand 400 Selling 1
48 Standard Selling Upper Bearing Plate 300 Selling 1
49 Standard Selling Wing Sheet 30.8 Selling 1