Fixes saving of Sales Order and fetching Prices frappe/frappe#478
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index fb36484..3b09090 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -260,8 +260,7 @@
"""Validate Fixed Asset and whether Income Account Entered Exists"""
for d in self.get('entries'):
item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem`
- where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00'
- or end_of_life > now())""", d.item_code)
+ where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now())""", d.item_code)
acc = frappe.db.sql("""select account_type from `tabAccount`
where name = %s and docstatus != 2""", d.income_account)
if not acc:
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index a0eb85d..3caed03 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -87,7 +87,7 @@
"""set missing item values"""
from erpnext.stock.get_item_details import get_item_details
if hasattr(self, "fname"):
- parent_dict = {}
+ parent_dict = {"doctype": self.doctype}
for fieldname in self.meta.get_valid_columns():
parent_dict[fieldname] = self.get(fieldname)
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index e8cdc80..408f434 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -16,47 +16,47 @@
flt.append([doctype, f[0], '!=', f[1][1:]])
else:
flt.append([doctype, f[0], '=', f[1]])
-
+
query = DatabaseQuery(doctype)
query.filters = flt
query.conditions = conditions
query.build_filter_conditions()
-
- cond = ' and ' + ' and '.join(query.conditions)
+
+ cond = ' and ' + ' and '.join(query.conditions)
else:
cond = ''
return cond
# searches for active employees
def employee_query(doctype, txt, searchfield, start, page_len, filters):
- return frappe.db.sql("""select name, employee_name from `tabEmployee`
- where status = 'Active'
- and docstatus < 2
- and (%(key)s like "%(txt)s"
- or employee_name like "%(txt)s")
+ return frappe.db.sql("""select name, employee_name from `tabEmployee`
+ where status = 'Active'
+ and docstatus < 2
+ and (%(key)s like "%(txt)s"
+ or employee_name like "%(txt)s")
%(mcond)s
- order by
- case when name like "%(txt)s" then 0 else 1 end,
- case when employee_name like "%(txt)s" then 0 else 1 end,
- name
- limit %(start)s, %(page_len)s""" % {'key': searchfield, 'txt': "%%%s%%" % txt,
+ order by
+ case when name like "%(txt)s" then 0 else 1 end,
+ case when employee_name like "%(txt)s" then 0 else 1 end,
+ name
+ limit %(start)s, %(page_len)s""" % {'key': searchfield, 'txt': "%%%s%%" % txt,
'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len})
# searches for leads which are not converted
-def lead_query(doctype, txt, searchfield, start, page_len, filters):
+def lead_query(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select name, lead_name, company_name from `tabLead`
- where docstatus < 2
- and ifnull(status, '') != 'Converted'
- and (%(key)s like "%(txt)s"
- or lead_name like "%(txt)s"
- or company_name like "%(txt)s")
+ where docstatus < 2
+ and ifnull(status, '') != 'Converted'
+ and (%(key)s like "%(txt)s"
+ or lead_name like "%(txt)s"
+ or company_name like "%(txt)s")
%(mcond)s
- order by
- case when name like "%(txt)s" then 0 else 1 end,
- case when lead_name like "%(txt)s" then 0 else 1 end,
- case when company_name like "%(txt)s" then 0 else 1 end,
- lead_name asc
- limit %(start)s, %(page_len)s""" % {'key': searchfield, 'txt': "%%%s%%" % txt,
+ order by
+ case when name like "%(txt)s" then 0 else 1 end,
+ case when lead_name like "%(txt)s" then 0 else 1 end,
+ case when company_name like "%(txt)s" then 0 else 1 end,
+ lead_name asc
+ limit %(start)s, %(page_len)s""" % {'key': searchfield, 'txt': "%%%s%%" % txt,
'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len})
# searches for customer
@@ -68,82 +68,82 @@
else:
fields = ["name", "customer_name", "customer_group", "territory"]
- fields = ", ".join(fields)
+ fields = ", ".join(fields)
- return frappe.db.sql("""select %(field)s from `tabCustomer`
- where docstatus < 2
- and (%(key)s like "%(txt)s"
- or customer_name like "%(txt)s")
+ return frappe.db.sql("""select %(field)s from `tabCustomer`
+ where docstatus < 2
+ and (%(key)s like "%(txt)s"
+ or customer_name like "%(txt)s")
%(mcond)s
- order by
- case when name like "%(txt)s" then 0 else 1 end,
- case when customer_name like "%(txt)s" then 0 else 1 end,
- name, customer_name
- limit %(start)s, %(page_len)s""" % {'field': fields,'key': searchfield,
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype),
+ order by
+ case when name like "%(txt)s" then 0 else 1 end,
+ case when customer_name like "%(txt)s" then 0 else 1 end,
+ name, customer_name
+ limit %(start)s, %(page_len)s""" % {'field': fields,'key': searchfield,
+ 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype),
'start': start, 'page_len': page_len})
# searches for supplier
def supplier_query(doctype, txt, searchfield, start, page_len, filters):
supp_master_name = frappe.defaults.get_user_default("supp_master_name")
- if supp_master_name == "Supplier Name":
+ if supp_master_name == "Supplier Name":
fields = ["name", "supplier_type"]
- else:
+ else:
fields = ["name", "supplier_name", "supplier_type"]
- fields = ", ".join(fields)
+ fields = ", ".join(fields)
- return frappe.db.sql("""select %(field)s from `tabSupplier`
- where docstatus < 2
- and (%(key)s like "%(txt)s"
- or supplier_name like "%(txt)s")
+ return frappe.db.sql("""select %(field)s from `tabSupplier`
+ where docstatus < 2
+ and (%(key)s like "%(txt)s"
+ or supplier_name like "%(txt)s")
%(mcond)s
- order by
- case when name like "%(txt)s" then 0 else 1 end,
- case when supplier_name like "%(txt)s" then 0 else 1 end,
- name, supplier_name
- limit %(start)s, %(page_len)s """ % {'field': fields,'key': searchfield,
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype), 'start': start,
+ order by
+ case when name like "%(txt)s" then 0 else 1 end,
+ case when supplier_name like "%(txt)s" then 0 else 1 end,
+ name, supplier_name
+ limit %(start)s, %(page_len)s """ % {'field': fields,'key': searchfield,
+ 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype), 'start': start,
'page_len': page_len})
-
+
def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
- tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount
- where tabAccount.docstatus!=2
+ tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount
+ where tabAccount.docstatus!=2
and account_type in (%s)
and group_or_ledger = 'Ledger'
and company = %s
and `%s` LIKE %s
- limit %s, %s""" %
- (", ".join(['%s']*len(filters.get("account_type"))), "%s", searchfield, "%s", "%s", "%s"),
- tuple(filters.get("account_type") + [filters.get("company"), "%%%s%%" % txt,
+ limit %s, %s""" %
+ (", ".join(['%s']*len(filters.get("account_type"))), "%s", searchfield, "%s", "%s", "%s"),
+ tuple(filters.get("account_type") + [filters.get("company"), "%%%s%%" % txt,
start, page_len]))
if not tax_accounts:
- tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount
- where tabAccount.docstatus!=2 and group_or_ledger = 'Ledger'
- and company = %s and `%s` LIKE %s limit %s, %s"""
- % ("%s", searchfield, "%s", "%s", "%s"),
+ tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount
+ where tabAccount.docstatus!=2 and group_or_ledger = 'Ledger'
+ and company = %s and `%s` LIKE %s limit %s, %s"""
+ % ("%s", searchfield, "%s", "%s", "%s"),
(filters.get("company"), "%%%s%%" % txt, start, page_len))
-
+
return tax_accounts
def item_query(doctype, txt, searchfield, start, page_len, filters):
from frappe.utils import nowdate
-
+
conditions = []
- return frappe.db.sql("""select tabItem.name,
- if(length(tabItem.item_name) > 40,
- concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
+ return frappe.db.sql("""select tabItem.name,
+ if(length(tabItem.item_name) > 40,
+ concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
if(length(tabItem.description) > 40, \
concat(substr(tabItem.description, 1, 40), "..."), description) as decription
- from tabItem
+ from tabItem
where tabItem.docstatus < 2
and (ifnull(tabItem.end_of_life, '') = '' or tabItem.end_of_life > %(today)s)
and (tabItem.`{key}` LIKE %(txt)s
- or tabItem.item_name LIKE %(txt)s)
+ or tabItem.item_name LIKE %(txt)s)
{fcond} {mcond}
limit %(start)s, %(page_len)s """.format(key=searchfield,
fcond=get_filters_cond(doctype, filters, conditions),
- mcond=get_match_cond(doctype)),
+ mcond=get_match_cond(doctype)),
{
"today": nowdate(),
"txt": "%%%s%%" % txt,
@@ -152,38 +152,38 @@
})
def bom(doctype, txt, searchfield, start, page_len, filters):
- conditions = []
+ conditions = []
- return frappe.db.sql("""select tabBOM.name, tabBOM.item
- from tabBOM
- where tabBOM.docstatus=1
- and tabBOM.is_active=1
- and tabBOM.%(key)s like "%(txt)s"
- %(fcond)s %(mcond)s
- limit %(start)s, %(page_len)s """ % {'key': searchfield, 'txt': "%%%s%%" % txt,
- 'fcond': get_filters_cond(doctype, filters, conditions),
+ return frappe.db.sql("""select tabBOM.name, tabBOM.item
+ from tabBOM
+ where tabBOM.docstatus=1
+ and tabBOM.is_active=1
+ and tabBOM.%(key)s like "%(txt)s"
+ %(fcond)s %(mcond)s
+ limit %(start)s, %(page_len)s """ % {'key': searchfield, 'txt': "%%%s%%" % txt,
+ 'fcond': get_filters_cond(doctype, filters, conditions),
'mcond':get_match_cond(doctype), 'start': start, 'page_len': page_len})
def get_project_name(doctype, txt, searchfield, start, page_len, filters):
cond = ''
if filters['customer']:
cond = '(`tabProject`.customer = "' + filters['customer'] + '" or ifnull(`tabProject`.customer,"")="") and'
-
- return frappe.db.sql("""select `tabProject`.name from `tabProject`
- where `tabProject`.status not in ("Completed", "Cancelled")
- and %(cond)s `tabProject`.name like "%(txt)s" %(mcond)s
- order by `tabProject`.name asc
- limit %(start)s, %(page_len)s """ % {'cond': cond,'txt': "%%%s%%" % txt,
+
+ return frappe.db.sql("""select `tabProject`.name from `tabProject`
+ where `tabProject`.status not in ("Completed", "Cancelled")
+ and %(cond)s `tabProject`.name like "%(txt)s" %(mcond)s
+ order by `tabProject`.name asc
+ limit %(start)s, %(page_len)s """ % {'cond': cond,'txt': "%%%s%%" % txt,
'mcond':get_match_cond(doctype),'start': start, 'page_len': page_len})
-
+
def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select `tabDelivery Note`.name, `tabDelivery Note`.customer_name
- from `tabDelivery Note`
- where `tabDelivery Note`.`%(key)s` like %(txt)s and
+ from `tabDelivery Note`
+ where `tabDelivery Note`.`%(key)s` like %(txt)s and
`tabDelivery Note`.docstatus = 1 %(fcond)s and
- (ifnull((select sum(qty) from `tabDelivery Note Item` where
+ (ifnull((select sum(qty) from `tabDelivery Note Item` where
`tabDelivery Note Item`.parent=`tabDelivery Note`.name), 0) >
- ifnull((select sum(qty) from `tabSales Invoice Item` where
+ ifnull((select sum(qty) from `tabSales Invoice Item` where
`tabSales Invoice Item`.docstatus = 1 and
`tabSales Invoice Item`.delivery_note=`tabDelivery Note`.name), 0))
%(mcond)s order by `tabDelivery Note`.`%(key)s` asc
@@ -198,30 +198,30 @@
from erpnext.controllers.queries import get_match_cond
if filters.has_key('warehouse'):
- return frappe.db.sql("""select batch_no from `tabStock Ledger Entry` sle
- where item_code = '%(item_code)s'
- and warehouse = '%(warehouse)s'
- and batch_no like '%(txt)s'
- and exists(select * from `tabBatch`
- where name = sle.batch_no
- and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
- and docstatus != 2)
+ return frappe.db.sql("""select batch_no from `tabStock Ledger Entry` sle
+ where item_code = '%(item_code)s'
+ and warehouse = '%(warehouse)s'
+ and batch_no like '%(txt)s'
+ and exists(select * from `tabBatch`
+ where name = sle.batch_no
+ and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
+ and docstatus != 2)
%(mcond)s
- group by batch_no having sum(actual_qty) > 0
- order by batch_no desc
- limit %(start)s, %(page_len)s """ % {'item_code': filters['item_code'],
- 'warehouse': filters['warehouse'], 'posting_date': filters['posting_date'],
- 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype),
+ group by batch_no having sum(actual_qty) > 0
+ order by batch_no desc
+ limit %(start)s, %(page_len)s """ % {'item_code': filters['item_code'],
+ 'warehouse': filters['warehouse'], 'posting_date': filters['posting_date'],
+ 'txt': "%%%s%%" % txt, 'mcond':get_match_cond(doctype),
'start': start, 'page_len': page_len})
else:
- return frappe.db.sql("""select name from tabBatch
- where docstatus != 2
- and item = '%(item_code)s'
+ return frappe.db.sql("""select name from tabBatch
+ where docstatus != 2
+ and item = '%(item_code)s'
and (ifnull(expiry_date, '')='' or expiry_date >= '%(posting_date)s')
- and name like '%(txt)s'
- %(mcond)s
- order by name desc
- limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'],
- 'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt,
- 'mcond':get_match_cond(doctype),'start': start,
+ and name like '%(txt)s'
+ %(mcond)s
+ order by name desc
+ limit %(start)s, %(page_len)s""" % {'item_code': filters['item_code'],
+ 'posting_date': filters['posting_date'], 'txt': "%%%s%%" % txt,
+ 'mcond':get_match_cond(doctype),'start': start,
'page_len': page_len})
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index b302c7c..103144f 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -329,7 +329,7 @@
def update_item(source, target, source_parent):
target.amount = flt(source.amount) - flt(source.billed_amt)
target.base_amount = target.amount * flt(source_parent.conversion_rate)
- target.qty = source.rate and target.amount / flt(source.rate) or obj.qty
+ target.qty = source.rate and target.amount / flt(source.rate) or source.qty
doclist = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index ce2a798..e5d6cec 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -20,22 +20,22 @@
this.setup_queries();
this.toggle_editable_price_list_rate();
},
-
+
setup_queries: function() {
var me = this;
-
+
this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate");
-
- $.each([["customer_address", "customer_filter"],
+
+ $.each([["customer_address", "customer_filter"],
["shipping_address_name", "customer_filter"],
- ["contact_person", "customer_filter"],
- ["customer", "customer"],
- ["lead", "lead"]],
+ ["contact_person", "customer_filter"],
+ ["customer", "customer"],
+ ["lead", "lead"]],
function(i, opts) {
- if(me.frm.fields_dict[opts[0]])
+ if(me.frm.fields_dict[opts[0]])
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
});
-
+
if(this.frm.fields_dict.taxes_and_charges) {
this.frm.set_query("taxes_and_charges", function() {
return {
@@ -52,11 +52,11 @@
return { filters: { selling: 1 } };
});
}
-
+
if(!this.fname) {
return;
}
-
+
if(this.frm.fields_dict[this.fname].grid.get_field('item_code')) {
this.frm.set_query("item_code", this.fname, function() {
return {
@@ -67,7 +67,7 @@
}
});
}
-
+
if(this.frm.fields_dict[this.fname].grid.get_field('batch_no')) {
this.frm.set_query("batch_no", this.fname, function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
@@ -79,7 +79,7 @@
'posting_date': me.frm.doc.posting_date,
}
if(item.warehouse) filters["warehouse"] = item.warehouse
-
+
return {
query : "erpnext.controllers.queries.get_batch_no",
filters: filters
@@ -87,56 +87,56 @@
}
});
}
-
+
if(this.frm.fields_dict.sales_team && this.frm.fields_dict.sales_team.grid.get_field("sales_person")) {
this.frm.set_query("sales_person", "sales_team", erpnext.queries.not_a_group_filter);
}
},
-
+
refresh: function() {
this._super();
- this.frm.toggle_display("customer_name",
+ this.frm.toggle_display("customer_name",
(this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer));
if(this.frm.fields_dict.packing_details) {
var packing_list_exists = (this.frm.doc.packing_details || []).length;
this.frm.toggle_display("packing_list", packing_list_exists ? true : false);
}
},
-
+
customer: function() {
erpnext.utils.get_party_details(this.frm);
},
-
+
customer_address: function() {
erpnext.utils.get_address_display(this.frm, "customer_address");
},
-
+
shipping_address_name: function() {
erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address");
},
-
+
contact_person: function() {
erpnext.utils.get_contact_details(this.frm);
},
-
+
barcode: function(doc, cdt, cdn) {
this.item_code(doc, cdt, cdn);
},
-
+
selling_price_list: function() {
this.get_price_list_currency("Selling");
},
-
+
price_list_rate: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]);
-
+
item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0),
precision("rate", item));
-
+
this.calculate_taxes_and_totals();
},
-
+
discount_percentage: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
if(!item.price_list_rate) {
@@ -145,63 +145,63 @@
this.price_list_rate(doc, cdt, cdn);
}
},
-
+
rate: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
frappe.model.round_floats_in(item, ["rate", "price_list_rate"]);
-
+
if(item.price_list_rate) {
item.discount_percentage = flt((1 - item.rate / item.price_list_rate) * 100.0,
precision("discount_percentage", item));
} else {
item.discount_percentage = 0.0;
}
-
+
this.calculate_taxes_and_totals();
},
discount_amount: function() {
this.calculate_taxes_and_totals();
},
-
+
commission_rate: function() {
this.calculate_commission();
refresh_field("total_commission");
},
-
+
total_commission: function() {
if(this.frm.doc.net_total) {
frappe.model.round_floats_in(this.frm.doc, ["net_total", "total_commission"]);
-
+
if(this.frm.doc.net_total < this.frm.doc.total_commission) {
- var msg = (frappe._("[Error]") + " " +
- frappe._(frappe.meta.get_label(this.frm.doc.doctype, "total_commission",
- this.frm.doc.name)) + " > " +
+ var msg = (frappe._("[Error]") + " " +
+ frappe._(frappe.meta.get_label(this.frm.doc.doctype, "total_commission",
+ this.frm.doc.name)) + " > " +
frappe._(frappe.meta.get_label(this.frm.doc.doctype, "net_total", this.frm.doc.name)));
msgprint(msg);
throw msg;
}
-
- this.frm.set_value("commission_rate",
+
+ this.frm.set_value("commission_rate",
flt(this.frm.doc.total_commission * 100.0 / this.frm.doc.net_total));
}
},
-
+
allocated_percentage: function(doc, cdt, cdn) {
var sales_person = frappe.get_doc(cdt, cdn);
-
+
if(sales_person.allocated_percentage) {
sales_person.allocated_percentage = flt(sales_person.allocated_percentage,
precision("allocated_percentage", sales_person));
sales_person.allocated_amount = flt(this.frm.doc.net_total *
- sales_person.allocated_percentage / 100.0,
+ sales_person.allocated_percentage / 100.0,
precision("allocated_amount", sales_person));
refresh_field(["allocated_percentage", "allocated_amount"], sales_person.name,
sales_person.parentfield);
}
},
-
+
warehouse: function(doc, cdt, cdn) {
var item = frappe.get_doc(cdt, cdn);
if(item.item_code && item.warehouse) {
@@ -215,7 +215,7 @@
});
}
},
-
+
toggle_rounded_total: function() {
var me = this;
if(cint(frappe.defaults.get_global_default("disable_rounded_total"))) {
@@ -225,16 +225,16 @@
});
}
},
-
+
toggle_editable_price_list_rate: function() {
var df = frappe.meta.get_docfield(this.tname, "price_list_rate", this.frm.doc.name);
var editable_price_list_rate = cint(frappe.defaults.get_default("editable_price_list_rate"));
-
+
if(df && editable_price_list_rate) {
df.read_only = 0;
}
},
-
+
calculate_taxes_and_totals: function() {
this._super();
this.calculate_total_advance("Sales Invoice", "advance_adjustment_details");
@@ -242,13 +242,13 @@
this.calculate_contribution();
// TODO check for custom_recalc in custom scripts of server
-
+
this.frm.refresh_fields();
},
-
+
calculate_item_values: function() {
var me = this;
-
+
if (!this.discount_amount_applied) {
$.each(this.frm.item_doclist, function(i, item) {
frappe.model.round_floats_in(item);
@@ -260,34 +260,34 @@
});
}
},
-
+
determine_exclusive_rate: function() {
var me = this;
$.each(me.frm.item_doclist, function(n, item) {
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
var cumulated_tax_fraction = 0.0;
-
+
$.each(me.frm.tax_doclist, function(i, tax) {
tax.tax_fraction_for_current_item = me.get_current_tax_fraction(tax, item_tax_map);
-
+
if(i==0) {
tax.grand_total_fraction_for_current_item = 1 + tax.tax_fraction_for_current_item;
} else {
- tax.grand_total_fraction_for_current_item =
+ tax.grand_total_fraction_for_current_item =
me.frm.tax_doclist[i-1].grand_total_fraction_for_current_item +
tax.tax_fraction_for_current_item;
}
-
+
cumulated_tax_fraction += tax.tax_fraction_for_current_item;
});
-
+
if(cumulated_tax_fraction && !me.discount_amount_applied) {
item.base_amount = flt(
(item.amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
precision("base_amount", item));
item.base_rate = flt(item.base_amount / item.qty, precision("base_rate", item));
-
+
if(item.discount_percentage == 100) {
item.base_price_list_rate = item.base_rate;
item.base_rate = 0.0;
@@ -298,31 +298,31 @@
}
});
},
-
+
get_current_tax_fraction: function(tax, item_tax_map) {
// Get tax fraction for calculating tax exclusive amount
// from tax inclusive amount
var current_tax_fraction = 0.0;
-
+
if(cint(tax.included_in_print_rate)) {
var tax_rate = this._get_tax_rate(tax, item_tax_map);
-
+
if(tax.charge_type == "On Net Total") {
current_tax_fraction = (tax_rate / 100.0);
-
+
} else if(tax.charge_type == "On Previous Row Amount") {
current_tax_fraction = (tax_rate / 100.0) *
this.frm.tax_doclist[cint(tax.row_id) - 1].tax_fraction_for_current_item;
-
+
} else if(tax.charge_type == "On Previous Row Total") {
current_tax_fraction = (tax_rate / 100.0) *
this.frm.tax_doclist[cint(tax.row_id) - 1].grand_total_fraction_for_current_item;
}
}
-
+
return current_tax_fraction;
},
-
+
calculate_net_total: function() {
var me = this;
this.frm.doc.net_total = this.frm.doc.net_total_export = 0.0;
@@ -334,7 +334,7 @@
frappe.model.round_floats_in(this.frm.doc, ["net_total", "net_total_export"]);
},
-
+
calculate_totals: function() {
var me = this;
var tax_count = this.frm.tax_doclist.length;
@@ -344,13 +344,13 @@
precision("grand_total"));
this.frm.doc.grand_total_export = flt(this.frm.doc.grand_total / this.frm.doc.conversion_rate,
precision("grand_total_export"));
-
+
this.frm.doc.other_charges_total = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
precision("other_charges_total"));
- this.frm.doc.other_charges_total_export = flt(this.frm.doc.grand_total_export -
+ this.frm.doc.other_charges_total_export = flt(this.frm.doc.grand_total_export -
this.frm.doc.net_total_export + flt(this.frm.doc.discount_amount),
precision("other_charges_total_export"));
-
+
this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total);
this.frm.doc.rounded_total_export = Math.round(this.frm.doc.grand_total_export);
},
@@ -393,19 +393,19 @@
total_actual_tax += value;
});
- grand_total_for_discount_amount = flt(this.frm.doc.grand_total - total_actual_tax,
+ grand_total_for_discount_amount = flt(this.frm.doc.grand_total - total_actual_tax,
precision("grand_total"));
return grand_total_for_discount_amount;
},
-
+
calculate_outstanding_amount: function() {
- // NOTE:
+ // NOTE:
// paid_amount and write_off_amount is only for POS Invoice
// total_advance is only for non POS Invoice
if(this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.docstatus==0) {
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount",
"paid_amount"]);
- var total_amount_to_pay = this.frm.doc.grand_total - this.frm.doc.write_off_amount
+ var total_amount_to_pay = this.frm.doc.grand_total - this.frm.doc.write_off_amount
- this.frm.doc.total_advance;
if(this.frm.doc.is_pos) {
if(!this.frm.doc.paid_amount) this.frm.doc.paid_amount = flt(total_amount_to_pay);
@@ -413,11 +413,11 @@
this.frm.doc.paid_amount = 0
}
- this.frm.set_value("outstanding_amount", flt(total_amount_to_pay
+ this.frm.set_value("outstanding_amount", flt(total_amount_to_pay
- this.frm.doc.paid_amount, precision("outstanding_amount")));
}
},
-
+
calculate_commission: function() {
if(this.frm.fields_dict.commission_rate) {
if(this.frm.doc.commission_rate > 100) {
@@ -426,12 +426,12 @@
msgprint(msg);
throw msg;
}
-
+
this.frm.doc.total_commission = flt(this.frm.doc.net_total * this.frm.doc.commission_rate / 100.0,
precision("total_commission"));
}
},
-
+
calculate_contribution: function() {
var me = this;
$.each(this.frm.doc.doctype.sales_team || [], function(i, sales_person) {
@@ -443,7 +443,7 @@
}
});
},
-
+
_cleanup: function() {
this._super();
this.frm.doc.in_words = this.frm.doc.in_words_export = "";
@@ -463,16 +463,16 @@
})
}
},
-
+
set_dynamic_labels: function() {
this._super();
set_sales_bom_help(this.frm.doc);
},
-
+
change_form_labels: function(company_currency) {
var me = this;
var field_label_map = {};
-
+
var setup_field_label_map = function(fields_list, currency) {
$.each(fields_list, function(i, fname) {
var docfield = frappe.meta.docfield_map[me.frm.doc.doctype][fname];
@@ -482,76 +482,76 @@
}
});
};
- setup_field_label_map(["net_total", "other_charges_total", "grand_total",
+ setup_field_label_map(["net_total", "other_charges_total", "grand_total",
"rounded_total", "in_words",
"outstanding_amount", "total_advance", "paid_amount", "write_off_amount"],
company_currency);
-
- setup_field_label_map(["net_total_export", "other_charges_total_export", "grand_total_export",
+
+ setup_field_label_map(["net_total_export", "other_charges_total_export", "grand_total_export",
"rounded_total_export", "in_words_export"], this.frm.doc.currency);
-
- cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
+
+ cur_frm.set_df_property("conversion_rate", "description", "1 " + this.frm.doc.currency
+ " = [?] " + company_currency)
-
+
if(this.frm.doc.price_list_currency && this.frm.doc.price_list_currency!=company_currency) {
- cur_frm.set_df_property("plc_conversion_rate", "description", "1 " + this.frm.doc.price_list_currency
+ cur_frm.set_df_property("plc_conversion_rate", "description", "1 " + this.frm.doc.price_list_currency
+ " = [?] " + company_currency)
}
-
+
// toggle fields
- this.frm.toggle_display(["conversion_rate", "net_total", "other_charges_total",
+ this.frm.toggle_display(["conversion_rate", "net_total", "other_charges_total",
"grand_total", "rounded_total", "in_words"],
this.frm.doc.currency != company_currency);
-
- this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
+
+ this.frm.toggle_display(["plc_conversion_rate", "price_list_currency"],
this.frm.doc.price_list_currency != company_currency);
-
+
// set labels
$.each(field_label_map, function(fname, label) {
me.frm.fields_dict[fname].set_label(label);
});
},
-
+
change_grid_labels: function(company_currency) {
var me = this;
var field_label_map = {};
-
+
var setup_field_label_map = function(fields_list, currency, parentfield) {
var grid_doctype = me.frm.fields_dict[parentfield].grid.doctype;
$.each(fields_list, function(i, fname) {
var docfield = frappe.meta.docfield_map[grid_doctype][fname];
if(docfield) {
var label = frappe._(docfield.label || "").replace(/\([^\)]*\)/g, "");
- field_label_map[grid_doctype + "-" + fname] =
+ field_label_map[grid_doctype + "-" + fname] =
label.trim() + " (" + currency + ")";
}
});
}
-
+
setup_field_label_map(["base_rate", "base_price_list_rate", "base_amount"],
company_currency, this.fname);
-
+
setup_field_label_map(["rate", "price_list_rate", "amount"],
this.frm.doc.currency, this.fname);
-
+
setup_field_label_map(["tax_amount", "total"], company_currency, "other_charges");
-
+
if(this.frm.fields_dict["advance_allocation_details"]) {
setup_field_label_map(["advance_amount", "allocated_amount"], company_currency,
"advance_allocation_details");
}
-
+
// toggle columns
var item_grid = this.frm.fields_dict[this.fname].grid;
- var show = (this.frm.doc.currency != company_currency) ||
- (cur_frm.doc.other_charges.filter(
+ var show = (this.frm.doc.currency != company_currency) ||
+ ((cur_frm.doc.other_charges || []).filter(
function(d) { return d.included_in_print_rate===1}).length);
-
+
$.each(["base_rate", "base_price_list_rate", "base_amount"], function(i, fname) {
if(frappe.meta.get_docfield(item_grid.doctype, fname))
item_grid.set_column_disp(fname, show);
});
-
+
// set labels
var $wrapper = $(this.frm.wrapper);
$.each(field_label_map, function(fname, label) {
@@ -567,7 +567,7 @@
if(!cur_frm.fields_dict.packing_list) return;
if ((doc.packing_details || []).length) {
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
-
+
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
help_msg = "<div class='alert alert-warning'>" +
frappe._("For 'Sales BOM' items, warehouse, serial no and batch no \
@@ -576,7 +576,7 @@
those values can be entered in the main item table, values will be copied to 'Packing List' table.")+
"</div>";
frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
- }
+ }
} else {
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index b797420..78bdcb0 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -1,13 +1,15 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
+frappe.provide("erpnext.item");
+
cur_frm.cscript.refresh = function(doc) {
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
// read only if any stock ledger entry exists
cur_frm.cscript.make_dashboard()
erpnext.hide_naming_series();
-
+
if(!doc.__islocal && doc.show_in_website) {
cur_frm.appframe.add_button("View In Website", function() {
window.open(doc.page_name);
@@ -19,8 +21,19 @@
cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method'],
doc.__sle_exists=="exists" ? false : true);
}
+
+ erpnext.item.toggle_reqd(cur_frm);
}
+erpnext.item.toggle_reqd = function(frm) {
+ frm.toggle_reqd("default_warehouse", frm.doc.is_stock_item==="Yes");
+};
+
+frappe.ui.form.on("Item", "is_stock_item", function(frm) {
+ erpnext.item.toggle_reqd(frm);
+});
+
+
cur_frm.cscript.make_dashboard = function() {
cur_frm.dashboard.reset();
if(cur_frm.doc.__islocal)
@@ -152,7 +165,7 @@
cur_frm.cscript.copy_from_item_group = function(doc) {
frappe.model.with_doc("Item Group", doc.item_group, function() {
$.each((doc.item_website_specifications || []), function(i, d) {
- var n = frappe.model.add_child(doc, "Item Website Specification",
+ var n = frappe.model.add_child(doc, "Item Website Specification",
"item_website_specifications");
n.label = d.label;
n.description = d.description;
@@ -164,11 +177,11 @@
cur_frm.cscript.image = function() {
refresh_field("image_view");
-
+
if(!cur_frm.doc.description_html)
cur_frm.cscript.add_image(cur_frm.doc);
else {
- msgprint(frappe._("You may need to update: ") +
+ msgprint(frappe._("You may need to update: ") +
frappe.meta.get_docfield(cur_frm.doc.doctype, "description_html").label);
}
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index dd364ff..1bdab9e 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -7,7 +7,7 @@
from frappe.utils import cstr, flt, getdate, now_datetime, formatdate
from frappe.website.website_generator import WebsiteGenerator
-class WarehouseNotSet(Exception): pass
+class WarehouseNotSet(frappe.ValidationError): pass
class Item(WebsiteGenerator):
def onload(self):
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index b6ffb83..cb130b2 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -369,8 +369,8 @@
arg = json.loads(arg)
item = frappe.db.sql("""select stock_uom, description, item_name,
expense_account, buying_cost_center from `tabItem`
- where name = %s and (ifnull(end_of_life,'')='' or end_of_life ='0000-00-00'
- or end_of_life > now())""", (arg.get('item_code')), as_dict = 1)
+ where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now())""",
+ (arg.get('item_code')), as_dict = 1)
if not item:
msgprint("Item is not active", raise_exception=1)
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index eeff275..85d7e12 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -31,49 +31,49 @@
if isinstance(args, basestring):
args = json.loads(args)
-
+
args = frappe._dict(args)
if not args.get("transaction_type"):
args.transaction_type = "buying" if frappe.get_meta(args.get("doctype")).get_field("supplier") \
else "selling"
-
+
if not args.get("price_list"):
args.price_list = args.get("selling_price_list") or args.get("buying_price_list")
-
+
if args.barcode:
args.item_code = get_item_code(barcode=args.barcode)
elif not args.item_code and args.serial_no:
args.item_code = get_item_code(serial_no=args.serial_no)
-
+
item_doc = frappe.get_doc("Item", args.item_code)
item = item_doc
validate_item_details(args, item)
-
+
out = get_basic_details(args, item_doc)
-
+
get_party_item_code(args, item_doc, out)
if out.get("warehouse"):
out.update(get_available_qty(args.item_code, out.warehouse))
out.update(get_projected_qty(item.name, out.warehouse))
-
+
get_price_list_rate(args, item_doc, out)
if args.transaction_type == "selling" and cint(args.is_pos):
out.update(get_pos_settings_item_details(args.company, args))
-
+
apply_pricing_rule(out, args)
-
+
if args.get("doctype") in ("Sales Invoice", "Delivery Note"):
if item_doc.has_serial_no == "Yes" and not args.serial_no:
out.serial_no = get_serial_nos_by_fifo(args, item_doc)
-
+
if args.transaction_date and item.lead_time_days:
out.schedule_date = out.lead_time_date = add_days(args.transaction_date,
item.lead_time_days)
-
+
return out
def get_item_code(barcode=None, serial_no=None):
@@ -83,26 +83,26 @@
item_code = frappe.db.get_value("Serial No", serial_no, "item_code")
if not item_code:
- throw(_("No Item found with ") + _("Barcode") if barcode else _("Serial No") +
+ throw(_("No Item found with ") + _("Barcode") if barcode else _("Serial No") +
": %s" % (barcode or serial_no))
-
+
return item_code
-
+
def validate_item_details(args, item):
if not args.company:
throw(_("Please specify Company"))
-
+
from erpnext.stock.doctype.item.item import validate_end_of_life
validate_end_of_life(item.name, item.end_of_life)
-
+
if args.transaction_type == "selling":
# validate if sales item or service item
if args.get("order_type") == "Maintenance":
if item.is_service_item != "Yes":
- throw(_("Item") + (" %s: " % item.name) +
+ throw(_("Item") + (" %s: " % item.name) +
_("is not a service item.") +
_("Please select a service item or change the order type to Sales."))
-
+
elif item.is_sales_item != "Yes":
throw(_("Item") + (" %s: " % item.name) + _("is not a sales item"))
@@ -110,15 +110,15 @@
# validate if purchase item or subcontracted item
if item.is_purchase_item != "Yes":
throw(_("Item") + (" %s: " % item.name) + _("is not a purchase item"))
-
+
if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != "Yes":
- throw(_("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."))
-
+
def get_basic_details(args, item_doc):
item = item_doc
-
+
from frappe.defaults import get_user_default_as_list
user_default_warehouse_list = get_user_default_as_list('warehouse')
user_default_warehouse = user_default_warehouse_list[0] \
@@ -136,7 +136,7 @@
"cost_center": item.selling_cost_center \
if args.transaction_type == "selling" else item.buying_cost_center,
"batch_no": None,
- "item_tax_rate": json.dumps(dict(([d.tax_type, d.tax_rate] for d in
+ "item_tax_rate": json.dumps(dict(([d.tax_type, d.tax_rate] for d in
item_doc.get("item_tax")))),
"uom": item.stock_uom,
"min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "",
@@ -150,12 +150,12 @@
"base_amount": 0.0,
"discount_percentage": 0.0
})
-
+
for fieldname in ("item_name", "item_group", "barcode", "brand", "stock_uom"):
out[fieldname] = item.get(fieldname)
-
+
return out
-
+
def get_price_list_rate(args, item_doc, out):
meta = frappe.get_meta(args.doctype)
@@ -163,50 +163,50 @@
validate_price_list(args)
validate_conversion_rate(args, meta)
- price_list_rate = frappe.db.get_value("Item Price",
+ price_list_rate = frappe.db.get_value("Item Price",
{"price_list": args.price_list, "item_code": args.item_code}, "price_list_rate")
-
+
if not price_list_rate: return {}
-
+
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
/ flt(args.conversion_rate)
-
+
if not out.price_list_rate and args.transaction_type == "buying":
from erpnext.stock.doctype.item.item import get_last_purchase_details
- out.update(get_last_purchase_details(item_doc.name,
+ out.update(get_last_purchase_details(item_doc.name,
args.docname, args.conversion_rate))
-
+
def validate_price_list(args):
if args.get("price_list"):
- if not frappe.db.get_value("Price List",
+ if not frappe.db.get_value("Price List",
{"name": args.price_list, args.transaction_type: 1, "enabled": 1}):
throw(_("Price List is either disabled or for not ") + _(args.transaction_type))
else:
throw(_("Price List not selected"))
-
+
def validate_conversion_rate(args, meta):
from erpnext.setup.doctype.currency.currency import validate_conversion_rate
from frappe.model.meta import get_field_precision
-
+
# validate currency conversion rate
- validate_conversion_rate(args.currency, args.conversion_rate,
+ validate_conversion_rate(args.currency, args.conversion_rate,
meta.get_label("conversion_rate"), args.company)
-
- args.conversion_rate = flt(args.conversion_rate,
- get_field_precision(meta.get_field("conversion_rate"),
+
+ args.conversion_rate = flt(args.conversion_rate,
+ get_field_precision(meta.get_field("conversion_rate"),
frappe._dict({"fields": args})))
-
+
# validate price list currency conversion rate
if not args.get("price_list_currency"):
throw(_("Price List Currency not selected"))
else:
- validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate,
+ validate_conversion_rate(args.price_list_currency, args.plc_conversion_rate,
meta.get_label("plc_conversion_rate"), args.company)
-
- args.plc_conversion_rate = flt(args.plc_conversion_rate,
- get_field_precision(meta.get_field("plc_conversion_rate"),
+
+ args.plc_conversion_rate = flt(args.plc_conversion_rate,
+ get_field_precision(meta.get_field("plc_conversion_rate"),
frappe._dict({"fields": args})))
-
+
def get_party_item_code(args, item_doc, out):
if args.transaction_type == "selling":
customer_item_code = item_doc.get("item_customer_details", {"customer_name": args.customer})
@@ -214,35 +214,35 @@
else:
item_supplier = item_doc.get("item_supplier_details", {"supplier": args.supplier})
out.supplier_part_no = item_supplier[0].supplier_part_no if item_supplier else None
-
+
def get_pos_settings_item_details(company, args, pos_settings=None):
res = frappe._dict()
-
+
if not pos_settings:
pos_settings = get_pos_settings(company)
-
+
if pos_settings:
for fieldname in ("income_account", "cost_center", "warehouse", "expense_account"):
if not args.get(fieldname):
res[fieldname] = pos_settings.get(fieldname)
-
+
if res.get("warehouse"):
- res.actual_qty = get_available_qty(args.item_code,
+ res.actual_qty = get_available_qty(args.item_code,
res.warehouse).get("actual_qty")
-
+
return res
def get_pos_settings(company):
- pos_settings = frappe.db.sql("""select * from `tabPOS Setting` where user = %s
+ pos_settings = frappe.db.sql("""select * from `tabPOS Setting` where user = %s
and company = %s""", (frappe.session['user'], company), as_dict=1)
-
+
if not pos_settings:
- pos_settings = frappe.db.sql("""select * from `tabPOS Setting`
+ pos_settings = frappe.db.sql("""select * from `tabPOS Setting`
where ifnull(user,'') = '' and company = %s""", company, as_dict=1)
-
+
return pos_settings and pos_settings[0] or None
-
+
def apply_pricing_rule(out, args):
args_dict = frappe._dict().update(args)
args_dict.update(out)
@@ -260,67 +260,67 @@
out["price_list_rate"] = pricing_rules[0]["price"] * \
flt(args_dict.plc_conversion_rate) / flt(args_dict.conversion_rate)
out["pricing_rule_for_price"] = pricing_rules[-1]["name"]
-
+
def get_pricing_rules(args_dict):
def _get_tree_conditions(doctype, allow_blank=True):
field = frappe.scrub(doctype)
condition = ""
if args_dict.get(field):
lft, rgt = frappe.db.get_value(doctype, args_dict[field], ["lft", "rgt"])
- parent_groups = frappe.db.sql_list("""select name from `tab%s`
+ parent_groups = frappe.db.sql_list("""select name from `tab%s`
where lft<=%s and rgt>=%s""" % (doctype, '%s', '%s'), (lft, rgt))
-
+
if parent_groups:
if allow_blank: parent_groups.append('')
condition = " ifnull("+field+", '') in ('" + "', '".join(parent_groups)+"')"
return condition
-
-
+
+
conditions = ""
for field in ["customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
if args_dict.get(field):
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
else:
conditions += " and ifnull("+field+", '') = ''"
-
+
for doctype in ["Customer Group", "Territory"]:
group_condition = _get_tree_conditions(doctype)
if group_condition:
conditions += " and " + group_condition
-
+
conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')"
-
+
if args_dict.get("transaction_date"):
- conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
+ conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
and ifnull(valid_upto, '2500-12-31')"""
-
- return frappe.db.sql("""select * from `tabPricing Rule`
- where (item_code=%(item_code)s or {item_group_condition} or brand=%(brand)s)
+
+ return frappe.db.sql("""select * from `tabPricing Rule`
+ where (item_code=%(item_code)s or {item_group_condition} or brand=%(brand)s)
and docstatus < 2 and ifnull(disable, 0) = 0 {conditions}
order by priority desc, name desc""".format(
- item_group_condition=_get_tree_conditions("Item Group", False), conditions=conditions),
+ item_group_condition=_get_tree_conditions("Item Group", False), conditions=conditions),
args_dict, as_dict=1)
def filter_pricing_rules(args_dict, pricing_rules, price_or_discount):
# filter for qty
if pricing_rules and args_dict.get("qty"):
- pricing_rules = filter(lambda x: (args_dict.qty>=flt(x.min_qty)
+ pricing_rules = filter(lambda x: (args_dict.qty>=flt(x.min_qty)
and (args_dict.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
-
+
# find pricing rule with highest priority
if pricing_rules:
max_priority = max([cint(p.priority) for p in pricing_rules])
if max_priority:
pricing_rules = filter(lambda x: cint(x.priority)==max_priority, pricing_rules)
-
+
# apply internal priority
- all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
+ all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
"supplier", "supplier_type", "campaign", "for_price_list", "sales_partner"]
-
+
if len(pricing_rules) > 1:
- for field_set in [["item_code", "item_group", "brand"],
+ for field_set in [["item_code", "item_group", "brand"],
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
remaining_fields = list(set(all_fields) - set(field_set))
if if_all_rules_same(pricing_rules, remaining_fields):
@@ -329,7 +329,7 @@
if len(pricing_rules) > 1:
pricing_rules = sorted(pricing_rules, key=lambda x: x[price_or_discount])
-
+
return pricing_rules
def if_all_rules_same(pricing_rules, fields):
@@ -339,7 +339,7 @@
if val != [p[k] for k in fields]:
all_rules_same = False
break
-
+
return all_rules_same
def apply_internal_priority(pricing_rules, field_set, args_dict):
@@ -352,8 +352,8 @@
return filtered_rules or pricing_rules
def get_serial_nos_by_fifo(args, item_doc):
- return "\n".join(frappe.db.sql_list("""select name from `tabSerial No`
- where item_code=%(item_code)s and warehouse=%(warehouse)s and status='Available'
+ return "\n".join(frappe.db.sql_list("""select name from `tabSerial No`
+ where item_code=%(item_code)s and warehouse=%(warehouse)s and status='Available'
order by timestamp(purchase_date, purchase_time) asc limit %(qty)s""", {
"item_code": args.item_code,
"warehouse": args.warehouse,
@@ -367,10 +367,10 @@
@frappe.whitelist()
def get_projected_qty(item_code, warehouse):
- return {"projected_qty": frappe.db.get_value("Bin",
+ return {"projected_qty": frappe.db.get_value("Bin",
{"item_code": item_code, "warehouse": warehouse}, "projected_qty")}
@frappe.whitelist()
def get_available_qty(item_code, warehouse):
- return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
- ["projected_qty", "actual_qty"], as_dict=True) or {}
\ No newline at end of file
+ return frappe.db.get_value("Bin", {"item_code": item_code, "warehouse": warehouse},
+ ["projected_qty", "actual_qty"], as_dict=True) or {}