Skip to content

Commit 12f7a1e

Browse files
committed
[ADD] sale_forecast
1 parent 40e3219 commit 12f7a1e

File tree

9 files changed

+182
-0
lines changed

9 files changed

+182
-0
lines changed

sale_forecast/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

sale_forecast/__manifest__.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2024 Therp BV
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
3+
{
4+
"name": "Sale Forecast",
5+
"summary": "Sale forecast report",
6+
"version": "16.0.1.0.0",
7+
"category": "Generic Modules/Sale",
8+
"author": "Therp BV, Odoo Community Association (OCA)",
9+
"website": "https://github.com/OCA/sale-workflow",
10+
"depends": ["sale", "stock_demand_estimate", "stock_demand_estimate_matrix"],
11+
"data": [
12+
"security/ir.model.access.csv",
13+
"views/date_range.xml",
14+
"views/sale_forecast.xml",
15+
],
16+
"license": "AGPL-3",
17+
}

sale_forecast/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import sale_forecast

sale_forecast/models/sale_forecast.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from odoo import fields, models
2+
3+
4+
class SaleForecast(models.Model):
5+
_name = "sale.forecast"
6+
_inherits = {"stock.demand.estimate": "stock_demand_id"}
7+
_description = "Sale forecast"
8+
9+
stock_demand_id = fields.Many2one(
10+
comodel_name="stock.demand.estimate", required=True, ondelete="cascade"
11+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
access_sale_forecast,sale.forcast,model_sale_forecast,stock.group_stock_user,1,0,0,0
3+
access_sale_forecast_system,sale.forecast.system,model_sale_forecast,stock.group_stock_manager,1,1,1,1

sale_forecast/views/date_range.xml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" ?>
2+
<odoo>
3+
<menuitem
4+
id="date_range_menu"
5+
name="Date Ranges"
6+
parent="sale.menu_sale_config"
7+
action="date_range.date_range_action"
8+
sequence="99"
9+
/>
10+
</odoo>

sale_forecast/views/sale_forecast.xml

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?xml version="1.0" ?>
2+
<odoo>
3+
<record id="sale_forecast_view_tree" model="ir.ui.view">
4+
<field name="name">sale.forecast.tree</field>
5+
<field name="model">sale.forecast</field>
6+
<field name="arch" type="xml">
7+
<tree edit="1" editable="bottom">
8+
<field name="date_range_id" />
9+
<field name="date_from" string="Date From" />
10+
<field name="date_to" string="Date To" />
11+
<field name="product_id" />
12+
<field name="location_id" />
13+
<field name="product_uom_qty" />
14+
<field name="product_uom" />
15+
<field name="product_qty" />
16+
<field name="daily_qty" />
17+
</tree>
18+
</field>
19+
</record>
20+
<record id="sale_forecast_view_form" model="ir.ui.view">
21+
<field name="name">sale.forecast.form</field>
22+
<field name="model">sale.forecast</field>
23+
<field name="arch" type="xml">
24+
<form>
25+
<sheet>
26+
<group>
27+
<group name="dates_read" class="oe_read_only">
28+
<field name="date_from" string="Date From" />
29+
<field name="date_to" string="Date To" />
30+
<field name="duration" string="Duration" />
31+
</group>
32+
<group name="dates_edit" class="oe_edit_only">
33+
<field name="manual_date_from" string="Date From" />
34+
<field name="manual_date_to" string="Date To" />
35+
<field name="manual_duration" string="Duration" />
36+
</group>
37+
<group>
38+
<field name="product_id" />
39+
<field name="location_id" />
40+
<field name="product_uom_qty" />
41+
<field name="product_uom" />
42+
<field name="daily_qty" />
43+
</group>
44+
</group>
45+
</sheet>
46+
</form>
47+
</field>
48+
</record>
49+
<record id="sale_forecast_view_pivot" model="ir.ui.view">
50+
<field name="name">sale.forecast.pivot</field>
51+
<field name="model">sale.forecast</field>
52+
<field name="arch" type="xml">
53+
<pivot string="Sale Forecast">
54+
<field name="product_qty" type="measure" />
55+
<field name="product_id" type="row" />
56+
<field name="date_range_id" type="col" />
57+
<field name="date_from" type="col" />
58+
</pivot>
59+
</field>
60+
</record>
61+
62+
<record id="sale_forecast_view_graph" model="ir.ui.view">
63+
<field name="name">sale.forecast.graph</field>
64+
<field name="model">sale.forecast</field>
65+
<field name="arch" type="xml">
66+
<graph type="bar" stacked="True">
67+
<field name="product_qty" type="measure" />
68+
<field name="date_from" />
69+
<field name="product_id" />
70+
</graph>
71+
</field>
72+
</record>
73+
74+
<record id="sale_forecast_view_search" model="ir.ui.view">
75+
<field name="name">sale.forecast.search</field>
76+
<field name="model">sale.forecast</field>
77+
<field name="arch" type="xml">
78+
<search string="Search Sale Forecast">
79+
<field name="product_id" />
80+
<field name="location_id" />
81+
<field name="date_range_id" />
82+
<separator />
83+
<filter
84+
name="expired"
85+
string="Expired"
86+
domain="[('date_to', '&lt;', context_today().strftime('%Y-%m-%d'))]"
87+
/>
88+
<filter
89+
name="not_expired"
90+
string="Not Expired"
91+
domain="['|', ('date_to', '=', False), ('date_to', '&gt;', context_today().strftime('%Y-%m-%d'))]"
92+
/>
93+
<separator />
94+
<group expand="0" string="Group By">
95+
<filter
96+
string="Product"
97+
name="groupby_product"
98+
domain="[]"
99+
context="{'group_by':'product_id'}"
100+
/>
101+
<filter
102+
string="Location"
103+
name="groupby_location"
104+
domain="[]"
105+
context="{'group_by':'location_id'}"
106+
/>
107+
<filter
108+
string="Date (From)"
109+
name="groupby_date_from"
110+
domain="[]"
111+
context="{'group_by':'date_from'}"
112+
/>
113+
</group>
114+
</search>
115+
</field>
116+
</record>
117+
<record id="sale_forecast_action" model="ir.actions.act_window">
118+
<field name="name">Sale Forecast</field>
119+
<field name="type">ir.actions.act_window</field>
120+
<field name="res_model">sale.forecast</field>
121+
<field name="view_mode">tree,form,pivot,graph</field>
122+
<field name="search_view_id" ref="sale_forecast_view_search" />
123+
<field name="context">{"search_default_not_expired": 1}</field>
124+
</record>
125+
<menuitem
126+
id="sale_forecast_menu"
127+
name="Forecast"
128+
parent="sale.sale_menu_root"
129+
action="sale_forecast_action"
130+
sequence="10"
131+
/>
132+
</odoo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../sale_forecast

setup/sale_forecast/setup.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import setuptools
2+
3+
setuptools.setup(
4+
setup_requires=['setuptools-odoo'],
5+
odoo_addon=True,
6+
)

0 commit comments

Comments
 (0)