Fixes for updating item variant from template (#10975)
* Fixes for updating item variant from template * More fixes for test cases
This commit is contained in:
parent
9c339145b2
commit
945f502748
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cstr, flt
|
from frappe.utils import cstr, flt
|
||||||
import json
|
import json, copy
|
||||||
|
|
||||||
class ItemVariantExistsError(frappe.ValidationError): pass
|
class ItemVariantExistsError(frappe.ValidationError): pass
|
||||||
class InvalidItemAttributeValueError(frappe.ValidationError): pass
|
class InvalidItemAttributeValueError(frappe.ValidationError): pass
|
||||||
@ -175,18 +175,28 @@ def copy_attributes_to_variant(item, variant):
|
|||||||
# copy non no-copy fields
|
# copy non no-copy fields
|
||||||
|
|
||||||
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
||||||
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate", "variant_based_on"]
|
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate"]
|
||||||
|
|
||||||
if item.variant_based_on=='Manufacturer':
|
if item.variant_based_on=='Manufacturer':
|
||||||
# don't copy manufacturer values if based on part no
|
# don't copy manufacturer values if based on part no
|
||||||
exclude_fields += ['manufacturer', 'manufacturer_part_no']
|
exclude_fields += ['manufacturer', 'manufacturer_part_no']
|
||||||
|
|
||||||
allow_fields = [d.field_name for d in frappe.get_all("Variant Field", fields = ['field_name'])]
|
allow_fields = [d.field_name for d in frappe.get_all("Variant Field", fields = ['field_name'])]
|
||||||
|
if "variant_based_on" not in allow_fields:
|
||||||
|
allow_fields.append("variant_based_on")
|
||||||
for field in item.meta.fields:
|
for field in item.meta.fields:
|
||||||
# "Table" is part of `no_value_field` but we shouldn't ignore tables
|
# "Table" is part of `no_value_field` but we shouldn't ignore tables
|
||||||
if (field.reqd or field.fieldname in allow_fields) and field.fieldname not in exclude_fields:
|
if (field.reqd or field.fieldname in allow_fields) and field.fieldname not in exclude_fields:
|
||||||
if variant.get(field.fieldname) != item.get(field.fieldname):
|
if variant.get(field.fieldname) != item.get(field.fieldname):
|
||||||
variant.set(field.fieldname, item.get(field.fieldname))
|
if field.fieldtype == "Table":
|
||||||
|
variant.set(field.fieldname, [])
|
||||||
|
for d in item.get(field.fieldname):
|
||||||
|
row = copy.deepcopy(d)
|
||||||
|
if row.get("name"):
|
||||||
|
row.name = None
|
||||||
|
variant.append(field.fieldname, row)
|
||||||
|
else:
|
||||||
|
variant.set(field.fieldname, item.get(field.fieldname))
|
||||||
|
|
||||||
variant.variant_of = item.name
|
variant.variant_of = item.name
|
||||||
variant.has_variants = 0
|
variant.has_variants = 0
|
||||||
|
@ -61,7 +61,7 @@ class Project(Document):
|
|||||||
self.send_welcome_email()
|
self.send_welcome_email()
|
||||||
|
|
||||||
def validate_project_name(self):
|
def validate_project_name(self):
|
||||||
if frappe.db.exists("Project", self.project_name):
|
if self.get("__islocal") and frappe.db.exists("Project", self.project_name):
|
||||||
frappe.throw(_("Project {0} already exists").format(self.project_name))
|
frappe.throw(_("Project {0} already exists").format(self.project_name))
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
|
@ -120,6 +120,8 @@ class TestItem(unittest.TestCase):
|
|||||||
self.assertRaises(ItemVariantExistsError, variant.save)
|
self.assertRaises(ItemVariantExistsError, variant.save)
|
||||||
|
|
||||||
def test_copy_fields_from_template_to_variants(self):
|
def test_copy_fields_from_template_to_variants(self):
|
||||||
|
frappe.delete_doc_if_exists("Item", "_Test Variant Item-XL", force=1)
|
||||||
|
|
||||||
fields = [{'field_name': 'item_group'}, {'field_name': 'is_stock_item'}]
|
fields = [{'field_name': 'item_group'}, {'field_name': 'is_stock_item'}]
|
||||||
allow_fields = [d.get('field_name') for d in fields]
|
allow_fields = [d.get('field_name') for d in fields]
|
||||||
set_item_variant_settings(fields)
|
set_item_variant_settings(fields)
|
||||||
|
@ -5,7 +5,7 @@ frappe.ui.form.on('Item Variant Settings', {
|
|||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
const allow_fields = [];
|
const allow_fields = [];
|
||||||
const exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
const exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
||||||
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate", "variant_based_on"];
|
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate"];
|
||||||
|
|
||||||
frappe.model.with_doctype('Item', () => {
|
frappe.model.with_doctype('Item', () => {
|
||||||
frappe.get_meta('Item').fields.forEach(d => {
|
frappe.get_meta('Item').fields.forEach(d => {
|
||||||
|
@ -12,7 +12,7 @@ class ItemVariantSettings(Document):
|
|||||||
fields = frappe.get_meta('Item').fields
|
fields = frappe.get_meta('Item').fields
|
||||||
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
||||||
"show_variant_in_website", "standard_rate", "opening_stock", "image", "description",
|
"show_variant_in_website", "standard_rate", "opening_stock", "image", "description",
|
||||||
"variant_of", "valuation_rate", "description", "variant_based_on",
|
"variant_of", "valuation_rate", "description",
|
||||||
"website_image", "thumbnail", "website_specifiations", "web_long_description"]
|
"website_image", "thumbnail", "website_specifiations", "web_long_description"]
|
||||||
|
|
||||||
for d in fields:
|
for d in fields:
|
||||||
|
@ -11,7 +11,7 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
|
|||||||
from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError
|
from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError
|
||||||
from erpnext.stock.stock_ledger import get_previous_sle
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||||
from erpnext.stock.doctype.item.test_item import set_item_variant_settings
|
from erpnext.stock.doctype.item.test_item import set_item_variant_settings, make_item_variant
|
||||||
from frappe.tests.test_permissions import set_user_permission_doctypes
|
from frappe.tests.test_permissions import set_user_permission_doctypes
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||||
@ -46,6 +46,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=10)
|
make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=10)
|
||||||
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
||||||
|
|
||||||
self.assertEqual([[1, 10]], frappe.safe_eval(sle.stock_queue))
|
self.assertEqual([[1, 10]], frappe.safe_eval(sle.stock_queue))
|
||||||
|
|
||||||
# negative qty
|
# negative qty
|
||||||
@ -74,7 +75,6 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
frappe.db.set_default("allow_negative_stock", 0)
|
frappe.db.set_default("allow_negative_stock", 0)
|
||||||
|
|
||||||
def test_auto_material_request(self):
|
def test_auto_material_request(self):
|
||||||
from erpnext.stock.doctype.item.test_item import make_item_variant
|
|
||||||
make_item_variant()
|
make_item_variant()
|
||||||
self._test_auto_material_request("_Test Item")
|
self._test_auto_material_request("_Test Item")
|
||||||
self._test_auto_material_request("_Test Item", material_request_type="Transfer")
|
self._test_auto_material_request("_Test Item", material_request_type="Transfer")
|
||||||
@ -82,6 +82,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
def test_auto_material_request_for_variant(self):
|
def test_auto_material_request_for_variant(self):
|
||||||
fields = [{'field_name': 'reorder_levels'}]
|
fields = [{'field_name': 'reorder_levels'}]
|
||||||
set_item_variant_settings(fields)
|
set_item_variant_settings(fields)
|
||||||
|
make_item_variant()
|
||||||
template = frappe.get_doc("Item", "_Test Variant Item")
|
template = frappe.get_doc("Item", "_Test Variant Item")
|
||||||
|
|
||||||
if not template.reorder_levels:
|
if not template.reorder_levels:
|
||||||
|
@ -13,13 +13,6 @@
|
|||||||
"warehouse_name": "_Test Scrap Warehouse",
|
"warehouse_name": "_Test Scrap Warehouse",
|
||||||
"is_group": 0
|
"is_group": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"company": "_Test Company",
|
|
||||||
"create_account_under": "Stock Assets - _TC",
|
|
||||||
"doctype": "Warehouse",
|
|
||||||
"warehouse_name": "_Test Warehouse",
|
|
||||||
"is_group": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"create_account_under": "Fixed Assets - _TC",
|
"create_account_under": "Fixed Assets - _TC",
|
||||||
|
@ -25,7 +25,7 @@ class TransactionBase(StatusUpdater):
|
|||||||
if not getattr(self, 'set_posting_time', None):
|
if not getattr(self, 'set_posting_time', None):
|
||||||
now = now_datetime()
|
now = now_datetime()
|
||||||
self.posting_date = now.strftime('%Y-%m-%d')
|
self.posting_date = now.strftime('%Y-%m-%d')
|
||||||
self.posting_time = now.strftime('%H:%M:%S')
|
self.posting_time = now.strftime('%H:%M:%S.%f')
|
||||||
|
|
||||||
def add_calendar_event(self, opts, force=False):
|
def add_calendar_event(self, opts, force=False):
|
||||||
if cstr(self.contact_by) != cstr(self._prev.contact_by) or \
|
if cstr(self.contact_by) != cstr(self._prev.contact_by) or \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user