mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
@@ -46,6 +46,7 @@ class OrderpointTemplate(models.Model):
|
||||
("median", "Most frequent"),
|
||||
("avg", "Average"),
|
||||
("min", "Minimum"),
|
||||
("delivered", "Delivered"),
|
||||
],
|
||||
default="max",
|
||||
help="Select a criteria to auto compute the minimum",
|
||||
@@ -60,6 +61,7 @@ class OrderpointTemplate(models.Model):
|
||||
("median", "Most frequent"),
|
||||
("avg", "Average"),
|
||||
("min", "Minimum"),
|
||||
("delivered", "Delivered"),
|
||||
],
|
||||
help="Select a criteria to auto compute the maximum",
|
||||
)
|
||||
@@ -118,7 +120,13 @@ class OrderpointTemplate(models.Model):
|
||||
self, products, location_id, from_date, to_date, criteria
|
||||
):
|
||||
"""Returns a dict with product ids as keys and the resulting
|
||||
calculation of historic moves according to criteria"""
|
||||
calculation of historic moves according to criteria. If the
|
||||
creteria is delivered we just search how many items were
|
||||
delivered in the given period of time"""
|
||||
if criteria == "delivered":
|
||||
return products._get_delivered_to_customer_dict(
|
||||
location_id, from_date, to_date
|
||||
)
|
||||
stock_qty_history = products._compute_historic_quantities_dict(
|
||||
location_id=location_id, from_date=from_date, to_date=to_date
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
|
||||
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
@@ -49,8 +50,13 @@ class ProductProduct(models.Model):
|
||||
# default the compute the stock value anyway to default the value
|
||||
# for products with no moves for the given period
|
||||
initial_stock = {}
|
||||
# Compute the second before the given date so we don't duplicate
|
||||
# history values in case the given hour is the same than the one
|
||||
# of the first move
|
||||
from_date_stock = from_date - timedelta(seconds=1)
|
||||
to_date_stock = to_date + timedelta(seconds=1)
|
||||
initial_stock = self.with_context(location=location)._compute_quantities_dict(
|
||||
False, False, False, to_date=from_date or to_date
|
||||
False, False, False, to_date=from_date_stock or to_date_stock
|
||||
)
|
||||
product_moves_dict = {}
|
||||
for move in moves:
|
||||
@@ -76,23 +82,47 @@ class ProductProduct(models.Model):
|
||||
# we can compute the stock historical values from the moves
|
||||
# sequence so we can exploit it statisticaly
|
||||
product_moves = OrderedDict(sorted(product_moves.items()))
|
||||
stock = False
|
||||
product_moves_dict[product.id]["stock_history"] = [
|
||||
prod_initial_stock.get("qty_available", 0)
|
||||
]
|
||||
stock = 0
|
||||
first_item = product_moves[next(iter(product_moves))]
|
||||
if from_date:
|
||||
stock = prod_initial_stock.get("qty_available")
|
||||
if not stock:
|
||||
stock = first_item["prod_qty"]
|
||||
first_item["stock"] = stock
|
||||
first_item["stock"] = stock + first_item["prod_qty"]
|
||||
stock = first_item["stock"]
|
||||
iter_moves = iter(product_moves)
|
||||
next(iter_moves, None)
|
||||
for date in iter_moves:
|
||||
stock += product_moves[date]["prod_qty"]
|
||||
product_moves[date]["stock"] = stock
|
||||
product_moves_dict[product.id]["stock_history"] = [
|
||||
product_moves_dict[product.id]["stock_history"] += [
|
||||
v["stock"] for k, v in product_moves.items()
|
||||
]
|
||||
return product_moves_dict
|
||||
|
||||
def _get_delivered_to_customer_dict(
|
||||
self, location=False, from_date=False, to_date=False
|
||||
):
|
||||
"""Returns a dict of products with their delivered qtys for the
|
||||
given dates and locations
|
||||
"""
|
||||
domain = [
|
||||
("product_id", "in", self.ids),
|
||||
("state", "=", "done"),
|
||||
("location_dest_id.usage", "=", "customer"),
|
||||
]
|
||||
if location:
|
||||
domain += [("location_id", "child_of", location.id)]
|
||||
if from_date:
|
||||
domain += [("date", ">=", from_date)]
|
||||
if to_date:
|
||||
domain += [("date", "<=", to_date)]
|
||||
move_lines = self.env["stock.move.line"].read_group(
|
||||
domain, ["product_id", "qty_done"], ["product_id"]
|
||||
)
|
||||
return {p["product_id"][0]: p["qty_done"] for p in move_lines}
|
||||
|
||||
def _compute_historic_quantities_dict(
|
||||
self, location_id=False, from_date=False, to_date=False
|
||||
):
|
||||
|
||||
@@ -318,7 +318,7 @@ class TestOrderpointGenerator(SavepointCase):
|
||||
self.template.write(
|
||||
{
|
||||
"auto_min_qty": True,
|
||||
"auto_min_date_start": "2019-01-01 00:00:00",
|
||||
"auto_min_date_start": "2019-01-01 01:30:00",
|
||||
"auto_min_date_end": "2019-02-01 00:00:00",
|
||||
"auto_min_qty_criteria": "max",
|
||||
}
|
||||
@@ -368,7 +368,7 @@ class TestOrderpointGenerator(SavepointCase):
|
||||
# Auto min max over a shorter period
|
||||
self.template.write(
|
||||
{
|
||||
"auto_max_date_start": "2019-01-01 02:00:00",
|
||||
"auto_max_date_start": "2019-01-01 02:30:00",
|
||||
"auto_max_date_end": "2019-01-01 03:00:00",
|
||||
"auto_min_date_start": "2019-01-01 04:00:00",
|
||||
"auto_min_date_end": "2019-01-01 06:00:00",
|
||||
@@ -378,6 +378,13 @@ class TestOrderpointGenerator(SavepointCase):
|
||||
wizard.action_configure()
|
||||
orderpoint_auto_dict.update({"product_min_qty": 55, "product_max_qty": 50})
|
||||
self.check_orderpoint(self.p1, self.template, orderpoint_auto_dict)
|
||||
# Check delivered
|
||||
self.template.auto_min_qty_criteria = "delivered"
|
||||
self.template.auto_max_qty_criteria = "delivered"
|
||||
wizard = self.wizard_over_products(self.p1, self.template)
|
||||
wizard.action_configure()
|
||||
orderpoint_auto_dict.update({"product_min_qty": 3, "product_max_qty": 5})
|
||||
self.check_orderpoint(self.p1, self.template, orderpoint_auto_dict)
|
||||
|
||||
def test_auto_qty_multi_products(self):
|
||||
"""Each product has a different history"""
|
||||
|
||||
Reference in New Issue
Block a user