refactor: get frozen accounts settings from Company in patches

This commit is contained in:
Khushi Rawat
2025-06-13 14:35:20 +05:30
committed by khushi8112
parent e088427e92
commit 7bce3ac7fa
4 changed files with 88 additions and 65 deletions

View File

@@ -10,15 +10,17 @@ def execute():
purchase_invoices = frappe.db.sql( purchase_invoices = frappe.db.sql(
""" """
select select
parenttype as type, parent as name PI.company, PI_ADV.parenttype as type, PI_ADV.parent as name
from from
`tabPurchase Invoice Advance` `tabPurchase Invoice Advance` as PI_ADV join `tabPurchase Invoice` as PI
on
PI_ADV.parent = PI.name
where where
ref_exchange_rate = 1 PI_ADV.ref_exchange_rate = 1
and docstatus = 1 and PI_ADV.docstatus = 1
and ifnull(exchange_gain_loss, 0) != 0 and ifnull(PI_ADV.exchange_gain_loss, 0) != 0
group by group by
parent PI_ADV.parent
""", """,
as_dict=1, as_dict=1,
) )
@@ -26,15 +28,17 @@ def execute():
sales_invoices = frappe.db.sql( sales_invoices = frappe.db.sql(
""" """
select select
parenttype as type, parent as name SI.company, SI_ADV.parenttype as type, SI_ADV.parent as name
from from
`tabSales Invoice Advance` `tabSales Invoice Advance` as SI_ADV join `tabSales Invoice` as SI
on
SI_ADV.parent = SI.name
where where
ref_exchange_rate = 1 SI_ADV.ref_exchange_rate = 1
and docstatus = 1 and SI_ADV.docstatus = 1
and ifnull(exchange_gain_loss, 0) != 0 and ifnull(SI_ADV.exchange_gain_loss, 0) != 0
group by group by
parent SI_ADV.parent
""", """,
as_dict=1, as_dict=1,
) )
@@ -45,11 +49,21 @@ def execute():
message=json.dumps(purchase_invoices + sales_invoices, indent=2), message=json.dumps(purchase_invoices + sales_invoices, indent=2),
) )
acc_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto") original_frozen_dates = {}
if acc_frozen_upto:
frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", None)
for invoice in purchase_invoices + sales_invoices: for invoice in purchase_invoices + sales_invoices:
company = invoice.company
# Unfreeze only once per company
if company not in original_frozen_dates:
accounts_frozen_till_date = frappe.get_cached_value(
"Company", company, "accounts_frozen_till_date"
)
original_frozen_dates[company] = accounts_frozen_till_date
if accounts_frozen_till_date:
frappe.db.set_value("Company", company, "accounts_frozen_till_date", None)
try: try:
doc = frappe.get_doc(invoice.type, invoice.name) doc = frappe.get_doc(invoice.type, invoice.name)
doc.docstatus = 2 doc.docstatus = 2
@@ -64,5 +78,6 @@ def execute():
frappe.db.rollback() frappe.db.rollback()
print(f"Failed to correct gl entries of {invoice.name}") print(f"Failed to correct gl entries of {invoice.name}")
if acc_frozen_upto: for company, frozen_date in original_frozen_dates.items():
frappe.db.set_single_value("Accounts Settings", "acc_frozen_upto", acc_frozen_upto) if frozen_date:
frappe.db.set_value("Company", company, "accounts_frozen_till_date", frozen_date)

View File

@@ -9,43 +9,47 @@ def execute():
# Migrate schema of all uncancelled dunnings # Migrate schema of all uncancelled dunnings
filters = {"docstatus": ("!=", 2)} filters = {"docstatus": ("!=", 2)}
for company in frappe.get_all("Company", pluck="name"):
filters["company"] = company
can_edit_accounts_after = get_accounts_closing_date(company)
if can_edit_accounts_after:
# Get dunnings after the date when accounts were frozen/closed
filters["posting_date"] = (">", can_edit_accounts_after)
can_edit_accounts_after = get_accounts_closing_date() all_dunnings = frappe.get_all("Dunning", filters=filters, pluck="name")
if can_edit_accounts_after:
# Get dunnings after the date when accounts were frozen/closed
filters["posting_date"] = (">", can_edit_accounts_after)
all_dunnings = frappe.get_all("Dunning", filters=filters, pluck="name") for dunning_name in all_dunnings:
dunning = frappe.get_doc("Dunning", dunning_name)
if not dunning.sales_invoice:
# nothing we can do
continue
for dunning_name in all_dunnings: if dunning.overdue_payments:
dunning = frappe.get_doc("Dunning", dunning_name) # something's already here, doesn't need patching
if not dunning.sales_invoice: continue
# nothing we can do
continue
if dunning.overdue_payments: payment_schedules = frappe.get_all(
# something's already here, doesn't need patching "Payment Schedule",
continue filters={"parent": dunning.sales_invoice},
fields=[
"parent as sales_invoice",
"name as payment_schedule",
"payment_term",
"due_date",
"invoice_portion",
"payment_amount",
# at the time of creating this dunning, the full amount was outstanding
"payment_amount as outstanding",
"'0' as paid_amount",
"discounted_amount",
],
)
payment_schedules = frappe.get_all( dunning.extend("overdue_payments", payment_schedules)
"Payment Schedule", dunning.validate()
filters={"parent": dunning.sales_invoice},
fields=[
"parent as sales_invoice",
"name as payment_schedule",
"payment_term",
"due_date",
"invoice_portion",
"payment_amount",
# at the time of creating this dunning, the full amount was outstanding
"payment_amount as outstanding",
"'0' as paid_amount",
"discounted_amount",
],
)
dunning.extend("overdue_payments", payment_schedules) dunning.flags.ignore_validate_update_after_submit = True
dunning.validate() dunning.save()
dunning.flags.ignore_validate_update_after_submit = True dunning.flags.ignore_validate_update_after_submit = True
dunning.flags.ignore_links = True dunning.flags.ignore_links = True
@@ -60,20 +64,21 @@ def execute():
make_reverse_gl_entries(voucher_type="Dunning", voucher_no=dunning.name) make_reverse_gl_entries(voucher_type="Dunning", voucher_no=dunning.name)
def get_accounts_closing_date(): def get_accounts_closing_date(company):
"""Get the date when accounts were frozen/closed""" """Get the date when accounts were frozen/closed"""
accounts_frozen_till = frappe.db.get_single_value( accounts_frozen_till_date = frappe.db.get_value("Company", company, "accounts_frozen_till_date")
"Accounts Settings", "acc_frozen_upto"
) # always returns datetime.date
period_closing_date = frappe.db.get_value( period_closing_date = frappe.db.get_value(
"Period Closing Voucher", {"docstatus": 1}, "period_end_date", order_by="period_end_date desc" "Period Closing Voucher",
{"docstatus": 1, "company": company},
"period_end_date",
order_by="period_end_date desc",
) )
# Set most recent frozen/closing date as filter # Set most recent frozen/closing date as filter
if accounts_frozen_till and period_closing_date: if accounts_frozen_till_date and period_closing_date:
can_edit_accounts_after = max(accounts_frozen_till, period_closing_date) can_edit_accounts_after = max(accounts_frozen_till_date, period_closing_date)
else: else:
can_edit_accounts_after = accounts_frozen_till or period_closing_date can_edit_accounts_after = accounts_frozen_till_date or period_closing_date
return can_edit_accounts_after return can_edit_accounts_after

View File

@@ -58,9 +58,9 @@ def execute():
): ):
posting_date = period_closing_voucher[0].period_end_date posting_date = period_closing_voucher[0].period_end_date
acc_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto") acc_frozen_till_date = frappe.db.get_value("Company", company, "accounts_frozen_till_date")
if acc_frozen_upto and getdate(acc_frozen_upto) > getdate(posting_date): if acc_frozen_till_date and getdate(acc_frozen_till_date) > getdate(posting_date):
posting_date = acc_frozen_upto posting_date = acc_frozen_till_date
stock_frozen_upto = frappe.db.get_single_value("Stock Settings", "stock_frozen_upto") stock_frozen_upto = frappe.db.get_single_value("Stock Settings", "stock_frozen_upto")
if stock_frozen_upto and getdate(stock_frozen_upto) > getdate(posting_date): if stock_frozen_upto and getdate(stock_frozen_upto) > getdate(posting_date):

View File

@@ -159,16 +159,19 @@ class RepostItemValuation(Document):
return query[0][0] if query and query[0][0] else None return query[0][0] if query and query[0][0] else None
def validate_accounts_freeze(self): def validate_accounts_freeze(self):
acc_settings = frappe.get_cached_doc("Accounts Settings") acc_frozen_till_date = frappe.db.get_value("Company", self.company, "accounts_frozen_till_date")
if not acc_settings.acc_frozen_upto: frozen_accounts_modifier = frappe.db.get_value(
"Company", self.company, "role_allowed_for_frozen_entries"
)
if not acc_frozen_till_date:
return return
if getdate(self.posting_date) <= getdate(acc_settings.acc_frozen_upto): if getdate(self.posting_date) <= getdate(acc_frozen_till_date):
if acc_settings.frozen_accounts_modifier and frappe.session.user in get_users_with_role( if frozen_accounts_modifier and frappe.session.user in get_users_with_role(
acc_settings.frozen_accounts_modifier frozen_accounts_modifier
): ):
frappe.msgprint(_("Caution: This might alter frozen accounts.")) frappe.msgprint(_("Caution: This might alter frozen accounts."))
return return
frappe.throw(_("You cannot repost item valuation before {}").format(acc_settings.acc_frozen_upto)) frappe.throw(_("You cannot repost item valuation before {}").format(acc_frozen_till_date))
def reset_field_values(self): def reset_field_values(self):
if self.based_on == "Transaction": if self.based_on == "Transaction":