mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-04 04:39:11 +00:00
Merge branch 'master' of github.com:webnotes/erpnext into slow
Conflicts: stock/doctype/purchase_receipt/purchase_receipt.js
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-03-01 08:21:54",
|
||||
"creation": "2013-03-05 14:50:38",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-01 08:22:16",
|
||||
"modified": "2013-05-01 15:49:47",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "harshada@webnotestech.com"
|
||||
},
|
||||
@@ -98,24 +98,6 @@
|
||||
"oldfieldname": "finished_date",
|
||||
"oldfieldtype": "Date"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "trash_reason",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Trash Reason",
|
||||
"oldfieldname": "trash_reason",
|
||||
"oldfieldtype": "Small Text",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm"
|
||||
}
|
||||
|
||||
@@ -77,10 +77,6 @@ class DocType:
|
||||
|
||||
self.doc.save()
|
||||
|
||||
if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
|
||||
and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
|
||||
self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
|
||||
|
||||
def get_first_sle(self):
|
||||
sle = sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
@@ -90,82 +86,4 @@ class DocType:
|
||||
order by timestamp(posting_date, posting_time) asc, name asc
|
||||
limit 1
|
||||
""", (self.doc.item_code, self.doc.warehouse), as_dict=1)
|
||||
return sle and sle[0] or None
|
||||
|
||||
def reorder_item(self,doc_type,doc_name):
|
||||
""" Reorder item if stock reaches reorder level"""
|
||||
if not hasattr(webnotes, "auto_indent"):
|
||||
webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent')
|
||||
|
||||
if webnotes.auto_indent:
|
||||
#check if re-order is required
|
||||
item_reorder = webnotes.conn.get("Item Reorder",
|
||||
{"parent": self.doc.item_code, "warehouse": self.doc.warehouse})
|
||||
if item_reorder:
|
||||
reorder_level = item_reorder.warehouse_reorder_level
|
||||
reorder_qty = item_reorder.warehouse_reorder_qty
|
||||
material_request_type = item_reorder.material_request_type or "Purchase"
|
||||
else:
|
||||
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
|
||||
["re_order_level", "re_order_qty"])
|
||||
material_request_type = "Purchase"
|
||||
|
||||
if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level):
|
||||
self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty,
|
||||
material_request_type)
|
||||
|
||||
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty,
|
||||
material_request_type="Purchase"):
|
||||
""" Create indent on reaching reorder level """
|
||||
defaults = webnotes.defaults.get_defaults()
|
||||
item = webnotes.doc("Item", self.doc.item_code)
|
||||
|
||||
mr = webnotes.bean([{
|
||||
"doctype": "Material Request",
|
||||
"company": defaults.company,
|
||||
"fiscal_year": defaults.fiscal_year,
|
||||
"transaction_date": nowdate(),
|
||||
"material_request_type": material_request_type,
|
||||
"remark": _("This is an auto generated Material Request.") + \
|
||||
_("It was raised because the (actual + ordered + indented - reserved) quantity reaches re-order level when the following record was created") + \
|
||||
": " + _(doc_type) + " " + doc_name
|
||||
}, {
|
||||
"doctype": "Material Request Item",
|
||||
"parenttype": "Material Request",
|
||||
"parentfield": "indent_details",
|
||||
"item_code": self.doc.item_code,
|
||||
"schedule_date": add_days(nowdate(),cint(item.lead_time_days)),
|
||||
"uom": self.doc.stock_uom,
|
||||
"warehouse": self.doc.warehouse,
|
||||
"item_name": item.item_name,
|
||||
"description": item.description,
|
||||
"item_group": item.item_group,
|
||||
"qty": reorder_qty,
|
||||
"brand": item.brand,
|
||||
}])
|
||||
mr.insert()
|
||||
mr.submit()
|
||||
|
||||
msgprint("""Item: %s is to be re-ordered. Material Request %s raised.
|
||||
It was generated from %s: %s""" %
|
||||
(self.doc.item_code, mr.doc.name, doc_type, doc_name))
|
||||
|
||||
if(item.email_notify):
|
||||
self.send_email_notification(doc_type, doc_name, mr)
|
||||
|
||||
def send_email_notification(self, doc_type, doc_name, bean):
|
||||
""" Notify user about auto creation of indent"""
|
||||
|
||||
from webnotes.utils.email_lib import sendmail
|
||||
email_list=[d[0] for d in sql("""select distinct r.parent from tabUserRole r, tabProfile p
|
||||
where p.name = r.parent and p.enabled = 1 and p.docstatus < 2
|
||||
and r.role in ('Purchase Manager','Material Manager')
|
||||
and p.name not in ('Administrator', 'All', 'Guest')""")]
|
||||
|
||||
msg="""A new Material Request has been raised for Item: %s and Warehouse: %s \
|
||||
on %s due to %s: %s. See %s: %s """ % (self.doc.item_code, self.doc.warehouse,
|
||||
formatdate(), doc_type, doc_name, bean.doc.doctype,
|
||||
get_url_to_form(bean.doc.doctype, bean.doc.name))
|
||||
|
||||
sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg)
|
||||
|
||||
return sle and sle[0] or None
|
||||
@@ -323,6 +323,17 @@ if (sys_defaults.auto_inventory_accounting) {
|
||||
}
|
||||
|
||||
// cost center
|
||||
cur_frm.cscript.cost_center = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.cost_center) {
|
||||
var cl = getchildren('Delivery Note Item', doc.name, cur_frm.cscript.fname, doc.doctype);
|
||||
for(var i = 0; i < cl.length; i++){
|
||||
if(!cl[i].cost_center) cl[i].cost_center = d.cost_center;
|
||||
}
|
||||
}
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.delivery_note_details.grid.get_field("cost_center").get_query = function(doc) {
|
||||
return {
|
||||
query: "accounts.utils.get_cost_center_list",
|
||||
|
||||
@@ -419,4 +419,4 @@ class DocType(SellingController):
|
||||
|
||||
if gl_entries:
|
||||
from accounts.general_ledger import make_gl_entries
|
||||
make_gl_entries(gl_entries)
|
||||
make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2))
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-29 17:54:12",
|
||||
"creation": "2013-04-02 10:50:50",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-02 19:18:38",
|
||||
"modified_by": "Administrator",
|
||||
@@ -32,9 +32,7 @@
|
||||
"parent": "Delivery Note",
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1
|
||||
"read": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
@@ -1123,20 +1121,25 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Material User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Accounts User",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Material User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
@@ -1145,31 +1148,73 @@
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Sales User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"match": "customer_name",
|
||||
"role": "Customer"
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Material Manager",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Material Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Material User",
|
||||
"match": "",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Sales User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"match": "customer_name",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Customer"
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-04-01 10:49:21",
|
||||
"creation": "2013-04-22 13:15:44",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-04-17 17:20:58",
|
||||
"modified": "2013-05-22 12:05:32",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -340,6 +340,7 @@
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Document Type",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
@@ -371,6 +372,7 @@
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Against Document Date",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_date",
|
||||
"oldfieldtype": "Date",
|
||||
"print_hide": 1,
|
||||
@@ -383,6 +385,7 @@
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Against Document Detail No",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_detail_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
|
||||
@@ -14,11 +14,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.add_fetch("price_list_name", "currency", "ref_currency")
|
||||
|
||||
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.toggle_enable("item_code", doc.__islocal);
|
||||
cur_frm.toggle_display("naming_series", sys_defaults.item_naming_by=="Naming Series"
|
||||
&& doc.__islocal)
|
||||
cur_frm.toggle_display("item_code", sys_defaults.item_naming_by!="Naming Series"
|
||||
&& doc.__islocal)
|
||||
|
||||
|
||||
if ((!doc.__islocal) && (doc.is_stock_item == 'Yes')) {
|
||||
var callback = function(r, rt) {
|
||||
@@ -128,11 +134,7 @@ cur_frm.fields_dict.item_supplier_details.grid.get_field("supplier").get_query =
|
||||
erpnext.utils.supplier_query;
|
||||
|
||||
cur_frm.cscript.on_remove_attachment = function(doc) {
|
||||
// refresh image list before unsetting image
|
||||
refresh_field("image");
|
||||
if(!inList(cur_frm.fields_dict.image.df.options.split("\n"), doc.image)) {
|
||||
// if the selected image is removed from attachment, unset it
|
||||
cur_frm.set_value("image", "");
|
||||
msgprint(wn._("Attachment removed. You may need to update: ")
|
||||
+ wn.meta.get_docfield(doc.doctype, "description_html").label);
|
||||
}
|
||||
@@ -151,3 +153,7 @@ cur_frm.cscript.copy_from_item_group = function(doc) {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.image = function() {
|
||||
refresh_field("image_view");
|
||||
}
|
||||
@@ -23,51 +23,197 @@ from webnotes.model.bean import getlist
|
||||
from webnotes import msgprint, _
|
||||
|
||||
from webnotes.model.controller import DocListController
|
||||
class DocType(DocListController):
|
||||
def get_tax_rate(self, tax_type):
|
||||
rate = webnotes.conn.sql("select tax_rate from tabAccount where name = %s", tax_type)
|
||||
ret = {
|
||||
'tax_rate' : rate and flt(rate[0][0]) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
class PriceListCurrencyMismatch(Exception): pass
|
||||
|
||||
class DocType(DocListController):
|
||||
def autoname(self):
|
||||
if webnotes.conn.get_default("item_naming_by")=="Naming Series":
|
||||
from webnotes.model.doc import make_autoname
|
||||
self.doc.item_code = make_autoname(self.doc.naming_series+'.#####')
|
||||
elif not self.doc.item_code:
|
||||
msgprint(_("Item Code is mandatory"), raise_exception=1)
|
||||
|
||||
self.doc.name = self.doc.item_code
|
||||
|
||||
def validate(self):
|
||||
if not self.doc.stock_uom:
|
||||
msgprint(_("Please enter Default Unit of Measure"), raise_exception=1)
|
||||
|
||||
self.check_stock_uom_with_bin()
|
||||
self.validate_conversion_factor()
|
||||
self.add_default_uom_in_conversion_factor_table()
|
||||
self.valiadte_item_type()
|
||||
self.check_for_active_boms()
|
||||
self.validate_price_lists()
|
||||
self.fill_customer_code()
|
||||
self.check_item_tax()
|
||||
self.validate_barcode()
|
||||
self.check_non_asset_warehouse()
|
||||
self.cant_change()
|
||||
self.validate_item_type_for_reorder()
|
||||
|
||||
if self.doc.name:
|
||||
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
|
||||
|
||||
def on_update(self):
|
||||
self.validate_name_with_item_group()
|
||||
|
||||
# webpage updates
|
||||
self.update_website()
|
||||
|
||||
bin = webnotes.conn.sql("select stock_uom from `tabBin` where item_code = %s",
|
||||
self.doc.item_code)
|
||||
if bin and cstr(bin[0][0]) and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
||||
msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.")
|
||||
raise Exception
|
||||
|
||||
def add_default_uom_in_conversion_factor_table(self):
|
||||
uom_conv_list = [d.uom for d in self.doclist.get({"parentfield": "uom_conversion_details"})]
|
||||
if self.doc.stock_uom not in uom_conv_list:
|
||||
ch = addchild(self.doc, 'uom_conversion_details', 'UOM Conversion Detail', self.doclist)
|
||||
ch.uom = self.doc.stock_uom
|
||||
ch.conversion_factor = 1
|
||||
|
||||
def check_stock_uom_with_bin(self):
|
||||
if not self.doc.fields.get("__islocal"):
|
||||
bin = webnotes.conn.sql("select stock_uom from `tabBin` where item_code = %s",
|
||||
self.doc.name)
|
||||
if self.doc.stock_uom and bin and cstr(bin[0][0]) \
|
||||
and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
||||
msgprint(_("Please Update Stock UOM with the help of Stock UOM Replace Utility."),
|
||||
raise_exception=1)
|
||||
|
||||
def validate_conversion_factor(self):
|
||||
check_list = []
|
||||
for d in getlist(self.doclist,'uom_conversion_details'):
|
||||
if not self.doc.stock_uom:
|
||||
msgprint("Please enter Stock UOM first.")
|
||||
raise Exception
|
||||
|
||||
if cstr(d.uom) in check_list:
|
||||
msgprint("UOM %s has been entered more than once in Conversion Factor Details." % cstr(d.uom))
|
||||
raise Exception
|
||||
msgprint(_("UOM %s has been entered more than once in Conversion Factor Table." %
|
||||
cstr(d.uom)), raise_exception=1)
|
||||
else:
|
||||
check_list.append(cstr(d.uom))
|
||||
|
||||
if cstr(d.uom) == cstr(self.doc.stock_uom):
|
||||
if flt(d.conversion_factor) != 1:
|
||||
msgprint("Conversion Factor of UOM : %s should be equal to 1. As UOM : %s is Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
elif cstr(d.uom) != cstr(self.doc.stock_uom) and flt(d.conversion_factor) == 1:
|
||||
msgprint("Conversion Factor of UOM : %s should not be equal to 1. As UOM : %s is not Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
if d.uom and cstr(d.uom) == cstr(self.doc.stock_uom) and flt(d.conversion_factor) != 1:
|
||||
msgprint(_("""Conversion Factor of UOM: %s should be equal to 1.
|
||||
As UOM: %s is Stock UOM of Item: %s.""" %
|
||||
(d.uom, d.uom, self.doc.name)), raise_exception=1)
|
||||
elif d.uom and cstr(d.uom)!= self.doc.stock_uom and flt(d.conversion_factor) == 1:
|
||||
msgprint(_("""Conversion Factor of UOM: %s should not be equal to 1.
|
||||
As UOM: %s is not Stock UOM of Item: %s""" %
|
||||
(d.uom, d.uom, self.doc.name)), raise_exception=1)
|
||||
|
||||
def valiadte_item_type(self):
|
||||
if cstr(self.doc.is_manufactured_item) == "No":
|
||||
self.doc.is_pro_applicable = "No"
|
||||
|
||||
if not cstr(self.doc.stock_uom) in check_list :
|
||||
child = addchild( self.doc, 'uom_conversion_details',
|
||||
'UOM Conversion Detail', self.doclist)
|
||||
child.uom = self.doc.stock_uom
|
||||
child.conversion_factor = 1
|
||||
child.save()
|
||||
if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1)
|
||||
|
||||
if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1)
|
||||
|
||||
def check_for_active_boms(self):
|
||||
def _check_for_active_boms(field_label):
|
||||
if field_label in ['Is Active', 'Is Purchase Item']:
|
||||
bom_mat = webnotes.conn.sql("""select distinct t1.parent
|
||||
from `tabBOM Item` t1, `tabBOM` t2 where t2.name = t1.parent
|
||||
and t1.item_code =%s and ifnull(t1.bom_no, '') = '' and t2.is_active = 1
|
||||
and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name)
|
||||
if bom_mat and bom_mat[0][0]:
|
||||
msgprint(_(field_label) + _(" should be 'Yes'. As Item: ") + self.doc.name +
|
||||
_(" is present in one or many Active BOMs"), raise_exception=1)
|
||||
|
||||
if ((field_label == 'Allow Production Order'
|
||||
and self.doc.is_sub_contracted_item != 'Yes')
|
||||
or (field_label == 'Is Sub Contracted Item'
|
||||
and self.doc.is_manufactured_item != 'Yes')):
|
||||
bom = webnotes.conn.sql("""select name from `tabBOM` where item = %s
|
||||
and is_active = 1""", (self.doc.name,))
|
||||
if bom and bom[0][0]:
|
||||
msgprint(_(field_label) + _(" should be 'Yes'. As Item: ") + self.doc.name +
|
||||
_(" is present in one or many Active BOMs"), raise_exception=1)
|
||||
|
||||
if not cint(self.doc.fields.get("__islocal")):
|
||||
fl = {'is_manufactured_item' :'Allow Bill of Materials',
|
||||
'is_sub_contracted_item':'Is Sub Contracted Item',
|
||||
'is_purchase_item' :'Is Purchase Item',
|
||||
'is_pro_applicable' :'Allow Production Order'}
|
||||
for d in fl:
|
||||
if cstr(self.doc.fields.get(d)) != 'Yes':
|
||||
_check_for_active_boms(fl[d])
|
||||
|
||||
def validate_price_lists(self):
|
||||
price_lists=[]
|
||||
for d in getlist(self.doclist,'ref_rate_details'):
|
||||
if d.price_list_name in price_lists:
|
||||
msgprint(_("Cannot have two prices for same Price List") + ": " + d.price_list_name,
|
||||
raise_exception= webnotes.DuplicateEntryError)
|
||||
else:
|
||||
price_list_currency = webnotes.conn.get_value("Price List", d.price_list_name, "currency")
|
||||
if price_list_currency and d.ref_currency != price_list_currency:
|
||||
msgprint(_("Currency does not match Price List Currency for Price List") \
|
||||
+ ": " + d.price_list_name, raise_exception=PriceListCurrencyMismatch)
|
||||
|
||||
price_lists.append(d.price_list_name)
|
||||
|
||||
|
||||
def fill_customer_code(self):
|
||||
""" Append all the customer codes and insert into "customer_code" field of item table """
|
||||
cust_code=[]
|
||||
for d in getlist(self.doclist,'item_customer_details'):
|
||||
cust_code.append(d.ref_code)
|
||||
self.doc.customer_code=','.join(cust_code)
|
||||
|
||||
def check_item_tax(self):
|
||||
"""Check whether Tax Rate is not entered twice for same Tax Type"""
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'item_tax'):
|
||||
if d.tax_type:
|
||||
account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type")
|
||||
|
||||
if account_type not in ['Tax', 'Chargeable']:
|
||||
msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1)
|
||||
else:
|
||||
if d.tax_type in check_list:
|
||||
msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1)
|
||||
else:
|
||||
check_list.append(d.tax_type)
|
||||
|
||||
def validate_barcode(self):
|
||||
if self.doc.barcode:
|
||||
duplicate = webnotes.conn.sql("""select name from tabItem where barcode = %s
|
||||
and name != %s""", (self.doc.barcode, self.doc.name))
|
||||
if duplicate:
|
||||
msgprint("Barcode: %s already used in item: %s" %
|
||||
(self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1)
|
||||
|
||||
def check_non_asset_warehouse(self):
|
||||
if not self.doc.__islocal and self.doc.is_asset_item == "Yes":
|
||||
existing_qty = webnotes.conn.sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name)
|
||||
for e in existing_qty:
|
||||
msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." %
|
||||
(e[1],e[0]))
|
||||
if existing_qty:
|
||||
self.doc.is_asset_item = 'No'
|
||||
msgprint(_("""Please transfer the above quantities to an asset warehouse \
|
||||
before changing this item to an asset item"""), raise_exception=1)
|
||||
|
||||
def cant_change(self):
|
||||
if not self.doc.fields.get("__islocal"):
|
||||
vals = webnotes.conn.get_value("Item", self.doc.name,
|
||||
["has_serial_no", "is_stock_item", "valuation_method"], as_dict=True)
|
||||
|
||||
if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or
|
||||
vals.has_serial_no != self.doc.has_serial_no or
|
||||
vals.valuation_method != self.doc.valuation_method):
|
||||
if self.check_if_sle_exists() == "exists":
|
||||
webnotes.msgprint(_("As there are existing stock transactions for this \
|
||||
item, you can not change the values of 'Has Serial No', \
|
||||
'Is Stock Item' and 'Valuation Method'"), raise_exception=1)
|
||||
|
||||
def validate_item_type_for_reorder(self):
|
||||
if self.doc.re_order_level or len(self.doclist.get({"parentfield": "item_reorder",
|
||||
"material_request_type": "Purchase"})):
|
||||
if not self.doc.is_purchase_item:
|
||||
webnotes.msgprint(_("""To set reorder level, item must be Purchase Item"""),
|
||||
raise_exception=1)
|
||||
|
||||
def check_if_sle_exists(self):
|
||||
sle = webnotes.conn.sql("""select name from `tabStock Ledger Entry`
|
||||
where item_code = %s and ifnull(is_cancelled, 'No') = 'No'""", self.doc.name)
|
||||
return sle and 'exists' or 'not exists'
|
||||
|
||||
def validate_name_with_item_group(self):
|
||||
if webnotes.conn.exists("Item Group", self.doc.name):
|
||||
@@ -104,107 +250,17 @@ class DocType(DocListController):
|
||||
|
||||
webnotes.conn.set(self.doc, "page_name", None)
|
||||
|
||||
# On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception)
|
||||
def on_trash(self):
|
||||
webnotes.conn.sql("""delete from tabBin where item_code=%s""", self.doc.item_code)
|
||||
webnotes.conn.sql("""delete from `tabStock Ledger Entry`
|
||||
where item_code=%s and is_cancelled='Yes' """, self.doc.item_code)
|
||||
|
||||
if self.doc.page_name:
|
||||
from webnotes.webutils import clear_cache
|
||||
clear_cache(self.doc.page_name)
|
||||
|
||||
# Check whether Ref Rate is not entered twice for same Price List and Currency
|
||||
def check_ref_rate_detail(self):
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'ref_rate_details'):
|
||||
if [cstr(d.price_list_name),cstr(d.ref_currency),cint(d.selling),cint(d.buying)] in check_list:
|
||||
msgprint("Ref Rate is entered twice for Price List : '%s' and Currency : '%s'." % (d.price_list_name,d.ref_currency))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append([cstr(d.price_list_name),cstr(d.ref_currency)])
|
||||
def get_tax_rate(self, tax_type):
|
||||
return { "tax_rate": webnotes.conn.get_value("Account", tax_type, "tax_rate") }
|
||||
|
||||
# Append all the customer codes and insert into "customer_code" field of item table
|
||||
def fill_customer_code(self):
|
||||
cust_code=[]
|
||||
for d in getlist(self.doclist,'item_customer_details'):
|
||||
cust_code.append(d.ref_code)
|
||||
self.doc.customer_code=','.join(cust_code)
|
||||
def prepare_template_args(self):
|
||||
from website.helpers.product import get_parent_item_groups
|
||||
self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}]
|
||||
self.doc.title = self.doc.item_name
|
||||
|
||||
def check_item_tax(self):
|
||||
"""Check whether Tax Rate is not entered twice for same Tax Type"""
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'item_tax'):
|
||||
if d.tax_type:
|
||||
account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type")
|
||||
|
||||
if account_type not in ['Tax', 'Chargeable']:
|
||||
msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1)
|
||||
else:
|
||||
if d.tax_type in check_list:
|
||||
msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1)
|
||||
else:
|
||||
check_list.append(d.tax_type)
|
||||
|
||||
def check_for_active_boms(self, field_label):
|
||||
if field_label in ['Is Active', 'Is Purchase Item']:
|
||||
bom_mat = webnotes.conn.sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code =%s and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 1 and t2.docstatus = 1 and t1.docstatus =1 ", self.doc.name)
|
||||
if bom_mat and bom_mat[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
if ((field_label == 'Allow Production Order'
|
||||
and self.doc.is_sub_contracted_item != 'Yes')
|
||||
or (field_label == 'Is Sub Contracted Item'
|
||||
and self.doc.is_manufactured_item != 'Yes')):
|
||||
bom = webnotes.conn.sql("select name from `tabBOM` where item = %s and is_active = 1",
|
||||
(self.doc.name,))
|
||||
if bom and bom[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
|
||||
def validate_barcode(self):
|
||||
if self.doc.barcode:
|
||||
duplicate = webnotes.conn.sql("select name from tabItem where barcode = %s and name != %s", (self.doc.barcode, self.doc.name))
|
||||
if duplicate:
|
||||
msgprint("Barcode: %s already used in item: %s" % (self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1)
|
||||
|
||||
def validate(self):
|
||||
if not cint(self.doc.fields.get("__islocal")):
|
||||
fl = {'is_manufactured_item' :'Allow Bill of Materials',
|
||||
'is_sub_contracted_item':'Is Sub Contracted Item',
|
||||
'is_purchase_item' :'Is Purchase Item',
|
||||
'is_pro_applicable' :'Allow Production Order'}
|
||||
for d in fl:
|
||||
if cstr(self.doc.fields.get(d)) != 'Yes':
|
||||
self.check_for_active_boms(fl[d])
|
||||
self.check_ref_rate_detail()
|
||||
self.fill_customer_code()
|
||||
self.check_item_tax()
|
||||
self.validate_barcode()
|
||||
self.check_non_asset_warehouse()
|
||||
self.cant_change()
|
||||
|
||||
if cstr(self.doc.is_manufactured_item) == "No":
|
||||
self.doc.is_pro_applicable = "No"
|
||||
|
||||
if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1)
|
||||
|
||||
if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1)
|
||||
|
||||
if self.doc.name:
|
||||
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
|
||||
|
||||
def check_non_asset_warehouse(self):
|
||||
if self.doc.is_asset_item == "Yes":
|
||||
existing_qty = webnotes.conn.sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name)
|
||||
for e in existing_qty:
|
||||
msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." % (e[1],e[0]))
|
||||
if existing_qty:
|
||||
msgprint("Please transfer the above quantities to an asset warehouse before changing this item to an asset item.")
|
||||
self.doc.is_asset_item = 'No'
|
||||
raise Exception
|
||||
if self.doc.slideshow:
|
||||
from website.helpers.slideshow import get_slideshow
|
||||
get_slideshow(self)
|
||||
|
||||
def get_file_details(self, arg = ''):
|
||||
file = webnotes.conn.sql("select file_group, description from tabFile where name = %s", eval(arg)['file_name'], as_dict = 1)
|
||||
@@ -215,35 +271,17 @@ class DocType(DocListController):
|
||||
}
|
||||
return ret
|
||||
|
||||
def on_trash(self):
|
||||
webnotes.conn.sql("""delete from tabBin where item_code=%s""", self.doc.item_code)
|
||||
webnotes.conn.sql("""delete from `tabStock Ledger Entry`
|
||||
where item_code=%s and is_cancelled='Yes' """, self.doc.item_code)
|
||||
|
||||
def check_if_sle_exists(self):
|
||||
sle = webnotes.conn.sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
|
||||
return sle and 'exists' or 'not exists'
|
||||
|
||||
def on_rename(self,newdn,olddn):
|
||||
webnotes.conn.sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
|
||||
if self.doc.page_name:
|
||||
from webnotes.webutils import clear_cache
|
||||
clear_cache(self.doc.page_name)
|
||||
|
||||
def prepare_template_args(self):
|
||||
from website.helpers.product import get_parent_item_groups
|
||||
self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}]
|
||||
self.doc.title = self.doc.item_name
|
||||
|
||||
if self.doc.slideshow:
|
||||
from website.helpers.slideshow import get_slideshow
|
||||
get_slideshow(self)
|
||||
|
||||
def cant_change(self):
|
||||
if not self.doc.fields.get("__islocal"):
|
||||
vals = webnotes.conn.get_value("Item", self.doc.name,
|
||||
["has_serial_no", "is_stock_item", "valuation_method"], as_dict=True)
|
||||
|
||||
if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or
|
||||
vals.has_serial_no != self.doc.has_serial_no or
|
||||
vals.valuation_method != self.doc.valuation_method):
|
||||
if self.check_if_sle_exists() == "exists":
|
||||
webnotes.msgprint(_("As there are existing stock transactions for this \
|
||||
item, you can not change the values of 'Has Serial No', \
|
||||
'Is Stock Item' and 'Valuation Method'"), raise_exception=1)
|
||||
def on_rename(self,newdn,olddn, merge=False):
|
||||
webnotes.conn.sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
|
||||
if self.doc.page_name:
|
||||
from webnotes.webutils import clear_cache
|
||||
clear_cache(self.doc.page_name)
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-03-07 15:53:11",
|
||||
"creation": "2013-05-03 10:45:46",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-20 15:10:12",
|
||||
"modified": "2013-05-22 15:48:27",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -33,6 +33,7 @@
|
||||
"parent": "Item",
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"submit": 0
|
||||
@@ -47,7 +48,16 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item",
|
||||
"no_copy": 0,
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Naming Series",
|
||||
"options": "\nITEM",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "Item will be saved by this name in the data base.",
|
||||
@@ -56,9 +66,11 @@
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 0,
|
||||
"label": "Item Code",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"reqd": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
@@ -70,6 +82,7 @@
|
||||
"label": "Item Name",
|
||||
"oldfieldname": "item_name",
|
||||
"oldfieldtype": "Data",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -83,6 +96,7 @@
|
||||
"oldfieldname": "item_group",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item Group",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -94,7 +108,8 @@
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "UOM",
|
||||
"reqd": 0
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -106,25 +121,29 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Brand",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Barcode"
|
||||
"label": "Barcode",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Select",
|
||||
"label": "Image",
|
||||
"options": "attach_files:"
|
||||
"options": "attach_files:",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -132,7 +151,8 @@
|
||||
"fieldtype": "Image",
|
||||
"in_list_view": 1,
|
||||
"label": "Image View",
|
||||
"options": "image"
|
||||
"options": "image",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -143,6 +163,7 @@
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
@@ -150,21 +171,24 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "description_html",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Description HTML"
|
||||
"label": "Description HTML",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "Generates HTML to include selected image in the description",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "add_image",
|
||||
"fieldtype": "Button",
|
||||
"label": "Generate Description HTML"
|
||||
"label": "Generate Description HTML",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "inventory",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Inventory",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "Yes",
|
||||
@@ -176,6 +200,7 @@
|
||||
"oldfieldname": "is_stock_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -187,7 +212,8 @@
|
||||
"label": "Default Reserved Warehouse",
|
||||
"oldfieldname": "default_warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse"
|
||||
"options": "Warehouse",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -197,7 +223,8 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Allowance Percent",
|
||||
"oldfieldname": "tolerance",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -205,7 +232,8 @@
|
||||
"fieldname": "valuation_method",
|
||||
"fieldtype": "Select",
|
||||
"label": "Valuation Method",
|
||||
"options": "\nFIFO\nMoving Average"
|
||||
"options": "\nFIFO\nMoving Average",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "0.00",
|
||||
@@ -217,7 +245,8 @@
|
||||
"hidden": 0,
|
||||
"label": "Minimum Order Qty",
|
||||
"oldfieldname": "min_order_qty",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -225,6 +254,7 @@
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -238,6 +268,7 @@
|
||||
"oldfieldname": "is_asset_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -250,6 +281,7 @@
|
||||
"oldfieldname": "has_batch_no",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -264,6 +296,7 @@
|
||||
"oldfieldname": "has_serial_no",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -273,7 +306,8 @@
|
||||
"fieldtype": "Data",
|
||||
"label": "Warranty Period (in days)",
|
||||
"oldfieldname": "warranty_period",
|
||||
"oldfieldtype": "Data"
|
||||
"oldfieldtype": "Data",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -282,7 +316,8 @@
|
||||
"fieldtype": "Date",
|
||||
"label": "End of Life",
|
||||
"oldfieldname": "end_of_life",
|
||||
"oldfieldtype": "Date"
|
||||
"oldfieldtype": "Date",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -290,7 +325,8 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "net_weight",
|
||||
"fieldtype": "Float",
|
||||
"label": "Net Weight"
|
||||
"label": "Net Weight",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -298,14 +334,16 @@
|
||||
"fieldname": "weight_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Weight UOM",
|
||||
"options": "UOM"
|
||||
"options": "UOM",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "Auto-raise Material Request if quantity goes below re-order level in a warehouse",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "reorder_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Re-order"
|
||||
"label": "Re-order",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
@@ -314,47 +352,39 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Re-Order Level",
|
||||
"oldfieldname": "re_order_level",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "re_order_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Re-Order Qty"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break_31",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_stock_item==\"Yes\"",
|
||||
"description": "Send an email to users of role \"Material Manager\" and \"Purchase Manager\" when re-order level is crossed.",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "email_notify",
|
||||
"fieldtype": "Check",
|
||||
"label": "Notify by Email on Re-order"
|
||||
"label": "Re-Order Qty",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "section_break_31",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple"
|
||||
"options": "Simple",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_reorder",
|
||||
"fieldtype": "Table",
|
||||
"label": "Warehouse-wise Item Reorder",
|
||||
"options": "Item Reorder"
|
||||
"options": "Item Reorder",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "purchase_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Purchase Details",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "Yes",
|
||||
@@ -366,6 +396,7 @@
|
||||
"oldfieldname": "is_purchase_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -377,7 +408,8 @@
|
||||
"label": "Lead Time Days",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "lead_time_days",
|
||||
"oldfieldtype": "Int"
|
||||
"oldfieldtype": "Int",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
@@ -388,7 +420,8 @@
|
||||
"label": "Default Expense Account",
|
||||
"oldfieldname": "purchase_account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account"
|
||||
"options": "Account",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
@@ -399,7 +432,8 @@
|
||||
"label": "Default Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center"
|
||||
"options": "Cost Center",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
@@ -419,7 +453,8 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Standard Rate",
|
||||
"oldfieldname": "standard_rate",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
@@ -427,6 +462,7 @@
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -438,21 +474,24 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "uom_conversion_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "UOM Conversion Detail"
|
||||
"options": "UOM Conversion Detail",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "manufacturer",
|
||||
"fieldtype": "Data",
|
||||
"label": "Manufacturer"
|
||||
"label": "Manufacturer",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "manufacturer_part_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Manufacturer Part Number"
|
||||
"label": "Manufacturer Part Number",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_purchase_item==\"Yes\"",
|
||||
@@ -460,14 +499,16 @@
|
||||
"fieldname": "item_supplier_details",
|
||||
"fieldtype": "Table",
|
||||
"label": "Item Supplier Details",
|
||||
"options": "Item Supplier"
|
||||
"options": "Item Supplier",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sales_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sales Details",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "Yes",
|
||||
@@ -480,6 +521,7 @@
|
||||
"oldfieldname": "is_sales_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -494,6 +536,7 @@
|
||||
"oldfieldname": "is_service_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -507,6 +550,7 @@
|
||||
"oldfieldname": "is_sample_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -516,7 +560,8 @@
|
||||
"fieldtype": "Float",
|
||||
"label": "Max Discount (%)",
|
||||
"oldfieldname": "max_discount",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
@@ -524,7 +569,8 @@
|
||||
"fieldname": "default_income_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Income Account",
|
||||
"options": "Account"
|
||||
"options": "Account",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
@@ -532,7 +578,8 @@
|
||||
"fieldname": "default_sales_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
"options": "Cost Center",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
@@ -542,7 +589,8 @@
|
||||
"hidden": 1,
|
||||
"label": "Sales Rate",
|
||||
"oldfieldname": "sales_rate",
|
||||
"oldfieldtype": "Currency"
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_sales_item==\"Yes\"",
|
||||
@@ -550,6 +598,7 @@
|
||||
"fieldname": "column_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -559,14 +608,16 @@
|
||||
"fieldname": "item_customer_details",
|
||||
"fieldtype": "Table",
|
||||
"label": "Customer Codes",
|
||||
"options": "Item Customer Detail"
|
||||
"options": "Item Customer Detail",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_tax_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item Tax",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -575,13 +626,15 @@
|
||||
"label": "Item Tax1",
|
||||
"oldfieldname": "item_tax",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Item Tax"
|
||||
"options": "Item Tax",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "price_list_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price Lists and Rates"
|
||||
"label": "Price Lists and Rates",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"description": "Create a price list from Price List master and enter standard ref rates against each of them. On selection of a price list in Quotation, Sales Order or Delivery Note, corresponding ref rate will be fetched for this item.",
|
||||
@@ -591,14 +644,16 @@
|
||||
"label": "Item Prices",
|
||||
"oldfieldname": "ref_rate_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Item Price"
|
||||
"options": "Item Price",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "inspection_criteria",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Inspection Criteria",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "No",
|
||||
@@ -610,6 +665,7 @@
|
||||
"oldfieldname": "inspection_required",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -621,14 +677,16 @@
|
||||
"label": "Item Quality Inspection Parameter",
|
||||
"oldfieldname": "item_specification_details",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Item Quality Inspection Parameter"
|
||||
"options": "Item Quality Inspection Parameter",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "manufacturing",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Manufacturing",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "No",
|
||||
@@ -640,6 +698,7 @@
|
||||
"oldfieldname": "is_manufactured_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -665,6 +724,7 @@
|
||||
"oldfieldname": "is_pro_applicable",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -677,17 +737,9 @@
|
||||
"oldfieldname": "is_sub_contracted_item",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_code",
|
||||
@@ -696,19 +748,22 @@
|
||||
"in_filter": 1,
|
||||
"label": "Customer Code",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "website_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Website"
|
||||
"label": "Website",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "show_in_website",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show in Website"
|
||||
"label": "Show in Website",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -726,6 +781,7 @@
|
||||
"fieldname": "weightage",
|
||||
"fieldtype": "Int",
|
||||
"label": "Weightage",
|
||||
"read_only": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
@@ -735,7 +791,8 @@
|
||||
"fieldname": "slideshow",
|
||||
"fieldtype": "Link",
|
||||
"label": "Slideshow",
|
||||
"options": "Website Slideshow"
|
||||
"options": "Website Slideshow",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -744,12 +801,14 @@
|
||||
"fieldname": "website_image",
|
||||
"fieldtype": "Select",
|
||||
"label": "Image",
|
||||
"options": "attach_files:"
|
||||
"options": "attach_files:",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "cb72",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -758,7 +817,8 @@
|
||||
"fieldname": "website_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "Website Price List",
|
||||
"options": "Price List"
|
||||
"options": "Price List",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -767,7 +827,8 @@
|
||||
"fieldname": "website_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Website Warehouse",
|
||||
"options": "Warehouse"
|
||||
"options": "Warehouse",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -776,19 +837,22 @@
|
||||
"fieldname": "website_item_groups",
|
||||
"fieldtype": "Table",
|
||||
"label": "Website Item Groups",
|
||||
"options": "Website Item Group"
|
||||
"options": "Website Item Group",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sb72",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "copy_from_item_group",
|
||||
"fieldtype": "Button",
|
||||
"label": "Copy From Item Group"
|
||||
"label": "Copy From Item Group",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
@@ -796,37 +860,21 @@
|
||||
"fieldname": "item_website_specifications",
|
||||
"fieldtype": "Table",
|
||||
"label": "Item Website Specifications",
|
||||
"options": "Item Website Specification"
|
||||
"options": "Item Website Specification",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "show_in_website",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "web_long_description",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Website Description"
|
||||
"label": "Website Description",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "System Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"role": "Material Master Manager",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material Master Manager",
|
||||
"write": 1
|
||||
},
|
||||
@@ -835,15 +883,6 @@
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"role": "System Manager"
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"role": "Material Manager",
|
||||
"write": 0
|
||||
},
|
||||
@@ -852,25 +891,6 @@
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material Manager",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 1,
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
}
|
||||
|
||||
@@ -20,6 +20,22 @@ import webnotes
|
||||
|
||||
test_ignore = ["BOM"]
|
||||
|
||||
class TestItem(unittest.TestCase):
|
||||
def test_duplicate_price_list(self):
|
||||
item = webnotes.bean(copy=test_records[0])
|
||||
item.doc.item_code = "_Test Item 10"
|
||||
item_price = item.doclist.get({"doctype": "Item Price"})[0]
|
||||
item.doclist.append(webnotes.doc(item_price.fields.copy()))
|
||||
self.assertRaises(webnotes.DuplicateEntryError, item.insert)
|
||||
|
||||
def test_price_list_mismatch(self):
|
||||
from stock.doctype.item.item import PriceListCurrencyMismatch
|
||||
item = webnotes.bean(copy=test_records[0])
|
||||
item.doc.item_code = "_Test Item 11"
|
||||
item_price = item.doclist.get({"doctype": "Item Price"})[0].ref_currency="USD"
|
||||
self.assertRaises(PriceListCurrencyMismatch, item.insert)
|
||||
|
||||
|
||||
test_records = [
|
||||
[{
|
||||
"doctype": "Item",
|
||||
@@ -45,7 +61,14 @@ test_records = [
|
||||
"warehouse": "_Test Warehouse",
|
||||
"warehouse_reorder_level": 20,
|
||||
"warehouse_reorder_qty": 20
|
||||
}],
|
||||
}, {
|
||||
"doctype": "Item Price",
|
||||
"parentfield": "ref_rate_details",
|
||||
"price_list_name": "_Test Price List",
|
||||
"ref_rate": 100,
|
||||
"ref_currency": "INR"
|
||||
}
|
||||
],
|
||||
[{
|
||||
"doctype": "Item",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-03-08 15:37:16",
|
||||
"creation": "2013-04-29 15:18:04",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-21 17:29:15",
|
||||
"modified": "2013-04-29 19:16:45",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -68,13 +68,13 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "selling",
|
||||
"fieldtype": "Check",
|
||||
"label": "For Selling"
|
||||
"label": "Valid For Selling"
|
||||
},
|
||||
{
|
||||
"description": "Allow this price in purchase related forms",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "buying",
|
||||
"fieldtype": "Check",
|
||||
"label": "For Buying"
|
||||
"label": "Valid For Buying"
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-21 14:15:25",
|
||||
"creation": "2013-03-07 14:48:38",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-25 15:38:02",
|
||||
"modified_by": "Administrator",
|
||||
@@ -331,15 +331,6 @@
|
||||
"options": "Print Heading",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
|
||||
@@ -263,6 +263,12 @@ class TestMaterialRequest(unittest.TestCase):
|
||||
se = webnotes.bean(copy=se_doclist)
|
||||
self.assertRaises(webnotes.MappingMismatchError, se.insert)
|
||||
|
||||
def test_warehouse_company_validation(self):
|
||||
from controllers.buying_controller import WrongWarehouseCompany
|
||||
mr = webnotes.bean(copy=test_records[0])
|
||||
mr.doc.company = "_Test Company 1"
|
||||
self.assertRaises(WrongWarehouseCompany, mr.insert)
|
||||
|
||||
test_records = [
|
||||
[
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-22 15:24:18",
|
||||
"creation": "2013-03-25 16:01:29",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-02 19:09:37",
|
||||
"modified_by": "Administrator",
|
||||
@@ -31,9 +31,7 @@
|
||||
"parent": "Purchase Receipt",
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1
|
||||
"read": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
@@ -886,44 +884,78 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Purchase User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"match": "supplier",
|
||||
"role": "Supplier"
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Material Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Material Manager",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"report": 0,
|
||||
"role": "Material User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Material User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Purchase User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"match": "",
|
||||
"permlevel": 1,
|
||||
"role": "Purchase User",
|
||||
"submit": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"match": "supplier",
|
||||
"permlevel": 0,
|
||||
"report": 1,
|
||||
"role": "Supplier"
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-22 01:28:03",
|
||||
"creation": "2013-03-07 11:42:59",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-07 07:03:28",
|
||||
"modified": "2013-05-22 12:01:08",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -35,6 +35,7 @@
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"width": "100px"
|
||||
@@ -48,6 +49,7 @@
|
||||
"oldfieldname": "item_name",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
@@ -59,6 +61,7 @@
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "300px"
|
||||
},
|
||||
@@ -72,6 +75,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -84,6 +88,7 @@
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -97,6 +102,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"search_index": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -110,6 +116,7 @@
|
||||
"options": "UOM",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -119,14 +126,16 @@
|
||||
"fieldtype": "Currency",
|
||||
"label": "Ref Rate ",
|
||||
"options": "currency",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "discount_rate",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount %",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "0.00",
|
||||
@@ -139,6 +148,7 @@
|
||||
"options": "currency",
|
||||
"print_hide": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -157,7 +167,8 @@
|
||||
"fieldtype": "Currency",
|
||||
"label": "Ref Rate*",
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "0.00",
|
||||
@@ -170,6 +181,7 @@
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -184,6 +196,7 @@
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -198,6 +211,7 @@
|
||||
"options": "Warehouse",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -209,6 +223,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"width": "100px"
|
||||
},
|
||||
@@ -235,6 +250,7 @@
|
||||
"oldfieldname": "serial_no",
|
||||
"oldfieldtype": "Text",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0
|
||||
},
|
||||
{
|
||||
@@ -242,7 +258,8 @@
|
||||
"fieldname": "rejected_serial_no",
|
||||
"fieldtype": "Text",
|
||||
"label": "Rejected Serial No",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -252,7 +269,8 @@
|
||||
"oldfieldname": "batch_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Batch",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -278,6 +296,7 @@
|
||||
"oldfieldname": "schedule_date",
|
||||
"oldfieldtype": "Date",
|
||||
"print_hide": 1,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
@@ -288,7 +307,8 @@
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"options": "Project",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -299,7 +319,8 @@
|
||||
"oldfieldname": "qa_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Quality Inspection",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -336,6 +357,7 @@
|
||||
"oldfieldtype": "Currency",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"width": "100px"
|
||||
},
|
||||
{
|
||||
@@ -344,9 +366,11 @@
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Prevdoc Doctype",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -355,7 +379,7 @@
|
||||
"hidden": 0,
|
||||
"in_filter": 1,
|
||||
"label": "PO No",
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_docname",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Purchase Order",
|
||||
@@ -373,6 +397,7 @@
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "PO Date",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_date",
|
||||
"oldfieldtype": "Date",
|
||||
"print_hide": 1,
|
||||
@@ -418,7 +443,7 @@
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Purchase Order Item No",
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_detail_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"print_hide": 1,
|
||||
@@ -479,6 +504,7 @@
|
||||
"label": "Page Break",
|
||||
"oldfieldname": "page_break",
|
||||
"oldfieldtype": "Check",
|
||||
"print_hide": 1
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -1,11 +0,0 @@
|
||||
[
|
||||
"Package Items",
|
||||
"Sales BOM Items",
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.\n\nNote: BOM = Bill of Materials",
|
||||
"List items that form the package.",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"",
|
||||
"Sales BOM Item",
|
||||
"Sales BOM",
|
||||
"Parent Item",
|
||||
"Stock"
|
||||
]
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "\u0625\u062c\u0645\u0627\u0644\u064a \u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u0646 \u0627\u0644\u0639\u0646\u0627\u0635\u0631 ** ** ** \u0641\u064a \u0628\u0646\u062f \u0622\u062e\u0631. ** \u0647\u0630\u0627 \u0645\u0641\u064a\u062f \u0625\u0630\u0627 \u0643\u0646\u062a \u062a\u062c\u0645\u064a\u0639 \u0639\u0646\u0627\u0635\u0631 \u0645\u0639\u064a\u0646\u0629 ** ** \u0641\u064a \u062d\u0632\u0645\u0629 \u0648\u064a\u0645\u0643\u0646\u0643 \u0627\u0644\u062d\u0641\u0627\u0638 \u0639\u0644\u0649 \u0627\u0644\u0645\u062e\u0632\u0648\u0646 \u0645\u0646 \u0627\u0644\u0623\u0635\u0646\u0627\u0641 ** ** \u0645\u0639\u0628\u0623\u0629 \u0648\u0644\u064a\u0633 \u0627\u0644\u0643\u0644\u064a ** \u0627\u0644\u0633\u0644\u0639\u0629 **. \u0627\u0644\u062d\u0632\u0645\u0629 \u0627\u0644\u0633\u0644\u0639\u0629 ** ** \u0633\u064a\u0643\u0648\u0646 "\u0647\u0648 \u0627\u0644\u0645\u062e\u0632\u0648\u0646 \u0627\u0644\u0633\u0644\u0639\u0629" \u0628 "\u0644\u0627" \u0648 "\u0647\u0644 \u0627\u0644\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0633\u0644\u0639\u0629" \u0628 "\u0646\u0639\u0645" \u0639\u0644\u0649 \u0633\u0628\u064a\u0644 \u0627\u0644\u0645\u062b\u0627\u0644: \u0625\u0630\u0627 \u0643\u0646\u062a \u062a\u0628\u064a\u0639 \u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0643\u0645\u0628\u064a\u0648\u062a\u0631 \u0627\u0644\u0645\u062d\u0645\u0648\u0644\u0629 \u0648\u062d\u0642\u0627\u0626\u0628 \u062a\u062d\u0645\u0644 \u0639\u0644\u0649 \u0627\u0644\u0638\u0647\u0631 \u0628\u0634\u0643\u0644 \u0645\u0646\u0641\u0635\u0644 \u0648\u0644\u0647\u0627 \u0633\u0639\u0631 \u062e\u0627\u0635 \u0627\u0630\u0627 \u0643\u0627\u0646 \u0627\u0644\u0632\u0628\u0648\u0646 \u064a\u0634\u062a\u0631\u064a \u0643\u0644 \u060c \u062b\u0645 \u0633\u064a\u0642\u0648\u0645 \u0627\u0644\u0643\u0645\u0628\u064a\u0648\u062a\u0631 \u0627\u0644\u0645\u062d\u0645\u0648\u0644 + \u062d\u0642\u064a\u0628\u0629 \u0627\u0644\u0638\u0647\u0631 \u062a\u0643\u0648\u0646 \u062c\u062f\u064a\u062f\u0629 \u0627\u0644\u0645\u0628\u064a\u0639\u0627\u062a BOM Item.Note: BOM = \u0628\u064a\u0644 \u0627\u0644\u0645\u0648\u0627\u062f",
|
||||
"List items that form the package.": "\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u064a \u062a\u0634\u0643\u0644 \u0627\u0644\u062d\u0632\u0645\u0629.",
|
||||
"Package Items": "\u062d\u0632\u0645\u0629 \u0627\u0644\u0628\u0646\u0648\u062f",
|
||||
"Parent Item": "\u0627\u0644\u0623\u0645 \u0627\u0644\u0645\u062f\u064a\u0646\u0629",
|
||||
"Sales BOM": "\u0645\u0628\u064a\u0639\u0627\u062a BOM",
|
||||
"Sales BOM Item": "\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0633\u0644\u0639\u0629 BOM",
|
||||
"Sales BOM Items": "\u0639\u0646\u0627\u0635\u0631 \u0645\u0628\u064a\u0639\u0627\u062a BOM",
|
||||
"Stock": "\u0627\u0644\u0623\u0648\u0631\u0627\u0642 \u0627\u0644\u0645\u0627\u0644\u064a\u0629",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "\u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0630\u064a \u064a\u0645\u062b\u0644 \u0627\u0644\u062d\u0632\u0645\u0629. \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0644\u062f\u0649 \u0647\u0630\u0627 \u0627\u0644\u0628\u0646\u062f "\u0647\u0648 \u0627\u0644\u0645\u062e\u0632\u0648\u0646 \u0627\u0644\u0633\u0644\u0639\u0629" \u0628 "\u0644\u0627" \u0648 "\u0647\u0644 \u0627\u0644\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0633\u0644\u0639\u0629" \u0628 "\u0646\u0639\u0645""
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"List items that form the package.": "Diese Liste Artikel bilden das Paket.",
|
||||
"Package Items": "Package Angebote",
|
||||
"Parent Item": "\u00dcbergeordneter Artikel",
|
||||
"Sales BOM": "Vertrieb BOM",
|
||||
"Sales BOM Item": "Vertrieb St\u00fccklistenposition",
|
||||
"Sales BOM Items": "Vertrieb St\u00fccklistenpositionen",
|
||||
"Stock": "Lager",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "Das Element, das das Paket darstellt. Dieser Artikel muss \"Ist Stock Item\" als \"Nein\" und \"Ist Vertrieb Item\" als \"Ja\""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "Grupo global de productos ** ** en otro art\u00edculo **. ** Esto es \u00fatil si usted est\u00e1 empaquetando un cierto ** ** Los productos en un paquete y usted mantiene un balance de los art\u00edculos envasados \u200b\u200b** ** y no el agregado del art\u00edculo **. ** El paquete ** art\u00edculo ** habr\u00e1 "es el tema de" como "No" y "\u00bfSales Item" como "S\u00ed", por ejemplo:. Si usted est\u00e1 vendiendo computadoras port\u00e1tiles y Mochilas por separado y recibir un descuento si el cliente compra a la vez , entonces el ordenador port\u00e1til + Mochila ser\u00e1 una nueva lista de materiales de ventas Item.Note: BOM = Bill de Materiales",
|
||||
"List items that form the package.": "Lista de tareas que forman el paquete.",
|
||||
"Package Items": "Art\u00edculos del embalaje",
|
||||
"Parent Item": "Art\u00edculo principal",
|
||||
"Sales BOM": "Ventas BOM",
|
||||
"Sales BOM Item": "Ventas de art\u00edculo de lista de materiales",
|
||||
"Sales BOM Items": "Los productos que la lista de materiales de ventas",
|
||||
"Stock": "Valores",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "El punto que representa el paquete. Este elemento debe tener "es el tema de" como "No" y "\u00bfSales Item" como "S\u00ed""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "Groupe global de ** ** Articles dans un autre article **. ** Ceci est utile si vous mettez en place un certains articles ** ** dans un paquet et vous maintenir le stock des articles emball\u00e9s ** ** et non pas le total ** Article **. Le paquet ** ** Point aura \u00abEst Produit en stock" comme "No" et "Est Point de vente" que "Oui" Par exemple:. Si vous vendez des ordinateurs portables et sacs \u00e0 dos s\u00e9par\u00e9ment et un prix sp\u00e9cial si le client ach\u00e8te \u00e0 la fois , puis l'ordinateur portable Sac \u00e0 dos + sera une nouvelle nomenclature des ventes Item.Note: BOM = Bill of Materials",
|
||||
"List items that form the package.": "Liste des articles qui composent le paquet.",
|
||||
"Package Items": "Articles paquet",
|
||||
"Parent Item": "Article Parent",
|
||||
"Sales BOM": "BOM ventes",
|
||||
"Sales BOM Item": "Article nomenclature des ventes",
|
||||
"Sales BOM Items": "Articles ventes de nomenclature",
|
||||
"Stock": "Stock",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "L'article qui repr\u00e9sente le package. Cet article doit avoir \u00abEst Produit en stock" comme "No" et "Est Point de vente" que "Oui""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "** \u0906\u0907\u091f\u092e \u0915\u0947 \u0938\u0915\u0932 \u0938\u092e\u0942\u0939 \u092e\u0947\u0902 \u090f\u0915 \u0914\u0930 \u0906\u0907\u091f\u092e ** **. \u092f\u0939 \u0909\u092a\u092f\u094b\u0917\u0940 \u0939\u0948 \u0905\u0917\u0930 \u0906\u092a \u090f\u0915 \u092a\u0948\u0915\u0947\u091c \u092e\u0947\u0902 ** \u0915\u0941\u091b ** \u0906\u0907\u091f\u092e bundling \u0939\u0948\u0902 \u0914\u0930 \u0906\u092a \u092a\u0948\u0915 ** \u0914\u0930 \u0928\u0939\u0940\u0902 \u0915\u0941\u0932 ** \u0906\u0907\u091f\u092e ** ** \u0906\u0907\u091f\u092e \u0915\u0947 \u0938\u094d\u091f\u0949\u0915 \u0915\u094b \u092c\u0928\u093e\u090f \u0930\u0916\u0928\u0947. \u092a\u0948\u0915\u0947\u091c ** \u0906\u0907\u091f\u092e ** \u0939\u0948 "\u0938\u094d\u091f\u0949\u0915 \u0906\u0907\u091f\u092e \u0939\u0948" "\u0928\u0939\u0940\u0902" \u0915\u0947 \u0930\u0942\u092a \u092e\u0947\u0902 \u0914\u0930 \u0915\u0947 \u0930\u0942\u092a \u092e\u0947\u0902 "\u0939\u093e\u0901" "\u092c\u093f\u0915\u094d\u0930\u0940 \u0906\u0907\u091f\u092e \u0939\u0948," \u0909\u0926\u093e\u0939\u0930\u0923 \u0915\u0947 \u0932\u093f\u090f: \u092f\u0926\u093f \u0906\u092a \u0932\u0948\u092a\u091f\u0949\u092a \u0914\u0930 Backpacks \u092c\u0947\u091a \u0930\u0939\u0947 \u0939\u0948\u0902 \u0914\u0930 \u0905\u0932\u0917 \u0938\u0947 \u090f\u0915 \u0935\u093f\u0936\u0947\u0937 \u092e\u0942\u0932\u094d\u092f \u0939\u0948 \u0905\u0917\u0930 \u0917\u094d\u0930\u093e\u0939\u0915 \u0926\u094b\u0928\u094b\u0902 \u0916\u0930\u0940\u0926\u0924\u093e BOM = \u0935\u093f\u0927\u0947\u092f\u0915 \u0915\u0940 \u0938\u093e\u092e\u0917\u094d\u0930\u0940:, \u0924\u094b \u090f\u0915 \u0928\u092f\u093e \u0932\u0948\u092a\u091f\u0949\u092a + \u092c\u0948\u0917 \u092c\u093f\u0915\u094d\u0930\u0940 \u092c\u0940\u0913\u090f\u092e Item.Note \u0939\u094b\u0917\u093e",
|
||||
"List items that form the package.": "\u0938\u0942\u091a\u0940 \u0906\u0907\u091f\u092e \u0939\u0948 \u0915\u093f \u092a\u0948\u0915\u0947\u091c \u0915\u093e \u092b\u093e\u0930\u094d\u092e.",
|
||||
"Package Items": "\u092a\u0948\u0915\u0947\u091c \u0906\u0907\u091f\u092e",
|
||||
"Parent Item": "\u092e\u0942\u0932 \u0906\u0907\u091f\u092e",
|
||||
"Sales BOM": "\u092c\u093f\u0915\u094d\u0930\u0940 \u092c\u0940\u0913\u090f\u092e",
|
||||
"Sales BOM Item": "\u092c\u093f\u0915\u094d\u0930\u0940 \u092c\u0940\u0913\u090f\u092e \u0906\u0907\u091f\u092e",
|
||||
"Sales BOM Items": "\u092c\u093f\u0915\u094d\u0930\u0940 \u092c\u0940\u0913\u090f\u092e \u0906\u0907\u091f\u092e",
|
||||
"Stock": "\u0938\u094d\u091f\u0949\u0915",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "\u0906\u0907\u091f\u092e \u0939\u0948 \u0915\u093f \u092a\u0948\u0915\u0947\u091c \u0915\u093e \u092a\u094d\u0930\u0924\u093f\u0928\u093f\u0927\u093f\u0924\u094d\u0935 \u0915\u0930\u0924\u093e \u0939\u0948. \u0907\u0938 \u092e\u0926 "\u0938\u094d\u091f\u0949\u0915 \u0906\u0907\u091f\u092e" "\u0928\u0939\u0940\u0902" \u0915\u0947 \u0930\u0942\u092a \u092e\u0947\u0902 \u0914\u0930 \u0915\u0947 \u0930\u0942\u092a \u092e\u0947\u0902 "\u0939\u093e\u0901" "\u092c\u093f\u0915\u094d\u0930\u0940 \u0906\u0907\u091f\u092e \u0939\u0948""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "Agregat skupina ** stavki ** u drugoj to\u010dki ** **. To je korisno ako ste vezanje odre\u0111ene artikle ** ** u paketu i odr\u017eavanje zalihe pakiran ** stavki ** a ne agregata ** artikla **. Paket ** artikla ** \u0107e "Je katalo\u0161ki Stavka" kao "Ne" i "Je li prodaja artikla" kao "Da", na primjer:. Ako prodajete Prijenosna ra\u010dunala i Ruksaci odvojeno i imaju posebnu cijenu ako kupac kupuje oboje , onda laptop + ruksak \u0107e biti novi Prodaja BOM Item.Note: BOM = Bill materijala",
|
||||
"List items that form the package.": "Popis stavki koje \u010dine paket.",
|
||||
"Package Items": "Paket Proizvodi",
|
||||
"Parent Item": "Roditelj artikla",
|
||||
"Sales BOM": "Prodaja BOM",
|
||||
"Sales BOM Item": "Prodaja BOM artikla",
|
||||
"Sales BOM Items": "Prodaja BOM Proizvodi",
|
||||
"Stock": "Zaliha",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "Stavka koja predstavlja paket. Ova stavka mora imati "Je katalo\u0161ki Stavka" kao "Ne" i "Je li prodaja artikla" kao "Da""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "De totale groep van ** Items ** in een andere ** Item **. Dit is handig als u de bundeling van een bepaalde ** Items ** in een pakket en u onderhoudt voorraad van de verpakte ** Items ** en niet de totale ** Item **. Het pakket ** Item ** zal hebben "Is Stock Item" als "No" en "Is Sales Item" als "Ja" Bijvoorbeeld:. Als je verkoopt laptops en Rugzakken apart en hebben een speciale prijs als de klant koopt zowel , dan is de laptop + Rugzak zal een nieuwe Sales BOM Item.Note: BOM = Bill of Materials",
|
||||
"List items that form the package.": "Lijst items die het pakket vormen.",
|
||||
"Package Items": "Pakket Artikelen",
|
||||
"Parent Item": "Parent Item",
|
||||
"Sales BOM": "Verkoop BOM",
|
||||
"Sales BOM Item": "Verkoop BOM Item",
|
||||
"Sales BOM Items": "Verkoop BOM Items",
|
||||
"Stock": "Voorraad",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "Het item dat het pakket vertegenwoordigt. Dit artikel moet hebben "Is Stock Item" als "No" en "Is Sales Item" als "Yes""
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"List items that form the package.": "Lista de itens que comp\u00f5em o pacote.",
|
||||
"Package Items": "Itens do pacote",
|
||||
"Parent Item": "Item Pai",
|
||||
"Sales BOM": "LDM de Vendas",
|
||||
"Sales BOM Item": "Item da LDM de Vendas",
|
||||
"Sales BOM Items": "Itens da LDM de Vendas",
|
||||
"Stock": "Estoque",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "O item que representa o pacote. Este item deve ter "\u00c9 Item de Estoque" como "N\u00e3o" e "\u00c9 Item de Venda" como "Sim""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "Grupo agregado de Itens ** ** em outro item **. ** Isso \u00e9 \u00fatil se voc\u00ea est\u00e1 empacotando um certo ** ** Itens em um pacote e voc\u00ea manter o estoque dos itens embalados ** ** e n\u00e3o agregar o item **. ** O pacote ** ** item ter\u00e1 "\u00e9 o item da" como "N\u00e3o" e "\u00e9 o item de vendas" como "Sim", por exemplo:. Se voc\u00ea est\u00e1 vendendo laptops e mochilas separadamente e t\u00eam um pre\u00e7o especial se o cliente compra tanto , ent\u00e3o o Laptop Backpack + ser\u00e1 uma nova Vendas BOM Item.Note: BOM = Bill of Materials",
|
||||
"List items that form the package.": "Lista de itens que comp\u00f5em o pacote.",
|
||||
"Package Items": "Itens do pacote",
|
||||
"Parent Item": "Item Pai",
|
||||
"Sales BOM": "BOM vendas",
|
||||
"Sales BOM Item": "Vendas item BOM",
|
||||
"Sales BOM Items": "Vendas Itens BOM",
|
||||
"Stock": "Estoque",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "O item que representa o pacote. Este item deve ter "\u00e9 o item da" como "N\u00e3o" e "\u00e9 o item de vendas" como "Sim""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "\u0410\u0433\u0440\u0435\u0433\u0430\u0442 \u0433\u0440\u0443\u043f\u0430 ** ** \u0458\u0435\u0434\u0438\u043d\u0438\u0446\u0435 \u0443 \u0434\u0440\u0443\u0433\u0443 ** ** \u0442\u0430\u0447\u043a\u0435. \u041e\u0432\u043e \u0458\u0435 \u043a\u043e\u0440\u0438\u0441\u043d\u043e \u0430\u043a\u043e \u0441\u0442\u0435 \u0433\u0440\u0443\u043f\u0438\u0441\u0430\u045a\u0435 \u043e\u0434\u0440\u0435\u0452\u0435\u043d\u0435 \u0441\u0442\u0430\u0432\u043a\u0435 ** ** \u0443 \u043f\u0430\u043a\u0435\u0442\u0443 \u0438 \u0434\u0430 \u043e\u0434\u0440\u0436\u0438 \u0437\u0430\u043b\u0438\u0445\u0435 \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u0438\u0445 ** ** \u0441\u0442\u0430\u0432\u043a\u0438, \u0430 \u043d\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442 ** ** \u0442\u0430\u0447\u043a\u0430. \u041f\u0430\u043a\u0435\u0442 ** ** \u0448\u0438\u0444\u0440\u0430 \u045b\u0435 "\u0414\u0430 \u043b\u0438 \u0458\u0435 \u0431\u0435\u0440\u0437\u0430 \u0421\u0442\u0430\u0432\u043a\u0430" \u043a\u0430\u043e "\u043d\u0435" \u0438 "\u0414\u0430 \u043b\u0438 \u0458\u0435 \u043f\u0440\u043e\u0434\u0430\u0458\u0435 \u0421\u0442\u0430\u0432\u043a\u0430" \u043a\u0430\u043e "\u0414\u0430" \u0417\u0430 \u041f\u0440\u0438\u043c\u0435\u0440: \u0410\u043a\u043e \u0441\u0435 \u043f\u0440\u043e\u0434\u0430\u0458\u0435 \u043b\u0430\u043f\u0442\u043e\u043f \u0438 \u0440\u0430\u043d\u0447\u0435\u0432\u0438 \u043e\u0434\u0432\u043e\u0458\u0435\u043d\u043e \u0438 \u0438\u043c\u0430\u0458\u0443 \u043f\u043e\u0441\u0435\u0431\u043d\u0443 \u0446\u0435\u043d\u0443 \u0443\u043a\u043e\u043b\u0438\u043a\u043e \u043a\u0443\u043f\u0430\u0446 \u043a\u0443\u043f\u0443\u0458\u0435 \u043e\u0431\u043e\u0458\u0435. , \u043e\u043d\u0434\u0430 \u043b\u0430\u043f\u0442\u043e\u043f + \u0420\u0430\u043d\u0430\u0446 \u045b\u0435 \u0431\u0438\u0442\u0438 \u043d\u043e\u0432\u0438 \u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0411\u041e\u041c \u0418\u0442\u0435\u043c.\u041d\u043e\u0442\u0435: \u0411\u041e\u041c = \u0421\u0430\u0441\u0442\u0430\u0432\u043d\u0438\u0446\u0435",
|
||||
"List items that form the package.": "\u041b\u0438\u0441\u0442\u0430 \u0441\u0442\u0432\u0430\u0440\u0438 \u043a\u043e\u0458\u0435 \u0447\u0438\u043d\u0435 \u043f\u0430\u043a\u0435\u0442.",
|
||||
"Package Items": "\u041f\u0430\u043a\u0435\u0442 \u0410\u0440\u0442\u0438\u043a\u043b\u0438",
|
||||
"Parent Item": "\u0420\u043e\u0434\u0438\u0442\u0435\u0459 \u0448\u0438\u0444\u0440\u0430",
|
||||
"Sales BOM": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0411\u041e\u041c",
|
||||
"Sales BOM Item": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0411\u041e\u041c \u0448\u0438\u0444\u0440\u0430",
|
||||
"Sales BOM Items": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0411\u041e\u041c \u0410\u0440\u0442\u0438\u043a\u043b\u0438",
|
||||
"Stock": "\u0417\u0430\u043b\u0438\u0445\u0430",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "\u0421\u0442\u0430\u0432\u043a\u0430 \u043a\u043e\u0458\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0459\u0430 \u043f\u0430\u043a\u0435\u0442. \u041e\u0432\u0430 \u0442\u0430\u0447\u043a\u0430 \u043c\u043e\u0440\u0430 \u0434\u0430 "\u0417\u0430\u0440 \u0431\u0435\u0440\u0437\u0430 \u0421\u0442\u0430\u0432\u043a\u0430" \u043a\u0430\u043e "\u043d\u0435" \u0438 "\u0414\u0430 \u043b\u0438 \u0458\u0435 \u043f\u0440\u043e\u0434\u0430\u0458\u0435 \u0442\u0430\u0447\u043a\u0430" \u043a\u0430\u043e "\u0414\u0430""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "\u0bae\u0ba4\u0bbf\u0baa\u0bcd\u0baa\u0bc0\u0b9f\u0bcd\u0b9f\u0bc1 ** \u0bb5\u0bbf\u0b9f\u0baf\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0b95\u0bc1\u0bb4\u0bc1 ** \u0bae\u0bb1\u0bcd\u0bb1\u0bc6\u0bbe\u0bb0\u0bc1 ** \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd \u0b95\u0bc6\u0bbe\u0ba3\u0bcd\u0b9f\u0bc1 **. \u0ba8\u0bc0\u0b99\u0bcd\u0b95\u0bb3\u0bcd ** \u0b92\u0bb0\u0bc1 \u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0baa\u0bcd\u0baa\u0bc1 \u0b92\u0bb0\u0bc1 \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bbf\u0b9f\u0bcd\u0b9f ** \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0b9f\u0bcd\u0b95\u0bb3\u0bc8 \u0b92\u0ba9\u0bcd\u0bb1\u0bc1 \u0b95\u0bc2\u0b9f\u0bcd\u0b9f\u0bc1\u0ba4\u0bb2\u0bcd \u0b87\u0bb0\u0bc1\u0ba8\u0bcd\u0ba4\u0bbe\u0bb2\u0bcd \u0b87\u0ba8\u0bcd\u0ba4 \u0baa\u0baf\u0ba9\u0bc1\u0bb3\u0bcd\u0bb3\u0ba4\u0bbe\u0b95 \u0b87\u0bb0\u0bc1\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd \u0ba8\u0bc0\u0b99\u0bcd\u0b95\u0bb3\u0bcd ** \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0bae\u0ba4\u0bbf\u0baa\u0bcd\u0baa\u0bc0\u0b9f\u0bcd\u0b9f\u0bc1 ** \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd ** \u0baa\u0bc7\u0b95\u0bcd ** \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0b9f\u0bcd\u0b95\u0bb3\u0bc8 \u0baa\u0b99\u0bcd\u0b95\u0bc1 \u0bb5\u0bc8\u0ba4\u0bcd\u0ba4\u0bc1. \u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0baa\u0bcd\u0baa\u0bc1 ** \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd ** "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8" \u0b8e\u0ba9 "\u0baa\u0b99\u0bcd\u0b95\u0bc1 \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf \u0b87\u0bb2\u0bcd\u0bb2\u0bc8" \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd "\u0b86\u0bae\u0bcd" \u0b8e\u0ba9 "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bbe\u0b95 \u0b89\u0bb3\u0bcd\u0bb3\u0ba4\u0bc1" \u0b89\u0ba4\u0bbe\u0bb0\u0ba3\u0bae\u0bbe\u0b95:. \u0ba8\u0bc0\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0ba4\u0ba9\u0bbf\u0baf\u0bbe\u0b95 \u0bae\u0b9f\u0bbf\u0b95\u0bcd\u0b95\u0ba3\u0bbf\u0ba9\u0bbf\u0b95\u0bb3\u0bcd \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0bae\u0bc1\u0ba4\u0bc1\u0b95\u0bbf\u0bb2\u0bcd \u0b9a\u0bc1\u0bae\u0bc8 \u0baa\u0bc8\u0baf\u0bc1\u0b9f\u0ba9\u0bc1\u0bae\u0bcd \u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b92\u0bb0\u0bc1 \u0b9a\u0bbf\u0bb1\u0baa\u0bcd\u0baa\u0bc1 \u0bb5\u0bbf\u0bb2\u0bc8 \u0b87\u0bb2\u0bcd\u0bb2\u0bc8 \u0b8e\u0ba9\u0bcd\u0bb1\u0bbe\u0bb2\u0bcd \u0bb5\u0bbe\u0b9f\u0bbf\u0b95\u0bcd\u0b95\u0bc8\u0baf\u0bbe\u0bb3\u0bb0\u0bcd \u0b87\u0bb0\u0bc1 \u0bb5\u0bbe\u0b99\u0bcd\u0b95\u0bc1\u0bae\u0bcd \u0baa\u0bc7\u0bbe\u0ba4\u0bc1 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0b9f\u0bcd\u0b95\u0bb3\u0bc8 BOM = \u0baa\u0bbf\u0bb2\u0bcd:, \u0baa\u0bbf\u0ba9\u0bcd\u0ba9\u0bb0\u0bcd \u0bb2\u0bc7\u0baa\u0bcd\u0b9f\u0bbe\u0baa\u0bcd + \u0baa\u0bc8\u0baf\u0bc1\u0b9f\u0ba9\u0bc1\u0bae\u0bcd \u0b92\u0bb0\u0bc1 \u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 BOM Item.Note \u0b87\u0bb0\u0bc1\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd",
|
||||
"List items that form the package.": "\u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0baa\u0bcd\u0baa\u0bc1 \u0b85\u0bae\u0bc8\u0b95\u0bcd\u0b95 \u0b8e\u0ba9\u0bcd\u0bb1\u0bc1 \u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0b95\u0bb3\u0bcd.",
|
||||
"Package Items": "\u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0baa\u0bcd\u0baa\u0bc1 \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",
|
||||
"Parent Item": "\u0baa\u0bc6\u0bb1\u0bcd\u0bb1\u0bc7\u0bbe\u0bb0\u0bcd \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd",
|
||||
"Sales BOM": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 BOM",
|
||||
"Sales BOM Item": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 BOM \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd",
|
||||
"Sales BOM Items": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 BOM \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0b95\u0bb3\u0bcd",
|
||||
"Stock": "\u0baa\u0b99\u0bcd\u0b95\u0bc1",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "\u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0baa\u0bcd\u0baa\u0bc1 \u0baa\u0bbf\u0bb0\u0ba4\u0bbf\u0baa\u0bb2\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb1\u0ba4\u0bc1 \u0b8e\u0ba9\u0bcd\u0bb1\u0bc1 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd. \u0b87\u0ba8\u0bcd\u0ba4 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8" \u0b8e\u0ba9 "\u0baa\u0b99\u0bcd\u0b95\u0bc1 \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf \u0b87\u0bb2\u0bcd\u0bb2\u0bc8" \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd "\u0b86\u0bae\u0bcd" \u0b8e\u0ba9 "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd \u0b87\u0bb2\u0bcd\u0bb2\u0bc8""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. The package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".For Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.Note: BOM = Bill of Materials": "\u0e01\u0e25\u0e38\u0e48\u0e21\u0e23\u0e27\u0e21\u0e02\u0e2d\u0e07\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 ** ** \u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\u0e2d\u0e35\u0e01\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 ** ** \u0e19\u0e35\u0e49\u0e08\u0e30\u0e40\u0e1b\u0e47\u0e19\u0e1b\u0e23\u0e30\u0e42\u0e22\u0e0a\u0e19\u0e4c\u0e16\u0e49\u0e32\u0e04\u0e38\u0e13\u0e01\u0e33\u0e25\u0e31\u0e07 bundling \u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 ** ** \u0e1a\u0e32\u0e07\u0e40\u0e1b\u0e47\u0e19\u0e41\u0e1e\u0e04\u0e40\u0e01\u0e08\u0e41\u0e25\u0e30\u0e04\u0e38\u0e13\u0e23\u0e31\u0e01\u0e29\u0e32\u0e2a\u0e15\u0e47\u0e2d\u0e01\u0e02\u0e2d\u0e07\u0e1a\u0e23\u0e23\u0e08\u0e38\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 ** ** \u0e41\u0e25\u0e30\u0e44\u0e21\u0e48\u0e23\u0e27\u0e21\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 ** ** \u0e41\u0e1e\u0e04\u0e40\u0e01\u0e08\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32 ** ** \u0e08\u0e30\u0e21\u0e35 "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32" \u0e02\u0e13\u0e30\u0e17\u0e35\u0e48 "\u0e44\u0e21\u0e48\u0e21\u0e35" \u0e41\u0e25\u0e30 "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22" \u0e40\u0e1b\u0e47\u0e19 "\u0e43\u0e0a\u0e48" \u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07:. \u0e16\u0e49\u0e32\u0e04\u0e38\u0e13\u0e01\u0e33\u0e25\u0e31\u0e07\u0e02\u0e32\u0e22\u0e41\u0e25\u0e47\u0e1b\u0e17\u0e47\u0e2d\u0e1b\u0e41\u0e25\u0e30\u0e40\u0e1b\u0e49\u0e2a\u0e30\u0e1e\u0e32\u0e22\u0e2b\u0e25\u0e31\u0e07\u0e41\u0e22\u0e01\u0e41\u0e25\u0e30\u0e21\u0e35\u0e23\u0e32\u0e04\u0e32\u0e1e\u0e34\u0e40\u0e28\u0e29\u0e2b\u0e32\u0e01\u0e25\u0e39\u0e01\u0e04\u0e49\u0e32\u0e0b\u0e37\u0e49\u0e2d\u0e17\u0e31\u0e49\u0e07 \u0e41\u0e25\u0e49\u0e27\u0e41\u0e25\u0e47\u0e1b\u0e17\u0e47\u0e2d\u0e1b\u0e01\u0e23\u0e30\u0e40\u0e1b\u0e4b\u0e32\u0e40\u0e1b\u0e49\u0e2a\u0e30\u0e1e\u0e32\u0e22\u0e2b\u0e25\u0e31\u0e07 + \u0e08\u0e30\u0e02\u0e32\u0e22\u0e43\u0e2b\u0e21\u0e48 BOM Item.Note: BOM \u0e1a\u0e34\u0e25\u0e02\u0e2d\u0e07\u0e27\u0e31\u0e2a\u0e14\u0e38 =",
|
||||
"List items that form the package.": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e41\u0e1e\u0e04\u0e40\u0e01\u0e08",
|
||||
"Package Items": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e41\u0e1e\u0e04\u0e40\u0e01\u0e08",
|
||||
"Parent Item": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2b\u0e25\u0e31\u0e01",
|
||||
"Sales BOM": "BOM \u0e02\u0e32\u0e22",
|
||||
"Sales BOM Item": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 BOM \u0e02\u0e32\u0e22",
|
||||
"Sales BOM Items": "\u0e02\u0e32\u0e22\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32 BOM",
|
||||
"Stock": "\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32",
|
||||
"The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e41\u0e2a\u0e14\u0e07\u0e16\u0e36\u0e07\u0e41\u0e1e\u0e04\u0e40\u0e01\u0e08 \u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e19\u0e35\u200b\u200b\u0e49\u0e08\u0e30\u0e15\u0e49\u0e2d\u0e07\u0e21\u0e35 "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32" \u0e02\u0e13\u0e30\u0e17\u0e35\u0e48 "\u0e44\u0e21\u0e48\u0e21\u0e35" \u0e41\u0e25\u0e30 "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22" \u0e40\u0e1b\u0e47\u0e19 "\u0e43\u0e0a\u0e48""
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.toggle_enable('new_item_code', doc.__islocal);
|
||||
if(!doc.__islocal) {
|
||||
cur_frm.add_custom_button("Check for Duplicates", function() {
|
||||
cur_frm.call_server('check_duplicate', 1)
|
||||
}, 'icon-search')
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.new_item_code.get_query = function() {
|
||||
return 'select name, description from tabItem where is_stock_item="No" and is_sales_item="Yes"\
|
||||
and name not in (select name from `tabSales BOM`)\
|
||||
and `%(key)s` like "%s"'
|
||||
}
|
||||
cur_frm.fields_dict.new_item_code.query_description = 'Select Item where "Is Stock Item" is "No" \
|
||||
and "Is Sales Item" is "Yes" and there is no other Sales BOM';
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, dt, dn) {
|
||||
var d = locals[dt][dn];
|
||||
if (d.item_code){
|
||||
get_server_fields('get_item_details', d.item_code, 'sales_bom_items', doc ,dt, dn, 1);
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt
|
||||
from webnotes.model.utils import getlist
|
||||
|
||||
class DocType:
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
def autoname(self):
|
||||
self.doc.name = self.doc.new_item_code
|
||||
|
||||
def validate(self):
|
||||
# check for duplicate
|
||||
self.check_duplicate()
|
||||
self.validate_main_item()
|
||||
|
||||
def validate_main_item(self):
|
||||
"""main item must have Is Stock Item as No and Is Sales Item as Yes"""
|
||||
if not webnotes.conn.sql("""select name from tabItem where name=%s and
|
||||
ifnull(is_stock_item,'')='No' and ifnull(is_sales_item,'')='Yes'""", self.doc.new_item_code):
|
||||
webnotes.msgprint("""Parent Item %s is either a Stock Item or a not a Sales Item""",
|
||||
raise_exception=1)
|
||||
|
||||
def get_item_details(self, name):
|
||||
det = webnotes.conn.sql("""select description, stock_uom from `tabItem`
|
||||
where name = %s""", name)
|
||||
rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||
where price_list_name = %s and parent = %s
|
||||
and ref_currency = %s""", (self.doc.price_list, name, self.doc.currency))
|
||||
return {
|
||||
'description' : det and det[0][0] or '',
|
||||
'uom': det and det[0][1] or '',
|
||||
'rate': rate and flt(rate[0][0]) or 0.00
|
||||
}
|
||||
|
||||
def check_duplicate(self, finder=0):
|
||||
il = getlist(self.doclist, "sales_bom_items")
|
||||
if not il:
|
||||
webnotes.msgprint("Add atleast one item")
|
||||
return
|
||||
|
||||
# get all Sales BOM that have the first item
|
||||
sbl = webnotes.conn.sql("""select distinct parent from `tabSales BOM Item` where item_code=%s
|
||||
and parent != %s and docstatus != 2""", (il[0].item_code, self.doc.name))
|
||||
|
||||
# check all siblings
|
||||
sub_items = [[d.item_code, flt(d.qty)] for d in il]
|
||||
|
||||
for s in sbl:
|
||||
t = webnotes.conn.sql("""select item_code, qty from `tabSales BOM Item` where parent=%s and
|
||||
docstatus != 2""", s[0])
|
||||
t = [[d[0], flt(d[1])] for d in t]
|
||||
|
||||
if self.has_same_items(sub_items, t):
|
||||
webnotes.msgprint("%s has the same Sales BOM details" % s[0])
|
||||
raise Exception
|
||||
if finder:
|
||||
webnotes.msgprint("There is no Sales BOM present with the following Combination.")
|
||||
|
||||
def has_same_items(self, l1, l2):
|
||||
if len(l1)!=len(l2): return 0
|
||||
for l in l2:
|
||||
if l not in l1:
|
||||
return 0
|
||||
for l in l1:
|
||||
if l not in l2:
|
||||
return 0
|
||||
return 1
|
||||
@@ -1,97 +0,0 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-10 16:34:29",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-01-22 14:57:23",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"description": "Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**. \n\nThe package **Item** will have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\".\n\nFor Example: If you are selling Laptops and Backpacks separately and have a special price if the customer buys both, then the Laptop + Backpack will be a new Sales BOM Item.\n\nNote: BOM = Bill of Materials",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"is_submittable": 0,
|
||||
"module": "Stock",
|
||||
"name": "__common__"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"name": "__common__",
|
||||
"parent": "Sales BOM",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"doctype": "DocPerm",
|
||||
"name": "__common__",
|
||||
"parent": "Sales BOM",
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"submit": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"name": "Sales BOM"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "basic_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sales BOM Item"
|
||||
},
|
||||
{
|
||||
"description": "The Item that represents the Package. This Item must have \"Is Stock Item\" as \"No\" and \"Is Sales Item\" as \"Yes\"",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "new_item_code",
|
||||
"fieldtype": "Link",
|
||||
"label": "Parent Item",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "new_item_code",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"description": "List items that form the package.",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Package Items"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sales_bom_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Sales BOM Items",
|
||||
"oldfieldname": "sales_bom_items",
|
||||
"oldfieldtype": "Table",
|
||||
"options": "Sales BOM Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Material Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Sales User",
|
||||
"write": 1
|
||||
}
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
test_records = [
|
||||
[
|
||||
{
|
||||
"doctype": "Sales BOM",
|
||||
"new_item_code": "_Test Sales BOM Item"
|
||||
},
|
||||
{
|
||||
"doctype": "Sales BOM Item",
|
||||
"item_code": "_Test Item",
|
||||
"parentfield": "sales_bom_items",
|
||||
"qty": 5.0
|
||||
},
|
||||
{
|
||||
"doctype": "Sales BOM Item",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"parentfield": "sales_bom_items",
|
||||
"qty": 2.0
|
||||
}
|
||||
],
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -1,9 +0,0 @@
|
||||
[
|
||||
"Description",
|
||||
"Item",
|
||||
"Qty",
|
||||
"Sales BOM Item",
|
||||
"Rate",
|
||||
"UOM",
|
||||
"Stock"
|
||||
]
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "\u0648\u0635\u0641",
|
||||
"Item": "\u0628\u0646\u062f",
|
||||
"Qty": "\u0627\u0644\u0643\u0645\u064a\u0629",
|
||||
"Rate": "\u0645\u0639\u062f\u0644",
|
||||
"Sales BOM Item": "\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0633\u0644\u0639\u0629 BOM",
|
||||
"Stock": "\u0627\u0644\u0623\u0648\u0631\u0627\u0642 \u0627\u0644\u0645\u0627\u0644\u064a\u0629",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Beschreibung",
|
||||
"Item": "Artikel",
|
||||
"Qty": "Menge",
|
||||
"Rate": "Rate",
|
||||
"Sales BOM Item": "Vertrieb St\u00fccklistenposition",
|
||||
"Stock": "Lager",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Descripci\u00f3n",
|
||||
"Item": "Art\u00edculo",
|
||||
"Qty": "Cantidad",
|
||||
"Rate": "Velocidad",
|
||||
"Sales BOM Item": "Ventas de art\u00edculo de lista de materiales",
|
||||
"Stock": "Valores",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Description",
|
||||
"Item": "Article",
|
||||
"Qty": "Qt\u00e9",
|
||||
"Rate": "Taux",
|
||||
"Sales BOM Item": "Article nomenclature des ventes",
|
||||
"Stock": "Stock",
|
||||
"UOM": "Emballage"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "\u0935\u093f\u0935\u0930\u0923",
|
||||
"Item": "\u092e\u0926",
|
||||
"Qty": "\u092e\u093e\u0924\u094d\u0930\u093e",
|
||||
"Rate": "\u0926\u0930",
|
||||
"Sales BOM Item": "\u092c\u093f\u0915\u094d\u0930\u0940 \u092c\u0940\u0913\u090f\u092e \u0906\u0907\u091f\u092e",
|
||||
"Stock": "\u0938\u094d\u091f\u0949\u0915",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Opis",
|
||||
"Item": "Stavka",
|
||||
"Qty": "Kol",
|
||||
"Rate": "Stopa",
|
||||
"Sales BOM Item": "Prodaja BOM artikla",
|
||||
"Stock": "Zaliha",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Beschrijving",
|
||||
"Item": "Item",
|
||||
"Qty": "Aantal",
|
||||
"Rate": "Tarief",
|
||||
"Sales BOM Item": "Verkoop BOM Item",
|
||||
"Stock": "Voorraad",
|
||||
"UOM": "Verpakking"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Descri\u00e7\u00e3o",
|
||||
"Item": "Item",
|
||||
"Qty": "Qtde.",
|
||||
"Rate": "Taxa",
|
||||
"Sales BOM Item": "Item da LDM de Vendas",
|
||||
"Stock": "Estoque",
|
||||
"UOM": "UDM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "Descri\u00e7\u00e3o",
|
||||
"Item": "Item",
|
||||
"Qty": "Qty",
|
||||
"Rate": "Taxa",
|
||||
"Sales BOM Item": "Vendas item BOM",
|
||||
"Stock": "Estoque",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "\u041e\u043f\u0438\u0441",
|
||||
"Item": "\u0421\u0442\u0430\u0432\u043a\u0430",
|
||||
"Qty": "\u041a\u043e\u043b",
|
||||
"Rate": "\u0421\u0442\u043e\u043f\u0430",
|
||||
"Sales BOM Item": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0411\u041e\u041c \u0448\u0438\u0444\u0440\u0430",
|
||||
"Stock": "\u0417\u0430\u043b\u0438\u0445\u0430",
|
||||
"UOM": "\u0423\u041e\u041c"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "\u0bb5\u0bbf\u0bb3\u0b95\u0bcd\u0b95\u0bae\u0bcd",
|
||||
"Item": "\u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf",
|
||||
"Qty": "\u0b85\u0bb3\u0bb5\u0bc1",
|
||||
"Rate": "\u0bb5\u0bbf\u0bb2\u0bc8",
|
||||
"Sales BOM Item": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 BOM \u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0bb3\u0bcd",
|
||||
"Stock": "\u0baa\u0b99\u0bcd\u0b95\u0bc1",
|
||||
"UOM": "\u0bae\u0bc6\u0bbe\u0bb1\u0b9f\u0bcd\u0b9f\u0bc1\u0bb5 \u0baa\u0bb2\u0bcd\u0b95\u0bb2\u0bc8\u0b95\u0bb4\u0b95\u0bae\u0bcd"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"Description": "\u0e25\u0e31\u0e01\u0e29\u0e13\u0e30",
|
||||
"Item": "\u0e0a\u0e34\u0e49\u0e19",
|
||||
"Qty": "\u0e08\u0e33\u0e19\u0e27\u0e19",
|
||||
"Rate": "\u0e2d\u0e31\u0e15\u0e23\u0e32",
|
||||
"Sales BOM Item": "\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23 BOM \u0e02\u0e32\u0e22",
|
||||
"Stock": "\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32",
|
||||
"UOM": "UOM"
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-22 01:28:03",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-07 07:03:30",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"istable": 1,
|
||||
"module": "Stock",
|
||||
"name": "__common__"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"name": "__common__",
|
||||
"parent": "Sales BOM Item",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"name": "Sales BOM Item"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item",
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Qty",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
"print_width": "300px",
|
||||
"width": "300px"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Float",
|
||||
"label": "Rate",
|
||||
"oldfieldname": "rate",
|
||||
"oldfieldtype": "Currency"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "UOM",
|
||||
"oldfieldname": "uom",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "UOM",
|
||||
"read_only": 1,
|
||||
"search_index": 0
|
||||
}
|
||||
]
|
||||
@@ -19,7 +19,7 @@ import webnotes
|
||||
|
||||
from webnotes.utils import cint, getdate, nowdate
|
||||
import datetime
|
||||
from webnotes import msgprint
|
||||
from webnotes import msgprint, _
|
||||
|
||||
from controllers.stock_controller import StockController
|
||||
|
||||
@@ -117,8 +117,11 @@ class DocType(StockController):
|
||||
self.make_stock_ledger_entry(1)
|
||||
self.make_gl_entries()
|
||||
|
||||
def on_rename(self, new, old):
|
||||
def on_rename(self, new, old, merge=False):
|
||||
"""rename serial_no text fields"""
|
||||
if merge:
|
||||
msgprint(_("Sorry. Serial Nos. cannot be merged"), raise_exception=True)
|
||||
|
||||
for dt in webnotes.conn.sql("""select parent from tabDocField
|
||||
where fieldname='serial_no' and fieldtype='Text'"""):
|
||||
|
||||
@@ -139,7 +142,8 @@ class DocType(StockController):
|
||||
gl_entries = self.get_gl_entries_for_stock(against_stock_account, self.doc.purchase_rate)
|
||||
|
||||
for entry in gl_entries:
|
||||
entry["posting_date"] = self.doc.purchase_date
|
||||
entry["posting_date"] = self.doc.purchase_date or (self.doc.creation and
|
||||
self.doc.creation.split(' ')[0]) or nowdate()
|
||||
|
||||
if gl_entries:
|
||||
make_gl_entries(gl_entries, cancel)
|
||||
@@ -1,14 +1,14 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-10 16:34:29",
|
||||
"creation": "2013-05-16 10:59:15",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-01-29 16:27:57",
|
||||
"modified": "2013-06-20 11:23:01",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"allow_attach": 1,
|
||||
"allow_rename": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:serial_no",
|
||||
"description": "Distinct unit of an Item",
|
||||
"doctype": "DocType",
|
||||
@@ -32,7 +32,9 @@
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"read": 1
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"submit": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
@@ -43,12 +45,14 @@
|
||||
"fieldname": "details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Details",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"default": "In Store",
|
||||
@@ -75,6 +79,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "serial_no",
|
||||
"oldfieldtype": "Data",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -88,13 +93,15 @@
|
||||
"oldfieldname": "item_code",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -146,12 +153,14 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "purchase_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Purchase Details"
|
||||
"label": "Purchase Details",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -160,7 +169,8 @@
|
||||
"fieldtype": "Select",
|
||||
"label": "Purchase Document Type",
|
||||
"no_copy": 1,
|
||||
"options": "\nPurchase Receipt\nStock Entry"
|
||||
"options": "\nPurchase Receipt\nStock Entry",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -168,7 +178,8 @@
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Purchase Document No",
|
||||
"no_copy": 1
|
||||
"no_copy": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -179,6 +190,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "purchase_date",
|
||||
"oldfieldtype": "Date",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
@@ -188,6 +200,7 @@
|
||||
"fieldtype": "Time",
|
||||
"label": "Incoming Time",
|
||||
"no_copy": 1,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@@ -200,6 +213,7 @@
|
||||
"oldfieldname": "purchase_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
@@ -207,6 +221,7 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break3",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -220,6 +235,7 @@
|
||||
"oldfieldname": "warehouse",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Warehouse",
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -230,7 +246,8 @@
|
||||
"in_filter": 1,
|
||||
"label": "Supplier",
|
||||
"no_copy": 1,
|
||||
"options": "Supplier"
|
||||
"options": "Supplier",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -254,12 +271,14 @@
|
||||
"fieldname": "delivery_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Delivery Details",
|
||||
"oldfieldtype": "Column Break"
|
||||
"oldfieldtype": "Column Break",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break4",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -318,12 +337,14 @@
|
||||
"oldfieldname": "is_cancelled",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nYes\nNo",
|
||||
"read_only": 0,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -378,12 +399,14 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "warranty_amc_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warranty / AMC Details"
|
||||
"label": "Warranty / AMC Details",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break6",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -396,6 +419,7 @@
|
||||
"oldfieldname": "maintenance_status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nUnder Warranty\nOut of Warranty\nUnder AMC\nOut of AMC",
|
||||
"read_only": 0,
|
||||
"search_index": 1,
|
||||
"width": "150px"
|
||||
},
|
||||
@@ -406,12 +430,14 @@
|
||||
"label": "Warranty Period (Days)",
|
||||
"oldfieldname": "warranty_period",
|
||||
"oldfieldtype": "Int",
|
||||
"read_only": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break7",
|
||||
"fieldtype": "Column Break",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
@@ -422,6 +448,7 @@
|
||||
"label": "Warranty Expiry Date",
|
||||
"oldfieldname": "warranty_expiry_date",
|
||||
"oldfieldtype": "Date",
|
||||
"read_only": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
{
|
||||
@@ -432,6 +459,7 @@
|
||||
"label": "AMC Expiry Date",
|
||||
"oldfieldname": "amc_expiry_date",
|
||||
"oldfieldtype": "Date",
|
||||
"read_only": 0,
|
||||
"search_index": 0,
|
||||
"width": "150px"
|
||||
},
|
||||
@@ -439,13 +467,15 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info"
|
||||
"label": "More Info",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "serial_no_details",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Serial No Details"
|
||||
"label": "Serial No Details",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -454,6 +484,7 @@
|
||||
"in_filter": 1,
|
||||
"label": "Company",
|
||||
"options": "link:Company",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -464,6 +495,7 @@
|
||||
"in_filter": 1,
|
||||
"label": "Fiscal Year",
|
||||
"options": "link:Fiscal Year",
|
||||
"read_only": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
@@ -476,15 +508,6 @@
|
||||
"oldfieldtype": "Small Text",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "file_list",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 1,
|
||||
"label": "File List",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sle_exists",
|
||||
@@ -500,21 +523,30 @@
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"report": 1,
|
||||
"role": "Material User",
|
||||
"submit": 0,
|
||||
"role": "System Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Sales User"
|
||||
"role": "Material Master Manager",
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Purchase User"
|
||||
"role": "Material Manager",
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"doctype": "DocPerm",
|
||||
"role": "Accounts User"
|
||||
"role": "Material User",
|
||||
"write": 0
|
||||
}
|
||||
]
|
||||
@@ -57,6 +57,7 @@ class DocType(StockController):
|
||||
self.validate_return_reference_doc()
|
||||
self.validate_with_material_request()
|
||||
self.validate_fiscal_year()
|
||||
self.set_total_amount()
|
||||
|
||||
def on_submit(self):
|
||||
self.update_serial_no(1)
|
||||
@@ -174,6 +175,9 @@ class DocType(StockController):
|
||||
elif self.doc.purpose != "Material Transfer":
|
||||
self.doc.production_order = None
|
||||
|
||||
def set_total_amount(self):
|
||||
self.doc.total_amount = sum([flt(item.amount) for item in self.doclist.get({"parentfield": "mtn_details"})])
|
||||
|
||||
def make_gl_entries(self):
|
||||
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
|
||||
return
|
||||
@@ -194,10 +198,10 @@ class DocType(StockController):
|
||||
total_valuation_amount = 0
|
||||
for item in self.doclist.get({"parentfield": "mtn_details"}):
|
||||
if item.t_warehouse and not item.s_warehouse:
|
||||
total_valuation_amount += flt(item.incoming_rate) * flt(item.transfer_qty)
|
||||
total_valuation_amount += flt(item.incoming_rate, 2) * flt(item.transfer_qty)
|
||||
|
||||
if item.s_warehouse and not item.t_warehouse:
|
||||
total_valuation_amount -= flt(item.incoming_rate) * flt(item.transfer_qty)
|
||||
total_valuation_amount -= flt(item.incoming_rate, 2) * flt(item.transfer_qty)
|
||||
|
||||
return total_valuation_amount
|
||||
|
||||
@@ -220,7 +224,7 @@ class DocType(StockController):
|
||||
if not flt(d.incoming_rate):
|
||||
d.incoming_rate = self.get_incoming_rate(args)
|
||||
|
||||
d.amount = flt(d.qty) * flt(d.incoming_rate)
|
||||
d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
|
||||
|
||||
def get_incoming_rate(self, args):
|
||||
incoming_rate = 0
|
||||
@@ -502,17 +506,13 @@ class DocType(StockController):
|
||||
|
||||
if self.doc.use_multi_level_bom:
|
||||
# get all raw materials with sub assembly childs
|
||||
fl_bom_sa_child_item = sql("""select
|
||||
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,
|
||||
description,stock_uom
|
||||
from ( select distinct fb.name, fb.description, fb.item_code,
|
||||
fb.qty_consumed_per_unit, fb.stock_uom
|
||||
from `tabBOM Explosion Item` fb,`tabItem` it
|
||||
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus<2
|
||||
and fb.parent=%s
|
||||
) a
|
||||
group by item_code, stock_uom""" , (qty, self.doc.bom_no), as_dict=1)
|
||||
fl_bom_sa_child_item = sql("""select fb.item_code,
|
||||
ifnull(sum(fb.qty_consumed_per_unit),0)*%s as qty, fb.description, fb.stock_uom
|
||||
from `tabBOM Explosion Item` fb,`tabItem` it
|
||||
where it.name = fb.item_code and ifnull(it.is_pro_applicable, 'No') = 'No'
|
||||
and ifnull(it.is_sub_contracted_item, 'No') = 'No' and fb.docstatus < 2
|
||||
and fb.parent=%s group by item_code, stock_uom""",
|
||||
(qty, self.doc.bom_no), as_dict=1)
|
||||
|
||||
if fl_bom_sa_child_item:
|
||||
_make_items_dict(fl_bom_sa_child_item)
|
||||
@@ -520,10 +520,10 @@ class DocType(StockController):
|
||||
# Get all raw materials considering multi level BOM,
|
||||
# if multi level bom consider childs of Sub-Assembly items
|
||||
fl_bom_sa_items = sql("""select item_code,
|
||||
ifnull(sum(qty_consumed_per_unit), 0) * '%s' as qty,
|
||||
ifnull(sum(qty_consumed_per_unit), 0) *%s as qty,
|
||||
description, stock_uom from `tabBOM Item`
|
||||
where parent = '%s' and docstatus < 2
|
||||
group by item_code""" % (qty, self.doc.bom_no), as_dict=1)
|
||||
where parent = %s and docstatus < 2
|
||||
group by item_code""", (qty, self.doc.bom_no), as_dict=1)
|
||||
|
||||
if fl_bom_sa_items:
|
||||
_make_items_dict(fl_bom_sa_items)
|
||||
@@ -607,7 +607,7 @@ class DocType(StockController):
|
||||
'voucher_no': self.doc.name,
|
||||
'voucher_detail_no': d.name,
|
||||
'actual_qty': qty,
|
||||
'incoming_rate': flt(d.incoming_rate) or 0,
|
||||
'incoming_rate': flt(d.incoming_rate, 2) or 0,
|
||||
'stock_uom': d.stock_uom,
|
||||
'company': self.doc.company,
|
||||
'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No',
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-03-28 15:56:40",
|
||||
"creation": "2013-04-09 11:43:55",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-29 15:31:42",
|
||||
"modified": "2013-05-09 13:31:00",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -518,6 +518,14 @@
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Amount",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "project_name",
|
||||
@@ -558,6 +566,14 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col5",
|
||||
"fieldtype": "Column Break",
|
||||
"print_width": "50%",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
@@ -576,14 +592,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col5",
|
||||
"fieldtype": "Column Break",
|
||||
"print_width": "50%",
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"doctype": "DocField",
|
||||
|
||||
@@ -21,10 +21,15 @@ class TestStockEntry(unittest.TestCase):
|
||||
st2.insert()
|
||||
st2.submit()
|
||||
|
||||
from stock.utils import reorder_item
|
||||
reorder_item()
|
||||
|
||||
mr_name = webnotes.conn.sql("""select parent from `tabMaterial Request Item`
|
||||
where item_code='_Test Item'""")
|
||||
|
||||
self.assertTrue(mr_name)
|
||||
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def test_warehouse_company_validation(self):
|
||||
from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany
|
||||
@@ -71,7 +76,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
|
||||
def test_material_issue_gl_entry(self):
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
self._clear_stock()
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
mr = webnotes.bean(copy=test_records[0])
|
||||
@@ -111,9 +116,10 @@ class TestStockEntry(unittest.TestCase):
|
||||
)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def test_material_transfer_gl_entry(self):
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
self._clear_stock()
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
|
||||
|
||||
mr = webnotes.bean(copy=test_records[0])
|
||||
@@ -145,6 +151,7 @@ class TestStockEntry(unittest.TestCase):
|
||||
self.assertFalse(gl_entries)
|
||||
|
||||
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
|
||||
# check stock ledger entries
|
||||
@@ -173,6 +180,9 @@ class TestStockEntry(unittest.TestCase):
|
||||
def _clear_stock(self):
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||
webnotes.conn.sql("""delete from `tabBin`""")
|
||||
|
||||
self.old_default_company = webnotes.conn.get_default("company")
|
||||
webnotes.conn.set_default("company", "_Test Company")
|
||||
|
||||
def _insert_material_receipt(self):
|
||||
self._clear_stock()
|
||||
@@ -185,6 +195,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
se2.insert()
|
||||
se2.submit()
|
||||
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
def _get_actual_qty(self):
|
||||
return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item",
|
||||
"warehouse": "_Test Warehouse"}, "actual_qty"))
|
||||
@@ -463,6 +475,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
|
||||
self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
||||
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
return se, pr.doc.name
|
||||
|
||||
def test_over_stock_return(self):
|
||||
@@ -563,6 +577,8 @@ class TestStockEntry(unittest.TestCase):
|
||||
|
||||
self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
||||
|
||||
webnotes.conn.set_default("company", self.old_default_company)
|
||||
|
||||
return se, pr.doc.name
|
||||
|
||||
test_records = [
|
||||
|
||||
@@ -114,7 +114,8 @@ class DocType:
|
||||
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = '', rejected=None):
|
||||
exists = webnotes.conn.sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
|
||||
if is_submit:
|
||||
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
|
||||
if exists and exists[0][2] != 2 and \
|
||||
purpose not in ['Material Transfer', "Material Receipt", 'Sales Return']:
|
||||
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
|
||||
elif exists:
|
||||
s = Document('Serial No', exists and exists[0][0])
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-03-26 06:51:17",
|
||||
"creation": "2013-03-28 10:35:31",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-03-26 08:32:03",
|
||||
"modified": "2013-04-10 13:44:19",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -52,6 +52,7 @@
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Posting Date",
|
||||
"oldfieldname": "reconciliation_date",
|
||||
"oldfieldtype": "Date",
|
||||
@@ -63,6 +64,7 @@
|
||||
"fieldname": "posting_time",
|
||||
"fieldtype": "Time",
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Posting Time",
|
||||
"oldfieldname": "reconciliation_time",
|
||||
"oldfieldtype": "Time",
|
||||
@@ -148,6 +150,7 @@
|
||||
"fieldname": "stock_value_difference",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Stock Value Difference",
|
||||
"print_hide": 1
|
||||
},
|
||||
|
||||
@@ -2,7 +2,8 @@ test_records = [
|
||||
[{
|
||||
"doctype": "Warehouse",
|
||||
"warehouse_name": "_Test Warehouse",
|
||||
"warehouse_type": "_Test Warehouse Type"
|
||||
"warehouse_type": "_Test Warehouse Type",
|
||||
"company": "_Test Company"
|
||||
}],
|
||||
[{
|
||||
"doctype": "Warehouse",
|
||||
|
||||
@@ -95,6 +95,8 @@ erpnext.StockAgeing = erpnext.StockGridReport.extend({
|
||||
|
||||
this.data = [].concat(this._data);
|
||||
|
||||
this.serialized_buying_rates = this.get_serialized_buying_rates();
|
||||
|
||||
$.each(this.data, function(i, d) {
|
||||
me.reset_item_values(d);
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
||||
|
||||
var qty_diff = sl.qty;
|
||||
var value_diff = me.get_value_diff(wh, sl, is_fifo);
|
||||
|
||||
|
||||
if(sl_posting_date < from_date) {
|
||||
item.opening_qty += qty_diff;
|
||||
item.opening_value += value_diff;
|
||||
@@ -146,6 +146,8 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
me.round_item_values(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,6 +197,42 @@ wn.module_page["Stock"] = [
|
||||
route: "query-report/Item-Wise Price List",
|
||||
doctype: "Item"
|
||||
},
|
||||
{
|
||||
"label":wn._("Purchase In Transit"),
|
||||
route: "query-report/Purchase In Transit",
|
||||
},
|
||||
{
|
||||
"label":wn._("Requested Items To Be Transferred"),
|
||||
route: "query-report/Requested Items To Be Transferred",
|
||||
},
|
||||
{
|
||||
"label":wn._("Batch-Wise Balance History"),
|
||||
route: "query-report/Batch-Wise Balance History",
|
||||
},
|
||||
{
|
||||
"label":wn._("Warehouse-Wise Stock Balance"),
|
||||
route: "query-report/Warehouse-Wise Stock Balance",
|
||||
},
|
||||
{
|
||||
"label":wn._("Item Prices"),
|
||||
route: "query-report/Item Prices",
|
||||
|
||||
},
|
||||
{
|
||||
"label":wn._("Itemwise Recommended Reorder Level"),
|
||||
route: "query-report/Itemwise Recommended Reorder Level",
|
||||
doctype: "Item"
|
||||
},
|
||||
{
|
||||
"label":wn._("Delivery Note Trends"),
|
||||
route: "query-report/Delivery Note Trends",
|
||||
doctype: "Delivery Note"
|
||||
},
|
||||
{
|
||||
"label":wn._("Purchase Receipt Trends"),
|
||||
route: "query-report/Purchase Receipt Trends",
|
||||
doctype: "Purchase Receipt"
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
0
stock/report/batch_wise_balance_history/__init__.py
Normal file
0
stock/report/batch_wise_balance_history/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
wn.query_reports["Batch-Wise Balance History"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": "From Date",
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": sys_defaults.year_start_date,
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": "To Date",
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": wn.datetime.get_today()
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
columns = get_columns(filters)
|
||||
item_map = get_item_details(filters)
|
||||
iwb_map = get_item_warehouse_batch_map(filters)
|
||||
|
||||
data = []
|
||||
for item in sorted(iwb_map):
|
||||
for wh in sorted(iwb_map[item]):
|
||||
for batch in sorted(iwb_map[item][wh]):
|
||||
qty_dict = iwb_map[item][wh][batch]
|
||||
data.append([item, item_map[item]["item_name"],
|
||||
item_map[item]["description"], wh, batch,
|
||||
qty_dict.opening_qty, qty_dict.in_qty,
|
||||
qty_dict.out_qty, qty_dict.bal_qty
|
||||
])
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(filters):
|
||||
"""return columns based on filters"""
|
||||
|
||||
columns = ["Item:Link/Item:100"] + ["Item Name::150"] + ["Description::150"] + \
|
||||
["Warehouse:Link/Warehouse:100"] + ["Batch:Link/Batch:100"] + ["Opening Qty::90"] + \
|
||||
["In Qty::80"] + ["Out Qty::80"] + ["Balance Qty::90"]
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if not filters.get("from_date"):
|
||||
webnotes.msgprint("Please enter From Date", raise_exception=1)
|
||||
|
||||
if filters.get("to_date"):
|
||||
conditions += " and posting_date <= '%s'" % filters["to_date"]
|
||||
else:
|
||||
webnotes.msgprint("Please enter To Date", raise_exception=1)
|
||||
|
||||
return conditions
|
||||
|
||||
#get all details
|
||||
def get_stock_ledger_entries(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return webnotes.conn.sql("""select item_code, batch_no, warehouse,
|
||||
posting_date, actual_qty
|
||||
from `tabStock Ledger Entry`
|
||||
where ifnull(is_cancelled, 'No') = 'No' %s order by item_code, warehouse""" %
|
||||
conditions, as_dict=1)
|
||||
|
||||
def get_item_warehouse_batch_map(filters):
|
||||
sle = get_stock_ledger_entries(filters)
|
||||
iwb_map = {}
|
||||
|
||||
for d in sle:
|
||||
iwb_map.setdefault(d.item_code, {}).setdefault(d.warehouse, {})\
|
||||
.setdefault(d.batch_no, webnotes._dict({
|
||||
"opening_qty": 0.0, "in_qty": 0.0, "out_qty": 0.0, "bal_qty": 0.0
|
||||
}))
|
||||
qty_dict = iwb_map[d.item_code][d.warehouse][d.batch_no]
|
||||
if d.posting_date < filters["from_date"]:
|
||||
qty_dict.opening_qty += flt(d.actual_qty)
|
||||
elif d.posting_date >= filters["from_date"] and d.posting_date <= filters["to_date"]:
|
||||
if flt(d.actual_qty) > 0:
|
||||
qty_dict.in_qty += flt(d.actual_qty)
|
||||
else:
|
||||
qty_dict.out_qty += abs(flt(d.actual_qty))
|
||||
|
||||
qty_dict.bal_qty += flt(d.actual_qty)
|
||||
|
||||
return iwb_map
|
||||
|
||||
def get_item_details(filters):
|
||||
item_map = {}
|
||||
for d in webnotes.conn.sql("select name, item_name, description from tabItem", as_dict=1):
|
||||
item_map.setdefault(d.name, d)
|
||||
|
||||
return item_map
|
||||
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-04 11:03:47",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-04 19:32:27",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Batch-Wise Balance History",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Batch-Wise Balance History"
|
||||
}
|
||||
]
|
||||
0
stock/report/delivery_note_trends/__init__.py
Normal file
0
stock/report/delivery_note_trends/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
wn.require("app/js/sales_trends_filters.js");
|
||||
|
||||
wn.query_reports["Delivery Note Trends"] = {
|
||||
filters: get_filters()
|
||||
}
|
||||
@@ -16,7 +16,12 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from controllers.trends import get_columns,get_data
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
def execute(filters=None):
|
||||
if not filters: filters ={}
|
||||
data = []
|
||||
conditions = get_columns(filters, "Delivery Note")
|
||||
data = get_data(filters, conditions)
|
||||
|
||||
return conditions["columns"], data
|
||||
21
stock/report/delivery_note_trends/delivery_note_trends.txt
Normal file
21
stock/report/delivery_note_trends/delivery_note_trends.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-13 18:42:11",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-13 18:42:11",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Delivery Note",
|
||||
"report_name": "Delivery Note Trends",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Delivery Note Trends"
|
||||
}
|
||||
]
|
||||
0
stock/report/item_prices/__init__.py
Normal file
0
stock/report/item_prices/__init__.py
Normal file
150
stock/report/item_prices/item_prices.py
Normal file
150
stock/report/item_prices/item_prices.py
Normal file
@@ -0,0 +1,150 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
columns = get_columns(filters)
|
||||
item_map = get_item_details()
|
||||
pl = get_price_list()
|
||||
last_purchase_rate = get_last_purchase_rate()
|
||||
bom_rate = get_item_bom_rate()
|
||||
val_rate_map = get_valuation_rate()
|
||||
|
||||
precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2
|
||||
|
||||
data = []
|
||||
for item in sorted(item_map):
|
||||
data.append([item, item_map[item]["item_name"],
|
||||
item_map[item]["description"], item_map[item]["stock_uom"],
|
||||
flt(last_purchase_rate.get(item, 0), precision),
|
||||
flt(val_rate_map.get(item, 0), precision),
|
||||
pl.get(item, {}).get("selling"),
|
||||
pl.get(item, {}).get("buying"),
|
||||
flt(bom_rate.get(item, 0), precision),
|
||||
flt(item_map[item]["standard_rate"], precision)
|
||||
])
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(filters):
|
||||
"""return columns based on filters"""
|
||||
|
||||
columns = ["Item:Link/Item:100", "Item Name::150", "Description::150", "UOM:Link/UOM:80",
|
||||
"Last Purchase Rate:Currency:90", "Valuation Rate:Currency:80", "Sales Price List::80",
|
||||
"Purchase Price List::80", "BOM Rate:Currency:90", "Standard Rate:Currency:100"]
|
||||
|
||||
return columns
|
||||
|
||||
def get_item_details():
|
||||
"""returns all items details"""
|
||||
|
||||
item_map = {}
|
||||
|
||||
for i in webnotes.conn.sql("select name, item_name, description, \
|
||||
stock_uom, standard_rate from tabItem \
|
||||
order by item_code", as_dict=1):
|
||||
item_map.setdefault(i.name, i)
|
||||
|
||||
return item_map
|
||||
|
||||
def get_price_list():
|
||||
"""Get selling & buying price list of every item"""
|
||||
|
||||
rate = {}
|
||||
|
||||
price_list = webnotes.conn.sql("""select parent, selling, buying,
|
||||
concat(price_list_name, " - ", ref_currency, " ", ref_rate) as price
|
||||
from `tabItem Price` where docstatus<2""", as_dict=1)
|
||||
|
||||
for j in price_list:
|
||||
if j.price:
|
||||
if j.selling:
|
||||
rate.setdefault(j.parent, {}).setdefault("selling", []).append(j.price)
|
||||
if j.buying:
|
||||
rate.setdefault(j.parent, {}).setdefault("buying", []).append(j.price)
|
||||
|
||||
item_rate_map = {}
|
||||
|
||||
for item in rate:
|
||||
item_rate_map.setdefault(item, {}).setdefault("selling",
|
||||
", ".join(rate[item].get("selling", [])))
|
||||
item_rate_map[item]["buying"] = ", ".join(rate[item].get("buying", []))
|
||||
|
||||
return item_rate_map
|
||||
|
||||
def get_last_purchase_rate():
|
||||
|
||||
item_last_purchase_rate_map = {}
|
||||
|
||||
query = """select * from (select
|
||||
result.item_code,
|
||||
result.purchase_rate
|
||||
from (
|
||||
(select
|
||||
po_item.item_code,
|
||||
po_item.item_name,
|
||||
po.transaction_date as posting_date,
|
||||
po_item.purchase_ref_rate,
|
||||
po_item.discount_rate,
|
||||
po_item.purchase_rate
|
||||
from `tabPurchase Order` po, `tabPurchase Order Item` po_item
|
||||
where po.name = po_item.parent and po.docstatus = 1)
|
||||
union
|
||||
(select
|
||||
pr_item.item_code,
|
||||
pr_item.item_name,
|
||||
pr.posting_date,
|
||||
pr_item.purchase_ref_rate,
|
||||
pr_item.discount_rate,
|
||||
pr_item.purchase_rate
|
||||
from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
|
||||
where pr.name = pr_item.parent and pr.docstatus = 1)
|
||||
) result
|
||||
order by result.item_code asc, result.posting_date desc) result_wrapper
|
||||
group by item_code"""
|
||||
|
||||
for d in webnotes.conn.sql(query, as_dict=1):
|
||||
item_last_purchase_rate_map.setdefault(d.item_code, d.purchase_rate)
|
||||
|
||||
return item_last_purchase_rate_map
|
||||
|
||||
def get_item_bom_rate():
|
||||
"""Get BOM rate of an item from BOM"""
|
||||
|
||||
item_bom_map = {}
|
||||
|
||||
for b in webnotes.conn.sql("""select item, (total_cost/quantity) as bom_rate
|
||||
from `tabBOM` where is_active=1 and is_default=1""", as_dict=1):
|
||||
item_bom_map.setdefault(b.item, flt(b.bom_rate))
|
||||
|
||||
return item_bom_map
|
||||
|
||||
def get_valuation_rate():
|
||||
"""Get an average valuation rate of an item from all warehouses"""
|
||||
|
||||
item_val_rate_map = {}
|
||||
|
||||
for d in webnotes.conn.sql("""select item_code,
|
||||
sum(actual_qty*valuation_rate)/sum(actual_qty) as val_rate
|
||||
from tabBin where actual_qty > 0 group by item_code""", as_dict=1):
|
||||
item_val_rate_map.setdefault(d.item_code, d.val_rate)
|
||||
|
||||
return item_val_rate_map
|
||||
21
stock/report/item_prices/item_prices.txt
Normal file
21
stock/report/item_prices/item_prices.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-05 11:43:30",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-05 11:43:30",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Item Prices",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Item Prices"
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-01-02 14:22:51",
|
||||
"creation": "2013-02-22 18:01:55",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-22 15:53:01",
|
||||
"modified": "2013-05-07 11:50:46",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -10,7 +10,7 @@
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "select\n item.name as \"ID:Link/Item:120\", \n item.item_name as \"Item Name::120\", \n item_price.price_list_name as \"Price List::80\",\n item_price.ref_currency as \"Currency::40\", \n item_price.ref_rate as \"Rate:Currency:80\",\n item.description as \"Description::160\",\n item.item_group as \"Item Group:Link/Item Group:100\",\n item.brand as \"Brand::100\"\nfrom `tabItem` item, `tabItem Price` item_price\nwhere\n item_price.parent = item.name",
|
||||
"query": "select\n item.name as \"ID:Link/Item:120\", \n item.item_name as \"Item Name::120\", \n item_price.price_list_name as \"Price List::80\",\n item_price.ref_currency as \"Currency::40\", \n item_price.ref_rate as \"Rate:Float:80\",\n item.description as \"Description::160\",\n item.item_group as \"Item Group:Link/Item Group:100\",\n item.brand as \"Brand::100\"\nfrom `tabItem` item, `tabItem Price` item_price\nwhere\n item_price.parent = item.name",
|
||||
"ref_doctype": "Item",
|
||||
"report_name": "Item-Wise Price List",
|
||||
"report_type": "Query Report"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
wn.query_reports["Itemwise Recommended Reorder Level"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": "From Date",
|
||||
"fieldtype": "Date",
|
||||
"default": sys_defaults.year_start_date
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": "To Date",
|
||||
"fieldtype": "Date",
|
||||
"default": get_today()
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import webnotes
|
||||
from webnotes.utils import getdate, flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
float_preceision = webnotes.conn.get_default("float_preceision")
|
||||
|
||||
condition =get_condition(filters)
|
||||
|
||||
avg_daily_outgoing = 0
|
||||
diff = ((getdate(filters.get("to_date")) - getdate(filters.get("from_date"))).days)+1
|
||||
if diff <= 0:
|
||||
webnotes.msgprint("To Date should not be less than eual to From Date",raise_exception=1)
|
||||
|
||||
columns = get_columns()
|
||||
items = get_item_info()
|
||||
consumed_item_map = get_consumed_items(condition)
|
||||
delivered_item_map = get_delivered_items(condition)
|
||||
|
||||
data = []
|
||||
for item in items:
|
||||
|
||||
total_outgoing = consumed_item_map.get(item.name, 0)+delivered_item_map.get(item.name,0)
|
||||
avg_daily_outgoing = flt(total_outgoing/diff, float_preceision)
|
||||
reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.min_order_qty)
|
||||
|
||||
data.append([item.name, item.item_name, item.description, item.min_order_qty, item.lead_time_days,
|
||||
consumed_item_map.get(item.name, 0), delivered_item_map.get(item.name,0), total_outgoing,
|
||||
avg_daily_outgoing, reorder_level])
|
||||
|
||||
return columns , data
|
||||
|
||||
def get_columns():
|
||||
return[
|
||||
"Item:Link/Item:120", "Item name:Data:120", "Description::160",
|
||||
"Minimum Inventory Level:Float:160", "Lead Time Days:Float:120", "Consumed:Float:120",
|
||||
"Delivered:Float:120", "Total Outgoing:Float:120", "Avg Daily Outgoing:Float:160",
|
||||
"Reorder Level:Float:120"
|
||||
]
|
||||
|
||||
def get_item_info():
|
||||
return webnotes.conn.sql("""select name, item_name, description, min_order_qty,
|
||||
lead_time_days from tabItem""", as_dict=1)
|
||||
|
||||
def get_consumed_items(condition):
|
||||
|
||||
cn_items = webnotes.conn.sql("""select se_item.item_code,
|
||||
sum(se_item.actual_qty) as 'consume_qty'
|
||||
from `tabStock Entry` se, `tabStock Entry Detail` se_item
|
||||
where se.name = se_item.parent and se.docstatus = 1
|
||||
and ifnull(se_item.t_warehouse, '') = '' %s
|
||||
group by se_item.item_code""" % (condition), as_dict=1)
|
||||
|
||||
cn_items_map = {}
|
||||
for item in cn_items:
|
||||
cn_items_map.setdefault(item.item_code, item.consume_qty)
|
||||
|
||||
return cn_items_map
|
||||
|
||||
def get_delivered_items(condition):
|
||||
|
||||
dn_items = webnotes.conn.sql("""select dn_item.item_code, sum(dn_item.qty) as dn_qty
|
||||
from `tabDelivery Note` dn, `tabDelivery Note Item` dn_item
|
||||
where dn.name = dn_item.parent and dn.docstatus = 1 %s
|
||||
group by dn_item.item_code""" % (condition), as_dict=1)
|
||||
|
||||
si_items = webnotes.conn.sql("""select si_item.item_name, sum(si_item.qty) as si_qty
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where si.name = si_item.parent and si.docstatus = 1 and
|
||||
ifnull(si.update_stock, 0) = 1 and ifnull(si.is_pos, 0) = 1 %s
|
||||
group by si_item.item_name""" % (condition), as_dict=1)
|
||||
|
||||
dn_item_map = {}
|
||||
for item in dn_items:
|
||||
dn_item_map.setdefault(item.item_code, item.dn_qty)
|
||||
|
||||
for item in si_items:
|
||||
dn_item_map.setdefault(item.item_code, item.si_qty)
|
||||
|
||||
return dn_item_map
|
||||
|
||||
def get_condition(filters):
|
||||
conditions = ""
|
||||
if filters.get("from_date") and filters.get("to_date"):
|
||||
conditions += " and posting_date between '%s' and '%s'" % (filters["from_date"],filters["to_date"])
|
||||
else:
|
||||
webnotes.msgprint("Please set date in from date field",raise_exception=1)
|
||||
return conditions
|
||||
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-07 12:47:22",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-07 13:03:54",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Item",
|
||||
"report_name": "Itemwise Recommended Reorder Level",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Itemwise Recommended Reorder Level"
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-21 14:26:49",
|
||||
"creation": "2013-02-22 18:01:55",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-22 15:53:01",
|
||||
"modified": "2013-07-08 11:17:54",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -10,7 +10,7 @@
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`status` as \"Status\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project_name` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Stopped\"\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\norder by `tabSales Order`.transaction_date asc",
|
||||
"query": "select \n `tabSales Order`.`name` as \"Sales Order:Link/Sales Order:120\",\n `tabSales Order`.`customer` as \"Customer:Link/Customer:120\",\n `tabSales Order`.`transaction_date` as \"Date:Date\",\n `tabSales Order`.`project_name` as \"Project\",\n `tabSales Order Item`.item_code as \"Item:Link/Item:120\",\n `tabSales Order Item`.qty as \"Qty:Float:140\",\n `tabSales Order Item`.delivered_qty as \"Delivered Qty:Float:140\",\n (`tabSales Order Item`.qty - ifnull(`tabSales Order Item`.delivered_qty, 0)) as \"Qty to Deliver:Float:140\",\n `tabSales Order Item`.amount as \"Amount:Float:140\",\n `tabSales Order`.`delivery_date` as \"Expected Delivery Date:Date:120\",\n `tabSales Order Item`.item_name as \"Item Name::150\",\n `tabSales Order Item`.description as \"Description::200\",\n `tabSales Order Item`.item_group as \"Item Group:Link/Item Group:120\"\nfrom\n `tabSales Order`, `tabSales Order Item`\nwhere\n `tabSales Order Item`.`parent` = `tabSales Order`.`name`\n and `tabSales Order`.docstatus = 1\n and `tabSales Order`.status != \"Stopped\"\n and ifnull(`tabSales Order Item`.delivered_qty,0) < ifnull(`tabSales Order Item`.qty,0)\norder by `tabSales Order`.transaction_date asc",
|
||||
"ref_doctype": "Delivery Note",
|
||||
"report_name": "Ordered Items To Be Delivered",
|
||||
"report_type": "Query Report"
|
||||
|
||||
0
stock/report/purchase_in_transit/__init__.py
Normal file
0
stock/report/purchase_in_transit/__init__.py
Normal file
22
stock/report/purchase_in_transit/purchase_in_transit.txt
Normal file
22
stock/report/purchase_in_transit/purchase_in_transit.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-06 12:09:05",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-06 12:22:52",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "SELECT\n pi.name as \"Purchase Invoice:Link/Purchase Invoice:120\",\n\tpi.posting_date as \"Posting Date:Date:100\",\n\tpi.credit_to as \"Supplier Account:Link/Account:120\",\n\tpi_item.item_code as \"Item Code:Link/Item:120\",\n\tpi_item.description as \"Description:Data:140\",\n\tpi_item.qty as \"Qty:Float:120\",\n\tpi_item.amount as \"Amount:Currency:120\",\n\tpi_item.purchase_order as \"Purchase Order:Link/Purchase Order:120\",\n\tpi_item.purchase_receipt as \"Purchase Receipt:Link/Purchase Receipt:120\",\n\tpr.posting_date as \"PR Posting Date:Date:130\",\n\tpi.company as \"Company:Link/Company:120\"\nFROM\n\t`tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item, `tabPurchase Receipt` pr\nWHERE\n\tpi.name = pi_item.parent and pi_item.purchase_receipt = pr.name\n\tand pi.docstatus = 1 and pr.posting_date > pi.posting_date\nORDER BY\n\tpi.name desc",
|
||||
"ref_doctype": "Purchase Receipt",
|
||||
"report_name": "Purchase In Transit",
|
||||
"report_type": "Query Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Purchase In Transit"
|
||||
}
|
||||
]
|
||||
@@ -1,16 +1,17 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-02-21 14:26:49",
|
||||
"creation": "2013-02-22 18:01:55",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-02-22 15:53:01",
|
||||
"modified": "2013-05-28 16:03:15",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "select \n `tabPurchase Order`.`name` as \"Purchase Order:Link/Purchase Order:120\",\n `tabPurchase Order`.`transaction_date` as \"Date:Date:100\",\n `tabPurchase Order`.`supplier` as \"Supplier:Link/Supplier:120\",\n `tabPurchase Order`.`project_name` as \"Project\",\n `tabPurchase Order Item`.item_code as \"Item Code:Link/Item:120\",\n `tabPurchase Order Item`.qty as \"Qty:Float:100\",\n `tabPurchase Order Item`.received_qty as \"Received Qty:Float:100\", \n (`tabPurchase Order Item`.qty - ifnull(`tabPurchase Order Item`.received_qty, 0)) as \"Qty to Receive:Float:100\",\n `tabPurchase Order Item`.item_name as \"Item Name::150\",\n `tabPurchase Order Item`.description as \"Description::200\"\nfrom\n `tabPurchase Order`, `tabPurchase Order Item`\nwhere\n `tabPurchase Order Item`.`parent` = `tabPurchase Order`.`name`\n and `tabPurchase Order`.docstatus = 1\n and `tabPurchase Order`.status != \"Stopped\"\n and ifnull(`tabPurchase Order Item`.received_qty, 0) < ifnull(`tabPurchase Order Item`.qty, 0)\norder by `tabPurchase Order`.transaction_date asc",
|
||||
"query": "select \n `tabPurchase Order`.`name` as \"Purchase Order:Link/Purchase Order:120\",\n\t`tabPurchase Order`.`transaction_date` as \"Date:Date:100\",\n\t`tabPurchase Order`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`tabPurchase Order Item`.`project_name` as \"Project\",\n\t`tabPurchase Order Item`.item_code as \"Item Code:Link/Item:120\",\n\t`tabPurchase Order Item`.qty as \"Qty:Float:100\",\n\t`tabPurchase Order Item`.received_qty as \"Received Qty:Float:100\", \n\t(`tabPurchase Order Item`.qty - ifnull(`tabPurchase Order Item`.received_qty, 0)) as \"Qty to Receive:Float:100\",\n\t`tabPurchase Order Item`.item_name as \"Item Name::150\",\n\t`tabPurchase Order Item`.description as \"Description::200\"\nfrom\n\t`tabPurchase Order`, `tabPurchase Order Item`\nwhere\n\t`tabPurchase Order Item`.`parent` = `tabPurchase Order`.`name`\n\tand `tabPurchase Order`.docstatus = 1\n\tand `tabPurchase Order`.status != \"Stopped\"\n\tand ifnull(`tabPurchase Order Item`.received_qty, 0) < ifnull(`tabPurchase Order Item`.qty, 0)\norder by `tabPurchase Order`.transaction_date asc",
|
||||
"ref_doctype": "Purchase Receipt",
|
||||
"report_name": "Purchase Order Items To Be Received",
|
||||
"report_type": "Query Report"
|
||||
|
||||
0
stock/report/purchase_receipt_trends/__init__.py
Normal file
0
stock/report/purchase_receipt_trends/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
wn.require("app/js/purchase_trends_filters.js");
|
||||
|
||||
wn.query_reports["Purchase Receipt Trends"] = {
|
||||
filters: get_filters()
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from controllers.trends import get_columns,get_data
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters ={}
|
||||
data = []
|
||||
conditions = get_columns(filters, "Purchase Receipt")
|
||||
data = get_data(filters, conditions)
|
||||
|
||||
return conditions["columns"], data
|
||||
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-13 18:45:44",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-13 18:45:44",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Purchase Receipt",
|
||||
"report_name": "Purchase Receipt Trends",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Purchase Receipt Trends"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-05-13 16:23:05",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-05-13 16:25:08",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tmr_item.qty as \"Qty:Float:100\",\n\tmr_item.ordered_qty as \"Transferred Qty:Float:100\", \n\t(mr_item.qty - ifnull(mr_item.ordered_qty, 0)) as \"Qty to Transfer:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Transfer\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\n\tand ifnull(mr_item.ordered_qty, 0) < ifnull(mr_item.qty, 0)\norder by mr.transaction_date asc",
|
||||
"ref_doctype": "Stock Entry",
|
||||
"report_name": "Requested Items To Be Transferred",
|
||||
"report_type": "Query Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Requested Items To Be Transferred"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
wn.query_reports["Warehouse-Wise Stock Balance"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"label": "From Date",
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": sys_defaults.year_start_date,
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"label": "To Date",
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"default": wn.datetime.get_today()
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
columns = get_columns(filters)
|
||||
item_map = get_item_details(filters)
|
||||
iwb_map = get_item_warehouse_map(filters)
|
||||
|
||||
data = []
|
||||
for company in sorted(iwb_map):
|
||||
for item in sorted(iwb_map[company]):
|
||||
for wh in sorted(iwb_map[company][item]):
|
||||
qty_dict = iwb_map[company][item][wh]
|
||||
data.append([item, item_map[item]["item_name"],
|
||||
item_map[item]["description"], wh,
|
||||
qty_dict.opening_qty, qty_dict.in_qty,
|
||||
qty_dict.out_qty, qty_dict.bal_qty, company
|
||||
])
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns(filters):
|
||||
"""return columns based on filters"""
|
||||
|
||||
columns = ["Item:Link/Item:100", "Item Name::150", "Description::150", \
|
||||
"Warehouse:Link/Warehouse:100", "Opening Qty::90", \
|
||||
"In Qty::80", "Out Qty::80", "Balance Qty::90", "Company:Link/Company:100"]
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if not filters.get("from_date"):
|
||||
webnotes.msgprint("Please enter From Date", raise_exception=1)
|
||||
|
||||
if filters.get("to_date"):
|
||||
conditions += " and posting_date <= '%s'" % filters["to_date"]
|
||||
else:
|
||||
webnotes.msgprint("Please enter To Date", raise_exception=1)
|
||||
|
||||
return conditions
|
||||
|
||||
#get all details
|
||||
def get_stock_ledger_entries(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return webnotes.conn.sql("""select item_code, warehouse,
|
||||
posting_date, actual_qty, company
|
||||
from `tabStock Ledger Entry`
|
||||
where ifnull(is_cancelled, 'No') = 'No' %s order by item_code, warehouse""" %
|
||||
conditions, as_dict=1)
|
||||
|
||||
def get_item_warehouse_map(filters):
|
||||
sle = get_stock_ledger_entries(filters)
|
||||
iwb_map = {}
|
||||
|
||||
for d in sle:
|
||||
iwb_map.setdefault(d.company, {}).setdefault(d.item_code, {}).\
|
||||
setdefault(d.warehouse, webnotes._dict({\
|
||||
"opening_qty": 0.0, "in_qty": 0.0, "out_qty": 0.0, "bal_qty": 0.0
|
||||
}))
|
||||
qty_dict = iwb_map[d.company][d.item_code][d.warehouse]
|
||||
if d.posting_date < filters["from_date"]:
|
||||
qty_dict.opening_qty += flt(d.actual_qty)
|
||||
elif d.posting_date >= filters["from_date"] and d.posting_date <= filters["to_date"]:
|
||||
if flt(d.actual_qty) > 0:
|
||||
qty_dict.in_qty += flt(d.actual_qty)
|
||||
else:
|
||||
qty_dict.out_qty += abs(flt(d.actual_qty))
|
||||
|
||||
qty_dict.bal_qty += flt(d.actual_qty)
|
||||
|
||||
return iwb_map
|
||||
|
||||
def get_item_details(filters):
|
||||
item_map = {}
|
||||
for d in webnotes.conn.sql("select name, item_name, description from tabItem", as_dict=1):
|
||||
item_map.setdefault(d.name, d)
|
||||
|
||||
return item_map
|
||||
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-06-05 11:00:31",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-05 11:00:31",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Warehouse-Wise Stock Balance",
|
||||
"report_type": "Script Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Warehouse-Wise Stock Balance"
|
||||
}
|
||||
]
|
||||
@@ -35,6 +35,9 @@ def update_entries_after(args, verbose=1):
|
||||
"posting_time": "12:00"
|
||||
}
|
||||
"""
|
||||
global _exceptions
|
||||
_exceptions = []
|
||||
|
||||
previous_sle = get_sle_before_datetime(args)
|
||||
|
||||
qty_after_transaction = flt(previous_sle.get("qty_after_transaction"))
|
||||
|
||||
155
stock/utils.py
155
stock/utils.py
@@ -17,15 +17,16 @@
|
||||
import webnotes
|
||||
from webnotes import msgprint, _
|
||||
import json
|
||||
from webnotes.utils import flt, cstr
|
||||
from webnotes.utils import flt, cstr, nowdate, add_days, cint
|
||||
from webnotes.defaults import get_global_default
|
||||
from webnotes.utils.email_lib import sendmail
|
||||
|
||||
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
|
||||
if not end_of_life:
|
||||
end_of_life = webnotes.conn.get_value("Item", item_code, "end_of_life")
|
||||
|
||||
from webnotes.utils import getdate, now_datetime, formatdate
|
||||
if end_of_life and getdate(end_of_life) > now_datetime().date():
|
||||
if end_of_life and getdate(end_of_life) <= now_datetime().date():
|
||||
msg = (_("Item") + " %(item_code)s: " + _("reached its end of life on") + \
|
||||
" %(date)s. " + _("Please check") + ": %(end_of_life_label)s " + \
|
||||
"in Item master") % {
|
||||
@@ -194,4 +195,152 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse,
|
||||
buying_amount = previous_stock_value - flt(sle.stock_value)
|
||||
|
||||
return buying_amount
|
||||
return 0.0
|
||||
return 0.0
|
||||
|
||||
|
||||
def reorder_item():
|
||||
""" Reorder item if stock reaches reorder level"""
|
||||
if not hasattr(webnotes, "auto_indent"):
|
||||
webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent')
|
||||
|
||||
if webnotes.auto_indent:
|
||||
material_requests = {}
|
||||
bin_list = webnotes.conn.sql("""select item_code, warehouse, projected_qty
|
||||
from tabBin where ifnull(item_code, '') != '' and ifnull(warehouse, '') != ''
|
||||
and exists (select name from `tabItem`
|
||||
where `tabItem`.name = `tabBin`.item_code and
|
||||
is_stock_item='Yes' and (is_purchase_item='Yes' or is_sub_contracted_item='Yes') and
|
||||
(ifnull(end_of_life, '')='') or end_of_life > now())""",
|
||||
as_dict=True)
|
||||
for bin in bin_list:
|
||||
#check if re-order is required
|
||||
item_reorder = webnotes.conn.get("Item Reorder",
|
||||
{"parent": bin.item_code, "warehouse": bin.warehouse})
|
||||
if item_reorder:
|
||||
reorder_level = item_reorder.warehouse_reorder_level
|
||||
reorder_qty = item_reorder.warehouse_reorder_qty
|
||||
material_request_type = item_reorder.material_request_type or "Purchase"
|
||||
else:
|
||||
reorder_level, reorder_qty = webnotes.conn.get_value("Item", bin.item_code,
|
||||
["re_order_level", "re_order_qty"])
|
||||
material_request_type = "Purchase"
|
||||
|
||||
if flt(reorder_level) and flt(bin.projected_qty) < flt(reorder_level):
|
||||
if flt(reorder_level) - flt(bin.projected_qty) > flt(reorder_qty):
|
||||
reorder_qty = flt(reorder_level) - flt(bin.projected_qty)
|
||||
|
||||
company = webnotes.conn.get_value("Warehouse", bin.warehouse, "company") or \
|
||||
webnotes.defaults.get_defaults()["company"] or \
|
||||
webnotes.conn.sql("""select name from tabCompany limit 1""")[0][0]
|
||||
|
||||
material_requests.setdefault(material_request_type, webnotes._dict()).setdefault(
|
||||
company, []).append(webnotes._dict({
|
||||
"item_code": bin.item_code,
|
||||
"warehouse": bin.warehouse,
|
||||
"reorder_qty": reorder_qty
|
||||
})
|
||||
)
|
||||
|
||||
create_material_request(material_requests)
|
||||
|
||||
def create_material_request(material_requests):
|
||||
""" Create indent on reaching reorder level """
|
||||
mr_list = []
|
||||
defaults = webnotes.defaults.get_defaults()
|
||||
exceptions_list = []
|
||||
for request_type in material_requests:
|
||||
for company in material_requests[request_type]:
|
||||
try:
|
||||
items = material_requests[request_type][company]
|
||||
if not items:
|
||||
continue
|
||||
|
||||
mr = [{
|
||||
"doctype": "Material Request",
|
||||
"company": company,
|
||||
"fiscal_year": defaults.fiscal_year,
|
||||
"transaction_date": nowdate(),
|
||||
"material_request_type": request_type,
|
||||
"remark": _("This is an auto generated Material Request.") + \
|
||||
_("""It was raised because the (actual + ordered + indented - reserved)
|
||||
quantity reaches re-order level when the following record was created""")
|
||||
}]
|
||||
|
||||
for d in items:
|
||||
item = webnotes.doc("Item", d.item_code)
|
||||
mr.append({
|
||||
"doctype": "Material Request Item",
|
||||
"parenttype": "Material Request",
|
||||
"parentfield": "indent_details",
|
||||
"item_code": d.item_code,
|
||||
"schedule_date": add_days(nowdate(),cint(item.lead_time_days)),
|
||||
"uom": item.stock_uom,
|
||||
"warehouse": d.warehouse,
|
||||
"item_name": item.item_name,
|
||||
"description": item.description,
|
||||
"item_group": item.item_group,
|
||||
"qty": d.reorder_qty,
|
||||
"brand": item.brand,
|
||||
})
|
||||
|
||||
mr_bean = webnotes.bean(mr)
|
||||
mr_bean.insert()
|
||||
mr_bean.submit()
|
||||
mr_list.append(mr_bean)
|
||||
|
||||
except:
|
||||
if webnotes.message_log:
|
||||
exceptions_list.append([] + webnotes.message_log)
|
||||
webnotes.message_log = []
|
||||
else:
|
||||
exceptions_list.append(webnotes.getTraceback())
|
||||
|
||||
if mr_list:
|
||||
if not hasattr(webnotes, "reorder_email_notify"):
|
||||
webnotes.reorder_email_notify = webnotes.conn.get_value('Global Defaults', None,
|
||||
'reorder_email_notify')
|
||||
|
||||
if(webnotes.reorder_email_notify):
|
||||
send_email_notification(mr_list)
|
||||
|
||||
if exceptions_list:
|
||||
notify_errors(exceptions_list)
|
||||
|
||||
def send_email_notification(mr_list):
|
||||
""" Notify user about auto creation of indent"""
|
||||
|
||||
email_list = webnotes.conn.sql_list("""select distinct r.parent
|
||||
from tabUserRole r, tabProfile p
|
||||
where p.name = r.parent and p.enabled = 1 and p.docstatus < 2
|
||||
and r.role in ('Purchase Manager','Material Manager')
|
||||
and p.name not in ('Administrator', 'All', 'Guest')""")
|
||||
|
||||
msg="""<h3>Following Material Requests has been raised automatically \
|
||||
based on item reorder level:</h3>"""
|
||||
for mr in mr_list:
|
||||
msg += "<p><b><u>" + mr.doc.name + """</u></b></p><table class='table table-bordered'><tr>
|
||||
<th>Item Code</th><th>Warehouse</th><th>Qty</th><th>UOM</th></tr>"""
|
||||
for item in mr.doclist.get({"parentfield": "indent_details"}):
|
||||
msg += "<tr><td>" + item.item_code + "</td><td>" + item.warehouse + "</td><td>" + \
|
||||
cstr(item.qty) + "</td><td>" + cstr(item.uom) + "</td></tr>"
|
||||
msg += "</table>"
|
||||
|
||||
sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg)
|
||||
|
||||
def notify_errors(exceptions_list):
|
||||
subject = "[Important] [ERPNext] Error(s) while creating Material Requests based on Re-order Levels"
|
||||
msg = """Dear System Manager,
|
||||
|
||||
An error occured for certain Items while creating Material Requests based on Re-order level.
|
||||
|
||||
Please rectify these issues:
|
||||
---
|
||||
|
||||
%s
|
||||
|
||||
---
|
||||
Regards,
|
||||
Administrator""" % ("\n\n".join(["\n".join(msg) for msg in exceptions_list]),)
|
||||
|
||||
from webnotes.profile import get_system_managers
|
||||
sendmail(get_system_managers(), subject=subject, msg=msg)
|
||||
|
||||
Reference in New Issue
Block a user