Skip to content

Commit adbba1b

Browse files
committed
fix: Removed conflict
1 parent eac3ae5 commit adbba1b

File tree

7 files changed

+713
-661
lines changed

7 files changed

+713
-661
lines changed

erpnext/assets/doctype/asset/asset.py

+156-117
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
get_asset_depr_schedule_doc,
3434
get_depr_schedule,
3535
make_draft_asset_depr_schedules,
36-
make_draft_asset_depr_schedules_if_not_present,
3736
update_draft_asset_depr_schedules,
3837
)
3938
from erpnext.controllers.accounts_controller import AccountsController
@@ -127,30 +126,55 @@ def validate(self):
127126
self.set_missing_values()
128127
self.validate_gross_and_purchase_amount()
129128
self.validate_finance_books()
130-
131-
if not self.split_from:
132-
self.prepare_depreciation_data()
133-
134-
if self.calculate_depreciation:
135-
update_draft_asset_depr_schedules(self)
136-
137-
if frappe.db.exists("Asset", self.name):
138-
asset_depr_schedules_names = make_draft_asset_depr_schedules_if_not_present(self)
139-
140-
if asset_depr_schedules_names:
141-
asset_depr_schedules_links = get_comma_separated_links(
142-
asset_depr_schedules_names, "Asset Depreciation Schedule"
143-
)
144-
frappe.msgprint(
145-
_(
146-
"Asset Depreciation Schedules created:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
147-
).format(asset_depr_schedules_links)
148-
)
149129
self.validate_expected_value_after_useful_life()
150130
self.set_total_booked_depreciations()
151131
self.total_asset_cost = self.gross_purchase_amount
152132
self.status = self.get_status()
153133

134+
def create_asset_depreciation_schedule(self):
135+
if self.split_from or not self.calculate_depreciation:
136+
return
137+
138+
self.set_depr_rate_and_value_after_depreciation()
139+
140+
schedules = []
141+
for row in self.get("finance_books"):
142+
self.validate_asset_finance_books(row)
143+
if not row.rate_of_depreciation:
144+
row.rate_of_depreciation = self.get_depreciation_rate(row, on_validate=True)
145+
146+
schedule_doc = get_asset_depr_schedule_doc(self.name, "Draft", row.finance_book)
147+
if not schedule_doc:
148+
schedule_doc = frappe.new_doc("Asset Depreciation Schedule")
149+
150+
schedule_doc.prepare_draft_asset_depr_schedule_data(self, row)
151+
schedule_doc.save()
152+
schedules.append(schedule_doc.name)
153+
154+
self.show_schedule_creation_message(schedules)
155+
156+
def set_depr_rate_and_value_after_depreciation(self):
157+
if self.calculate_depreciation:
158+
self.value_after_depreciation = 0
159+
self.set_depreciation_rate()
160+
else:
161+
self.finance_books = []
162+
self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(
163+
self.opening_accumulated_depreciation
164+
)
165+
166+
def show_schedule_creation_message(self, schedules):
167+
if schedules:
168+
asset_depr_schedules_links = get_comma_separated_links(schedules, "Asset Depreciation Schedule")
169+
frappe.msgprint(
170+
_(
171+
"Asset Depreciation Schedules created/updated:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
172+
).format(asset_depr_schedules_links)
173+
)
174+
175+
def on_update(self):
176+
self.create_asset_depreciation_schedule()
177+
154178
def on_submit(self):
155179
self.validate_in_use_date()
156180
self.make_asset_movement()
@@ -174,17 +198,17 @@ def on_cancel(self):
174198
self.db_set("booked_fixed_asset", 0)
175199
add_asset_activity(self.name, _("Asset cancelled"))
176200

177-
def after_insert(self):
178-
if self.calculate_depreciation and not self.split_from:
179-
asset_depr_schedules_names = make_draft_asset_depr_schedules(self)
180-
asset_depr_schedules_links = get_comma_separated_links(
181-
asset_depr_schedules_names, "Asset Depreciation Schedule"
182-
)
183-
frappe.msgprint(
184-
_(
185-
"Asset Depreciation Schedules created:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
186-
).format(asset_depr_schedules_links)
187-
)
201+
# def after_insert(self):
202+
# if self.calculate_depreciation and not self.split_from:
203+
# asset_depr_schedules_names = make_draft_asset_depr_schedules(self)
204+
# asset_depr_schedules_links = get_comma_separated_links(
205+
# asset_depr_schedules_names, "Asset Depreciation Schedule"
206+
# )
207+
# frappe.msgprint(
208+
# _(
209+
# "Asset Depreciation Schedules created:<br>{0}<br><br>Please check, edit if needed, and submit the Asset."
210+
# ).format(asset_depr_schedules_links)
211+
# )
188212
if (
189213
not frappe.db.exists(
190214
{
@@ -214,16 +238,6 @@ def validate_asset_and_reference(self):
214238
if self.is_existing_asset and self.purchase_invoice:
215239
frappe.throw(_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name))
216240

217-
def prepare_depreciation_data(self):
218-
if self.calculate_depreciation:
219-
self.value_after_depreciation = 0
220-
self.set_depreciation_rate()
221-
else:
222-
self.finance_books = []
223-
self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(
224-
self.opening_accumulated_depreciation
225-
)
226-
227241
def validate_item(self):
228242
item = frappe.get_cached_value(
229243
"Item", self.item_code, ["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1
@@ -308,6 +322,22 @@ def validate_finance_books(self):
308322
title=_("Missing Finance Book"),
309323
)
310324

325+
# def set_depreciation_start_date(self):
326+
# if not self.calculate_depreciation:
327+
# return
328+
329+
# for d in self.get("finance_books"):
330+
# if not d.depreciation_start_date:
331+
# if self.is_existing_asset and self.opening_number_of_booked_depreciations:
332+
333+
# months = d.frequency_of_depreciation * self.opening_number_of_booked_depreciations
334+
# else:
335+
# months = d.frequency_of_depreciation
336+
337+
# d.depreciation_start_date = get_last_day(
338+
# add_months(self.available_for_use_date, months)
339+
# )
340+
311341
def validate_precision(self):
312342
float_precision = cint(frappe.db.get_default("float_precision")) or 2
313343
if self.gross_purchase_amount:
@@ -418,61 +448,65 @@ def validate_asset_finance_books(self, row):
418448
frappe.throw(
419449
_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount").format(
420450
row.idx
421-
),
422-
title=_("Invalid Schedule"),
451+
)
423452
)
424453

425454
if not row.depreciation_start_date:
426-
if not self.available_for_use_date:
427-
frappe.throw(
428-
_("Row {0}: Depreciation Start Date is required").format(row.idx),
429-
title=_("Invalid Schedule"),
430-
)
431455
row.depreciation_start_date = get_last_day(self.available_for_use_date)
456+
self.validate_depreciation_start_date(row)
432457

433458
if not self.is_existing_asset:
434459
self.opening_accumulated_depreciation = 0
435460
self.opening_number_of_booked_depreciations = 0
436461
else:
437-
depreciable_amount = flt(
438-
flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life),
439-
self.precision("gross_purchase_amount"),
440-
)
441-
if flt(self.opening_accumulated_depreciation) > depreciable_amount:
442-
frappe.throw(
443-
_("Opening Accumulated Depreciation must be less than or equal to {0}").format(
444-
depreciable_amount
445-
)
462+
self.validate_opening_depreciation_values(row)
463+
464+
def validate_opening_depreciation_values(self, row):
465+
row.expected_value_after_useful_life = flt(
466+
row.expected_value_after_useful_life, self.precision("gross_purchase_amount")
467+
)
468+
depreciable_amount = flt(
469+
flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life),
470+
self.precision("gross_purchase_amount"),
471+
)
472+
if flt(self.opening_accumulated_depreciation) > depreciable_amount:
473+
frappe.throw(
474+
_("Row #{0}: Opening Accumulated Depreciation must be less than or equal to {1}").format(
475+
row.idx, depreciable_amount
446476
)
477+
)
447478

448-
if self.opening_accumulated_depreciation:
449-
if not self.opening_number_of_booked_depreciations:
450-
frappe.throw(_("Please set Opening Number of Booked Depreciations"))
451-
else:
452-
self.opening_number_of_booked_depreciations = 0
479+
if self.opening_accumulated_depreciation:
480+
if not self.opening_number_of_booked_depreciations:
481+
frappe.throw(_("Please set opening number of booked depreciations"))
482+
else:
483+
self.opening_number_of_booked_depreciations = 0
484+
485+
if flt(row.total_number_of_depreciations) <= cint(self.opening_number_of_booked_depreciations):
486+
frappe.throw(
487+
_(
488+
"Row #{0}: Total Number of Depreciations cannot be less than or equal to Opening Number of Booked Depreciations"
489+
).format(row.idx),
490+
title=_("Invalid Schedule"),
491+
)
453492

454-
if flt(row.total_number_of_depreciations) <= cint(self.opening_number_of_booked_depreciations):
493+
def validate_depreciation_start_date(self, row):
494+
if row.depreciation_start_date:
495+
if getdate(row.depreciation_start_date) < getdate(self.purchase_date):
455496
frappe.throw(
456-
_(
457-
"Row {0}: Total Number of Depreciations cannot be less than or equal to Opening Number of Booked Depreciations"
458-
).format(row.idx),
459-
title=_("Invalid Schedule"),
497+
_("Row #{0}: Next Depreciation Date cannot be before Purchase Date").format(row.idx)
460498
)
461499

462-
if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.purchase_date):
463-
frappe.throw(
464-
_("Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date").format(
465-
row.idx
500+
if getdate(row.depreciation_start_date) < getdate(self.available_for_use_date):
501+
frappe.throw(
502+
_("Row #{0}: Next Depreciation Date cannot be before Available-for-use Date").format(
503+
row.idx
504+
)
466505
)
467-
)
468-
469-
if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(
470-
self.available_for_use_date
471-
):
506+
else:
472507
frappe.throw(
473-
_(
474-
"Depreciation Row {0}: Next Depreciation Date cannot be before Available-for-use Date"
475-
).format(row.idx)
508+
_("Row #{0}: Depreciation Start Date is required").format(row.idx),
509+
title=_("Invalid Schedule"),
476510
)
477511

478512
def set_total_booked_depreciations(self):
@@ -496,15 +530,11 @@ def validate_expected_value_after_useful_life(self):
496530
if not depr_schedule:
497531
continue
498532

499-
accumulated_depreciation_after_full_schedule = [
500-
d.accumulated_depreciation_amount for d in depr_schedule
501-
]
533+
accumulated_depreciation_after_full_schedule = max(
534+
[d.accumulated_depreciation_amount for d in depr_schedule]
535+
)
502536

503537
if accumulated_depreciation_after_full_schedule:
504-
accumulated_depreciation_after_full_schedule = max(
505-
accumulated_depreciation_after_full_schedule
506-
)
507-
508538
asset_value_after_full_schedule = flt(
509539
flt(self.gross_purchase_amount) - flt(accumulated_depreciation_after_full_schedule),
510540
self.precision("gross_purchase_amount"),
@@ -786,50 +816,59 @@ def get_depreciation_rate(self, args, on_validate=False):
786816
if isinstance(args, str):
787817
args = json.loads(args)
788818

789-
float_precision = cint(frappe.db.get_default("float_precision")) or 2
819+
rate_field_precision = frappe.get_precision(args.doctype, "rate_of_depreciation") or 2
790820

791821
if args.get("depreciation_method") == "Double Declining Balance":
792-
return 200.0 / (
822+
return self.get_double_declining_balance_rate(args, rate_field_precision)
823+
elif args.get("depreciation_method") == "Written Down Value":
824+
return self.get_written_down_value_rate(args, rate_field_precision, on_validate)
825+
826+
def get_double_declining_balance_rate(self, args, rate_field_precision):
827+
return flt(
828+
200.0
829+
/ (
793830
(
794831
flt(args.get("total_number_of_depreciations"), 2)
795832
* flt(args.get("frequency_of_depreciation"))
796833
)
797834
/ 12
798-
)
835+
),
836+
rate_field_precision,
837+
)
799838

800-
if args.get("depreciation_method") == "Written Down Value":
801-
if (
802-
args.get("rate_of_depreciation")
803-
and on_validate
804-
and not self.flags.increase_in_asset_value_due_to_repair
805-
):
806-
return args.get("rate_of_depreciation")
839+
def get_written_down_value_rate(self, args, rate_field_precision, on_validate):
840+
if (
841+
args.get("rate_of_depreciation")
842+
and on_validate
843+
and not self.flags.increase_in_asset_value_due_to_repair
844+
):
845+
return args.get("rate_of_depreciation")
807846

808-
if self.flags.increase_in_asset_value_due_to_repair:
809-
value = flt(args.get("expected_value_after_useful_life")) / flt(
810-
args.get("value_after_depreciation")
811-
)
812-
else:
813-
value = flt(args.get("expected_value_after_useful_life")) / (
814-
flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)
815-
)
847+
if self.flags.increase_in_asset_value_due_to_repair:
848+
value = flt(args.get("expected_value_after_useful_life")) / flt(
849+
args.get("value_after_depreciation")
850+
)
851+
else:
852+
value = flt(args.get("expected_value_after_useful_life")) / (
853+
flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)
854+
)
816855

817-
depreciation_rate = math.pow(
818-
value,
819-
1.0
820-
/ (
856+
depreciation_rate = math.pow(
857+
value,
858+
1.0
859+
/ (
860+
(
821861
(
822-
(
823-
flt(args.get("total_number_of_depreciations"), 2)
824-
- flt(self.opening_number_of_booked_depreciations)
825-
)
826-
* flt(args.get("frequency_of_depreciation"))
862+
flt(args.get("total_number_of_depreciations"), 2)
863+
- flt(self.opening_number_of_booked_depreciations)
827864
)
828-
/ 12
829-
),
830-
)
865+
* flt(args.get("frequency_of_depreciation"))
866+
)
867+
/ 12
868+
),
869+
)
831870

832-
return flt((100 * (1 - depreciation_rate)), float_precision)
871+
return flt((100 * (1 - depreciation_rate)), rate_field_precision)
833872

834873

835874
def has_gl_entries(doctype, docname, target_account):

erpnext/assets/doctype/asset/test_asset.py

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
_get_pro_rata_amt,
3535
get_asset_depr_schedule_doc,
3636
get_depr_schedule,
37+
)
38+
from erpnext.assets.doctype.asset_depreciation_schedule.utils import (
3739
get_depreciation_amount,
3840
)
3941
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (

0 commit comments

Comments
 (0)