-
Notifications
You must be signed in to change notification settings - Fork 5
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
[REF] membership changes #80
base: 16.0
Are you sure you want to change the base?
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 |
---|---|---|
@@ -1 +1,2 @@ | ||
from . import models | ||
from . import wizard |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<odoo noupdate="1"> | ||
|
||
<record id="ir_cron_revoke_memberships" model="ir.cron"> | ||
<field name="name">Membership: Revoke expired memberships</field> | ||
<field name="interval_number">1</field> | ||
<field name="interval_type">days</field> | ||
<field name="nextcall" | ||
eval="(DateTime.now().replace(hour=5, minute=0, second=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')" /> | ||
<field name="numbercall">-1</field> | ||
<field name="model_id" ref="model_membership_group_member" /> | ||
<field name="state">code</field> | ||
<field name="code">model._cron_revoke_membership()</field> | ||
<field name="active" eval="True" /> | ||
</record> | ||
|
||
<record id="ir_cron_revoke_memberships" model="ir.cron"> | ||
<field name="name">Membership: Revoke expired memberships</field> | ||
<field name="interval_number">1</field> | ||
<field name="interval_type">days</field> | ||
<field name="nextcall" | ||
eval="(DateTime.now().replace(hour=5, minute=0, second=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')" /> | ||
<field name="numbercall">-1</field> | ||
<field name="model_id" ref="model_membership_group_member" /> | ||
<field name="state">code</field> | ||
<field name="code">model._cron_revoke_membership()</field> | ||
<field name="active" eval="True" /> | ||
</record> | ||
|
||
</odoo> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from . import membership_group | ||
from . import membership_group_member | ||
from . import membership_vote_snapshot | ||
from . import res_partner |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
from odoo import fields, models | ||
from odoo import api, fields, models | ||
|
||
|
||
class MembershipGroupMember(models.Model): | ||
_name = "membership.group.member" | ||
_description = "Membership Group Member" | ||
|
||
active = fields.Boolean(default=True) | ||
partner_id = fields.Many2one("res.partner", required=True, ondelete="cascade") | ||
group_id = fields.Many2one("membership.group", required=True, ondelete="cascade") | ||
wants_to_collaborate = fields.Boolean() | ||
|
@@ -18,11 +19,55 @@ class MembershipGroupMember(models.Model): | |
("committee", "Committee"), | ||
], | ||
) | ||
date_from = fields.Date( | ||
default=fields.Date.context_today, | ||
help="Start date of the membership", | ||
) | ||
date_to = fields.Date( | ||
compute="_compute_date_to", | ||
store=True, | ||
readonly=False, | ||
precompute=True, | ||
help="Planned end date of the membership", | ||
) | ||
date_end = fields.Date( | ||
help="End date of the membership", | ||
) | ||
can_revoke_membership = fields.Boolean(compute="_compute_can_revoke_membership") | ||
|
||
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'm not sure what this field is used for atm. Left over for development? |
||
_sql_constraints = [ | ||
( | ||
"partner_group_uniq", | ||
"unique(partner_id, group_id)", | ||
"unique(active, partner_id, group_id)", | ||
"Member already exists for this group!", | ||
) | ||
] | ||
|
||
@api.depends("group_id") | ||
def _compute_date_to(self): | ||
for record in self: | ||
if ( | ||
not record.date_to | ||
and record.group_id | ||
and record.group_id._has_termination_cycle() | ||
): | ||
record.date_to = record.group_id.next_termination_date | ||
|
||
@api.depends("date_to") | ||
def _compute_can_revoke_membership(self): | ||
for record in self: | ||
record.can_revoke_membership = record._can_revoke_membership() | ||
|
||
def _can_revoke_membership(self): | ||
self.ensure_one() | ||
return self.date_to < fields.Date.today() if self.date_to else True | ||
|
||
def action_revoke_membership(self): | ||
if active_records := self.filtered(lambda x: x.active): | ||
active_records.active = False | ||
active_records.date_end = fields.Date.today() | ||
return True | ||
|
||
@api.model | ||
def _cron_revoke_membership(self): | ||
self.search([("date_to", "<=", fields.date.today())]).action_revoke_membership() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from odoo import api, fields, models | ||
|
||
|
||
class MembershipVoteSnapshot(models.Model): | ||
_name = "membership.vote.snapshot" | ||
_description = "Membership Vote Snapshot" | ||
rec_name = "partner_id" | ||
|
||
partner_id = fields.Many2one( | ||
"res.partner", | ||
required=True, | ||
readonly=True, | ||
ondelete="restrict", | ||
) | ||
date = fields.Date( | ||
required=True, | ||
readonly=True, | ||
) | ||
|
||
def action_voting_at_date(self): | ||
return { | ||
"res_model": "membership.vote.history", | ||
"views": [[False, "form"]], | ||
"target": "new", | ||
"type": "ir.actions.act_window", | ||
} | ||
|
||
@api.model | ||
def action_create_can_vote_snapshot(self): | ||
voting_members = self.env["res.partner"].search( | ||
[("member_can_vote", "=", True)] | ||
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. When I have voting members in the future or in the past it doesn't work. Is it maybe easier to have a domain which uses date_from and date_end / date_to on membership.group.member? And then in membership.vote.history.open_at_date set the selected date as context variable. |
||
) | ||
today = fields.Date.today() | ||
values = [{"partner_id": member.id, "date": today} for member in voting_members] | ||
self.search([("date", "=", today)]).sudo().unlink() | ||
self.sudo().create(values) | ||
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. Can you remove the sudo here and instead use ir.model.access. I think we can give full rights to the user and add |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<templates id="template" xml:space="preserve"> | ||
|
||
<t t-name="MembershipReport.Buttons" t-inherit="web.ListView.Buttons" t-inherit-mode="primary" owl="1"> | ||
<xpath expr="(//div/*)[last()]" position="after"> | ||
<button type="button" class="btn btn-primary me-2" t-on-click="onClickMembershipVoteAtDate"> | ||
Voting at Date | ||
</button> | ||
<button type="button" class="btn btn-secondary me-2" t-on-click="onClickMembershipVoteRefresh"> | ||
Refresh | ||
</button> | ||
</xpath> | ||
</t> | ||
|
||
</templates> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** @odoo-module */ | ||
|
||
import {ListController} from "@web/views/list/list_controller"; | ||
|
||
export class MembershipReportListController extends ListController { | ||
async onClickMembershipVoteAtDate() { | ||
const context = { | ||
active_model: this.props.resModel, | ||
}; | ||
this.actionService.doAction({ | ||
res_model: "membership.vote.history", | ||
views: [[false, "form"]], | ||
target: "new", | ||
type: "ir.actions.act_window", | ||
context, | ||
}); | ||
} | ||
|
||
async onClickMembershipVoteRefresh() { | ||
await this.orm.call("membership.vote.snapshot", "action_create_can_vote_snapshot", [], {}); | ||
this.actionService.doAction({ | ||
type: "ir.actions.client", | ||
tag: "reload", | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** @odoo-module */ | ||
|
||
import {listView} from "@web/views/list/list_view"; | ||
import {MembershipReportListController} from "./membership_report_list_controller"; | ||
import {registry} from "@web/core/registry"; | ||
|
||
export const MembershipReportListView = { | ||
...listView, | ||
Controller: MembershipReportListController, | ||
buttonTemplate: "MembershipReport.Buttons", | ||
}; | ||
|
||
registry.category("views").add("membership_report_list", MembershipReportListView); |
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.
Duplicate of the above