Enabled feature in Price List

This commit is contained in:
Akhilesh Darjee
2014-01-20 16:09:45 +05:30
22 changed files with 133 additions and 62 deletions

View File

@@ -530,6 +530,7 @@ erpnext.POS = Class.extend({
else if (operation == "decrease-qty") else if (operation == "decrease-qty")
d.qty != 1 ? d.qty -= 1 : d.qty = 1; d.qty != 1 ? d.qty -= 1 : d.qty = 1;
me.frm.script_manager.trigger("qty", d.doctype, d.name);
me.refresh(); me.refresh();
} }
}); });

View File

@@ -3,7 +3,7 @@
wn.require('app/setup/doctype/contact_control/contact_control.js'); wn.require('app/setup/doctype/contact_control/contact_control.js');
cur_frm.cscript.refresh = function(doc,dt,dn) { cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.cscript.make_dashboard(doc); cur_frm.cscript.make_dashboard(doc);
erpnext.hide_naming_series(); erpnext.hide_naming_series();
@@ -93,7 +93,7 @@ cur_frm.cscript.make_contact = function() {
cur_frm.contact_list.run(); cur_frm.contact_list.run();
} }
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) { cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
return{ return{
filters:{'buying': 1} filters:{'buying': 1}
} }

View File

@@ -89,8 +89,10 @@ def _get_price_list_rate(args, item_bean, meta):
# try fetching from price list # try fetching from price list
if args.buying_price_list and args.price_list_currency: if args.buying_price_list and args.price_list_currency:
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price` price_list_rate = webnotes.conn.sql("""select ip.ref_rate from
where price_list=%s and item_code=%s and buying=1""", `tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and ip.price_list=%s and
ip.item_code=%s and ip.buying=1 and pl.enabled=1""",
(args.buying_price_list, args.item_code), as_dict=1) (args.buying_price_list, args.item_code), as_dict=1)
if price_list_rate: if price_list_rate:

View File

@@ -1,6 +1,6 @@
{ {
"app_name": "ERPNext", "app_name": "ERPNext",
"app_version": "3.6.2", "app_version": "3.6.3",
"base_template": "app/portal/templates/base.html", "base_template": "app/portal/templates/base.html",
"modules": { "modules": {
"Accounts": { "Accounts": {
@@ -74,5 +74,5 @@
"type": "module" "type": "module"
} }
}, },
"requires_framework_version": "==3.7.2" "requires_framework_version": "==3.7.3"
} }

View File

@@ -43,7 +43,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) {
jv = locals['Journal Voucher'][jv]; jv = locals['Journal Voucher'][jv];
jv.voucher_type = 'Bank Voucher'; jv.voucher_type = 'Bank Voucher';
jv.user_remark = wn._('Payment of salary for the month: ') + doc.month + jv.user_remark = wn._('Payment of salary for the month: ') + doc.month +
wn._('and fiscal year: ') + doc.fiscal_year; wn._(' and fiscal year: ') + doc.fiscal_year;
jv.fiscal_year = doc.fiscal_year; jv.fiscal_year = doc.fiscal_year;
jv.company = doc.company; jv.company = doc.company;
jv.posting_date = dateutil.obj_to_str(new Date()); jv.posting_date = dateutil.obj_to_str(new Date());

View File

@@ -20,7 +20,7 @@ requirements = [
"jinja2", "jinja2",
"markdown2", "markdown2",
"markupsafe", "markupsafe",
"mysql-python==1.2.4", "mysql-python",
"pygeoip", "pygeoip",
"python-dateutil", "python-dateutil",
"python-memcached", "python-memcached",

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import webnotes
from webnotes.utils import flt
def execute():
for order_type in ["Sales", "Purchase"]:
for d in webnotes.conn.sql("""select par.name, sum(ifnull(child.qty, 0)) as total_qty
from `tab%s Order` par, `tab%s Order Item` child
where par.name = child.parent and par.docstatus = 1
and ifnull(par.net_total, 0) = 0 group by par.name""" %
(order_type, order_type), as_dict=1):
billed_qty = flt(webnotes.conn.sql("""select sum(ifnull(qty, 0))
from `tab%s Invoice Item` where %s=%s and docstatus=1""" %
(order_type, "sales_order" if order_type=="Sales" else "purchase_order", '%s'),
(d.name))[0][0])
per_billed = ((d.total_qty if billed_qty > d.total_qty else billed_qty)\
/ d.total_qty)*100
webnotes.conn.set_value(order_type+ " Order", d.name, "per_billed", per_billed)
if order_type == "Sales":
if per_billed < 0.001: billing_status = "Not Billed"
elif per_billed >= 99.99: billing_status = "Fully Billed"
else: billing_status = "Partly Billed"
webnotes.conn.set_value("Sales Order", d.name, "billing_status", billing_status)

View File

@@ -265,4 +265,6 @@ patch_list = [
"patches.1312.p02_update_item_details_in_item_price", "patches.1312.p02_update_item_details_in_item_price",
"patches.1401.p01_move_related_property_setters_to_custom_field", "patches.1401.p01_move_related_property_setters_to_custom_field",
"patches.1401.p01_make_buying_selling_as_check_box_in_price_list", "patches.1401.p01_make_buying_selling_as_check_box_in_price_list",
"patches.1401.update_billing_status_for_zero_value_order",
"execute:webnotes.reload_doc('stock', 'doctype', 'price_list') #2014-01-20",
] ]

View File

@@ -24,16 +24,17 @@ $(document).bind('toolbar_setup', function() {
wn.provide('wn.ui.misc'); wn.provide('wn.ui.misc');
wn.ui.misc.about = function() { wn.ui.misc.about = function() {
if(!wn.ui.misc.about_dialog) { if(!wn.ui.misc.about_dialog) {
var d = new wn.ui.Dialog({title: wn._('About ERPNext')}) var d = new wn.ui.Dialog({title: wn._('About')})
$(d.body).html(repl("<div>\ $(d.body).html(repl("<div>\
<p>"+wn._("ERPNext is an open-source web based ERP made by Web Notes Technologies Pvt Ltd.\ <h2>ERPNext</h2> \
to provide an integrated tool to manage most processes in a small organization.\ <p><strong>v" + wn.boot.app_version + "</strong></p>\
For more information about Web Notes, or to buy hosting servies, go to ")+ <p>"+wn._("An open source ERP made for the web.</p>") +
"<a href='https://erpnext.com'>https://erpnext.com</a>.</p>\ "<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p> \
<p>"+wn._("To report an issue, go to ")+"<a href='https://github.com/webnotes/erpnext/issues'>GitHub Issues</a></p>\ <p><a href='http://erpnext.org' target='_blank'>http://erpnext.org</a>.</p>\
<hr>\
<p><a href='http://www.gnu.org/copyleft/gpl.html'>License: GNU General Public License Version 3</a></p>\ <p><a href='http://www.gnu.org/copyleft/gpl.html'>License: GNU General Public License Version 3</a></p>\
<hr>\
<p>&copy; 2014 Web Notes Technologies Pvt. Ltd and contributers </p> \
</div>", wn.app)); </div>", wn.app));
wn.ui.misc.about_dialog = d; wn.ui.misc.about_dialog = d;

View File

@@ -21,6 +21,6 @@ erpnext.toolbar.setup = function() {
<i class="icon-fixed-width icon-comments"></i> '+wn._('Live Chat')+'</a></li>'); <i class="icon-fixed-width icon-comments"></i> '+wn._('Live Chat')+'</a></li>');
} }
$("#toolbar-tools").append('<li><a href="#latest-updates">\ $("#toolbar-tools").append('<li><a href="https://github.com/webnotes/erpnext/releases" target="_blank">\
<i class="icon-fixed-width icon-rss"></i> Latest Updates</li>'); <i class="icon-fixed-width icon-rss"></i> Latest Updates</li>');
} }

View File

@@ -18,7 +18,7 @@ cur_frm.cscript.load_defaults = function(doc, dt, dn) {
cur_frm.add_fetch('lead_name', 'company_name', 'customer_name'); cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate'); cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
cur_frm.cscript.refresh = function(doc,dt,dn) { cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.cscript.setup_dashboard(doc); cur_frm.cscript.setup_dashboard(doc);
erpnext.hide_naming_series(); erpnext.hide_naming_series();
@@ -107,20 +107,20 @@ cur_frm.cscript.make_contact = function() {
} }
cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) { cur_frm.fields_dict['customer_group'].get_query = function(doc, dt, dn) {
return{ return{
filters:{'is_group': 'No'} filters:{'is_group': 'No'}
} }
} }
cur_frm.fields_dict.lead_name.get_query = function(doc,cdt,cdn) { cur_frm.fields_dict.lead_name.get_query = function(doc, cdt, cdn) {
return{ return{
query:"controllers.queries.lead_query" query:"controllers.queries.lead_query"
} }
} }
cur_frm.fields_dict['default_price_list'].get_query = function(doc,cdt,cdn) { cur_frm.fields_dict['default_price_list'].get_query = function(doc, cdt, cdn) {
return{ return{
filters:{'selling': 1} filters:{'selling': 1}
} }

View File

@@ -150,8 +150,10 @@ def _get_basic_details(args, item_bean, warehouse_fieldname):
return out return out
def _get_price_list_rate(args, item_bean, meta): def _get_price_list_rate(args, item_bean, meta):
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price` ref_rate = webnotes.conn.sql("""select ip.ref_rate from
where price_list=%s and item_code=%s and selling=1""", `tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and ip.price_list=%s and
ip.item_code=%s and ip.selling=1 and pl.enabled=1""",
(args.selling_price_list, args.item_code), as_dict=1) (args.selling_price_list, args.item_code), as_dict=1)
if not ref_rate: if not ref_rate:

View File

@@ -27,8 +27,9 @@ def get_product_info(item_code):
else: else:
in_stock = -1 in_stock = -1
price = price_list and webnotes.conn.sql("""select ref_rate, currency from price = price_list and webnotes.conn.sql("""select ip.ref_rate, ip.currency from
`tabItem Price` where item_code=%s and price_list=%s""", `tabItem Price` ip, `tabPrice List` pl where ip.price_list=pl.name and
ip.item_code=%s and ip.price_list=%s and pl.enabled=1""",
(item_code, price_list), as_dict=1) or [] (item_code, price_list), as_dict=1) or []
price = price and price[0] or None price = price and price[0] or None

View File

@@ -244,8 +244,6 @@ class DocType:
webnotes.conn.set(self.doc, a, account_name) webnotes.conn.set(self.doc, a, account_name)
_set_default_accounts({ _set_default_accounts({
"default_income_account": "Sales",
"default_expense_account": "Cost of Goods Sold",
"receivables_group": "Accounts Receivable", "receivables_group": "Accounts Receivable",
"payables_group": "Accounts Payable", "payables_group": "Accounts Payable",
"default_cash_account": "Cash" "default_cash_account": "Cash"
@@ -257,8 +255,6 @@ class DocType:
"stock_adjustment_account": "Stock Adjustment", "stock_adjustment_account": "Stock Adjustment",
"expenses_included_in_valuation": "Expenses Included In Valuation" "expenses_included_in_valuation": "Expenses Included In Valuation"
}) })
def create_default_cost_center(self): def create_default_cost_center(self):
cc_list = [ cc_list = [

View File

@@ -98,6 +98,7 @@ def create_price_lists(args):
{ {
"doctype": "Price List", "doctype": "Price List",
"price_list_name": "Standard " + pl_type, "price_list_name": "Standard " + pl_type,
"enabled": 1,
"buying": 1 if pl_type == "Buying" else 0, "buying": 1 if pl_type == "Buying" else 0,
"selling": 1 if pl_type == "Selling" else 0, "selling": 1 if pl_type == "Selling" else 0,
"currency": args["currency"] "currency": args["currency"]

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import _, msgprint from webnotes import _, msgprint, throw
import json import json
def get_company_currency(company): def get_company_currency(company):
@@ -11,8 +11,8 @@ def get_company_currency(company):
if not currency: if not currency:
currency = webnotes.conn.get_default("currency") currency = webnotes.conn.get_default("currency")
if not currency: if not currency:
msgprint(_('Please specify Default Currency in Company Master \ throw(_('Please specify Default Currency in Company Master \
and Global Defaults'), raise_exception=True) and Global Defaults'))
return currency return currency
@@ -32,5 +32,14 @@ def get_ancestors_of(doctype, name):
@webnotes.whitelist() @webnotes.whitelist()
def get_price_list_currency(price_list): def get_price_list_currency(price_list):
return {"price_list_currency": webnotes.conn.get_value("Price List", price_list, price_list_currency = webnotes.conn.get_value("Price List", {"name": price_list,
"currency")} "enabled": 1}, "currency")
if not price_list_currency:
throw("{message}: {price_list} {disabled}".format(**{
"message": _("Price List"),
"price_list": price_list,
"disabled": _("is disabled.")
}))
else:
return {"price_list_currency": price_list_currency}

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes import _ from webnotes import throw, _
class ItemPriceDuplicateItem(webnotes.ValidationError): pass class ItemPriceDuplicateItem(webnotes.ValidationError): pass
@@ -12,26 +12,36 @@ class DocType:
self.doc, self.doclist = d, dl self.doc, self.doclist = d, dl
def validate(self): def validate(self):
self.validate_price_list()
self.check_duplicate_item() self.check_duplicate_item()
self.update_price_list_details() self.update_price_list_details()
self.update_item_details() self.update_item_details()
def update_price_list_details(self): def validate_price_list(self):
self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List", enabled = webnotes.conn.get_value("Price List", self.doc.price_list, "enabled")
self.doc.price_list, ["buying", "selling", "currency"]) if not enabled:
throw("{message}: {price_list} {disabled}".format(**{
def update_item_details(self): "message": _("Price List"),
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item", "price_list": self.doc.price_list,
self.doc.item_code, ["item_name", "description"]) "disabled": _("is disabled.")
}))
def check_duplicate_item(self): def check_duplicate_item(self):
if webnotes.conn.sql("""select name from `tabItem Price` if webnotes.conn.sql("""select name from `tabItem Price`
where item_code=%s and price_list=%s and name!=%s""", where item_code=%s and price_list=%s and name!=%s""",
(self.doc.item_code, self.doc.price_list, self.doc.name)): (self.doc.item_code, self.doc.price_list, self.doc.name)):
webnotes.throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{ throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{
"duplicate_item": _("Duplicate Item"), "duplicate_item": _("Duplicate Item"),
"item_code": self.doc.item_code, "item_code": self.doc.item_code,
"already": _("already available in Price List"), "already": _("already available in Price List"),
"price_list": self.doc.price_list "price_list": self.doc.price_list
}), ItemPriceDuplicateItem) }), ItemPriceDuplicateItem)
def update_price_list_details(self):
self.doc.buying, self.doc.selling, self.doc.currency = webnotes.conn.get_value("Price List",
{"name": self.doc.price_list, "enabled": 1}, ["buying", "selling", "currency"])
def update_item_details(self):
self.doc.item_name, self.doc.item_description = webnotes.conn.get_value("Item",
self.doc.item_code, ["item_name", "description"])

View File

@@ -2,7 +2,7 @@
{ {
"creation": "2013-01-25 11:35:09", "creation": "2013-01-25 11:35:09",
"docstatus": 0, "docstatus": 0,
"modified": "2014-01-06 18:28:23", "modified": "2014-01-17 13:29:39",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@@ -42,6 +42,18 @@
"doctype": "DocType", "doctype": "DocType",
"name": "Price List" "name": "Price List"
}, },
{
"default": "1",
"doctype": "DocField",
"fieldname": "enabled",
"fieldtype": "Check",
"label": "Enabled"
},
{
"doctype": "DocField",
"fieldname": "sb_1",
"fieldtype": "Section Break"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "price_list_name", "fieldname": "price_list_name",

View File

@@ -11,6 +11,7 @@ test_records = [
{ {
"doctype": "Price List", "doctype": "Price List",
"price_list_name": "_Test Price List", "price_list_name": "_Test Price List",
"enabled": 1,
"currency": "INR", "currency": "INR",
"selling": 1 "selling": 1
}, },
@@ -24,6 +25,7 @@ test_records = [
{ {
"doctype": "Price List", "doctype": "Price List",
"price_list_name": "_Test Price List 2", "price_list_name": "_Test Price List 2",
"enabled": 1,
"currency": "INR", "currency": "INR",
"selling": 1 "selling": 1
}, },
@@ -37,6 +39,7 @@ test_records = [
{ {
"doctype": "Price List", "doctype": "Price List",
"price_list_name": "_Test Price List India", "price_list_name": "_Test Price List India",
"enabled": 1,
"currency": "INR", "currency": "INR",
"selling": 1 "selling": 1
}, },
@@ -50,6 +53,7 @@ test_records = [
{ {
"doctype": "Price List", "doctype": "Price List",
"price_list_name": "_Test Price List Rest of the World", "price_list_name": "_Test Price List Rest of the World",
"enabled": 1,
"currency": "USD", "currency": "USD",
"selling": 1 "selling": 1
}, },

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import cint, validate_email_add from webnotes.utils import cint, validate_email_add
from webnotes import msgprint, _ from webnotes import throw, msgprint, _
class DocType: class DocType:
def __init__(self, doc, doclist=[]): def __init__(self, doc, doclist=[]):
@@ -18,7 +18,7 @@ class DocType:
def validate(self): def validate(self):
if self.doc.email_id and not validate_email_add(self.doc.email_id): if self.doc.email_id and not validate_email_add(self.doc.email_id):
msgprint("Please enter valid Email Id", raise_exception=1) throw(_("Please enter valid Email Id"))
self.update_parent_account() self.update_parent_account()
@@ -76,8 +76,8 @@ class DocType:
for d in bins: for d in bins:
if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \ if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \
d['indented_qty'] or d['projected_qty'] or d['planned_qty']: d['indented_qty'] or d['projected_qty'] or d['planned_qty']:
msgprint("""Warehouse: %s can not be deleted as qty exists for item: %s""" throw("""Warehouse: %s can not be deleted as qty exists for item: %s"""
% (self.doc.name, d['item_code']), raise_exception=1) % (self.doc.name, d['item_code']))
else: else:
webnotes.conn.sql("delete from `tabBin` where name = %s", d['name']) webnotes.conn.sql("delete from `tabBin` where name = %s", d['name'])
@@ -88,8 +88,8 @@ class DocType:
if webnotes.conn.sql("""select name from `tabStock Ledger Entry` if webnotes.conn.sql("""select name from `tabStock Ledger Entry`
where warehouse = %s""", self.doc.name): where warehouse = %s""", self.doc.name):
msgprint("""Warehouse can not be deleted as stock ledger entry throw(_("""Warehouse can not be deleted as stock ledger entry
exists for this warehouse.""", raise_exception=1) exists for this warehouse."""))
def before_rename(self, olddn, newdn, merge=False): def before_rename(self, olddn, newdn, merge=False):
# Add company abbr if not provided # Add company abbr if not provided

View File

@@ -16,7 +16,6 @@ def execute(filters=None):
val_rate_map = get_valuation_rate() val_rate_map = get_valuation_rate()
precision = get_currency_precision() or 2 precision = get_currency_precision() or 2
data = [] data = []
for item in sorted(item_map): for item in sorted(item_map):
data.append([item, item_map[item]["item_name"], data.append([item, item_map[item]["item_name"],
@@ -65,9 +64,10 @@ def get_price_list():
rate = {} rate = {}
price_list = webnotes.conn.sql("""select item_code, buying, selling, price_list = webnotes.conn.sql("""select ip.item_code, ip.buying, ip.selling,
concat(price_list, " - ", currency, " ", ref_rate) as price concat(ip.price_list, " - ", ip.currency, " ", ip.ref_rate) as price
from `tabItem Price`""", as_dict=1) from `tabItem Price` ip, `tabPrice List` pl
where ip.price_list=pl.name and pl.enabled=1""", as_dict=1)
for j in price_list: for j in price_list:
if j.price: if j.price:

View File

@@ -78,8 +78,9 @@ class TransactionBase(StatusUpdater):
3. Clears existing Sales Team and fetches the one mentioned in Customer 3. Clears existing Sales Team and fetches the one mentioned in Customer
""" """
customer_defaults = self.get_customer_defaults() customer_defaults = self.get_customer_defaults()
customer_defaults["selling_price_list"] = self.get_user_default_price_list("Selling") or \ customer_defaults["selling_price_list"] = \
self.get_user_default_price_list("selling_price_list") or \
customer_defaults.get("price_list") or \ customer_defaults.get("price_list") or \
webnotes.conn.get_value("Customer Group", self.doc.customer_group, webnotes.conn.get_value("Customer Group", self.doc.customer_group,
"default_price_list") or self.doc.selling_price_list "default_price_list") or self.doc.selling_price_list
@@ -91,11 +92,11 @@ class TransactionBase(StatusUpdater):
if self.meta.get_field("sales_team") and self.doc.customer: if self.meta.get_field("sales_team") and self.doc.customer:
self.set_sales_team_for_customer() self.set_sales_team_for_customer()
def get_user_default_price_list(self, price_list_for): def get_user_default_price_list(self, price_list):
from webnotes.defaults import get_user_default_as_list from webnotes.defaults import get_defaults_for
user_default_price_list = get_user_default_as_list("selling_price_list" user_default_price_list = get_defaults_for(webnotes.session.user).get(price_list)
if price_list_for=="Selling" else "buying_price_list") return cstr(user_default_price_list) \
return user_default_price_list[0] if len(user_default_price_list)==1 else "" if not isinstance(user_default_price_list, list) else ""
def set_sales_team_for_customer(self): def set_sales_team_for_customer(self):
from webnotes.model import default_fields from webnotes.model import default_fields
@@ -128,7 +129,7 @@ class TransactionBase(StatusUpdater):
if supplier.default_currency: if supplier.default_currency:
out["currency"] = supplier.default_currency out["currency"] = supplier.default_currency
out["buying_price_list"] = self.get_user_default_price_list("Buying") or \ out["buying_price_list"] = self.get_user_default_price_list("buying_price_list") or \
supplier.default_price_list or self.doc.buying_price_list supplier.default_price_list or self.doc.buying_price_list
return out return out