From 9e26f2d797ee17b332463e9aace65b516c0c2deb Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 9 Jul 2021 22:08:56 +0530 Subject: [PATCH 01/60] fix: Organize buttons --- erpnext/assets/doctype/asset/asset.js | 67 ++++++++++++------- erpnext/assets/doctype/asset/asset.py | 11 ++- .../doctype/asset_repair/asset_repair.json | 42 +++++------- 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 6f1bb28f37..2a57183a80 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -82,24 +82,46 @@ frappe.ui.form.on('Asset', { if (in_list(["Submitted", "Partially Depreciated", "Fully Depreciated"], frm.doc.status)) { frm.add_custom_button("Transfer Asset", function() { erpnext.asset.transfer_asset(frm); - }); + }, __("Manage")); frm.add_custom_button("Scrap Asset", function() { erpnext.asset.scrap_asset(frm); - }); + }, __("Manage")); frm.add_custom_button("Sell Asset", function() { frm.trigger("make_sales_invoice"); - }); + }, __("Manage")); } else if (frm.doc.status=='Scrapped') { frm.add_custom_button("Restore Asset", function() { erpnext.asset.restore_asset(frm); - }); + }, __("Manage")); + } + + if (frm.doc.maintenance_required && !frm.doc.maintenance_schedule) { + frm.add_custom_button(__("Maintain Asset"), function() { + frm.trigger("create_asset_maintenance"); + }, __("Manage")); + } + + frm.add_custom_button(__("Repair Asset"), function() { + frm.trigger("create_asset_repair"); + }, __("Manage")); + + if (frm.doc.status != 'Fully Depreciated') { + frm.add_custom_button(__("Adjust Asset Value"), function() { + frm.trigger("create_asset_adjustment"); + }, __("Manage")); + } + + if (!frm.doc.calculate_depreciation) { + frm.add_custom_button(__("Create Depreciation Entry"), function() { + frm.trigger("make_journal_entry"); + }, __("Manage")); } if (frm.doc.purchase_receipt || !frm.doc.is_existing_asset) { - frm.add_custom_button("General Ledger", function() { + frm.add_custom_button("View General Ledger", function() { frappe.route_options = { "voucher_no": frm.doc.name, "from_date": frm.doc.available_for_use_date, @@ -107,27 +129,10 @@ frappe.ui.form.on('Asset', { "company": frm.doc.company }; frappe.set_route("query-report", "General Ledger"); - }); + }, __("Manage")); } - if (frm.doc.maintenance_required && !frm.doc.maintenance_schedule) { - frm.add_custom_button(__("Asset Maintenance"), function() { - frm.trigger("create_asset_maintenance"); - }, __('Create')); - } - if (frm.doc.status != 'Fully Depreciated') { - frm.add_custom_button(__("Asset Value Adjustment"), function() { - frm.trigger("create_asset_adjustment"); - }, __('Create')); - } - - if (!frm.doc.calculate_depreciation) { - frm.add_custom_button(__("Depreciation Entry"), function() { - frm.trigger("make_journal_entry"); - }, __('Create')); - } - - frm.page.set_inner_btn_group_as_primary(__('Create')); + frm.page.set_inner_btn_group_as_primary(__("Manage")); frm.trigger("setup_chart"); } @@ -304,6 +309,20 @@ frappe.ui.form.on('Asset', { }) }, + create_asset_repair: function(frm) { + frappe.call({ + args: { + "asset": frm.doc.name, + "asset_name": frm.doc.asset_name + }, + method: "erpnext.assets.doctype.asset.asset.create_asset_repair", + callback: function(r) { + var doclist = frappe.model.sync(r.message); + frappe.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }) + }, + create_asset_adjustment: function(frm) { frappe.call({ args: { diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 8799275fc4..456649fa07 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -625,9 +625,18 @@ def create_asset_maintenance(asset, item_code, item_name, asset_category, compan }) return asset_maintenance +@frappe.whitelist() +def create_asset_repair(asset, asset_name): + asset_repair = frappe.new_doc("Asset Repair") + asset_repair.update({ + "asset": asset, + "asset_name": asset_name + }) + return asset_repair + @frappe.whitelist() def create_asset_adjustment(asset, asset_category, company): - asset_maintenance = frappe.new_doc("Asset Value Adjustment") + asset_maintenance = frappe.get_doc("Asset Value Adjustment") asset_maintenance.update({ "asset": asset, "company": company, diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index d338fc0fb7..853534eb31 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -8,10 +8,9 @@ "engine": "InnoDB", "field_order": [ "naming_series", - "asset_name", "column_break_2", - "item_code", - "item_name", + "asset", + "asset_name", "section_break_5", "failure_date", "assign_to", @@ -30,15 +29,6 @@ "amended_from" ], "fields": [ - { - "columns": 1, - "fieldname": "asset_name", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Asset", - "options": "Asset", - "reqd": 1 - }, { "fieldname": "naming_series", "fieldtype": "Select", @@ -50,18 +40,6 @@ "fieldname": "column_break_2", "fieldtype": "Column Break" }, - { - "fetch_from": "asset_name.item_code", - "fieldname": "item_code", - "fieldtype": "Read Only", - "label": "Item Code" - }, - { - "fetch_from": "asset_name.item_name", - "fieldname": "item_name", - "fieldtype": "Read Only", - "label": "Item Name" - }, { "fieldname": "section_break_5", "fieldtype": "Section Break", @@ -159,12 +137,26 @@ "options": "Asset Repair", "print_hide": 1, "read_only": 1 + }, + { + "columns": 1, + "fieldname": "asset", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Asset", + "options": "Asset", + "reqd": 1 + }, + { + "fieldname": "asset_name", + "fieldtype": "Read Only", + "label": "Asset Name" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-01-22 15:08:12.495850", + "modified": "2021-05-10 22:48:42.165513", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 58bc967073255a6e28eac76d4776810553ea0aa1 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 9 Jul 2021 22:10:35 +0530 Subject: [PATCH 02/60] fix: Rename 'Fixed Asset Depreciation Settings' to 'Fixed Asset Deafults' --- .../doctype/asset_repair/asset_repair.js | 4 ++++ .../doctype/asset_repair/asset_repair.json | 22 +++++++++++++++++-- .../doctype/asset_repair/asset_repair.py | 4 ++++ erpnext/setup/doctype/company/company.json | 16 +++++++------- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index 4ba2b4474a..f5eeeda5fb 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -2,6 +2,10 @@ // For license information, please see license.txt frappe.ui.form.on('Asset Repair', { + refresh: function(frm) { + frm.toggle_display(['completion_date', 'repair_status'], !(frm.doc.__islocal)); + }, + repair_status: (frm) => { if (frm.doc.completion_date && frm.doc.repair_status == "Completed") { frappe.call ({ diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 853534eb31..4ed9916392 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -7,9 +7,9 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ + "asset", "naming_series", "column_break_2", - "asset", "asset_name", "section_break_5", "failure_date", @@ -18,7 +18,10 @@ "column_break_6", "completion_date", "repair_status", + "section_break_7", "repair_cost", + "column_break_8", + "payable_account", "section_break_9", "description", "column_break_9", @@ -151,12 +154,27 @@ "fieldname": "asset_name", "fieldtype": "Read Only", "label": "Asset Name" + }, + { + "fieldname": "payable_account", + "fieldtype": "Link", + "label": "Payable Account", + "options": "Account" + }, + { + "fieldname": "section_break_7", + "fieldtype": "Section Break", + "label": "Accounting Details" + }, + { + "fieldname": "column_break_8", + "fieldtype": "Column Break" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-05-10 22:48:42.165513", + "modified": "2021-05-11 05:11:58.330860", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 049b931b5e..884dc19588 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -13,6 +13,10 @@ class AssetRepair(Document): if self.repair_status == "Completed" and not self.completion_date: frappe.throw(_("Please select Completion Date for Completed Repair")) + if self.repair_status == 'Pending': + frappe.db.set_value('Asset', self.asset, 'status', 'Out of Order') + else: + frappe.db.set_value('Asset', self.asset, 'status', 'Submitted') @frappe.whitelist() def get_downtime(failure_date, completion_date): diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 061986d92d..2d2f336e93 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -74,7 +74,7 @@ "stock_received_but_not_billed", "service_received_but_not_billed", "expenses_included_in_valuation", - "fixed_asset_depreciation_settings", + "fixed_asset_defaults", "accumulated_depreciation_account", "depreciation_expense_account", "series_for_depreciation_entry", @@ -519,12 +519,6 @@ "no_copy": 1, "options": "Account" }, - { - "collapsible": 1, - "fieldname": "fixed_asset_depreciation_settings", - "fieldtype": "Section Break", - "label": "Fixed Asset Depreciation Settings" - }, { "fieldname": "accumulated_depreciation_account", "fieldtype": "Link", @@ -734,6 +728,12 @@ "fieldtype": "Link", "label": "Default Payment Discount Account", "options": "Account" + }, + { + "collapsible": 1, + "fieldname": "fixed_asset_defaults", + "fieldtype": "Section Break", + "label": "Fixed Asset Defaults" } ], "icon": "fa fa-building", @@ -741,7 +741,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2021-05-07 03:11:28.189740", + "modified": "2021-05-11 21:45:22.803065", "modified_by": "Administrator", "module": "Setup", "name": "Company", From 42c70fba3c7c645b308d1f6f84123037a8466712 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 9 Jul 2021 22:11:50 +0530 Subject: [PATCH 03/60] fix: Modify depreciation schedule when increase_in_asset_life is not a multiple of frequency_of_depreciation) --- erpnext/assets/doctype/asset/asset.js | 1 - erpnext/assets/doctype/asset/asset.json | 23 ++- erpnext/assets/doctype/asset/asset.py | 31 +++- .../asset_maintenance/asset_maintenance.js | 3 + .../asset_maintenance/asset_maintenance.json | 31 +++- .../asset_maintenance/asset_maintenance.py | 37 ++++- .../doctype/asset_repair/asset_repair.js | 11 +- .../doctype/asset_repair/asset_repair.json | 127 ++++++++++---- .../doctype/asset_repair/asset_repair.py | 157 +++++++++++++++++- erpnext/assets/doctype/stock_item/__init__.py | 0 .../assets/doctype/stock_item/stock_item.json | 55 ++++++ .../assets/doctype/stock_item/stock_item.py | 8 + erpnext/setup/doctype/company/company.json | 9 +- 13 files changed, 444 insertions(+), 49 deletions(-) create mode 100644 erpnext/assets/doctype/stock_item/__init__.py create mode 100644 erpnext/assets/doctype/stock_item/stock_item.json create mode 100644 erpnext/assets/doctype/stock_item/stock_item.py diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 2a57183a80..1e67ec816b 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -132,7 +132,6 @@ frappe.ui.form.on('Asset', { }, __("Manage")); } - frm.page.set_inner_btn_group_as_primary(__("Manage")); frm.trigger("setup_chart"); } diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 421b9a6c37..8a0e3ad2a6 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -23,6 +23,7 @@ "asset_name", "asset_category", "location", + "asset_value", "custodian", "department", "disposal_date", @@ -53,6 +54,8 @@ "next_depreciation_date", "section_break_14", "schedules", + "to_date", + "edit_dates", "insurance_details", "policy_number", "insurer", @@ -480,6 +483,24 @@ "fieldname": "section_break_36", "fieldtype": "Section Break", "label": "Finance Books" + }, + { + "fieldname": "asset_value", + "fieldtype": "Currency", + "label": "Asset Value", + "read_only": 1 + }, + { + "fieldname": "to_date", + "fieldtype": "Date", + "hidden": 1, + "label": "To Date" + }, + { + "fieldname": "edit_dates", + "fieldtype": "Data", + "hidden": 1, + "label": "Edit Dates" } ], "idx": 72, @@ -502,7 +523,7 @@ "link_fieldname": "asset" } ], - "modified": "2021-01-22 12:38:59.091510", + "modified": "2021-05-21 12:05:29.424083", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 456649fa07..e8cfe0ae17 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -96,6 +96,9 @@ class Asset(AccountsController): finance_books = get_item_details(self.item_code, self.asset_category) self.set('finance_books', finance_books) + if not(self.asset_value): + self.asset_value = self.gross_purchase_amount + def validate_asset_values(self): if not self.asset_category: self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category") @@ -168,15 +171,23 @@ class Asset(AccountsController): d.precision("rate_of_depreciation")) def make_depreciation_schedule(self): - if 'Manual' not in [d.depreciation_method for d in self.finance_books]: + if 'Manual' not in [d.depreciation_method for d in self.finance_books] and not self.schedules: self.schedules = [] - if self.get("schedules") or not self.available_for_use_date: + if not self.available_for_use_date: return for d in self.get('finance_books'): self.validate_asset_finance_books(d) + start = 0 + for n in range (len(self.schedules)): + if not self.schedules[n].journal_entry: + print("*"*100) + del self.schedules[n:] + start = n + break + value_after_depreciation = (flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)) @@ -189,9 +200,9 @@ class Asset(AccountsController): if has_pro_rata: number_of_pending_depreciations += 1 - + skip_row = False - for n in range(number_of_pending_depreciations): + for n in range(start, number_of_pending_depreciations): # If depreciation is already completed (for double declining balance) if skip_row: continue @@ -216,11 +227,12 @@ class Asset(AccountsController): # For last row elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1: - to_date = add_months(self.available_for_use_date, - n * cint(d.frequency_of_depreciation)) + if not self.edit_dates: + self.to_date = add_months(self.available_for_use_date, + n * cint(d.frequency_of_depreciation)) - depreciation_amount, days, months = self.get_pro_rata_amt(d, - depreciation_amount, schedule_date, to_date) + depreciation_amount, days, months = get_pro_rata_amt(d, + depreciation_amount, schedule_date, self.to_date) monthly_schedule_date = add_months(schedule_date, 1) @@ -346,11 +358,12 @@ class Asset(AccountsController): if d.finance_book_id not in finance_books: accumulated_depreciation = flt(self.opening_accumulated_depreciation) value_after_depreciation = flt(self.get_value_after_depreciation(d.finance_book_id)) - finance_books.append(d.finance_book_id) + finance_books.append(int(d.finance_book_id)) depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount")) value_after_depreciation -= flt(depreciation_amount) + # for the last row, if depreciation method = Straight Line if straight_line_idx and i == max(straight_line_idx) - 1: book = self.get('finance_books')[cint(d.finance_book_id) - 1] depreciation_amount += flt(value_after_depreciation - diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js index 70b8654509..3830d1168c 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js @@ -30,7 +30,10 @@ frappe.ui.form.on('Asset Maintenance', { if(!frm.is_new()) { frm.trigger('make_dashboard'); } + + frm.toggle_display(['stock_consumption_details_section'], frm.doc.stock_consumption) }, + make_dashboard: (frm) => { if(!frm.is_new()) { frappe.call({ diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json index c0c2566fe2..da2fd75451 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json @@ -12,13 +12,17 @@ "column_break_3", "item_code", "item_name", + "stock_consumption", "section_break_6", "maintenance_team", "column_break_9", "maintenance_manager", "maintenance_manager_name", "section_break_8", - "asset_maintenance_tasks" + "asset_maintenance_tasks", + "stock_consumption_details_section", + "warehouse", + "stock_items" ], "fields": [ { @@ -100,10 +104,33 @@ "label": "Maintenance Tasks", "options": "Asset Maintenance Task", "reqd": 1 + }, + { + "default": "0", + "fieldname": "stock_consumption", + "fieldtype": "Check", + "label": "Stock Consumed During Maintenance" + }, + { + "fieldname": "stock_consumption_details_section", + "fieldtype": "Section Break", + "label": "Stock Consumption Details" + }, + { + "fieldname": "warehouse", + "fieldtype": "Link", + "label": "Warehouse", + "options": "Warehouse" + }, + { + "fieldname": "stock_items", + "fieldtype": "Table", + "label": "Stock Items", + "options": "Stock Item" } ], "links": [], - "modified": "2020-05-28 20:28:32.993823", + "modified": "2021-05-13 05:24:58.480132", "modified_by": "Administrator", "module": "Assets", "name": "Asset Maintenance", diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py index a506deec93..e3e654c398 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py @@ -19,10 +19,45 @@ class AssetMaintenance(Document): if not task.assign_to and self.docstatus == 0: throw(_("Row #{}: Please asign task to a member.").format(task.idx)) + if self.stock_consumption: + self.check_for_stock_items_and_warehouse() + self.increase_asset_value() + self.decrease_stock_quantity() + def on_update(self): for task in self.get('asset_maintenance_tasks'): assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date) - self.sync_maintenance_tasks() + self.sync_maintenance_tasks() + + def check_for_stock_items_and_warehouse(self): + if self.stock_consumption: + if not self.stock_items: + frappe.throw(_("Please enter Stock Items consumed during Asset Maintenance.")) + if not self.warehouse: + frappe.throw(_("Please enter Warehouse from which Stock Items consumed during Asset Maintenance were taken.")) + + def increase_asset_value(self): + asset_value = frappe.db.get_value('Asset', self.asset_name, 'asset_value') + for item in self.stock_items: + asset_value += item.total_value + + frappe.db.set_value('Asset', self.asset_name, 'asset_value', asset_value) + + def decrease_stock_quantity(self): + stock_entry = frappe.get_doc({ + "doctype": "Stock Entry", + "stock_entry_type": "Material Issue" + }) + + for stock_item in self.stock_items: + stock_entry.append('items', { + "s_warehouse": self.warehouse, + "item_code": stock_item.item, + "qty": stock_item.consumed_quantity + }) + + stock_entry.insert() + stock_entry.submit() def sync_maintenance_tasks(self): tasks_names = [] diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index f5eeeda5fb..7633a595a2 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -3,7 +3,16 @@ frappe.ui.form.on('Asset Repair', { refresh: function(frm) { - frm.toggle_display(['completion_date', 'repair_status'], !(frm.doc.__islocal)); + frm.toggle_display(['completion_date', 'repair_status', 'accounting_details', 'accounting_dimensions_section'], !(frm.doc.__islocal)); + + if (frm.doc.docstatus) { + frm.add_custom_button("View General Ledger", function() { + frappe.route_options = { + "voucher_no": frm.doc.name + }; + frappe.set_route("query-report", "General Ledger"); + }); + } }, repair_status: (frm) => { diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 4ed9916392..522f2874d9 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -13,20 +13,30 @@ "asset_name", "section_break_5", "failure_date", - "assign_to", - "assign_to_name", + "repair_status", "column_break_6", "completion_date", - "repair_status", - "section_break_7", + "accounting_dimensions_section", + "cost_center", + "column_break_14", + "project", + "accounting_details", "repair_cost", + "capitalize_repair_cost", + "stock_consumption", "column_break_8", - "payable_account", + "total_repair_cost", + "purchase_invoice", + "stock_consumption_details_section", + "warehouse", + "stock_items", + "asset_depreciation_details_section", + "increase_in_asset_life", "section_break_9", "description", "column_break_9", "actions_performed", - "section_break_17", + "section_break_23", "downtime", "column_break_19", "amended_from" @@ -55,20 +65,6 @@ "label": "Failure Date", "reqd": 1 }, - { - "allow_on_submit": 1, - "fieldname": "assign_to", - "fieldtype": "Link", - "label": "Assign To", - "options": "User" - }, - { - "allow_on_submit": 1, - "fetch_from": "assign_to.full_name", - "fieldname": "assign_to_name", - "fieldtype": "Read Only", - "label": "Assign To Name" - }, { "fieldname": "column_break_6", "fieldtype": "Column Break" @@ -110,10 +106,6 @@ "fieldtype": "Long Text", "label": "Actions performed" }, - { - "fieldname": "section_break_17", - "fieldtype": "Section Break" - }, { "allow_on_submit": 1, "fieldname": "downtime", @@ -151,30 +143,103 @@ "reqd": 1 }, { + "fetch_from": "asset.asset_name", "fieldname": "asset_name", "fieldtype": "Read Only", "label": "Asset Name" }, { - "fieldname": "payable_account", - "fieldtype": "Link", - "label": "Payable Account", - "options": "Account" + "fieldname": "column_break_8", + "fieldtype": "Column Break" }, { - "fieldname": "section_break_7", + "default": "0", + "fieldname": "capitalize_repair_cost", + "fieldtype": "Check", + "label": "Capitalize Repair Cost" + }, + { + "fieldname": "accounting_details", "fieldtype": "Section Break", "label": "Accounting Details" }, { - "fieldname": "column_break_8", + "fieldname": "stock_items", + "fieldtype": "Table", + "label": "Stock Items", + "options": "Stock Item" + }, + { + "fieldname": "section_break_23", + "fieldtype": "Section Break" + }, + { + "fieldname": "accounting_dimensions_section", + "fieldtype": "Section Break", + "label": "Accounting Dimensions" + }, + { + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center" + }, + { + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" + }, + { + "fieldname": "column_break_14", "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "stock_consumption", + "fieldtype": "Check", + "label": "Stock Consumed During Repair" + }, + { + "depends_on": "stock_consumption", + "fieldname": "stock_consumption_details_section", + "fieldtype": "Section Break", + "label": "Stock Consumption Details" + }, + { + "depends_on": "stock_consumption", + "fieldname": "total_repair_cost", + "fieldtype": "Currency", + "label": "Total Repair Cost" + }, + { + "fieldname": "warehouse", + "fieldtype": "Link", + "label": "Warehouse", + "options": "Warehouse" + }, + { + "depends_on": "capitalize_repair_cost", + "fieldname": "asset_depreciation_details_section", + "fieldtype": "Section Break", + "label": "Asset Depreciation Details" + }, + { + "fieldname": "increase_in_asset_life", + "fieldtype": "Int", + "label": "Increase In Asset Life(Months)" + }, + { + "fieldname": "purchase_invoice", + "fieldtype": "Link", + "label": "Purchase Invoice", + "options": "Purchase Invoice" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-05-11 05:11:58.330860", + "modified": "2021-05-21 10:37:35.002238", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 884dc19588..8fd019febd 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -5,19 +5,172 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import time_diff_in_hours +from frappe.utils import time_diff_in_hours, getdate, add_days, date_diff, add_months, flt, cint from frappe.model.document import Document +from erpnext.accounts.general_ledger import make_gl_entries class AssetRepair(Document): def validate(self): if self.repair_status == "Completed" and not self.completion_date: frappe.throw(_("Please select Completion Date for Completed Repair")) + self.update_status() + self.set_total_value() # change later + self.calculate_total_repair_cost() + + def update_status(self): if self.repair_status == 'Pending': frappe.db.set_value('Asset', self.asset, 'status', 'Out of Order') else: - frappe.db.set_value('Asset', self.asset, 'status', 'Submitted') + asset = frappe.get_doc('Asset', self.asset) + asset.set_status() + def set_total_value(self): + for item in self.stock_items: + item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) + + def calculate_total_repair_cost(self): + self.total_repair_cost = self.repair_cost + if self.stock_consumption: + for item in self.stock_items: + self.total_repair_cost += item.total_value + + def on_submit(self): + self.check_repair_status() + self.check_for_cost_center() + + if self.stock_consumption or self.capitalize_repair_cost: + self.increase_asset_value() + if self.stock_consumption: + self.check_for_stock_items_and_warehouse() + self.decrease_stock_quantity() + if self.capitalize_repair_cost: + self.check_for_purchase_invoice() + self.make_gl_entries() + self.modify_depreciation_schedule() + + def check_repair_status(self): + if self.repair_status == "Pending": + frappe.throw(_("Please update Repair Status.")) + + def check_for_stock_items_and_warehouse(self): + if not self.stock_items: + frappe.throw(_("Please enter Stock Items consumed during Asset Repair.")) + if not self.warehouse: + frappe.throw(_("Please enter Warehouse from which Stock Items consumed during Asset Repair were taken.")) + + def check_for_cost_center(self): + if not self.cost_center: + frappe.throw(_("Please enter Cost Center.")) + + def increase_asset_value(self): + asset_value = frappe.db.get_value('Asset', self.asset, 'asset_value') + for item in self.stock_items: + asset_value += item.total_value + + if self.capitalize_repair_cost: + asset_value += self.repair_cost + frappe.db.set_value('Asset', self.asset, 'asset_value', asset_value) + + def decrease_stock_quantity(self): + stock_entry = frappe.get_doc({ + "doctype": "Stock Entry", + "stock_entry_type": "Material Issue" + }) + + for stock_item in self.stock_items: + stock_entry.append('items', { + "s_warehouse": self.warehouse, + "item_code": stock_item.item, + "qty": stock_item.consumed_quantity + }) + + stock_entry.insert() + stock_entry.submit() + + def check_for_purchase_invoice(self): + if not self.purchase_invoice: + frappe.throw(_("Please link Purchase Invoice.")) + + def on_cancel(self): + self.make_gl_entries(cancel=True) + + def make_gl_entries(self, cancel=False): + if flt(self.repair_cost) > 0: + gl_entries = self.get_gl_entries() + make_gl_entries(gl_entries, cancel) + + def get_gl_entries(self): + gl_entry = [] + company = frappe.db.get_value('Asset', self.asset, 'company') + repair_and_maintenance_account = frappe.db.get_value('Company', company, 'repair_and_maintenance_account') + fixed_asset_account = self.get_fixed_asset_account() + expense_account = frappe.get_doc('Purchase Invoice', self.purchase_invoice).items[0].expense_account + + gl_entry = frappe.get_doc({ + "doctype": "GL Entry", + "account": expense_account, + "credit": self.total_repair_cost, + "credit_in_account_currency": self.total_repair_cost, + "against": repair_and_maintenance_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate() + }) + gl_entry.insert() + gl_entry = frappe.get_doc({ + "doctype": "GL Entry", + "account": fixed_asset_account, + "debit": self.total_repair_cost, + "debit_in_account_currency": self.total_repair_cost, + "against": expense_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate(), + "against_voucher_type": "Purchase Invoice", + "against_voucher": self.purchase_invoice + }) + gl_entry.insert() + + def get_fixed_asset_account(self): + asset_category = frappe.get_doc('Asset Category', frappe.db.get_value('Asset', self.asset, 'asset_category')) + company = frappe.db.get_value('Asset', self.asset, 'company') + for account in asset_category.accounts: + if account.company_name == company: + return account.fixed_asset_account + + def modify_depreciation_schedule(self): + if self.increase_in_asset_life: + asset = frappe.get_doc('Asset', self.asset) + asset.flags.ignore_validate_update_after_submit = True + for row in asset.finance_books: + row.total_number_of_depreciations += self.increase_in_asset_life/row.frequency_of_depreciation + + asset.edit_dates = "" + extra_months = self.increase_in_asset_life % row.frequency_of_depreciation + if extra_months != 0: + self.calculate_last_schedule_date(asset, row, extra_months) + # fix depreciation amount + + asset.prepare_depreciation_data() + asset.save() + + # to help modify depreciation schedule when increase_in_asset_life is not a multiple of frequency_of_depreciation + def calculate_last_schedule_date(self, asset, row, extra_months): + asset.edit_dates = "Don't Edit" + number_of_pending_depreciations = cint(row.total_number_of_depreciations) - \ + cint(asset.number_of_depreciations_booked) + last_schedule_date = asset.schedules[len(asset.schedules)-1].schedule_date + asset.to_date = add_months(last_schedule_date, extra_months) + schedule_date = add_months(row.depreciation_start_date, + number_of_pending_depreciations * cint(row.frequency_of_depreciation)) + + if asset.to_date > schedule_date: + row.total_number_of_depreciations += 1 + + @frappe.whitelist() def get_downtime(failure_date, completion_date): downtime = time_diff_in_hours(completion_date, failure_date) diff --git a/erpnext/assets/doctype/stock_item/__init__.py b/erpnext/assets/doctype/stock_item/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/assets/doctype/stock_item/stock_item.json b/erpnext/assets/doctype/stock_item/stock_item.json new file mode 100644 index 0000000000..b1f05db395 --- /dev/null +++ b/erpnext/assets/doctype/stock_item/stock_item.json @@ -0,0 +1,55 @@ +{ + "actions": [], + "creation": "2021-05-12 02:41:54.161024", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "item", + "valuation_rate", + "consumed_quantity", + "total_value" + ], + "fields": [ + { + "fieldname": "item", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item", + "options": "Item" + }, + { + "fetch_from": "item.valuation_rate", + "fieldname": "valuation_rate", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Valuation Rate", + "read_only": 1 + }, + { + "fieldname": "consumed_quantity", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Consumed Quantity" + }, + { + "fieldname": "total_value", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Total Value", + "read_only": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-05-12 03:19:55.006300", + "modified_by": "Administrator", + "module": "Assets", + "name": "Stock Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/assets/doctype/stock_item/stock_item.py b/erpnext/assets/doctype/stock_item/stock_item.py new file mode 100644 index 0000000000..0e3cc3f8ba --- /dev/null +++ b/erpnext/assets/doctype/stock_item/stock_item.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class StockItem(Document): + pass diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 2d2f336e93..e6ec496a65 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -83,6 +83,7 @@ "disposal_account", "depreciation_cost_center", "capital_work_in_progress_account", + "repair_and_maintenance_account", "asset_received_but_not_billed", "budget_detail", "exception_budget_approver_role", @@ -734,6 +735,12 @@ "fieldname": "fixed_asset_defaults", "fieldtype": "Section Break", "label": "Fixed Asset Defaults" + }, + { + "fieldname": "repair_and_maintenance_account", + "fieldtype": "Link", + "label": "Repair and Maintenance Account", + "options": "Account" } ], "icon": "fa fa-building", @@ -741,7 +748,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2021-05-11 21:45:22.803065", + "modified": "2021-05-12 16:51:08.187233", "modified_by": "Administrator", "module": "Setup", "name": "Company", From 4e284433d17e7830c8c4a33885c2d82db689b926 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 9 Jul 2021 22:12:46 +0530 Subject: [PATCH 04/60] fix: Fix depreciation_amount calculation --- erpnext/assets/doctype/asset/asset.py | 15 +++++++++------ .../assets/doctype/asset_repair/asset_repair.py | 1 - 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index e8cfe0ae17..3bd20023ab 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -183,13 +183,12 @@ class Asset(AccountsController): start = 0 for n in range (len(self.schedules)): if not self.schedules[n].journal_entry: - print("*"*100) del self.schedules[n:] start = n break - value_after_depreciation = (flt(self.gross_purchase_amount) - - flt(self.opening_accumulated_depreciation)) + value_after_depreciation = (flt(self.asset_value) - + flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) d.value_after_depreciation = value_after_depreciation @@ -779,9 +778,13 @@ def get_depreciation_amount(asset, depreciable_value, row): depreciation_left = flt(row.total_number_of_depreciations) - flt(asset.number_of_depreciations_booked) if row.depreciation_method in ("Straight Line", "Manual"): - depreciation_amount = (flt(row.value_after_depreciation) - - flt(row.expected_value_after_useful_life)) / depreciation_left + if not asset.to_date: + depreciation_amount = (flt(row.value_after_depreciation) - + flt(row.expected_value_after_useful_life)) / depreciation_left + else: + depreciation_amount = (flt(row.value_after_depreciation) - + flt(row.expected_value_after_useful_life)) / (date_diff(asset.to_date, asset.available_for_use_date) / 365) else: depreciation_amount = flt(depreciable_value * (flt(row.rate_of_depreciation) / 100)) - return depreciation_amount \ No newline at end of file + return depreciation_amount diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 8fd019febd..9973afd80a 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -152,7 +152,6 @@ class AssetRepair(Document): extra_months = self.increase_in_asset_life % row.frequency_of_depreciation if extra_months != 0: self.calculate_last_schedule_date(asset, row, extra_months) - # fix depreciation amount asset.prepare_depreciation_data() asset.save() From 97193a46324dd0c10650e4f51111eea323555602 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 9 Jul 2021 22:15:10 +0530 Subject: [PATCH 05/60] fix: Sider issues --- erpnext/assets/doctype/asset/asset.js | 2 +- erpnext/assets/doctype/asset/asset.py | 2 +- erpnext/assets/doctype/asset_maintenance/asset_maintenance.js | 2 +- erpnext/assets/doctype/asset_repair/asset_repair.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 1e67ec816b..922cc4a7b2 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -319,7 +319,7 @@ frappe.ui.form.on('Asset', { var doclist = frappe.model.sync(r.message); frappe.set_route("Form", doclist[0].doctype, doclist[0].name); } - }) + }); }, create_asset_adjustment: function(frm) { diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 3bd20023ab..b3d3a198c3 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -181,7 +181,7 @@ class Asset(AccountsController): self.validate_asset_finance_books(d) start = 0 - for n in range (len(self.schedules)): + for n in range(len(self.schedules)): if not self.schedules[n].journal_entry: del self.schedules[n:] start = n diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js index 3830d1168c..19393b7e9d 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js @@ -31,7 +31,7 @@ frappe.ui.form.on('Asset Maintenance', { frm.trigger('make_dashboard'); } - frm.toggle_display(['stock_consumption_details_section'], frm.doc.stock_consumption) + frm.toggle_display(['stock_consumption_details_section'], frm.doc.stock_consumption); }, make_dashboard: (frm) => { diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 9973afd80a..3e81ba55b0 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import time_diff_in_hours, getdate, add_days, date_diff, add_months, flt, cint +from frappe.utils import time_diff_in_hours, getdate, add_months, flt, cint from frappe.model.document import Document from erpnext.accounts.general_ledger import make_gl_entries From 794807ecc3bb709a0cfdb0bb5ee7aa50c0399698 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 04:55:49 +0530 Subject: [PATCH 06/60] fix(Asset Repair): Only modify depreciation schedule if calculate_depreciation is checked --- erpnext/assets/doctype/asset_repair/asset_repair.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 3e81ba55b0..e3093df7fb 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -47,7 +47,8 @@ class AssetRepair(Document): if self.capitalize_repair_cost: self.check_for_purchase_invoice() self.make_gl_entries() - self.modify_depreciation_schedule() + if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation'): + self.modify_depreciation_schedule() def check_repair_status(self): if self.repair_status == "Pending": From c6ed66ec5b54b96a455452f33c927989fb9ab586 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 21:07:07 +0530 Subject: [PATCH 07/60] fix(Asset Repair): Remove unnecessary condition --- erpnext/assets/doctype/asset_repair/asset_repair.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index e3093df7fb..070e7b0a9b 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -72,7 +72,7 @@ class AssetRepair(Document): if self.capitalize_repair_cost: asset_value += self.repair_cost frappe.db.set_value('Asset', self.asset, 'asset_value', asset_value) - + def decrease_stock_quantity(self): stock_entry = frappe.get_doc({ "doctype": "Stock Entry", From 3f9f0ffdfe504646b09e76fe7554bf31816ca0d4 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 21:28:58 +0530 Subject: [PATCH 08/60] fix(Asset Repair): Add Company in GL Entries --- erpnext/assets/doctype/asset_repair/asset_repair.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 070e7b0a9b..9f09643864 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -117,7 +117,8 @@ class AssetRepair(Document): "voucher_type": self.doctype, "voucher_no": self.name, "cost_center": self.cost_center, - "posting_date": getdate() + "posting_date": getdate(), + "company": company }) gl_entry.insert() gl_entry = frappe.get_doc({ @@ -131,7 +132,8 @@ class AssetRepair(Document): "cost_center": self.cost_center, "posting_date": getdate(), "against_voucher_type": "Purchase Invoice", - "against_voucher": self.purchase_invoice + "against_voucher": self.purchase_invoice, + "company": company }) gl_entry.insert() From 70de9744965045c6302ac63f0ec1eb3004c4efe5 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 22:28:30 +0530 Subject: [PATCH 09/60] fix(Asset): Add depreciation schedule details in create_asset() --- erpnext/assets/doctype/asset/test_asset.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 8845f24d10..29fbc9f15d 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -699,7 +699,7 @@ def create_asset(**args): "item_code": args.item_code or "Macbook Pro", "company": args.company or"_Test Company", "purchase_date": "2015-01-01", - "calculate_depreciation": 0, + "calculate_depreciation": args.calculate_depreciation or 0, "gross_purchase_amount": 100000, "purchase_receipt_amount": 100000, "expected_value_after_useful_life": 10000, @@ -710,6 +710,13 @@ def create_asset(**args): "is_existing_asset": args.is_existing_asset or 0 }) + if asset.calculate_depreciation: + asset.append("finance_books", { + "depreciation_method": "Straight Line", + "frequency_of_depreciation": 12, + "total_number_of_depreciations": 5 + }) + try: asset.save() except frappe.DuplicateEntryError: From 2833903ce570abd3a2d5a68adf6dd5c4afac42b6 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 22:28:57 +0530 Subject: [PATCH 10/60] fix(Asset Repair): Add tests --- .../doctype/asset_repair/asset_repair.py | 1 - .../doctype/asset_repair/test_asset_repair.py | 166 +++++++++++++++++- 2 files changed, 164 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 9f09643864..4ca6fbc5d0 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -172,7 +172,6 @@ class AssetRepair(Document): if asset.to_date > schedule_date: row.total_number_of_depreciations += 1 - @frappe.whitelist() def get_downtime(failure_date, completion_date): downtime = time_diff_in_hours(completion_date, failure_date) diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index 3d325a9683..9c9dd44971 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -2,8 +2,170 @@ # Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt from __future__ import unicode_literals - +import frappe +from frappe.utils import nowdate, flt import unittest +from erpnext.assets.doctype.asset.test_asset import create_asset_data, create_asset, set_depreciation_settings_in_company class TestAssetRepair(unittest.TestCase): - pass + def setUp(self): + set_depreciation_settings_in_company() + create_asset_data() + frappe.db.sql("delete from `tabTax Rule`") + + def test_completion_date(self): + asset_repair = create_asset_repair() + asset_repair.repair_status = "Completed" + asset_repair.save() + self.assertTrue(asset_repair.completion_date) + + def test_update_status(self): + asset = create_asset() + initial_status = asset.status + asset_repair = create_asset_repair(asset = asset) + + if asset_repair.repair_status == "Pending": + asset.reload() + self.assertEqual(asset.status, "Out of Order") + + asset_repair.repair_status = "Completed" + asset_repair.save() + asset_status = frappe.db.get_value("Asset", asset_repair.asset, "status") + self.assertEqual(asset_status, initial_status) + + def test_stock_item_total_value(self): + asset_repair = create_asset_repair(stock_consumption = 1) + + for item in asset_repair.stock_items: + total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) + self.assertEqual(item.total_value, total_value) + + def test_total_repair_cost(self): + asset_repair = create_asset_repair(stock_consumption = 1) + + total_repair_cost = asset_repair.repair_cost + self.assertEqual(total_repair_cost, asset_repair.repair_cost) + for item in asset_repair.stock_items: + total_repair_cost += item.total_value + + self.assertEqual(total_repair_cost, asset_repair.total_repair_cost) + + def test_repair_status_after_submit(self): + asset_repair = create_asset_repair(submit = 1) + self.assertNotEqual(asset_repair.repair_status, "Pending") + + def test_stock_items(self): + asset_repair = create_asset_repair(stock_consumption = 1) + self.assertTrue(asset_repair.stock_consumption) + self.assertTrue(asset_repair.stock_items) + + def test_warehouse(self): + asset_repair = create_asset_repair(stock_consumption = 1) + self.assertTrue(asset_repair.stock_consumption) + self.assertTrue(asset_repair.warehouse) + + def test_decrease_stock_quantity(self): + asset_repair = create_asset_repair(stock_consumption = 1, submit = 1) + stock_entry = frappe.get_last_doc('Stock Entry') + + self.assertEqual(stock_entry.stock_entry_type, "Material Issue") + self.assertEqual(stock_entry.items[0].s_warehouse, asset_repair.warehouse) + self.assertEqual(stock_entry.items[0].item_code, asset_repair.stock_items[0].item) + self.assertEqual(stock_entry.items[0].qty, asset_repair.stock_items[0].consumed_quantity) + + def test_increase_in_asset_value_due_to_stock_consumption(self): + asset = create_asset() + initial_asset_value = asset.asset_value + asset_repair = create_asset_repair(asset= asset, stock_consumption = 1, submit = 1) + asset.reload() + + increase_in_asset_value = asset.asset_value - initial_asset_value + self.assertEqual(asset_repair.stock_items[0].total_value, increase_in_asset_value) + + def test_increase_in_asset_value_due_to_repair_cost_capitalisation(self): + asset = create_asset() + initial_asset_value = asset.asset_value + asset_repair = create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1) + asset.reload() + + increase_in_asset_value = asset.asset_value - initial_asset_value + self.assertEqual(asset_repair.repair_cost, increase_in_asset_value) + + def test_purchase_invoice(self): + asset_repair = create_asset_repair(capitalize_repair_cost = 1, submit = 1) + self.assertTrue(asset_repair.purchase_invoice) + + def test_gl_entries(self): + asset_repair = create_asset_repair(capitalize_repair_cost = 1, submit = 1) + gl_entry = frappe.get_last_doc('GL Entry') + self.assertEqual(asset_repair.name, gl_entry.voucher_no) + + def test_increase_in_asset_life(self): + asset = create_asset(calculate_depreciation = 1) + initial_num_of_depreciations = num_of_depreciations(asset) + create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1) + asset.reload() + self.assertEqual((initial_num_of_depreciations + 1), num_of_depreciations(asset)) + +def num_of_depreciations(asset): + return asset.finance_books[0].total_number_of_depreciations + +def create_asset_repair(**args): + from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse + from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice + + args = frappe._dict(args) + + if args.asset: + asset = args.asset + else: + asset = create_asset(is_existing_asset = 1) + asset_repair = frappe.new_doc("Asset Repair") + asset_repair.update({ + "asset": asset.name, + "asset_name": asset.asset_name, + "failure_date": nowdate(), + "description": "Test Description", + "repair_cost": 0 + }) + + if args.stock_consumption: + asset_repair.stock_consumption = 1 + asset_repair.warehouse = create_warehouse("Test Warehouse", company = asset.company) + asset_repair.append("stock_items", { + "item": args.item or args.item_code or "_Test Item", + "valuation_rate": args.rate if args.get("rate") is not None else 100, + "consumed_quantity": args.qty or 1 + }) + + try: + asset_repair.save() + except frappe.DuplicateEntryError: + pass + + if args.submit: + asset_repair.repair_status = "Completed" + asset_repair.cost_center = "_Test Cost Center - _TC" + + if args.stock_consumption: + stock_entry = frappe.get_doc({ + "doctype": "Stock Entry", + "stock_entry_type": "Material Receipt", + "company": asset.company + }) + stock_entry.append('items', { + "t_warehouse": asset_repair.warehouse, + "item_code": asset_repair.stock_items[0].item, + "qty": asset_repair.stock_items[0].consumed_quantity + }) + stock_entry.submit() + + if args.capitalize_repair_cost: + asset_repair.capitalize_repair_cost = 1 + asset_repair.repair_cost = 1000 + if asset.calculate_depreciation: + asset_repair.increase_in_asset_life = 12 + asset_repair.purchase_invoice = make_purchase_invoice().name + + asset_repair.submit() + return asset_repair \ No newline at end of file From 65b2f9234b46f8e6442292bb0e54d56dd6841a46 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 3 Jun 2021 01:54:44 +0530 Subject: [PATCH 11/60] fix(Asset Repair): Set company when creating Stock Entry --- erpnext/assets/doctype/asset_repair/asset_repair.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 4ca6fbc5d0..6a5776a835 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -76,7 +76,8 @@ class AssetRepair(Document): def decrease_stock_quantity(self): stock_entry = frappe.get_doc({ "doctype": "Stock Entry", - "stock_entry_type": "Material Issue" + "stock_entry_type": "Material Issue", + "company": frappe.get_value('Asset', self.asset, "company") }) for stock_item in self.stock_items: From 4e620c3b32381b97fb44c50f0608bd6522d10668 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 15 Jun 2021 12:02:07 +0530 Subject: [PATCH 12/60] fix: Set asset_name as title --- erpnext/assets/doctype/asset_repair/asset_repair.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 522f2874d9..640762d82c 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -239,7 +239,8 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-05-21 10:37:35.002238", + "modified": "2021-06-15 10:34:00.839353", + "title_field": "asset_name", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From fd272569aa1bb8e35c65d982691c32402cf6cdd2 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 07:03:32 +0530 Subject: [PATCH 13/60] fix(Asset Repair): Display fields according to the state of the doc --- erpnext/assets/doctype/asset_repair/asset_repair.js | 2 -- erpnext/assets/doctype/asset_repair/asset_repair.json | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index 7633a595a2..fdb8d0af67 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -3,8 +3,6 @@ frappe.ui.form.on('Asset Repair', { refresh: function(frm) { - frm.toggle_display(['completion_date', 'repair_status', 'accounting_details', 'accounting_dimensions_section'], !(frm.doc.__islocal)); - if (frm.doc.docstatus) { frm.add_custom_button("View General Ledger", function() { frappe.route_options = { diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 640762d82c..baae93d468 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -71,6 +71,7 @@ }, { "allow_on_submit": 1, + "depends_on": "eval:!doc.__islocal", "fieldname": "completion_date", "fieldtype": "Datetime", "label": "Completion Date" @@ -78,6 +79,7 @@ { "allow_on_submit": 1, "default": "Pending", + "depends_on": "eval:!doc.__islocal", "fieldname": "repair_status", "fieldtype": "Select", "label": "Repair Status", @@ -154,6 +156,7 @@ }, { "default": "0", + "depends_on": "eval:!doc.__islocal", "fieldname": "capitalize_repair_cost", "fieldtype": "Check", "label": "Capitalize Repair Cost" @@ -196,6 +199,7 @@ }, { "default": "0", + "depends_on": "eval:!doc.__islocal", "fieldname": "stock_consumption", "fieldtype": "Check", "label": "Stock Consumed During Repair" @@ -230,6 +234,7 @@ "label": "Increase In Asset Life(Months)" }, { + "depends_on": "eval:!doc.__islocal", "fieldname": "purchase_invoice", "fieldtype": "Link", "label": "Purchase Invoice", @@ -239,8 +244,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-15 10:34:00.839353", - "title_field": "asset_name", + "modified": "2021-06-16 07:01:28.217619", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", @@ -279,6 +283,7 @@ ], "sort_field": "modified", "sort_order": "DESC", + "title_field": "asset_name", "track_changes": 1, "track_seen": 1 } \ No newline at end of file From 654074ad7a3e55a4bf073e7c6f9e11195a12bfcd Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 07:50:03 +0530 Subject: [PATCH 14/60] fix(Asset Repair): Add title to error messages --- erpnext/assets/doctype/asset_repair/asset_repair.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 6a5776a835..6565f356ae 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -56,9 +56,9 @@ class AssetRepair(Document): def check_for_stock_items_and_warehouse(self): if not self.stock_items: - frappe.throw(_("Please enter Stock Items consumed during Asset Repair.")) + 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 Asset Repair were taken.")) + frappe.throw(_("Please enter Warehouse from which Stock Items consumed during the Repair were taken."), title=_("Missing Warehouse")) def check_for_cost_center(self): if not self.cost_center: From 5ab0cabf911581fe27cff997b326c76c6c90d777 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 07:56:40 +0530 Subject: [PATCH 15/60] fix(Asset Repair): Make Stock Items and Warehouse mandatory if stock_consumption is checked --- erpnext/assets/doctype/asset_repair/asset_repair.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index baae93d468..17d33c41ec 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -170,6 +170,7 @@ "fieldname": "stock_items", "fieldtype": "Table", "label": "Stock Items", + "mandatory_depends_on": "stock_consumption", "options": "Stock Item" }, { @@ -217,6 +218,7 @@ "label": "Total Repair Cost" }, { + "depends_on": "stock_consumption", "fieldname": "warehouse", "fieldtype": "Link", "label": "Warehouse", @@ -244,7 +246,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-16 07:01:28.217619", + "modified": "2021-06-16 07:52:49.438800", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 867fd02b2dfb1d54a823cabc1f0ebaef295ccc6f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:07:06 +0530 Subject: [PATCH 16/60] fix(Asset Repair): Add Company field --- .../assets/doctype/asset_repair/asset_repair.json | 10 +++++++++- erpnext/assets/doctype/asset_repair/asset_repair.py | 12 +++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 17d33c41ec..840589ca2e 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -11,6 +11,7 @@ "naming_series", "column_break_2", "asset_name", + "company", "section_break_5", "failure_date", "repair_status", @@ -241,12 +242,19 @@ "fieldtype": "Link", "label": "Purchase Invoice", "options": "Purchase Invoice" + }, + { + "fetch_from": "asset.company", + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-16 07:52:49.438800", + "modified": "2021-06-16 08:02:34.782990", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 6565f356ae..bd5e462f13 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -77,7 +77,7 @@ class AssetRepair(Document): stock_entry = frappe.get_doc({ "doctype": "Stock Entry", "stock_entry_type": "Material Issue", - "company": frappe.get_value('Asset', self.asset, "company") + "company": self.company }) for stock_item in self.stock_items: @@ -104,8 +104,7 @@ class AssetRepair(Document): def get_gl_entries(self): gl_entry = [] - company = frappe.db.get_value('Asset', self.asset, 'company') - repair_and_maintenance_account = frappe.db.get_value('Company', company, 'repair_and_maintenance_account') + repair_and_maintenance_account = frappe.db.get_value('Company', self.company, 'repair_and_maintenance_account') fixed_asset_account = self.get_fixed_asset_account() expense_account = frappe.get_doc('Purchase Invoice', self.purchase_invoice).items[0].expense_account @@ -119,7 +118,7 @@ class AssetRepair(Document): "voucher_no": self.name, "cost_center": self.cost_center, "posting_date": getdate(), - "company": company + "company": self.company }) gl_entry.insert() gl_entry = frappe.get_doc({ @@ -134,15 +133,14 @@ class AssetRepair(Document): "posting_date": getdate(), "against_voucher_type": "Purchase Invoice", "against_voucher": self.purchase_invoice, - "company": company + "company": self.company }) gl_entry.insert() def get_fixed_asset_account(self): asset_category = frappe.get_doc('Asset Category', frappe.db.get_value('Asset', self.asset, 'asset_category')) - company = frappe.db.get_value('Asset', self.asset, 'company') for account in asset_category.accounts: - if account.company_name == company: + if account.company_name == self.company: return account.fixed_asset_account def modify_depreciation_schedule(self): From 17fa1217792bb06554d4c2f60e45768091da2bac Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:13:36 +0530 Subject: [PATCH 17/60] fix(Asset Repair): Filter Cost Center and Project by Company --- .../doctype/asset_repair/asset_repair.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index fdb8d0af67..1e87722179 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -30,3 +30,21 @@ frappe.ui.form.on('Asset Repair', { } } }); + +cur_frm.fields_dict.cost_center.get_query = function(doc) { + return{ + filters:{ + 'is_group': 0, + 'company': doc.company + } + } +} + +cur_frm.fields_dict.project.get_query = function(doc) { + return{ + filters:{ + 'is_group': 0, + 'company': doc.company + } + } +} \ No newline at end of file From aff97095252aa2807f4ea4c0bf1a35c6e7d8e912 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:18:45 +0530 Subject: [PATCH 18/60] fix(Asset Repair): Add mandatory_depends_on condition for Purchase Invoice --- erpnext/assets/doctype/asset_repair/asset_repair.json | 3 ++- erpnext/assets/doctype/asset_repair/asset_repair.py | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 840589ca2e..d3335c5afb 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -241,6 +241,7 @@ "fieldname": "purchase_invoice", "fieldtype": "Link", "label": "Purchase Invoice", + "mandatory_depends_on": "eval: doc.repair_status == 'Completed' && doc.repair_cost > 0", "options": "Purchase Invoice" }, { @@ -254,7 +255,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-16 08:02:34.782990", + "modified": "2021-06-16 08:16:07.581813", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index bd5e462f13..01eeb36e3a 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -45,7 +45,6 @@ class AssetRepair(Document): self.check_for_stock_items_and_warehouse() self.decrease_stock_quantity() if self.capitalize_repair_cost: - self.check_for_purchase_invoice() self.make_gl_entries() if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation'): self.modify_depreciation_schedule() @@ -90,10 +89,6 @@ class AssetRepair(Document): stock_entry.insert() stock_entry.submit() - def check_for_purchase_invoice(self): - if not self.purchase_invoice: - frappe.throw(_("Please link Purchase Invoice.")) - def on_cancel(self): self.make_gl_entries(cancel=True) From 9779aa11fbd7390bc08a9f025f6893eb4890a5b9 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:26:02 +0530 Subject: [PATCH 19/60] fix(Asset Repair): Use existing function from asset.py for fetching fixed_asset_account --- erpnext/assets/doctype/asset_repair/asset_repair.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 01eeb36e3a..63cdaf5cde 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -8,6 +8,7 @@ from frappe import _ from frappe.utils import time_diff_in_hours, getdate, add_months, flt, cint from frappe.model.document import Document from erpnext.accounts.general_ledger import make_gl_entries +from erpnext.assets.doctype.asset.asset import get_asset_account class AssetRepair(Document): def validate(self): @@ -100,7 +101,7 @@ class AssetRepair(Document): def get_gl_entries(self): gl_entry = [] repair_and_maintenance_account = frappe.db.get_value('Company', self.company, 'repair_and_maintenance_account') - fixed_asset_account = self.get_fixed_asset_account() + fixed_asset_account = get_asset_account("fixed_asset_account", asset=self.asset, company=self.company) expense_account = frappe.get_doc('Purchase Invoice', self.purchase_invoice).items[0].expense_account gl_entry = frappe.get_doc({ @@ -132,12 +133,6 @@ class AssetRepair(Document): }) gl_entry.insert() - def get_fixed_asset_account(self): - asset_category = frappe.get_doc('Asset Category', frappe.db.get_value('Asset', self.asset, 'asset_category')) - for account in asset_category.accounts: - if account.company_name == self.company: - return account.fixed_asset_account - def modify_depreciation_schedule(self): if self.increase_in_asset_life: asset = frappe.get_doc('Asset', self.asset) From 0aaf88cc0aadd37f1e19a79829c767fb3a69265c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:33:05 +0530 Subject: [PATCH 20/60] fix(Asset Repair): Uncheck allow_on_submit for all fields --- erpnext/assets/doctype/asset_repair/asset_repair.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index d3335c5afb..88e75a168f 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -71,14 +71,12 @@ "fieldtype": "Column Break" }, { - "allow_on_submit": 1, "depends_on": "eval:!doc.__islocal", "fieldname": "completion_date", "fieldtype": "Datetime", "label": "Completion Date" }, { - "allow_on_submit": 1, "default": "Pending", "depends_on": "eval:!doc.__islocal", "fieldname": "repair_status", @@ -104,13 +102,11 @@ "fieldtype": "Column Break" }, { - "allow_on_submit": 1, "fieldname": "actions_performed", "fieldtype": "Long Text", "label": "Actions performed" }, { - "allow_on_submit": 1, "fieldname": "downtime", "fieldtype": "Data", "in_list_view": 1, @@ -122,7 +118,6 @@ "fieldtype": "Column Break" }, { - "allow_on_submit": 1, "fieldname": "repair_cost", "fieldtype": "Currency", "label": "Repair Cost" @@ -255,7 +250,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-16 08:16:07.581813", + "modified": "2021-06-16 08:32:06.160615", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 75fbda10ad1c51c00a02123e63b62c4d6a066d36 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:35:50 +0530 Subject: [PATCH 21/60] fix(Asset Repair): Make Cost Center non-mandatory --- erpnext/assets/doctype/asset_repair/asset_repair.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 63cdaf5cde..5f4c382079 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -38,7 +38,6 @@ class AssetRepair(Document): def on_submit(self): self.check_repair_status() - self.check_for_cost_center() if self.stock_consumption or self.capitalize_repair_cost: self.increase_asset_value() @@ -60,10 +59,6 @@ class AssetRepair(Document): if not self.warehouse: frappe.throw(_("Please enter Warehouse from which Stock Items consumed during the Repair were taken."), title=_("Missing Warehouse")) - def check_for_cost_center(self): - if not self.cost_center: - frappe.throw(_("Please enter Cost Center.")) - def increase_asset_value(self): asset_value = frappe.db.get_value('Asset', self.asset, 'asset_value') for item in self.stock_items: From 71eaf3dbd8bffed9f1e499170729d84884944d02 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 08:45:54 +0530 Subject: [PATCH 22/60] fix(Asset Repair): Fix Sider issues --- .../assets/doctype/asset_repair/asset_repair.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index 1e87722179..2319b069b0 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -32,19 +32,19 @@ frappe.ui.form.on('Asset Repair', { }); cur_frm.fields_dict.cost_center.get_query = function(doc) { - return{ - filters:{ + return { + filters: { 'is_group': 0, 'company': doc.company } - } -} + }; +}; cur_frm.fields_dict.project.get_query = function(doc) { - return{ - filters:{ + return { + filters: { 'is_group': 0, 'company': doc.company } - } -} \ No newline at end of file + }; +}; \ No newline at end of file From 96de4fdf1fd8b3047ede42ff10b20ecc443e3026 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 10:42:37 +0530 Subject: [PATCH 23/60] fix(Asset Repair): Fix GL Entry creation --- .../doctype/asset_repair/asset_repair.py | 78 ++++++++++++------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 5f4c382079..92f7408ba7 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -9,8 +9,9 @@ from frappe.utils import time_diff_in_hours, getdate, add_months, flt, cint from frappe.model.document import Document from erpnext.accounts.general_ledger import make_gl_entries from erpnext.assets.doctype.asset.asset import get_asset_account +from erpnext.controllers.accounts_controller import AccountsController -class AssetRepair(Document): +class AssetRepair(AccountsController): def validate(self): if self.repair_status == "Completed" and not self.completion_date: frappe.throw(_("Please select Completion Date for Completed Repair")) @@ -94,39 +95,56 @@ class AssetRepair(Document): make_gl_entries(gl_entries, cancel) def get_gl_entries(self): - gl_entry = [] + gl_entries = [] repair_and_maintenance_account = frappe.db.get_value('Company', self.company, 'repair_and_maintenance_account') fixed_asset_account = get_asset_account("fixed_asset_account", asset=self.asset, company=self.company) expense_account = frappe.get_doc('Purchase Invoice', self.purchase_invoice).items[0].expense_account - gl_entry = frappe.get_doc({ - "doctype": "GL Entry", - "account": expense_account, - "credit": self.total_repair_cost, - "credit_in_account_currency": self.total_repair_cost, - "against": repair_and_maintenance_account, - "voucher_type": self.doctype, - "voucher_no": self.name, - "cost_center": self.cost_center, - "posting_date": getdate(), - "company": self.company - }) - gl_entry.insert() - gl_entry = frappe.get_doc({ - "doctype": "GL Entry", - "account": fixed_asset_account, - "debit": self.total_repair_cost, - "debit_in_account_currency": self.total_repair_cost, - "against": expense_account, - "voucher_type": self.doctype, - "voucher_no": self.name, - "cost_center": self.cost_center, - "posting_date": getdate(), - "against_voucher_type": "Purchase Invoice", - "against_voucher": self.purchase_invoice, - "company": self.company - }) - gl_entry.insert() + gl_entries.append( + self.get_gl_dict({ + "account": expense_account, + "credit": self.repair_cost, + "credit_in_account_currency": self.repair_cost, + "against": repair_and_maintenance_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate(), + "company": self.company + }, item=self) + ) + + gl_entries.append( + self.get_gl_dict({ + "account": expense_account, + "credit": self.total_repair_cost - self.repair_cost, + "credit_in_account_currency": self.total_repair_cost - self.repair_cost, + "against": repair_and_maintenance_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate(), + "company": self.company + }, item=self) + ) + + gl_entries.append( + self.get_gl_dict({ + "account": fixed_asset_account, + "debit": self.total_repair_cost, + "debit_in_account_currency": self.total_repair_cost, + "against": expense_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate(), + "against_voucher_type": "Purchase Invoice", + "against_voucher": self.purchase_invoice, + "company": self.company + }, item=self) + ) + + return gl_entries def modify_depreciation_schedule(self): if self.increase_in_asset_life: From 9520efb941097765fefce9754beb158699386a25 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 16 Jun 2021 10:48:07 +0530 Subject: [PATCH 24/60] fix(Asset Repair): Filter Warehouse by Company --- erpnext/assets/doctype/asset_repair/asset_repair.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index 2319b069b0..efa6a9d494 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -41,6 +41,14 @@ cur_frm.fields_dict.cost_center.get_query = function(doc) { }; cur_frm.fields_dict.project.get_query = function(doc) { + return { + filters: { + 'company': doc.company + } + }; +}; + +cur_frm.fields_dict.warehouse.get_query = function(doc) { return { filters: { 'is_group': 0, From d354a301cbc0fd77a5283ca7690b5c82ba053c47 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 17 Jun 2021 08:28:19 +0530 Subject: [PATCH 25/60] fix(Asset Repair): Display value_after_depreciation in Finance Books --- .../assets/doctype/asset_finance_book/asset_finance_book.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json index d9b7b695f7..ee3a2072f0 100644 --- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json +++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json @@ -67,7 +67,6 @@ { "fieldname": "value_after_depreciation", "fieldtype": "Currency", - "hidden": 1, "label": "Value After Depreciation", "no_copy": 1, "options": "Company:company:default_currency", @@ -85,7 +84,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2020-11-05 16:30:09.213479", + "modified": "2021-06-17 08:02:32.650738", "modified_by": "Administrator", "module": "Assets", "name": "Asset Finance Book", From 50826f16ee1c16454cbfa24af316d2bf32e8c1e9 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 17 Jun 2021 13:02:02 +0530 Subject: [PATCH 26/60] fix(Asset): Replace asset_value with value_after_depreciation in Finance Books --- erpnext/assets/doctype/asset/asset.json | 9 +-------- erpnext/assets/doctype/asset/asset.py | 11 ++++++----- .../asset_finance_book/asset_finance_book.json | 2 +- .../assets/doctype/asset_repair/asset_repair.py | 16 +++++++++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index 8a0e3ad2a6..d55258c8f6 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -23,7 +23,6 @@ "asset_name", "asset_category", "location", - "asset_value", "custodian", "department", "disposal_date", @@ -484,12 +483,6 @@ "fieldtype": "Section Break", "label": "Finance Books" }, - { - "fieldname": "asset_value", - "fieldtype": "Currency", - "label": "Asset Value", - "read_only": 1 - }, { "fieldname": "to_date", "fieldtype": "Date", @@ -523,7 +516,7 @@ "link_fieldname": "asset" } ], - "modified": "2021-05-21 12:05:29.424083", + "modified": "2021-06-17 12:59:39.189106", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index b3d3a198c3..4820f8b487 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -96,9 +96,6 @@ class Asset(AccountsController): finance_books = get_item_details(self.item_code, self.asset_category) self.set('finance_books', finance_books) - if not(self.asset_value): - self.asset_value = self.gross_purchase_amount - def validate_asset_values(self): if not self.asset_category: self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category") @@ -187,8 +184,12 @@ class Asset(AccountsController): start = n break - value_after_depreciation = (flt(self.asset_value) - - flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) + if d.value_after_depreciation: + value_after_depreciation = (flt(d.value_after_depreciation) - + flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) + else: + value_after_depreciation = (flt(self.gross_purchase_amount) - + flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) d.value_after_depreciation = value_after_depreciation diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json index ee3a2072f0..e5a5f194c1 100644 --- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json +++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json @@ -84,7 +84,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-06-17 08:02:32.650738", + "modified": "2021-06-17 12:59:05.743683", "modified_by": "Administrator", "module": "Assets", "name": "Asset Finance Book", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 92f7408ba7..2d039190e3 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -61,13 +61,19 @@ class AssetRepair(AccountsController): frappe.throw(_("Please enter Warehouse from which Stock Items consumed during the Repair were taken."), title=_("Missing Warehouse")) def increase_asset_value(self): - asset_value = frappe.db.get_value('Asset', self.asset, 'asset_value') + total_value_of_stock_consumed = 0 for item in self.stock_items: - asset_value += item.total_value + total_value_of_stock_consumed += item.total_value - if self.capitalize_repair_cost: - asset_value += self.repair_cost - frappe.db.set_value('Asset', self.asset, 'asset_value', asset_value) + asset = frappe.get_doc('Asset', self.asset) + asset.flags.ignore_validate_update_after_submit = True + if asset.calculate_depreciation: + for row in asset.finance_books: + row.value_after_depreciation += total_value_of_stock_consumed + + if self.capitalize_repair_cost: + row.value_after_depreciation += self.repair_cost + asset.save() def decrease_stock_quantity(self): stock_entry = frappe.get_doc({ From 54cbc8324acac8bdff796d72f7f128fe076eae3f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 18 Jun 2021 09:53:18 +0530 Subject: [PATCH 27/60] fix(Asset Repair): Create GL Entries for each item in Stock Items --- .../doctype/asset_repair/asset_repair.py | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 2d039190e3..7864cb70a5 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -120,19 +120,23 @@ class AssetRepair(AccountsController): }, item=self) ) - gl_entries.append( - self.get_gl_dict({ - "account": expense_account, - "credit": self.total_repair_cost - self.repair_cost, - "credit_in_account_currency": self.total_repair_cost - self.repair_cost, - "against": repair_and_maintenance_account, - "voucher_type": self.doctype, - "voucher_no": self.name, - "cost_center": self.cost_center, - "posting_date": getdate(), - "company": self.company - }, item=self) - ) + if self.stock_consumption: + # creating GL Entries for each row in Stock Items based on the Stock Entry created for it + stock_entry = frappe.get_last_doc('Stock Entry') + for item in stock_entry.items: + gl_entries.append( + self.get_gl_dict({ + "account": item.expense_account, + "credit": item.amount, + "credit_in_account_currency": item.amount, + "against": repair_and_maintenance_account, + "voucher_type": self.doctype, + "voucher_no": self.name, + "cost_center": self.cost_center, + "posting_date": getdate(), + "company": self.company + }, item=self) + ) gl_entries.append( self.get_gl_dict({ From bd336c7d8e4d4053fb69c12a669dfc1efcf4250c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 18 Jun 2021 09:59:45 +0530 Subject: [PATCH 28/60] fix(Asset): Add function to clear old depreciation schedule --- erpnext/assets/doctype/asset/asset.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 4820f8b487..9273f01da7 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -176,13 +176,8 @@ class Asset(AccountsController): for d in self.get('finance_books'): self.validate_asset_finance_books(d) - - start = 0 - for n in range(len(self.schedules)): - if not self.schedules[n].journal_entry: - del self.schedules[n:] - start = n - break + + start = self.clear_depreciation_schedule() if d.value_after_depreciation: value_after_depreciation = (flt(d.value_after_depreciation) - @@ -296,6 +291,15 @@ class Asset(AccountsController): "finance_book_id": d.idx }) + def clear_depreciation_schedule(self): + start = 0 + for n in range(len(self.schedules)): + if not self.schedules[n].journal_entry: + del self.schedules[n:] + start = n + break + return start + def check_is_pro_rata(self, row): has_pro_rata = False From be536040df75293c2eb6de9b084b1fa6d10cf495 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 13:06:27 +0530 Subject: [PATCH 29/60] fix: Add comments --- erpnext/assets/doctype/asset/asset.py | 12 ++++++-- .../doctype/asset_repair/asset_repair.py | 30 +++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 9273f01da7..18e3ffc8a6 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -179,7 +179,8 @@ class Asset(AccountsController): start = self.clear_depreciation_schedule() - if d.value_after_depreciation: + # value_after_depreciation - current Asset value + if d.value_after_depreciation: value_after_depreciation = (flt(d.value_after_depreciation) - flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) else: @@ -291,6 +292,7 @@ class Asset(AccountsController): "finance_book_id": d.idx }) + # used when depreciation schedule needs to be modified due to increase in asset life def clear_depreciation_schedule(self): start = 0 for n in range(len(self.schedules)): @@ -300,10 +302,13 @@ class Asset(AccountsController): break return start + + # if it returns True, depreciation_amount will not be equal for the first and last rows def check_is_pro_rata(self, row): has_pro_rata = False - days = date_diff(row.depreciation_start_date, self.available_for_use_date) + 1 + + # if frequency_of_depreciation is 12 months, total_days = 365 total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation) if days < total_days: @@ -783,9 +788,12 @@ def get_depreciation_amount(asset, depreciable_value, row): depreciation_left = flt(row.total_number_of_depreciations) - flt(asset.number_of_depreciations_booked) if row.depreciation_method in ("Straight Line", "Manual"): + # if the Depreciation Schedule is being prepared for the first time if not asset.to_date: depreciation_amount = (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / depreciation_left + + # if the Depreciation Schedule is being modified after Asset Repair else: depreciation_amount = (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / (date_diff(asset.to_date, asset.available_for_use_date) / 365) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 7864cb70a5..0befee70cb 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -47,7 +47,7 @@ class AssetRepair(AccountsController): self.decrease_stock_quantity() if self.capitalize_repair_cost: self.make_gl_entries() - if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation'): + if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation') and self.increase_in_asset_life: self.modify_depreciation_schedule() def check_repair_status(self): @@ -157,27 +157,33 @@ class AssetRepair(AccountsController): return gl_entries def modify_depreciation_schedule(self): - if self.increase_in_asset_life: - asset = frappe.get_doc('Asset', self.asset) - asset.flags.ignore_validate_update_after_submit = True - for row in asset.finance_books: - row.total_number_of_depreciations += self.increase_in_asset_life/row.frequency_of_depreciation + asset = frappe.get_doc('Asset', self.asset) + asset.flags.ignore_validate_update_after_submit = True + for row in asset.finance_books: + row.total_number_of_depreciations += self.increase_in_asset_life/row.frequency_of_depreciation - asset.edit_dates = "" - extra_months = self.increase_in_asset_life % row.frequency_of_depreciation - if extra_months != 0: - self.calculate_last_schedule_date(asset, row, extra_months) + asset.edit_dates = "" + extra_months = self.increase_in_asset_life % row.frequency_of_depreciation + if extra_months != 0: + self.calculate_last_schedule_date(asset, row, extra_months) - asset.prepare_depreciation_data() - asset.save() + asset.prepare_depreciation_data() + asset.save() # to help modify depreciation schedule when increase_in_asset_life is not a multiple of frequency_of_depreciation def calculate_last_schedule_date(self, asset, row, extra_months): asset.edit_dates = "Don't Edit" number_of_pending_depreciations = cint(row.total_number_of_depreciations) - \ cint(asset.number_of_depreciations_booked) + + # the Schedule Date in the final row of the old Depreciation Schedule last_schedule_date = asset.schedules[len(asset.schedules)-1].schedule_date + + # the Schedule Date in the final row of the new Depreciation Schedule asset.to_date = add_months(last_schedule_date, extra_months) + + # the latest possible date at which the depreciation can occur, without increasing the Total Number of Depreciations + # if depreciations happen yearly and the Depreciation Posting Date is 01-01-2020, this could be 01-01-2021, 01-01-2022... schedule_date = add_months(row.depreciation_start_date, number_of_pending_depreciations * cint(row.frequency_of_depreciation)) From ae8cb335b6fb458dd7fc405e71c5dfabb272f94a Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 13:45:37 +0530 Subject: [PATCH 30/60] fix(Asset Repair): Fix depreciation_amount calculation --- erpnext/assets/doctype/asset/asset.py | 2 +- erpnext/regional/india/utils.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 18e3ffc8a6..93b05ebd5c 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -789,7 +789,7 @@ def get_depreciation_amount(asset, depreciable_value, row): if row.depreciation_method in ("Straight Line", "Manual"): # if the Depreciation Schedule is being prepared for the first time - if not asset.to_date: + if not asset.edit_dates: depreciation_amount = (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / depreciation_left diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index a4466e78f2..11b19ae696 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -834,8 +834,16 @@ def get_depreciation_amount(asset, depreciable_value, row): depreciation_left = flt(row.total_number_of_depreciations) - flt(asset.number_of_depreciations_booked) if row.depreciation_method in ("Straight Line", "Manual"): - depreciation_amount = (flt(row.value_after_depreciation) - - flt(row.expected_value_after_useful_life)) / depreciation_left + # if the Depreciation Schedule is being prepared for the first time + if not asset.edit_dates: + depreciation_amount = (flt(row.value_after_depreciation) - + flt(row.expected_value_after_useful_life)) / depreciation_left + + # if the Depreciation Schedule is being modified after Asset Repair + else: + depreciation_amount = (flt(row.value_after_depreciation) - + flt(row.expected_value_after_useful_life)) / (date_diff(asset.to_date, asset.available_for_use_date) / 365) + else: rate_of_depreciation = row.rate_of_depreciation # if its the first depreciation From bd1796cbb61ff261ee2f5d699e44eeaedbe6638a Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 14:00:26 +0530 Subject: [PATCH 31/60] fix: Replace edit_dates with flags.increase_in_asset_life --- erpnext/assets/doctype/asset/asset.json | 9 +-------- erpnext/assets/doctype/asset/asset.py | 4 ++-- erpnext/assets/doctype/asset_repair/asset_repair.py | 4 ++-- erpnext/regional/india/utils.py | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index d55258c8f6..d77eb10418 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -54,7 +54,6 @@ "section_break_14", "schedules", "to_date", - "edit_dates", "insurance_details", "policy_number", "insurer", @@ -488,12 +487,6 @@ "fieldtype": "Date", "hidden": 1, "label": "To Date" - }, - { - "fieldname": "edit_dates", - "fieldtype": "Data", - "hidden": 1, - "label": "Edit Dates" } ], "idx": 72, @@ -516,7 +509,7 @@ "link_fieldname": "asset" } ], - "modified": "2021-06-17 12:59:39.189106", + "modified": "2021-06-19 13:56:58.450182", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 93b05ebd5c..63b70f6613 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -223,7 +223,7 @@ class Asset(AccountsController): # For last row elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1: - if not self.edit_dates: + if not self.flags.increase_in_asset_life: self.to_date = add_months(self.available_for_use_date, n * cint(d.frequency_of_depreciation)) @@ -789,7 +789,7 @@ def get_depreciation_amount(asset, depreciable_value, row): if row.depreciation_method in ("Straight Line", "Manual"): # if the Depreciation Schedule is being prepared for the first time - if not asset.edit_dates: + if not asset.flags.increase_in_asset_life: depreciation_amount = (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / depreciation_left diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 0befee70cb..da237f09f0 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -162,7 +162,7 @@ class AssetRepair(AccountsController): for row in asset.finance_books: row.total_number_of_depreciations += self.increase_in_asset_life/row.frequency_of_depreciation - asset.edit_dates = "" + asset.flags.increase_in_asset_life = False extra_months = self.increase_in_asset_life % row.frequency_of_depreciation if extra_months != 0: self.calculate_last_schedule_date(asset, row, extra_months) @@ -172,7 +172,7 @@ class AssetRepair(AccountsController): # to help modify depreciation schedule when increase_in_asset_life is not a multiple of frequency_of_depreciation def calculate_last_schedule_date(self, asset, row, extra_months): - asset.edit_dates = "Don't Edit" + asset.flags.increase_in_asset_life = True number_of_pending_depreciations = cint(row.total_number_of_depreciations) - \ cint(asset.number_of_depreciations_booked) diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 11b19ae696..81c0918b99 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -835,7 +835,7 @@ def get_depreciation_amount(asset, depreciable_value, row): if row.depreciation_method in ("Straight Line", "Manual"): # if the Depreciation Schedule is being prepared for the first time - if not asset.edit_dates: + if not asset.flags.increase_in_asset_life: depreciation_amount = (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / depreciation_left From 4004bcd4362e2cec8e39977768024ee256c378c7 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 14:06:45 +0530 Subject: [PATCH 32/60] fix(Asset Repair): Move Total Repair Cost to the Stock Consumption Details section --- erpnext/assets/doctype/asset_repair/asset_repair.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 88e75a168f..89f7fa3bca 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -26,11 +26,11 @@ "capitalize_repair_cost", "stock_consumption", "column_break_8", - "total_repair_cost", "purchase_invoice", "stock_consumption_details_section", "warehouse", "stock_items", + "total_repair_cost", "asset_depreciation_details_section", "increase_in_asset_life", "section_break_9", @@ -209,6 +209,7 @@ }, { "depends_on": "stock_consumption", + "description": "Sum of Repair Cost and the total value of all Stock Items consumed during the repair.", "fieldname": "total_repair_cost", "fieldtype": "Currency", "label": "Total Repair Cost" @@ -250,7 +251,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-16 08:32:06.160615", + "modified": "2021-06-19 14:04:35.423111", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From e755c74a60b84b0c8399196db4a5cabc8c91ae4b Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 14:54:30 +0530 Subject: [PATCH 33/60] fix(Asset Repair): Add Stock Entry field --- .../doctype/asset_repair/asset_repair.json | 16 +++++++++++++--- .../assets/doctype/asset_repair/asset_repair.py | 4 +++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 89f7fa3bca..ee18c4bdc4 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -31,6 +31,7 @@ "warehouse", "stock_items", "total_repair_cost", + "stock_entry", "asset_depreciation_details_section", "increase_in_asset_life", "section_break_9", @@ -118,6 +119,7 @@ "fieldtype": "Column Break" }, { + "default": "0", "fieldname": "repair_cost", "fieldtype": "Currency", "label": "Repair Cost" @@ -208,11 +210,12 @@ "label": "Stock Consumption Details" }, { - "depends_on": "stock_consumption", + "depends_on": "eval: doc.stock_consumption && doc.total_repair_cost > 0", "description": "Sum of Repair Cost and the total value of all Stock Items consumed during the repair.", "fieldname": "total_repair_cost", "fieldtype": "Currency", - "label": "Total Repair Cost" + "label": "Total Repair Cost", + "read_only": 1 }, { "depends_on": "stock_consumption", @@ -246,12 +249,19 @@ "fieldtype": "Link", "label": "Company", "options": "Company" + }, + { + "fieldname": "stock_entry", + "fieldtype": "Link", + "label": "Stock Entry", + "options": "Stock Entry", + "read_only": 1 } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-19 14:04:35.423111", + "modified": "2021-06-19 14:47:25.875814", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index da237f09f0..c074cc930e 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -92,6 +92,8 @@ class AssetRepair(AccountsController): stock_entry.insert() stock_entry.submit() + self.stock_entry = stock_entry.name + def on_cancel(self): self.make_gl_entries(cancel=True) @@ -122,7 +124,7 @@ class AssetRepair(AccountsController): if self.stock_consumption: # creating GL Entries for each row in Stock Items based on the Stock Entry created for it - stock_entry = frappe.get_last_doc('Stock Entry') + stock_entry = frappe.get_doc('Stock Entry', self.stock_entry) for item in stock_entry.items: gl_entries.append( self.get_gl_dict({ From 399d17e40efde2ef674becd036ce3ffd5cb7fc0f Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 15:18:54 +0530 Subject: [PATCH 34/60] fix(Asset Repair): Make Error Description non-mandatory --- erpnext/assets/doctype/asset_repair/asset_repair.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index ee18c4bdc4..cfa084e606 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -95,8 +95,7 @@ { "fieldname": "description", "fieldtype": "Long Text", - "label": "Error Description", - "reqd": 1 + "label": "Error Description" }, { "fieldname": "column_break_9", @@ -261,7 +260,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-19 14:47:25.875814", + "modified": "2021-06-19 15:18:10.625833", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 68e0c96c0366a18da4215b2834644db44f35171c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 19 Jun 2021 15:23:06 +0530 Subject: [PATCH 35/60] fix(Asset Repair): Prevent some fields from being copied on duplicating the doc --- erpnext/assets/doctype/asset_repair/asset_repair.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index cfa084e606..a0fe632802 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -75,7 +75,8 @@ "depends_on": "eval:!doc.__islocal", "fieldname": "completion_date", "fieldtype": "Datetime", - "label": "Completion Date" + "label": "Completion Date", + "no_copy": 1 }, { "default": "Pending", @@ -232,7 +233,8 @@ { "fieldname": "increase_in_asset_life", "fieldtype": "Int", - "label": "Increase In Asset Life(Months)" + "label": "Increase In Asset Life(Months)", + "no_copy": 1 }, { "depends_on": "eval:!doc.__islocal", @@ -240,6 +242,7 @@ "fieldtype": "Link", "label": "Purchase Invoice", "mandatory_depends_on": "eval: doc.repair_status == 'Completed' && doc.repair_cost > 0", + "no_copy": 1, "options": "Purchase Invoice" }, { @@ -260,7 +263,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-19 15:18:10.625833", + "modified": "2021-06-19 15:20:24.056706", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 42fd7ffbc01c59b901b46953ead07096da957887 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sun, 20 Jun 2021 17:44:35 +0530 Subject: [PATCH 36/60] fix(Asset Repair): Set completion_date on changing repair_status to 'Completed' --- erpnext/assets/doctype/asset_repair/asset_repair.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index efa6a9d494..ced3dad1e5 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -28,6 +28,10 @@ frappe.ui.form.on('Asset Repair', { } }); } + + if (frm.doc.repair_status == "Completed") { + frm.set_value('completion_date', frappe.datetime.now_datetime()); + } } }); From 852881e33e5bbe887b801e11cee3282928dc3a7b Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 21 Jun 2021 14:52:00 +0530 Subject: [PATCH 37/60] fix(Asset Repair): Fix tests --- .../doctype/asset_repair/asset_repair.json | 2 +- .../doctype/asset_repair/asset_repair.py | 55 ++++++++----------- .../doctype/asset_repair/test_asset_repair.py | 7 ++- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index a0fe632802..6bcddbfb94 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -263,7 +263,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-19 15:20:24.056706", + "modified": "2021-06-20 17:35:51.075537", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index c074cc930e..5fccfb76a5 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -6,74 +6,72 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.utils import time_diff_in_hours, getdate, add_months, flt, cint -from frappe.model.document import Document from erpnext.accounts.general_ledger import make_gl_entries from erpnext.assets.doctype.asset.asset import get_asset_account from erpnext.controllers.accounts_controller import AccountsController class AssetRepair(AccountsController): def validate(self): - if self.repair_status == "Completed" and not self.completion_date: - frappe.throw(_("Please select Completion Date for Completed Repair")) - + self.asset_doc = frappe.get_doc('Asset', self.asset) self.update_status() - self.set_total_value() # change later + if self.get('stock_items'): + self.set_total_value() # change later self.calculate_total_repair_cost() def update_status(self): if self.repair_status == 'Pending': frappe.db.set_value('Asset', self.asset, 'status', 'Out of Order') else: - asset = frappe.get_doc('Asset', self.asset) - asset.set_status() + self.asset_doc.set_status() def set_total_value(self): - for item in self.stock_items: + for item in self.get('stock_items'): item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) def calculate_total_repair_cost(self): self.total_repair_cost = self.repair_cost - if self.stock_consumption: - for item in self.stock_items: + if self.get('stock_items'): + for item in self.get('stock_items'): self.total_repair_cost += item.total_value def on_submit(self): self.check_repair_status() - if self.stock_consumption or self.capitalize_repair_cost: + if self.get('stock_consumption') or self.get('capitalize_repair_cost'): self.increase_asset_value() - if self.stock_consumption: + if self.get('stock_consumption'): self.check_for_stock_items_and_warehouse() self.decrease_stock_quantity() - if self.capitalize_repair_cost: + if self.get('capitalize_repair_cost'): self.make_gl_entries() if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation') and self.increase_in_asset_life: self.modify_depreciation_schedule() + self.asset_doc.flags.ignore_validate_update_after_submit = True + self.asset_doc.save() + def check_repair_status(self): if self.repair_status == "Pending": frappe.throw(_("Please update Repair Status.")) def check_for_stock_items_and_warehouse(self): - if not self.stock_items: + 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 = 0 - for item in self.stock_items: - total_value_of_stock_consumed += item.total_value + if self.get('stock_consumption'): + for item in self.get('stock_items'): + total_value_of_stock_consumed += item.total_value - asset = frappe.get_doc('Asset', self.asset) - asset.flags.ignore_validate_update_after_submit = True - if asset.calculate_depreciation: - for row in asset.finance_books: + if self.asset_doc.calculate_depreciation: + for row in self.asset_doc.finance_books: row.value_after_depreciation += total_value_of_stock_consumed if self.capitalize_repair_cost: row.value_after_depreciation += self.repair_cost - asset.save() def decrease_stock_quantity(self): stock_entry = frappe.get_doc({ @@ -82,7 +80,7 @@ class AssetRepair(AccountsController): "company": self.company }) - for stock_item in self.stock_items: + for stock_item in self.get('stock_items'): stock_entry.append('items', { "s_warehouse": self.warehouse, "item_code": stock_item.item, @@ -122,7 +120,7 @@ class AssetRepair(AccountsController): }, item=self) ) - if self.stock_consumption: + if self.get('stock_consumption'): # 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) for item in stock_entry.items: @@ -159,18 +157,13 @@ class AssetRepair(AccountsController): return gl_entries def modify_depreciation_schedule(self): - asset = frappe.get_doc('Asset', self.asset) - asset.flags.ignore_validate_update_after_submit = True - for row in asset.finance_books: + for row in self.asset_doc.finance_books: row.total_number_of_depreciations += self.increase_in_asset_life/row.frequency_of_depreciation - asset.flags.increase_in_asset_life = False + self.asset_doc.flags.increase_in_asset_life = False extra_months = self.increase_in_asset_life % row.frequency_of_depreciation if extra_months != 0: - self.calculate_last_schedule_date(asset, row, extra_months) - - asset.prepare_depreciation_data() - asset.save() + self.calculate_last_schedule_date(self.asset_doc, row, extra_months) # to help modify depreciation schedule when increase_in_asset_life is not a multiple of frequency_of_depreciation def calculate_last_schedule_date(self, asset, row, extra_months): diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index 9c9dd44971..d1b417fd38 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -105,7 +105,9 @@ class TestAssetRepair(unittest.TestCase): initial_num_of_depreciations = num_of_depreciations(asset) create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1) asset.reload() + self.assertEqual((initial_num_of_depreciations + 1), num_of_depreciations(asset)) + self.assertEqual(asset.schedules[-1].accumulated_depreciation_amount, asset.finance_books[0].value_after_depreciation) def num_of_depreciations(asset): return asset.finance_books[0].total_number_of_depreciations @@ -126,7 +128,8 @@ def create_asset_repair(**args): "asset_name": asset.asset_name, "failure_date": nowdate(), "description": "Test Description", - "repair_cost": 0 + "repair_cost": 0, + "company": asset.company }) if args.stock_consumption: @@ -142,7 +145,7 @@ def create_asset_repair(**args): asset_repair.save() except frappe.DuplicateEntryError: pass - + if args.submit: asset_repair.repair_status = "Completed" asset_repair.cost_center = "_Test Cost Center - _TC" From e92187863347ff5421fb209942b36a26cc9115b8 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 21 Jun 2021 14:55:34 +0530 Subject: [PATCH 38/60] fix: Rename 'Stock Item' to 'Asset Repair Consumed Item' --- .../assets/doctype/asset_maintenance/asset_maintenance.json | 4 ++-- erpnext/assets/doctype/asset_repair/asset_repair.json | 4 ++-- .../{stock_item => asset_repair_consumed_item}/__init__.py | 0 .../asset_repair_consumed_item.json} | 2 +- .../asset_repair_consumed_item.py} | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename erpnext/assets/doctype/{stock_item => asset_repair_consumed_item}/__init__.py (100%) rename erpnext/assets/doctype/{stock_item/stock_item.json => asset_repair_consumed_item/asset_repair_consumed_item.json} (96%) rename erpnext/assets/doctype/{stock_item/stock_item.py => asset_repair_consumed_item/asset_repair_consumed_item.py} (81%) diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json index da2fd75451..63a55389d8 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json @@ -126,11 +126,11 @@ "fieldname": "stock_items", "fieldtype": "Table", "label": "Stock Items", - "options": "Stock Item" + "options": "Asset Repair Consumed Item" } ], "links": [], - "modified": "2021-05-13 05:24:58.480132", + "modified": "2021-06-21 14:53:46.041123", "modified_by": "Administrator", "module": "Assets", "name": "Asset Maintenance", diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 6bcddbfb94..14f18b5309 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -169,7 +169,7 @@ "fieldtype": "Table", "label": "Stock Items", "mandatory_depends_on": "stock_consumption", - "options": "Stock Item" + "options": "Asset Repair Consumed Item" }, { "fieldname": "section_break_23", @@ -263,7 +263,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-20 17:35:51.075537", + "modified": "2021-06-21 14:53:46.665576", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", diff --git a/erpnext/assets/doctype/stock_item/__init__.py b/erpnext/assets/doctype/asset_repair_consumed_item/__init__.py similarity index 100% rename from erpnext/assets/doctype/stock_item/__init__.py rename to erpnext/assets/doctype/asset_repair_consumed_item/__init__.py diff --git a/erpnext/assets/doctype/stock_item/stock_item.json b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json similarity index 96% rename from erpnext/assets/doctype/stock_item/stock_item.json rename to erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json index b1f05db395..528f0ec986 100644 --- a/erpnext/assets/doctype/stock_item/stock_item.json +++ b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json @@ -46,7 +46,7 @@ "modified": "2021-05-12 03:19:55.006300", "modified_by": "Administrator", "module": "Assets", - "name": "Stock Item", + "name": "Asset Repair Consumed Item", "owner": "Administrator", "permissions": [], "sort_field": "modified", diff --git a/erpnext/assets/doctype/stock_item/stock_item.py b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py similarity index 81% rename from erpnext/assets/doctype/stock_item/stock_item.py rename to erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py index 0e3cc3f8ba..fa22a5712f 100644 --- a/erpnext/assets/doctype/stock_item/stock_item.py +++ b/erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.py @@ -4,5 +4,5 @@ # import frappe from frappe.model.document import Document -class StockItem(Document): +class AssetRepairConsumedItem(Document): pass From ad78888c867335a8ececa2e307a3740a4a234283 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 21 Jun 2021 15:02:40 +0530 Subject: [PATCH 39/60] fix(Asset Repair): Compute total_value instantly --- erpnext/assets/doctype/asset_repair/asset_repair.js | 7 +++++++ erpnext/assets/doctype/asset_repair/asset_repair.py | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index ced3dad1e5..91bed4fdd0 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -35,6 +35,13 @@ frappe.ui.form.on('Asset Repair', { } }); +frappe.ui.form.on('Asset Repair Consumed Item', { + consumed_quantity: function(frm, cdt, cdn) { + var row = locals[cdt][cdn]; + frappe.model.set_value(cdt, cdn, 'total_value', row.consumed_quantity * row.valuation_rate); + }, +}); + cur_frm.fields_dict.cost_center.get_query = function(doc) { return { filters: { diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 5fccfb76a5..79b9a6a2b5 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -14,8 +14,6 @@ class AssetRepair(AccountsController): def validate(self): self.asset_doc = frappe.get_doc('Asset', self.asset) self.update_status() - if self.get('stock_items'): - self.set_total_value() # change later self.calculate_total_repair_cost() def update_status(self): @@ -24,10 +22,6 @@ class AssetRepair(AccountsController): else: self.asset_doc.set_status() - def set_total_value(self): - for item in self.get('stock_items'): - item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) - def calculate_total_repair_cost(self): self.total_repair_cost = self.repair_cost if self.get('stock_items'): From 6c2f4ce6a5b12d3fbfd2675c6fa23e12f7a8285a Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 21 Jun 2021 15:22:02 +0530 Subject: [PATCH 40/60] fix(Asset Repair): Increase stock quantity and decrease asset value on cancellation --- .../doctype/asset_repair/asset_repair.py | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 79b9a6a2b5..e7b8b45b7e 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -24,9 +24,9 @@ class AssetRepair(AccountsController): def calculate_total_repair_cost(self): self.total_repair_cost = self.repair_cost - if self.get('stock_items'): - for item in self.get('stock_items'): - self.total_repair_cost += item.total_value + + total_value_of_stock_consumed = self.get_total_value_of_stock_consumed() + self.total_repair_cost += total_value_of_stock_consumed def on_submit(self): self.check_repair_status() @@ -44,6 +44,14 @@ class AssetRepair(AccountsController): self.asset_doc.flags.ignore_validate_update_after_submit = True self.asset_doc.save() + def on_cancel(self): + if self.get('stock_consumption') or self.get('capitalize_repair_cost'): + self.decrease_asset_value() + if self.get('stock_consumption'): + self.increase_stock_quantity() + if self.get('capitalize_repair_cost'): + self.make_gl_entries(cancel=True) + def check_repair_status(self): if self.repair_status == "Pending": frappe.throw(_("Please update Repair Status.")) @@ -55,10 +63,7 @@ class AssetRepair(AccountsController): 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 = 0 - if self.get('stock_consumption'): - for item in self.get('stock_items'): - total_value_of_stock_consumed += item.total_value + total_value_of_stock_consumed = self.get_total_value_of_stock_consumed() if self.asset_doc.calculate_depreciation: for row in self.asset_doc.finance_books: @@ -67,6 +72,24 @@ class AssetRepair(AccountsController): if self.capitalize_repair_cost: row.value_after_depreciation += self.repair_cost + def decrease_asset_value(self): + total_value_of_stock_consumed = self.get_total_value_of_stock_consumed() + + if self.asset_doc.calculate_depreciation: + for row in self.asset_doc.finance_books: + row.value_after_depreciation -= total_value_of_stock_consumed + + if self.capitalize_repair_cost: + row.value_after_depreciation -= self.repair_cost + + def get_total_value_of_stock_consumed(self): + total_value_of_stock_consumed = 0 + if self.get('stock_consumption'): + for item in self.get('stock_items'): + total_value_of_stock_consumed += item.total_value + + return total_value_of_stock_consumed + def decrease_stock_quantity(self): stock_entry = frappe.get_doc({ "doctype": "Stock Entry", @@ -86,8 +109,22 @@ class AssetRepair(AccountsController): self.stock_entry = stock_entry.name - def on_cancel(self): - self.make_gl_entries(cancel=True) + def increase_stock_quantity(self): + stock_entry = frappe.get_doc({ + "doctype": "Stock Entry", + "stock_entry_type": "Material Receipt", + "company": self.company + }) + + for stock_item in self.get('stock_items'): + stock_entry.append('items', { + "s_warehouse": self.warehouse, + "item_code": stock_item.item, + "qty": stock_item.consumed_quantity + }) + + stock_entry.insert() + stock_entry.submit() def make_gl_entries(self, cancel=False): if flt(self.repair_cost) > 0: From ba9558527d78b75b0bb22356a290c37cd8f1d273 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Mon, 21 Jun 2021 18:57:11 +0530 Subject: [PATCH 41/60] fix(Asset Repair): Return Depreciation Schedule to original state on cancellation --- .../doctype/asset_repair/asset_repair.py | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index e7b8b45b7e..01b36880be 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -42,15 +42,25 @@ class AssetRepair(AccountsController): self.modify_depreciation_schedule() self.asset_doc.flags.ignore_validate_update_after_submit = True + self.asset_doc.prepare_depreciation_data() self.asset_doc.save() def on_cancel(self): + self.asset_doc = frappe.get_doc('Asset', self.asset) + if self.get('stock_consumption') or self.get('capitalize_repair_cost'): self.decrease_asset_value() 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) + if frappe.db.get_value('Asset', self.asset, 'calculate_depreciation') and self.increase_in_asset_life: + self.revert_depreciation_schedule_on_cancellation() + + self.asset_doc.flags.ignore_validate_update_after_submit = True + self.asset_doc.prepare_depreciation_data() + self.asset_doc.save() def check_repair_status(self): if self.repair_status == "Pending": @@ -101,7 +111,8 @@ class AssetRepair(AccountsController): stock_entry.append('items', { "s_warehouse": self.warehouse, "item_code": stock_item.item, - "qty": stock_item.consumed_quantity + "qty": stock_item.consumed_quantity, + "basic_rate": stock_item.valuation_rate }) stock_entry.insert() @@ -118,7 +129,7 @@ class AssetRepair(AccountsController): for stock_item in self.get('stock_items'): stock_entry.append('items', { - "s_warehouse": self.warehouse, + "t_warehouse": self.warehouse, "item_code": stock_item.item, "qty": stock_item.consumed_quantity }) @@ -126,6 +137,8 @@ class AssetRepair(AccountsController): stock_entry.insert() stock_entry.submit() + self.stock_entry = stock_entry.name + def make_gl_entries(self, cancel=False): if flt(self.repair_cost) > 0: gl_entries = self.get_gl_entries() @@ -216,6 +229,34 @@ class AssetRepair(AccountsController): if asset.to_date > schedule_date: row.total_number_of_depreciations += 1 + def revert_depreciation_schedule_on_cancellation(self): + for row in self.asset_doc.finance_books: + row.total_number_of_depreciations -= self.increase_in_asset_life/row.frequency_of_depreciation + + self.asset_doc.flags.increase_in_asset_life = False + extra_months = self.increase_in_asset_life % row.frequency_of_depreciation + if extra_months != 0: + self.calculate_last_schedule_date_before_modification(self.asset_doc, row, extra_months) + + def calculate_last_schedule_date_before_modification(self, asset, row, extra_months): + asset.flags.increase_in_asset_life = True + number_of_pending_depreciations = cint(row.total_number_of_depreciations) - \ + cint(asset.number_of_depreciations_booked) + + # the Schedule Date in the final row of the modified Depreciation Schedule + last_schedule_date = asset.schedules[len(asset.schedules)-1].schedule_date + + # the Schedule Date in the final row of the original Depreciation Schedule + asset.to_date = add_months(last_schedule_date, -extra_months) + + # the latest possible date at which the depreciation can occur, without decreasing the Total Number of Depreciations + # if depreciations happen yearly and the Depreciation Posting Date is 01-01-2020, this could be 01-01-2021, 01-01-2022... + schedule_date = add_months(row.depreciation_start_date, + (number_of_pending_depreciations - 1) * cint(row.frequency_of_depreciation)) + + if asset.to_date < schedule_date: + row.total_number_of_depreciations -= 1 + @frappe.whitelist() def get_downtime(failure_date, completion_date): downtime = time_diff_in_hours(completion_date, failure_date) From c34e6b1889dfc49f4a40e2157f13f037feb88c9a Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 22 Jun 2021 16:28:29 +0530 Subject: [PATCH 42/60] fix(Asset): Fix tests for Asset Repair --- erpnext/assets/doctype/asset/test_asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 29fbc9f15d..f3667c7b95 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -707,7 +707,7 @@ def create_asset(**args): "available_for_use_date": "2020-06-06", "location": "Test Location", "asset_owner": "Company", - "is_existing_asset": args.is_existing_asset or 0 + "is_existing_asset": 1 }) if asset.calculate_depreciation: From 55bca4cbc704217294f9fb1fc71ced01f58fb8c8 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 22 Jun 2021 16:33:10 +0530 Subject: [PATCH 43/60] fix(Asset Repair): Revert Stock Entry on cancellation --- .../doctype/asset_repair/asset_repair.py | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 01b36880be..0049dcaded 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -118,26 +118,11 @@ class AssetRepair(AccountsController): stock_entry.insert() stock_entry.submit() - self.stock_entry = stock_entry.name + self.db_set('stock_entry', stock_entry.name) def increase_stock_quantity(self): - stock_entry = frappe.get_doc({ - "doctype": "Stock Entry", - "stock_entry_type": "Material Receipt", - "company": self.company - }) - - for stock_item in self.get('stock_items'): - stock_entry.append('items', { - "t_warehouse": self.warehouse, - "item_code": stock_item.item, - "qty": stock_item.consumed_quantity - }) - - stock_entry.insert() - stock_entry.submit() - - self.stock_entry = stock_entry.name + stock_entry = frappe.get_doc('Stock Entry', self.stock_entry) + stock_entry.cancel() def make_gl_entries(self, cancel=False): if flt(self.repair_cost) > 0: From 307fe43e08919252c983935779b92f5679c5a307 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 22 Jun 2021 17:16:12 +0530 Subject: [PATCH 44/60] fix: Remove changes made to Asset Maintenance --- .../asset_maintenance/asset_maintenance.js | 3 -- .../asset_maintenance/asset_maintenance.json | 31 +--------------- .../asset_maintenance/asset_maintenance.py | 37 +------------------ 3 files changed, 3 insertions(+), 68 deletions(-) diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js index 19393b7e9d..70b8654509 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js @@ -30,10 +30,7 @@ frappe.ui.form.on('Asset Maintenance', { if(!frm.is_new()) { frm.trigger('make_dashboard'); } - - frm.toggle_display(['stock_consumption_details_section'], frm.doc.stock_consumption); }, - make_dashboard: (frm) => { if(!frm.is_new()) { frappe.call({ diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json index 63a55389d8..c0c2566fe2 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json @@ -12,17 +12,13 @@ "column_break_3", "item_code", "item_name", - "stock_consumption", "section_break_6", "maintenance_team", "column_break_9", "maintenance_manager", "maintenance_manager_name", "section_break_8", - "asset_maintenance_tasks", - "stock_consumption_details_section", - "warehouse", - "stock_items" + "asset_maintenance_tasks" ], "fields": [ { @@ -104,33 +100,10 @@ "label": "Maintenance Tasks", "options": "Asset Maintenance Task", "reqd": 1 - }, - { - "default": "0", - "fieldname": "stock_consumption", - "fieldtype": "Check", - "label": "Stock Consumed During Maintenance" - }, - { - "fieldname": "stock_consumption_details_section", - "fieldtype": "Section Break", - "label": "Stock Consumption Details" - }, - { - "fieldname": "warehouse", - "fieldtype": "Link", - "label": "Warehouse", - "options": "Warehouse" - }, - { - "fieldname": "stock_items", - "fieldtype": "Table", - "label": "Stock Items", - "options": "Asset Repair Consumed Item" } ], "links": [], - "modified": "2021-06-21 14:53:46.041123", + "modified": "2020-05-28 20:28:32.993823", "modified_by": "Administrator", "module": "Assets", "name": "Asset Maintenance", diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py index e3e654c398..a506deec93 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py @@ -19,45 +19,10 @@ class AssetMaintenance(Document): if not task.assign_to and self.docstatus == 0: throw(_("Row #{}: Please asign task to a member.").format(task.idx)) - if self.stock_consumption: - self.check_for_stock_items_and_warehouse() - self.increase_asset_value() - self.decrease_stock_quantity() - def on_update(self): for task in self.get('asset_maintenance_tasks'): assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date) - self.sync_maintenance_tasks() - - def check_for_stock_items_and_warehouse(self): - if self.stock_consumption: - if not self.stock_items: - frappe.throw(_("Please enter Stock Items consumed during Asset Maintenance.")) - if not self.warehouse: - frappe.throw(_("Please enter Warehouse from which Stock Items consumed during Asset Maintenance were taken.")) - - def increase_asset_value(self): - asset_value = frappe.db.get_value('Asset', self.asset_name, 'asset_value') - for item in self.stock_items: - asset_value += item.total_value - - frappe.db.set_value('Asset', self.asset_name, 'asset_value', asset_value) - - def decrease_stock_quantity(self): - stock_entry = frappe.get_doc({ - "doctype": "Stock Entry", - "stock_entry_type": "Material Issue" - }) - - for stock_item in self.stock_items: - stock_entry.append('items', { - "s_warehouse": self.warehouse, - "item_code": stock_item.item, - "qty": stock_item.consumed_quantity - }) - - stock_entry.insert() - stock_entry.submit() + self.sync_maintenance_tasks() def sync_maintenance_tasks(self): tasks_names = [] From 72ea64f6ac3de658758dd9249d361f28337053e5 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Tue, 22 Jun 2021 17:24:14 +0530 Subject: [PATCH 45/60] fix: Sider issues --- erpnext/assets/doctype/asset_repair/asset_repair.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 0049dcaded..6054258ea6 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -14,6 +14,9 @@ class AssetRepair(AccountsController): def validate(self): self.asset_doc = frappe.get_doc('Asset', self.asset) self.update_status() + + if self.get('stock_items'): + self.set_total_value() self.calculate_total_repair_cost() def update_status(self): @@ -22,6 +25,10 @@ class AssetRepair(AccountsController): else: self.asset_doc.set_status() + def set_total_value(self): + for item in self.get('stock_items'): + item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) + def calculate_total_repair_cost(self): self.total_repair_cost = self.repair_cost From 3ba9fb32de38fbaaa3109938308b84ab3c9b31e6 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 23 Jun 2021 13:26:47 +0530 Subject: [PATCH 46/60] fix(Asset Repair): Replace asset_value with value_after_depreciation in tests --- .../doctype/asset_repair/test_asset_repair.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index d1b417fd38..52a960e850 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -74,21 +74,21 @@ class TestAssetRepair(unittest.TestCase): self.assertEqual(stock_entry.items[0].qty, asset_repair.stock_items[0].consumed_quantity) def test_increase_in_asset_value_due_to_stock_consumption(self): - asset = create_asset() - initial_asset_value = asset.asset_value + asset = create_asset(calculate_depreciation = 1) + initial_asset_value = get_asset_value(asset) asset_repair = create_asset_repair(asset= asset, stock_consumption = 1, submit = 1) asset.reload() - increase_in_asset_value = asset.asset_value - initial_asset_value + increase_in_asset_value = get_asset_value(asset) - initial_asset_value self.assertEqual(asset_repair.stock_items[0].total_value, increase_in_asset_value) def test_increase_in_asset_value_due_to_repair_cost_capitalisation(self): - asset = create_asset() - initial_asset_value = asset.asset_value + asset = create_asset(calculate_depreciation = 1) + initial_asset_value = get_asset_value(asset) asset_repair = create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1) asset.reload() - increase_in_asset_value = asset.asset_value - initial_asset_value + increase_in_asset_value = get_asset_value(asset) - initial_asset_value self.assertEqual(asset_repair.repair_cost, increase_in_asset_value) def test_purchase_invoice(self): @@ -109,6 +109,9 @@ class TestAssetRepair(unittest.TestCase): self.assertEqual((initial_num_of_depreciations + 1), num_of_depreciations(asset)) self.assertEqual(asset.schedules[-1].accumulated_depreciation_amount, asset.finance_books[0].value_after_depreciation) +def get_asset_value(asset): + return asset.finance_books[0].value_after_depreciation + def num_of_depreciations(asset): return asset.finance_books[0].total_number_of_depreciations From 39dba43b87423d82821b2da3dc87cf79c62025ca Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 23 Jun 2021 22:19:05 +0530 Subject: [PATCH 47/60] fix(Asset): Fix value_after_depreciation calculation --- erpnext/assets/doctype/asset/asset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 63b70f6613..110922e66b 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -182,10 +182,10 @@ class Asset(AccountsController): # value_after_depreciation - current Asset value if d.value_after_depreciation: value_after_depreciation = (flt(d.value_after_depreciation) - - flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) + flt(self.opening_accumulated_depreciation)) else: value_after_depreciation = (flt(self.gross_purchase_amount) - - flt(self.opening_accumulated_depreciation)) - flt(d.expected_value_after_useful_life) + flt(self.opening_accumulated_depreciation)) d.value_after_depreciation = value_after_depreciation From 18bbfdf343cca9bfed4dd648c5394cf6ced81bc9 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Wed, 23 Jun 2021 22:26:45 +0530 Subject: [PATCH 48/60] fix(Asset Repair): Remove test that's no longer necessary --- erpnext/assets/doctype/asset_repair/test_asset_repair.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index 52a960e850..b3d78b3bfb 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -13,12 +13,6 @@ class TestAssetRepair(unittest.TestCase): create_asset_data() frappe.db.sql("delete from `tabTax Rule`") - def test_completion_date(self): - asset_repair = create_asset_repair() - asset_repair.repair_status = "Completed" - asset_repair.save() - self.assertTrue(asset_repair.completion_date) - def test_update_status(self): asset = create_asset() initial_status = asset.status From f3ae1dd23b05aed611c657931583474f2b5070c2 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 12:44:13 +0530 Subject: [PATCH 49/60] fix(Asset): Fix test --- erpnext/assets/doctype/asset/test_asset.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index f3667c7b95..32bdb5224a 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -125,7 +125,6 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 12, "depreciation_start_date": "2030-12-31" }) - asset.insert() self.assertEqual(asset.status, "Draft") asset.save() expected_schedules = [ From 81bcae7433206d99d6f5cffbe857b96478a14909 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 13:22:26 +0530 Subject: [PATCH 50/60] fix(Asset): Remove redundant code --- erpnext/assets/doctype/asset/test_asset.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 32bdb5224a..59fbe3b030 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -153,9 +153,8 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 12, "depreciation_start_date": '2030-12-31' }) - asset.insert() - self.assertEqual(asset.status, "Draft") asset.save() + self.assertEqual(asset.status, "Draft") expected_schedules = [ ['2030-12-31', 66667.00, 66667.00], @@ -184,7 +183,7 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 12, "depreciation_start_date": "2030-12-31" }) - asset.insert() + asset.save() self.assertEqual(asset.status, "Draft") expected_schedules = [ @@ -215,7 +214,6 @@ class TestAsset(unittest.TestCase): "depreciation_start_date": "2030-12-31" }) - asset.insert() asset.save() expected_schedules = [ @@ -246,7 +244,6 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 10, "depreciation_start_date": "2020-12-31" }) - asset.insert() asset.submit() asset.load_from_db() self.assertEqual(asset.status, "Submitted") @@ -349,7 +346,6 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 10, "depreciation_start_date": "2020-12-31" }) - asset.insert() asset.submit() post_depreciation_entries(date="2021-01-01") @@ -379,7 +375,6 @@ class TestAsset(unittest.TestCase): "total_number_of_depreciations": 10, "frequency_of_depreciation": 1 }) - asset.insert() asset.submit() post_depreciation_entries(date=add_months('2020-01-01', 4)) @@ -423,7 +418,6 @@ class TestAsset(unittest.TestCase): "frequency_of_depreciation": 10, "depreciation_start_date": "2020-12-31" }) - asset.insert() asset.submit() post_depreciation_entries(date="2021-01-01") @@ -467,7 +461,7 @@ class TestAsset(unittest.TestCase): "total_number_of_depreciations": 3, "frequency_of_depreciation": 10 }) - asset.insert() + asset.save() accumulated_depreciation_after_full_schedule = \ max(d.accumulated_depreciation_amount for d in asset.get("schedules")) From cba0966ec59e719ae52c10e38b234f4dd4958525 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 14:56:34 +0530 Subject: [PATCH 51/60] fix(Asset Repair): Change controller hooks --- erpnext/assets/doctype/asset_repair/asset_repair.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 6054258ea6..64c51fd8c3 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -35,7 +35,7 @@ class AssetRepair(AccountsController): total_value_of_stock_consumed = self.get_total_value_of_stock_consumed() self.total_repair_cost += total_value_of_stock_consumed - def on_submit(self): + def before_submit(self): self.check_repair_status() if self.get('stock_consumption') or self.get('capitalize_repair_cost'): @@ -52,7 +52,7 @@ class AssetRepair(AccountsController): self.asset_doc.prepare_depreciation_data() self.asset_doc.save() - def on_cancel(self): + def before_cancel(self): self.asset_doc = frappe.get_doc('Asset', self.asset) if self.get('stock_consumption') or self.get('capitalize_repair_cost'): From 7c37e83535b0c2a7ddc7ff50718fb1ed3e69409c Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 15:04:44 +0530 Subject: [PATCH 52/60] fix(Asset): Remove to_date field --- erpnext/assets/doctype/asset/asset.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index d77eb10418..de060757e2 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -53,7 +53,6 @@ "next_depreciation_date", "section_break_14", "schedules", - "to_date", "insurance_details", "policy_number", "insurer", @@ -481,12 +480,6 @@ "fieldname": "section_break_36", "fieldtype": "Section Break", "label": "Finance Books" - }, - { - "fieldname": "to_date", - "fieldtype": "Date", - "hidden": 1, - "label": "To Date" } ], "idx": 72, @@ -509,7 +502,7 @@ "link_fieldname": "asset" } ], - "modified": "2021-06-19 13:56:58.450182", + "modified": "2021-06-24 14:58:51.097908", "modified_by": "Administrator", "module": "Assets", "name": "Asset", From 597016bb34942170354994f7b90eeb6b529c60f5 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 22:18:59 +0530 Subject: [PATCH 53/60] fix(Asset): Remove extra tabs --- erpnext/assets/doctype/asset/asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 110922e66b..0e1bba6362 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -196,7 +196,7 @@ class Asset(AccountsController): if has_pro_rata: number_of_pending_depreciations += 1 - + skip_row = False for n in range(start, number_of_pending_depreciations): # If depreciation is already completed (for double declining balance) From 267fed2d239b240e12f3d4526e1db79c3ce8dd92 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 22:21:08 +0530 Subject: [PATCH 54/60] fix(Asset): Add comment --- erpnext/assets/doctype/asset/asset.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 0e1bba6362..2fe71672b3 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -224,6 +224,7 @@ class Asset(AccountsController): # For last row elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1: if not self.flags.increase_in_asset_life: + # In case of increase_in_asset_life, the self.to_date is already set on asset_repair submission self.to_date = add_months(self.available_for_use_date, n * cint(d.frequency_of_depreciation)) From c8caafa680edeeea0f16655bed200187be4010b8 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 22:25:45 +0530 Subject: [PATCH 55/60] fix(Asset Repair): Move filters for cost_center, warehouse and project to setup --- .../doctype/asset_repair/asset_repair.js | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.js b/erpnext/assets/doctype/asset_repair/asset_repair.js index 91bed4fdd0..1cebfff66e 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.js +++ b/erpnext/assets/doctype/asset_repair/asset_repair.js @@ -2,6 +2,34 @@ // For license information, please see license.txt frappe.ui.form.on('Asset Repair', { + setup: function(frm) { + frm.fields_dict.cost_center.get_query = function(doc) { + return { + filters: { + 'is_group': 0, + 'company': doc.company + } + }; + }; + + frm.fields_dict.project.get_query = function(doc) { + return { + filters: { + 'company': doc.company + } + }; + }; + + frm.fields_dict.warehouse.get_query = function(doc) { + return { + filters: { + 'is_group': 0, + 'company': doc.company + } + }; + }; + }, + refresh: function(frm) { if (frm.doc.docstatus) { frm.add_custom_button("View General Ledger", function() { @@ -40,30 +68,4 @@ frappe.ui.form.on('Asset Repair Consumed Item', { var row = locals[cdt][cdn]; frappe.model.set_value(cdt, cdn, 'total_value', row.consumed_quantity * row.valuation_rate); }, -}); - -cur_frm.fields_dict.cost_center.get_query = function(doc) { - return { - filters: { - 'is_group': 0, - 'company': doc.company - } - }; -}; - -cur_frm.fields_dict.project.get_query = function(doc) { - return { - filters: { - 'company': doc.company - } - }; -}; - -cur_frm.fields_dict.warehouse.get_query = function(doc) { - return { - filters: { - 'is_group': 0, - 'company': doc.company - } - }; -}; \ No newline at end of file +}); \ No newline at end of file From e328e3b48a51fb44b2fd744d80421bb555f777d1 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 22:27:30 +0530 Subject: [PATCH 56/60] fix(Asset Repair): Edit description for total_repair_cost --- erpnext/assets/doctype/asset_repair/asset_repair.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 14f18b5309..3f62443bda 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -211,7 +211,7 @@ }, { "depends_on": "eval: doc.stock_consumption && doc.total_repair_cost > 0", - "description": "Sum of Repair Cost and the total value of all Stock Items consumed during the repair.", + "description": "Sum of Repair Cost and Value of Consumed Stock Items.", "fieldname": "total_repair_cost", "fieldtype": "Currency", "label": "Total Repair Cost", From fd7fb37697a7720f9e752588799514f917416648 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Thu, 24 Jun 2021 22:30:08 +0530 Subject: [PATCH 57/60] fix(Asset Repair): Simplify code for Asset Repair creation in tests --- erpnext/assets/doctype/asset_repair/test_asset_repair.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py index b3d78b3bfb..30bbb37851 100644 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py @@ -138,10 +138,7 @@ def create_asset_repair(**args): "consumed_quantity": args.qty or 1 }) - try: - asset_repair.save() - except frappe.DuplicateEntryError: - pass + asset_repair.insert(ignore_if_duplicate=True) if args.submit: asset_repair.repair_status = "Completed" From 073b50f7fd0a6c89f86d09bb5b497d7e3a2b188d Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Sat, 26 Jun 2021 01:32:17 +0530 Subject: [PATCH 58/60] fix(Asset Repair): Rearrange fields --- erpnext/assets/doctype/asset_repair/asset_repair.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json index 3f62443bda..19528a26cc 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.json +++ b/erpnext/assets/doctype/asset_repair/asset_repair.json @@ -8,10 +8,10 @@ "engine": "InnoDB", "field_order": [ "asset", - "naming_series", + "company", "column_break_2", "asset_name", - "company", + "naming_series", "section_break_5", "failure_date", "repair_status", @@ -263,7 +263,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2021-06-21 14:53:46.665576", + "modified": "2021-06-25 13:14:38.307723", "modified_by": "Administrator", "module": "Assets", "name": "Asset Repair", From 2e507b47a8f82b62cf4674fe962cf6cc9e035da1 Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 28 Jun 2021 11:42:28 +0530 Subject: [PATCH 59/60] fix(Asset Repair): cancellation --- erpnext/assets/doctype/asset_repair/asset_repair.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index 64c51fd8c3..d32fdf7054 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -30,7 +30,7 @@ class AssetRepair(AccountsController): item.total_value = flt(item.valuation_rate) * flt(item.consumed_quantity) def calculate_total_repair_cost(self): - self.total_repair_cost = self.repair_cost + self.total_repair_cost = flt(self.repair_cost) total_value_of_stock_consumed = self.get_total_value_of_stock_consumed() self.total_repair_cost += total_value_of_stock_consumed @@ -129,6 +129,7 @@ class AssetRepair(AccountsController): def increase_stock_quantity(self): 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): @@ -252,4 +253,4 @@ class AssetRepair(AccountsController): @frappe.whitelist() def get_downtime(failure_date, completion_date): downtime = time_diff_in_hours(completion_date, failure_date) - return round(downtime, 2) \ No newline at end of file + return round(downtime, 2) From 56cdcebbf4d4daa0bffeead320c1187507cc40f6 Mon Sep 17 00:00:00 2001 From: GangaManoj Date: Fri, 16 Jul 2021 02:23:55 +0530 Subject: [PATCH 60/60] fix: Sider issues --- erpnext/assets/doctype/asset/asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 2fe71672b3..ecc35b05b3 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -228,7 +228,7 @@ class Asset(AccountsController): self.to_date = add_months(self.available_for_use_date, n * cint(d.frequency_of_depreciation)) - depreciation_amount, days, months = get_pro_rata_amt(d, + depreciation_amount, days, months = self.get_pro_rata_amt(d, depreciation_amount, schedule_date, self.to_date) monthly_schedule_date = add_months(schedule_date, 1)