mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-03 05:28:27 +00:00
fix: remove duplicate patch
This commit is contained in:
@@ -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 = []
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user