mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-27 13:55:19 +00:00
refactor(stock): extract Purchase Receipt ProvisionalAccountingService
Move provisional accounting for non-stock items into stock/doctype/purchase_receipt/services/provisional_accounting.py: - add_provisional_gl_entry stays as a controller delegator (called as a doc method by both the PR and PI GL composers) - validate_provisional_expense_account moves into the service; validate() repointed No behaviour change.
This commit is contained in:
@@ -9,10 +9,12 @@ from frappe.model.document import Document
|
|||||||
from frappe.utils import cint, flt, get_datetime, getdate, nowdate
|
from frappe.utils import cint, flt, get_datetime, getdate, nowdate
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.utils import get_account_currency
|
|
||||||
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
|
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
from erpnext.stock.doctype.purchase_receipt.services.billing_status import BillingStatusService
|
from erpnext.stock.doctype.purchase_receipt.services.billing_status import BillingStatusService
|
||||||
|
from erpnext.stock.doctype.purchase_receipt.services.provisional_accounting import (
|
||||||
|
ProvisionalAccountingService,
|
||||||
|
)
|
||||||
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import StockReservation
|
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import StockReservation
|
||||||
|
|
||||||
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
form_grid_templates = {"items": "templates/form_grid/item_grid.html"}
|
||||||
@@ -251,7 +253,7 @@ class PurchaseReceipt(BuyingController):
|
|||||||
self.validate_with_previous_doc()
|
self.validate_with_previous_doc()
|
||||||
self.validate_uom_is_integer()
|
self.validate_uom_is_integer()
|
||||||
self.validate_cwip_accounts()
|
self.validate_cwip_accounts()
|
||||||
self.validate_provisional_expense_account()
|
ProvisionalAccountingService(self).validate_provisional_expense_account()
|
||||||
|
|
||||||
self.check_for_on_hold_or_closed_status("Purchase Order", "purchase_order")
|
self.check_for_on_hold_or_closed_status("Purchase Order", "purchase_order")
|
||||||
|
|
||||||
@@ -280,19 +282,6 @@ class PurchaseReceipt(BuyingController):
|
|||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
def validate_provisional_expense_account(self):
|
|
||||||
provisional_accounting_for_non_stock_items = cint(
|
|
||||||
frappe.db.get_value("Company", self.company, "enable_provisional_accounting_for_non_stock_items")
|
|
||||||
)
|
|
||||||
|
|
||||||
if not provisional_accounting_for_non_stock_items:
|
|
||||||
return
|
|
||||||
|
|
||||||
default_provisional_account = self.get_company_default("default_provisional_account")
|
|
||||||
for item in self.get("items"):
|
|
||||||
if not item.get("provisional_expense_account"):
|
|
||||||
item.provisional_expense_account = default_provisional_account
|
|
||||||
|
|
||||||
def validate_with_previous_doc(self):
|
def validate_with_previous_doc(self):
|
||||||
super().validate_with_previous_doc(
|
super().validate_with_previous_doc(
|
||||||
{
|
{
|
||||||
@@ -483,49 +472,8 @@ class PurchaseReceipt(BuyingController):
|
|||||||
def add_provisional_gl_entry(
|
def add_provisional_gl_entry(
|
||||||
self, item, gl_entries, posting_date, provisional_account, reverse=0, item_amount=None
|
self, item, gl_entries, posting_date, provisional_account, reverse=0, item_amount=None
|
||||||
):
|
):
|
||||||
credit_currency = get_account_currency(provisional_account)
|
ProvisionalAccountingService(self).add_provisional_gl_entry(
|
||||||
expense_account = item.expense_account
|
item, gl_entries, posting_date, provisional_account, reverse, item_amount
|
||||||
debit_currency = get_account_currency(item.expense_account)
|
|
||||||
remarks = self.get("remarks") or _("Accounting Entry for Service")
|
|
||||||
multiplication_factor = 1
|
|
||||||
amount = item.base_amount
|
|
||||||
|
|
||||||
if reverse:
|
|
||||||
multiplication_factor = -1
|
|
||||||
# Post reverse entry for previously posted amount
|
|
||||||
amount = item_amount
|
|
||||||
expense_account = frappe.db.get_value(
|
|
||||||
"Purchase Receipt Item", {"name": item.get("pr_detail")}, ["expense_account"]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.add_gl_entry(
|
|
||||||
gl_entries=gl_entries,
|
|
||||||
account=provisional_account,
|
|
||||||
cost_center=item.cost_center,
|
|
||||||
debit=0.0,
|
|
||||||
credit=multiplication_factor * amount,
|
|
||||||
remarks=remarks,
|
|
||||||
against_account=expense_account,
|
|
||||||
account_currency=credit_currency,
|
|
||||||
project=item.project,
|
|
||||||
voucher_detail_no=item.name,
|
|
||||||
item=item,
|
|
||||||
posting_date=posting_date,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.add_gl_entry(
|
|
||||||
gl_entries=gl_entries,
|
|
||||||
account=expense_account,
|
|
||||||
cost_center=item.cost_center,
|
|
||||||
debit=multiplication_factor * amount,
|
|
||||||
credit=0.0,
|
|
||||||
remarks=remarks,
|
|
||||||
against_account=provisional_account,
|
|
||||||
account_currency=debit_currency,
|
|
||||||
project=item.project,
|
|
||||||
voucher_detail_no=item.name,
|
|
||||||
item=item,
|
|
||||||
posting_date=posting_date,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def is_landed_cost_booked_for_any_item(self) -> bool:
|
def is_landed_cost_booked_for_any_item(self) -> bool:
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
"""Provisional accounting for non-stock items received via Purchase Receipt."""
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import cint
|
||||||
|
|
||||||
|
from erpnext.accounts.utils import get_account_currency
|
||||||
|
|
||||||
|
|
||||||
|
class ProvisionalAccountingService:
|
||||||
|
def __init__(self, doc):
|
||||||
|
self.doc = doc
|
||||||
|
|
||||||
|
def validate_provisional_expense_account(self) -> None:
|
||||||
|
doc = self.doc
|
||||||
|
provisional_accounting_for_non_stock_items = cint(
|
||||||
|
frappe.db.get_value("Company", doc.company, "enable_provisional_accounting_for_non_stock_items")
|
||||||
|
)
|
||||||
|
|
||||||
|
if not provisional_accounting_for_non_stock_items:
|
||||||
|
return
|
||||||
|
|
||||||
|
default_provisional_account = doc.get_company_default("default_provisional_account")
|
||||||
|
for item in doc.get("items"):
|
||||||
|
if not item.get("provisional_expense_account"):
|
||||||
|
item.provisional_expense_account = default_provisional_account
|
||||||
|
|
||||||
|
def add_provisional_gl_entry(
|
||||||
|
self, item, gl_entries, posting_date, provisional_account, reverse=0, item_amount=None
|
||||||
|
) -> None:
|
||||||
|
doc = self.doc
|
||||||
|
credit_currency = get_account_currency(provisional_account)
|
||||||
|
expense_account = item.expense_account
|
||||||
|
debit_currency = get_account_currency(item.expense_account)
|
||||||
|
remarks = doc.get("remarks") or _("Accounting Entry for Service")
|
||||||
|
multiplication_factor = 1
|
||||||
|
amount = item.base_amount
|
||||||
|
|
||||||
|
if reverse:
|
||||||
|
multiplication_factor = -1
|
||||||
|
# Post reverse entry for previously posted amount
|
||||||
|
amount = item_amount
|
||||||
|
expense_account = frappe.db.get_value(
|
||||||
|
"Purchase Receipt Item", {"name": item.get("pr_detail")}, ["expense_account"]
|
||||||
|
)
|
||||||
|
|
||||||
|
doc.add_gl_entry(
|
||||||
|
gl_entries=gl_entries,
|
||||||
|
account=provisional_account,
|
||||||
|
cost_center=item.cost_center,
|
||||||
|
debit=0.0,
|
||||||
|
credit=multiplication_factor * amount,
|
||||||
|
remarks=remarks,
|
||||||
|
against_account=expense_account,
|
||||||
|
account_currency=credit_currency,
|
||||||
|
project=item.project,
|
||||||
|
voucher_detail_no=item.name,
|
||||||
|
item=item,
|
||||||
|
posting_date=posting_date,
|
||||||
|
)
|
||||||
|
|
||||||
|
doc.add_gl_entry(
|
||||||
|
gl_entries=gl_entries,
|
||||||
|
account=expense_account,
|
||||||
|
cost_center=item.cost_center,
|
||||||
|
debit=multiplication_factor * amount,
|
||||||
|
credit=0.0,
|
||||||
|
remarks=remarks,
|
||||||
|
against_account=provisional_account,
|
||||||
|
account_currency=debit_currency,
|
||||||
|
project=item.project,
|
||||||
|
voucher_detail_no=item.name,
|
||||||
|
item=item,
|
||||||
|
posting_date=posting_date,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user