diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 4dae78c8c4..900a6e9d95 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1084,7 +1084,7 @@ class TestSalesInvoice(unittest.TestCase): si.items[0].price_list_rate = price_list_rate si.items[0].margin_type = 'Percentage' si.items[0].margin_rate_or_amount = 25 - si.insert() + si.save() self.assertEqual(si.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate)) def test_outstanding_amount_after_advance_jv_cancelation(self): diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index ff11eb258d..5b5cd9e690 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -174,7 +174,8 @@ def copy_attributes_to_variant(item, variant): # copy non no-copy fields - exclude_fields = ["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"] if item.variant_based_on=='Manufacturer': # don't copy manufacturer values if based on part no @@ -186,6 +187,7 @@ def copy_attributes_to_variant(item, variant): 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)) + variant.variant_of = item.name variant.has_variants = 0 if not variant.description: diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index f04fddfae3..31aedb38f0 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -370,8 +370,13 @@ class ProductionOrder(Document): self.actual_start_date = None self.actual_end_date = None if self.get("operations"): - self.actual_start_date = min([d.actual_start_time for d in self.get("operations") if d.actual_start_time]) - self.actual_end_date = max([d.actual_end_time for d in self.get("operations") if d.actual_end_time]) + actual_start_dates = [d.actual_start_time for d in self.get("operations") if d.actual_start_time] + if actual_start_dates: + self.actual_start_date = min(actual_start_dates) + + actual_end_dates = [d.actual_end_time for d in self.get("operations") if d.actual_end_time] + if actual_end_dates: + self.actual_end_date = max(actual_end_dates) def delete_timesheet(self): for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}): diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 2cb93f02d1..9f4c2b9c35 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -53,12 +53,17 @@ class Project(Document): return frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc") def validate(self): + self.validate_project_name() self.validate_dates() self.validate_weights() self.sync_tasks() self.tasks = [] self.send_welcome_email() + def validate_project_name(self): + if frappe.db.exists("Project", self.project_name): + frappe.throw(_("Project {0} already exists").format(self.project_name)) + def validate_dates(self): if self.expected_start_date and self.expected_end_date: if getdate(self.expected_end_date) < getdate(self.expected_start_date): diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index fb40e32e37..4e23591e07 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -12,7 +12,7 @@ def setup(company=None, patch=True): make_custom_fields() add_permissions() add_custom_roles_for_reports() - frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes') + frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes', now=frappe.flags.in_test) add_print_formats() if not patch: update_address_template() diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index 7c0d7f9dca..9c5c82edc4 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -494,7 +494,7 @@ class TestSalesOrder(unittest.TestCase): so.items[0].price_list_rate = price_list_rate = 100 so.items[0].margin_type = 'Percentage' so.items[0].margin_rate_or_amount = 25 - so.insert() + so.save() new_so = frappe.copy_doc(so) new_so.save(ignore_permissions=True) 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 f3404cc78b..df78572dcb 100644 --- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js +++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.js @@ -4,8 +4,8 @@ frappe.ui.form.on('Item Variant Settings', { setup: function(frm) { const allow_fields = []; - const exclude_fields = ["item_code", "item_name", "show_in_website", "show_variant_in_website", - "opening_stock", "variant_of", "valuation_rate", "variant_based_on"]; + 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"]; 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 80462d1ab8..0c6acd4290 100644 --- a/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py +++ b/erpnext/stock/doctype/item_variant_settings/item_variant_settings.py @@ -10,8 +10,8 @@ class ItemVariantSettings(Document): def set_default_fields(self): self.fields = [] fields = frappe.get_meta('Item').fields - exclude_fields = ["item_code", "item_name", "show_in_website", "show_variant_in_website", - "standard_rate", "opening_stock", "image", "description", + 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", "website_image", "thumbnail", "website_specifiations", "web_long_description"]