Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-40584

This commit is contained in:
mergify[bot]
2024-04-10 15:57:49 +00:00
committed by GitHub
605 changed files with 5625 additions and 6617 deletions

View File

@@ -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",
},
{

View File

@@ -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)

View File

@@ -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
)
)

View File

@@ -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)

View File

@@ -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

View File

@@ -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):

View File

@@ -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:

View File

@@ -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")

View File

@@ -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(

View File

@@ -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}

View File

@@ -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)

View File

@@ -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:]
]

View File

@@ -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(

View File

@@ -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)

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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(

View File

@@ -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 = {

View File

@@ -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),

View File

@@ -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,
)

View File

@@ -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"))

View File

@@ -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"):