[MIG][IMP]GOLEM member migration to v10, and better guidelines

This commit is contained in:
Fabien BOURGEOIS 2017-05-01 19:17:53 +02:00
parent be30d16435
commit cbec4b22a6
10 changed files with 1016 additions and 933 deletions

View File

@ -23,9 +23,11 @@
'author': 'Fabien Bourgeois',
'license': 'AGPL-3',
'application': True,
'installable': False,
'installable': True,
'depends': ['golem_base', 'golem_activity', 'golem_season'],
'data': ['views/golem_member_view.xml', 'views/members_menu.xml',
'views/res_partner_view.xml', 'views/number_config.xml',
'data/number_config.xml', 'security/ir.model.access.csv']
'data': ['views/golem_member_views.xml',
'views/res_partner_views.xml',
'views/golem_member_numberconfig_views.xml',
'data/golem_member_numberconfig_data.xml',
'security/ir.model.access.csv']
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,17 +15,21 @@
# 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/>.
""" GOLEM Members """
from odoo import models, fields, api, _
class ResPartner(models.Model):
""" GOLEM Member partner adaptations """
_inherit = 'res.partner'
@api.model
def _get_default_nationality_id(self):
return self.env.ref('base.main_company').country_id
nationality_id = fields.Many2one(default=_get_default_nationality_id)
nationality_id = fields.Many2one('res.country', 'Nationality',
default=_get_default_nationality_id)
country_id = fields.Many2one(default=_get_default_nationality_id)
# Gender overwriting : no need for 'other' choice
@ -37,26 +41,27 @@ class ResPartner(models.Model):
@api.multi
def create_golem_member(self):
""" Member creation from partner form """
self.ensure_one()
gm = self.env['golem.member']
gm.create({'partner_id': self.id})
return True
gm_obj = self.env['golem.member']
gm_obj.create({'partner_id': self[0].id})
class GolemMember(models.Model):
""" GOLEM Member model """
_name = 'golem.member'
_description = 'GOLEM Member'
_inherit = 'mail.thread'
_inherits = {'res.partner': 'partner_id'}
partner_id = fields.Many2one('res.partner', required=True,
partner_id = fields.Many2one('res.partner', required=True, index=True,
ondelete='cascade')
@api.model
def _default_season(self):
""" Get default season """
domain = [('is_default', '=', True)]
return self.env['golem.season'].search(domain)
return self.env['golem.season'].search(domain, limit=1)
number = fields.Char('Member number', store=True, readonly=True)
number_manual = fields.Char('Manual number', size=50, index=True,
@ -78,101 +83,102 @@ class GolemMember(models.Model):
'UNIQUE (number_manual)',
_('This member number has already been used.'))]
@api.one
@api.multi
@api.depends('season_ids')
def _compute_is_current(self):
""" Computes is current according to seasons """
default_s = self._default_season()
self.is_current = default_s in self.season_ids
for member in self:
member.is_current = default_s in member.season_ids
@api.one
@api.multi
@api.depends('number')
def _compute_is_number_manual(self):
conf = self.env['ir.config_parameter']
is_num_man = (conf.get_param('golem_numberconfig_isautomatic') == '0')
self.is_number_manual = is_num_man
@api.one
def _generate_number_perseason(self):
@api.multi
def generate_number_perseason(self):
""" Number generation in case of per season configuration """
res = None
conf = self.env['ir.config_parameter']
member_number_obj = self.env['golem.member.number']
for member in self:
for s in member.season_ids:
for season in member.season_ids:
domain = ['&',
('member_id', '=', member.id),
('season_id', '=', s.id)]
member_num = self.env['golem.member.number']
mn = member_num.search(domain)
if not mn:
s.member_counter += 1
s.write({'member_counter': s.member_counter})
('season_id', '=', season.id)]
member_num = member_number_obj.search(domain)
if not member_num:
season.member_counter += 1
season.write({'member_counter': season.member_counter})
pkey = 'golem_numberconfig_prefix'
pfx = conf.get_param(pkey)
number = pfx + str(s.member_counter)
number = pfx + str(season.member_counter)
data = {'member_id': member.id,
'season_id': s.id,
'season_id': season.id,
'number': number}
mn = member_num.create(data)
if s.is_default:
res = mn.number
member_num = member_number_obj.create(data)
if season.is_default:
res = member_num.number
return res
@api.one
def _generate_number_global(self):
@api.multi
def generate_number_global(self):
""" Number generation in case of global configuration """
self.ensure_one()
conf = self.env['ir.config_parameter']
domain = ['&',
('member_id', '=', self.id),
('member_id', '=', self[0].id),
('season_id', '=', None)]
member_num = self.env['golem.member.number']
mn = member_num.search(domain)
if not mn:
member_number_obj = self.env['golem.member.number']
member_num = member_number_obj.search(domain)
if not member_num:
last = int(conf.get_param('golem_number_counter', 0))
last += 1
conf.set_param('golem_number_counter', str(last))
pfx = conf.get_param('golem_numberconfig_prefix')
number = pfx + str(last)
data = {'member_id': self.id,
data = {'member_id': self[0].id,
'season_id': None,
'number': number}
mn = member_num.create(data)
return mn.number
member_num = member_number_obj.create(data)
return member_num.number
@api.one
def _generate_number(self):
@api.multi
def generate_number(self):
""" Computes number according to pre-existing number and chosen
seasons """
self.ensure_one()
conf = self.env['ir.config_parameter']
if conf.get_param('golem_numberconfig_isautomatic') == '0':
self.number = self.number_manual
else:
if conf.get_param('golem_numberconfig_isperseason') == '1':
mn = self._generate_number_perseason()
for member in self:
if conf.get_param('golem_numberconfig_isautomatic') == '0':
member.number = member.number_manual
else:
mn = self._generate_number_global()
if mn:
self.number = mn[0]
if conf.get_param('golem_numberconfig_isperseason') == '1':
member_num = member.generate_number_perseason()
else:
member_num = member.generate_number_global()
if member_num:
member.number = member_num[0]
@api.model
@api.returns('self', lambda rec: rec.id)
def create(self, values):
""" Number generation after creation """
new_member = super(GolemMember, self).create(values)
new_member._generate_number()
new_member.generate_number()
return new_member
@api.multi
def write(self, values):
""" Number generation after updates """
res = super(GolemMember, self).write(values)
if 'season_ids' in values or 'number_manual' in values:
self._generate_number()
self.generate_number()
return res
class GolemMemberNumber(models.Model):
""" GOLEM Member Numbers """
_name = 'golem.member.number'
_description = 'GOLEM Member Numbers'
@ -185,14 +191,14 @@ class GolemMemberNumber(models.Model):
auto_join=True)
number = fields.Char('Number', index=True, readonly=True)
@api.one
@api.multi
@api.depends('season_id')
def _compute_name(self):
self.name = self.season_id.name
for number in self:
number.name = number.season_id.name
class GolemNumberConfig(models.TransientModel):
""" Configuration for number computing """
_name = 'golem.member.numberconfig'
_description = 'Configuration for number computing'
@ -222,6 +228,7 @@ class GolemNumberConfig(models.TransientModel):
@api.multi
def apply_config(self):
""" Apply new configuration """
self.ensure_one()
conf = self.env['ir.config_parameter']
conf.set_param('golem_numberconfig_isautomatic', self.is_automatic)
@ -230,10 +237,11 @@ class GolemNumberConfig(models.TransientModel):
@api.multi
def apply_recompute(self):
""" Recomputes all member numbers according to new configuration """
self.ensure_one()
self.apply_config()
conf = self.env['ir.config_parameter']
conf.set_param('golem_number_counter', '0')
self.env['golem.member.number'].search([]).unlink()
self.env['golem.season'].search([]).write({'member_counter': 0})
self.env['golem.member'].search([])._generate_number()
self.env['golem.member'].search([]).generate_number()

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Fabien Bourgeois <fabien@yaltik.com>
Copyright 2017 Fabien Bourgeois <fabien@yaltik.com>
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
@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<data>
<!-- Forms -->
<record id="numberconfig_form" model="ir.ui.view">
<record id="golem_member_numberconfig_form" model="ir.ui.view">
<field name="name">GOLEM Member number configuration</field>
<field name="model">golem.member.numberconfig</field>
<field name="arch" type="xml">
@ -50,13 +50,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</record>
<!-- Actions -->
<act_window id="numberconfig_action"
<act_window id="golem_member_numberconfig_action"
name="GOLEM Member Number Config" res_model="golem.member.numberconfig"
view_mode="form" target="new" />
<!-- Menus -->
<menuitem
id="numberconfig_menu" action="numberconfig_action"
parent="base.menu_marketing_config_association" sequence="3"
id="golem_member_numberconfig_menu"
action="golem_member_numberconfig_action"
parent="membership.menu_marketing_config_association" sequence="10"
groups="golem_base.group_golem_manager" />
</data>
</odoo>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Fabien Bourgeois <fabien@yaltik.com>
Copyright 2017 Fabien Bourgeois <fabien@yaltik.com>
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
@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<odoo>
<data>
<!-- Forms -->
<record id="view_form" model="ir.ui.view">
<record id="golem_member_form" model="ir.ui.view">
<field name="name">GOLEM Member Form</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
@ -108,8 +108,78 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</field>
</record>
<!-- Kanban -->
<record model="ir.ui.view" id="golem_member_kanban">
<field name="name">GOLEM Member Kanban view</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
<kanban>
<field name="color" />
<field name="display_name" />
<field name="title" />
<field name="email" />
<field name="phone" />
<field name="mobile" />
<field name="city" />
<field name="country_id" />
<field name="number" />
<field name="season_ids" />
<field name="category_id"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette oe_semantic_html_override">
<a type="open">
<t t-if="record.image_small.raw_value">
<img t-att-src="kanban_image('res.partner', 'image_small', record.id.value)" class="oe_kanban_image"/>
</t>
<t t-if="record.image_small.raw_value === false">
<img t-att-src='_s + "/base/static/src/img/avatar.png"'
class="oe_kanban_image"/>
</t>
</a>
<div class="oe_kanban_details">
<h4 class="oe_partner_heading">
<a type="open"><field name="display_name" /></a>
(N° <field name="number" />)
</h4>
<div class="oe_kanban_partner_categories" />
<div class="oe_kanban_partner_links" />
<field name="season_ids" />
<ul>
<li t-if="record.city.raw_value and !record.country_id.raw_value">
<field name="city" />
</li>
<li t-if="!record.city.raw_value and record.country_id.raw_value">
<field name="country_id" />
</li>
<li t-if="record.city.raw_value and record.country_id.raw_value">
<field name="city" />, <field name="country_id" />
</li>
<li t-if="record.phone.raw_value or record.mobile.raw_value">
<a t-attf-href="tel:#{record.phone.raw_value}">
<field name="phone" />
</a>
<a t-attf-href="tel:#{record.mobile.raw_value}">
<field name="mobile" />
</a>
</li>
<li t-if="record.email.raw_value">
<a t-attf-href="mailto:#{record.email.raw_value}">
<field name="email" />
</a>
</li>
</ul>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Trees -->
<record model="ir.ui.view" id="view_tree">
<record model="ir.ui.view" id="golem_member_tree">
<field name="name">GOLEM Member Tree/List</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
@ -126,7 +196,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</record>
<!-- Searches -->
<record id="view_filter" model="ir.ui.view">
<record id="golem_member_search" model="ir.ui.view">
<field name="name">GOLEM Member Filters</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
@ -155,7 +225,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</record>
<!-- Graphs -->
<record model="ir.ui.view" id="view_graph_golem_member">
<record model="ir.ui.view" id="golem_member_graph">
<field name="name">GOLEM Member Graph</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
@ -166,23 +236,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</record>
<!-- Actions -->
<act_window id="action"
<act_window id="golem_member_action"
name="GOLEM Members"
res_model="golem.member"
view_mode="kanban,tree,form,graph"
context="{'search_default_season_default': True}" />
<act_window id="tags_action_list" name="GOLEM Members Tags"
<act_window id="res_partner_category_action" name="GOLEM Members Tags"
res_model="res.partner.category" view_mode="tree,form" />
<!-- Menu items -->
<menuitem id="membership.menu_membership" name="Members" sequence="5"
parent="membership.menu_association" />
<menuitem id="golem_members_menu" name="GOLEM Members"
parent="membership.menu_membership" sequence="5"
action="action" groups="golem_base.group_golem_user" />
<menuitem id="golem_members_contacts" name="Contacts"
action="golem_member_action" groups="golem_base.group_golem_user" />
<menuitem id="golem_members_menu_contacts" name="Contacts"
parent="membership.menu_membership" sequence="20"
action="contacts.action_contacts" groups="golem_base.group_golem_user" />
<menuitem id="golem_members_menu_tags" name="Member Tags"
parent="base.menu_marketing_config_association" sequence="10"
action="tags_action_list" groups="golem_base.group_golem_manager" />
<menuitem id="res_partner_category_menu" name="Member Tags"
parent="membership.menu_marketing_config_association" sequence="10"
action="res_partner_category_action"
groups="golem_base.group_golem_manager" />
</data>
</odoo>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Fabien Bourgeois <fabien@yaltik.com>
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/>.
-->
<odoo>
<data noupdate="1">
<delete id="membership.menu_members" model="ir.ui.menu" />
</data>
</odoo>

View File

@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Fabien Bourgeois <fabien@yaltik.com>
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/>.
-->
<odoo>
<data>
<!-- Forms -->
<record model="ir.ui.view" id="member_add">
<field name="name">Add information on linked member or member creation into main form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<h1 position="after">
<label for="member_id"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '=', False)]}" />
<field name="member_id" widget="many2one" readonly="True"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '=', False)]}" />
<button type="object" name="create_golem_member"
string="Create a GOLEM member from this contact"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '!=', False)]}" />
</h1>
</field>
</record>
<!-- Kanban -->
<record model="ir.ui.view" id="member_kanban">
<field name="name">GOLEM Member Kanban view</field>
<field name="model">golem.member</field>
<field name="arch" type="xml">
<kanban>
<field name="color" />
<field name="display_name" />
<field name="title" />
<field name="email" />
<field name="phone" />
<field name="mobile" />
<field name="city" />
<field name="country_id" />
<field name="has_image" />
<field name="number" />
<field name="season_ids" />
<field name="category_id"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette oe_semantic_html_override">
<a type="open">
<t t-if="record.has_image.raw_value === true">
<img t-att-src="kanban_image('res.partner', 'image_small', record.id.value)" class="oe_kanban_image"/>
</t>
<t t-if="record.has_image.raw_value === false">
<img t-att-src='_s + "/base/static/src/img/avatar.png"'
class="oe_kanban_image"/>
</t>
</a>
<div class="oe_kanban_details">
<h4 class="oe_partner_heading">
<a type="open"><field name="display_name" /></a>
(N° <field name="number" />)
</h4>
<div class="oe_kanban_partner_categories" />
<div class="oe_kanban_partner_links" />
<field name="season_ids" />
<ul>
<li t-if="record.city.raw_value and !record.country_id.raw_value">
<field name="city" />
</li>
<li t-if="!record.city.raw_value and record.country_id.raw_value">
<field name="country_id" />
</li>
<li t-if="record.city.raw_value and record.country_id.raw_value">
<field name="city" />, <field name="country_id" />
</li>
<li t-if="record.phone.raw_value or record.mobile.raw_value">
<a t-attf-href="tel:#{record.phone.raw_value}">
<field name="phone" />
</a>
<a t-attf-href="tel:#{record.mobile.raw_value}">
<field name="mobile" />
</a>
</li>
<li t-if="record.email.raw_value">
<a t-attf-href="mailto:#{record.email.raw_value}">
<field name="email" />
</a>
</li>
</ul>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Trees -->
<record model="ir.ui.view" id="member_tree">
<field name="name">Add member number to tree</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree" />
<field name="arch" type="xml">
<field name="display_name" position="before">
<field name="member_number" />
</field>
</field>
</record>
<!-- Searches -->
<record model="ir.ui.view" id="member_number_search">
<field name="name">Partner GOLEM Member Number search</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter" />
<field name="arch" type="xml">
<field name="name" position="after">
<field name="member_number" />
</field>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 Fabien Bourgeois <fabien@yaltik.com>
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/>.
-->
<odoo>
<data>
<!-- Forms -->
<record model="ir.ui.view" id="res_partner_form_inherit_golem_member">
<field name="name">Add information on linked member or member creation into main form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<h1 position="after">
<label for="member_id"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '=', False)]}" />
<field name="member_id" widget="many2one" readonly="True"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '=', False)]}" />
<button type="object" name="create_golem_member"
string="Create a GOLEM member from this contact"
attrs="{'invisible': ['|', ('is_company', '=', True),
('member_id', '!=', False)]}" />
</h1>
</field>
</record>
<!-- Trees -->
<record model="ir.ui.view" id="res_partner_tree_inherit_golem_member">
<field name="name">Add member number to tree</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree" />
<field name="arch" type="xml">
<field name="display_name" position="before">
<field name="member_number" />
</field>
</field>
</record>
<!-- Searches -->
<record model="ir.ui.view" id="res_partner_search_inherit_golem_member">
<field name="name">Partner GOLEM Member Number search</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter" />
<field name="arch" type="xml">
<field name="name" position="after">
<field name="member_number" />
</field>
</field>
</record>
</data>
</odoo>