Merge pull request #975 from akhileshdarjee/master
[item price] item price made as an individual master and removed from price list
This commit is contained in:
commit
6b6e0c004f
@ -167,7 +167,7 @@ erpnext.POS = Class.extend({
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Barcode",
|
"label": "Barcode",
|
||||||
"fieldname": "pos_barcode",
|
"fieldname": "pos_barcode",
|
||||||
"placeholder": "Barcode"
|
"placeholder": "Barcode / Serial No"
|
||||||
},
|
},
|
||||||
parent: this.wrapper.find(".barcode-area")
|
parent: this.wrapper.find(".barcode-area")
|
||||||
});
|
});
|
||||||
@ -228,7 +228,7 @@ erpnext.POS = Class.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
add_to_cart: function(item_code) {
|
add_to_cart: function(item_code, serial_no) {
|
||||||
var me = this;
|
var me = this;
|
||||||
var caught = false;
|
var caught = false;
|
||||||
|
|
||||||
@ -239,39 +239,46 @@ erpnext.POS = Class.extend({
|
|||||||
if (no_of_items != 0) {
|
if (no_of_items != 0) {
|
||||||
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||||
if (d.item_code == item_code)
|
if (d.item_code == item_code) {
|
||||||
caught = true;
|
caught = true;
|
||||||
|
if (serial_no) {
|
||||||
|
d.serial_no += '\n' + serial_no;
|
||||||
|
me.frm.script_manager.trigger("serial_no", d.doctype, d.name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d.qty += 1;
|
||||||
|
me.frm.script_manager.trigger("qty", d.doctype, d.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if duplicate row then append the qty
|
// if item not found then add new item
|
||||||
if (caught) {
|
if (!caught) {
|
||||||
me.update_qty(item_code, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
|
var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
|
||||||
this.frm.cscript.fname);
|
this.frm.cscript.fname);
|
||||||
child.item_code = item_code;
|
child.item_code = item_code;
|
||||||
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
|
|
||||||
|
if (serial_no)
|
||||||
|
child.serial_no = serial_no;
|
||||||
|
|
||||||
|
me.frm.script_manager.trigger("item_code", child.doctype, child.name);
|
||||||
}
|
}
|
||||||
|
me.refresh();
|
||||||
},
|
},
|
||||||
update_qty: function(item_code, qty, textbox_qty) {
|
update_qty: function(item_code, qty) {
|
||||||
var me = this;
|
var me = this;
|
||||||
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||||
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||||
if (d.item_code == item_code) {
|
if (d.item_code == item_code) {
|
||||||
if (textbox_qty) {
|
if (qty == 0)
|
||||||
if (qty == 0 && d.item_code == item_code)
|
wn.model.clear_doc(d.doctype, d.name);
|
||||||
wn.model.clear_doc(d.doctype, d.name);
|
else {
|
||||||
d.qty = qty;
|
d.qty = qty;
|
||||||
|
me.frm.script_manager.trigger("qty", d.doctype, d.name);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
d.qty += 1;
|
|
||||||
|
|
||||||
me.frm.cscript.qty(me.frm.doc, d.doctype, d.name);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
me.frm.dirty();
|
|
||||||
me.refresh();
|
me.refresh();
|
||||||
},
|
},
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
@ -352,7 +359,7 @@ erpnext.POS = Class.extend({
|
|||||||
// append quantity to the respective item after change from input box
|
// append quantity to the respective item after change from input box
|
||||||
$(this.wrapper).find("input.qty").on("change", function() {
|
$(this.wrapper).find("input.qty").on("change", function() {
|
||||||
var item_code = $(this).closest("tr")[0].id;
|
var item_code = $(this).closest("tr")[0].id;
|
||||||
me.update_qty(item_code, $(this).val(), true);
|
me.update_qty(item_code, $(this).val());
|
||||||
});
|
});
|
||||||
|
|
||||||
// on td click toggle the highlighting of row
|
// on td click toggle the highlighting of row
|
||||||
@ -407,11 +414,14 @@ erpnext.POS = Class.extend({
|
|||||||
var me = this;
|
var me = this;
|
||||||
me.barcode_timeout = null;
|
me.barcode_timeout = null;
|
||||||
wn.call({
|
wn.call({
|
||||||
method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode',
|
method: 'accounts.doctype.sales_invoice.pos.get_item_code',
|
||||||
args: {barcode: this.barcode.$input.val()},
|
args: {barcode_serial_no: this.barcode.$input.val()},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if (r.message) {
|
if (r.message) {
|
||||||
me.add_to_cart(r.message[0].name);
|
if (r.message[1] == "serial_no")
|
||||||
|
me.add_to_cart(r.message[0][0].item_code, r.message[0][0].name);
|
||||||
|
else
|
||||||
|
me.add_to_cart(r.message[0][0].name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
msgprint(wn._("Invalid Barcode"));
|
msgprint(wn._("Invalid Barcode"));
|
||||||
@ -443,7 +453,6 @@ erpnext.POS = Class.extend({
|
|||||||
});
|
});
|
||||||
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
|
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
|
||||||
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
||||||
me.frm.dirty();
|
|
||||||
me.refresh();
|
me.refresh();
|
||||||
},
|
},
|
||||||
make_payment: function() {
|
make_payment: function() {
|
||||||
|
@ -20,25 +20,30 @@ def get_items(price_list, sales_or_purchase, item=None, item_group=None):
|
|||||||
condition += " and i.name='%s'" % item
|
condition += " and i.name='%s'" % item
|
||||||
|
|
||||||
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
|
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
|
||||||
pl_items.ref_rate, pl_items.currency
|
item_det.ref_rate, item_det.currency
|
||||||
from `tabItem` i LEFT JOIN
|
from `tabItem` i LEFT JOIN
|
||||||
(select ip.item_code, ip.ref_rate, pl.currency from
|
(select item_code, ref_rate, currency from
|
||||||
`tabItem Price` ip, `tabPrice List` pl
|
`tabItem Price` where price_list=%s) item_det
|
||||||
where ip.parent=%s and ip.parent = pl.name) pl_items
|
|
||||||
ON
|
ON
|
||||||
pl_items.item_code=i.name
|
item_det.item_code=i.name
|
||||||
where
|
where
|
||||||
%s""" % ('%s', condition), (price_list), as_dict=1)
|
%s""" % ('%s', condition), (price_list), as_dict=1)
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_item_from_barcode(barcode):
|
def get_item_code(barcode_serial_no):
|
||||||
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
input_via = "serial_no"
|
||||||
(barcode), as_dict=1)
|
item_code = webnotes.conn.sql("""select name, item_code from `tabSerial No` where
|
||||||
|
name=%s""", (barcode_serial_no), as_dict=1)
|
||||||
|
|
||||||
@webnotes.whitelist()
|
if not item_code:
|
||||||
def get_item_from_serial_no(serial_no):
|
input_via = "barcode"
|
||||||
return webnotes.conn.sql("""select name, item_code from `tabSerial No` where
|
item_code = webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
||||||
name=%s""", (serial_no), as_dict=1)
|
(barcode_serial_no), as_dict=1)
|
||||||
|
|
||||||
|
if item_code:
|
||||||
|
return item_code, input_via
|
||||||
|
else:
|
||||||
|
webnotes.throw("Invalid Barcode / Serial No")
|
||||||
|
|
||||||
@webnotes.whitelist()
|
@webnotes.whitelist()
|
||||||
def get_mode_of_payment():
|
def get_mode_of_payment():
|
||||||
|
@ -67,9 +67,14 @@ wn.module_page["Buying"] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: wn._("Price List"),
|
label: wn._("Price List"),
|
||||||
description: wn._("Mupltiple Item prices."),
|
description: wn._("Multiple Price list."),
|
||||||
doctype:"Price List"
|
doctype:"Price List"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: wn._("Item Price"),
|
||||||
|
description: wn._("Multiple Item prices."),
|
||||||
|
doctype:"Item Price"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype":"Supplier Type",
|
"doctype":"Supplier Type",
|
||||||
"label": wn._("Supplier Type"),
|
"label": wn._("Supplier Type"),
|
||||||
|
@ -89,10 +89,9 @@ 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 ip.ref_rate from `tabItem Price` ip,
|
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||||
`tabPrice List` pl where ip.parent = pl.name and ip.parent=%s and
|
where price_list=%s and item_code=%s and buying_or_selling='Buying'""",
|
||||||
ip.item_code=%s and pl.buying_or_selling='Buying'""",
|
(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:
|
||||||
from utilities.transaction_base import validate_currency
|
from utilities.transaction_base import validate_currency
|
||||||
|
@ -121,7 +121,7 @@ class DocType:
|
|||||||
elif self.doc.rm_cost_as_per == "Price List":
|
elif self.doc.rm_cost_as_per == "Price List":
|
||||||
if not self.doc.buying_price_list:
|
if not self.doc.buying_price_list:
|
||||||
webnotes.throw(_("Please select Price List"))
|
webnotes.throw(_("Please select Price List"))
|
||||||
rate = webnotes.conn.get_value("Item Price", {"parent": self.doc.buying_price_list,
|
rate = webnotes.conn.get_value("Item Price", {"price_list": self.doc.buying_price_list,
|
||||||
"item_code": arg["item_code"]}, "ref_rate") or 0
|
"item_code": arg["item_code"]}, "ref_rate") or 0
|
||||||
elif self.doc.rm_cost_as_per == 'Standard Rate':
|
elif self.doc.rm_cost_as_per == 'Standard Rate':
|
||||||
rate = arg['standard_rate']
|
rate = arg['standard_rate']
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
webnotes.reload_doc("setup", "doctype", "item_price")
|
||||||
|
|
||||||
|
webnotes.conn.sql("""update `tabItem Price` ip, `tabItem` i
|
||||||
|
set ip.item_name=i.item_name, ip.item_description=i.description
|
||||||
|
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""")
|
||||||
|
|
||||||
|
webnotes.conn.sql("""update `tabItem Price`
|
||||||
|
set parent=null, parenttype=null, parentfield=null, idx=null""")
|
@ -222,4 +222,6 @@ patch_list = [
|
|||||||
"patches.october_2013.fix_is_cancelled_in_sle",
|
"patches.october_2013.fix_is_cancelled_in_sle",
|
||||||
"patches.october_2013.repost_ordered_qty",
|
"patches.october_2013.repost_ordered_qty",
|
||||||
"patches.october_2013.repost_planned_qty",
|
"patches.october_2013.repost_planned_qty",
|
||||||
|
"patches.october_2013.p02_update_price_list_and_item_details_in_item_price",
|
||||||
|
"execute:webnotes.delete_doc('Report', 'Item-wise Price List')",
|
||||||
]
|
]
|
@ -114,6 +114,40 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
|||||||
this.frm.refresh();
|
this.frm.refresh();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
serial_no: function(doc, cdt, cdn) {
|
||||||
|
var me = this;
|
||||||
|
var item = wn.model.get_doc(cdt, cdn);
|
||||||
|
|
||||||
|
if (item.serial_no) {
|
||||||
|
if (!item.item_code) {
|
||||||
|
this.frm.script_manager.trigger("item_code", cdt, cdn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var sr_no = [];
|
||||||
|
|
||||||
|
// Replacing all occurences of comma with carriage return
|
||||||
|
var serial_nos = item.serial_no.trim().replace(/,/g, '\n');
|
||||||
|
|
||||||
|
serial_nos = serial_nos.trim().split('\n');
|
||||||
|
|
||||||
|
// Trim each string and push unique string to new list
|
||||||
|
for (var x=0; x<=serial_nos.length - 1; x++) {
|
||||||
|
if (serial_nos[x].trim() != "" && sr_no.indexOf(serial_nos[x].trim()) == -1) {
|
||||||
|
sr_no.push(serial_nos[x].trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new list to the serial no. field in grid with each in new line
|
||||||
|
item.serial_no = "";
|
||||||
|
for (var x=0; x<=sr_no.length - 1; x++)
|
||||||
|
item.serial_no += sr_no[x] + '\n';
|
||||||
|
|
||||||
|
refresh_field("serial_no", item.name, item.parentfield);
|
||||||
|
wn.model.set_value(item.doctype, item.name, "qty", sr_no.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
validate: function() {
|
validate: function() {
|
||||||
this.calculate_taxes_and_totals();
|
this.calculate_taxes_and_totals();
|
||||||
|
@ -160,7 +160,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
item_code: function(doc, cdt, cdn) {
|
item_code: function(doc, cdt, cdn) {
|
||||||
var me = this;
|
var me = this;
|
||||||
var item = wn.model.get_doc(cdt, cdn);
|
var item = wn.model.get_doc(cdt, cdn);
|
||||||
if(item.item_code || item.barcode) {
|
if(item.item_code || item.barcode || item.serial_no) {
|
||||||
if(!this.validate_company_and_party("customer")) {
|
if(!this.validate_company_and_party("customer")) {
|
||||||
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
|
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
|
||||||
} else {
|
} else {
|
||||||
@ -171,6 +171,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
args: {
|
args: {
|
||||||
item_code: item.item_code,
|
item_code: item.item_code,
|
||||||
barcode: item.barcode,
|
barcode: item.barcode,
|
||||||
|
serial_no: item.serial_no,
|
||||||
warehouse: item.warehouse,
|
warehouse: item.warehouse,
|
||||||
doctype: me.frm.doc.doctype,
|
doctype: me.frm.doc.doctype,
|
||||||
parentfield: item.parentfield,
|
parentfield: item.parentfield,
|
||||||
|
@ -83,9 +83,14 @@ wn.module_page["Selling"] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: wn._("Price List"),
|
label: wn._("Price List"),
|
||||||
description: wn._("Mupltiple Item prices."),
|
description: wn._("Multiple Price list."),
|
||||||
doctype:"Price List"
|
doctype:"Price List"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: wn._("Item Price"),
|
||||||
|
description: wn._("Multiple Item prices."),
|
||||||
|
doctype:"Item Price"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: wn._("Sales BOM"),
|
label: wn._("Sales BOM"),
|
||||||
description: wn._("Bundle items at time of sale."),
|
description: wn._("Bundle items at time of sale."),
|
||||||
|
@ -40,7 +40,9 @@ def get_item_details(args):
|
|||||||
args = webnotes._dict(args)
|
args = webnotes._dict(args)
|
||||||
|
|
||||||
if args.barcode:
|
if args.barcode:
|
||||||
args.item_code = _get_item_code(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_bean = webnotes.bean("Item", args.item_code)
|
item_bean = webnotes.bean("Item", args.item_code)
|
||||||
|
|
||||||
@ -88,15 +90,17 @@ def _get_serial_nos_by_fifo(args, item_bean):
|
|||||||
"qty": cint(args.qty)
|
"qty": cint(args.qty)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
def _get_item_code(barcode):
|
def _get_item_code(barcode=None, serial_no=None):
|
||||||
item_code = webnotes.conn.sql_list("""select name from `tabItem` where barcode=%s""", barcode)
|
if barcode:
|
||||||
|
input_type = "Barcode"
|
||||||
|
item_code = webnotes.conn.sql_list("""select name from `tabItem` where barcode=%s""", barcode)
|
||||||
|
elif serial_no:
|
||||||
|
input_type = "Serial No"
|
||||||
|
item_code = webnotes.conn.sql_list("""select item_code from `tabSerial No`
|
||||||
|
where name=%s""", serial_no)
|
||||||
|
|
||||||
if not item_code:
|
if not item_code:
|
||||||
msgprint(_("No Item found with Barcode") + ": %s" % barcode, raise_exception=True)
|
msgprint(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no), raise_exception=True)
|
||||||
|
|
||||||
elif len(item_code) > 1:
|
|
||||||
msgprint(_("Items") + " %s " % comma_and(item_code) +
|
|
||||||
_("have the same Barcode") + " %s" % barcode, raise_exception=True)
|
|
||||||
|
|
||||||
return item_code[0]
|
return item_code[0]
|
||||||
|
|
||||||
@ -142,9 +146,8 @@ 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 ip.ref_rate from `tabItem Price` ip,
|
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||||
`tabPrice List` pl where ip.parent = pl.name and ip.parent=%s and
|
where price_list=%s and item_code=%s and buying_or_selling='Selling'""",
|
||||||
ip.item_code=%s and pl.buying_or_selling='Selling'""",
|
|
||||||
(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:
|
||||||
|
@ -27,9 +27,8 @@ def get_product_info(item_code):
|
|||||||
else:
|
else:
|
||||||
in_stock = -1
|
in_stock = -1
|
||||||
|
|
||||||
price = price_list and webnotes.conn.sql("""select ip.ref_rate, pl.currency from
|
price = price_list and webnotes.conn.sql("""select ref_rate, currency from
|
||||||
`tabItem Price` ip, `tabPrice List` pl where ip.parent = pl.name and
|
`tabItem Price` where item_code=%s and price_list=%s""",
|
||||||
ip.item_code=%s and ip.parent=%s""",
|
|
||||||
(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
|
||||||
|
16
setup/doctype/item_price/item_price.js
Normal file
16
setup/doctype/item_price/item_price.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
|
// 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", "currency", "currency");
|
||||||
|
|
||||||
|
// Fetch item details
|
||||||
|
cur_frm.add_fetch("item_code", "item_name", "item_name");
|
||||||
|
cur_frm.add_fetch("item_code", "description", "item_description");
|
||||||
|
}
|
||||||
|
});
|
@ -5,7 +5,36 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
|
from webnotes import _
|
||||||
|
|
||||||
|
class ItemPriceDuplicateItem(Exception): pass
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self, d, dl):
|
def __init__(self, d, dl):
|
||||||
self.doc, self.doclist = d, dl
|
self.doc, self.doclist = d, dl
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
self.update_price_list_details()
|
||||||
|
self.update_item_details()
|
||||||
|
self.check_duplicate_item()
|
||||||
|
|
||||||
|
def update_price_list_details(self):
|
||||||
|
self.doc.buying_or_selling = webnotes.conn.get_value("Price List", self.doc.price_list,
|
||||||
|
"buying_or_selling")
|
||||||
|
|
||||||
|
self.doc.currency = webnotes.conn.get_value("Price List", self.doc.price_list,
|
||||||
|
"currency")
|
||||||
|
|
||||||
|
def update_item_details(self):
|
||||||
|
self.doc.item_name = webnotes.conn.get_value("Item", self.doc.item_code, "item_name")
|
||||||
|
|
||||||
|
self.doc.item_description = webnotes.conn.get_value("Item", self.doc.item_code,
|
||||||
|
"description")
|
||||||
|
|
||||||
|
def check_duplicate_item(self):
|
||||||
|
if webnotes.conn.sql("""select name from `tabItem Price`
|
||||||
|
where item_code=%s and price_list=%s and name!=%s""",
|
||||||
|
(self.doc.item_code, self.doc.price_list, self.doc.name)):
|
||||||
|
webnotes.throw(_("Duplicate Item: ") + self.doc.item_code +
|
||||||
|
_(" already available in Price List: ") + self.doc.price_list,
|
||||||
|
ItemPriceDuplicateItem)
|
@ -2,52 +2,126 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-05-02 16:29:48",
|
"creation": "2013-05-02 16:29:48",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-09-13 11:50:02",
|
"modified": "2013-10-18 13:45:46",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"autoname": "RFD/.#####",
|
"autoname": "RFD/.#####",
|
||||||
|
"description": "Multiple Item prices.",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
"document_type": "Master",
|
||||||
|
"icon": "icon-flag",
|
||||||
"in_create": 0,
|
"in_create": 0,
|
||||||
"istable": 1,
|
"istable": 0,
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"in_filter": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"parent": "Item Price",
|
"parent": "Item Price",
|
||||||
"parentfield": "fields",
|
"parentfield": "fields",
|
||||||
"parenttype": "DocType",
|
"parenttype": "DocType",
|
||||||
|
"permlevel": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"name": "__common__",
|
||||||
|
"parent": "Item Price",
|
||||||
|
"parentfield": "permissions",
|
||||||
|
"parenttype": "DocType",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"reqd": 1
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"name": "Item Price"
|
"name": "Item Price"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "price_list",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_filter": 1,
|
||||||
|
"label": "Price List",
|
||||||
|
"options": "Price List",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_filter": 1,
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"oldfieldname": "price_list_name",
|
"oldfieldname": "price_list_name",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
|
"reqd": 1,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "ref_rate",
|
"fieldname": "ref_rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
|
"in_filter": 1,
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Rate",
|
"label": "Rate",
|
||||||
"oldfieldname": "ref_rate",
|
"oldfieldname": "ref_rate",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
|
"reqd": 1,
|
||||||
"search_index": 0
|
"search_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"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",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Item Name",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "item_description",
|
||||||
|
"fieldtype": "Text",
|
||||||
|
"label": "Item Description",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "currency",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Currency",
|
||||||
|
"options": "Currency",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Sales Master Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"role": "Purchase Master Manager"
|
||||||
}
|
}
|
||||||
]
|
]
|
23
setup/doctype/item_price/test_item_price.py
Normal file
23
setup/doctype/item_price/test_item_price.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
import webnotes
|
||||||
|
from setup.doctype.item_price.item_price import ItemPriceDuplicateItem
|
||||||
|
|
||||||
|
class TestItem(unittest.TestCase):
|
||||||
|
def test_duplicate_item(self):
|
||||||
|
item_price = webnotes.bean(copy=test_records[0])
|
||||||
|
self.assertRaises(ItemPriceDuplicateItem, item_price.insert)
|
||||||
|
|
||||||
|
test_records = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"doctype": "Item Price",
|
||||||
|
"price_list": "_Test Price List",
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"ref_rate": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
@ -5,253 +5,13 @@ $.extend(cur_frm.cscript, {
|
|||||||
onload: function() {
|
onload: function() {
|
||||||
erpnext.add_for_territory();
|
erpnext.add_for_territory();
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
refresh: function() {
|
||||||
cur_frm.cscript.show_item_prices();
|
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
||||||
}
|
wn.route_options = {
|
||||||
|
"price_list": cur_frm.doc.name
|
||||||
cur_frm.cscript.show_item_prices = function() {
|
};
|
||||||
var item_price = wn.model.get("Item Price", {parent: cur_frm.doc.name});
|
wn.set_route("Report", "Item Price");
|
||||||
|
}, "icon-money");
|
||||||
$(cur_frm.fields_dict.item_prices_html.wrapper).empty();
|
|
||||||
|
|
||||||
new wn.ui.form.TableGrid({
|
|
||||||
parent: cur_frm.fields_dict.item_prices_html.wrapper,
|
|
||||||
frm: cur_frm,
|
|
||||||
table_field: wn.meta.get_docfield("Price List", "item_prices", cur_frm.doc.name)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
wn.ui.form.TableGrid = Class.extend({
|
|
||||||
init: function(opts) {
|
|
||||||
$.extend(this, opts);
|
|
||||||
this.fields = wn.meta.get_docfields("Item Price", cur_frm.doc.name);
|
|
||||||
this.make_table();
|
|
||||||
},
|
|
||||||
make_table: function() {
|
|
||||||
var me = this;
|
|
||||||
// Creating table & assigning attributes
|
|
||||||
var grid_table = document.createElement("table");
|
|
||||||
grid_table.className = "table table-hover table-bordered table-grid";
|
|
||||||
|
|
||||||
// Appending header & rows to table
|
|
||||||
grid_table.appendChild(this.make_table_headers());
|
|
||||||
grid_table.appendChild(this.make_table_rows());
|
|
||||||
|
|
||||||
// Creating button to add new row
|
|
||||||
var btn_div = document.createElement("div");
|
|
||||||
var new_row_btn = document.createElement("button");
|
|
||||||
new_row_btn.className = "btn btn-success table-new-row";
|
|
||||||
new_row_btn.title = "Add new row";
|
|
||||||
|
|
||||||
var btn_icon = document.createElement("i");
|
|
||||||
btn_icon.className = "icon-plus";
|
|
||||||
new_row_btn.appendChild(btn_icon);
|
|
||||||
new_row_btn.innerHTML += " Add new row";
|
|
||||||
btn_div.appendChild(new_row_btn);
|
|
||||||
|
|
||||||
// Appending table & button to parent
|
|
||||||
var $grid_table = $(grid_table).appendTo($(this.parent));
|
|
||||||
var $btn_div = $(btn_div).appendTo($(this.parent));
|
|
||||||
|
|
||||||
$btn_div.on("click", ".table-new-row", function() {
|
|
||||||
me.make_dialog();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$grid_table.on("click", ".table-row", function() {
|
|
||||||
me.make_dialog(this);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
make_table_headers: function() {
|
|
||||||
var me = this;
|
|
||||||
var header = document.createElement("thead");
|
|
||||||
|
|
||||||
// Creating header row
|
|
||||||
var row = document.createElement("tr");
|
|
||||||
row.className = "active";
|
|
||||||
|
|
||||||
// Creating head first cell
|
|
||||||
var th = document.createElement("th");
|
|
||||||
th.width = "8%";
|
|
||||||
th.className = "text-center";
|
|
||||||
th.innerHTML = "#";
|
|
||||||
row.appendChild(th);
|
|
||||||
|
|
||||||
// Make other headers with label as heading
|
|
||||||
for(var i=0, l=this.fields.length; i<l; i++) {
|
|
||||||
var df = this.fields[i];
|
|
||||||
|
|
||||||
if(!!!df.hidden && df.in_list_view === 1) {
|
|
||||||
var th = document.createElement("th");
|
|
||||||
|
|
||||||
// If currency then move header to right
|
|
||||||
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) th.className = "text-right";
|
|
||||||
|
|
||||||
th.innerHTML = wn._(df.label);
|
|
||||||
row.appendChild(th);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header.appendChild(row);
|
|
||||||
|
|
||||||
return header;
|
|
||||||
},
|
|
||||||
make_table_rows: function() {
|
|
||||||
var me = this;
|
|
||||||
|
|
||||||
// Creating table body
|
|
||||||
var table_body = document.createElement("tbody");
|
|
||||||
|
|
||||||
var item_prices = wn.model.get_children(this.table_field.options, this.frm.doc.name,
|
|
||||||
this.table_field.fieldname, this.frm.doctype);
|
|
||||||
|
|
||||||
for(var i=0, l=item_prices.length; i<l; i++) {
|
|
||||||
var d = item_prices[i];
|
|
||||||
|
|
||||||
// Creating table row
|
|
||||||
var tr = this.add_new_row(d);
|
|
||||||
|
|
||||||
// append row to table body
|
|
||||||
table_body.appendChild(tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.table_body = table_body;
|
|
||||||
|
|
||||||
return table_body;
|
|
||||||
},
|
|
||||||
make_dialog: function(row) {
|
|
||||||
var me = this;
|
|
||||||
|
|
||||||
this.dialog = new wn.ui.Dialog({
|
|
||||||
title: this.table_field.options,
|
|
||||||
fields: this.fields
|
|
||||||
});
|
|
||||||
|
|
||||||
if (row)
|
|
||||||
this.dialog.set_values(this.make_dialog_values(row));
|
|
||||||
|
|
||||||
$a(this.dialog.body, 'div', '', '', this.make_dialog_buttons(row));
|
|
||||||
this.dialog.show();
|
|
||||||
|
|
||||||
this.dialog.$wrapper.find('button.update').on('click', function() {
|
|
||||||
me.update_row(row);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.dialog.$wrapper.find('button.delete').on('click', function() {
|
|
||||||
me.delete_row(row);
|
|
||||||
});
|
|
||||||
return row;
|
|
||||||
},
|
|
||||||
make_dialog_values: function(row) {
|
|
||||||
var me = this;
|
|
||||||
var dialog_values = {};
|
|
||||||
|
|
||||||
$.each(this.fields, function(i, item) {
|
|
||||||
dialog_values[item.fieldname] = $(row).find('td[data-fieldname="'+ item.fieldname +'"]').attr('data-fieldvalue');
|
|
||||||
});
|
|
||||||
|
|
||||||
return dialog_values;
|
|
||||||
},
|
|
||||||
make_dialog_buttons: function(row) {
|
|
||||||
var me = this;
|
|
||||||
var buttons = '<button class="btn btn-primary update">Update</button>';
|
|
||||||
|
|
||||||
// if user can delete then only add the delete button in dialog
|
|
||||||
if (wn.model.can_delete(me.frm.doc.doctype) && row)
|
|
||||||
buttons += ' <button class="btn btn-default delete">Delete</button>';
|
|
||||||
|
|
||||||
return buttons;
|
|
||||||
},
|
|
||||||
update_row: function(row) {
|
|
||||||
var me = this;
|
|
||||||
|
|
||||||
if (!row) {
|
|
||||||
var d = wn.model.add_child(this.frm.doc, this.table_field.options,
|
|
||||||
this.table_field.fieldname);
|
|
||||||
refresh_field(this.table_field.fieldname);
|
|
||||||
this.update_item_price(d.name);
|
|
||||||
var tr = this.add_new_row(d);
|
|
||||||
this.table_body.appendChild(tr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.update_item_price(null, row);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dialog.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
update_item_price: function(docname, row) {
|
|
||||||
var me = this;
|
|
||||||
if(!docname && row) docname = $(row).attr("data-docname");
|
|
||||||
$.each(me.fields, function(i, df) {
|
|
||||||
var val = me.dialog.get_values()[df.fieldname];
|
|
||||||
|
|
||||||
if(["Currency", "Float"].indexOf(df.fieldtype)!==-1) {
|
|
||||||
val = flt(val);
|
|
||||||
} else if(["Int", "Check"].indexOf(df.fieldtype)!==-1) {
|
|
||||||
val = cint(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
wn.model.set_value(me.table_field.options, docname,
|
|
||||||
df.fieldname, val);
|
|
||||||
|
|
||||||
if(row) {
|
|
||||||
var $td = $(row).find('td[data-fieldname="'+ df.fieldname +'"]');
|
|
||||||
$td.attr('data-fieldvalue', val);
|
|
||||||
// If field type is currency the update with format currency
|
|
||||||
$td.html(wn.format(val, df));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
delete_row: function(row) {
|
|
||||||
var me = this;
|
|
||||||
var docname = $(row).find('td:last').attr('data-docname');
|
|
||||||
wn.model.clear_doc(me.table_field.options, docname);
|
|
||||||
$(row).remove();
|
|
||||||
|
|
||||||
// Re-assign idx
|
|
||||||
$.each($(this.parent).find("tbody tr"), function(idx, data) {
|
|
||||||
var $td = $(data).find('td:first');
|
|
||||||
$td.html(idx + 1);
|
|
||||||
});
|
|
||||||
this.dialog.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
add_new_row: function(d) {
|
|
||||||
var tr = document.createElement("tr");
|
|
||||||
tr.className = "table-row";
|
|
||||||
tr.setAttribute("data-docname", d.name);
|
|
||||||
|
|
||||||
// Creating table data & appending to row
|
|
||||||
var td = document.createElement("td");
|
|
||||||
td.className = "text-center";
|
|
||||||
td.innerHTML = d.idx;
|
|
||||||
tr.appendChild(td);
|
|
||||||
|
|
||||||
for(var f=0, lf=this.fields.length; f<lf; f++) {
|
|
||||||
var df = this.fields[f];
|
|
||||||
if(!!!df.hidden && df.in_list_view===1) {
|
|
||||||
var td = document.createElement("td");
|
|
||||||
td.setAttribute("data-fieldname", df.fieldname);
|
|
||||||
td.setAttribute("data-fieldvalue", d[df.fieldname]);
|
|
||||||
td.setAttribute("data-docname", d.name);
|
|
||||||
|
|
||||||
// If currency then move header to right
|
|
||||||
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) {
|
|
||||||
td.className = "text-right";
|
|
||||||
}
|
|
||||||
|
|
||||||
// format and set display
|
|
||||||
td.innerHTML = wn.format(d[df.fieldname], df);
|
|
||||||
|
|
||||||
// append column to tabel row
|
|
||||||
tr.appendChild(td);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tr;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -8,8 +8,6 @@ from webnotes.utils import comma_or, cint
|
|||||||
from webnotes.model.controller import DocListController
|
from webnotes.model.controller import DocListController
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
|
||||||
class PriceListDuplicateItem(Exception): pass
|
|
||||||
|
|
||||||
class DocType(DocListController):
|
class DocType(DocListController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.doc.buying_or_selling not in ["Buying", "Selling"]:
|
if self.doc.buying_or_selling not in ["Buying", "Selling"]:
|
||||||
@ -27,23 +25,13 @@ class DocType(DocListController):
|
|||||||
else:
|
else:
|
||||||
# at least one territory
|
# at least one territory
|
||||||
self.validate_table_has_rows("valid_for_territories")
|
self.validate_table_has_rows("valid_for_territories")
|
||||||
|
|
||||||
# check for duplicate items
|
|
||||||
self.check_duplicate_items()
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.set_default_if_missing()
|
self.set_default_if_missing()
|
||||||
|
self.update_item_price()
|
||||||
cart_settings = webnotes.get_obj("Shopping Cart Settings")
|
cart_settings = webnotes.get_obj("Shopping Cart Settings")
|
||||||
if cint(cart_settings.doc.enabled):
|
if cint(cart_settings.doc.enabled):
|
||||||
cart_settings.validate_price_lists()
|
cart_settings.validate_price_lists()
|
||||||
|
|
||||||
def check_duplicate_items(self):
|
|
||||||
item_codes = []
|
|
||||||
for d in self.doclist.get({"parentfield": "item_prices"}):
|
|
||||||
if d.item_code not in item_codes:
|
|
||||||
item_codes.append(d.item_code)
|
|
||||||
else:
|
|
||||||
msgprint(_("Duplicate Item ") + ": " + d.item_code, raise_exception=PriceListDuplicateItem)
|
|
||||||
|
|
||||||
def set_default_if_missing(self):
|
def set_default_if_missing(self):
|
||||||
if self.doc.buying_or_selling=="Selling":
|
if self.doc.buying_or_selling=="Selling":
|
||||||
@ -54,3 +42,7 @@ class DocType(DocListController):
|
|||||||
if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"):
|
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)
|
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 where price_list=%s""",
|
||||||
|
(self.doc.currency, self.doc.buying_or_selling, self.doc.name))
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-25 11:35:09",
|
"creation": "2013-01-25 11:35:09",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-10-02 11:36:09",
|
"modified": "2013-10-18 13:33:07",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -84,27 +84,6 @@
|
|||||||
"options": "For Territory",
|
"options": "For Territory",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"description": "To change row values, click on the respective row",
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "item_prices_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"label": "Item Prices"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "item_prices_html",
|
|
||||||
"fieldtype": "HTML"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "item_prices",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Item Prices",
|
|
||||||
"options": "Item Price"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
|
@ -2,16 +2,7 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import unittest
|
|
||||||
import webnotes
|
import webnotes
|
||||||
from setup.doctype.price_list.price_list import PriceListDuplicateItem
|
|
||||||
|
|
||||||
class TestItem(unittest.TestCase):
|
|
||||||
def test_duplicate_item(self):
|
|
||||||
price_list = webnotes.bean(copy=test_records[0])
|
|
||||||
item_price = price_list.doclist.get({"doctype": "Item Price"})[0]
|
|
||||||
price_list.doclist.append(webnotes.doc(item_price.fields.copy()))
|
|
||||||
self.assertRaises(PriceListDuplicateItem, price_list.insert)
|
|
||||||
|
|
||||||
# test_ignore = ["Item"]
|
# test_ignore = ["Item"]
|
||||||
|
|
||||||
@ -28,12 +19,6 @@ test_records = [
|
|||||||
"parentfield": "valid_for_territories",
|
"parentfield": "valid_for_territories",
|
||||||
"territory": "All Territories"
|
"territory": "All Territories"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "Item Price",
|
|
||||||
"parentfield": "item_prices",
|
|
||||||
"item_code": "_Test Item",
|
|
||||||
"ref_rate": 100
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"creation": "2013-09-25 10:29:04",
|
|
||||||
"docstatus": 0,
|
|
||||||
"modified": "2013-09-25 10:29:04",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"owner": "Administrator"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Report",
|
|
||||||
"is_standard": "Yes",
|
|
||||||
"json": "{\"filters\":[[\"Item Price\",\"item_code\",\"like\",\"%\"],[\"Price List\",\"price_list_name\",\"like\",\"%\"]],\"columns\":[[\"item_code\",\"Item Price\"],[\"price_list_name\",\"Price List\"],[\"currency\",\"Price List\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Price List\"],[\"name\",\"Price List\"]],\"sort_by\":\"Price List.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
|
||||||
"name": "__common__",
|
|
||||||
"ref_doctype": "Price List",
|
|
||||||
"report_name": "Item-Wise Price List",
|
|
||||||
"report_type": "Report Builder"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Report",
|
|
||||||
"name": "Item-Wise Price List"
|
|
||||||
}
|
|
||||||
]
|
|
@ -2,14 +2,14 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-09-25 10:21:15",
|
"creation": "2013-09-25 10:21:15",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-09-25 10:24:57",
|
"modified": "2013-10-18 15:08:36",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"json": "{\"filters\":[[\"Item Price\",\"item_code\",\"like\",\"%\"],[\"Price List\",\"price_list_name\",\"like\",\"%\"]],\"columns\":[[\"item_code\",\"Item Price\"],[\"price_list_name\",\"Price List\"],[\"currency\",\"Price List\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Price List\"],[\"name\",\"Price List\"]],\"sort_by\":\"Price List.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
"json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"ref_doctype": "Price List",
|
"ref_doctype": "Price List",
|
||||||
"report_name": "Item-wise Price List Rate",
|
"report_name": "Item-wise Price List Rate",
|
||||||
|
@ -6,6 +6,7 @@ cur_frm.cscript.refresh = function(doc) {
|
|||||||
// read only if any stock ledger entry exists
|
// read only if any stock ledger entry exists
|
||||||
|
|
||||||
cur_frm.cscript.make_dashboard()
|
cur_frm.cscript.make_dashboard()
|
||||||
|
cur_frm.cscript.edit_prices_button();
|
||||||
|
|
||||||
cur_frm.toggle_display("naming_series", sys_defaults.item_naming_by=="Naming Series"
|
cur_frm.toggle_display("naming_series", sys_defaults.item_naming_by=="Naming Series"
|
||||||
&& doc.__islocal)
|
&& doc.__islocal)
|
||||||
@ -28,6 +29,15 @@ cur_frm.cscript.make_dashboard = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur_frm.cscript.edit_prices_button = function() {
|
||||||
|
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
||||||
|
wn.route_options = {
|
||||||
|
"item_code": cur_frm.doc.name
|
||||||
|
};
|
||||||
|
wn.set_route("Report", "Item Price");
|
||||||
|
}, "icon-money");
|
||||||
|
}
|
||||||
|
|
||||||
cur_frm.cscript.item_code = function(doc) {
|
cur_frm.cscript.item_code = function(doc) {
|
||||||
if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code);
|
if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code);
|
||||||
if(!doc.description) cur_frm.set_value("description", doc.item_code);
|
if(!doc.description) cur_frm.set_value("description", doc.item_code);
|
||||||
|
@ -202,8 +202,8 @@ wn.module_page["Stock"] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label":wn._("Item-wise Price List Rate"),
|
"label":wn._("Item-wise Price List Rate"),
|
||||||
route: "Report/Price List/Item-Wise Price List",
|
route: "Report/Item Price/Item-wise Price List Rate",
|
||||||
doctype: "Price List"
|
doctype: "Item Price"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label":wn._("Purchase In Transit"),
|
"label":wn._("Purchase In Transit"),
|
||||||
|
@ -57,10 +57,9 @@ def get_price_list():
|
|||||||
|
|
||||||
rate = {}
|
rate = {}
|
||||||
|
|
||||||
price_list = webnotes.conn.sql("""select ip.item_code, pl.buying_or_selling,
|
price_list = webnotes.conn.sql("""select item_code, buying_or_selling,
|
||||||
concat(pl.name, " - ", pl.currency, " ", ip.ref_rate) as price
|
concat(price_list, " - ", currency, " ", ref_rate) as price
|
||||||
from `tabItem Price` ip, `tabPrice List` pl where
|
from `tabItem Price`""", as_dict=1)
|
||||||
ip.parent = pl.name and pl.docstatus<2""", as_dict=1)
|
|
||||||
|
|
||||||
for j in price_list:
|
for j in price_list:
|
||||||
if j.price:
|
if j.price:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user