如何重写控制器中的类方法 ERPNext 14

问题描述 投票:0回答:1

我一直在尝试通过我自己的自定义公式覆盖控制器(taxes_and_totals.py)中的方法(calculate_item_values),但它似乎不起作用,但是当我尝试使用 doctype 类方法(Quotation)时,它确实覆盖了我应该做的事情尝试别的吗?希望您能给我一些帮助

这是我的自定义应用程序中的自定义文件(override.py)

import frappe
from frappe import _, scrub
from frappe.utils import flt
from erpnext.controllers.taxes_and_totals import calculate_taxes_and_totals
from erpnext.accounts.doctype.pricing_rule.utils import get_applied_pricing_rules

class Calculating_amount(calculate_taxes_and_totals):
    def calculate_item_values(self):
        print('khello')
        if self.doc.get("is_consolidated"):
            return

        if not self.discount_amount_applied:
            for item in self._items:
                self.doc.round_floats_in(item)

                if item.discount_percentage == 100:
                    item.rate = 0.0
                elif item.price_list_rate:
                    if not item.rate or (
                        item.pricing_rules and item.discount_percentage > 0
                    ):
                        item.rate = flt(
                            item.price_list_rate
                            * (1.0 - (item.discount_percentage / 100.0)),
                            item.precision("rate"),
                        )

                        item.discount_amount = item.price_list_rate * (
                            item.discount_percentage / 100.0
                        )

                    elif item.discount_amount and item.pricing_rules:
                        item.rate = item.price_list_rate - item.discount_amount

                if item.doctype in [
                    "Quotation Item",
                    "Sales Order Item",
                    "Delivery Note Item",
                    "Sales Invoice Item",
                    "POS Invoice Item",
                    "Purchase Invoice Item",
                    "Purchase Order Item",
                    "Purchase Receipt Item",
                ]:
                    (
                        item.rate_with_margin,
                        item.base_rate_with_margin,
                    ) = self.calculate_margin(item)
                    if flt(item.rate_with_margin) > 0:
                        item.rate = flt(
                            item.rate_with_margin
                            * (1.0 - (item.discount_percentage / 100.0)),
                            item.precision("rate"),
                        )

                        if item.discount_amount and not item.discount_percentage:
                            item.rate = item.rate_with_margin - item.discount_amount
                        else:
                            item.discount_amount = item.rate_with_margin - item.rate

                    elif flt(item.price_list_rate) > 0:
                        item.discount_amount = item.price_list_rate - item.rate
                elif flt(item.price_list_rate) > 0 and not item.discount_amount:
                    item.discount_amount = item.price_list_rate - item.rate

                item.net_rate = item.rate

                if not item.qty and self.doc.get("is_return"):
                    item.amount = flt(-1 * item.rate, item.precision("amount"))
                elif not item.qty and self.doc.get("is_debit_note"):
                    item.amount = flt(item.rate, item.precision("amount"))
                else:
                    item.amount = flt(
                        item.rate * item.qty * item.length * item.width,
                        item.precision("amount"),
                    )

                item.net_amount = item.amount

                self._set_in_company_currency(
                    item,
                    ["price_list_rate", "rate", "net_rate", "amount", "net_amount"],
                )

                item.item_tax_amount = 0.0

    def _set_in_company_currency(self, doc, fields):
        # set values in base currency
        for f in fields:
            val = flt(
                flt(
                    doc.get(f),
                    doc.precision(f) * self.doc.conversion_rate,
                    doc.precision("base_" + f),
                )
            )
            doc.set("base_" + f, val)

    def calculate_margin(self, item):
        rate_with_margin = 0.0
        base_rate_with_margin = 0.0
        if item.price_list_rate:
            if item.pricing_rules and not self.doc.ignore_pricing_rule:
                has_margin = False
                for d in get_applied_pricing_rules(item.pricing_rules):
                    pricing_rule = frappe.get_cached_doc("Pricing Rule", d)
                    if pricing_rule.margin_rate_or_amount and (
                        (
                            pricing_rule.currency == self.doc.currency
                            and pricing_rule.margin_type in ["Amount", "Percentage"]
                        )
                        or pricing_rule.margin_type == "Percentage"
                    ):
                        item.margin_type = pricing_rule.margin_type
                        item.margin_rate_or_amount = pricing_rule.margin_rate_or_amount
                        has_margin = True
                if not has_margin:
                    item.margin_type = None
                    item.margin_rate_or_amount = 0.0
            if not item.pricing_rules and flt(item.rate) > flt(item.price_list_rate):
                item.margin_type = "Amount"
                item.margin_rate_or_amount = flt(
                    item.rate - item.price_list_rate,
                    item.precision("margin_rate_or_amount"),
                )
                item.rate_with_margin = item.rate
            elif item.margin_type and item.margin_rate_or_amount:
                margin_value = (
                    item.margin_rate_or_amount
                    if item.margin_type == "Amount"
                    else flt(item.price_list_rate)
                    * flt(item.margin_rate_or_amount)
                    / 100
                )
                rate_with_margin = flt(item.price_list_rate) + flt(margin_value)
                base_rate_with_margin = flt(rate_with_margin) * flt(
                    self.doc.conversion_rate
                )

        return rate_with_margin, base_rate_with_margin

这是我的钩子文件

override_doctype_class = {
    "calculate_taxes_and_totals":"test_app.override.Calculating_amount"
}

python customization erpnext frappe
1个回答
0
投票

在您的 hook.py 文件中,确保键“calculate_taxes_and_totals”对应于您要覆盖的正确控制器类。您应该指定原始类的完整路径,在本例中为 erpnext.controllers.taxes_and_totals.calculate_taxes_and_totals。如果您的应用程序/模块名称是 test_app,您需要这样指定:

override_doctype_class = { “erpnext.controllers.taxes_and_totals.calculate_taxes_and_totals”:“test_app.override.Calculate_amount” }
© www.soinside.com 2019 - 2024. All rights reserved.