Browse Source

[8.0] partner tag actions (#152)

* [ADD] partner_event

* simple tests

* remove leftover static files, unused

* make surue apply_partner gets called

* fix typos and getters/setters using self instead of record

* rename to tag actions

* finish renaming, complete description with intended usage

* fix rename leftovers

* add date start/end to tree view

* add cron to data, fix detection of active/inactive based on dates

* sort actions for partner apply

* Remove 'done' field which is redundant

* Add a constraint on dates

Start date must precede end date

* Add french translations

* [FIX] Rename leftovers

* [FIX] Fix PEP8
pull/414/merge
Vincent Vinet 8 years ago
committed by Rafael Blasco
parent
commit
099e7eebc4
  1. 56
      partner_tag_actions/README.rst
  2. 5
      partner_tag_actions/__init__.py
  3. 31
      partner_tag_actions/__openerp__.py
  4. 16
      partner_tag_actions/data/partner_action_data.xml
  5. 206
      partner_tag_actions/i18n/fr.po
  6. 210
      partner_tag_actions/i18n/partner_tag_actions.pot
  7. 7
      partner_tag_actions/models/__init__.py
  8. 46
      partner_tag_actions/models/partner.py
  9. 171
      partner_tag_actions/models/partner_action.py
  10. 25
      partner_tag_actions/models/partner_action_type.py
  11. 5
      partner_tag_actions/security/ir.model.access.csv
  12. 22
      partner_tag_actions/security/res_groups_data.xml
  13. BIN
      partner_tag_actions/static/description/icon.png
  14. 5
      partner_tag_actions/tests/__init__.py
  15. 98
      partner_tag_actions/tests/test_partner_action.py
  16. 45
      partner_tag_actions/views/partner_action_type_view.xml
  17. 81
      partner_tag_actions/views/partner_action_view.xml
  18. 25
      partner_tag_actions/views/partner_view.xml

56
partner_tag_actions/README.rst

@ -0,0 +1,56 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3
Partner Tag Actions
===================
This module was written to offer a way to attach and detach tags to a partner
while keeping a history of those changes. Actions may be constrained to a date
range.
The intended usage of this is for organisations wishing to use tags to manage
contacts, and requiring that those tags be automatically added or removed based
on series of pre-determined events.
Usage
=====
To use this module, you need to :
- Create a res.partner
- Create a partner tag action
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/partner-contact/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
`here <https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_tag_actions%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* David Dufresne <david.dufresne@savoirfairelinux.com>
* Vincent Vinet <vincent.vinet@savoirfairelinux.com>
* Mathieu Boldireff <matheu.boldireff@savoirfairelinux.com>
* Bruno JOLIVEAU <bruno.joliveau@savoirfairelinux.com>
* Agathe Mollé <agathe.molle@savoirfairelinux.com>
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 http://odoo-community.org.

5
partner_tag_actions/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models

31
partner_tag_actions/__openerp__.py

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Partner Tag Actions',
'version': '8.0.1.0.0',
'author': 'Savoir-faire Linux, Odoo Community Association (OCA)',
'maintainer': 'Odoo Community Association (OCA)',
'website': 'http://www.savoirfairelinux.com',
'license': 'AGPL-3',
'category': 'General',
'summary': 'Partner Tag Actions',
'depends': [
],
'external_dependencies': {
'python': [],
},
'data': [
'security/res_groups_data.xml',
'security/ir.model.access.csv',
'views/partner_action_type_view.xml',
'views/partner_action_view.xml',
'views/partner_view.xml',
'data/partner_action_data.xml',
],
'demo': [],
'test': [],
'installable': True,
'auto_install': False,
}

16
partner_tag_actions/data/partner_action_data.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record forcecreate="True" id="ir_cron_mail_scheduler_action" model="ir.cron">
<field name="name">Process Actions</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">3</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'partner.action'" name="model"/>
<field eval="'apply_active_actions'" name="function"/>
<field eval="'()'" name="args"/>
</record>
</data>
</openerp>

206
partner_tag_actions/i18n/fr.po

@ -0,0 +1,206 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_tag_actions
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-21 15:54+0000\n"
"PO-Revision-Date: 2015-09-21 12:02-0500\n"
"Last-Translator: Agathe Mollé <agathe.molle@savoirfairelinux.com>\n"
"Language-Team: Savoir-faire Linux <support@savoirfairelinux.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 1.5.4\n"
"Language: fr\n"
"X-Poedit-SourceCharset: UTF-8\n"
#. module: partner_tag_actions
#: model:ir.actions.act_window,name:partner_tag_actions.action_partner_action_type_view
#: model:ir.ui.menu,name:partner_tag_actions.menu_partner_action_type_act
msgid "Action Types"
msgstr "Types d'actions"
#. module: partner_tag_actions
#: code:addons/partner_tag_actions/models/partner.py:42
#: model:ir.actions.act_window,name:partner_tag_actions.action_partner_action_view
#: model:ir.ui.menu,name:partner_tag_actions.menu_partner_action
#: view:partner.action:partner_tag_actions.view_action_form
#: view:res.partner:partner_tag_actions.view_partner_form
#: field:res.partner,action_ids:0
#, python-format
msgid "Actions"
msgstr "Actions"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "Actions done by me"
msgstr "Actions effectuées par moi"
#. module: partner_tag_actions
#: view:partner.action.type:partner_tag_actions.view_partner_action_type_filter
#: field:partner.action.type,is_active:0
msgid "Active"
msgstr "Active"
#. module: partner_tag_actions
#: field:partner.action.type,add_tag:0
msgid "Add Tag"
msgstr "Ajouter l'étiquette"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_action_form
msgid "Confirm"
msgstr "Confirmer"
#. module: partner_tag_actions
#: field:partner.action,create_uid:0 field:partner.action.type,create_uid:0
msgid "Created by"
msgstr "Créé par"
#. module: partner_tag_actions
#: field:partner.action,create_date:0 field:partner.action.type,create_date:0
msgid "Created on"
msgstr "Créé le"
#. module: partner_tag_actions
#: help:partner.action,is_active:0
msgid "Currently active"
msgstr "Actuellement active"
#. module: partner_tag_actions
#: field:partner.action,date:0
msgid "Date"
msgstr "Date"
#. module: partner_tag_actions
#: field:partner.action,details:0
msgid "Details"
msgstr "Détails"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
#: selection:partner.action,state:0
msgid "Done"
msgstr "Fait"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
#: selection:partner.action,state:0
msgid "Draft"
msgstr "Brouillon"
#. module: partner_tag_actions
#: field:partner.action,date_end:0
msgid "End Date"
msgstr "Date de fin"
#. module: partner_tag_actions
#: field:partner.action,id:0 field:partner.action.type,id:0
msgid "ID"
msgstr "ID"
#. module: partner_tag_actions
#: field:partner.action,is_active:0
msgid "Is active"
msgstr "Est active"
#. module: partner_tag_actions
#: field:partner.action,write_uid:0 field:partner.action.type,write_uid:0
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: partner_tag_actions
#: field:partner.action,write_date:0 field:partner.action.type,write_date:0
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "My Actions"
msgstr "Mes actions"
#. module: partner_tag_actions
#: field:partner.action.type,name:0
msgid "Name"
msgstr "Nom"
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_res_partner
#: field:partner.action,partner_id:0
msgid "Partner"
msgstr "Partenaire"
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_partner_action
msgid "Partner Action"
msgstr "Action de partenaire"
#. module: partner_tag_actions
#: model:res.groups,name:partner_tag_actions.group_partner_action_manager
msgid "Partner Action Manager"
msgstr "Gestionnaire d'actions de partenaire"
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_partner_action_type
msgid "Partner Action Type"
msgstr "Type d'actions de partenaire"
#. module: partner_tag_actions
#: model:res.groups,name:partner_tag_actions.group_partner_action_user
msgid "Partner Action User"
msgstr "Utilisateur d'actions de partenaire"
#. module: partner_tag_actions
#: field:partner.action,priority:0 field:partner.action.type,priority:0
msgid "Priority"
msgstr "Priorité"
#. module: partner_tag_actions
#: field:partner.action.type,remove_tag:0
msgid "Remove Tag"
msgstr "Enlever l'étiquette"
#. module: partner_tag_actions
#: view:partner.action.type:partner_tag_actions.view_partner_action_type_filter
msgid "Search Action Types"
msgstr "Rechercher des types d'actions"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "Search Actions"
msgstr "Rechercher des actions"
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_action_form
msgid "Set To Draft"
msgstr "Mettre en brouillon"
#. module: partner_tag_actions
#: field:partner.action,date_start:0
msgid "Start Date"
msgstr "Date de début"
#. module: partner_tag_actions
#: field:partner.action,state:0
msgid "Status"
msgstr "État"
#. module: partner_tag_actions
#: code:addons/partner_tag_actions/models/partner_action.py:73
#, python-format
msgid "The end date cannot precede the start date!"
msgstr "La date de fin ne peut être antérieure à la date de début !"
#. module: partner_tag_actions
#: field:partner.action,action_type:0
msgid "Type"
msgstr "Type"
#. module: partner_tag_actions
#: field:partner.action,user_id:0
msgid "User"
msgstr "Utilisateur"

210
partner_tag_actions/i18n/partner_tag_actions.pot

@ -0,0 +1,210 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_tag_actions
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-21 15:54+0000\n"
"PO-Revision-Date: 2015-09-21 15:54+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: partner_tag_actions
#: model:ir.actions.act_window,name:partner_tag_actions.action_partner_action_type_view
#: model:ir.ui.menu,name:partner_tag_actions.menu_partner_action_type_act
msgid "Action Types"
msgstr ""
#. module: partner_tag_actions
#: code:addons/partner_tag_actions/models/partner.py:42
#: model:ir.actions.act_window,name:partner_tag_actions.action_partner_action_view
#: model:ir.ui.menu,name:partner_tag_actions.menu_partner_action
#: view:partner.action:partner_tag_actions.view_action_form
#: view:res.partner:partner_tag_actions.view_partner_form
#: field:res.partner,action_ids:0
#, python-format
msgid "Actions"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "Actions done by me"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action.type:partner_tag_actions.view_partner_action_type_filter
#: field:partner.action.type,is_active:0
msgid "Active"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action.type,add_tag:0
msgid "Add Tag"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_action_form
msgid "Confirm"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,create_uid:0
#: field:partner.action.type,create_uid:0
msgid "Created by"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,create_date:0
#: field:partner.action.type,create_date:0
msgid "Created on"
msgstr ""
#. module: partner_tag_actions
#: help:partner.action,is_active:0
msgid "Currently active"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,date:0
msgid "Date"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,details:0
msgid "Details"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
#: selection:partner.action,state:0
msgid "Done"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
#: selection:partner.action,state:0
msgid "Draft"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,date_end:0
msgid "End Date"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,id:0
#: field:partner.action.type,id:0
msgid "ID"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,is_active:0
msgid "Is active"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,write_uid:0
#: field:partner.action.type,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,write_date:0
#: field:partner.action.type,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "My Actions"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action.type,name:0
msgid "Name"
msgstr ""
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_res_partner
#: field:partner.action,partner_id:0
msgid "Partner"
msgstr ""
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_partner_action
msgid "Partner Action"
msgstr ""
#. module: partner_tag_actions
#: model:res.groups,name:partner_tag_actions.group_partner_action_manager
msgid "Partner Action Manager"
msgstr ""
#. module: partner_tag_actions
#: model:ir.model,name:partner_tag_actions.model_partner_action_type
msgid "Partner Action Type"
msgstr ""
#. module: partner_tag_actions
#: model:res.groups,name:partner_tag_actions.group_partner_action_user
msgid "Partner Action User"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,priority:0
#: field:partner.action.type,priority:0
msgid "Priority"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action.type,remove_tag:0
msgid "Remove Tag"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action.type:partner_tag_actions.view_partner_action_type_filter
msgid "Search Action Types"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_partner_action_filter
msgid "Search Actions"
msgstr ""
#. module: partner_tag_actions
#: view:partner.action:partner_tag_actions.view_action_form
msgid "Set To Draft"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,date_start:0
msgid "Start Date"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,state:0
msgid "Status"
msgstr ""
#. module: partner_tag_actions
#: code:addons/partner_tag_actions/models/partner_action.py:73
#, python-format
msgid "The end date cannot precede the start date!"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,action_type:0
msgid "Type"
msgstr ""
#. module: partner_tag_actions
#: field:partner.action,user_id:0
msgid "User"
msgstr ""

7
partner_tag_actions/models/__init__.py

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import partner_action_type
from . import partner_action
from . import partner

46
partner_tag_actions/models/partner.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, fields, api, _
class Partner(models.Model):
_inherit = 'res.partner'
@api.multi
def count_actions(self):
for record in self:
record.action_count = len(record.action_ids)
action_count = fields.Integer(compute=count_actions)
action_ids = fields.One2many('partner.action', 'partner_id',
string='Actions')
@api.multi
def button_actions(self):
self.ensure_one()
return {
'name': _('Actions'),
'type': 'ir.actions.act_window',
'res_model': 'partner.action',
'view_type': 'form',
'view_mode': 'tree,form',
'domain': [('partner_id', '=', self.id)],
}
def apply_actions(self):
self.ensure_one()
actions = self.action_ids.filtered(lambda a: a.state == 'done')
actions = actions.sorted(reverse=True)
actions.apply_all()
return True
@api.multi
def write(self, vals):
res = super(Partner, self).write(vals)
if "category_id" in vals and "norecurse" not in self.env.context:
self.with_context(norecurse=True).apply_actions()
return res

171
partner_tag_actions/models/partner_action.py

@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, fields, api, _
from openerp.exceptions import ValidationError
class PartnerAction(models.Model):
_name = 'partner.action'
_description = 'Partner Action'
_order = "priority"
def _get_name(self):
for record in self:
record.name = u"{0} [{1}] {2}".format(
record.date,
record.action_type.name,
record.partner_id.name,
)
# Fields
partner_id = fields.Many2one('res.partner', string='Partner',
required=True, ondelete='cascade')
user_id = fields.Many2one('res.users', string='User',
required=True, readonly=True,
default=lambda self: self.env.user)
name = fields.Char(compute=_get_name)
date = fields.Date('Date', required=True,
default=fields.Date.context_today)
date_start = fields.Date('Start Date',
default=fields.Date.context_today)
date_end = fields.Date('End Date')
details = fields.Text('Details')
state = fields.Selection([('draft', 'Draft'),
('done', 'Done')],
string='Status', required=True,
default='draft')
action_type = fields.Many2one(
'partner.action.type', string='Type', required=True,
default=lambda self: self.env['partner.action.type'].get_default(),
)
is_active = fields.Boolean(help="Currently active")
priority = fields.Integer(related="action_type.priority", store=True)
@api.constrains('date_start', 'date_end')
def check_dates(self):
if self.date_start and self.date_end and \
self.date_start > self.date_end:
raise ValidationError(
_('The end date cannot precede the start date!')
)
# Button actions
@api.multi
def button_confirm(self):
self.write({'state': 'done'})
self.apply_partner()
@api.multi
def button_draft(self):
self.write({'state': 'draft'})
self.apply_partner()
def check_date_active(self):
today = fields.Date.context_today(self)
start = self.date_start or today
end = self.date_end or today
return start <= today <= end
@api.depends('date_start', 'date_end', 'state')
def check_is_active(self, single=False):
"""
Make sure an action is in/active according to its state and
dates, correcting its status as required.
If `single` is True, re-apply partner rules when necessary
"""
if self.state == 'done' and self.check_date_active():
if not self.is_active:
self.is_active = True
elif self.is_active:
self.action_outdated(single=single)
def action_outdated(self, single=False):
"""
Tag action is outdated, revert its changes
if `single` is True, re-apply partner actions
"""
if not self.is_active:
return
self.is_active = False
action = self.action_type
if action.add_tag:
self.partner_id.category_id -= action.add_tag
if not single:
# We re-apply partner actions because this action may have
# prevented another one from applying
self.apply_partner()
return True
# Cron
@api.model
def apply_active_actions(self):
# We may want to limit this to actions that have start/end dates
# around today to pick up changes when appropriate
active_actions = self.search(
[('state', '=', 'done')],
order="partner_id, priority DESC")
return active_actions.apply_all()
@api.multi
def apply_all(self):
""" Apply all actions in the order they are passed """
partner_writes = {}
partners = {}
tag_obj = self.env["res.partner.category"]
# Collect the result of all add/remove tags
for action in self:
action.check_is_active(single=True)
if not action.is_active:
continue
partner = partner_writes.setdefault(action.partner_id.id,
{"+": set(), "-": set()})
partners.setdefault(action.partner_id.id, action.partner_id)
atype = action.action_type
if atype.add_tag:
partner["+"].add(atype.add_tag.id)
partner["-"].discard(atype.add_tag.id)
if atype.remove_tag:
partner["-"].add(atype.remove_tag.id)
partner["+"].discard(atype.remove_tag.id)
# Apply necessary changes to tags
for partner_id, changes in partner_writes.iteritems():
partner = partners[partner_id]
for tag in tag_obj.browse(changes["-"]):
partner.category_id -= tag
for tag in tag_obj.browse(changes["+"]):
partner.category_id |= tag
return True
@api.multi
def apply_partner(self):
partner = self.mapped(lambda x: x.partner_id)
partner.apply_actions()
return True
# Overriden methods to make sure changes are applied
@api.model
@api.returns('self', lambda value: value.id)
def create(self, vals):
res = super(PartnerAction, self).create(vals)
res.apply_partner()
return res
@api.multi
def write(self, vals):
res = super(PartnerAction, self).write(vals)
self.apply_partner()
return res

25
partner_tag_actions/models/partner_action_type.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, fields, api
class PartnerActionType(models.Model):
_name = 'partner.action.type'
_description = 'Partner Action Type'
_order = 'priority'
name = fields.Char('Name', translate=True, required=True)
priority = fields.Integer('Priority', required=True, default=0)
is_active = fields.Boolean('Active', default=True)
add_tag = fields.Many2one('res.partner.category', required=False,
string='Add Tag')
remove_tag = fields.Many2one('res.partner.category', required=False,
string='Remove Tag')
@api.model
def get_default(self):
return self.search([('is_active', '=', True)], limit=1).id

5
partner_tag_actions/security/ir.model.access.csv

@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_partner_action_user,partner.action.user,model_partner_action,group_partner_action_user,1,1,1,0
access_partner_action_manager,partner.action.manager,model_partner_action,group_partner_action_manager,1,1,1,1
access_partner_action_type_user,partner.action.type.user,model_partner_action_type,group_partner_action_user,1,0,0,0
access_partner_action_type_manager,partner.action.type.manager,model_partner_action_type,group_partner_action_manager,1,1,1,1

22
partner_tag_actions/security/res_groups_data.xml

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<record id="group_partner_action_user" model="res.groups">
<field name="name">Partner Action User</field>
<field name="category_id" ref="base.module_category_sale"/>
</record>
<record id="group_partner_action_manager" model="res.groups">
<field name="name">Partner Action Manager</field>
<field name="category_id" ref="base.module_category_sale"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
<field name="implied_ids" eval="[(4, ref('group_partner_action_user'))]"/>
</record>
<record id="base.group_sale_salesman" model="res.groups">
<field name="implied_ids" eval="[(4, ref('group_partner_action_user'))]"/>
</record>
</data>
</openerp>

BIN
partner_tag_actions/static/description/icon.png

After

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

5
partner_tag_actions/tests/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_partner_action

98
partner_tag_actions/tests/test_partner_action.py

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Savoir-faire Linux
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests import TransactionCase
class PartnerActionTest(TransactionCase):
"""
Tests tweaks to res.partner: defaults and case modifications
"""
def setUp(self):
super(PartnerActionTest, self).setUp()
self.partner_obj = self.env["res.partner"]
self.cat_obj = self.env["res.partner.category"]
self.action_obj = self.env["partner.action"]
self.action_type_obj = self.env["partner.action.type"]
self.partner = self.partner_obj.create({
"name": "Monty Python",
})
self.tag_a = self.cat_obj.create({"name": "Tag A"})
self.tag_b = self.cat_obj.create({"name": "Tag B"})
def test_create_done(self):
""" Test that tags are applied when creating """
add_a = self.action_type_obj.create({
"name": "Add A",
"add_tag": self.tag_a.id,
})
self.action_obj.create({
"partner_id": self.partner.id,
"state": "done",
"action_type": add_a.id,
})
self.assertIn(
self.tag_a,
self.partner.category_id,
"Partner should have gotten Tag A")
def test_create_and_done(self):
""" Test that tags are applied when changing their state """
add_a = self.action_type_obj.create({
"name": "Add A",
"add_tag": self.tag_a.id,
})
action = self.action_obj.create({
"partner_id": self.partner.id,
"state": "draft",
"action_type": add_a.id,
})
self.assertNotIn(
self.tag_a,
self.partner.category_id,
"Partner should not have gotten Tag A")
action.write({"state": 'done'})
self.assertIn(
self.tag_a,
self.partner.category_id,
"Partner should have gotten Tag A")
def test_01_priority(self):
""" Test that tags are applied by their priority """
add_a = self.action_type_obj.create({
"name": "Add A, Del B",
"add_tag": self.tag_a.id,
"remove_tag": self.tag_b.id,
"priority": 10,
})
add_b = self.action_type_obj.create({
"name": "Add B, Del A",
"add_tag": self.tag_b.id,
"remove_tag": self.tag_a.id,
"priority": 0,
})
self.action_obj.create({
"partner_id": self.partner.id,
"state": 'done',
"action_type": add_b.id,
})
self.action_obj.create({
"partner_id": self.partner.id,
"state": 'done',
"action_type": add_a.id,
})
self.assertNotIn(
self.tag_a,
self.partner.category_id,
"Partner should not have gotten Tag A")
self.assertIn(
self.tag_b,
self.partner.category_id,
"Partner should have gotten Tag B")

45
partner_tag_actions/views/partner_action_type_view.xml

@ -0,0 +1,45 @@
<?xm version="1.0"?>
<openerp>
<data>
<record id="view_action_type_tree" model="ir.ui.view">
<field name="name">partner.action.type.tree</field>
<field name="model">partner.action.type</field>
<field name="arch" type="xml">
<tree editable="top">
<field name="name"/>
<field name="priority"/>
<field name="is_active"/>
<field name="add_tag" />
<field name="remove_tag" />
</tree>
</field>
</record>
<record id="view_partner_action_type_filter" model="ir.ui.view">
<field name="name">Partner - Actions</field>
<field name="model">partner.action.type</field>
<field name="arch" type="xml">
<search string="Search Action Types">
<field name="name"/>
<filter string="Active" name="active_only"
domain="[('is_active', '=', True)]"/>
</search>
</field>
</record>
<record id="action_partner_action_type_view" model="ir.actions.act_window">
<field name="name">Action Types</field>
<field name="res_model">partner.action.type</field>
<field name="view_id" eval="view_action_type_tree"/>
<field name="search_view_id" ref="view_partner_action_type_filter"/>
</record>
<menuitem
action="action_partner_action_type_view" id="menu_partner_action_type_act"
name="Action Types" sequence="0"
parent="base.menu_base_config"
groups="group_partner_action_manager"/>
</data>
</openerp>

81
partner_tag_actions/views/partner_action_view.xml

@ -0,0 +1,81 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="view_action_form" model="ir.ui.view">
<field name="name">partner.action.form</field>
<field name="model">partner.action</field>
<field name="arch" type="xml">
<form string="Actions">
<header>
<button string="Confirm" name="button_confirm" type="object" states="draft" class="oe_highlight"/>
<button string="Set To Draft" name="button_draft" type="object" states="done"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<field name="partner_id"/>
<field name="date"/>
<field name="user_id"/>
<field name="date_start" />
<field name="date_end" />
<field name="action_type" domain="[('is_active', '=', True)]"/>
<field name="details" width="200"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_action_tree" model="ir.ui.view">
<field name="name">partner.action.tree</field>
<field name="model">partner.action</field>
<field name="arch" type="xml">
<tree>
<field name="partner_id"/>
<field name="date"/>
<field name="date_start" />
<field name="date_end" />
<field name="user_id"/>
<field name="action_type" domain="[('is_active', '=', True)]"/>
<field name="details"/>
<field name="state" readonly="True" />
</tree>
</field>
</record>
<record id="view_partner_action_filter" model="ir.ui.view">
<field name="name">Partner Actions</field>
<field name="model">partner.action</field>
<field name="arch" type="xml">
<search string="Search Actions">
<field name="partner_id"/>
<field name="date"/>
<field name="user_id"/>
<separator/>
<filter string="Draft" name="draft_only"
domain="[('state', '=', 'draft')]"/>
<filter string="Done" name="done_only"
domain="[('state', '=', 'done')]"/>
<separator/>
<filter string="My Actions" name="user_me"
domain="[('user_id', '=', uid)]"
help="Actions done by me"/>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_partner_action_view">
<field name="name">Actions</field>
<field name="res_model">partner.action</field>
<field name="view_mode">tree,form</field>
<field name="view_type">form</field>
<field name="search_view_id" ref="view_partner_action_filter"/>
<field name="context">{'search_default_user_me':1}</field>
</record>
<menuitem name="Actions" id="menu_partner_action" parent="base.menu_sales" sequence="5"
action="action_partner_action_view"
groups="group_partner_action_user,group_partner_action_manager"/>
</data>
</openerp>

25
partner_tag_actions/views/partner_view.xml

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="view_partner_form" model="ir.ui.view" >
<field name="name">Partner Form +Actions</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_right oe_button_box']" position="inside">
<button
class="oe_inline oe_stat_button"
type="object"
context="{
'default_partner_id': id,
}"
name="button_actions"
icon="fa-list">
<field string="Actions" name="action_count" widget="statinfo"/>
</button>
</xpath>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save