From 945f5027484a5a86119578fb69879ce62877c69f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 29 Sep 2017 15:11:50 +0530 Subject: [PATCH] Fixes for updating item variant from template (#10975) * Fixes for updating item variant from template * More fixes for test cases --- erpnext/controllers/item_variant.py | 16 +++++++++++++--- erpnext/projects/doctype/project/project.py | 2 +- erpnext/stock/doctype/item/test_item.py | 2 ++ .../item_variant_settings.js | 2 +- .../item_variant_settings.py | 2 +- .../doctype/stock_entry/test_stock_entry.py | 5 +++-- .../stock/doctype/warehouse/test_records.json | 7 ------- erpnext/utilities/transaction_base.py | 2 +- 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index 5b5cd9e690..e5564404ec 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.utils import cstr, flt -import json +import json, copy class ItemVariantExistsError(frappe.ValidationError): pass class InvalidItemAttributeValueError(frappe.ValidationError): pass @@ -175,18 +175,28 @@ def copy_attributes_to_variant(item, variant): # copy non no-copy fields 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': # don't copy manufacturer values if based on part no exclude_fields += ['manufacturer', 'manufacturer_part_no'] 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: # "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 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.has_variants = 0 diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 9f4c2b9c35..460ddc6210 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -61,7 +61,7 @@ class Project(Document): self.send_welcome_email() 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)) def validate_dates(self): diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 34e3af6102..c3f399a536 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -120,6 +120,8 @@ class TestItem(unittest.TestCase): self.assertRaises(ItemVariantExistsError, variant.save) 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'}] allow_fields = [d.get('field_name') for d in fields] set_item_variant_settings(fields) diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js index df78572dcb..24f7e31a0c 100644 --- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js +++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js @@ -5,7 +5,7 @@ frappe.ui.form.on('Item Variant Settings', { setup: function(frm) { const allow_fields = []; 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.get_meta('Item').fields.forEach(d => { diff --git a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py index 0c6acd4290..678de1a9ba 100644 --- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py +++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py @@ -12,7 +12,7 @@ class ItemVariantSettings(Document): fields = frappe.get_meta('Item').fields exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website", "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"] for d in fields: diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 4bcbcc4b6f..0aecb78ddd 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -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.stock_ledger import get_previous_sle 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 erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry 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) sle = get_sle(item_code = item_code, warehouse = warehouse)[0] + self.assertEqual([[1, 10]], frappe.safe_eval(sle.stock_queue)) # negative qty @@ -74,7 +75,6 @@ class TestStockEntry(unittest.TestCase): frappe.db.set_default("allow_negative_stock", 0) def test_auto_material_request(self): - from erpnext.stock.doctype.item.test_item import make_item_variant make_item_variant() self._test_auto_material_request("_Test Item") 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): fields = [{'field_name': 'reorder_levels'}] set_item_variant_settings(fields) + make_item_variant() template = frappe.get_doc("Item", "_Test Variant Item") if not template.reorder_levels: diff --git a/erpnext/stock/doctype/warehouse/test_records.json b/erpnext/stock/doctype/warehouse/test_records.json index af3bd231fc..014cf3e501 100644 --- a/erpnext/stock/doctype/warehouse/test_records.json +++ b/erpnext/stock/doctype/warehouse/test_records.json @@ -13,13 +13,6 @@ "warehouse_name": "_Test Scrap Warehouse", "is_group": 0 }, - { - "company": "_Test Company", - "create_account_under": "Stock Assets - _TC", - "doctype": "Warehouse", - "warehouse_name": "_Test Warehouse", - "is_group": 0 - }, { "company": "_Test Company", "create_account_under": "Fixed Assets - _TC", diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 0e3a4f9525..65310aa9e3 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -25,7 +25,7 @@ class TransactionBase(StatusUpdater): if not getattr(self, 'set_posting_time', None): now = now_datetime() 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): if cstr(self.contact_by) != cstr(self._prev.contact_by) or \