Browse Source

Merge PR #1192 into 14.0

Signed-off-by rafaelbn
14.0
OCA-git-bot 2 years ago
parent
commit
15c8135bca
  1. 1
      partner_stage/README.rst
  2. 2
      partner_stage/__init__.py
  3. 22
      partner_stage/__manifest__.py
  4. 20
      partner_stage/data/partner_stage_data.xml
  5. 26
      partner_stage/init_hook.py
  6. 25
      partner_stage/migrations/14.0.2.0.0/post-migration.py
  7. 11
      partner_stage/migrations/14.0.2.0.0/pre-migrate.py
  8. 2
      partner_stage/models/__init__.py
  9. 28
      partner_stage/models/res_partner.py
  10. 34
      partner_stage/models/res_partner_stage.py
  11. 7
      partner_stage/readme/CONFIGURATION.rst
  12. 1
      partner_stage/readme/CONTRIBUTORS.rst
  13. 2
      partner_stage/readme/DESCRIPTION.rst
  14. 4
      partner_stage/readme/USAGE.rst
  15. 3
      partner_stage/security/ir.model.access.csv
  16. BIN
      partner_stage/static/description/icon.png
  17. 1
      partner_stage/tests/__init__.py
  18. 24
      partner_stage/tests/test_partner_stage.py
  19. 57
      partner_stage/views/res_partner_stage_views.xml
  20. 34
      partner_stage/views/res_partner_views.xml
  21. 1
      setup/partner_stage/odoo/addons/partner_stage
  22. 6
      setup/partner_stage/setup.py

1
partner_stage/README.rst

@ -0,0 +1 @@
Generated

2
partner_stage/__init__.py

@ -0,0 +1,2 @@
from . import models
from .init_hook import post_init_hook

22
partner_stage/__manifest__.py

@ -0,0 +1,22 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
{
"name": "Partner Stage",
"summary": "Add lifecycle Stages to Partners",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/partner-contact",
"category": "Sales/CRM",
"version": "14.0.2.0.0",
"license": "AGPL-3",
"depends": ["contacts"],
"data": [
"security/ir.model.access.csv",
"data/partner_stage_data.xml",
"views/res_partner_stage_views.xml",
"views/res_partner_views.xml",
],
"post_init_hook": "post_init_hook",
"installable": True,
"maintainers": ["dreispt"],
}

20
partner_stage/data/partner_stage_data.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="partner_stage_draft" model="res.partner.stage">
<field name="name">Draft</field>
<field name="state">draft</field>
<field name="sequence">10</field>
</record>
<record id="partner_stage_active" model="res.partner.stage">
<field name="name">Active</field>
<field name="state">confirmed</field>
<field name="sequence">20</field>
<field name="is_default">True</field>
</record>
<record id="partner_stage_inactive" model="res.partner.stage">
<field name="name">Inactive</field>
<field name="state">cancel</field>
<field name="sequence">30</field>
<field name="fold">True</field>
</record>
</odoo>

26
partner_stage/init_hook.py

@ -0,0 +1,26 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
from odoo import SUPERUSER_ID, api
_logger = logging.getLogger(__name__)
def post_init_hook(cr, registry):
"""Set default Stage on partners"""
env = api.Environment(cr, SUPERUSER_ID, {})
Partner = env["res.partner"]
default_stage = Partner._get_default_stage_id()
missing_stages = Partner.search([("stage_id", "=", False)])
if default_stage and missing_stages:
_logger.info("Init stage_id for %d partner records...", len(missing_stages))
cr.execute(
"""
UPDATE res_partner
SET stage_id = %(id)s, state = %(state)s
WHERE stage_id IS NULL
""",
{"id": default_stage.id, "state": default_stage.state},
)

25
partner_stage/migrations/14.0.2.0.0/post-migration.py

@ -0,0 +1,25 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
from odoo import SUPERUSER_ID, api
_logger = logging.getLogger(__name__)
def migrate(cr, version):
env = api.Environment(cr, SUPERUSER_ID, {})
stages = env["res.partner.stage"].search([])
for stage in stages:
_logger.info(
"Migrating old state %s to stage_id %s...", stage.state, stage.name
)
cr.execute(
"""
UPDATE res_partner
SET stage_id = %(id)s, state = old_state
WHERE old_state = %(state)s
""",
{"id": stage.id, "state": stage.state},
)

11
partner_stage/migrations/14.0.2.0.0/pre-migrate.py

@ -0,0 +1,11 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.tools.sql import column_exists, rename_column
def migrate(cr, version):
if column_exists(cr, "res_partner", "state"):
if column_exists(cr, "res_partner", "old_state"):
cr.execute("ALTER TABLE res_partner DROP COLUMN old_state")
rename_column(cr, "res_partner", "state", "old_state")

2
partner_stage/models/__init__.py

@ -0,0 +1,2 @@
from . import res_partner_stage
from . import res_partner

28
partner_stage/models/res_partner.py

@ -0,0 +1,28 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
class Partner(models.Model):
_inherit = "res.partner"
@api.model
def _get_default_stage_id(self):
return self.env["res.partner.stage"].search(
[("is_default", "=", True)], limit=1
)
@api.model
def _read_group_stage_id(self, states, domain, order):
return states.search([])
stage_id = fields.Many2one(
comodel_name="res.partner.stage",
group_expand="_read_group_stage_id",
default=_get_default_stage_id,
index=True,
tracking=True,
)
state = fields.Selection(related="stage_id.state", store=True, readonly=True)

34
partner_stage/models/res_partner_stage.py

@ -0,0 +1,34 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class PartnerStage(models.Model):
_name = "res.partner.stage"
_description = "Contact Stage"
_order = "sequence, id"
name = fields.Char(required=True, translate=True)
code = fields.Char()
sequence = fields.Integer(help="Used to order the stages", default=10)
fold = fields.Boolean()
active = fields.Boolean(default=True)
description = fields.Text(translate=True)
is_default = fields.Boolean("Default state")
state = fields.Selection(
[("draft", "To Approve"), ("confirmed", "Approved"), ("cancel", "Archived")],
string="Related State",
default="confirmed",
)
_sql_constraints = [
("res_partner_stage_code_unique", "UNIQUE(code)", "Stage Code must be unique.")
]
@api.constrains("is_default")
def _check_default(self):
if self.search_count([("is_default", "=", True)]) > 1:
raise ValidationError(_("There should be only one default stage"))

7
partner_stage/readme/CONFIGURATION.rst

@ -0,0 +1,7 @@
To create a new Stage:
#. Navigate to *Contacts > Configuration > Contact Stages*.
#. Create a new record, and set the name, code and a description.
#. The stage order can be modified using teh handle widget, on the list view.

1
partner_stage/readme/CONTRIBUTORS.rst

@ -0,0 +1 @@
* Daniel Reis <dreis@opensourceintegrators.com>

2
partner_stage/readme/DESCRIPTION.rst

@ -0,0 +1,2 @@
Adds stages to Contacts allowing, for example, to setup a lifecycle workflow.
The default stages are: Draft, Active and Inactive.

4
partner_stage/readme/USAGE.rst

@ -0,0 +1,4 @@
Open a Contact form to see the corresponding Stage.
It is visible in the stages bar, at the top right are of the form.
The contact stage can be changed clicking on the stages bar.

3
partner_stage/security/ir.model.access.csv

@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_partner_stage_edit","access_partner_stage_edit","model_res_partner_stage","base.group_system",1,1,1,1
"access_partner_stage_read","access_partner_stage_read","model_res_partner_stage",,1,0,0,0

BIN
partner_stage/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

1
partner_stage/tests/__init__.py

@ -0,0 +1 @@
from . import test_partner_stage

24
partner_stage/tests/test_partner_stage.py

@ -0,0 +1,24 @@
# Copyright 2021 Open Source Integrators
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.exceptions import ValidationError
from odoo.tests.common import SavepointCase
class TestPartnerStage(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.Stage = cls.env["res.partner.stage"]
cls.Partner = cls.env["res.partner"]
def test_01_partner_stage(self):
default_stage = self.env.ref("partner_stage.partner_stage_active")
new_partner = self.Partner.create({"name": "A Partner"})
self.assertTrue(new_partner.stage_id, default_stage)
def test_02_stage_default_constraint(self):
with self.assertRaises(ValidationError) as ctx:
self.Stage.create({"name": "Another Default Stage", "is_default": True})
err_msg = ctx.exception.args[0]
self.assertEqual("There should be only one default stage", err_msg)

57
partner_stage/views/res_partner_stage_views.xml

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_partner_stage_form" model="ir.ui.view">
<field name="model">res.partner.stage</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only" />
<h1>
<field name="name" />
</h1>
</div>
<group name="top">
<group name="left">
<field name="state" />
<field name="code" />
</group>
<group name="right">
<field name="is_default" />
<field name="fold" />
<field name="active" />
</group>
</group>
<field name="description" />
</sheet>
</form>
</field>
</record>
<record id="view_partner_stage_tree" model="ir.ui.view">
<field name="model">res.partner.stage</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle" />
<field name="name" />
<field name="state" />
<field name="code" />
<field name="description" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_partner_stage">
<field name="name">Stage</field>
<field name="res_model">res.partner.stage</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.menu" id="menu_partner_stage">
<field name="name">Contact Stages</field>
<field name="action" ref="action_partner_stage" />
<field name="parent_id" ref="contacts.res_partner_menu_config" />
</record>
</odoo>

34
partner_stage/views/res_partner_views.xml

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<sheet position="before">
<header>
<field
name="stage_id"
widget="statusbar"
options="{'clickable': '1', 'fold_field': 'fold'}"
/>
</header>
</sheet>
</field>
</record>
<record id="view_partner_search" model="ir.ui.view">
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter" />
<field name="arch" type="xml">
<filter name="group_country" position="after">
<filter
name="group_country"
string="Stage"
context="{'group_by': 'stage_id'}"
/>
</filter>
</field>
</record>
</odoo>

1
setup/partner_stage/odoo/addons/partner_stage

@ -0,0 +1 @@
../../../../partner_stage

6
setup/partner_stage/setup.py

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
Loading…
Cancel
Save