Merge branch 'develop' into pr/38218

This commit is contained in:
ruthra kumar
2024-01-25 09:58:54 +05:30
968 changed files with 1493015 additions and 577355 deletions

View File

@@ -183,6 +183,7 @@ def get_balance_on(
cost_center=None,
ignore_account_permission=False,
account_type=None,
start_date=None,
):
if not account and frappe.form_dict.get("account"):
account = frappe.form_dict.get("account")
@@ -196,6 +197,8 @@ def get_balance_on(
cost_center = frappe.form_dict.get("cost_center")
cond = ["is_cancelled=0"]
if start_date:
cond.append("posting_date >= %s" % frappe.db.escape(cstr(start_date)))
if date:
cond.append("posting_date <= %s" % frappe.db.escape(cstr(date)))
else:
@@ -453,7 +456,19 @@ def add_cc(args=None):
return cc.name
def reconcile_against_document(args, skip_ref_details_update_for_pe=False): # nosemgrep
def _build_dimensions_dict_for_exc_gain_loss(
entry: dict | object = None, active_dimensions: list = None
):
dimensions_dict = frappe._dict()
if entry and active_dimensions:
for dim in active_dimensions:
dimensions_dict[dim.fieldname] = entry.get(dim.fieldname)
return dimensions_dict
def reconcile_against_document(
args, skip_ref_details_update_for_pe=False, active_dimensions=None
): # nosemgrep
"""
Cancel PE or JV, Update against document, split if required and resubmit
"""
@@ -472,12 +487,18 @@ def reconcile_against_document(args, skip_ref_details_update_for_pe=False): # n
# cancel advance entry
doc = frappe.get_doc(voucher_type, voucher_no)
frappe.flags.ignore_party_validation = True
_delete_pl_entries(voucher_type, voucher_no)
# For payments with `Advance` in separate account feature enabled, only new ledger entries are posted for each reference.
# No need to cancel/delete payment ledger entries
if not (voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account):
_delete_pl_entries(voucher_type, voucher_no)
for entry in entries:
check_if_advance_entry_modified(entry)
validate_allocated_amount(entry)
dimensions_dict = _build_dimensions_dict_for_exc_gain_loss(entry, active_dimensions)
# update ref in advance entry
if voucher_type == "Journal Entry":
referenced_row = update_reference_in_journal_entry(entry, doc, do_not_save=False)
@@ -485,25 +506,32 @@ def reconcile_against_document(args, skip_ref_details_update_for_pe=False): # n
# amount and account in args
# referenced_row is used to deduplicate gain/loss journal
entry.update({"referenced_row": referenced_row})
doc.make_exchange_gain_loss_journal([entry])
doc.make_exchange_gain_loss_journal([entry], dimensions_dict)
else:
update_reference_in_payment_entry(
entry, doc, do_not_save=True, skip_ref_details_update_for_pe=skip_ref_details_update_for_pe
referenced_row = update_reference_in_payment_entry(
entry,
doc,
do_not_save=True,
skip_ref_details_update_for_pe=skip_ref_details_update_for_pe,
dimensions_dict=dimensions_dict,
)
doc.save(ignore_permissions=True)
# re-submit advance entry
doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)
gl_map = doc.build_gl_map()
create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
if voucher_type == "Payment Entry" and doc.book_advance_payments_in_separate_party_account:
# both ledgers must be posted to for `Advance` in separate account feature
doc.make_advance_gl_entries(referenced_row, update_outstanding="No")
else:
gl_map = doc.build_gl_map()
create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
# Only update outstanding for newly linked vouchers
for entry in entries:
update_voucher_outstanding(
entry.against_voucher_type, entry.against_voucher, entry.account, entry.party_type, entry.party
)
if voucher_type == "Payment Entry":
doc.make_advance_gl_entries(entry.against_voucher_type, entry.against_voucher)
frappe.flags.ignore_party_validation = False
@@ -593,7 +621,10 @@ def update_reference_in_journal_entry(d, journal_entry, do_not_save=False):
jv_detail = journal_entry.get("accounts", {"name": d["voucher_detail_no"]})[0]
# Update Advance Paid in SO/PO since they might be getting unlinked
if jv_detail.get("reference_type") in ("Sales Order", "Purchase Order"):
advance_payment_doctypes = frappe.get_hooks(
"advance_payment_customer_doctypes"
) + frappe.get_hooks("advance_payment_supplier_doctypes")
if jv_detail.get("reference_type") in advance_payment_doctypes:
frappe.get_doc(jv_detail.reference_type, jv_detail.reference_name).set_total_advance_paid()
if flt(d["unadjusted_amount"]) - flt(d["allocated_amount"]) != 0:
@@ -647,7 +678,7 @@ def update_reference_in_journal_entry(d, journal_entry, do_not_save=False):
def update_reference_in_payment_entry(
d, payment_entry, do_not_save=False, skip_ref_details_update_for_pe=False
d, payment_entry, do_not_save=False, skip_ref_details_update_for_pe=False, dimensions_dict=None
):
reference_details = {
"reference_doctype": d.against_voucher_type,
@@ -655,16 +686,22 @@ def update_reference_in_payment_entry(
"total_amount": d.grand_total,
"outstanding_amount": d.outstanding_amount,
"allocated_amount": d.allocated_amount,
"exchange_rate": d.exchange_rate if d.exchange_gain_loss else payment_entry.get_exchange_rate(),
"exchange_gain_loss": d.exchange_gain_loss,
"exchange_rate": d.exchange_rate
if d.difference_amount is not None
else payment_entry.get_exchange_rate(),
"exchange_gain_loss": d.difference_amount,
"account": d.account,
"dimensions": d.dimensions,
}
if d.voucher_detail_no:
existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0]
# Update Advance Paid in SO/PO since they are getting unlinked
if existing_row.get("reference_doctype") in ("Sales Order", "Purchase Order"):
advance_payment_doctypes = frappe.get_hooks(
"advance_payment_customer_doctypes"
) + frappe.get_hooks("advance_payment_supplier_doctypes")
if existing_row.get("reference_doctype") in advance_payment_doctypes:
frappe.get_doc(
existing_row.reference_doctype, existing_row.reference_name
).set_total_advance_paid()
@@ -676,11 +713,12 @@ def update_reference_in_payment_entry(
new_row.docstatus = 1
for field in list(reference_details):
new_row.set(field, reference_details[field])
row = new_row
else:
new_row = payment_entry.append("references")
new_row.docstatus = 1
new_row.update(reference_details)
row = new_row
payment_entry.flags.ignore_validate_update_after_submit = True
payment_entry.clear_unallocated_reference_document_rows()
@@ -689,12 +727,14 @@ def update_reference_in_payment_entry(
if not skip_ref_details_update_for_pe:
payment_entry.set_missing_ref_details()
payment_entry.set_amounts()
payment_entry.make_exchange_gain_loss_journal(
frappe._dict({"difference_posting_date": d.difference_posting_date})
frappe._dict({"difference_posting_date": d.difference_posting_date}), dimensions_dict
)
if not do_not_save:
payment_entry.save(ignore_permissions=True)
return row
def cancel_exchange_gain_loss_journal(
@@ -871,7 +911,13 @@ def remove_ref_doc_link_from_pe(
try:
pe_doc = frappe.get_doc("Payment Entry", pe)
pe_doc.set_amounts()
pe_doc.make_advance_gl_entries(against_voucher_type=ref_type, against_voucher=ref_no, cancel=1)
# Call cancel on only removed reference
references = [
x for x in pe_doc.references if x.reference_doctype == ref_type and x.reference_name == ref_no
]
[pe_doc.make_advance_gl_entries(x, cancel=1) for x in references]
pe_doc.clear_unallocated_reference_document_rows()
pe_doc.validate_payment_type_with_outstanding()
except Exception as e:
@@ -1047,11 +1093,11 @@ def get_outstanding_invoices(
if (
min_outstanding
and max_outstanding
and not (outstanding_amount >= min_outstanding and outstanding_amount <= max_outstanding)
and (outstanding_amount < min_outstanding or outstanding_amount > max_outstanding)
):
continue
if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
if d.voucher_type != "Purchase Invoice" or d.voucher_no not in held_invoices:
outstanding_invoices.append(
frappe._dict(
{
@@ -1098,12 +1144,16 @@ def get_companies():
@frappe.whitelist()
def get_children(doctype, parent, company, is_root=False):
def get_children(doctype, parent, company, is_root=False, include_disabled=False):
if isinstance(include_disabled, str):
include_disabled = frappe.json.loads(include_disabled)
from erpnext.accounts.report.financial_statements import sort_accounts
parent_fieldname = "parent_" + doctype.lower().replace(" ", "_")
fields = ["name as value", "is_group as expandable"]
filters = [["docstatus", "<", 2]]
if frappe.db.has_column(doctype, "disabled") and not include_disabled:
filters.append(["disabled", "=", False])
filters.append(['ifnull(`{0}`,"")'.format(parent_fieldname), "=", "" if is_root else parent])
@@ -1253,7 +1303,7 @@ def get_autoname_with_number(number_value, doc_title, company):
def parse_naming_series_variable(doc, variable):
if variable == "FY":
if doc:
date = doc.get("posting_date") or doc.get("transaction_date")
date = doc.get("posting_date") or doc.get("transaction_date") or getdate()
company = doc.get("company")
else:
date = getdate()
@@ -1836,6 +1886,30 @@ class QueryPaymentLedger(object):
Table("outstanding").amount_in_account_currency >= self.max_outstanding
)
if self.limit and self.get_invoices:
outstanding_vouchers = (
qb.from_(ple)
.select(
ple.against_voucher_no.as_("voucher_no"),
Sum(ple.amount_in_account_currency).as_("amount_in_account_currency"),
)
.where(ple.delinked == 0)
.where(Criterion.all(filter_on_against_voucher_no))
.where(Criterion.all(self.common_filter))
.where(Criterion.all(self.dimensions_filter))
.where(Criterion.all(self.voucher_posting_date))
.groupby(ple.against_voucher_type, ple.against_voucher_no, ple.party_type, ple.party)
.orderby(ple.posting_date, ple.voucher_no)
.having(qb.Field("amount_in_account_currency") > 0)
.limit(self.limit)
.run()
)
if outstanding_vouchers:
filter_on_voucher_no.append(ple.voucher_no.isin([x[0] for x in outstanding_vouchers]))
filter_on_against_voucher_no.append(
ple.against_voucher_no.isin([x[0] for x in outstanding_vouchers])
)
# build query for voucher amount
query_voucher_amount = (
qb.from_(ple)
@@ -1997,6 +2071,7 @@ def create_gain_loss_journal(
ref2_dn,
ref2_detail_no,
cost_center,
dimensions,
) -> str:
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.voucher_type = "Exchange Gain Or Loss"
@@ -2030,7 +2105,8 @@ def create_gain_loss_journal(
dr_or_cr + "_in_account_currency": 0,
}
)
if dimensions:
journal_account.update(dimensions)
journal_entry.append("accounts", journal_account)
journal_account = frappe._dict(
@@ -2046,7 +2122,8 @@ def create_gain_loss_journal(
reverse_dr_or_cr: abs(exc_gain_loss),
}
)
if dimensions:
journal_account.update(dimensions)
journal_entry.append("accounts", journal_account)
journal_entry.save()