add purchase_order_product_recommendation_supermarket
This commit is contained in:
parent
7b37ed92a1
commit
e2a5a830f3
8 changed files with 558 additions and 0 deletions
30
purchase_order_product_recommendation_supermarket/README.rst
Normal file
30
purchase_order_product_recommendation_supermarket/README.rst
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
=================================================
|
||||
Purchase Order Product Recommendation Supermarket
|
||||
=================================================
|
||||
|
||||
Extends “purchase_order_product_recommendation” to add functionalities for food shops
|
||||
|
||||
Purpose
|
||||
=======
|
||||
|
||||
#. Allows to indicate the number of days for which the quantity calculation will be made. If this field is defined, the quantity ordered will be calculated as “quantity/day * no. of days to cover”.
|
||||
#. Allows to define the quantities according to the packaging of the products.
|
||||
#. New check field “Do not take into account days with 0 stock”. In the case of activating this check, the desired behavior would be to disregard in the calculation of daily sales the days when the stock of that product was at 0 or less than 0.
|
||||
#. New column indicating the scraps of the product in the period under analysis
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
To configure this module, you need to:
|
||||
|
||||
#. Mark the desired settings in the wizard
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module, you need to:
|
||||
|
||||
#. Go to the purchase order form view.
|
||||
#. Click on the "Recommend Products" button.
|
||||
#. In the wizard that appears, configure the desired settings.
|
||||
#. Click "Confirm" to generate the product recommendations.
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import wizards
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Copyright 2025 Criptomart
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
"name": "Purchase Order Product Recommendation Supermarket",
|
||||
"summary": """Extends “purchase_order_product_recommendation” to add functionalities for food shops""",
|
||||
"version": "16.0.0.1.0",
|
||||
"license": "AGPL-3",
|
||||
"author": "Criptomart",
|
||||
"website": "https://criptomart.net",
|
||||
"depends": ["purchase_order_product_recommendation"],
|
||||
"data": ["wizards/purchase_order_recommendation.xml"],
|
||||
"demo": [],
|
||||
}
|
||||
138
purchase_order_product_recommendation_supermarket/i18n/es.po
Normal file
138
purchase_order_product_recommendation_supermarket/i18n/es.po
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_order_product_recommendation_supermarket
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-10 15:20+0000\n"
|
||||
"PO-Revision-Date: 2025-06-10 17:33+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.6\n"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__avg_days_between_orders
|
||||
msgid "Average days between orders"
|
||||
msgstr "Promedio de días entre pedidos"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__avg_days_between_orders
|
||||
msgid "Average number of days between orders for this vendor."
|
||||
msgstr "Número medio de días entre pedidos para este proveedor."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__days_without_stock
|
||||
msgid "Days without stock"
|
||||
msgstr "Días sin existencias"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__ignore_zero_stock_days
|
||||
msgid ""
|
||||
"If enabled, days when the product stock was 0 or less will not be "
|
||||
"considered in the daily sales calculation."
|
||||
msgstr ""
|
||||
"Si se activa, los días en los que el stock del producto era 0 o negativo no "
|
||||
"se tendrán en cuenta en el cálculo de las ventas diarias."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__ignore_zero_stock_days
|
||||
msgid "Ignore days with zero stock"
|
||||
msgstr "Ignorar los días sin existencias"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_days
|
||||
msgid ""
|
||||
"Indicate for how many days the new order should cover the stock. If not "
|
||||
"set, the default module behavior is kept."
|
||||
msgstr ""
|
||||
"Indica durante cuántos días la nueva orden debe cubrir el stock. Si no se "
|
||||
"establece, se mantiene el comportamiento por defecto del módulo."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_by_packages
|
||||
msgid "Indicates if the order should be made by packages."
|
||||
msgstr "Indica si el pedido debe realizarse por paquetes."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_by_packages
|
||||
msgid "Order by packages"
|
||||
msgstr "Pedir por paquetes"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_days
|
||||
msgid "Order coverage (days)"
|
||||
msgstr "Días a cubrir"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_id
|
||||
msgid "Packaging"
|
||||
msgstr "Empaquetado"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Packaging Contained Qty"
|
||||
msgstr "Ctd contenida en el paquete"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Packaging Qty"
|
||||
msgstr "Ctd Paquetes"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_qty
|
||||
msgid "Packaging Quantity"
|
||||
msgstr "Cantidad de paquetes"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_contained_qty
|
||||
msgid "Packaging Quantity Contained"
|
||||
msgstr "Ctd contenida en el paquete"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Qty scrapped"
|
||||
msgstr "Ctd desechada"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_qty
|
||||
msgid "Quantity contained in the selected packaging for this product."
|
||||
msgstr "Cantidad contenida en el envase seleccionado para este producto."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_contained_qty
|
||||
msgid "Quantity of packages to order for this product."
|
||||
msgstr "Cantidad de paquetes a pedir para este producto."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model,name:purchase_order_product_recommendation_supermarket.model_purchase_order_recommendation_line
|
||||
msgid "Recommended product for current purchase order"
|
||||
msgstr "Producto recomendado para el pedido de compra en curso"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model,name:purchase_order_product_recommendation_supermarket.model_purchase_order_recommendation
|
||||
msgid "Recommended products for current purchase order"
|
||||
msgstr "Productos recomendados para el pedido de compra en curso"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__total_days
|
||||
msgid "Total days"
|
||||
msgstr "Días totales"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__total_days
|
||||
msgid ""
|
||||
"Total number of days between the start and end dates of the recommendation."
|
||||
msgstr ""
|
||||
"Número total de días entre las fechas de inicio y fin de la recomendación."
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__units_scrapped
|
||||
msgid "Units Scrapped"
|
||||
msgstr "Ctd desechada"
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * purchase_order_product_recommendation_supermarket
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-10 15:19+0000\n"
|
||||
"PO-Revision-Date: 2025-06-10 15:19+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__avg_days_between_orders
|
||||
msgid "Average days between orders"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__avg_days_between_orders
|
||||
msgid "Average number of days between orders for this vendor."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__days_without_stock
|
||||
msgid "Days without stock"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__ignore_zero_stock_days
|
||||
msgid ""
|
||||
"If enabled, days when the product stock was 0 or less will not be considered"
|
||||
" in the daily sales calculation."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__ignore_zero_stock_days
|
||||
msgid "Ignore days with zero stock"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_days
|
||||
msgid ""
|
||||
"Indicate for how many days the new order should cover the stock. If not set,"
|
||||
" the default module behavior is kept."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_by_packages
|
||||
msgid "Indicates if the order should be made by packages."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_by_packages
|
||||
msgid "Order by packages"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__order_days
|
||||
msgid "Order coverage (days)"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_id
|
||||
msgid "Packaging"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Packaging Contained Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Packaging Qty"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_qty
|
||||
msgid "Packaging Quantity"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_contained_qty
|
||||
msgid "Packaging Quantity Contained"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_order_product_recommendation_supermarket.view_purchase_order_recommendation_wizard_form_supermarket
|
||||
msgid "Qty scrapped"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_qty
|
||||
msgid "Quantity contained in the selected packaging for this product."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__packaging_contained_qty
|
||||
msgid "Quantity of packages to order for this product."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model,name:purchase_order_product_recommendation_supermarket.model_purchase_order_recommendation_line
|
||||
msgid "Recommended product for current purchase order"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model,name:purchase_order_product_recommendation_supermarket.model_purchase_order_recommendation
|
||||
msgid "Recommended products for current purchase order"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__total_days
|
||||
msgid "Total days"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,help:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation__total_days
|
||||
msgid ""
|
||||
"Total number of days between the start and end dates of the recommendation."
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_order_product_recommendation_supermarket
|
||||
#: model:ir.model.fields,field_description:purchase_order_product_recommendation_supermarket.field_purchase_order_recommendation_line__units_scrapped
|
||||
msgid "Units Scrapped"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import purchase_order_recommendation
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
from odoo import api, fields, models
|
||||
import math
|
||||
from datetime import timedelta, datetime, time
|
||||
|
||||
|
||||
class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
||||
_inherit = "purchase.order.recommendation"
|
||||
|
||||
order_days = fields.Integer(
|
||||
string="Order coverage (days)",
|
||||
help="Indicate for how many days the new order should cover the stock. If not set, the default module behavior is kept.",
|
||||
)
|
||||
order_by_packages = fields.Boolean(
|
||||
string="Order by packages",
|
||||
default=False,
|
||||
help="Indicates if the order should be made by packages.",
|
||||
)
|
||||
ignore_zero_stock_days = fields.Boolean(
|
||||
string="Ignore days with zero stock",
|
||||
default=False,
|
||||
help="If enabled, days when the product stock was 0 or less will not be considered in the daily sales calculation.",
|
||||
)
|
||||
total_days = fields.Integer(
|
||||
string="Total days",
|
||||
compute="_compute_total_days",
|
||||
readonly=True,
|
||||
help="Total number of days between the start and end dates of the recommendation.",
|
||||
)
|
||||
avg_days_between_orders = fields.Float(
|
||||
string="Average days between orders",
|
||||
compute="_compute_avg_days_between_orders",
|
||||
help="Average number of days between orders for this vendor.",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.depends("date_begin", "date_end")
|
||||
def _compute_total_days(self):
|
||||
for rec in self:
|
||||
if rec.date_begin and rec.date_end:
|
||||
rec.total_days = self._get_total_days()
|
||||
else:
|
||||
rec.total_days = 0
|
||||
|
||||
@api.depends("order_id")
|
||||
def _compute_avg_days_between_orders(self):
|
||||
if not self.order_id.partner_id:
|
||||
self.avg_days_between_orders = 0.0
|
||||
return
|
||||
|
||||
orders = self.env["purchase.order"].search(
|
||||
[
|
||||
("partner_id", "=", self.order_id.partner_id.id),
|
||||
("state", "in", ["purchase", "done"]),
|
||||
],
|
||||
order="date_order asc",
|
||||
)
|
||||
|
||||
dates = [o.date_order.date() for o in orders if o.date_order]
|
||||
if len(dates) < 2:
|
||||
self.avg_days_between_orders = 0.0
|
||||
return
|
||||
|
||||
day_diffs = [
|
||||
(dates[i + 1] - dates[i]).days
|
||||
for i in range(len(dates) - 1)
|
||||
if (dates[i + 1] - dates[i]).days > 0
|
||||
]
|
||||
|
||||
if not day_diffs:
|
||||
self.avg_days_between_orders = 0.0
|
||||
else:
|
||||
self.avg_days_between_orders = sum(day_diffs) / len(day_diffs)
|
||||
|
||||
@api.onchange(
|
||||
"order_days",
|
||||
"order_by_packages",
|
||||
"ignore_zero_stock_days",
|
||||
)
|
||||
def _onchange_order_fields(self):
|
||||
self._generate_recommendations()
|
||||
|
||||
def _prepare_wizard_line(self, vals, order_line=False):
|
||||
"""Used to create the wizard line"""
|
||||
res = super()._prepare_wizard_line(vals, order_line=order_line)
|
||||
product_id = order_line and order_line.product_id or vals["product_id"]
|
||||
qty_to_order = res["units_included"]
|
||||
|
||||
if self.ignore_zero_stock_days:
|
||||
days_with_stock = self._get_total_days() - self._get_days_out_of_stock(
|
||||
product_id
|
||||
)
|
||||
res["units_avg_delivered"] = (
|
||||
vals.get("qty_delivered", 0) / days_with_stock
|
||||
if days_with_stock != 0
|
||||
else 1
|
||||
)
|
||||
|
||||
if self.order_days != 0:
|
||||
qty_to_order = (self.order_days * res["units_avg_delivered"]) - res[
|
||||
"units_virtual_available"
|
||||
]
|
||||
|
||||
# Adjust qty_to_order to packaging multiples if order_by_packages is checked
|
||||
if self.order_by_packages and product_id.packaging_ids:
|
||||
packaging_qty = product_id.packaging_ids[:1].qty
|
||||
if packaging_qty:
|
||||
qty_to_order = math.ceil(qty_to_order / packaging_qty) * packaging_qty
|
||||
res["units_included"] = qty_to_order
|
||||
|
||||
# Get quantities scrapped
|
||||
domain = self._get_move_line_domain(product_id, src="internal", dst="inventory")
|
||||
found_scrapped = self.env["stock.move.line"].read_group(
|
||||
domain, ["product_id", "qty_done"], ["product_id"]
|
||||
)
|
||||
if len(found_scrapped):
|
||||
res["units_scrapped"] = found_scrapped[0]["qty_done"]
|
||||
|
||||
return res
|
||||
|
||||
def _get_days_out_of_stock(self, product):
|
||||
"""
|
||||
Returns the number of days between date_begin and date_end
|
||||
where the given product had zero or negative stock (qty_available).
|
||||
"""
|
||||
days_out_of_stock = 0
|
||||
date_from = self.date_begin
|
||||
date_to = self.date_end
|
||||
if not date_from or not date_to:
|
||||
return 0
|
||||
# Loop through each day in the range
|
||||
for n in range((date_to - date_from).days + 1):
|
||||
day = date_from + timedelta(days=n)
|
||||
qty = product.with_context(
|
||||
to_date=datetime.combine(day, time(23, 59, 59))
|
||||
).qty_available
|
||||
if qty <= 0:
|
||||
days_out_of_stock += 1
|
||||
return days_out_of_stock
|
||||
|
||||
def _get_products(self):
|
||||
"""Overwrite because filter by cateogory is not working in the base method."""
|
||||
products = self._get_supplier_products()
|
||||
# Filter products by category if set.
|
||||
# It will apply to show_all_partner_products as well
|
||||
if self.product_category_ids:
|
||||
products = products.filtered(
|
||||
lambda x: x.categ_id.id in self.product_category_ids.ids
|
||||
)
|
||||
print(self.product_category_ids)
|
||||
return products
|
||||
|
||||
|
||||
class PurchaseOrderRecommendationLine(models.TransientModel):
|
||||
_inherit = "purchase.order.recommendation.line"
|
||||
|
||||
packaging_id = fields.Many2one(
|
||||
comodel_name="product.packaging",
|
||||
string="Packaging",
|
||||
compute="_compute_first_packaging_id",
|
||||
readonly=True,
|
||||
)
|
||||
packaging_qty = fields.Integer(
|
||||
string="Packaging Quantity",
|
||||
help="Quantity contained in the selected packaging for this product.",
|
||||
compute="_compute_packaging_qty",
|
||||
inverse="_inverse_packaging_qty",
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
packaging_contained_qty = fields.Float(
|
||||
string="Packaging Quantity Contained",
|
||||
help="Quantity of packages to order for this product.",
|
||||
related="packaging_id.qty",
|
||||
readonly=True,
|
||||
)
|
||||
days_without_stock = fields.Integer(
|
||||
string="Days without stock",
|
||||
compute="_compute_days_without_stock",
|
||||
readonly=True,
|
||||
)
|
||||
units_scrapped = fields.Float(
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.depends("wizard_id.date_begin", "wizard_id.date_end")
|
||||
def _compute_days_without_stock(self):
|
||||
for rec in self:
|
||||
if rec.product_id:
|
||||
rec.days_without_stock = rec.wizard_id._get_days_out_of_stock(
|
||||
rec.product_id
|
||||
)
|
||||
else:
|
||||
rec.days_without_stock = 0
|
||||
|
||||
@api.onchange("packaging_qty")
|
||||
def _inverse_packaging_qty(self):
|
||||
for rec in self:
|
||||
if rec.packaging_id and rec.packaging_id.qty:
|
||||
rec.units_included = rec.packaging_qty * rec.packaging_id.qty
|
||||
|
||||
@api.depends("packaging_id", "units_included")
|
||||
def _compute_packaging_qty(self):
|
||||
for rec in self:
|
||||
if rec.packaging_id and rec.packaging_id.qty:
|
||||
rec.packaging_qty = int(rec.units_included // rec.packaging_id.qty)
|
||||
else:
|
||||
rec.packaging_qty = 0
|
||||
|
||||
@api.depends("product_id")
|
||||
def _compute_first_packaging_id(self):
|
||||
for rec in self:
|
||||
rec.packaging_id = (
|
||||
rec.product_id.packaging_ids[:1].id
|
||||
if rec.product_id and rec.product_id.packaging_ids
|
||||
else False
|
||||
)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_purchase_order_recommendation_wizard_form_supermarket" model="ir.ui.view">
|
||||
<field name="name">purchase.order.recommendation.wizard.form.supermarket</field>
|
||||
<field name="model">purchase.order.recommendation</field>
|
||||
<field name="inherit_id" ref="purchase_order_product_recommendation.purchase_order_recommendation_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="date_end" position="after">
|
||||
<field name="total_days" />
|
||||
<field name="order_days" widget="numeric_step" />
|
||||
<field name="avg_days_between_orders" />
|
||||
</field>
|
||||
<field name="show_all_products" position="after">
|
||||
<field name="order_by_packages" />
|
||||
<field name="ignore_zero_stock_days" />
|
||||
</field>
|
||||
<field name="units_included" position="before">
|
||||
<field name="units_scrapped" string="Qty scrapped" optional="hide" />
|
||||
<field name="days_without_stock" optional="hide" />
|
||||
<field name="packaging_id" optional="show" />
|
||||
<field name="packaging_contained_qty" string="Packaging Contained Qty" optional="hide" />
|
||||
<field name="packaging_qty" string="Packaging Qty" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue