Skip to content

Commit 78f11d5

Browse files
committed
[WIP] membership changes
1 parent 3489bd1 commit 78f11d5

8 files changed

+129
-37
lines changed
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo noupdate="1">
3+
4+
<record id="ir_cron_revoke_memberships" model="ir.cron">
5+
<field name="name">Membership: Revoke expired memberships</field>
6+
<field name="interval_number">1</field>
7+
<field name="interval_type">days</field>
8+
<field name="nextcall"
9+
eval="(DateTime.now().replace(hour=05, minute=0, second=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')" />
10+
<field name="numbercall">-1</field>
11+
<field name="model_id" ref="model_membership_group_member" />
12+
<field name="state">code</field>
13+
<field name="code">model._cron_revoke_membership()</field>
14+
<field name="active" eval="True" />
15+
</record>
16+
17+
</odoo>

membership_group/menuitems.xml

+7
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@
3030
parent="membership_group.membership_group_reporting_menu"
3131
/>
3232

33+
<menuitem
34+
id="membership_group_future_membership_menu"
35+
name="Membership Future Members"
36+
action="action_membership_group_future_member"
37+
parent="membership_group.membership_group_reporting_menu"
38+
/>
39+
3340
</odoo>

membership_group/models/membership_group.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,37 @@ class MembershipGroup(models.Model):
2828
)
2929
partner_ids_count = fields.Integer("# of Members", compute="_compute_partner_ids")
3030

31+
termination_cycle = fields.Boolean(
32+
help="""
33+
Members from a group with a termination cycle will be
34+
removed from the group on the termination date",
35+
""",
36+
)
37+
next_termination_date = fields.Date(
38+
help="Next termination date for members of this group",
39+
)
40+
3141
@api.depends("name", "parent_id.complete_name")
3242
def _compute_complete_name(self):
3343
for group in self:
3444
if group.parent_id:
35-
group.complete_name = "%s / %s" % (
36-
group.parent_id.complete_name,
37-
group.name,
38-
)
45+
group.complete_name = f"{group.parent_id.complete_name} / {group.name}"
3946
else:
4047
group.complete_name = group.name
4148

4249
@api.depends(
43-
"membership_group_member_ids", "membership_group_member_ids.partner_id"
50+
"membership_group_member_ids",
51+
"membership_group_member_ids.partner_id",
4452
)
4553
def _compute_partner_ids(self):
4654
for group in self:
4755
group.partner_ids = group.membership_group_member_ids.mapped("partner_id")
4856
group.partner_ids_count = len(group.partner_ids)
4957

58+
def _has_termination_cycle(self):
59+
self.ensure_one()
60+
return bool(self.termination_cycle and self.next_termination_date)
61+
5062
def action_open_partner_view(self):
5163
action_name = "membership.action_membership_members"
5264
action_vals = self.env["ir.actions.act_window"]._for_xml_id(action_name)

membership_group/models/membership_group_member.py

+47-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from odoo import fields, models
1+
from odoo import api, fields, models
22

33

44
class MembershipGroupMember(models.Model):
55
_name = "membership.group.member"
66
_description = "Membership Group Member"
77

8+
active = fields.Boolean(default=True)
89
partner_id = fields.Many2one("res.partner", required=True, ondelete="cascade")
910
group_id = fields.Many2one("membership.group", required=True, ondelete="cascade")
1011
wants_to_collaborate = fields.Boolean()
@@ -18,11 +19,55 @@ class MembershipGroupMember(models.Model):
1819
("committee", "Committee"),
1920
],
2021
)
22+
date_from = fields.Date(
23+
default=fields.Date.context_today,
24+
help="Start date of the membership",
25+
)
26+
date_to = fields.Date(
27+
compute="_compute_date_to",
28+
store=True,
29+
readonly=False,
30+
precompute=True,
31+
help="Planned end date of the membership",
32+
)
33+
date_end = fields.Date(
34+
help="End date of the membership",
35+
)
36+
can_revoke_membership = fields.Boolean(compute="_compute_can_revoke_membership")
2137

2238
_sql_constraints = [
2339
(
2440
"partner_group_uniq",
25-
"unique(partner_id, group_id)",
41+
"unique(active, partner_id, group_id)",
2642
"Member already exists for this group!",
2743
)
2844
]
45+
46+
@api.depends("group_id")
47+
def _compute_date_to(self):
48+
for record in self:
49+
if (
50+
not record.date_to
51+
and record.group_id
52+
and record.group_id._has_termination_cycle()
53+
):
54+
record.date_to = record.group_id.next_termination_date
55+
56+
@api.depends("date_to")
57+
def _compute_can_revoke_membership(self):
58+
for record in self:
59+
record.can_revoke_membership = record._can_revoke_membership()
60+
61+
def _can_revoke_membership(self):
62+
self.ensure_one()
63+
return self.date_to < fields.Date.today() if self.date_to else True
64+
65+
def action_revoke_membership(self):
66+
if active_records := self.filtered(lambda x: x.active):
67+
active_records.active = False
68+
active_records.date_end = fields.Date.today()
69+
return True
70+
71+
@api.model
72+
def _cron_revoke_membership(self):
73+
self.search([("date_to", "<", fields.date.today())]).action_revoke_membership()

membership_group/security/ir.model.access.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ access_membership_group_portal,access_membership_group_portal,model_membership_g
44
access_membership_group,access_membership_group,model_membership_group,base.group_user,1,1,1,1
55
access_membership_group_member_public,access_membership_group_member_public,model_membership_group_member,base.group_public,1,0,0,0
66
access_membership_group_member_portal,access_membership_group_member_portal,model_membership_group_member,base.group_portal,1,0,0,0
7-
access_membership_group_member,access_membership_group_member,model_membership_group_member,base.group_user,1,1,1,1
7+
access_membership_group_member,access_membership_group_member,model_membership_group_member,base.group_user,1,1,1,0
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<odoo>
33

44
<record id="membership_group_member_view_tree" model="ir.ui.view">
55
<field name="model">membership.group.member</field>
66
<field name="arch" type="xml">
77
<tree editable="bottom">
8+
<field name="active" invisible="1" />
89
<field name="partner_id" />
910
<field name="group_id" />
10-
<field name="type" />
11-
<field name="wants_to_collaborate" />
11+
<field name="date_from" optional="show" />
12+
<field name="date_to" optional="show" />
13+
<field name="date_end" optional="hide" />
14+
<field name="type" optional="hide" />
15+
<field name="wants_to_collaborate" optional="hide" />
16+
<button type="object" name="action_revoke_membership" string="Revoke"
17+
icon="fa-trash" attrs="{'invisible': [('active','=', False)]}"/>
1218
</tree>
1319
</field>
1420
</record>
@@ -17,24 +23,27 @@
1723
<field name="model">membership.group.member</field>
1824
<field name="arch" type="xml">
1925
<pivot string="Membership Group Members" disable_linking="True">
20-
<field name="partner_id" type="row"/>
21-
<field name="group_id" type="row"/>
22-
<field name="type" type="col"/>
26+
<field name="partner_id" type="row" />
27+
<field name="group_id" type="row" />
28+
<field name="type" type="col" />
2329
</pivot>
2430
</field>
2531
</record>
2632

27-
<record id="membership_group_member_view_search" model="ir.ui.view">
33+
<record id="membership_group_member_view_search" model="ir.ui.view">
2834
<field name="model">membership.group.member</field>
2935
<field name="arch" type="xml">
3036
<search>
3137
<field name="partner_id" />
3238
<field name="group_id" />
3339
<field name="type" />
3440
<group expand="0" name="claims" string="Group By">
35-
<filter string="Partner" name="partner_id" domain="[]" help="Partner" context="{'group_by':'partner_id'}" />
36-
<filter string="Group" name="group_id" domain="[]" help="Group" context="{'group_by':'group_id'}" />
37-
<filter string="Type" name="type" domain="[]" help="Group" context="{'group_by':'type'}" />
41+
<filter string="Partner" name="partner_id" domain="[]" help="Partner"
42+
context="{'group_by':'partner_id'}" />
43+
<filter string="Group" name="group_id" domain="[]" help="Group"
44+
context="{'group_by':'group_id'}" />
45+
<filter string="Type" name="type" domain="[]" help="Group"
46+
context="{'group_by':'type'}" />
3847
</group>
3948
</search>
4049
</field>
@@ -44,5 +53,14 @@
4453
<field name="name">Membership Group Members</field>
4554
<field name="res_model">membership.group.member</field>
4655
<field name="view_mode">tree,pivot</field>
56+
<field name="context">{'active_test': False}</field>
57+
</record>
58+
59+
<record id="action_membership_group_future_member" model="ir.actions.act_window">
60+
<field name="name">Membership Future Members</field>
61+
<field name="res_model">membership.group.member</field>
62+
<field name="view_mode">tree,pivot</field>
63+
<field name="context">{'active_test': False}</field>
4764
</record>
65+
4866
</odoo>

membership_group/views/membership_group_view.xml

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<odoo>
33

44
<record id="membership_group_view_tree" model="ir.ui.view">
@@ -48,20 +48,19 @@
4848
</group>
4949
</group>
5050
<group name="form_body" />
51-
5251
<notebook>
5352
<page string="Membership" name="membership">
54-
<field name="membership_group_member_ids">
55-
<tree editable="top">
56-
<field
57-
name="partner_id"
58-
domain="[('membership_state', 'in', ['invoiced', 'paid', 'free'])]"
59-
/>
60-
</tree>
61-
</field>
53+
<field name="membership_group_member_ids"/>
6254
</page>
6355
<page string="Subgroups">
64-
<field name="child_ids"/>
56+
<field name="child_ids" />
57+
</page>
58+
<page string="Configuration">
59+
<group>
60+
<field name="termination_cycle" widget="boolean_toggle" />
61+
<field name="next_termination_date"
62+
attrs="{'required': [('termination_cycle','=', True)], 'invisible': [('termination_cycle', '=', False)]}" />
63+
</group>
6564
</page>
6665
</notebook>
6766
</sheet>

membership_group/views/res_partner_view.xml

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<odoo>
33

44
<record id="view_partner_form" model="ir.ui.view">
@@ -22,13 +22,7 @@
2222
</xpath>
2323
<xpath expr="//field[@name='member_lines']" position="after">
2424
<group>
25-
<field name="membership_group_member_ids" string="Groups" colspan="4">
26-
<tree editable="bottom">
27-
<field name="group_id"/>
28-
<field name="type" />
29-
<field name="wants_to_collaborate" />
30-
</tree>
31-
</field>
25+
<field name="membership_group_member_ids" string="Groups" colspan="2" />
3226
</group>
3327
</xpath>
3428
</field>

0 commit comments

Comments
 (0)