mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 17:04:47 +00:00
Merge pull request #48326 from ljain112/cost-center-advance-pe
fix: cost center for payment entry against advance payment doctypes in accounts payable/rece
This commit is contained in:
@@ -24,6 +24,7 @@ from erpnext.accounts.party import get_party_account
|
|||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import (
|
||||||
cancel_exchange_gain_loss_journal,
|
cancel_exchange_gain_loss_journal,
|
||||||
get_account_currency,
|
get_account_currency,
|
||||||
|
get_advance_payment_doctypes,
|
||||||
get_balance_on,
|
get_balance_on,
|
||||||
get_stock_accounts,
|
get_stock_accounts,
|
||||||
get_stock_and_account_balance,
|
get_stock_and_account_balance,
|
||||||
@@ -311,9 +312,7 @@ class JournalEntry(AccountsController):
|
|||||||
|
|
||||||
def update_advance_paid(self):
|
def update_advance_paid(self):
|
||||||
advance_paid = frappe._dict()
|
advance_paid = frappe._dict()
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
advance_payment_doctypes = get_advance_payment_doctypes()
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
for d in self.get("accounts"):
|
for d in self.get("accounts"):
|
||||||
if d.is_advance:
|
if d.is_advance:
|
||||||
if d.reference_type in advance_payment_doctypes:
|
if d.reference_type in advance_payment_doctypes:
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ from erpnext.accounts.party import (
|
|||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import (
|
||||||
cancel_exchange_gain_loss_journal,
|
cancel_exchange_gain_loss_journal,
|
||||||
get_account_currency,
|
get_account_currency,
|
||||||
|
get_advance_payment_doctypes,
|
||||||
get_outstanding_invoices,
|
get_outstanding_invoices,
|
||||||
)
|
)
|
||||||
from erpnext.controllers.accounts_controller import (
|
from erpnext.controllers.accounts_controller import (
|
||||||
@@ -1099,10 +1100,7 @@ class PaymentEntry(AccountsController):
|
|||||||
|
|
||||||
def calculate_base_allocated_amount_for_reference(self, d) -> float:
|
def calculate_base_allocated_amount_for_reference(self, d) -> float:
|
||||||
base_allocated_amount = 0
|
base_allocated_amount = 0
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
if d.reference_doctype in get_advance_payment_doctypes():
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
if d.reference_doctype in advance_payment_doctypes:
|
|
||||||
# When referencing Sales/Purchase Order, use the source/target exchange rate depending on payment type.
|
# When referencing Sales/Purchase Order, use the source/target exchange rate depending on payment type.
|
||||||
# This is so there are no Exchange Gain/Loss generated for such doctypes
|
# This is so there are no Exchange Gain/Loss generated for such doctypes
|
||||||
|
|
||||||
@@ -1384,10 +1382,7 @@ class PaymentEntry(AccountsController):
|
|||||||
if not self.party_account:
|
if not self.party_account:
|
||||||
return
|
return
|
||||||
|
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
advance_payment_doctypes = get_advance_payment_doctypes()
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.payment_type == "Receive":
|
if self.payment_type == "Receive":
|
||||||
against_account = self.paid_to
|
against_account = self.paid_to
|
||||||
else:
|
else:
|
||||||
@@ -1780,9 +1775,7 @@ class PaymentEntry(AccountsController):
|
|||||||
if self.payment_type not in ("Receive", "Pay") or not self.party:
|
if self.payment_type not in ("Receive", "Pay") or not self.party:
|
||||||
return
|
return
|
||||||
|
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
advance_payment_doctypes = get_advance_payment_doctypes()
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if d.allocated_amount and d.reference_doctype in advance_payment_doctypes:
|
if d.allocated_amount and d.reference_doctype in advance_payment_doctypes:
|
||||||
frappe.get_lazy_doc(
|
frappe.get_lazy_doc(
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from erpnext.accounts.doctype.payment_entry.payment_entry import (
|
|||||||
)
|
)
|
||||||
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
|
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
|
||||||
from erpnext.accounts.party import get_party_account, get_party_bank_account
|
from erpnext.accounts.party import get_party_account, get_party_bank_account
|
||||||
from erpnext.accounts.utils import get_account_currency, get_currency_precision
|
from erpnext.accounts.utils import get_account_currency, get_advance_payment_doctypes, get_currency_precision
|
||||||
from erpnext.utilities import payment_app_import_guard
|
from erpnext.utilities import payment_app_import_guard
|
||||||
|
|
||||||
ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST = [
|
ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST = [
|
||||||
@@ -464,10 +464,7 @@ class PaymentRequest(Document):
|
|||||||
return create_stripe_subscription(gateway_controller, data)
|
return create_stripe_subscription(gateway_controller, data)
|
||||||
|
|
||||||
def update_reference_advance_payment_status(self):
|
def update_reference_advance_payment_status(self):
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
if self.reference_doctype in get_advance_payment_doctypes():
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
if self.reference_doctype in advance_payment_doctypes:
|
|
||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
ref_doc.set_advance_payment_status()
|
ref_doc.set_advance_payment_status()
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from frappe.utils.data import comma_and
|
|||||||
|
|
||||||
from erpnext.accounts.utils import (
|
from erpnext.accounts.utils import (
|
||||||
cancel_exchange_gain_loss_journal,
|
cancel_exchange_gain_loss_journal,
|
||||||
|
get_advance_payment_doctypes,
|
||||||
unlink_ref_doc_from_payment_entries,
|
unlink_ref_doc_from_payment_entries,
|
||||||
update_voucher_outstanding,
|
update_voucher_outstanding,
|
||||||
)
|
)
|
||||||
@@ -84,9 +85,7 @@ class UnreconcilePayment(Document):
|
|||||||
update_voucher_outstanding(
|
update_voucher_outstanding(
|
||||||
alloc.reference_doctype, alloc.reference_name, alloc.account, alloc.party_type, alloc.party
|
alloc.reference_doctype, alloc.reference_name, alloc.account, alloc.party_type, alloc.party
|
||||||
)
|
)
|
||||||
if doc.doctype in frappe.get_hooks("advance_payment_payable_doctypes") + frappe.get_hooks(
|
if doc.doctype in get_advance_payment_doctypes():
|
||||||
"advance_payment_receivable_doctypes"
|
|
||||||
):
|
|
||||||
doc.set_total_advance_paid()
|
doc.set_total_advance_paid()
|
||||||
|
|
||||||
frappe.db.set_value("Unreconcile Payment Entries", alloc.name, "unlinked", True)
|
frappe.db.set_value("Unreconcile Payment Entries", alloc.name, "unlinked", True)
|
||||||
|
|||||||
@@ -15,7 +15,11 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
|
|||||||
get_accounting_dimensions,
|
get_accounting_dimensions,
|
||||||
get_dimension_with_children,
|
get_dimension_with_children,
|
||||||
)
|
)
|
||||||
from erpnext.accounts.utils import get_currency_precision, get_party_types_from_account_type
|
from erpnext.accounts.utils import (
|
||||||
|
get_advance_payment_doctypes,
|
||||||
|
get_currency_precision,
|
||||||
|
get_party_types_from_account_type,
|
||||||
|
)
|
||||||
|
|
||||||
# This report gives a summary of all Outstanding Invoices considering the following
|
# This report gives a summary of all Outstanding Invoices considering the following
|
||||||
|
|
||||||
@@ -62,6 +66,9 @@ class ReceivablePayableReport:
|
|||||||
frappe.get_single_value("Accounts Settings", "receivable_payable_fetch_method")
|
frappe.get_single_value("Accounts Settings", "receivable_payable_fetch_method")
|
||||||
or "Buffered Cursor"
|
or "Buffered Cursor"
|
||||||
) # Fail Safe
|
) # Fail Safe
|
||||||
|
self.advance_payment_doctypes = frappe.get_hooks(
|
||||||
|
"advance_payment_receivable_doctypes"
|
||||||
|
) + frappe.get_hooks("advance_payment_payable_doctypes")
|
||||||
|
|
||||||
def run(self, args):
|
def run(self, args):
|
||||||
self.filters.update(args)
|
self.filters.update(args)
|
||||||
@@ -85,6 +92,7 @@ class ReceivablePayableReport:
|
|||||||
self.party_details = {}
|
self.party_details = {}
|
||||||
self.invoices = set()
|
self.invoices = set()
|
||||||
self.skip_total_row = 0
|
self.skip_total_row = 0
|
||||||
|
self.advance_payment_doctypes = get_advance_payment_doctypes()
|
||||||
|
|
||||||
if self.filters.get("group_by_party"):
|
if self.filters.get("group_by_party"):
|
||||||
self.previous_party = ""
|
self.previous_party = ""
|
||||||
@@ -181,7 +189,10 @@ class ReceivablePayableReport:
|
|||||||
if key not in self.voucher_balance:
|
if key not in self.voucher_balance:
|
||||||
self.voucher_balance[key] = self.build_voucher_dict(ple)
|
self.voucher_balance[key] = self.build_voucher_dict(ple)
|
||||||
|
|
||||||
if ple.voucher_type == ple.against_voucher_type and ple.voucher_no == ple.against_voucher_no:
|
if (ple.voucher_type == ple.against_voucher_type and ple.voucher_no == ple.against_voucher_no) or (
|
||||||
|
ple.voucher_type in ("Payment Entry", "Journal Entry")
|
||||||
|
and ple.against_voucher_type in self.advance_payment_doctypes
|
||||||
|
):
|
||||||
self.voucher_balance[key].cost_center = ple.cost_center
|
self.voucher_balance[key].cost_center = ple.cost_center
|
||||||
|
|
||||||
self.get_invoices(ple)
|
self.get_invoices(ple)
|
||||||
|
|||||||
@@ -644,10 +644,8 @@ def update_reference_in_journal_entry(d, journal_entry, do_not_save=False):
|
|||||||
|
|
||||||
# Update Advance Paid in SO/PO since they might be getting unlinked
|
# Update Advance Paid in SO/PO since they might be getting unlinked
|
||||||
update_advance_paid = []
|
update_advance_paid = []
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
|
||||||
"advance_payment_payable_doctypes"
|
if jv_detail.get("reference_type") in get_advance_payment_doctypes():
|
||||||
)
|
|
||||||
if jv_detail.get("reference_type") in advance_payment_doctypes:
|
|
||||||
update_advance_paid.append((jv_detail.reference_type, jv_detail.reference_name))
|
update_advance_paid.append((jv_detail.reference_type, jv_detail.reference_name))
|
||||||
|
|
||||||
rev_dr_or_cr = (
|
rev_dr_or_cr = (
|
||||||
@@ -754,10 +752,7 @@ def update_reference_in_payment_entry(
|
|||||||
existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0]
|
existing_row = payment_entry.get("references", {"name": d["voucher_detail_no"]})[0]
|
||||||
|
|
||||||
# Update Advance Paid in SO/PO since they are getting unlinked
|
# Update Advance Paid in SO/PO since they are getting unlinked
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
if existing_row.get("reference_doctype") in get_advance_payment_doctypes():
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
if existing_row.get("reference_doctype") in advance_payment_doctypes:
|
|
||||||
update_advance_paid.append((existing_row.reference_doctype, existing_row.reference_name))
|
update_advance_paid.append((existing_row.reference_doctype, existing_row.reference_name))
|
||||||
|
|
||||||
if d.allocated_amount <= existing_row.allocated_amount:
|
if d.allocated_amount <= existing_row.allocated_amount:
|
||||||
@@ -2291,6 +2286,19 @@ def get_party_types_from_account_type(account_type):
|
|||||||
return frappe.db.get_all("Party Type", {"account_type": account_type}, pluck="name")
|
return frappe.db.get_all("Party Type", {"account_type": account_type}, pluck="name")
|
||||||
|
|
||||||
|
|
||||||
|
def get_advance_payment_doctypes(payment_type=None):
|
||||||
|
"""
|
||||||
|
Get list of advance payment doctypes based on type.
|
||||||
|
:param type: Optional, can be "receivable" or "payable". If not provided, returns both.
|
||||||
|
"""
|
||||||
|
if payment_type:
|
||||||
|
return frappe.get_hooks(f"advance_payment_{payment_type}_doctypes") or []
|
||||||
|
|
||||||
|
return (frappe.get_hooks("advance_payment_receivable_doctypes") or []) + (
|
||||||
|
frappe.get_hooks("advance_payment_payable_doctypes") or []
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_ledger_health_checks():
|
def run_ledger_health_checks():
|
||||||
health_monitor_settings = frappe.get_doc("Ledger Health Monitor")
|
health_monitor_settings = frappe.get_doc("Ledger Health Monitor")
|
||||||
if health_monitor_settings.enable_health_monitor:
|
if health_monitor_settings.enable_health_monitor:
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ from erpnext.accounts.utils import (
|
|||||||
get_fiscal_years,
|
get_fiscal_years,
|
||||||
validate_fiscal_year,
|
validate_fiscal_year,
|
||||||
)
|
)
|
||||||
|
from erpnext.accounts.utils import (
|
||||||
|
get_advance_payment_doctypes as _get_advance_payment_doctypes,
|
||||||
|
)
|
||||||
from erpnext.buying.utils import update_last_purchase_rate
|
from erpnext.buying.utils import update_last_purchase_rate
|
||||||
from erpnext.controllers.print_settings import (
|
from erpnext.controllers.print_settings import (
|
||||||
set_print_templates_for_item_table,
|
set_print_templates_for_item_table,
|
||||||
@@ -383,10 +386,7 @@ class AccountsController(TransactionBase):
|
|||||||
adv = qb.DocType("Advance Payment Ledger Entry")
|
adv = qb.DocType("Advance Payment Ledger Entry")
|
||||||
qb.from_(adv).delete().where(adv.voucher_type.eq(self.doctype) & adv.voucher_no.eq(self.name)).run()
|
qb.from_(adv).delete().where(adv.voucher_type.eq(self.doctype) & adv.voucher_no.eq(self.name)).run()
|
||||||
|
|
||||||
advance_payment_doctypes = frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
if self.doctype in self.get_advance_payment_doctypes():
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
if self.doctype in advance_payment_doctypes:
|
|
||||||
qb.from_(adv).delete().where(
|
qb.from_(adv).delete().where(
|
||||||
adv.against_voucher_type.eq(self.doctype) & adv.against_voucher_no.eq(self.name)
|
adv.against_voucher_type.eq(self.doctype) & adv.against_voucher_no.eq(self.name)
|
||||||
).run()
|
).run()
|
||||||
@@ -2269,9 +2269,9 @@ class AccountsController(TransactionBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not paid_amount:
|
if not paid_amount:
|
||||||
if self.doctype in frappe.get_hooks("advance_payment_receivable_doctypes"):
|
if self.doctype in self.get_advance_payment_doctypes(payment_type="receivable"):
|
||||||
new_status = "Not Requested" if paid_amount is None else "Requested"
|
new_status = "Not Requested" if paid_amount is None else "Requested"
|
||||||
elif self.doctype in frappe.get_hooks("advance_payment_payable_doctypes"):
|
elif self.doctype in self.get_advance_payment_doctypes(payment_type="payable"):
|
||||||
new_status = "Not Initiated" if paid_amount is None else "Initiated"
|
new_status = "Not Initiated" if paid_amount is None else "Initiated"
|
||||||
else:
|
else:
|
||||||
total_amount = self.get("rounded_total") or self.get("grand_total")
|
total_amount = self.get("rounded_total") or self.get("grand_total")
|
||||||
@@ -2925,10 +2925,8 @@ class AccountsController(TransactionBase):
|
|||||||
repost_ledger.insert()
|
repost_ledger.insert()
|
||||||
repost_ledger.submit()
|
repost_ledger.submit()
|
||||||
|
|
||||||
def get_advance_payment_doctypes(self) -> list:
|
def get_advance_payment_doctypes(self, payment_type=None) -> list:
|
||||||
return frappe.get_hooks("advance_payment_receivable_doctypes") + frappe.get_hooks(
|
return _get_advance_payment_doctypes(payment_type=payment_type)
|
||||||
"advance_payment_payable_doctypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
def make_advance_payment_ledger_for_journal(self):
|
def make_advance_payment_ledger_for_journal(self):
|
||||||
advance_payment_doctypes = self.get_advance_payment_doctypes()
|
advance_payment_doctypes = self.get_advance_payment_doctypes()
|
||||||
|
|||||||
Reference in New Issue
Block a user