Merge branch 'develop' into hr-separation
This commit is contained in:
commit
f222284c33
@ -42,7 +42,7 @@ class GLEntry(Document):
|
|||||||
self.validate_and_set_fiscal_year()
|
self.validate_and_set_fiscal_year()
|
||||||
self.pl_must_have_cost_center()
|
self.pl_must_have_cost_center()
|
||||||
|
|
||||||
if not self.flags.from_repost:
|
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
|
||||||
self.check_mandatory()
|
self.check_mandatory()
|
||||||
self.validate_cost_center()
|
self.validate_cost_center()
|
||||||
self.check_pl_account()
|
self.check_pl_account()
|
||||||
@ -51,7 +51,7 @@ class GLEntry(Document):
|
|||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
adv_adj = self.flags.adv_adj
|
adv_adj = self.flags.adv_adj
|
||||||
if not self.flags.from_repost:
|
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
|
||||||
self.validate_account_details(adv_adj)
|
self.validate_account_details(adv_adj)
|
||||||
self.validate_dimensions_for_pl_and_bs()
|
self.validate_dimensions_for_pl_and_bs()
|
||||||
self.validate_allowed_dimensions()
|
self.validate_allowed_dimensions()
|
||||||
|
@ -10,10 +10,11 @@
|
|||||||
"fiscal_year",
|
"fiscal_year",
|
||||||
"amended_from",
|
"amended_from",
|
||||||
"company",
|
"company",
|
||||||
"cost_center_wise_pnl",
|
|
||||||
"column_break1",
|
"column_break1",
|
||||||
"closing_account_head",
|
"closing_account_head",
|
||||||
"remarks"
|
"remarks",
|
||||||
|
"gle_processing_status",
|
||||||
|
"error_message"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -86,17 +87,26 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"depends_on": "eval:doc.docstatus!=0",
|
||||||
"fieldname": "cost_center_wise_pnl",
|
"fieldname": "gle_processing_status",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Select",
|
||||||
"label": "Book Cost Center Wise Profit/Loss"
|
"label": "GL Entry Processing Status",
|
||||||
|
"options": "In Progress\nCompleted\nFailed",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.gle_processing_status=='Failed'",
|
||||||
|
"fieldname": "error_message",
|
||||||
|
"fieldtype": "Text",
|
||||||
|
"label": "Error Message",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-05-20 15:27:37.210458",
|
"modified": "2022-07-20 14:51:04.714154",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Period Closing Voucher",
|
"name": "Period Closing Voucher",
|
||||||
|
@ -8,7 +8,6 @@ from frappe.utils import flt
|
|||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
||||||
get_accounting_dimensions,
|
get_accounting_dimensions,
|
||||||
get_dimensions,
|
|
||||||
)
|
)
|
||||||
from erpnext.accounts.utils import get_account_currency
|
from erpnext.accounts.utils import get_account_currency
|
||||||
from erpnext.controllers.accounts_controller import AccountsController
|
from erpnext.controllers.accounts_controller import AccountsController
|
||||||
@ -20,12 +19,27 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
self.validate_posting_date()
|
self.validate_posting_date()
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
|
self.db_set("gle_processing_status", "In Progress")
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
self.db_set("gle_processing_status", "In Progress")
|
||||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
|
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
|
||||||
from erpnext.accounts.general_ledger import make_reverse_gl_entries
|
gle_count = frappe.db.count(
|
||||||
|
"GL Entry",
|
||||||
|
{"voucher_type": "Period Closing Voucher", "voucher_no": self.name, "is_cancelled": 0},
|
||||||
|
)
|
||||||
|
if gle_count > 5000:
|
||||||
|
frappe.enqueue(
|
||||||
|
make_reverse_gl_entries,
|
||||||
|
voucher_type="Period Closing Voucher",
|
||||||
|
voucher_no=self.name,
|
||||||
|
queue="long",
|
||||||
|
)
|
||||||
|
frappe.msgprint(
|
||||||
|
_("The GL Entries will be cancelled in the background, it can take a few minutes."), alert=True
|
||||||
|
)
|
||||||
|
else:
|
||||||
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
|
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
|
||||||
|
|
||||||
def validate_account_head(self):
|
def validate_account_head(self):
|
||||||
@ -67,18 +81,32 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
def make_gl_entries(self):
|
def make_gl_entries(self):
|
||||||
gl_entries = self.get_gl_entries()
|
gl_entries = self.get_gl_entries()
|
||||||
if gl_entries:
|
if gl_entries:
|
||||||
from erpnext.accounts.general_ledger import make_gl_entries
|
if len(gl_entries) > 5000:
|
||||||
|
frappe.enqueue(process_gl_entries, gl_entries=gl_entries, queue="long")
|
||||||
make_gl_entries(gl_entries)
|
frappe.msgprint(
|
||||||
|
_("The GL Entries will be processed in the background, it can take a few minutes."),
|
||||||
|
alert=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
process_gl_entries(gl_entries)
|
||||||
|
|
||||||
def get_gl_entries(self):
|
def get_gl_entries(self):
|
||||||
gl_entries = []
|
gl_entries = []
|
||||||
pl_accounts = self.get_pl_balances()
|
|
||||||
|
|
||||||
for acc in pl_accounts:
|
# pl account
|
||||||
|
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=True):
|
||||||
if flt(acc.bal_in_company_currency):
|
if flt(acc.bal_in_company_currency):
|
||||||
gl_entries.append(
|
gl_entries.append(self.get_gle_for_pl_account(acc))
|
||||||
self.get_gl_dict(
|
|
||||||
|
# closing liability account
|
||||||
|
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=False):
|
||||||
|
if flt(acc.bal_in_company_currency):
|
||||||
|
gl_entries.append(self.get_gle_for_closing_account(acc))
|
||||||
|
|
||||||
|
return gl_entries
|
||||||
|
|
||||||
|
def get_gle_for_pl_account(self, acc):
|
||||||
|
gl_entry = self.get_gl_dict(
|
||||||
{
|
{
|
||||||
"account": acc.account,
|
"account": acc.account,
|
||||||
"cost_center": acc.cost_center,
|
"cost_center": acc.cost_center,
|
||||||
@ -87,70 +115,46 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
||||||
if flt(acc.bal_in_account_currency) < 0
|
if flt(acc.bal_in_account_currency) < 0
|
||||||
else 0,
|
else 0,
|
||||||
"debit": abs(flt(acc.bal_in_company_currency))
|
"debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0,
|
||||||
if flt(acc.bal_in_company_currency) < 0
|
|
||||||
else 0,
|
|
||||||
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
||||||
if flt(acc.bal_in_account_currency) > 0
|
if flt(acc.bal_in_account_currency) > 0
|
||||||
else 0,
|
else 0,
|
||||||
"credit": abs(flt(acc.bal_in_company_currency))
|
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
|
||||||
if flt(acc.bal_in_company_currency) > 0
|
|
||||||
else 0,
|
|
||||||
},
|
},
|
||||||
item=acc,
|
item=acc,
|
||||||
)
|
)
|
||||||
)
|
self.update_default_dimensions(gl_entry, acc)
|
||||||
|
return gl_entry
|
||||||
|
|
||||||
if gl_entries:
|
def get_gle_for_closing_account(self, acc):
|
||||||
gle_for_net_pl_bal = self.get_pnl_gl_entry(pl_accounts)
|
|
||||||
gl_entries += gle_for_net_pl_bal
|
|
||||||
|
|
||||||
return gl_entries
|
|
||||||
|
|
||||||
def get_pnl_gl_entry(self, pl_accounts):
|
|
||||||
company_cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
|
||||||
gl_entries = []
|
|
||||||
|
|
||||||
for acc in pl_accounts:
|
|
||||||
if flt(acc.bal_in_company_currency):
|
|
||||||
cost_center = acc.cost_center if self.cost_center_wise_pnl else company_cost_center
|
|
||||||
gl_entry = self.get_gl_dict(
|
gl_entry = self.get_gl_dict(
|
||||||
{
|
{
|
||||||
"account": self.closing_account_head,
|
"account": self.closing_account_head,
|
||||||
"cost_center": cost_center,
|
"cost_center": acc.cost_center,
|
||||||
"finance_book": acc.finance_book,
|
"finance_book": acc.finance_book,
|
||||||
"account_currency": acc.account_currency,
|
"account_currency": acc.account_currency,
|
||||||
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
||||||
if flt(acc.bal_in_account_currency) > 0
|
if flt(acc.bal_in_account_currency) > 0
|
||||||
else 0,
|
else 0,
|
||||||
"debit": abs(flt(acc.bal_in_company_currency))
|
"debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
|
||||||
if flt(acc.bal_in_company_currency) > 0
|
|
||||||
else 0,
|
|
||||||
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
|
||||||
if flt(acc.bal_in_account_currency) < 0
|
if flt(acc.bal_in_account_currency) < 0
|
||||||
else 0,
|
else 0,
|
||||||
"credit": abs(flt(acc.bal_in_company_currency))
|
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0,
|
||||||
if flt(acc.bal_in_company_currency) < 0
|
|
||||||
else 0,
|
|
||||||
},
|
},
|
||||||
item=acc,
|
item=acc,
|
||||||
)
|
)
|
||||||
|
self.update_default_dimensions(gl_entry, acc)
|
||||||
|
return gl_entry
|
||||||
|
|
||||||
self.update_default_dimensions(gl_entry)
|
def update_default_dimensions(self, gl_entry, acc):
|
||||||
|
|
||||||
gl_entries.append(gl_entry)
|
|
||||||
|
|
||||||
return gl_entries
|
|
||||||
|
|
||||||
def update_default_dimensions(self, gl_entry):
|
|
||||||
if not self.accounting_dimensions:
|
if not self.accounting_dimensions:
|
||||||
self.accounting_dimensions = get_accounting_dimensions()
|
self.accounting_dimensions = get_accounting_dimensions()
|
||||||
|
|
||||||
_, default_dimensions = get_dimensions()
|
|
||||||
for dimension in self.accounting_dimensions:
|
for dimension in self.accounting_dimensions:
|
||||||
gl_entry.update({dimension: default_dimensions.get(self.company, {}).get(dimension)})
|
gl_entry.update({dimension: acc.get(dimension)})
|
||||||
|
|
||||||
def get_pl_balances(self):
|
def get_pl_balances_based_on_dimensions(self, group_by_account=False):
|
||||||
"""Get balance for dimension-wise pl accounts"""
|
"""Get balance for dimension-wise pl accounts"""
|
||||||
|
|
||||||
dimension_fields = ["t1.cost_center", "t1.finance_book"]
|
dimension_fields = ["t1.cost_center", "t1.finance_book"]
|
||||||
@ -159,20 +163,56 @@ class PeriodClosingVoucher(AccountsController):
|
|||||||
for dimension in self.accounting_dimensions:
|
for dimension in self.accounting_dimensions:
|
||||||
dimension_fields.append("t1.{0}".format(dimension))
|
dimension_fields.append("t1.{0}".format(dimension))
|
||||||
|
|
||||||
|
if group_by_account:
|
||||||
|
dimension_fields.append("t1.account")
|
||||||
|
|
||||||
return frappe.db.sql(
|
return frappe.db.sql(
|
||||||
"""
|
"""
|
||||||
select
|
select
|
||||||
t1.account, t2.account_currency, {dimension_fields},
|
t2.account_currency,
|
||||||
|
{dimension_fields},
|
||||||
sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) as bal_in_account_currency,
|
sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) as bal_in_account_currency,
|
||||||
sum(t1.debit) - sum(t1.credit) as bal_in_company_currency
|
sum(t1.debit) - sum(t1.credit) as bal_in_company_currency
|
||||||
from `tabGL Entry` t1, `tabAccount` t2
|
from `tabGL Entry` t1, `tabAccount` t2
|
||||||
where t1.is_cancelled = 0 and t1.account = t2.name and t2.report_type = 'Profit and Loss'
|
where
|
||||||
and t2.docstatus < 2 and t2.company = %s
|
t1.is_cancelled = 0
|
||||||
|
and t1.account = t2.name
|
||||||
|
and t2.report_type = 'Profit and Loss'
|
||||||
|
and t2.docstatus < 2
|
||||||
|
and t2.company = %s
|
||||||
and t1.posting_date between %s and %s
|
and t1.posting_date between %s and %s
|
||||||
group by t1.account, {dimension_fields}
|
group by {dimension_fields}
|
||||||
""".format(
|
""".format(
|
||||||
dimension_fields=", ".join(dimension_fields)
|
dimension_fields=", ".join(dimension_fields)
|
||||||
),
|
),
|
||||||
(self.company, self.get("year_start_date"), self.posting_date),
|
(self.company, self.get("year_start_date"), self.posting_date),
|
||||||
as_dict=1,
|
as_dict=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def process_gl_entries(gl_entries):
|
||||||
|
from erpnext.accounts.general_ledger import make_gl_entries
|
||||||
|
|
||||||
|
try:
|
||||||
|
make_gl_entries(gl_entries, merge_entries=False)
|
||||||
|
frappe.db.set_value(
|
||||||
|
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Completed"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
frappe.db.rollback()
|
||||||
|
frappe.log_error(e)
|
||||||
|
frappe.db.set_value(
|
||||||
|
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Failed"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_reverse_gl_entries(voucher_type, voucher_no):
|
||||||
|
from erpnext.accounts.general_ledger import make_reverse_gl_entries
|
||||||
|
|
||||||
|
try:
|
||||||
|
make_reverse_gl_entries(voucher_type=voucher_type, voucher_no=voucher_no)
|
||||||
|
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Completed")
|
||||||
|
except Exception as e:
|
||||||
|
frappe.db.rollback()
|
||||||
|
frappe.log_error(e)
|
||||||
|
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Failed")
|
||||||
|
@ -49,7 +49,7 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
|
|
||||||
expected_gle = (
|
expected_gle = (
|
||||||
("Cost of Goods Sold - TPC", 0.0, 600.0),
|
("Cost of Goods Sold - TPC", 0.0, 600.0),
|
||||||
(surplus_account, 600.0, 400.0),
|
(surplus_account, 200.0, 0.0),
|
||||||
("Sales - TPC", 400.0, 0.0),
|
("Sales - TPC", 400.0, 0.0),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,7 +59,8 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
""",
|
""",
|
||||||
(pcv.name),
|
(pcv.name),
|
||||||
)
|
)
|
||||||
|
pcv.reload()
|
||||||
|
self.assertEqual(pcv.gle_processing_status, "Completed")
|
||||||
self.assertEqual(pcv_gle, expected_gle)
|
self.assertEqual(pcv_gle, expected_gle)
|
||||||
|
|
||||||
def test_cost_center_wise_posting(self):
|
def test_cost_center_wise_posting(self):
|
||||||
@ -93,7 +94,6 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
pcv = self.make_period_closing_voucher(submit=False)
|
pcv = self.make_period_closing_voucher(submit=False)
|
||||||
pcv.cost_center_wise_pnl = 1
|
|
||||||
pcv.save()
|
pcv.save()
|
||||||
pcv.submit()
|
pcv.submit()
|
||||||
surplus_account = pcv.closing_account_head
|
surplus_account = pcv.closing_account_head
|
||||||
@ -116,6 +116,16 @@ class TestPeriodClosingVoucher(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(pcv_gle, expected_gle)
|
self.assertEqual(pcv_gle, expected_gle)
|
||||||
|
|
||||||
|
pcv.reload()
|
||||||
|
pcv.cancel()
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
frappe.db.get_value(
|
||||||
|
"GL Entry",
|
||||||
|
{"voucher_type": "Period Closing Voucher", "voucher_no": pcv.name, "is_cancelled": 0},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def test_period_closing_with_finance_book_entries(self):
|
def test_period_closing_with_finance_book_entries(self):
|
||||||
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
|
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")
|
||||||
|
|
||||||
|
@ -168,6 +168,7 @@ def get_cost_center_allocation_data(company, posting_date):
|
|||||||
def merge_similar_entries(gl_map, precision=None):
|
def merge_similar_entries(gl_map, precision=None):
|
||||||
merged_gl_map = []
|
merged_gl_map = []
|
||||||
accounting_dimensions = get_accounting_dimensions()
|
accounting_dimensions = get_accounting_dimensions()
|
||||||
|
|
||||||
for entry in gl_map:
|
for entry in gl_map:
|
||||||
# if there is already an entry in this account then just add it
|
# if there is already an entry in this account then just add it
|
||||||
# to that entry
|
# to that entry
|
||||||
@ -298,9 +299,10 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
|||||||
gle.flags.from_repost = from_repost
|
gle.flags.from_repost = from_repost
|
||||||
gle.flags.adv_adj = adv_adj
|
gle.flags.adv_adj = adv_adj
|
||||||
gle.flags.update_outstanding = update_outstanding or "Yes"
|
gle.flags.update_outstanding = update_outstanding or "Yes"
|
||||||
|
gle.flags.notify_update = False
|
||||||
gle.submit()
|
gle.submit()
|
||||||
|
|
||||||
if not from_repost:
|
if not from_repost and gle.voucher_type != "Period Closing Voucher":
|
||||||
validate_expense_against_budget(args)
|
validate_expense_against_budget(args)
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
"purchase_date",
|
"purchase_date",
|
||||||
"section_break_23",
|
"section_break_23",
|
||||||
"calculate_depreciation",
|
"calculate_depreciation",
|
||||||
"allow_monthly_depreciation",
|
|
||||||
"column_break_33",
|
"column_break_33",
|
||||||
"opening_accumulated_depreciation",
|
"opening_accumulated_depreciation",
|
||||||
"number_of_depreciations_booked",
|
"number_of_depreciations_booked",
|
||||||
@ -456,13 +455,6 @@
|
|||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"depends_on": "calculate_depreciation",
|
|
||||||
"fieldname": "allow_monthly_depreciation",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Allow Monthly Depreciation"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"collapsible_depends_on": "is_existing_asset",
|
"collapsible_depends_on": "is_existing_asset",
|
||||||
@ -518,7 +510,7 @@
|
|||||||
"link_fieldname": "asset"
|
"link_fieldname": "asset"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2022-01-30 20:19:24.680027",
|
"modified": "2022-07-20 10:15:12.887372",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
|
@ -343,44 +343,6 @@ class Asset(AccountsController):
|
|||||||
skip_row = True
|
skip_row = True
|
||||||
|
|
||||||
if depreciation_amount > 0:
|
if depreciation_amount > 0:
|
||||||
# With monthly depreciation, each depreciation is divided by months remaining until next date
|
|
||||||
if self.allow_monthly_depreciation:
|
|
||||||
# month range is 1 to 12
|
|
||||||
# In pro rata case, for first and last depreciation, month range would be different
|
|
||||||
month_range = (
|
|
||||||
months
|
|
||||||
if (has_pro_rata and n == 0)
|
|
||||||
or (has_pro_rata and n == cint(number_of_pending_depreciations) - 1)
|
|
||||||
else finance_book.frequency_of_depreciation
|
|
||||||
)
|
|
||||||
|
|
||||||
for r in range(month_range):
|
|
||||||
if has_pro_rata and n == 0:
|
|
||||||
# For first entry of monthly depr
|
|
||||||
if r == 0:
|
|
||||||
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date)
|
|
||||||
per_day_amt = depreciation_amount / days
|
|
||||||
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
|
|
||||||
depreciation_amount -= depreciation_amount_for_current_month
|
|
||||||
date = monthly_schedule_date
|
|
||||||
amount = depreciation_amount_for_current_month
|
|
||||||
else:
|
|
||||||
date = add_months(monthly_schedule_date, r)
|
|
||||||
amount = depreciation_amount / (month_range - 1)
|
|
||||||
elif (has_pro_rata and n == cint(number_of_pending_depreciations) - 1) and r == cint(
|
|
||||||
month_range
|
|
||||||
) - 1:
|
|
||||||
# For last entry of monthly depr
|
|
||||||
date = last_schedule_date
|
|
||||||
amount = depreciation_amount / month_range
|
|
||||||
else:
|
|
||||||
date = add_months(monthly_schedule_date, r)
|
|
||||||
amount = depreciation_amount / month_range
|
|
||||||
|
|
||||||
self._add_depreciation_row(
|
|
||||||
date, amount, finance_book.depreciation_method, finance_book.finance_book, finance_book.idx
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self._add_depreciation_row(
|
self._add_depreciation_row(
|
||||||
schedule_date,
|
schedule_date,
|
||||||
depreciation_amount,
|
depreciation_amount,
|
||||||
@ -854,10 +816,8 @@ class Asset(AccountsController):
|
|||||||
return args.get("rate_of_depreciation")
|
return args.get("rate_of_depreciation")
|
||||||
|
|
||||||
value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
|
value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
|
||||||
|
|
||||||
depreciation_rate = math.pow(value, 1.0 / flt(args.get("total_number_of_depreciations"), 2))
|
depreciation_rate = math.pow(value, 1.0 / flt(args.get("total_number_of_depreciations"), 2))
|
||||||
|
return flt((100 * (1 - depreciation_rate)), float_precision)
|
||||||
return 100 * (1 - flt(depreciation_rate, float_precision))
|
|
||||||
|
|
||||||
def get_pro_rata_amt(self, row, depreciation_amount, from_date, to_date):
|
def get_pro_rata_amt(self, row, depreciation_amount, from_date, to_date):
|
||||||
days = date_diff(to_date, from_date)
|
days = date_diff(to_date, from_date)
|
||||||
|
@ -721,12 +721,12 @@ class TestDepreciationMethods(AssetSetup):
|
|||||||
)
|
)
|
||||||
|
|
||||||
expected_schedules = [
|
expected_schedules = [
|
||||||
["2022-02-28", 645.0, 645.0],
|
["2022-02-28", 647.25, 647.25],
|
||||||
["2022-03-31", 1206.8, 1851.8],
|
["2022-03-31", 1210.71, 1857.96],
|
||||||
["2022-04-30", 1051.12, 2902.92],
|
["2022-04-30", 1053.99, 2911.95],
|
||||||
["2022-05-31", 915.52, 3818.44],
|
["2022-05-31", 917.55, 3829.5],
|
||||||
["2022-06-30", 797.42, 4615.86],
|
["2022-06-30", 798.77, 4628.27],
|
||||||
["2022-07-15", 384.14, 5000.0],
|
["2022-07-15", 371.73, 5000.0],
|
||||||
]
|
]
|
||||||
|
|
||||||
schedules = [
|
schedules = [
|
||||||
@ -737,7 +737,6 @@ class TestDepreciationMethods(AssetSetup):
|
|||||||
]
|
]
|
||||||
for d in asset.get("schedules")
|
for d in asset.get("schedules")
|
||||||
]
|
]
|
||||||
|
|
||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,4 +306,5 @@ erpnext.patches.v14_0.copy_is_subcontracted_value_to_is_old_subcontracting_flow
|
|||||||
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
||||||
erpnext.patches.v14_0.crm_ux_cleanup
|
erpnext.patches.v14_0.crm_ux_cleanup
|
||||||
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
erpnext.patches.v14_0.remove_india_localisation # 14-07-2022
|
||||||
|
erpnext.patches.v13_0.fix_number_and_frequency_for_monthly_depreciation
|
||||||
erpnext.patches.v14_0.remove_hr_and_payroll_modules
|
erpnext.patches.v14_0.remove_hr_and_payroll_modules
|
@ -0,0 +1,14 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
assets = frappe.get_all("Asset", filters={"allow_monthly_depreciation": 1})
|
||||||
|
|
||||||
|
for d in assets:
|
||||||
|
print(d.name)
|
||||||
|
asset_doc = frappe.get_doc("Asset", d.name)
|
||||||
|
for i in asset_doc.get("finance_books"):
|
||||||
|
if i.frequency_of_depreciation != 1:
|
||||||
|
i.total_number_of_depreciations *= i.frequency_of_depreciation
|
||||||
|
i.frequency_of_depreciation = 1
|
||||||
|
i.db_update()
|
@ -208,6 +208,8 @@ def repost_future_sle(
|
|||||||
via_landed_cost_voucher=False,
|
via_landed_cost_voucher=False,
|
||||||
doc=None,
|
doc=None,
|
||||||
):
|
):
|
||||||
|
if not args:
|
||||||
|
args = [] # set args to empty list if None to avoid enumerate error
|
||||||
|
|
||||||
items_to_be_repost = get_items_to_be_repost(
|
items_to_be_repost = get_items_to_be_repost(
|
||||||
voucher_type=voucher_type, voucher_no=voucher_no, doc=doc
|
voucher_type=voucher_type, voucher_no=voucher_no, doc=doc
|
||||||
@ -303,7 +305,7 @@ def get_items_to_be_repost(voucher_type=None, voucher_no=None, doc=None):
|
|||||||
group_by="item_code, warehouse",
|
group_by="item_code, warehouse",
|
||||||
)
|
)
|
||||||
|
|
||||||
return items_to_be_repost
|
return items_to_be_repost or []
|
||||||
|
|
||||||
|
|
||||||
def get_distinct_item_warehouse(args=None, doc=None):
|
def get_distinct_item_warehouse(args=None, doc=None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user