Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: refactor Asset Repair and Stock Entry linkage to resolve amendme… #41919

Merged
45 changes: 39 additions & 6 deletions erpnext/assets/doctype/asset_repair/asset_repair.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ frappe.ui.form.on("Asset Repair", {
};
};

frm.fields_dict.warehouse.get_query = function (doc) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same filter should be applied to the warehouse field in the child table.

frm.set_query("warehouse", "stock_items", function () {
return {
filters: {
is_group: 0,
company: doc.company,
company: frm.doc.company,
},
};
};
});

frm.set_query("serial_and_batch_bundle", "stock_items", (doc, cdt, cdn) => {
let row = locals[cdt][cdn];
Expand Down Expand Up @@ -79,23 +79,56 @@ frappe.ui.form.on("Asset Repair", {
});
}

if (frm.doc.repair_status == "Completed") {
if (frm.doc.repair_status == "Completed" && !frm.doc.completion_date) {
frm.set_value("completion_date", frappe.datetime.now_datetime());
}
},

stock_items_on_form_rendered() {
erpnext.setup_serial_or_batch_no();
},

stock_consumption: function (frm) {
if (!frm.doc.stock_consumption) {
frm.clear_table("stock_items");
frm.refresh_field("stock_items");
}
},

purchase_invoice: function (frm) {
if (frm.doc.purchase_invoice) {
frappe.call({
method: "frappe.client.get_value",
args: {
doctype: "Purchase Invoice",
fieldname: "base_net_total",
filters: { name: frm.doc.purchase_invoice },
},
callback: function (r) {
if (r.message) {
frm.set_value("repair_cost", r.message.base_net_total);
}
},
});
} else {
frm.set_value("repair_cost", 0);
}
},
});

frappe.ui.form.on("Asset Repair Consumed Item", {
item_code: function (frm, cdt, cdn) {
warehouse: function (frm, cdt, cdn) {
var item = locals[cdt][cdn];

if (!item.item_code) {
frappe.msgprint(__("Please select an item code before setting the warehouse."));
frappe.model.set_value(cdt, cdn, "warehouse", "");
return;
}

let item_args = {
item_code: item.item_code,
warehouse: frm.doc.warehouse,
warehouse: item.warehouse,
qty: item.consumed_quantity,
serial_no: item.serial_no,
company: frm.doc.company,
Expand Down
26 changes: 5 additions & 21 deletions erpnext/assets/doctype/asset_repair/asset_repair.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@
"column_break_14",
"project",
"accounting_details",
"repair_cost",
"purchase_invoice",
"capitalize_repair_cost",
"stock_consumption",
"column_break_8",
"purchase_invoice",
"repair_cost",
"stock_consumption_details_section",
"warehouse",
"stock_items",
"total_repair_cost",
"stock_entry",
"asset_depreciation_details_section",
"increase_in_asset_life",
"section_break_9",
Expand Down Expand Up @@ -122,7 +120,8 @@
"default": "0",
"fieldname": "repair_cost",
"fieldtype": "Currency",
"label": "Repair Cost"
"label": "Repair Cost",
"read_only": 1
},
{
"fieldname": "amended_from",
Expand Down Expand Up @@ -218,13 +217,6 @@
"label": "Total Repair Cost",
"read_only": 1
},
{
"depends_on": "stock_consumption",
"fieldname": "warehouse",
"fieldtype": "Link",
"label": "Warehouse",
"options": "Warehouse"
},
{
"depends_on": "capitalize_repair_cost",
"fieldname": "asset_depreciation_details_section",
Expand All @@ -251,20 +243,12 @@
"fieldtype": "Link",
"label": "Company",
"options": "Company"
},
{
"fieldname": "stock_entry",
"fieldtype": "Link",
"label": "Stock Entry",
"no_copy": 1,
"options": "Stock Entry",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-03-27 13:06:35.397626",
"modified": "2024-06-13 16:14:14.398356",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Repair",
Expand Down
94 changes: 43 additions & 51 deletions erpnext/assets/doctype/asset_repair/asset_repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,25 @@ class AssetRepair(AccountsController):
repair_cost: DF.Currency
repair_status: DF.Literal["Pending", "Completed", "Cancelled"]
stock_consumption: DF.Check
stock_entry: DF.Link | None
stock_items: DF.Table[AssetRepairConsumedItem]
total_repair_cost: DF.Currency
warehouse: DF.Link | None
# end: auto-generated types

def validate(self):
self.asset_doc = frappe.get_doc("Asset", self.asset)
self.validate_dates()
self.update_status()

if self.get("stock_items"):
self.set_stock_items_cost()
self.calculate_total_repair_cost()

def validate_dates(self):
if self.completion_date and (self.failure_date > self.completion_date):
frappe.throw(
_("Completion Date can not be before Failure Date. Please adjust the dates accordingly.")
)

def update_status(self):
if self.repair_status == "Pending" and self.asset_doc.status != "Out of Order":
frappe.db.set_value("Asset", self.asset, "status", "Out of Order")
Expand Down Expand Up @@ -105,22 +110,22 @@ def before_submit(self):
if self.asset_doc.calculate_depreciation and self.increase_in_asset_life:
self.modify_depreciation_schedule()

notes = _(
"This schedule was created when Asset {0} was repaired through Asset Repair {1}."
).format(
get_link_to_form(self.asset_doc.doctype, self.asset_doc.name),
get_link_to_form(self.doctype, self.name),
)
self.asset_doc.flags.ignore_validate_update_after_submit = True
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
self.asset_doc.save()

add_asset_activity(
self.asset,
_("Asset updated after completion of Asset Repair {0}").format(
get_link_to_form("Asset Repair", self.name)
),
)
notes = _(
"This schedule was created when Asset {0} was repaired through Asset Repair {1}."
).format(
get_link_to_form(self.asset_doc.doctype, self.asset_doc.name),
get_link_to_form(self.doctype, self.name),
)
self.asset_doc.flags.ignore_validate_update_after_submit = True
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
self.asset_doc.save()

add_asset_activity(
self.asset,
_("Asset updated after completion of Asset Repair {0}").format(
get_link_to_form("Asset Repair", self.name)
),
)

def before_cancel(self):
self.asset_doc = frappe.get_doc("Asset", self.asset)
Expand All @@ -136,29 +141,28 @@ def before_cancel(self):
self.asset_doc.total_asset_cost -= self.repair_cost
self.asset_doc.additional_asset_cost -= self.repair_cost

if self.get("stock_consumption"):
self.increase_stock_quantity()
if self.get("capitalize_repair_cost"):
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
self.make_gl_entries(cancel=True)
self.db_set("stock_entry", None)
if self.asset_doc.calculate_depreciation and self.increase_in_asset_life:
self.revert_depreciation_schedule_on_cancellation()

notes = _("This schedule was created when Asset {0}'s Asset Repair {1} was cancelled.").format(
get_link_to_form(self.asset_doc.doctype, self.asset_doc.name),
get_link_to_form(self.doctype, self.name),
)
self.asset_doc.flags.ignore_validate_update_after_submit = True
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
self.asset_doc.save()

add_asset_activity(
self.asset,
_("Asset updated after cancellation of Asset Repair {0}").format(
get_link_to_form("Asset Repair", self.name)
),
)
notes = _(
"This schedule was created when Asset {0}'s Asset Repair {1} was cancelled."
).format(
get_link_to_form(self.asset_doc.doctype, self.asset_doc.name),
get_link_to_form(self.doctype, self.name),
)
self.asset_doc.flags.ignore_validate_update_after_submit = True
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
self.asset_doc.save()

add_asset_activity(
self.asset,
_("Asset updated after cancellation of Asset Repair {0}").format(
get_link_to_form("Asset Repair", self.name)
),
)

def after_delete(self):
frappe.get_doc("Asset", self.asset).set_status()
Expand All @@ -170,11 +174,6 @@ def check_repair_status(self):
def check_for_stock_items_and_warehouse(self):
if not self.get("stock_items"):
frappe.throw(_("Please enter Stock Items consumed during the Repair."), title=_("Missing Items"))
if not self.warehouse:
frappe.throw(
_("Please enter Warehouse from which Stock Items consumed during the Repair were taken."),
title=_("Missing Warehouse"),
)

def increase_asset_value(self):
total_value_of_stock_consumed = self.get_total_value_of_stock_consumed()
Expand Down Expand Up @@ -208,14 +207,15 @@ def decrease_stock_quantity(self):
stock_entry = frappe.get_doc(
{"doctype": "Stock Entry", "stock_entry_type": "Material Issue", "company": self.company}
)
stock_entry.asset_repair = self.name

for stock_item in self.get("stock_items"):
self.validate_serial_no(stock_item)

stock_entry.append(
"items",
{
"s_warehouse": self.warehouse,
"s_warehouse": stock_item.warehouse,
"item_code": stock_item.item_code,
"qty": stock_item.consumed_quantity,
"basic_rate": stock_item.valuation_rate,
Expand All @@ -228,8 +228,6 @@ def decrease_stock_quantity(self):
stock_entry.insert()
stock_entry.submit()

self.db_set("stock_entry", stock_entry.name)

def validate_serial_no(self, stock_item):
if not stock_item.serial_and_batch_bundle and frappe.get_cached_value(
"Item", stock_item.item_code, "has_serial_no"
Expand All @@ -247,12 +245,6 @@ def validate_serial_no(self, stock_item):
"Serial and Batch Bundle", stock_item.serial_and_batch_bundle, values_to_update
)

def increase_stock_quantity(self):
if self.stock_entry:
stock_entry = frappe.get_doc("Stock Entry", self.stock_entry)
stock_entry.flags.ignore_links = True
stock_entry.cancel()

def make_gl_entries(self, cancel=False):
if flt(self.total_repair_cost) > 0:
gl_entries = self.get_gl_entries()
Expand Down Expand Up @@ -316,7 +308,7 @@ def get_gl_entries_for_consumed_items(self, gl_entries, fixed_asset_account):
return

# creating GL Entries for each row in Stock Items based on the Stock Entry created for it
stock_entry = frappe.get_doc("Stock Entry", self.stock_entry)
stock_entry = frappe.get_doc("Stock Entry", {"asset_repair": self.name})

default_expense_account = None
if not erpnext.is_perpetual_inventory_enabled(self.company):
Expand Down Expand Up @@ -357,7 +349,7 @@ def get_gl_entries_for_consumed_items(self, gl_entries, fixed_asset_account):
"cost_center": self.cost_center,
"posting_date": getdate(),
"against_voucher_type": "Stock Entry",
"against_voucher": self.stock_entry,
"against_voucher": stock_entry.name,
"company": self.company,
},
item=self,
Expand Down
Loading
Loading