diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index a5fd70402c4..6a215040679 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -160,7 +160,7 @@ class Asset(AccountsController): if self.calculate_depreciation: self.set_depreciation_rate() for d in self.finance_books: - d.value_after_depreciation = self.value_after_depreciation + d.db_set("value_after_depreciation", self.value_after_depreciation) else: self.finance_books = [] diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index de7d14cb8a1..868441d60c3 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -28,7 +28,7 @@ from erpnext.assets.doctype.asset_activity.asset_activity import add_asset_activ from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import ( get_asset_depr_schedule_doc, get_asset_depr_schedule_name, - get_temp_asset_depr_schedule_doc, + get_temp_depr_schedule_doc, reschedule_depreciation, ) @@ -874,9 +874,7 @@ def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_ row = asset_doc.finance_books[idx - 1] - temp_asset_depreciation_schedule = get_temp_asset_depr_schedule_doc( - asset_doc, row, getdate(disposal_date) - ) + temp_asset_depreciation_schedule = get_temp_depr_schedule_doc(asset_doc, row, getdate(disposal_date)) accumulated_depr_amount = temp_asset_depreciation_schedule.get("depreciation_schedule")[ -1 diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py index c75e08bbb87..e0e60d7cdfd 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py @@ -107,14 +107,9 @@ class AssetDepreciationSchedule(DepreciationScheduleController): frappe.get_doc("Journal Entry", d.journal_entry).cancel() def update_shift_depr_schedule(self): - if not self.shift_based or self.docstatus != 0: + if not self.shift_based or self.docstatus != 0 or self.get("__islocal"): return - - asset_doc = frappe.get_doc("Asset", self.asset) - fb_row = asset_doc.finance_books[self.finance_book_id - 1] - - self.make_depr_schedule(asset_doc, fb_row) - self.set_accumulated_depreciation(asset_doc, fb_row) + self.create_depreciation_schedule() def get_finance_book_row(self, fb_row=None): if fb_row: @@ -144,6 +139,7 @@ class AssetDepreciationSchedule(DepreciationScheduleController): self.total_number_of_depreciations = self.fb_row.total_number_of_depreciations self.frequency_of_depreciation = self.fb_row.frequency_of_depreciation self.rate_of_depreciation = self.fb_row.get("rate_of_depreciation") + self.value_after_depreciation = self.fb_row.value_after_depreciation self.expected_value_after_useful_life = self.fb_row.get("expected_value_after_useful_life") self.daily_prorata_based = self.fb_row.get("daily_prorata_based") self.shift_based = self.fb_row.get("shift_based") @@ -218,50 +214,46 @@ def set_modified_depreciation_rate(asset_doc, row, new_schedule): new_schedule.rate_of_depreciation = new_rate_of_depreciation +def get_temp_depr_schedule_doc(asset_doc, fb_row, disposal_date=None, updated_depr_schedule=None): + current_schedule = get_current_asset_depr(asset_doc, fb_row) + temp_schedule_doc = frappe.copy_doc(current_schedule) -def get_temp_asset_depr_schedule_doc( - asset_doc, - row, - disposal_date=None, - date_of_return=None, - update_asset_finance_book_row=False, - new_depr_schedule=None, -): + if updated_depr_schedule: + modify_depreciation_dchedule(temp_schedule_doc, updated_depr_schedule) + + temp_schedule_doc.create_depreciation_schedule(fb_row, disposal_date) + return temp_schedule_doc + + +def get_current_asset_depr(asset_doc, row): current_schedule = get_asset_depr_schedule_doc(asset_doc.name, "Active", row.finance_book) - if not current_schedule: frappe.throw( _("Asset Depreciation Schedule not found for Asset {0} and Finance Book {1}").format( get_link_to_form("Asset", asset_doc.name), row.finance_book ) ) + return current_schedule - temp_asset_depr_schedule_doc = frappe.copy_doc(current_schedule) - if new_depr_schedule: - temp_asset_depr_schedule_doc.depreciation_schedule = [] +def modify_depreciation_dchedule(temp_schedule_doc, updated_depr_schedule): + temp_schedule_doc.depreciation_schedule = [] - for schedule in new_depr_schedule: - temp_asset_depr_schedule_doc.append( - "depreciation_schedule", - { - "schedule_date": schedule.schedule_date, - "depreciation_amount": schedule.depreciation_amount, - "accumulated_depreciation_amount": schedule.accumulated_depreciation_amount, - "journal_entry": schedule.journal_entry, - "shift": schedule.shift, - }, - ) + for schedule in updated_depr_schedule: + temp_schedule_doc.append( + "depreciation_schedule", + { + "schedule_date": schedule.schedule_date, + "depreciation_amount": schedule.depreciation_amount, + "accumulated_depreciation_amount": schedule.accumulated_depreciation_amount, + "journal_entry": schedule.journal_entry, + "shift": schedule.shift, + }, + ) - temp_asset_depr_schedule_doc.create_depreciation_schedule( - asset_doc, - row, - disposal_date, - date_of_return, - update_asset_finance_book_row, - ) - return temp_asset_depr_schedule_doc +def get_asset_shift_factors_map(): + return dict(frappe.db.get_all("Asset Shift Factor", ["shift_name", "shift_factor"], as_list=True)) @frappe.whitelist() diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/deppreciation_schedule_controller.py b/erpnext/assets/doctype/asset_depreciation_schedule/deppreciation_schedule_controller.py index 0f72f80e907..277b12cfc5c 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/deppreciation_schedule_controller.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/deppreciation_schedule_controller.py @@ -42,7 +42,6 @@ class DepreciationScheduleController(StraightLineMethod, WDVMethod): depr_schedule = [] self.schedules_before_clearing = self.get("depreciation_schedule") - for schedule in self.get("depreciation_schedule"): if schedule.journal_entry: num_of_depreciations_completed += 1 @@ -68,7 +67,6 @@ class DepreciationScheduleController(StraightLineMethod, WDVMethod): self.schedule_date = self.get_next_schedule_date(row_idx) self.depreciation_amount = self.get_depreciation_amount(row_idx) - print(row_idx, self.schedule_date, self.depreciation_amount) # if asset is being sold or scrapped if self.disposal_date and getdate(self.schedule_date) >= getdate(self.disposal_date): @@ -228,12 +226,8 @@ class DepreciationScheduleController(StraightLineMethod, WDVMethod): total_months = cint(self.fb_row.total_number_of_depreciations) * cint( self.fb_row.frequency_of_depreciation ) + cint(self.fb_row.increase_in_asset_life) - depr_booked_for_months = 0 last_depr_date = self.get_last_booked_depreciation_date() - if last_depr_date: - depr_booked_for_months = date_diff(last_depr_date, self.asset_doc.available_for_use_date) / ( - 365 / 12 - ) + depr_booked_for_months = self.get_booked_depr_for_months_count(last_depr_date) self.pending_months = total_months - depr_booked_for_months @@ -245,9 +239,22 @@ class DepreciationScheduleController(StraightLineMethod, WDVMethod): last_depr_date = add_months( self.fb_row.depreciation_start_date, -1 * self.fb_row.frequency_of_depreciation ) - return last_depr_date + def get_booked_depr_for_months_count(self, last_depr_date): + depr_booked_for_months = 0 + if last_depr_date: + asset_used_for_months = self.fb_row.frequency_of_depreciation * ( + 1 + self.asset_doc.opening_number_of_booked_depreciations + ) + computed_available_for_use_date = add_days( + add_months(self.fb_row.depreciation_start_date, -1 * asset_used_for_months), 1 + ) + if getdate(computed_available_for_use_date) < getdate(self.asset_doc.available_for_use_date): + computed_available_for_use_date = self.asset_doc.available_for_use_date + depr_booked_for_months = date_diff(last_depr_date, computed_available_for_use_date) / (365 / 12) + return depr_booked_for_months + def get_total_pending_days_or_years(self): if cint(frappe.db.get_single_value("Accounts Settings", "calculate_depr_using_total_days")): last_depr_date = self.get_last_booked_depreciation_date() diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/depreciation_methods.py b/erpnext/assets/doctype/asset_depreciation_schedule/depreciation_methods.py index 9a573ea05e1..da7962db63e 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/depreciation_methods.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/depreciation_methods.py @@ -25,7 +25,7 @@ class StraightLineMethod(Document): ) if self.fb_row.shift_based: - self.get_shift_depr_amount(row_idx) + return self.get_shift_depr_amount(row_idx) if self.fb_row.daily_prorata_based: return self.get_daily_prorata_based_depr_amount(row_idx) @@ -51,31 +51,29 @@ class StraightLineMethod(Document): return yearly_depr_amount / total_days_in_current_depr_year def get_shift_depr_amount(self, row_idx): - depreciable_value = ( - flt(self.asset_doc.gross_purchase_amount) - - flt(self.asset_doc.opening_accumulated_depreciation) - - flt(self.fb_row.expected_value_after_useful_life) - ) - if self.get("__islocal") and not self.asset_doc.flags.shift_allocation: - pending_depreciations = flt( - self.fb_row.total_number_of_depreciations - - self.asset_doc.opening_number_of_booked_depreciations - ) - return depreciable_value / pending_depreciations + if not self.schedules_before_clearing: + pending_periods = flt(self.pending_months) / flt(self.fb_row.frequency_of_depreciation) + return self.depreciable_value / pending_periods asset_shift_factors_map = self.get_asset_shift_factors_map() - shift = ( - self.schedules_before_clearing[row_idx].shift - if len(self.schedules_before_clearing) > row_idx - else None - ) + + if self.schedules_before_clearing: + shift = ( + self.schedules_before_clearing[row_idx].shift + if len(self.schedules_before_clearing) > row_idx + else None + ) + shift_factor = asset_shift_factors_map.get(shift, 0) - shift_factors_sum = sum( - [flt(asset_shift_factors_map.get(d.shift)) for d in self.schedules_before_clearing] + [ + flt(asset_shift_factors_map.get(d.shift)) + for d in self.schedules_before_clearing + if not d.journal_entry + ] ) - return (depreciable_value / shift_factors_sum) * shift_factor + return (self.depreciable_value / shift_factors_sum) * shift_factor def get_asset_shift_factors_map(self): return dict(frappe.db.get_all("Asset Shift Factor", ["shift_name", "shift_factor"], as_list=True)) diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js index c22feb05458..98903048f79 100644 --- a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js +++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.js @@ -2,6 +2,15 @@ // For license information, please see license.txt frappe.ui.form.on("Asset Shift Allocation", { onload: function (frm) { + frm.set_query("asset", function () { + return { + filters: { + company: frm.doc.company, + docstatus: 1, + }, + }; + }); + frm.events.make_schedules_editable(frm); }, diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json index 7693037042d..22c274df970 100644 --- a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json +++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json @@ -12,6 +12,7 @@ "finance_book", "amended_from", "depreciation_schedule_section", + "column_break_jomc", "depreciation_schedule" ], "fields": [ @@ -57,7 +58,9 @@ "fieldname": "depreciation_schedule", "fieldtype": "Table", "label": "Depreciation Schedule", - "options": "Depreciation Schedule" + "no_copy": 1, + "options": "Depreciation Schedule", + "read_only": 1 }, { "fieldname": "naming_series", @@ -65,12 +68,16 @@ "label": "Naming Series", "options": "ACC-ASA-.YYYY.-", "reqd": 1 + }, + { + "fieldname": "column_break_jomc", + "fieldtype": "Column Break" } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-03-27 13:06:35.732191", + "modified": "2025-01-10 16:25:31.397325", "modified_by": "Administrator", "module": "Assets", "name": "Asset Shift Allocation", diff --git a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py index 4c5253b338d..e273b997a3d 100644 --- a/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py +++ b/erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.py @@ -16,10 +16,8 @@ from frappe.utils import ( from erpnext.assets.doctype.asset_activity.asset_activity import add_asset_activity from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import ( get_asset_depr_schedule_doc, - get_temp_asset_depr_schedule_doc, -) -from erpnext.erpnext.assets.doctype.asset_depreciation_schedule.deppreciation_schedule_controller import ( get_asset_shift_factors_map, + get_temp_depr_schedule_doc, ) @@ -32,9 +30,7 @@ class AssetShiftAllocation(Document): if TYPE_CHECKING: from frappe.types import DF - from erpnext.assets.doctype.depreciation_schedule.depreciation_schedule import ( - DepreciationSchedule, - ) + from erpnext.assets.doctype.depreciation_schedule.depreciation_schedule import DepreciationSchedule amended_from: DF.Link | None asset: DF.Link @@ -43,32 +39,138 @@ class AssetShiftAllocation(Document): naming_series: DF.Literal["ACC-ASA-.YYYY.-"] # end: auto-generated types - def after_insert(self): - self.fetch_and_set_depr_schedule() - def validate(self): self.asset_depr_schedule_doc = get_asset_depr_schedule_doc(self.asset, "Active", self.finance_book) + if self.get("depreciation_schedule") and self.docstatus == 0: + self.validate_invalid_shift_change() + self.update_depr_schedule() - self.validate_invalid_shift_change() - self.update_depr_schedule() + def after_insert(self): + self.fetch_and_set_depr_schedule() def on_submit(self): self.create_new_asset_depr_schedule() + def validate_invalid_shift_change(self): + for i, sch in enumerate(self.depreciation_schedule): + if sch.journal_entry and self.asset_depr_schedule_doc.depreciation_schedule[i].shift != sch.shift: + frappe.throw( + _( + "Row {0}: Shift cannot be changed since the depreciation has already been processed" + ).format(i) + ) + + def update_depr_schedule(self): + self.adjust_depr_shifts() + + asset_doc = frappe.get_doc("Asset", self.asset) + fb_row = self.get_finance_book_row(asset_doc) + + temp_depr_schedule_doc = get_temp_depr_schedule_doc( + asset_doc, fb_row, updated_depr_schedule=self.depreciation_schedule + ) + + # Update the depreciation schedule with the new shifts + self.depreciation_schedule = [] + self.modify_depr_schedule(temp_depr_schedule_doc.get("depreciation_schedule")) + + def adjust_depr_shifts(self): + """ + Adjust the shifts in the depreciation schedule based on the new shifts + """ + shift_factors_map = get_asset_shift_factors_map() + reverse_shift_factors_map = {v: k for k, v in shift_factors_map.items()} + factor_diff = self.calculate_shift_factor_diff(shift_factors_map) + + # Case 1: Reduce shifts if there is an excess factor + if factor_diff > 0: + self.reduce_depr_shifts(factor_diff, shift_factors_map, reverse_shift_factors_map) + + # Case 2: Add shifts if there is a missing factor + elif factor_diff < 0: + self.add_depr_shifts(factor_diff, shift_factors_map, reverse_shift_factors_map) + + def calculate_shift_factor_diff(self, shift_factors_map): + original_shift_sum = sum( + shift_factors_map.get(schedule.shift, 0) + for schedule in self.asset_depr_schedule_doc.depreciation_schedule + ) + new_shift_sum = sum( + shift_factors_map.get(schedule.shift, 0) for schedule in self.depreciation_schedule + ) + return new_shift_sum - original_shift_sum + + def reduce_depr_shifts(self, factor_diff, shift_factors_map, reverse_shift_factors_map): + for i, schedule in reversed(list(enumerate(self.depreciation_schedule))): + if factor_diff <= 0: + break + + current_factor = shift_factors_map.get(schedule.shift, 0) + if current_factor <= factor_diff: + self.depreciation_schedule.pop(i) + factor_diff -= current_factor + else: + new_factor = current_factor - factor_diff + self.depreciation_schedule[i].shift = reverse_shift_factors_map.get(new_factor) + factor_diff = 0 + + def add_depr_shifts(self, factor_diff, shift_factors_map, reverse_shift_factors_map): + factor_diff = abs(factor_diff) + shift_factors = sorted(shift_factors_map.values(), reverse=True) + + while factor_diff > 0: + for factor in shift_factors: + if factor <= factor_diff: + self.add_schedule_row(factor, reverse_shift_factors_map) + factor_diff -= factor + break + else: + frappe.throw( + _("Could not find a suitable shift to match the difference: {0}").format(factor_diff) + ) + + def add_schedule_row(self, factor, reverse_shift_factors_map): + schedule_date = add_months( + self.depreciation_schedule[-1].schedule_date, + cint(self.asset_depr_schedule_doc.frequency_of_depreciation), + ) + if is_last_day_of_the_month(self.depreciation_schedule[-1].schedule_date): + schedule_date = get_last_day(schedule_date) + + self.append( + "depreciation_schedule", + { + "schedule_date": schedule_date, + "shift": reverse_shift_factors_map.get(factor), + }, + ) + + def get_finance_book_row(self, asset_doc): + idx = 0 + for d in asset_doc.get("finance_books"): + if d.finance_book == self.finance_book: + idx = d.idx + break + + return asset_doc.get("finance_books")[idx - 1] + + def modify_depr_schedule(self, temp_depr_schedule): + for schedule in temp_depr_schedule: + self.append( + "depreciation_schedule", + { + "schedule_date": schedule.schedule_date, + "depreciation_amount": schedule.depreciation_amount, + "accumulated_depreciation_amount": schedule.accumulated_depreciation_amount, + "journal_entry": schedule.journal_entry, + "shift": schedule.shift, + }, + ) + def fetch_and_set_depr_schedule(self): if self.asset_depr_schedule_doc: if self.asset_depr_schedule_doc.shift_based: - for schedule in self.asset_depr_schedule_doc.get("depreciation_schedule"): - self.append( - "depreciation_schedule", - { - "schedule_date": schedule.schedule_date, - "depreciation_amount": schedule.depreciation_amount, - "accumulated_depreciation_amount": schedule.accumulated_depreciation_amount, - "journal_entry": schedule.journal_entry, - "shift": schedule.shift, - }, - ) + self.modify_depr_schedule(self.asset_depr_schedule_doc.depreciation_schedule) self.flags.ignore_validate = True self.save() @@ -85,143 +187,6 @@ class AssetShiftAllocation(Document): ) ) - def validate_invalid_shift_change(self): - if not self.get("depreciation_schedule") or self.docstatus == 1: - return - - for i, sch in enumerate(self.depreciation_schedule): - if sch.journal_entry and self.asset_depr_schedule_doc.depreciation_schedule[i].shift != sch.shift: - frappe.throw( - _( - "Row {0}: Shift cannot be changed since the depreciation has already been processed" - ).format(i) - ) - - def update_depr_schedule(self): - if not self.get("depreciation_schedule") or self.docstatus == 1: - return - - self.allocate_shift_diff_in_depr_schedule() - - asset_doc = frappe.get_doc("Asset", self.asset) - fb_row = asset_doc.finance_books[self.asset_depr_schedule_doc.finance_book_id - 1] - - asset_doc.flags.shift_allocation = True - - temp_depr_schedule = get_temp_asset_depr_schedule_doc( - asset_doc, fb_row, new_depr_schedule=self.depreciation_schedule - ).get("depreciation_schedule") - - self.depreciation_schedule = [] - - for schedule in temp_depr_schedule: - self.append( - "depreciation_schedule", - { - "schedule_date": schedule.schedule_date, - "depreciation_amount": schedule.depreciation_amount, - "accumulated_depreciation_amount": schedule.accumulated_depreciation_amount, - "journal_entry": schedule.journal_entry, - "shift": schedule.shift, - }, - ) - - def allocate_shift_diff_in_depr_schedule(self): - asset_shift_factors_map = get_asset_shift_factors_map() - reverse_asset_shift_factors_map = {asset_shift_factors_map[k]: k for k in asset_shift_factors_map} - - original_shift_factors_sum = sum( - flt(asset_shift_factors_map.get(schedule.shift)) - for schedule in self.asset_depr_schedule_doc.depreciation_schedule - ) - - new_shift_factors_sum = sum( - flt(asset_shift_factors_map.get(schedule.shift)) for schedule in self.depreciation_schedule - ) - - diff = new_shift_factors_sum - original_shift_factors_sum - - if diff > 0: - for i, schedule in reversed(list(enumerate(self.depreciation_schedule))): - if diff <= 0: - break - - shift_factor = flt(asset_shift_factors_map.get(schedule.shift)) - - if shift_factor <= diff: - self.depreciation_schedule.pop() - diff -= shift_factor - else: - try: - self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get( - shift_factor - diff - ) - diff = 0 - except Exception: - frappe.throw( - _("Could not auto update shifts. Shift with shift factor {0} needed.") - ).format(shift_factor - diff) - elif diff < 0: - shift_factors = list(asset_shift_factors_map.values()) - desc_shift_factors = sorted(shift_factors, reverse=True) - depr_schedule_len_diff = self.asset_depr_schedule_doc.total_number_of_depreciations - len( - self.depreciation_schedule - ) - subsets_result = [] - - if depr_schedule_len_diff > 0: - num_rows_to_add = depr_schedule_len_diff - - while not subsets_result and num_rows_to_add > 0: - find_subsets_with_sum(shift_factors, num_rows_to_add, abs(diff), [], subsets_result) - if subsets_result: - break - num_rows_to_add -= 1 - - if subsets_result: - for i in range(num_rows_to_add): - schedule_date = add_months( - self.depreciation_schedule[-1].schedule_date, - cint(self.asset_depr_schedule_doc.frequency_of_depreciation), - ) - - if is_last_day_of_the_month(self.depreciation_schedule[-1].schedule_date): - schedule_date = get_last_day(schedule_date) - - self.append( - "depreciation_schedule", - { - "schedule_date": schedule_date, - "shift": reverse_asset_shift_factors_map.get(subsets_result[0][i]), - }, - ) - - if depr_schedule_len_diff <= 0 or not subsets_result: - for i, schedule in reversed(list(enumerate(self.depreciation_schedule))): - diff = abs(diff) - - if diff <= 0: - break - - shift_factor = flt(asset_shift_factors_map.get(schedule.shift)) - - if shift_factor <= diff: - for sf in desc_shift_factors: - if sf - shift_factor <= diff: - self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get(sf) - diff -= sf - shift_factor - break - else: - try: - self.depreciation_schedule[i].shift = reverse_asset_shift_factors_map.get( - shift_factor + diff - ) - diff = 0 - except Exception: - frappe.throw( - _("Could not auto update shifts. Shift with shift factor {0} needed.") - ).format(shift_factor + diff) - def create_new_asset_depr_schedule(self): new_asset_depr_schedule_doc = frappe.copy_doc(self.asset_depr_schedule_doc) @@ -259,17 +224,3 @@ class AssetShiftAllocation(Document): get_link_to_form(self.doctype, self.name) ), ) - - -def find_subsets_with_sum(numbers, k, target_sum, current_subset, result): - if k == 0 and target_sum == 0: - result.append(current_subset.copy()) - return - if k <= 0 or target_sum <= 0 or not numbers: - return - - # Include the current number in the subset - find_subsets_with_sum(numbers, k - 1, target_sum - numbers[0], [*current_subset, numbers[0]], result) - - # Exclude the current number from the subset - find_subsets_with_sum(numbers[1:], k, target_sum, current_subset, result) diff --git a/erpnext/patches/v15_0/update_journal_entry_type.py b/erpnext/patches/v15_0/update_journal_entry_type.py index 32a499d01af..0d243bac2f7 100644 --- a/erpnext/patches/v15_0/update_journal_entry_type.py +++ b/erpnext/patches/v15_0/update_journal_entry_type.py @@ -6,6 +6,7 @@ def execute(): "Property Setter", {"doc_type": "Journal Entry", "field_name": "voucher_type", "property": "options"}, ["name", "value"], + as_dict=True, ) if custom_je_type: custom_je_type.value += "\nAsset Disposal"