mirror of
https://github.com/OCA/stock-logistics-reporting.git
synced 2025-02-16 17:13:21 +02:00
[IMP] stock_average_daily_sale: Store the configurations on profile level + add demo
The configurations are now stored on abc profiles. Some demo data are loaded in order to show this module features more easily.
This commit is contained in:
committed by
twalter-c2c
parent
35310da0bc
commit
bc6e262a84
@@ -1 +1 @@
|
||||
from . import models
|
||||
from . import models, wizards
|
||||
|
||||
@@ -13,18 +13,23 @@
|
||||
"sale",
|
||||
"stock_storage_type_putaway_abc",
|
||||
"product_abc_classification",
|
||||
"product_abc_classification_sale_stock",
|
||||
"product_route_mto",
|
||||
"stock_location_zone",
|
||||
],
|
||||
"data": [
|
||||
"security/stock_average_daily_sale_config.xml",
|
||||
"security/stock_average_daily_sale.xml",
|
||||
"security/stock_average_daily_sale_demo.xml",
|
||||
"views/stock_average_daily_sale_config.xml",
|
||||
"views/stock_average_daily_sale.xml",
|
||||
"views/abc_classification_profile.xml",
|
||||
"views/stock_warehouse.xml",
|
||||
"data/ir_cron.xml",
|
||||
],
|
||||
"external_dependencies": {"python": ["freezegun"]},
|
||||
"demo": [
|
||||
"demo/stock_average_daily_sale_config.xml",
|
||||
"demo/stock_move.xml",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
model="stock.average.daily.sale.config"
|
||||
id="stock_average_daily_sale_config_level_a"
|
||||
>
|
||||
<field
|
||||
name="abc_classification_profile_id"
|
||||
ref="product_abc_classification_sale_stock.abc_classification_profile_sale_stock"
|
||||
/>
|
||||
<field name="abc_classification_level">a</field>
|
||||
<field name="period_value">2</field>
|
||||
<field name="period_name">week</field>
|
||||
@@ -17,6 +21,10 @@
|
||||
model="stock.average.daily.sale.config"
|
||||
id="stock_average_daily_sale_config_level_b"
|
||||
>
|
||||
<field
|
||||
name="abc_classification_profile_id"
|
||||
ref="product_abc_classification_sale_stock.abc_classification_profile_sale_stock"
|
||||
/>
|
||||
<field name="abc_classification_level">b</field>
|
||||
<field name="period_value">13</field>
|
||||
<field name="period_name">week</field>
|
||||
@@ -28,6 +36,10 @@
|
||||
model="stock.average.daily.sale.config"
|
||||
id="stock_average_daily_sale_config_level_c"
|
||||
>
|
||||
<field
|
||||
name="abc_classification_profile_id"
|
||||
ref="product_abc_classification_sale_stock.abc_classification_profile_sale_stock"
|
||||
/>
|
||||
<field name="abc_classification_level">c</field>
|
||||
<field name="period_value">26</field>
|
||||
<field name="period_name">week</field>
|
||||
|
||||
7
stock_average_daily_sale/demo/stock_move.xml
Normal file
7
stock_average_daily_sale/demo/stock_move.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2023 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo noupdate="1">
|
||||
|
||||
<function model="stock.average.daily.sale.demo" name="_action_create_data" />
|
||||
</odoo>
|
||||
@@ -1,3 +1,4 @@
|
||||
from . import stock_warehouse # isort:skip
|
||||
from . import stock_average_daily_sale_config # isort:skip
|
||||
from . import stock_average_daily_sale # isort:skip
|
||||
from . import abc_classification_profile
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AbcClassificationProfile(models.Model):
|
||||
|
||||
_inherit = "abc.classification.profile"
|
||||
|
||||
stock_average_daily_sale_config_ids = fields.One2many(
|
||||
comodel_name="stock.average.daily.sale.config",
|
||||
inverse_name="abc_classification_profile_id",
|
||||
string="Average Daily Sale Configurations",
|
||||
)
|
||||
@@ -22,6 +22,11 @@ class StockAverageDailySale(models.Model):
|
||||
_order = "abc_classification_level ASC, product_id ASC"
|
||||
_description = "Average Daily Sale for Products"
|
||||
|
||||
abc_classification_profile_id = fields.Many2one(
|
||||
comodel_name="abc.classification.profile",
|
||||
required=True,
|
||||
index=True,
|
||||
)
|
||||
abc_classification_level = fields.Selection(
|
||||
selection=ABC_SELECTION, required=True, readonly=True, index=True
|
||||
)
|
||||
@@ -282,6 +287,7 @@ class StockAverageDailySale(models.Model):
|
||||
date_to,
|
||||
config_id,
|
||||
abc_classification_level,
|
||||
cfg.abc_classification_profile_id,
|
||||
sale_ok,
|
||||
is_mto,
|
||||
sqty.qty_in_stock as qty_in_stock,
|
||||
|
||||
@@ -13,6 +13,11 @@ class StockAverageDailySaleConfig(models.Model):
|
||||
_name = "stock.average.daily.sale.config"
|
||||
_description = "Average daily sales computation parameters"
|
||||
|
||||
abc_classification_profile_id = fields.Many2one(
|
||||
comodel_name="abc.classification.profile",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
)
|
||||
abc_classification_level = fields.Selection(
|
||||
selection=ABC_SELECTION, required=True, readonly=True
|
||||
)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2021 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record model="ir.model.access" id="stock_average_daily_sale_demo_access_user">
|
||||
<field name="name">stock.average.daily.sale.demo access user</field>
|
||||
<field name="model_id" ref="model_stock_average_daily_sale_demo" />
|
||||
<field name="group_id" ref="base.group_user" />
|
||||
<field name="perm_read" eval="1" />
|
||||
<field name="perm_create" eval="0" />
|
||||
<field name="perm_write" eval="0" />
|
||||
<field name="perm_unlink" eval="0" />
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!-- Copyright 2023 ACSONE SA/NV
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="abc_classification_profile_form_view" model="ir.ui.view">
|
||||
<field
|
||||
name="name"
|
||||
>abc.classification.profile.form (in stock_average_daily_sale)</field>
|
||||
<field name="model">abc.classification.profile</field>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="product_abc_classification.abc_classification_profile_form_view"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="level_ids" position="after">
|
||||
<field name="stock_average_daily_sale_config_ids" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
1
stock_average_daily_sale/wizards/__init__.py
Normal file
1
stock_average_daily_sale/wizards/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import stock_average_daily_sale_demo
|
||||
@@ -0,0 +1,91 @@
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from freezegun import freeze_time
|
||||
|
||||
from odoo import _, api, models
|
||||
from odoo.fields import Date, Datetime
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class StockAverageDailySaleDemo(models.TransientModel):
|
||||
|
||||
_name = "stock.average.daily.sale.demo"
|
||||
_description = "Wizard to populate demo data with past moves for Average Daily Sale"
|
||||
|
||||
def _create_move(self, product, origin_location, qty):
|
||||
suppliers = self.env.ref("stock.stock_location_suppliers")
|
||||
customers = self.env.ref("stock.stock_location_customers")
|
||||
move_obj = self.env["stock.move"]
|
||||
# Create first an incoming move to avoid negative quantities
|
||||
move = move_obj.create(
|
||||
{
|
||||
"product_id": product.id,
|
||||
"name": product.name,
|
||||
"location_id": suppliers.id,
|
||||
"location_dest_id": customers.id,
|
||||
"product_uom_qty": qty,
|
||||
}
|
||||
)
|
||||
move._action_confirm()
|
||||
move._action_assign()
|
||||
move.quantity_done = move.product_uom_qty
|
||||
move._action_done()
|
||||
|
||||
# Create the OUT move
|
||||
move = move_obj.create(
|
||||
{
|
||||
"product_id": product.id,
|
||||
"name": product.name,
|
||||
"location_id": origin_location.id,
|
||||
"location_dest_id": customers.id,
|
||||
"product_uom_qty": qty,
|
||||
"priority": "1",
|
||||
}
|
||||
)
|
||||
return move
|
||||
|
||||
@api.model
|
||||
def _create_movement(self, product):
|
||||
now = Datetime.now()
|
||||
stock = self.env.ref("stock.stock_location_stock")
|
||||
move_1_date = Date.to_string(now - relativedelta(weeks=11))
|
||||
with freeze_time(move_1_date):
|
||||
move = self._create_move(product, stock, 10.0)
|
||||
move._action_confirm()
|
||||
move._action_assign()
|
||||
move.quantity_done = move.product_uom_qty
|
||||
move._action_done()
|
||||
move.priority = "1"
|
||||
move_2_date = Date.to_string(now - relativedelta(weeks=9))
|
||||
with freeze_time(move_2_date):
|
||||
move = self._create_move(product, stock, 12.0)
|
||||
move._action_confirm()
|
||||
move._action_assign()
|
||||
move.quantity_done = move.product_uom_qty
|
||||
move._action_done()
|
||||
move.priority = "1"
|
||||
|
||||
@api.model
|
||||
def _action_create_data(self):
|
||||
"""
|
||||
This is called through an xml function in order to populate
|
||||
demo data with past moves as the report depends on that.
|
||||
"""
|
||||
module = self.env["ir.module.module"].search(
|
||||
[("name", "=", "stock_average_daily_sale"), ("demo", "=", True)]
|
||||
)
|
||||
if not module:
|
||||
_logger.warning(
|
||||
_("You cannot call the _action_create_data() on production database.")
|
||||
)
|
||||
return
|
||||
product = self.env.ref("product.product_product_25")
|
||||
self._create_movement(product)
|
||||
product = self.env.ref("product.product_product_27")
|
||||
self._create_movement(product)
|
||||
|
||||
self.env["stock.average.daily.sale"].refresh_view()
|
||||
Reference in New Issue
Block a user