-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[WIP] Add base_stage_state #368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg | ||
| :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html | ||
| :alt: License: AGPL-3 | ||
|
|
||
| ============================= | ||
| Stage and Stage support Mixin | ||
| ============================= | ||
|
|
||
| This module provides a mixin Abstract class to be used by other models. | ||
| It will add to the Model all the fields relevant to Kanban boards: | ||
|
|
||
| - ``stage_id`` | ||
| - ``state`` | ||
| - ``kanban_state`` | ||
| - ``color`` | ||
|
|
||
|
|
||
| Installation | ||
| ============ | ||
|
|
||
|
|
||
| To make use of it, you need to add it as a dependency to your module, | ||
| and then have your Model inherit from ``base.stage.mixin``. | ||
|
|
||
| The view layer is not provided, so you will also need to add the fields | ||
| to the model's views and create your kanban view, if desired. | ||
|
|
||
|
|
||
| Configuration | ||
| ============= | ||
|
|
||
| To configure this module, you need to: | ||
|
|
||
| - Create "Stage Sets". Each representes a process pipeline to use in a specific model. | ||
| - Create "Stages". Each is a step in a process pipile, and maps to a canonical State. | ||
|
|
||
|
|
||
| Usage | ||
| ===== | ||
|
|
||
| Not applicable. | ||
|
|
||
|
|
||
| .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas | ||
| :alt: Try me on Runbot | ||
| :target: https://runbot.odoo-community.org/runbot/149/8.0 | ||
|
|
||
|
|
||
| Known issues / Roadmap | ||
| ====================== | ||
|
|
||
| * Add UI menu options for the configuration | ||
| * Add stage-related statistics, such as time open or days to close. | ||
|
|
||
|
|
||
| Bug Tracker | ||
| =========== | ||
|
|
||
| Bugs are tracked on `GitHub Issues | ||
| <https://github.com/OCA/server-tools/issues>`_. In case of trouble, please | ||
| check there if your issue has already been reported. If you spotted it first, | ||
| help us smashing it by providing a detailed and welcomed feedback. | ||
|
|
||
| Credits | ||
| ======= | ||
|
|
||
| Images | ||
| ------ | ||
|
|
||
| * Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. | ||
|
|
||
| Contributors | ||
| ------------ | ||
|
|
||
| * Daniel Reis (author) | ||
|
|
||
|
|
||
| Maintainer | ||
| ---------- | ||
|
|
||
| .. image:: https://odoo-community.org/logo.png | ||
| :alt: Odoo Community Association | ||
| :target: https://odoo-community.org | ||
|
|
||
| This module is maintained by the OCA. | ||
|
|
||
| OCA, or the Odoo Community Association, is a nonprofit organization whose | ||
| mission is to support the collaborative development of Odoo features and | ||
| promote its widespread use. | ||
|
|
||
| To contribute to this module, please visit https://odoo-community.org. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # -*- coding: utf-8 -*- | ||
| from . import models |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # -*- coding: utf-8 -*- | ||
| ############################################################################### | ||
| # | ||
| # Copyright (C) 2016 Daniel Reis | ||
| # | ||
| # This program is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU Affero General Public License as | ||
| # published by the Free Software Foundation, either version 3 of the | ||
| # License, or (at your option) any later version. | ||
| # | ||
| # This program is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU Affero General Public License for more details. | ||
| # | ||
| # You should have received a copy of the GNU Affero General Public License | ||
| # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| # | ||
| ############################################################################### | ||
|
|
||
| { | ||
| 'name': 'Stages and States Mixin', | ||
| 'summary': 'Add Stages and Stages to any Model', | ||
| 'version': '8.0.1.0.0', | ||
| 'category': 'Hidden', | ||
| 'author': 'Daniel Reis, Odoo Community Association (OCA)', | ||
| 'license': 'AGPL-3', | ||
| 'depends': ['base'], | ||
| 'data': [ | ||
| 'security/ir.model.access.csv', | ||
| 'views/menu.xml', | ||
| ], | ||
| 'installable': True, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # -*- coding: utf-8 -*- | ||
| from . import base_stage | ||
| from . import base_stage_mixin |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # -*- coding: utf-8 -*- | ||
| # © 2016 Daniel Reis | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
| from openerp import models, fields, api | ||
|
|
||
|
|
||
| class BaseStageSet(models.Model): | ||
| """ | ||
| Organize Stages in Sets | ||
| """ | ||
| _name = 'base.stage.set' | ||
| _description = 'Base Stage Set' | ||
| name = fields.Char(translate=True) | ||
| stage_ids = fields.One2many('base.stage', 'stage_set_id', 'Stages') | ||
|
|
||
|
|
||
| class BaseStage(models.Model): | ||
| _name = 'base.stage' | ||
| _description = 'Generic Stage' | ||
| _order = 'stage_set_id, sequence' | ||
|
|
||
| @api.model | ||
| def _get_states(self): | ||
| return [ | ||
| ('draft', 'New'), | ||
| ('open', 'In Progress'), | ||
| ('pending', 'Pending'), | ||
| ('done', 'Done'), | ||
| ('cancelled', 'Cancelled')] | ||
|
|
||
| @api.model | ||
| def get_default_stage(self, model): | ||
| domain = [('model_id', '=', model), ('fold', '=', False)] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work? I don't see a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're probably right, I'll look at that. |
||
| return self.search(domain, limit=1) | ||
|
|
||
| stage_set_id = fields.Many2one( | ||
| 'base.stage.set', 'Stage Set', required=True) | ||
| sequence = fields.Integer('Sequence', default=1, index=True) | ||
| name = fields.Char('Stage Name', required=True, translate=True) | ||
| description = fields.Text('Description') | ||
| case_default = fields.Boolean( | ||
| 'Default for New Projects', | ||
| help="When checked, this stage will be proposed by default.") | ||
| fold = fields.Boolean( | ||
| 'Folded in Kanban View', | ||
| help='This stage is folded in the kanban view when' | ||
| 'there are no records in that stage to display.') | ||
| state = fields.Selection( | ||
| _get_states, string="State", | ||
| help="Common canonical stages easier to use " | ||
| "in custom business logic.") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # -*- coding: utf-8 -*- | ||
| # © 2016 Daniel Reis | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
|
||
|
|
||
| from openerp import models, fields, api | ||
|
|
||
|
|
||
| class BaseStageMixin(models.AbstractModel): | ||
| _name = "base.stage.mixin" | ||
| _description = "Stage Aware Model" | ||
|
|
||
| @api.model | ||
| def _get_default_stage(self): | ||
| """ Gives default stage_id """ | ||
| return self.env['base.stages'].get_default_stage(self._name) | ||
|
|
||
| stage_id = fields.Many2one( | ||
| 'base.stage', 'Stage', | ||
| track_visibility='always', index=True, | ||
| domain="[('model_name', '=', self._name)]", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not see a field declaration for
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will check that. |
||
| default=_get_default_stage, | ||
| copy=False) | ||
| state = fields.Selection( | ||
| related='stage_id.state', readonly=True, store=True) | ||
|
|
||
| # Kanban fields | ||
| kanban_state = fields.Selection( | ||
| [('normal', 'Normal'), | ||
| ('blocked', 'Blocked'), | ||
| ('done', 'Ready for next stage')], | ||
| 'Kanban State', | ||
| track_visibility='onchange', | ||
| default='normal', | ||
| copy=False, | ||
| help="The kanban state indicates the workflow readiness:\n" | ||
| " * Normal is the default situation\n" | ||
| " * Blocked indicates something is preventing progress\n" | ||
| " * Ready for next stage indicates it is ready" | ||
| " to be pulled to the next stage") | ||
| color = fields.Integer('Color Index') | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we maybe want to add in the KanBan legend fields as well?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was introduced only on 9.0, didn't check if it is easy to replicate it in 8.0.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ohhhh cool I didn't know it was a 9.0 thing, thanks for that clarification. I was just comparing with a vertical medical module I made for the same thing. Roadmap sounds like a good plan; I doubt it's an easy back port. Not sure if it was clear, but I will take on the upgrade to 9.0 if you would like. This is most definitely something I need :) |
||
|
|
||
| @api.multi | ||
| def _read_group_stage_ids(self, domain, | ||
| read_group_order=None, access_rights_uid=None): | ||
| stage_sets = self.mapped('stage_id.stage_set_id') | ||
| domain = [('stage_set_id', 'in', stage_sets)] | ||
| stages = self.stage_ids._search( | ||
| domain, access_rights_uid=access_rights_uid) | ||
| result = [(x.id, x.display_name) for x in stages] | ||
| fold = {x.id: x.fold for x in stages} | ||
| return result, fold | ||
|
|
||
| _group_by_full = { | ||
| 'stage_id': _read_group_stage_ids, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink | ||
| access_stage_user,base.stage.user,model_base_stage,base.group_user,1,0,0,0 | ||
| access_stage_set_user,base.stage.set.user,model_base_stage_set,base.group_user,1,0,0,0 | ||
| access_stage_system,base.stage.system,model_base_stage,base.group_system,1,1,1,1 | ||
| access_stage_set_system,base.stage.set.system,model_base_stage_set,base.group_system,1,1,1,1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a unique validation to avoid naming conflicts between the stage groups? Totally cosmetic, but seems appropriate IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to have.