Skip to content

Commit 5350586

Browse files
committed
[ADD] stock_location_history
1 parent dfea88f commit 5350586

File tree

14 files changed

+349
-0
lines changed

14 files changed

+349
-0
lines changed

stock_location_history/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "Stock Location History",
3+
"version": "18.0.1.0.0",
4+
"license": "AGPL-3",
5+
"author": "Open Source Integrators, Odoo Community Association (OCA)",
6+
"depends": ["stock"],
7+
"category": "Stock",
8+
"data": [
9+
"security/ir.model.access.csv",
10+
"views/stock_location_views.xml",
11+
"views/stock_location_stage_views.xml"
12+
],
13+
"development_status": "Beta",
14+
"maintainers": ["jasiel-OSI"],
15+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import stock_location
2+
from . import stock_location_stage
3+
from . import stock_location_history
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from odoo import models, fields, api
2+
from odoo.exceptions import ValidationError, UserError
3+
from odoo.addons.queue_job.delay import group, chain
4+
5+
from sqlalchemy import text
6+
7+
class StockLocation(models.Model):
8+
_inherit = "stock.location"
9+
10+
track_stage = fields.Boolean(
11+
string="Track location stage?",
12+
default=False,
13+
help="If enabled, the location stages will be tracked."
14+
)
15+
stage_id = fields.Many2one(
16+
"location.stage",
17+
string="Stage"
18+
)
19+
last_stage_id = fields.Many2one(
20+
"location.stage",
21+
string="Last stage"
22+
)
23+
location_history_ids = fields.One2many(
24+
'location.history', 'location_id', string="Location History"
25+
)
26+
last_stage_validated = fields.Boolean(
27+
string="Is the last stage progress validated?"
28+
)
29+
30+
@api.constrains('stage_id')
31+
def check_stage_change(self):
32+
self.ensure_one()
33+
34+
if self.stage_id and not any(g in self.env.user.groups_id for g in self.stage_id.change_group_ids):
35+
raise ValidationError("Stage change not allowed for your user")
36+
37+
if self.past_stage_id and self.past_stage_id.validation and not self.last_stage_validated:
38+
raise ValidationError("Validation required")
39+
40+
if self.stage_id != self.past_stage_id and self.past_stage_id:
41+
if not self.validate_stage_route():
42+
raise ValidationError("Invalid stage change")
43+
else:
44+
if self.stage_id.is_first:
45+
self.create_location_history('free')
46+
elif self.stage_id.is_final:
47+
self.create_location_history('maint')
48+
elif self.stage_id.is_pause:
49+
self.create_location_history('paused')
50+
elif self.stage_id.is_use:
51+
if not self.verifyBDSource():
52+
raise ValidationError("Database not found")
53+
else:
54+
self.with_delay().PLC_Complete()
55+
self.create_location_history('prog')
56+
elif self.past_stage_id.is_first and not self.macrolot_product_id and self.stage_id:
57+
raise ValidationError("Product required")
58+
elif self.past_stage_id.is_first and self.macrolot_product_id:
59+
self.create_new_macrolot()
60+
self.create_location_history('prog')
61+
elif self.past_stage_id.is_pause:
62+
self.create_location_history('reg')
63+
else:
64+
self.create_location_history('prog')
65+
elif not self.past_stage_id and self.stage_id:
66+
self.create_location_history('free')
67+
68+
self.past_stage_id = self.stage_id
69+
70+
if self.stage_id.validation:
71+
self.last_stage_validated = False
72+
else:
73+
self.last_stage_validated = True
74+
75+
@api.constrains('location_history_ids')
76+
def check_last_history_change(self):
77+
last_history = self.env['location.history'].search(
78+
[('location_id', '=', self.id)],
79+
order='create_date desc',
80+
limit=1
81+
)
82+
if not last_history:
83+
self.last_stage_validated = True
84+
else:
85+
if last_history.registry_type == 'val':
86+
self.last_stage_validated = True
87+
88+
def validate_stage_route(self):
89+
if not self.stage_id:
90+
return True
91+
destination_ids = self.last_stage_id.allowed_destination_location_ids
92+
return self.stage_id in destination_ids
93+
94+
def create_location_history(self, type):
95+
history_vals = {
96+
'location_id': self.id,
97+
'before_stage_id': self.past_stage_id.id,
98+
'after_stage_id': self.stage_id.id,
99+
'registry_type': type,
100+
'user_id': self.env.uid,
101+
}
102+
if self.actual_macrolot_id:
103+
history_vals['macrolot_id'] = self.actual_macrolot_id.id
104+
105+
self.env['location.history'].create(history_vals)
106+
107+
def validate_stage(self):
108+
if not any(g in self.env.user.groups_id for g in self.stage_id.validation_group_ids):
109+
raise ValidationError("Stage change not allowed for your user")
110+
else:
111+
self.create_location_history('val')
112+
self.last_stage_validated = True
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from odoo import models, fields
2+
3+
class StockLocationHistory(models.Model):
4+
_name = "stock.location.history"
5+
_description = "Stock Location History"
6+
_order = "registry_date desc"
7+
8+
location_id = fields.Many2one(
9+
'stock.location', string="Location", required=True
10+
)
11+
before_stage_id = fields.Many2one(
12+
"location.stage",
13+
string="Previous Stage"
14+
)
15+
after_stage_id = fields.Many2one(
16+
"location.stage",
17+
string="Next Stage"
18+
)
19+
user_id = fields.Many2one(
20+
"res.users",
21+
string="Performed by"
22+
)
23+
registry_date = fields.Datetime(string="Record date", default=fields.Datetime.now)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from odoo import models, fields
2+
3+
class StockLocationStage(models.Model):
4+
_name = "stock.location.stage"
5+
_description = "Stock Location Stage"
6+
_order = "sequence, name, id"
7+
8+
name = fields.Char(string="Name")
9+
validation = fields.Boolean(string="Requires validation?")
10+
sequence = fields.Integer(default=1)
11+
active = fields.Boolean(help="If active, the stage will be displayed")
12+
fold = fields.Boolean(
13+
"Folded in Kanban",
14+
help="This stage is folded in the kanban view when "
15+
"there are no record in that stage to display.",
16+
)
17+
is_closed = fields.Boolean(
18+
"Is a close stage",
19+
help="Locations in this stage are considered as closed."
20+
)
21+
is_default = fields.Boolean("Is a default stage", help="Used a default stage")
22+
next_ids = fields.Many2many(
23+
'location.stage',
24+
'location_stage_rel',
25+
'stage_id',
26+
'allowed_stage_id',
27+
string='Allowed next stages'
28+
)
29+
is_use = fields.Boolean(
30+
string="Usage stage?",
31+
help="Mark this stage as a usage stage if raw material is being taken from the location"
32+
)
33+
validation_group_ids = fields.Many2many(
34+
"res.groups",
35+
"location_stage_validation_group_rel",
36+
"stage_id",
37+
"group_id",
38+
string="Group allowed to validate",
39+
help="Only users in this group can validate the current stage"
40+
)
41+
change_group_ids = fields.Many2many(
42+
"res.groups",
43+
"location_stage_change_group_rel",
44+
"stage_id",
45+
"group_id",
46+
string="Group allowed to change the current stage",
47+
help="Only users in this group can move the process forward from this stage"
48+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
* Go to Inventory > Configuration > Location Stages.
2+
* Click New to create a stage and configure only the following parameters:
3+
4+
* Name
5+
* Sequence
6+
* Status: Active
7+
* Allowed Validation Groups
8+
* Allowed Stage Change Groups
9+
10+
* Set Stage Properties
11+
* For each stage, specify whether it applies to one of the following categories (these fields are used for form validations):
12+
13+
* Is First
14+
* Is Final
15+
* Is Pause
16+
* Is Use
17+
18+
* Configure Stage Transitions
19+
* After creating all the stages, define the allowed transitions for each stage to establish a proper flow.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* Johannan Luna <jluna@opensourceintegrators.com>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This module allows you to manage stages of location and their history. This
2+
was developed to manage silos and similar storage locations for bulk products.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
* Go to Inventory > Operations > Locations
2+
* Open a location to see its stages and history
3+
* Use the buttons to change the stages of the location
4+
* Based on its stage, the location will be available to receive a new lot of
5+
bulk products or not.

0 commit comments

Comments
 (0)