mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-05 06:28:29 +00:00
Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-40584
This commit is contained in:
@@ -12,7 +12,6 @@ from erpnext.buying.dashboard_fixtures import get_company_for_dashboards
|
||||
|
||||
|
||||
def get_data():
|
||||
|
||||
fiscal_year = _get_fiscal_year(nowdate())
|
||||
|
||||
if not fiscal_year:
|
||||
@@ -168,9 +167,7 @@ def get_number_cards(fiscal_year, year_start_date, year_end_date):
|
||||
"is_public": 1,
|
||||
"show_percentage_stats": 1,
|
||||
"stats_time_interval": "Monthly",
|
||||
"filters_json": json.dumps(
|
||||
[["Asset", "creation", "between", [year_start_date, year_end_date]]]
|
||||
),
|
||||
"filters_json": json.dumps([["Asset", "creation", "between", [year_start_date, year_end_date]]]),
|
||||
"doctype": "Number Card",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -209,9 +209,7 @@ class Asset(AccountsController):
|
||||
)
|
||||
|
||||
if self.is_existing_asset and self.purchase_invoice:
|
||||
frappe.throw(
|
||||
_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name)
|
||||
)
|
||||
frappe.throw(_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name))
|
||||
|
||||
def prepare_depreciation_data(self):
|
||||
if self.calculate_depreciation:
|
||||
@@ -272,9 +270,9 @@ class Asset(AccountsController):
|
||||
for d in self.finance_books:
|
||||
if d.depreciation_start_date == self.available_for_use_date:
|
||||
frappe.throw(
|
||||
_("Row #{}: Depreciation Posting Date should not be equal to Available for Use Date.").format(
|
||||
d.idx
|
||||
),
|
||||
_(
|
||||
"Row #{}: Depreciation Posting Date should not be equal to Available for Use Date."
|
||||
).format(d.idx),
|
||||
title=_("Incorrect Date"),
|
||||
)
|
||||
|
||||
@@ -283,9 +281,7 @@ class Asset(AccountsController):
|
||||
self.asset_category = frappe.get_cached_value("Item", self.item_code, "asset_category")
|
||||
|
||||
if self.item_code and not self.get("finance_books"):
|
||||
finance_books = get_item_details(
|
||||
self.item_code, self.asset_category, self.gross_purchase_amount
|
||||
)
|
||||
finance_books = get_item_details(self.item_code, self.asset_category, self.gross_purchase_amount)
|
||||
self.set("finance_books", finance_books)
|
||||
|
||||
def validate_finance_books(self):
|
||||
@@ -335,7 +331,9 @@ class Asset(AccountsController):
|
||||
and not frappe.db.get_value("Purchase Invoice", self.purchase_invoice, "update_stock")
|
||||
):
|
||||
frappe.throw(
|
||||
_("Update stock must be enabled for the purchase invoice {0}").format(self.purchase_invoice)
|
||||
_("Update stock must be enabled for the purchase invoice {0}").format(
|
||||
self.purchase_invoice
|
||||
)
|
||||
)
|
||||
|
||||
if not self.calculate_depreciation:
|
||||
@@ -349,9 +347,7 @@ class Asset(AccountsController):
|
||||
if self.is_existing_asset:
|
||||
return
|
||||
|
||||
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(
|
||||
self.purchase_date
|
||||
):
|
||||
if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date):
|
||||
frappe.throw(_("Available-for-use Date should be after purchase date"))
|
||||
|
||||
def validate_gross_and_purchase_amount(self):
|
||||
@@ -374,7 +370,7 @@ class Asset(AccountsController):
|
||||
posting_date, posting_time = frappe.db.get_value(
|
||||
reference_doctype, reference_docname, ["posting_date", "posting_time"]
|
||||
)
|
||||
transaction_date = get_datetime("{} {}".format(posting_date, posting_time))
|
||||
transaction_date = get_datetime(f"{posting_date} {posting_time}")
|
||||
assets = [
|
||||
{
|
||||
"asset": self.name,
|
||||
@@ -414,7 +410,8 @@ class Asset(AccountsController):
|
||||
if not row.depreciation_start_date:
|
||||
if not self.available_for_use_date:
|
||||
frappe.throw(
|
||||
_("Row {0}: Depreciation Start Date is required").format(row.idx), title=_("Invalid Schedule")
|
||||
_("Row {0}: Depreciation Start Date is required").format(row.idx),
|
||||
title=_("Invalid Schedule"),
|
||||
)
|
||||
row.depreciation_start_date = get_last_day(self.available_for_use_date)
|
||||
|
||||
@@ -444,9 +441,7 @@ class Asset(AccountsController):
|
||||
title=_("Invalid Schedule"),
|
||||
)
|
||||
|
||||
if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(
|
||||
self.purchase_date
|
||||
):
|
||||
if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.purchase_date):
|
||||
frappe.throw(
|
||||
_("Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date").format(
|
||||
row.idx
|
||||
@@ -568,11 +563,14 @@ class Asset(AccountsController):
|
||||
|
||||
if self.calculate_depreciation:
|
||||
idx = self.get_default_finance_book_idx() or 0
|
||||
expected_value_after_useful_life = self.finance_books[idx].expected_value_after_useful_life
|
||||
expected_value_after_useful_life = self.finance_books[
|
||||
idx
|
||||
].expected_value_after_useful_life
|
||||
value_after_depreciation = self.finance_books[idx].value_after_depreciation
|
||||
|
||||
if (
|
||||
flt(value_after_depreciation) <= expected_value_after_useful_life or self.is_fully_depreciated
|
||||
flt(value_after_depreciation) <= expected_value_after_useful_life
|
||||
or self.is_fully_depreciated
|
||||
):
|
||||
status = "Fully Depreciated"
|
||||
elif flt(value_after_depreciation) < flt(self.gross_purchase_amount):
|
||||
@@ -605,9 +603,7 @@ class Asset(AccountsController):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_manual_depreciation_entries(self):
|
||||
(_, _, depreciation_expense_account) = get_depreciation_accounts(
|
||||
self.asset_category, self.company
|
||||
)
|
||||
(_, _, depreciation_expense_account) = get_depreciation_accounts(self.asset_category, self.company)
|
||||
|
||||
gle = frappe.qb.DocType("GL Entry")
|
||||
|
||||
@@ -700,10 +696,7 @@ class Asset(AccountsController):
|
||||
purchase_document = self.get_purchase_document()
|
||||
fixed_asset_account, cwip_account = self.get_fixed_asset_account(), self.get_cwip_account()
|
||||
|
||||
if (
|
||||
purchase_document and self.purchase_receipt_amount and self.available_for_use_date <= nowdate()
|
||||
):
|
||||
|
||||
if purchase_document and self.purchase_receipt_amount and self.available_for_use_date <= nowdate():
|
||||
gl_entries.append(
|
||||
self.get_gl_dict(
|
||||
{
|
||||
@@ -750,7 +743,8 @@ class Asset(AccountsController):
|
||||
if args.get("depreciation_method") == "Double Declining Balance":
|
||||
return 200.0 / (
|
||||
(
|
||||
flt(args.get("total_number_of_depreciations"), 2) * flt(args.get("frequency_of_depreciation"))
|
||||
flt(args.get("total_number_of_depreciations"), 2)
|
||||
* flt(args.get("frequency_of_depreciation"))
|
||||
)
|
||||
/ 12
|
||||
)
|
||||
@@ -794,9 +788,7 @@ def update_maintenance_status():
|
||||
asset = frappe.get_doc("Asset", asset.name)
|
||||
if frappe.db.exists("Asset Repair", {"asset_name": asset.name, "repair_status": "Pending"}):
|
||||
asset.set_status("Out of Order")
|
||||
elif frappe.db.exists(
|
||||
"Asset Maintenance Task", {"parent": asset.name, "next_due_date": today()}
|
||||
):
|
||||
elif frappe.db.exists("Asset Maintenance Task", {"parent": asset.name, "next_due_date": today()}):
|
||||
asset.set_status("In Maintenance")
|
||||
else:
|
||||
asset.set_status()
|
||||
@@ -880,9 +872,7 @@ def create_asset_capitalization(asset):
|
||||
@frappe.whitelist()
|
||||
def create_asset_value_adjustment(asset, asset_category, company):
|
||||
asset_value_adjustment = frappe.new_doc("Asset Value Adjustment")
|
||||
asset_value_adjustment.update(
|
||||
{"asset": asset, "company": company, "asset_category": asset_category}
|
||||
)
|
||||
asset_value_adjustment.update({"asset": asset, "company": company, "asset_category": asset_category})
|
||||
return asset_value_adjustment
|
||||
|
||||
|
||||
@@ -939,18 +929,14 @@ def get_asset_account(account_name, asset=None, asset_category=None, company=Non
|
||||
)
|
||||
|
||||
if not asset and not account:
|
||||
account = get_asset_category_account(
|
||||
account_name, asset_category=asset_category, company=company
|
||||
)
|
||||
account = get_asset_category_account(account_name, asset_category=asset_category, company=company)
|
||||
|
||||
if not account:
|
||||
account = frappe.get_cached_value("Company", company, account_name)
|
||||
|
||||
if not account:
|
||||
if not asset_category:
|
||||
frappe.throw(
|
||||
_("Set {0} in company {1}").format(account_name.replace("_", " ").title(), company)
|
||||
)
|
||||
frappe.throw(_("Set {0} in company {1}").format(account_name.replace("_", " ").title(), company))
|
||||
else:
|
||||
frappe.throw(
|
||||
_("Set {0} in asset category {1} or company {2}").format(
|
||||
@@ -979,7 +965,7 @@ def make_journal_entry(asset_name):
|
||||
je.voucher_type = "Depreciation Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.company = asset.company
|
||||
je.remark = ("Depreciation Entry against asset {0}").format(asset_name)
|
||||
je.remark = f"Depreciation Entry against asset {asset_name}"
|
||||
|
||||
je.append(
|
||||
"accounts",
|
||||
@@ -1080,15 +1066,11 @@ def update_existing_asset(asset, remaining_qty, new_asset_name):
|
||||
|
||||
add_asset_activity(
|
||||
asset.name,
|
||||
_("Asset updated after being split into Asset {0}").format(
|
||||
get_link_to_form("Asset", new_asset_name)
|
||||
),
|
||||
_("Asset updated after being split into Asset {0}").format(get_link_to_form("Asset", new_asset_name)),
|
||||
)
|
||||
|
||||
for row in asset.get("finance_books"):
|
||||
value_after_depreciation = flt(
|
||||
(row.value_after_depreciation * remaining_qty) / asset.asset_quantity
|
||||
)
|
||||
value_after_depreciation = flt((row.value_after_depreciation * remaining_qty) / asset.asset_quantity)
|
||||
expected_value_after_useful_life = flt(
|
||||
(row.expected_value_after_useful_life * remaining_qty) / asset.asset_quantity
|
||||
)
|
||||
@@ -1102,9 +1084,7 @@ def update_existing_asset(asset, remaining_qty, new_asset_name):
|
||||
expected_value_after_useful_life,
|
||||
)
|
||||
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(
|
||||
asset.name, "Active", row.finance_book
|
||||
)
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, "Active", row.finance_book)
|
||||
new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
|
||||
|
||||
new_asset_depr_schedule_doc.set_draft_asset_depr_schedule_details(asset, row)
|
||||
@@ -1119,9 +1099,7 @@ def update_existing_asset(asset, remaining_qty, new_asset_name):
|
||||
|
||||
notes = _(
|
||||
"This schedule was created when Asset {0} was updated after being split into new Asset {1}."
|
||||
).format(
|
||||
get_link_to_form(asset.doctype, asset.name), get_link_to_form(asset.doctype, new_asset_name)
|
||||
)
|
||||
).format(get_link_to_form(asset.doctype, asset.name), get_link_to_form(asset.doctype, new_asset_name))
|
||||
new_asset_depr_schedule_doc.notes = notes
|
||||
|
||||
current_asset_depr_schedule_doc.flags.should_not_cancel_depreciation_entries = True
|
||||
@@ -1145,9 +1123,7 @@ def create_new_asset_after_split(asset, split_qty):
|
||||
new_asset.split_from = asset.name
|
||||
|
||||
for row in new_asset.get("finance_books"):
|
||||
row.value_after_depreciation = flt(
|
||||
(row.value_after_depreciation * split_qty) / asset.asset_quantity
|
||||
)
|
||||
row.value_after_depreciation = flt((row.value_after_depreciation * split_qty) / asset.asset_quantity)
|
||||
row.expected_value_after_useful_life = flt(
|
||||
(row.expected_value_after_useful_life * split_qty) / asset.asset_quantity
|
||||
)
|
||||
@@ -1156,18 +1132,14 @@ def create_new_asset_after_split(asset, split_qty):
|
||||
|
||||
add_asset_activity(
|
||||
new_asset.name,
|
||||
_("Asset created after being split from Asset {0}").format(
|
||||
get_link_to_form("Asset", asset.name)
|
||||
),
|
||||
_("Asset created after being split from Asset {0}").format(get_link_to_form("Asset", asset.name)),
|
||||
)
|
||||
|
||||
new_asset.submit()
|
||||
new_asset.set_status()
|
||||
|
||||
for row in new_asset.get("finance_books"):
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(
|
||||
asset.name, "Active", row.finance_book
|
||||
)
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, "Active", row.finance_book)
|
||||
new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
|
||||
|
||||
new_asset_depr_schedule_doc.set_draft_asset_depr_schedule_details(new_asset, row)
|
||||
|
||||
@@ -71,7 +71,10 @@ def post_depreciation_entries(date=None):
|
||||
) not in credit_and_debit_accounts_for_asset_category_and_company:
|
||||
credit_and_debit_accounts_for_asset_category_and_company.update(
|
||||
{
|
||||
(asset_category, asset_company): get_credit_and_debit_accounts_for_asset_category_and_company(
|
||||
(
|
||||
asset_category,
|
||||
asset_company,
|
||||
): get_credit_and_debit_accounts_for_asset_category_and_company(
|
||||
asset_category, asset_company
|
||||
),
|
||||
}
|
||||
@@ -135,9 +138,7 @@ def get_depreciable_asset_depr_schedules_data(date):
|
||||
|
||||
def make_depreciation_entry_for_all_asset_depr_schedules(asset_doc, date=None):
|
||||
for row in asset_doc.get("finance_books"):
|
||||
asset_depr_schedule_name = get_asset_depr_schedule_name(
|
||||
asset_doc.name, "Active", row.finance_book
|
||||
)
|
||||
asset_depr_schedule_name = get_asset_depr_schedule_name(asset_doc.name, "Active", row.finance_book)
|
||||
make_depreciation_entry(asset_depr_schedule_name, date)
|
||||
|
||||
|
||||
@@ -147,9 +148,7 @@ def get_acc_frozen_upto():
|
||||
if not acc_frozen_upto:
|
||||
return
|
||||
|
||||
frozen_accounts_modifier = frappe.db.get_single_value(
|
||||
"Accounts Settings", "frozen_accounts_modifier"
|
||||
)
|
||||
frozen_accounts_modifier = frappe.db.get_single_value("Accounts Settings", "frozen_accounts_modifier")
|
||||
|
||||
if frozen_accounts_modifier not in frappe.get_roles() or frappe.session.user == "Administrator":
|
||||
return getdate(acc_frozen_upto)
|
||||
@@ -278,9 +277,7 @@ def _make_journal_entry_for_depreciation(
|
||||
je.posting_date = depr_schedule.schedule_date
|
||||
je.company = asset.company
|
||||
je.finance_book = asset_depr_schedule_doc.finance_book
|
||||
je.remark = "Depreciation Entry against {0} worth {1}".format(
|
||||
asset.name, depr_schedule.depreciation_amount
|
||||
)
|
||||
je.remark = f"Depreciation Entry against {asset.name} worth {depr_schedule.depreciation_amount}"
|
||||
|
||||
credit_entry = {
|
||||
"account": credit_account,
|
||||
@@ -361,11 +358,7 @@ def get_depreciation_accounts(asset_category, company):
|
||||
if not depreciation_expense_account:
|
||||
depreciation_expense_account = accounts[1]
|
||||
|
||||
if (
|
||||
not fixed_asset_account
|
||||
or not accumulated_depreciation_account
|
||||
or not depreciation_expense_account
|
||||
):
|
||||
if not fixed_asset_account or not accumulated_depreciation_account or not depreciation_expense_account:
|
||||
frappe.throw(
|
||||
_("Please set Depreciation related Accounts in Asset Category {0} or Company {1}").format(
|
||||
asset_category, company
|
||||
@@ -443,9 +436,7 @@ def scrap_asset(asset_name):
|
||||
if asset.docstatus != 1:
|
||||
frappe.throw(_("Asset {0} must be submitted").format(asset.name))
|
||||
elif asset.status in ("Cancelled", "Sold", "Scrapped", "Capitalized", "Decapitalized"):
|
||||
frappe.throw(
|
||||
_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status)
|
||||
)
|
||||
frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status))
|
||||
|
||||
date = today()
|
||||
|
||||
@@ -456,16 +447,14 @@ def scrap_asset(asset_name):
|
||||
depreciate_asset(asset, date, notes)
|
||||
asset.reload()
|
||||
|
||||
depreciation_series = frappe.get_cached_value(
|
||||
"Company", asset.company, "series_for_depreciation_entry"
|
||||
)
|
||||
depreciation_series = frappe.get_cached_value("Company", asset.company, "series_for_depreciation_entry")
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Journal Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.posting_date = date
|
||||
je.company = asset.company
|
||||
je.remark = "Scrap Entry for asset {0}".format(asset_name)
|
||||
je.remark = f"Scrap Entry for asset {asset_name}"
|
||||
|
||||
for entry in get_gl_entries_on_asset_disposal(asset, date):
|
||||
entry.update({"reference_type": "Asset", "reference_name": asset_name})
|
||||
@@ -513,9 +502,7 @@ def depreciate_asset(asset_doc, date, notes):
|
||||
|
||||
asset_doc.flags.ignore_validate_update_after_submit = True
|
||||
|
||||
make_new_active_asset_depr_schedules_and_cancel_current_ones(
|
||||
asset_doc, notes, date_of_disposal=date
|
||||
)
|
||||
make_new_active_asset_depr_schedules_and_cancel_current_ones(asset_doc, notes, date_of_disposal=date)
|
||||
|
||||
asset_doc.save()
|
||||
|
||||
@@ -536,9 +523,7 @@ def reset_depreciation_schedule(asset_doc, date, notes):
|
||||
|
||||
asset_doc.flags.ignore_validate_update_after_submit = True
|
||||
|
||||
make_new_active_asset_depr_schedules_and_cancel_current_ones(
|
||||
asset_doc, notes, date_of_return=date
|
||||
)
|
||||
make_new_active_asset_depr_schedules_and_cancel_current_ones(asset_doc, notes, date_of_return=date)
|
||||
|
||||
modify_depreciation_schedule_for_asset_repairs(asset_doc, notes)
|
||||
|
||||
@@ -781,9 +766,7 @@ def get_disposal_account_and_cost_center(company):
|
||||
)
|
||||
|
||||
if not disposal_account:
|
||||
frappe.throw(
|
||||
_("Please set 'Gain/Loss Account on Asset Disposal' in Company {0}").format(company)
|
||||
)
|
||||
frappe.throw(_("Please set 'Gain/Loss Account on Asset Disposal' in Company {0}").format(company))
|
||||
if not depreciation_cost_center:
|
||||
frappe.throw(_("Please set 'Asset Depreciation Cost Center' in Company {0}").format(company))
|
||||
|
||||
@@ -796,7 +779,7 @@ def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_
|
||||
|
||||
if asset_doc.available_for_use_date > getdate(disposal_date):
|
||||
frappe.throw(
|
||||
"Disposal date {0} cannot be before available for use date {1} of the asset.".format(
|
||||
"Disposal date {} cannot be before available for use date {} of the asset.".format(
|
||||
disposal_date, asset_doc.available_for_use_date
|
||||
)
|
||||
)
|
||||
|
||||
@@ -109,9 +109,7 @@ class TestAsset(AssetSetup):
|
||||
self.assertRaises(frappe.ValidationError, asset.save)
|
||||
|
||||
def test_purchase_asset(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset = frappe.get_doc("Asset", asset_name)
|
||||
@@ -210,7 +208,7 @@ class TestAsset(AssetSetup):
|
||||
)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
post_depreciation_entries(date=add_months(purchase_date, 2))
|
||||
asset.load_from_db()
|
||||
@@ -219,25 +217,29 @@ class TestAsset(AssetSetup):
|
||||
asset.gross_purchase_amount - asset.finance_books[0].value_after_depreciation,
|
||||
asset.precision("gross_purchase_amount"),
|
||||
)
|
||||
self.assertEquals(accumulated_depr_amount, 18000.0)
|
||||
self.assertEqual(accumulated_depr_amount, 18000.0)
|
||||
|
||||
scrap_asset(asset.name)
|
||||
asset.load_from_db()
|
||||
first_asset_depr_schedule.load_from_db()
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
accumulated_depr_amount = flt(
|
||||
asset.gross_purchase_amount - asset.finance_books[0].value_after_depreciation,
|
||||
asset.precision("gross_purchase_amount"),
|
||||
)
|
||||
pro_rata_amount, _, _ = _get_pro_rata_amt(
|
||||
asset.finance_books[0], 9000, get_last_day(add_months(purchase_date, 1)), date
|
||||
asset.finance_books[0],
|
||||
9000,
|
||||
get_last_day(add_months(purchase_date, 1)),
|
||||
date,
|
||||
original_schedule_date=get_last_day(nowdate()),
|
||||
)
|
||||
pro_rata_amount = flt(pro_rata_amount, asset.precision("gross_purchase_amount"))
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
accumulated_depr_amount,
|
||||
flt(18000.0 + pro_rata_amount, asset.precision("gross_purchase_amount")),
|
||||
)
|
||||
@@ -266,8 +268,8 @@ class TestAsset(AssetSetup):
|
||||
second_asset_depr_schedule.load_from_db()
|
||||
|
||||
third_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(third_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(third_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
asset.load_from_db()
|
||||
self.assertFalse(asset.journal_entry_for_scrap)
|
||||
@@ -279,7 +281,7 @@ class TestAsset(AssetSetup):
|
||||
)
|
||||
this_month_depr_amount = 9000.0 if is_last_day_of_the_month(date) else 0
|
||||
|
||||
self.assertEquals(accumulated_depr_amount, 18000.0 + this_month_depr_amount)
|
||||
self.assertEqual(accumulated_depr_amount, 18000.0 + this_month_depr_amount)
|
||||
|
||||
def test_gle_made_by_asset_sale(self):
|
||||
date = nowdate()
|
||||
@@ -296,7 +298,7 @@ class TestAsset(AssetSetup):
|
||||
)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
post_depreciation_entries(date=add_months(purchase_date, 2))
|
||||
|
||||
@@ -312,11 +314,15 @@ class TestAsset(AssetSetup):
|
||||
first_asset_depr_schedule.load_from_db()
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
pro_rata_amount, _, _ = _get_pro_rata_amt(
|
||||
asset.finance_books[0], 9000, get_last_day(add_months(purchase_date, 1)), date
|
||||
asset.finance_books[0],
|
||||
9000,
|
||||
get_last_day(add_months(purchase_date, 1)),
|
||||
date,
|
||||
original_schedule_date=get_last_day(nowdate()),
|
||||
)
|
||||
pro_rata_amount = flt(pro_rata_amount, asset.precision("gross_purchase_amount"))
|
||||
|
||||
@@ -334,7 +340,6 @@ class TestAsset(AssetSetup):
|
||||
),
|
||||
("Debtors - _TC", 25000.0, 0.0),
|
||||
)
|
||||
|
||||
gle = get_gl_entries("Sales Invoice", si.name)
|
||||
self.assertSequenceEqual(gle, expected_gle)
|
||||
|
||||
@@ -380,7 +385,7 @@ class TestAsset(AssetSetup):
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")
|
||||
|
||||
expected_values = [["2023-03-31", 12000, 36000], ["2023-05-23", 1742.47, 37742.47]]
|
||||
expected_values = [["2023-03-31", 12000, 36000], ["2023-05-23", 1737.7, 37737.7]]
|
||||
|
||||
second_asset_depr_schedule = get_depr_schedule(asset.name, "Active")
|
||||
|
||||
@@ -393,7 +398,7 @@ class TestAsset(AssetSetup):
|
||||
expected_gle = (
|
||||
(
|
||||
"_Test Accumulated Depreciations - _TC",
|
||||
37742.47,
|
||||
37737.7,
|
||||
0.0,
|
||||
),
|
||||
(
|
||||
@@ -404,7 +409,7 @@ class TestAsset(AssetSetup):
|
||||
(
|
||||
"_Test Gain/Loss on Asset Disposal - _TC",
|
||||
0.0,
|
||||
17742.47,
|
||||
17737.7,
|
||||
),
|
||||
("Debtors - _TC", 40000.0, 0.0),
|
||||
)
|
||||
@@ -457,7 +462,7 @@ class TestAsset(AssetSetup):
|
||||
)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
post_depreciation_entries(date="2021-01-01")
|
||||
|
||||
@@ -471,9 +476,9 @@ class TestAsset(AssetSetup):
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
first_asset_depr_schedule_of_new_asset = get_asset_depr_schedule_doc(new_asset.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule_of_new_asset.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule_of_new_asset.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
depr_schedule_of_asset = second_asset_depr_schedule.get("depreciation_schedule")
|
||||
depr_schedule_of_new_asset = first_asset_depr_schedule_of_new_asset.get("depreciation_schedule")
|
||||
@@ -505,9 +510,7 @@ class TestAsset(AssetSetup):
|
||||
self.assertEqual(jv.accounts[3].reference_name, new_asset.name)
|
||||
|
||||
def test_expense_head(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=2, rate=200000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=2, rate=200000.0, location="Test Location")
|
||||
doc = make_invoice(pr.name)
|
||||
|
||||
self.assertEqual("Asset Received But Not Billed - _TC", doc.items[0].expense_account)
|
||||
@@ -617,9 +620,7 @@ class TestAsset(AssetSetup):
|
||||
self.assertFalse(gle)
|
||||
|
||||
# case 1 -- PR with cwip disabled, Asset with cwip enabled
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=200000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=200000.0, location="Test Location")
|
||||
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", 1)
|
||||
frappe.db.set_value("Asset Category Account", name, "capital_work_in_progress_account", cwip_acc)
|
||||
asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name")
|
||||
@@ -631,9 +632,7 @@ class TestAsset(AssetSetup):
|
||||
self.assertFalse(gle)
|
||||
|
||||
# case 2 -- PR with cwip enabled, Asset with cwip disabled
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=200000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=200000.0, location="Test Location")
|
||||
frappe.db.set_value("Asset Category", "Computers", "enable_cwip_accounting", 0)
|
||||
asset = frappe.db.get_value("Asset", {"purchase_receipt": pr.name, "docstatus": 0}, "name")
|
||||
asset_doc = frappe.get_doc("Asset", asset)
|
||||
@@ -715,25 +714,24 @@ class TestDepreciationMethods(AssetSetup):
|
||||
)
|
||||
|
||||
expected_schedules = [
|
||||
["2023-01-31", 1021.98, 1021.98],
|
||||
["2023-02-28", 923.08, 1945.06],
|
||||
["2023-03-31", 1021.98, 2967.04],
|
||||
["2023-04-30", 989.01, 3956.05],
|
||||
["2023-05-31", 1021.98, 4978.03],
|
||||
["2023-06-30", 989.01, 5967.04],
|
||||
["2023-07-31", 1021.98, 6989.02],
|
||||
["2023-08-31", 1021.98, 8011.0],
|
||||
["2023-09-30", 989.01, 9000.01],
|
||||
["2023-10-31", 1021.98, 10021.99],
|
||||
["2023-11-30", 989.01, 11011.0],
|
||||
["2023-12-31", 989.0, 12000.0],
|
||||
["2023-01-31", 1019.18, 1019.18],
|
||||
["2023-02-28", 920.55, 1939.73],
|
||||
["2023-03-31", 1019.18, 2958.91],
|
||||
["2023-04-30", 986.3, 3945.21],
|
||||
["2023-05-31", 1019.18, 4964.39],
|
||||
["2023-06-30", 986.3, 5950.69],
|
||||
["2023-07-31", 1019.18, 6969.87],
|
||||
["2023-08-31", 1019.18, 7989.05],
|
||||
["2023-09-30", 986.3, 8975.35],
|
||||
["2023-10-31", 1019.18, 9994.53],
|
||||
["2023-11-30", 986.3, 10980.83],
|
||||
["2023-12-31", 1019.17, 12000.0],
|
||||
]
|
||||
|
||||
schedules = [
|
||||
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||
for d in get_depr_schedule(asset.name, "Draft")
|
||||
]
|
||||
|
||||
self.assertEqual(schedules, expected_schedules)
|
||||
|
||||
def test_schedule_for_straight_line_method_for_existing_asset(self):
|
||||
@@ -1248,8 +1246,7 @@ class TestDepreciationBasics(AssetSetup):
|
||||
|
||||
je = frappe.get_doc("Journal Entry", get_depr_schedule(asset.name, "Active")[0].journal_entry)
|
||||
accounting_entries = [
|
||||
{"account": entry.account, "debit": entry.debit, "credit": entry.credit}
|
||||
for entry in je.accounts
|
||||
{"account": entry.account, "debit": entry.debit, "credit": entry.credit} for entry in je.accounts
|
||||
]
|
||||
|
||||
for entry in accounting_entries:
|
||||
@@ -1284,8 +1281,7 @@ class TestDepreciationBasics(AssetSetup):
|
||||
|
||||
je = frappe.get_doc("Journal Entry", get_depr_schedule(asset.name, "Active")[0].journal_entry)
|
||||
accounting_entries = [
|
||||
{"account": entry.account, "debit": entry.debit, "credit": entry.credit}
|
||||
for entry in je.accounts
|
||||
{"account": entry.account, "debit": entry.debit, "credit": entry.credit} for entry in je.accounts
|
||||
]
|
||||
|
||||
for entry in accounting_entries:
|
||||
@@ -1366,21 +1362,15 @@ class TestDepreciationBasics(AssetSetup):
|
||||
post_depreciation_entries(date="2020-04-01")
|
||||
asset.load_from_db()
|
||||
|
||||
asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(
|
||||
asset.name, "Active", "Test Finance Book 1"
|
||||
)
|
||||
asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(asset.name, "Active", "Test Finance Book 1")
|
||||
asset_depr_schedule_doc_1.clear_depr_schedule()
|
||||
self.assertEqual(len(asset_depr_schedule_doc_1.get("depreciation_schedule")), 3)
|
||||
|
||||
asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(
|
||||
asset.name, "Active", "Test Finance Book 2"
|
||||
)
|
||||
asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(asset.name, "Active", "Test Finance Book 2")
|
||||
asset_depr_schedule_doc_2.clear_depr_schedule()
|
||||
self.assertEqual(len(asset_depr_schedule_doc_2.get("depreciation_schedule")), 3)
|
||||
|
||||
asset_depr_schedule_doc_3 = get_asset_depr_schedule_doc(
|
||||
asset.name, "Active", "Test Finance Book 3"
|
||||
)
|
||||
asset_depr_schedule_doc_3 = get_asset_depr_schedule_doc(asset.name, "Active", "Test Finance Book 3")
|
||||
asset_depr_schedule_doc_3.clear_depr_schedule()
|
||||
self.assertEqual(len(asset_depr_schedule_doc_3.get("depreciation_schedule")), 0)
|
||||
|
||||
@@ -1412,14 +1402,10 @@ class TestDepreciationBasics(AssetSetup):
|
||||
)
|
||||
asset.save()
|
||||
|
||||
asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(
|
||||
asset.name, "Draft", "Test Finance Book 1"
|
||||
)
|
||||
asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(asset.name, "Draft", "Test Finance Book 1")
|
||||
self.assertEqual(len(asset_depr_schedule_doc_1.get("depreciation_schedule")), 3)
|
||||
|
||||
asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(
|
||||
asset.name, "Draft", "Test Finance Book 2"
|
||||
)
|
||||
asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(asset.name, "Draft", "Test Finance Book 2")
|
||||
self.assertEqual(len(asset_depr_schedule_doc_2.get("depreciation_schedule")), 6)
|
||||
|
||||
def test_depreciation_entry_cancellation(self):
|
||||
@@ -1521,13 +1507,13 @@ class TestDepreciationBasics(AssetSetup):
|
||||
asset.finance_books[0].expected_value_after_useful_life = 100
|
||||
asset.save()
|
||||
asset.reload()
|
||||
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||
self.assertEqual(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||
|
||||
# changing expected_value_after_useful_life shouldn't affect value_after_depreciation
|
||||
asset.finance_books[0].expected_value_after_useful_life = 200
|
||||
asset.save()
|
||||
asset.reload()
|
||||
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||
self.assertEqual(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||
|
||||
def test_asset_cost_center(self):
|
||||
asset = create_asset(is_existing_asset=1, do_not_save=1)
|
||||
|
||||
@@ -70,9 +70,7 @@ class AssetCapitalization(StockController):
|
||||
amended_from: DF.Link | None
|
||||
asset_items: DF.Table[AssetCapitalizationAssetItem]
|
||||
asset_items_total: DF.Currency
|
||||
capitalization_method: DF.Literal[
|
||||
"", "Create a new composite asset", "Choose a WIP composite asset"
|
||||
]
|
||||
capitalization_method: DF.Literal["", "Create a new composite asset", "Choose a WIP composite asset"]
|
||||
company: DF.Link
|
||||
cost_center: DF.Link | None
|
||||
entry_type: DF.Literal["Capitalization", "Decapitalization"]
|
||||
@@ -236,7 +234,9 @@ class AssetCapitalization(StockController):
|
||||
|
||||
if target_asset.item_code != self.target_item_code:
|
||||
frappe.throw(
|
||||
_("Asset {0} does not belong to Item {1}").format(self.target_asset, self.target_item_code)
|
||||
_("Asset {0} does not belong to Item {1}").format(
|
||||
self.target_asset, self.target_item_code
|
||||
)
|
||||
)
|
||||
|
||||
if target_asset.status in ("Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
||||
@@ -251,7 +251,9 @@ class AssetCapitalization(StockController):
|
||||
|
||||
if target_asset.company != self.company:
|
||||
frappe.throw(
|
||||
_("Target Asset {0} does not belong to company {1}").format(target_asset.name, self.company)
|
||||
_("Target Asset {0} does not belong to company {1}").format(
|
||||
target_asset.name, self.company
|
||||
)
|
||||
)
|
||||
|
||||
def validate_consumed_stock_item(self):
|
||||
@@ -281,13 +283,17 @@ class AssetCapitalization(StockController):
|
||||
|
||||
if asset.status in ("Draft", "Scrapped", "Sold", "Capitalized", "Decapitalized"):
|
||||
frappe.throw(
|
||||
_("Row #{0}: Consumed Asset {1} cannot be {2}").format(d.idx, asset.name, asset.status)
|
||||
_("Row #{0}: Consumed Asset {1} cannot be {2}").format(
|
||||
d.idx, asset.name, asset.status
|
||||
)
|
||||
)
|
||||
|
||||
if asset.docstatus == 0:
|
||||
frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be Draft").format(d.idx, asset.name))
|
||||
elif asset.docstatus == 2:
|
||||
frappe.throw(_("Row #{0}: Consumed Asset {1} cannot be cancelled").format(d.idx, asset.name))
|
||||
frappe.throw(
|
||||
_("Row #{0}: Consumed Asset {1} cannot be cancelled").format(d.idx, asset.name)
|
||||
)
|
||||
|
||||
if asset.company != self.company:
|
||||
frappe.throw(
|
||||
@@ -440,9 +446,7 @@ class AssetCapitalization(StockController):
|
||||
elif self.docstatus == 2:
|
||||
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
def get_gl_entries(
|
||||
self, warehouse_account=None, default_expense_account=None, default_cost_center=None
|
||||
):
|
||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None, default_cost_center=None):
|
||||
# Stock GL Entries
|
||||
gl_entries = []
|
||||
|
||||
@@ -456,15 +460,9 @@ class AssetCapitalization(StockController):
|
||||
target_account = self.get_target_account()
|
||||
target_against = set()
|
||||
|
||||
self.get_gl_entries_for_consumed_stock_items(
|
||||
gl_entries, target_account, target_against, precision
|
||||
)
|
||||
self.get_gl_entries_for_consumed_asset_items(
|
||||
gl_entries, target_account, target_against, precision
|
||||
)
|
||||
self.get_gl_entries_for_consumed_service_items(
|
||||
gl_entries, target_account, target_against, precision
|
||||
)
|
||||
self.get_gl_entries_for_consumed_stock_items(gl_entries, target_account, target_against, precision)
|
||||
self.get_gl_entries_for_consumed_asset_items(gl_entries, target_account, target_against, precision)
|
||||
self.get_gl_entries_for_consumed_service_items(gl_entries, target_account, target_against, precision)
|
||||
|
||||
self.get_gl_entries_for_target_item(gl_entries, target_against, precision)
|
||||
|
||||
@@ -476,9 +474,7 @@ class AssetCapitalization(StockController):
|
||||
else:
|
||||
return self.warehouse_account[self.target_warehouse]["account"]
|
||||
|
||||
def get_gl_entries_for_consumed_stock_items(
|
||||
self, gl_entries, target_account, target_against, precision
|
||||
):
|
||||
def get_gl_entries_for_consumed_stock_items(self, gl_entries, target_account, target_against, precision):
|
||||
# Consumed Stock Items
|
||||
for item_row in self.stock_items:
|
||||
sle_list = self.sle_map.get(item_row.name)
|
||||
@@ -507,9 +503,7 @@ class AssetCapitalization(StockController):
|
||||
)
|
||||
)
|
||||
|
||||
def get_gl_entries_for_consumed_asset_items(
|
||||
self, gl_entries, target_account, target_against, precision
|
||||
):
|
||||
def get_gl_entries_for_consumed_asset_items(self, gl_entries, target_account, target_against, precision):
|
||||
# Consumed Assets
|
||||
for item in self.asset_items:
|
||||
asset = frappe.get_doc("Asset", item.asset)
|
||||
@@ -518,7 +512,8 @@ class AssetCapitalization(StockController):
|
||||
notes = _(
|
||||
"This schedule was created when Asset {0} was consumed through Asset Capitalization {1}."
|
||||
).format(
|
||||
get_link_to_form(asset.doctype, asset.name), get_link_to_form(self.doctype, self.get("name"))
|
||||
get_link_to_form(asset.doctype, asset.name),
|
||||
get_link_to_form(self.doctype, self.get("name")),
|
||||
)
|
||||
depreciate_asset(asset, self.posting_date, notes)
|
||||
asset.reload()
|
||||
@@ -638,9 +633,9 @@ class AssetCapitalization(StockController):
|
||||
)
|
||||
|
||||
frappe.msgprint(
|
||||
_(
|
||||
"Asset {0} has been created. Please set the depreciation details if any and submit it."
|
||||
).format(get_link_to_form("Asset", asset_doc.name))
|
||||
_("Asset {0} has been created. Please set the depreciation details if any and submit it.").format(
|
||||
get_link_to_form("Asset", asset_doc.name)
|
||||
)
|
||||
)
|
||||
|
||||
def update_target_asset(self):
|
||||
@@ -660,9 +655,9 @@ class AssetCapitalization(StockController):
|
||||
asset_doc.save()
|
||||
|
||||
frappe.msgprint(
|
||||
_(
|
||||
"Asset {0} has been updated. Please set the depreciation details if any and submit it."
|
||||
).format(get_link_to_form("Asset", asset_doc.name))
|
||||
_("Asset {0} has been updated. Please set the depreciation details if any and submit it.").format(
|
||||
get_link_to_form("Asset", asset_doc.name)
|
||||
)
|
||||
)
|
||||
|
||||
def restore_consumed_asset_items(self):
|
||||
@@ -801,9 +796,7 @@ def get_consumed_stock_item_details(args):
|
||||
item_defaults = get_item_defaults(item.name, args.company)
|
||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
||||
out.cost_center = get_default_cost_center(
|
||||
args, item_defaults, item_group_defaults, brand_defaults
|
||||
)
|
||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
||||
|
||||
if args.item_code and out.warehouse:
|
||||
incoming_rate_args = frappe._dict(
|
||||
@@ -889,9 +882,7 @@ def get_consumed_asset_details(args):
|
||||
item_defaults = get_item_defaults(item.name, args.company)
|
||||
item_group_defaults = get_item_group_defaults(item.name, args.company)
|
||||
brand_defaults = get_brand_defaults(item.name, args.company)
|
||||
out.cost_center = get_default_cost_center(
|
||||
args, item_defaults, item_group_defaults, brand_defaults
|
||||
)
|
||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
||||
return out
|
||||
|
||||
|
||||
@@ -918,9 +909,7 @@ def get_service_item_details(args):
|
||||
out.expense_account = get_default_expense_account(
|
||||
args, item_defaults, item_group_defaults, brand_defaults
|
||||
)
|
||||
out.cost_center = get_default_cost_center(
|
||||
args, item_defaults, item_group_defaults, brand_defaults
|
||||
)
|
||||
out.cost_center = get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_sched
|
||||
)
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import (
|
||||
get_batch_from_bundle,
|
||||
get_serial_nos_from_bundle,
|
||||
make_serial_batch_bundle,
|
||||
)
|
||||
|
||||
@@ -323,7 +321,7 @@ class TestAssetCapitalization(unittest.TestCase):
|
||||
)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(consumed_asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
# Create and submit Asset Captitalization
|
||||
asset_capitalization = create_asset_capitalization(
|
||||
@@ -357,8 +355,8 @@ class TestAssetCapitalization(unittest.TestCase):
|
||||
first_asset_depr_schedule.load_from_db()
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(consumed_asset.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
depr_schedule_of_consumed_asset = second_asset_depr_schedule.get("depreciation_schedule")
|
||||
|
||||
@@ -367,9 +365,7 @@ class TestAssetCapitalization(unittest.TestCase):
|
||||
for d in depr_schedule_of_consumed_asset
|
||||
if getdate(d.schedule_date) == getdate(capitalization_date)
|
||||
]
|
||||
self.assertTrue(
|
||||
consumed_depreciation_schedule and consumed_depreciation_schedule[0].journal_entry
|
||||
)
|
||||
self.assertTrue(consumed_depreciation_schedule and consumed_depreciation_schedule[0].journal_entry)
|
||||
self.assertEqual(
|
||||
consumed_depreciation_schedule[0].depreciation_amount, depreciation_before_disposal_amount
|
||||
)
|
||||
@@ -392,15 +388,9 @@ class TestAssetCapitalization(unittest.TestCase):
|
||||
|
||||
|
||||
def create_asset_capitalization_data():
|
||||
create_item(
|
||||
"Capitalization Target Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0
|
||||
)
|
||||
create_item(
|
||||
"Capitalization Source Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0
|
||||
)
|
||||
create_item(
|
||||
"Capitalization Source Service Item", is_stock_item=0, is_fixed_asset=0, is_purchase_item=0
|
||||
)
|
||||
create_item("Capitalization Target Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0)
|
||||
create_item("Capitalization Source Stock Item", is_stock_item=1, is_fixed_asset=0, is_purchase_item=0)
|
||||
create_item("Capitalization Source Service Item", is_stock_item=0, is_fixed_asset=0, is_purchase_item=0)
|
||||
|
||||
|
||||
def create_asset_capitalization(**args):
|
||||
|
||||
@@ -57,7 +57,9 @@ class AssetCategory(Document):
|
||||
account_currency = frappe.get_value("Account", d.get(type_of_account), "account_currency")
|
||||
if account_currency != company_currency:
|
||||
invalid_accounts.append(
|
||||
frappe._dict({"type": type_of_account, "idx": d.idx, "account": d.get(type_of_account)})
|
||||
frappe._dict(
|
||||
{"type": type_of_account, "idx": d.idx, "account": d.get(type_of_account)}
|
||||
)
|
||||
)
|
||||
|
||||
for d in invalid_accounts:
|
||||
|
||||
@@ -31,9 +31,7 @@ class TestAssetCategory(unittest.TestCase):
|
||||
pass
|
||||
|
||||
def test_cwip_accounting(self):
|
||||
company_cwip_acc = frappe.db.get_value(
|
||||
"Company", "_Test Company", "capital_work_in_progress_account"
|
||||
)
|
||||
frappe.db.get_value("Company", "_Test Company", "capital_work_in_progress_account")
|
||||
frappe.db.set_value("Company", "_Test Company", "capital_work_in_progress_account", "")
|
||||
|
||||
asset_category = frappe.new_doc("Asset Category")
|
||||
|
||||
@@ -275,9 +275,7 @@ class AssetDepreciationSchedule(Document):
|
||||
row.depreciation_method in ("Written Down Value", "Double Declining Balance")
|
||||
and cint(row.frequency_of_depreciation) != 12
|
||||
):
|
||||
has_wdv_or_dd_non_yearly_pro_rata = _check_is_pro_rata(
|
||||
asset_doc, row, wdv_or_dd_non_yearly=True
|
||||
)
|
||||
has_wdv_or_dd_non_yearly_pro_rata = _check_is_pro_rata(asset_doc, row, wdv_or_dd_non_yearly=True)
|
||||
|
||||
skip_row = False
|
||||
should_get_last_day = is_last_day_of_the_month(row.depreciation_start_date)
|
||||
@@ -315,7 +313,6 @@ class AssetDepreciationSchedule(Document):
|
||||
has_wdv_or_dd_non_yearly_pro_rata,
|
||||
number_of_pending_depreciations,
|
||||
)
|
||||
|
||||
if not has_pro_rata or (
|
||||
n < (cint(final_number_of_depreciations) - 1) or final_number_of_depreciations == 2
|
||||
):
|
||||
@@ -340,6 +337,7 @@ class AssetDepreciationSchedule(Document):
|
||||
depreciation_amount,
|
||||
from_date,
|
||||
date_of_disposal,
|
||||
original_schedule_date=schedule_date,
|
||||
)
|
||||
|
||||
if depreciation_amount > 0:
|
||||
@@ -568,24 +566,26 @@ def _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=Fa
|
||||
|
||||
|
||||
def _get_pro_rata_amt(
|
||||
row, depreciation_amount, from_date, to_date, has_wdv_or_dd_non_yearly_pro_rata=False
|
||||
row,
|
||||
depreciation_amount,
|
||||
from_date,
|
||||
to_date,
|
||||
has_wdv_or_dd_non_yearly_pro_rata=False,
|
||||
original_schedule_date=None,
|
||||
):
|
||||
days = date_diff(to_date, from_date)
|
||||
months = month_diff(to_date, from_date)
|
||||
if has_wdv_or_dd_non_yearly_pro_rata:
|
||||
total_days = get_total_days(to_date, 12)
|
||||
total_days = get_total_days(original_schedule_date or to_date, 12)
|
||||
else:
|
||||
total_days = get_total_days(to_date, row.frequency_of_depreciation)
|
||||
|
||||
total_days = get_total_days(original_schedule_date or to_date, row.frequency_of_depreciation)
|
||||
return (depreciation_amount * flt(days)) / flt(total_days), days, months
|
||||
|
||||
|
||||
def get_total_days(date, frequency):
|
||||
period_start_date = add_months(date, cint(frequency) * -1)
|
||||
|
||||
if is_last_day_of_the_month(date):
|
||||
period_start_date = get_last_day(period_start_date)
|
||||
|
||||
return date_diff(date, period_start_date)
|
||||
|
||||
|
||||
@@ -636,39 +636,45 @@ def get_straight_line_or_manual_depr_amount(
|
||||
# if the Depreciation Schedule is being modified after Asset Value Adjustment due to decrease in asset value
|
||||
elif asset.flags.decrease_in_asset_value_due_to_value_adjustment:
|
||||
if row.daily_prorata_based:
|
||||
daily_depr_amount = (
|
||||
flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
|
||||
) / date_diff(
|
||||
get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
|
||||
* row.frequency_of_depreciation,
|
||||
)
|
||||
),
|
||||
add_days(
|
||||
amount = flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
|
||||
total_days = (
|
||||
date_diff(
|
||||
get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
flt(
|
||||
row.total_number_of_depreciations
|
||||
- asset.number_of_depreciations_booked
|
||||
- number_of_pending_depreciations
|
||||
- 1
|
||||
)
|
||||
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
|
||||
* row.frequency_of_depreciation,
|
||||
)
|
||||
),
|
||||
1,
|
||||
),
|
||||
add_days(
|
||||
get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
flt(
|
||||
row.total_number_of_depreciations
|
||||
- asset.number_of_depreciations_booked
|
||||
- number_of_pending_depreciations
|
||||
- 1
|
||||
)
|
||||
* row.frequency_of_depreciation,
|
||||
)
|
||||
),
|
||||
1,
|
||||
),
|
||||
)
|
||||
+ 1
|
||||
)
|
||||
|
||||
daily_depr_amount = amount / total_days
|
||||
|
||||
to_date = get_last_day(
|
||||
add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
|
||||
)
|
||||
from_date = add_days(
|
||||
get_last_day(
|
||||
add_months(row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation)
|
||||
add_months(
|
||||
row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
|
||||
)
|
||||
),
|
||||
1,
|
||||
)
|
||||
@@ -681,33 +687,44 @@ def get_straight_line_or_manual_depr_amount(
|
||||
# if the Depreciation Schedule is being prepared for the first time
|
||||
else:
|
||||
if row.daily_prorata_based:
|
||||
daily_depr_amount = (
|
||||
amount = (
|
||||
flt(asset.gross_purchase_amount)
|
||||
- flt(asset.opening_accumulated_depreciation)
|
||||
- flt(row.expected_value_after_useful_life)
|
||||
) / date_diff(
|
||||
get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
|
||||
* row.frequency_of_depreciation,
|
||||
)
|
||||
),
|
||||
add_days(
|
||||
get_last_day(add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation)), 1
|
||||
),
|
||||
)
|
||||
|
||||
total_days = (
|
||||
date_diff(
|
||||
get_last_day(
|
||||
add_months(
|
||||
row.depreciation_start_date,
|
||||
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
|
||||
* row.frequency_of_depreciation,
|
||||
)
|
||||
),
|
||||
add_days(
|
||||
get_last_day(
|
||||
add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation)
|
||||
),
|
||||
1,
|
||||
),
|
||||
)
|
||||
+ 1
|
||||
)
|
||||
|
||||
daily_depr_amount = amount / total_days
|
||||
|
||||
to_date = get_last_day(
|
||||
add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
|
||||
)
|
||||
from_date = add_days(
|
||||
get_last_day(
|
||||
add_months(row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation)
|
||||
add_months(
|
||||
row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
|
||||
)
|
||||
),
|
||||
1,
|
||||
)
|
||||
|
||||
return daily_depr_amount * (date_diff(to_date, from_date) + 1)
|
||||
else:
|
||||
return (
|
||||
@@ -930,9 +947,7 @@ def get_temp_asset_depr_schedule_doc(
|
||||
update_asset_finance_book_row=False,
|
||||
new_depr_schedule=None,
|
||||
):
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(
|
||||
asset_doc.name, "Active", row.finance_book
|
||||
)
|
||||
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_doc.name, "Active", row.finance_book)
|
||||
|
||||
if not current_asset_depr_schedule_doc:
|
||||
frappe.throw(
|
||||
|
||||
@@ -18,7 +18,7 @@ class TestAssetDepreciationSchedule(FrappeTestCase):
|
||||
asset = create_asset(item_code="Macbook Pro", calculate_depreciation=1, submit=1)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
second_asset_depr_schedule = frappe.get_doc(
|
||||
{"doctype": "Asset Depreciation Schedule", "asset": asset.name, "finance_book": None}
|
||||
|
||||
@@ -92,9 +92,7 @@ def calculate_next_due_date(
|
||||
if not start_date and not last_completion_date:
|
||||
start_date = frappe.utils.now()
|
||||
|
||||
if last_completion_date and (
|
||||
(start_date and last_completion_date > start_date) or not start_date
|
||||
):
|
||||
if last_completion_date and ((start_date and last_completion_date > start_date) or not start_date):
|
||||
start_date = last_completion_date
|
||||
if periodicity == "Daily":
|
||||
next_due_date = add_days(start_date, 1)
|
||||
|
||||
@@ -17,9 +17,7 @@ class TestAssetMaintenance(unittest.TestCase):
|
||||
create_maintenance_team()
|
||||
|
||||
def test_create_asset_maintenance(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Photocopier", qty=1, rate=100000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Photocopier", qty=1, rate=100000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset_doc = frappe.get_doc("Asset", asset_name)
|
||||
@@ -130,8 +128,7 @@ def create_maintenance_team():
|
||||
|
||||
def get_maintenance_team(user_list):
|
||||
return [
|
||||
{"team_member": user, "full_name": user, "maintenance_role": "Technician"}
|
||||
for user in user_list[1:]
|
||||
{"team_member": user, "full_name": user, "maintenance_role": "Technician"} for user in user_list[1:]
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,9 @@ class AssetMovement(Document):
|
||||
if d.source_location:
|
||||
if current_location != d.source_location:
|
||||
frappe.throw(
|
||||
_("Asset {0} does not belongs to the location {1}").format(d.asset, d.source_location)
|
||||
_("Asset {0} does not belongs to the location {1}").format(
|
||||
d.asset, d.source_location
|
||||
)
|
||||
)
|
||||
else:
|
||||
d.source_location = current_location
|
||||
@@ -79,19 +81,25 @@ class AssetMovement(Document):
|
||||
title=_("Incorrect Movement Purpose"),
|
||||
)
|
||||
if not d.target_location:
|
||||
frappe.throw(_("Target Location is required while transferring Asset {0}").format(d.asset))
|
||||
frappe.throw(
|
||||
_("Target Location is required while transferring Asset {0}").format(d.asset)
|
||||
)
|
||||
if d.source_location == d.target_location:
|
||||
frappe.throw(_("Source and Target Location cannot be same"))
|
||||
|
||||
if self.purpose == "Receipt":
|
||||
if not (d.source_location) and not (d.target_location or d.to_employee):
|
||||
frappe.throw(
|
||||
_("Target Location or To Employee is required while receiving Asset {0}").format(d.asset)
|
||||
_("Target Location or To Employee is required while receiving Asset {0}").format(
|
||||
d.asset
|
||||
)
|
||||
)
|
||||
elif d.source_location:
|
||||
if d.from_employee and not d.target_location:
|
||||
frappe.throw(
|
||||
_("Target Location is required while receiving Asset {0} from an employee").format(d.asset)
|
||||
_(
|
||||
"Target Location is required while receiving Asset {0} from an employee"
|
||||
).format(d.asset)
|
||||
)
|
||||
elif d.to_employee and d.target_location:
|
||||
frappe.throw(
|
||||
@@ -131,19 +139,17 @@ class AssetMovement(Document):
|
||||
# latest entry corresponds to current document's location, employee when transaction date > previous dates
|
||||
# In case of cancellation it corresponds to previous latest document's location, employee
|
||||
latest_movement_entry = frappe.db.sql(
|
||||
"""
|
||||
f"""
|
||||
SELECT asm_item.target_location, asm_item.to_employee
|
||||
FROM `tabAsset Movement Item` asm_item, `tabAsset Movement` asm
|
||||
WHERE
|
||||
asm_item.parent=asm.name and
|
||||
asm_item.asset=%(asset)s and
|
||||
asm.company=%(company)s and
|
||||
asm.docstatus=1 and {0}
|
||||
asm.docstatus=1 and {cond}
|
||||
ORDER BY
|
||||
asm.transaction_date desc limit 1
|
||||
""".format(
|
||||
cond
|
||||
),
|
||||
""",
|
||||
args,
|
||||
)
|
||||
if latest_movement_entry:
|
||||
@@ -164,7 +170,9 @@ class AssetMovement(Document):
|
||||
elif current_location:
|
||||
add_asset_activity(
|
||||
d.asset,
|
||||
_("Asset transferred to Location {0}").format(get_link_to_form("Location", current_location)),
|
||||
_("Asset transferred to Location {0}").format(
|
||||
get_link_to_form("Location", current_location)
|
||||
),
|
||||
)
|
||||
elif current_employee:
|
||||
add_asset_activity(
|
||||
|
||||
@@ -20,9 +20,7 @@ class TestAssetMovement(unittest.TestCase):
|
||||
make_location()
|
||||
|
||||
def test_movement(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset = frappe.get_doc("Asset", asset_name)
|
||||
@@ -51,7 +49,11 @@ class TestAssetMovement(unittest.TestCase):
|
||||
purpose="Transfer",
|
||||
company=asset.company,
|
||||
assets=[
|
||||
{"asset": asset.name, "source_location": "Test Location", "target_location": "Test Location 2"}
|
||||
{
|
||||
"asset": asset.name,
|
||||
"source_location": "Test Location",
|
||||
"target_location": "Test Location 2",
|
||||
}
|
||||
],
|
||||
reference_doctype="Purchase Receipt",
|
||||
reference_name=pr.name,
|
||||
@@ -62,7 +64,11 @@ class TestAssetMovement(unittest.TestCase):
|
||||
purpose="Transfer",
|
||||
company=asset.company,
|
||||
assets=[
|
||||
{"asset": asset.name, "source_location": "Test Location 2", "target_location": "Test Location"}
|
||||
{
|
||||
"asset": asset.name,
|
||||
"source_location": "Test Location 2",
|
||||
"target_location": "Test Location",
|
||||
}
|
||||
],
|
||||
reference_doctype="Purchase Receipt",
|
||||
reference_name=pr.name,
|
||||
@@ -97,9 +103,7 @@ class TestAssetMovement(unittest.TestCase):
|
||||
self.assertEqual(frappe.db.get_value("Asset", asset.name, "location"), "Test Location")
|
||||
|
||||
def test_last_movement_cancellation(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset = frappe.get_doc("Asset", asset_name)
|
||||
@@ -129,7 +133,11 @@ class TestAssetMovement(unittest.TestCase):
|
||||
purpose="Transfer",
|
||||
company=asset.company,
|
||||
assets=[
|
||||
{"asset": asset.name, "source_location": "Test Location", "target_location": "Test Location 2"}
|
||||
{
|
||||
"asset": asset.name,
|
||||
"source_location": "Test Location",
|
||||
"target_location": "Test Location 2",
|
||||
}
|
||||
],
|
||||
reference_doctype="Purchase Receipt",
|
||||
reference_name=pr.name,
|
||||
@@ -167,6 +175,4 @@ def create_asset_movement(**args):
|
||||
def make_location():
|
||||
for location in ["Pune", "Mumbai", "Nagpur"]:
|
||||
if not frappe.db.exists("Location", location):
|
||||
frappe.get_doc({"doctype": "Location", "location_name": location}).insert(
|
||||
ignore_permissions=True
|
||||
)
|
||||
frappe.get_doc({"doctype": "Location", "location_name": location}).insert(ignore_permissions=True)
|
||||
|
||||
@@ -169,9 +169,7 @@ class AssetRepair(AccountsController):
|
||||
|
||||
def check_for_stock_items_and_warehouse(self):
|
||||
if not self.get("stock_items"):
|
||||
frappe.throw(
|
||||
_("Please enter Stock Items consumed during the Repair."), title=_("Missing Items")
|
||||
)
|
||||
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."),
|
||||
@@ -263,9 +261,7 @@ class AssetRepair(AccountsController):
|
||||
def get_gl_entries(self):
|
||||
gl_entries = []
|
||||
|
||||
fixed_asset_account = get_asset_account(
|
||||
"fixed_asset_account", asset=self.asset, company=self.company
|
||||
)
|
||||
fixed_asset_account = get_asset_account("fixed_asset_account", asset=self.asset, company=self.company)
|
||||
self.get_gl_entries_for_repair_cost(gl_entries, fixed_asset_account)
|
||||
self.get_gl_entries_for_consumed_items(gl_entries, fixed_asset_account)
|
||||
|
||||
|
||||
@@ -199,9 +199,7 @@ class TestAssetRepair(unittest.TestCase):
|
||||
self.assertEqual(expected_values[d.account][1], d.credit)
|
||||
|
||||
def test_gl_entries_with_periodical_inventory(self):
|
||||
frappe.db.set_value(
|
||||
"Company", "_Test Company", "default_expense_account", "Cost of Goods Sold - _TC"
|
||||
)
|
||||
frappe.db.set_value("Company", "_Test Company", "default_expense_account", "Cost of Goods Sold - _TC")
|
||||
asset_repair = create_asset_repair(
|
||||
capitalize_repair_cost=1,
|
||||
stock_consumption=1,
|
||||
@@ -244,7 +242,7 @@ class TestAssetRepair(unittest.TestCase):
|
||||
asset = create_asset(calculate_depreciation=1, submit=1)
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
initial_num_of_depreciations = num_of_depreciations(asset)
|
||||
create_asset_repair(asset=asset, capitalize_repair_cost=1, submit=1)
|
||||
@@ -253,8 +251,8 @@ class TestAssetRepair(unittest.TestCase):
|
||||
first_asset_depr_schedule.load_from_db()
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(asset.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
self.assertEqual((initial_num_of_depreciations + 1), num_of_depreciations(asset))
|
||||
self.assertEqual(
|
||||
@@ -291,9 +289,7 @@ def create_asset_repair(**args):
|
||||
|
||||
if args.stock_consumption:
|
||||
asset_repair.stock_consumption = 1
|
||||
asset_repair.warehouse = args.warehouse or create_warehouse(
|
||||
"Test Warehouse", company=asset.company
|
||||
)
|
||||
asset_repair.warehouse = args.warehouse or create_warehouse("Test Warehouse", company=asset.company)
|
||||
|
||||
bundle = None
|
||||
if args.serial_no:
|
||||
|
||||
@@ -45,9 +45,7 @@ class AssetShiftAllocation(Document):
|
||||
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
|
||||
)
|
||||
self.asset_depr_schedule_doc = get_asset_depr_schedule_doc(self.asset, "Active", self.finance_book)
|
||||
|
||||
self.validate_invalid_shift_change()
|
||||
self.update_depr_schedule()
|
||||
@@ -90,9 +88,7 @@ class AssetShiftAllocation(Document):
|
||||
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
|
||||
):
|
||||
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"
|
||||
@@ -130,9 +126,7 @@ class AssetShiftAllocation(Document):
|
||||
|
||||
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
|
||||
}
|
||||
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))
|
||||
@@ -162,9 +156,9 @@ class AssetShiftAllocation(Document):
|
||||
)
|
||||
diff = 0
|
||||
except Exception:
|
||||
frappe.throw(_("Could not auto update shifts. Shift with shift factor {0} needed.")).format(
|
||||
shift_factor - diff
|
||||
)
|
||||
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)
|
||||
@@ -222,9 +216,9 @@ class AssetShiftAllocation(Document):
|
||||
)
|
||||
diff = 0
|
||||
except Exception:
|
||||
frappe.throw(_("Could not auto update shifts. Shift with shift factor {0} needed.")).format(
|
||||
shift_factor + diff
|
||||
)
|
||||
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)
|
||||
@@ -273,9 +267,7 @@ def find_subsets_with_sum(numbers, k, target_sum, current_subset, result):
|
||||
return
|
||||
|
||||
# Include the current number in the subset
|
||||
find_subsets_with_sum(
|
||||
numbers, k - 1, target_sum - numbers[0], current_subset + [numbers[0]], result
|
||||
)
|
||||
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)
|
||||
|
||||
@@ -25,9 +25,7 @@ class AssetShiftFactor(Document):
|
||||
|
||||
def validate_default(self):
|
||||
if self.default:
|
||||
existing_default_shift_factor = frappe.db.get_value(
|
||||
"Asset Shift Factor", {"default": 1}, "name"
|
||||
)
|
||||
existing_default_shift_factor = frappe.db.get_value("Asset Shift Factor", {"default": 1}, "name")
|
||||
|
||||
if existing_default_shift_factor:
|
||||
frappe.throw(
|
||||
|
||||
@@ -98,7 +98,7 @@ class AssetValueAdjustment(Document):
|
||||
je.naming_series = depreciation_series
|
||||
je.posting_date = self.date
|
||||
je.company = self.company
|
||||
je.remark = "Depreciation Entry against {0} worth {1}".format(self.asset, self.difference_amount)
|
||||
je.remark = f"Depreciation Entry against {self.asset} worth {self.difference_amount}"
|
||||
je.finance_book = self.finance_book
|
||||
|
||||
credit_entry = {
|
||||
|
||||
@@ -23,9 +23,7 @@ class TestAssetValueAdjustment(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_current_asset_value(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=100000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset_doc = frappe.get_doc("Asset", asset_name)
|
||||
@@ -52,9 +50,7 @@ class TestAssetValueAdjustment(unittest.TestCase):
|
||||
self.assertEqual(current_value, 100000.0)
|
||||
|
||||
def test_asset_depreciation_value_adjustment(self):
|
||||
pr = make_purchase_receipt(
|
||||
item_code="Macbook Pro", qty=1, rate=120000.0, location="Test Location"
|
||||
)
|
||||
pr = make_purchase_receipt(item_code="Macbook Pro", qty=1, rate=120000.0, location="Test Location")
|
||||
|
||||
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, "name")
|
||||
asset_doc = frappe.get_doc("Asset", asset_name)
|
||||
@@ -75,7 +71,7 @@ class TestAssetValueAdjustment(unittest.TestCase):
|
||||
asset_doc.submit()
|
||||
|
||||
first_asset_depr_schedule = get_asset_depr_schedule_doc(asset_doc.name, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Active")
|
||||
|
||||
post_depreciation_entries(getdate("2023-08-21"))
|
||||
|
||||
@@ -92,8 +88,8 @@ class TestAssetValueAdjustment(unittest.TestCase):
|
||||
first_asset_depr_schedule.load_from_db()
|
||||
|
||||
second_asset_depr_schedule = get_asset_depr_schedule_doc(asset_doc.name, "Active")
|
||||
self.assertEquals(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEquals(first_asset_depr_schedule.status, "Cancelled")
|
||||
self.assertEqual(second_asset_depr_schedule.status, "Active")
|
||||
self.assertEqual(first_asset_depr_schedule.status, "Cancelled")
|
||||
|
||||
expected_gle = (
|
||||
("_Test Accumulated Depreciations - _TC", 0.0, 4625.29),
|
||||
|
||||
@@ -216,17 +216,15 @@ def get_children(doctype, parent=None, location=None, is_root=False):
|
||||
parent = ""
|
||||
|
||||
return frappe.db.sql(
|
||||
"""
|
||||
f"""
|
||||
select
|
||||
name as value,
|
||||
is_group as expandable
|
||||
from
|
||||
`tabLocation` comp
|
||||
where
|
||||
ifnull(parent_location, "")={parent}
|
||||
""".format(
|
||||
parent=frappe.db.escape(parent)
|
||||
),
|
||||
ifnull(parent_location, "")={frappe.db.escape(parent)}
|
||||
""",
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@ class TestLocation(unittest.TestCase):
|
||||
ordered_test_location_features = sorted(
|
||||
test_location_features, key=lambda x: x["properties"]["feature_of"]
|
||||
)
|
||||
ordered_formatted_locations = sorted(
|
||||
formatted_locations, key=lambda x: x["properties"]["feature_of"]
|
||||
)
|
||||
ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x["properties"]["feature_of"])
|
||||
|
||||
self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
|
||||
self.assertEqual(area, test_location.get("area"))
|
||||
|
||||
@@ -122,11 +122,7 @@ def get_data(filters):
|
||||
assets_record = frappe.db.get_all("Asset", filters=conditions, fields=fields)
|
||||
|
||||
for asset in assets_record:
|
||||
if (
|
||||
assets_linked_to_fb
|
||||
and asset.calculate_depreciation
|
||||
and asset.asset_id not in assets_linked_to_fb
|
||||
):
|
||||
if assets_linked_to_fb and asset.calculate_depreciation and asset.asset_id not in assets_linked_to_fb:
|
||||
continue
|
||||
|
||||
asset_value = get_asset_value_after_depreciation(
|
||||
@@ -241,9 +237,7 @@ def get_assets_linked_to_fb(filters):
|
||||
|
||||
|
||||
def get_asset_depreciation_amount_map(filters, finance_book):
|
||||
start_date = (
|
||||
filters.from_date if filters.filter_based_on == "Date Range" else filters.year_start_date
|
||||
)
|
||||
start_date = filters.from_date if filters.filter_based_on == "Date Range" else filters.year_start_date
|
||||
end_date = filters.to_date if filters.filter_based_on == "Date Range" else filters.year_end_date
|
||||
|
||||
asset = frappe.qb.DocType("Asset")
|
||||
@@ -260,9 +254,7 @@ def get_asset_depreciation_amount_map(filters, finance_book):
|
||||
.join(company)
|
||||
.on(company.name == asset.company)
|
||||
.select(asset.name.as_("asset"), Sum(gle.debit).as_("depreciation_amount"))
|
||||
.where(
|
||||
gle.account == IfNull(aca.depreciation_expense_account, company.depreciation_expense_account)
|
||||
)
|
||||
.where(gle.account == IfNull(aca.depreciation_expense_account, company.depreciation_expense_account))
|
||||
.where(gle.debit != 0)
|
||||
.where(gle.is_cancelled == 0)
|
||||
.where(company.name == filters.company)
|
||||
@@ -281,9 +273,7 @@ def get_asset_depreciation_amount_map(filters, finance_book):
|
||||
else:
|
||||
query = query.where(asset.status.isin(["Sold", "Scrapped", "Capitalized", "Decapitalized"]))
|
||||
if finance_book:
|
||||
query = query.where(
|
||||
(gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull())
|
||||
)
|
||||
query = query.where((gle.finance_book.isin([cstr(finance_book), ""])) | (gle.finance_book.isnull()))
|
||||
else:
|
||||
query = query.where((gle.finance_book.isin([""])) | (gle.finance_book.isnull()))
|
||||
if filters.filter_based_on in ("Date Range", "Fiscal Year"):
|
||||
|
||||
Reference in New Issue
Block a user