build: configurar herramientas de verificación OCA
- Instalar pre-commit con 25 hooks configurados - Configurar black 26.1.0 para formateo de código Python - Configurar isort 7.0.0 para ordenación de imports - Configurar flake8 7.3.0 con flake8-bugbear - Configurar pylint 3.1.1 con pylint-odoo 9.1.2 - Añadir autoflake y pyupgrade para mejoras automáticas - Configurar prettier para formateo de XML/JSON/YAML - Crear .editorconfig para consistencia de editor - Crear Makefile con comandos útiles - Crear check_addon.sh para verificación rápida de addons - Actualizar configuración de VS Code con extensiones recomendadas - Añadir documentación completa de uso - Aplicar formateo automático a archivos existentes - Deshabilitar setuptools-odoo (no soporta Odoo 18.0 aún) - Deshabilitar fix-encoding-pragma (obsoleto, usar pyupgrade)
This commit is contained in:
parent
5b9c6e3211
commit
fe137dc265
224 changed files with 18376 additions and 0 deletions
1
product_get_price_helper/models/__init__.py
Normal file
1
product_get_price_helper/models/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import product_product
|
||||
120
product_get_price_helper/models/product_product.py
Normal file
120
product_get_price_helper/models/product_product.py
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# Copyright 2017 Akretion (http://www.akretion.com).
|
||||
# @author Sébastien BEAU <sebastien.beau@akretion.com>
|
||||
# Copyright 2021 Camptocamp (http://www.camptocamp.com).
|
||||
# @author Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models
|
||||
from odoo.tools import float_compare
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
from ..utils import float_round
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = "product.product"
|
||||
|
||||
def _get_price(
|
||||
self,
|
||||
qty=1.0,
|
||||
pricelist=None,
|
||||
fposition=None,
|
||||
company=None,
|
||||
date=None,
|
||||
price_unit=None,
|
||||
):
|
||||
"""Computes the product prices
|
||||
|
||||
:param qty: The product quantity, used to apply pricelist rules.
|
||||
:param pricelist: Optional. Get prices for a specific pricelist.
|
||||
:param fposition: Optional. Apply fiscal position to product taxes.
|
||||
:param company: Optional.
|
||||
:param date: Optional.
|
||||
|
||||
:returns: dict with the following keys:
|
||||
|
||||
<value> The product unitary price
|
||||
<tax_included> True if product taxes are included in <price>.
|
||||
|
||||
If the pricelist.discount_policy is "without_discount":
|
||||
<original_value> The original price (before pricelist is applied).
|
||||
<discount> The discounted percentage.
|
||||
"""
|
||||
self.ensure_one()
|
||||
AccountTax = self.env["account.tax"]
|
||||
# Apply company
|
||||
product = self.with_company(company) if company else self
|
||||
company = company or self.env.company
|
||||
# Always filter taxes by the company
|
||||
taxes = product.taxes_id.filtered(lambda tax: tax.company_id == company)
|
||||
# Apply fiscal position
|
||||
taxes = fposition.map_tax(taxes) if fposition else taxes
|
||||
# Set context. Some of the methods used here depend on these values
|
||||
product_context = dict(
|
||||
self.env.context,
|
||||
quantity=qty,
|
||||
pricelist=pricelist.id if pricelist else None,
|
||||
fiscal_position=fposition,
|
||||
date=date,
|
||||
)
|
||||
product = product.with_context(**product_context)
|
||||
pricelist = pricelist.with_context(**product_context) if pricelist else None
|
||||
if price_unit is None:
|
||||
price_unit = (
|
||||
pricelist._get_product_price(product, qty, date=date)
|
||||
if pricelist
|
||||
else product.lst_price
|
||||
)
|
||||
price_unit = AccountTax._fix_tax_included_price_company(
|
||||
price_unit, product.taxes_id, taxes, company
|
||||
)
|
||||
price_dp = self.env["decimal.precision"].precision_get("Product Price")
|
||||
price_unit = float_round(price_unit, price_dp)
|
||||
res = {
|
||||
"value": price_unit,
|
||||
"tax_included": any(tax.price_include for tax in taxes),
|
||||
# Default values in case price.discount_policy != "without_discount"
|
||||
"original_value": price_unit,
|
||||
"discount": 0.0,
|
||||
}
|
||||
if pricelist:
|
||||
rule_id = pricelist._get_product_rule(product, qty, date=date)
|
||||
pl_item = self.env["product.pricelist.item"].browse(rule_id)
|
||||
if not pl_item.exists():
|
||||
return res
|
||||
original_price_unit = product.lst_price
|
||||
if not pl_item._show_discount():
|
||||
# If the pricelist does not show the discount, we return the price as is
|
||||
if float_is_zero(original_price_unit, precision_digits=price_dp):
|
||||
res["original_value"] = 0.0
|
||||
return res
|
||||
# Get the price rule
|
||||
price_unit, _ = pricelist._get_product_price_rule(product, qty, date=date)
|
||||
# Get the price before applying the pricelist
|
||||
price_dp = self.env["decimal.precision"].precision_get("Product Price")
|
||||
# Compute discount
|
||||
if not float_is_zero(
|
||||
original_price_unit, precision_digits=price_dp
|
||||
) and float_compare(
|
||||
original_price_unit, price_unit, precision_digits=price_dp
|
||||
):
|
||||
discount = (
|
||||
(original_price_unit - price_unit) / original_price_unit * 100
|
||||
)
|
||||
# Apply the right precision on discount
|
||||
discount_dp = self.env["decimal.precision"].precision_get("Discount")
|
||||
discount = float_round(discount, discount_dp)
|
||||
else:
|
||||
discount = 0.00
|
||||
# Compute prices
|
||||
original_price_unit = AccountTax._fix_tax_included_price_company(
|
||||
original_price_unit, product.taxes_id, taxes, company
|
||||
)
|
||||
original_price_unit = float_round(original_price_unit, price_dp)
|
||||
res.update(
|
||||
{
|
||||
"original_value": original_price_unit,
|
||||
"discount": discount,
|
||||
}
|
||||
)
|
||||
return res
|
||||
Loading…
Add table
Add a link
Reference in a new issue