purchase_order_product_recommendation_supermarket: calculate by clicking button, instead onchanges. Include order and lines amounts. Last order date for selected vendor.
This commit is contained in:
parent
e2a5a830f3
commit
e72fa0d59d
2 changed files with 94 additions and 12 deletions
|
|
@ -32,6 +32,22 @@ class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
|||
help="Average number of days between orders for this vendor.",
|
||||
readonly=True,
|
||||
)
|
||||
date_last_order = fields.Date(
|
||||
string="Date of last order",
|
||||
compute="_compute_avg_days_between_orders",
|
||||
help="Date of the last order received from the vendor.",
|
||||
readonly=True,
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
related="order_id.currency_id",
|
||||
readonly=True,
|
||||
)
|
||||
order_total_amount = fields.Monetary(
|
||||
string="Order total amount",
|
||||
currency_field="currency_id",
|
||||
compute="_compute_order_total_amount",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.depends("date_begin", "date_end")
|
||||
def _compute_total_days(self):
|
||||
|
|
@ -55,6 +71,8 @@ class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
|||
order="date_order asc",
|
||||
)
|
||||
|
||||
self.date_last_order = orders[-1].effective_date.date() if orders else False
|
||||
|
||||
dates = [o.date_order.date() for o in orders if o.date_order]
|
||||
if len(dates) < 2:
|
||||
self.avg_days_between_orders = 0.0
|
||||
|
|
@ -71,13 +89,28 @@ class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
|||
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):
|
||||
@api.depends("line_ids")
|
||||
def _compute_order_total_amount(self):
|
||||
"""Compute the total amount of the order."""
|
||||
if not self.order_id:
|
||||
self.order_total_amount = 0.0
|
||||
return
|
||||
total_amount = sum(line.subtotal_amount for line in self.line_ids)
|
||||
self.order_total_amount = total_amount
|
||||
|
||||
# Override the method to remove onchange and recalculate only by clicking the button
|
||||
def _generate_recommendations(self):
|
||||
super()._generate_recommendations()
|
||||
|
||||
def regenerate_recommendations(self):
|
||||
self._generate_recommendations()
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"res_model": self._name,
|
||||
"res_id": self.id,
|
||||
"view_mode": "form",
|
||||
"target": "new",
|
||||
}
|
||||
|
||||
def _prepare_wizard_line(self, vals, order_line=False):
|
||||
"""Used to create the wizard line"""
|
||||
|
|
@ -96,9 +129,12 @@ class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
|||
)
|
||||
|
||||
if self.order_days != 0:
|
||||
qty_to_order = (self.order_days * res["units_avg_delivered"]) - res[
|
||||
"units_virtual_available"
|
||||
]
|
||||
qty_to_order = max(
|
||||
0,
|
||||
(self.order_days * res["units_avg_delivered"])
|
||||
- res["units_virtual_available"],
|
||||
)
|
||||
res["units_included_original"] = qty_to_order
|
||||
|
||||
# Adjust qty_to_order to packaging multiples if order_by_packages is checked
|
||||
if self.order_by_packages and product_id.packaging_ids:
|
||||
|
|
@ -146,7 +182,6 @@ class PurchaseOrderRecommendationSupermarketWizard(models.TransientModel):
|
|||
products = products.filtered(
|
||||
lambda x: x.categ_id.id in self.product_category_ids.ids
|
||||
)
|
||||
print(self.product_category_ids)
|
||||
return products
|
||||
|
||||
|
||||
|
|
@ -167,7 +202,6 @@ class PurchaseOrderRecommendationLine(models.TransientModel):
|
|||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
packaging_contained_qty = fields.Float(
|
||||
string="Packaging Quantity Contained",
|
||||
help="Quantity of packages to order for this product.",
|
||||
|
|
@ -182,6 +216,28 @@ class PurchaseOrderRecommendationLine(models.TransientModel):
|
|||
units_scrapped = fields.Float(
|
||||
readonly=True,
|
||||
)
|
||||
subtotal_amount = fields.Monetary(
|
||||
string="Subtotal Amount",
|
||||
compute="_compute_subtotal_amount",
|
||||
readonly=True,
|
||||
)
|
||||
units_included_original = fields.Float(
|
||||
string="Units Included Original",
|
||||
readonly=True,
|
||||
)
|
||||
stock_duration = fields.Float(
|
||||
string="Stock Duration",
|
||||
compute="_compute_stock_duration",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.depends("units_included", "product_id")
|
||||
def _compute_subtotal_amount(self):
|
||||
for rec in self:
|
||||
if rec.product_id and rec.units_included:
|
||||
rec.subtotal_amount = rec.units_included * rec.price_unit
|
||||
else:
|
||||
rec.subtotal_amount = 0.0
|
||||
|
||||
@api.depends("wizard_id.date_begin", "wizard_id.date_end")
|
||||
def _compute_days_without_stock(self):
|
||||
|
|
@ -215,3 +271,12 @@ class PurchaseOrderRecommendationLine(models.TransientModel):
|
|||
if rec.product_id and rec.product_id.packaging_ids
|
||||
else False
|
||||
)
|
||||
|
||||
@api.depends("units_avg_delivered")
|
||||
def _compute_stock_duration(self):
|
||||
for rec in self:
|
||||
rec.stock_duration = (
|
||||
rec.units_virtual_available / rec.units_avg_delivered
|
||||
if rec.units_avg_delivered > 0
|
||||
else 0.0
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,20 +5,37 @@
|
|||
<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">
|
||||
<xpath expr="//sheet" position="before">
|
||||
<header>
|
||||
<button name="regenerate_recommendations"
|
||||
string="Calculate"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-refresh"
|
||||
context="{'no_return_action': True}"/>
|
||||
</header>
|
||||
</xpath>
|
||||
|
||||
<field name="date_end" position="after">
|
||||
<field name="total_days" />
|
||||
<field name="order_days" widget="numeric_step" />
|
||||
<field name="avg_days_between_orders"/>
|
||||
<field name="date_last_order"/>
|
||||
</field>
|
||||
<field name="show_all_products" position="after">
|
||||
<field name="order_by_packages" />
|
||||
<field name="ignore_zero_stock_days" />
|
||||
<field name="order_total_amount" widget="monetary" options="{'currency_field': 'currency_id'}" />
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</field>
|
||||
<field name="units_included" position="before">
|
||||
<field name="units_scrapped" string="Qty scrapped" optional="hide" />
|
||||
<field name="stock_duration" string="Stock Duration" 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="subtotal_amount" string="Subtotal Amount" optional="hide" />
|
||||
<field name="units_included_original" string="Qty needed" optional="hide" />
|
||||
<field name="packaging_qty" string="Packaging Qty" optional="hide" />
|
||||
</field>
|
||||
</field>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue