[item variant] started

This commit is contained in:
Rushabh Mehta 2014-09-26 18:54:01 +05:30
parent 852e3600cd
commit 70aa8933b1
21 changed files with 1196 additions and 740 deletions

View File

@ -164,6 +164,7 @@
"permlevel": 0
},
{
"description": "Higher the number, higher the priority",
"fieldname": "priority",
"fieldtype": "Select",
"label": "Priority",
@ -235,7 +236,7 @@
"icon": "icon-gift",
"idx": 1,
"istable": 0,
"modified": "2014-06-20 19:36:22.502381",
"modified": "2014-09-26 09:09:38.418765",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",

View File

@ -0,0 +1,6 @@
[
{
"doctype": "Pricing Rule",
"name": "_Test Pricing Rule 1"
}
]

View File

@ -129,6 +129,11 @@ def get_data():
"description": _("Multiple Item prices."),
"route": "Report/Item Price"
},
{
"type": "doctype",
"name": "Item Attribute",
"description": _("Attributes for Item Variants. e.g Size, Color etc."),
},
]
},
{

View File

@ -35,11 +35,32 @@ erpnext.item.toggle_reqd = function(frm) {
frm.toggle_reqd("default_warehouse", frm.doc.is_stock_item==="Yes");
};
frappe.ui.form.on("Item", "is_stock_item", function(frm) {
erpnext.item.toggle_reqd(frm);
frappe.ui.form.on("Item", "onload", function(frm) {
var df = frappe.meta.get_docfield("Item Variant", "item_attribute_value");
df.on_make = function(field) {
field.$input.autocomplete({
minLength: 0,
minChars: 0,
source: function(request, response) {
frappe.call({
method:"frappe.client.get_list",
args:{
doctype:"Item Attribute Value",
filters: [
["parent","=", field.doc.item_attribute],
["attribute_value", "like", request.term + "%"]
],
fields: ["attribute_value"]
},
callback: function(r) {
response($.map(r.message, function(d) { return d.attribute_value; }));
}
});
}
})
}
});
cur_frm.cscript.make_dashboard = function() {
cur_frm.dashboard.reset();
if(cur_frm.doc.__islocal)

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ from frappe.website.render import clear_cache
from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow
class WarehouseNotSet(frappe.ValidationError): pass
class DuplicateVariant(frappe.ValidationError): pass
class Item(WebsiteGenerator):
page_title_field = "item_name"
@ -50,6 +51,7 @@ class Item(WebsiteGenerator):
self.validate_barcode()
self.cant_change()
self.validate_item_type_for_reorder()
self.validate_variants_are_unique()
if not self.get("__islocal"):
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@ -61,6 +63,7 @@ class Item(WebsiteGenerator):
invalidate_cache_for_item(self)
self.validate_name_with_item_group()
self.update_item_price()
self.make_variants()
def get_context(self, context):
context["parent_groups"] = get_parent_item_groups(self.item_group) + \
@ -114,6 +117,45 @@ class Item(WebsiteGenerator):
if not matched:
frappe.throw(_("Default Unit of Measure can not be changed directly because you have already made some transaction(s) with another UOM. To change default UOM, use 'UOM Replace Utility' tool under Stock module."))
def validate_variants_are_unique(self):
variants = []
for d in self.item_variants:
key = (d.item_attribute, d.item_attribute_value)
if key in variants:
frappe.throw(_("{0} {1} is entered more than once in Item Variants table").format(d.item_attribute,
d.item_attribute_value), DuplicateVariant)
variants.append(key)
def make_variants(self):
variant_dict = {}
variant_item_codes = []
for d in self.item_variants:
variant_dict.setdefault(d.item_attribute, []).append(d.item_attribute_value)
attributes = variant_dict.keys()
for d in frappe.get_list("Item Attribute", order_by = "priority asc", ignore_permissions=True):
if d.name in attributes:
attr = frappe.get_doc("Item Attribute", d.name)
abbr = dict((d.attribute_value, d.abbr) for d in attr.item_attribute_values)
for value in variant_dict[d.name]:
variant_item_codes.append(self.name + "-" + abbr[value])
# delete missing variants
existing_variants = [d.name for d in frappe.get_list("Item",
filters={"variant_of":self.name}, ignore_permissions=True)]
for existing_variant in existing_variants:
if existing_variant.name not in variant_item_codes:
frappe.delete_doc("Item", existing_variant.name)
else:
# update mandatory fields
pass
# for item_code in variant_item_codes:
# for
def validate_conversion_factor(self):
check_list = []
for d in self.get('uom_conversion_details'):

View File

@ -6,13 +6,23 @@ import unittest
import frappe
from frappe.test_runner import make_test_records
from erpnext.stock.doctype.item.item import WarehouseNotSet, DuplicateVariant
test_ignore = ["BOM"]
test_dependencies = ["Warehouse"]
class TestItem(unittest.TestCase):
def test_duplicate_variant(self):
item = frappe.copy_doc(test_records[11])
item.append("item_variants", {"item_attribute": "Test Size", "item_attribute_value": "Small"})
self.assertRaises(DuplicateVariant, item.insert)
def test_item_creation(self):
frappe.delete_doc("Item", test_records[11].get("item_code"))
item = frappe.copy_doc(test_records[11])
item.insert()
def test_default_warehouse(self):
from erpnext.stock.doctype.item.item import WarehouseNotSet
item = frappe.copy_doc(test_records[0])
item.is_stock_item = "Yes"
item.default_warehouse = None

View File

@ -1,7 +1,7 @@
[
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Item",
"description": "_Test Item 1",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -57,7 +57,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Item Home Desktop 100",
"description": "_Test Item Home Desktop 100 3",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -87,7 +87,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Item Home Desktop 200",
"description": "_Test Item Home Desktop 200 4",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -108,7 +108,7 @@
"stock_uom": "_Test UOM"
},
{
"description": "_Test Sales BOM Item",
"description": "_Test Sales BOM Item 5",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -129,7 +129,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test FG Item",
"description": "_Test FG Item 6",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -149,7 +149,7 @@
"stock_uom": "_Test UOM"
},
{
"description": "_Test Non Stock Item",
"description": "_Test Non Stock Item 7",
"doctype": "Item",
"has_batch_no": "No",
"has_serial_no": "No",
@ -168,7 +168,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Serialized Item",
"description": "_Test Serialized Item 8",
"doctype": "Item",
"has_batch_no": "No",
"has_serial_no": "Yes",
@ -187,7 +187,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Serialized Item",
"description": "_Test Serialized Item 9",
"doctype": "Item",
"has_batch_no": "No",
"has_serial_no": "Yes",
@ -207,7 +207,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Item Home Desktop Manufactured",
"description": "_Test Item Home Desktop Manufactured 10",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -229,7 +229,7 @@
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test FG Item 2",
"description": "_Test FG Item 2 11",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
@ -247,5 +247,32 @@
"item_group": "_Test Item Group Desktops",
"item_name": "_Test FG Item 2",
"stock_uom": "_Test UOM"
},
{
"default_warehouse": "_Test Warehouse - _TC",
"description": "_Test Variant Item 12",
"doctype": "Item",
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"has_batch_no": "No",
"has_serial_no": "No",
"income_account": "Sales - _TC",
"inspection_required": "No",
"is_asset_item": "No",
"is_pro_applicable": "Yes",
"is_purchase_item": "Yes",
"is_sales_item": "Yes",
"is_service_item": "No",
"is_stock_item": "Yes",
"is_sub_contracted_item": "Yes",
"item_code": "_Test Variant Item",
"item_group": "_Test Item Group Desktops",
"item_name": "_Test Variant Item",
"stock_uom": "_Test UOM",
"item_variants": [
{"item_attribute": "Test Size", "item_attribute_value": "Small"},
{"item_attribute": "Test Size", "item_attribute_value": "Medium"},
{"item_attribute": "Test Size", "item_attribute_value": "Large"}
]
}
]

View File

@ -0,0 +1,87 @@
{
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "field:attribute_name",
"creation": "2014-09-26 03:49:54.899170",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "attribute_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Attribute Name",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0
},
{
"default": "1",
"description": "Lower the number, higher the priority in the Item Code suffix that will be created for this Item Attribute for the Item Variant",
"fieldname": "priority",
"fieldtype": "Int",
"label": "Priority",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "item_attribute_values",
"fieldtype": "Table",
"label": "Item Attribute Values",
"options": "Item Attribute Value",
"permlevel": 0,
"precision": ""
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-edit",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2014-09-26 06:08:28.729519",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Attribute",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 0,
"export": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 1,
"role": "Material Master Manager",
"set_user_permissions": 0,
"submit": 0,
"write": 1
}
],
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,19 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
class ItemAttribute(Document):
def validate(self):
values, abbrs = [], []
for d in self.item_attribute_values:
if d.attribute_value in values:
frappe.throw(_("{0} must appear only once").format(d.attribute_value))
values.append(d.attribute_value)
if d.abbr in abbrs:
frappe.throw(_("{0} must appear only once").format(d.abbr))
abbrs.append(d.abbr)

View File

@ -0,0 +1,10 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import frappe
import unittest
test_records = frappe.get_test_records('Item Attribute')
class TestItemAttribute(unittest.TestCase):
pass

View File

@ -0,0 +1,22 @@
[
{
"doctype": "Item Attribute",
"attribute_name": "Test Size",
"priority": 1,
"item_attribute_values": [
{"attribute_value": "Small", "abbr": "SM"},
{"attribute_value": "Medium", "abbr": "MD"},
{"attribute_value": "Large", "abbr": "LG"}
]
},
{
"doctype": "Item Attribute",
"attribute_name": "Test Colour",
"priority": 2,
"item_attribute_values": [
{"attribute_value": "Red", "abbr": "R"},
{"attribute_value": "Green", "abbr": "G"},
{"attribute_value": "Blue", "abbr": "B"}
]
}
]

View File

@ -0,0 +1,64 @@
{
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "",
"creation": "2014-09-26 03:52:31.161255",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "attribute_value",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Attribute Value",
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"description": "This will be appended to the Item Code of the variant. For example, if your abbreviation is \"SM\", and the item code is \"T-SHIRT\", the item code of the variant will be \"T-SHIRT-SM\"",
"fieldname": "abbr",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Abbreviation",
"permlevel": 0,
"precision": "",
"reqd": 1,
"search_index": 1,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-edit",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2014-09-26 06:17:47.136386",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Attribute Value",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class ItemAttributeValue(Document):
pass

View File

@ -0,0 +1,10 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and Contributors
# See license.txt
import frappe
import unittest
test_records = frappe.get_test_records('Item Attribute Value')
class TestItemAttributeValue(unittest.TestCase):
pass

View File

@ -0,0 +1,6 @@
[
{
"doctype": "Item Attribute Value",
"name": "_Test Item Attribute Value 1"
}
]

View File

@ -0,0 +1,72 @@
{
"allow_copy": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "",
"creation": "2014-09-26 03:54:04.370259",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "item_attribute",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Item Attribute",
"no_copy": 0,
"options": "Item Attribute",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0
},
{
"allow_on_submit": 0,
"fieldname": "item_attribute_value",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Item Attribute Value",
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "",
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"modified": "2014-09-26 06:24:14.248364",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item Variant",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class ItemVariant(Document):
pass