Merge pull request #31860 from rohitwaghchaure/delete-custom-fields-on-dimension-delete
fix: delete custom fields on deletion of inventory dimension
This commit is contained in:
commit
396667b702
@ -386,9 +386,24 @@ class StockController(AccountsController):
|
||||
def update_inventory_dimensions(self, row, sl_dict) -> None:
|
||||
dimensions = get_evaluated_inventory_dimension(row, sl_dict, parent_doc=self)
|
||||
for dimension in dimensions:
|
||||
if dimension and row.get(dimension.source_fieldname):
|
||||
if not dimension:
|
||||
continue
|
||||
|
||||
if row.get(dimension.source_fieldname):
|
||||
sl_dict[dimension.target_fieldname] = row.get(dimension.source_fieldname)
|
||||
|
||||
if not sl_dict.get(dimension.target_fieldname) and dimension.fetch_from_parent:
|
||||
sl_dict[dimension.target_fieldname] = self.get(dimension.fetch_from_parent)
|
||||
|
||||
# Get value based on doctype name
|
||||
if not sl_dict.get(dimension.target_fieldname):
|
||||
fieldname = frappe.get_cached_value(
|
||||
"DocField", {"parent": self.doctype, "options": dimension.fetch_from_parent}, "fieldname"
|
||||
)
|
||||
|
||||
if fieldname and self.get(fieldname):
|
||||
sl_dict[dimension.target_fieldname] = self.get(fieldname)
|
||||
|
||||
def make_sl_entries(self, sl_entries, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||
from erpnext.stock.stock_ledger import make_sl_entries
|
||||
|
||||
|
@ -35,14 +35,39 @@ frappe.ui.form.on('Inventory Dimension', {
|
||||
refresh(frm) {
|
||||
if (frm.doc.__onload && frm.doc.__onload.has_stock_ledger
|
||||
&& frm.doc.__onload.has_stock_ledger.length) {
|
||||
let msg = __('Stock transactions exists against this dimension, user can not update document.');
|
||||
frm.dashboard.add_comment(msg, 'blue', true);
|
||||
let allow_to_edit_fields = ['disabled', 'fetch_from_parent',
|
||||
'type_of_transaction', 'condition'];
|
||||
|
||||
frm.fields.forEach((field) => {
|
||||
if (field.df.fieldname !== 'disabled') {
|
||||
if (!in_list(allow_to_edit_fields, field.df.fieldname)) {
|
||||
frm.set_df_property(field.df.fieldname, "read_only", "1");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!frm.is_new()) {
|
||||
frm.add_custom_button(__('Delete Dimension'), () => {
|
||||
frm.trigger('delete_dimension');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
delete_dimension(frm) {
|
||||
let msg = (`
|
||||
Custom fields related to this dimension will be deleted on deletion of dimension.
|
||||
<br> Do you want to delete {0} dimension?
|
||||
`);
|
||||
|
||||
frappe.confirm(__(msg, [frm.doc.name.bold()]), () => {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.inventory_dimension.inventory_dimension.delete_dimension',
|
||||
args: {
|
||||
dimension: frm.doc.name
|
||||
},
|
||||
callback: function() {
|
||||
frappe.set_route('List', 'Inventory Dimension');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:dimension_name",
|
||||
"creation": "2022-06-17 13:04:16.554051",
|
||||
"doctype": "DocType",
|
||||
@ -22,6 +21,7 @@
|
||||
"document_type",
|
||||
"istable",
|
||||
"type_of_transaction",
|
||||
"fetch_from_parent",
|
||||
"column_break_16",
|
||||
"condition",
|
||||
"applicable_condition_example_section",
|
||||
@ -101,12 +101,14 @@
|
||||
"fieldname": "target_fieldname",
|
||||
"fieldtype": "Data",
|
||||
"label": "Target Fieldname (Stock Ledger Entry)",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "source_fieldname",
|
||||
"fieldtype": "Data",
|
||||
"label": "Source Fieldname",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@ -123,7 +125,7 @@
|
||||
"fieldname": "type_of_transaction",
|
||||
"fieldtype": "Select",
|
||||
"label": "Type of Transaction",
|
||||
"options": "\nInward\nOutward"
|
||||
"options": "\nInward\nOutward\nBoth"
|
||||
},
|
||||
{
|
||||
"fieldname": "html_19",
|
||||
@ -140,11 +142,18 @@
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "istable",
|
||||
"description": "Set fieldname or DocType name like Supplier, Customer etc.",
|
||||
"fieldname": "fetch_from_parent",
|
||||
"fieldtype": "Data",
|
||||
"label": "Fetch Value From Parent Form"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2022-07-19 21:06:11.824976",
|
||||
"modified": "2022-08-17 11:43:24.722441",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Inventory Dimension",
|
||||
|
@ -43,13 +43,37 @@ class InventoryDimension(Document):
|
||||
return
|
||||
|
||||
old_doc = self._doc_before_save
|
||||
allow_to_edit_fields = [
|
||||
"disabled",
|
||||
"fetch_from_parent",
|
||||
"type_of_transaction",
|
||||
"condition",
|
||||
]
|
||||
|
||||
for field in frappe.get_meta("Inventory Dimension").fields:
|
||||
if field.fieldname != "disabled" and old_doc.get(field.fieldname) != self.get(field.fieldname):
|
||||
if field.fieldname not in allow_to_edit_fields and old_doc.get(field.fieldname) != self.get(
|
||||
field.fieldname
|
||||
):
|
||||
msg = f"""The user can not change value of the field {bold(field.label)} because
|
||||
stock transactions exists against the dimension {bold(self.name)}."""
|
||||
|
||||
frappe.throw(_(msg), DoNotChangeError)
|
||||
|
||||
def on_trash(self):
|
||||
self.delete_custom_fields()
|
||||
|
||||
def delete_custom_fields(self):
|
||||
filters = {"fieldname": self.source_fieldname}
|
||||
|
||||
if self.document_type:
|
||||
filters["dt"] = self.document_type
|
||||
|
||||
for field in frappe.get_all("Custom Field", filters=filters):
|
||||
frappe.delete_doc("Custom Field", field.name)
|
||||
|
||||
msg = f"Deleted custom fields related to the dimension {self.name}"
|
||||
frappe.msgprint(_(msg))
|
||||
|
||||
def reset_value(self):
|
||||
if self.apply_to_all_doctypes:
|
||||
self.istable = 0
|
||||
@ -76,30 +100,35 @@ class InventoryDimension(Document):
|
||||
self.add_custom_fields()
|
||||
|
||||
def add_custom_fields(self):
|
||||
dimension_field = dict(
|
||||
fieldname=self.source_fieldname,
|
||||
fieldtype="Link",
|
||||
insert_after="warehouse",
|
||||
options=self.reference_document,
|
||||
label=self.dimension_name,
|
||||
)
|
||||
dimension_fields = [
|
||||
dict(
|
||||
fieldname="inventory_dimension",
|
||||
fieldtype="Section Break",
|
||||
insert_after="warehouse",
|
||||
label="Inventory Dimension",
|
||||
collapsible=1,
|
||||
),
|
||||
dict(
|
||||
fieldname=self.source_fieldname,
|
||||
fieldtype="Link",
|
||||
insert_after="inventory_dimension",
|
||||
options=self.reference_document,
|
||||
label=self.dimension_name,
|
||||
),
|
||||
]
|
||||
|
||||
custom_fields = {}
|
||||
|
||||
if self.apply_to_all_doctypes:
|
||||
for doctype in get_inventory_documents():
|
||||
if not frappe.db.get_value(
|
||||
"Custom Field", {"dt": doctype[0], "fieldname": self.source_fieldname}
|
||||
):
|
||||
custom_fields.setdefault(doctype[0], dimension_field)
|
||||
elif not frappe.db.get_value(
|
||||
"Custom Field", {"dt": self.document_type, "fieldname": self.source_fieldname}
|
||||
):
|
||||
custom_fields.setdefault(self.document_type, dimension_field)
|
||||
custom_fields.setdefault(doctype[0], dimension_fields)
|
||||
else:
|
||||
custom_fields.setdefault(self.document_type, dimension_fields)
|
||||
|
||||
if not frappe.db.get_value(
|
||||
"Custom Field", {"dt": "Stock Ledger Entry", "fieldname": self.target_fieldname}
|
||||
):
|
||||
dimension_field = dimension_fields[1]
|
||||
dimension_field["fieldname"] = self.target_fieldname
|
||||
custom_fields["Stock Ledger Entry"] = dimension_field
|
||||
|
||||
@ -143,7 +172,7 @@ def get_evaluated_inventory_dimension(doc, sl_dict, parent_doc=None):
|
||||
elif (
|
||||
row.type_of_transaction == "Outward"
|
||||
if doc.docstatus == 1
|
||||
else row.type_of_transaction != "Inward"
|
||||
else row.type_of_transaction != "Outward"
|
||||
) and sl_dict.actual_qty > 0:
|
||||
continue
|
||||
|
||||
@ -166,7 +195,14 @@ def get_document_wise_inventory_dimensions(doctype) -> dict:
|
||||
if not frappe.local.document_wise_inventory_dimensions.get(doctype):
|
||||
dimensions = frappe.get_all(
|
||||
"Inventory Dimension",
|
||||
fields=["name", "source_fieldname", "condition", "target_fieldname", "type_of_transaction"],
|
||||
fields=[
|
||||
"name",
|
||||
"source_fieldname",
|
||||
"condition",
|
||||
"target_fieldname",
|
||||
"type_of_transaction",
|
||||
"fetch_from_parent",
|
||||
],
|
||||
filters={"disabled": 0},
|
||||
or_filters={"document_type": doctype, "apply_to_all_doctypes": 1},
|
||||
)
|
||||
@ -194,3 +230,9 @@ def get_inventory_dimensions():
|
||||
frappe.local.inventory_dimensions = dimensions
|
||||
|
||||
return frappe.local.inventory_dimensions
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def delete_dimension(dimension):
|
||||
doc = frappe.get_doc("Inventory Dimension", dimension)
|
||||
doc.delete()
|
||||
|
@ -8,6 +8,7 @@ from erpnext.stock.doctype.inventory_dimension.inventory_dimension import (
|
||||
CanNotBeChildDoc,
|
||||
CanNotBeDefaultDimension,
|
||||
DoNotChangeError,
|
||||
delete_dimension,
|
||||
)
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
@ -42,6 +43,32 @@ class TestInventoryDimension(FrappeTestCase):
|
||||
|
||||
self.assertRaises(CanNotBeDefaultDimension, inv_dim1.insert)
|
||||
|
||||
def test_delete_inventory_dimension(self):
|
||||
inv_dim1 = create_inventory_dimension(
|
||||
reference_document="Shelf",
|
||||
type_of_transaction="Outward",
|
||||
dimension_name="From Shelf",
|
||||
apply_to_all_doctypes=0,
|
||||
document_type="Stock Entry Detail",
|
||||
condition="parent.purpose == 'Material Issue'",
|
||||
)
|
||||
|
||||
inv_dim1.save()
|
||||
|
||||
custom_field = frappe.db.get_value(
|
||||
"Custom Field", {"fieldname": "from_shelf", "dt": "Stock Entry Detail"}, "name"
|
||||
)
|
||||
|
||||
self.assertTrue(custom_field)
|
||||
|
||||
delete_dimension(inv_dim1.name)
|
||||
|
||||
custom_field = frappe.db.get_value(
|
||||
"Custom Field", {"fieldname": "from_shelf", "dt": "Stock Entry Detail"}, "name"
|
||||
)
|
||||
|
||||
self.assertFalse(custom_field)
|
||||
|
||||
def test_inventory_dimension(self):
|
||||
warehouse = "Shelf Warehouse - _TC"
|
||||
item_code = "_Test Item"
|
||||
|
Loading…
x
Reference in New Issue
Block a user