Skip to content

Commit

Permalink
[MIG] donation_recurring from v12 to v14
Browse files Browse the repository at this point in the history
Add buttons to suspend/re-activate
Add a red banner on suspended recurring donations
  • Loading branch information
alexis-via committed Feb 28, 2023
1 parent 7c800d3 commit 2194545
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 82 deletions.
2 changes: 0 additions & 2 deletions donation_recurring/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
from . import wizard
10 changes: 6 additions & 4 deletions donation_recurring/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# © 2014-2016 Barroux Abbey (http://www.barroux.org)
# © 2014-2016 Akretion France (Alexis de Lattre <[email protected]>)
# Copyright 2014-2021 Barroux Abbey (http://www.barroux.org)
# Copyright 2014-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
'name': 'Donation Recurring',
'version': '12.0.1.0.0',
'category': 'Accounting & Finance',
'version': '14.0.1.0.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Manage recurring donations',
'author': 'Barroux Abbey, Akretion, Odoo Community Association (OCA)',
Expand All @@ -16,6 +17,7 @@
'data': [
'views/donation.xml',
'wizard/donation_recurring_generate_view.xml',
'security/ir.model.access.csv',
],
'demo': [
'demo/donation_recurring_demo.xml'
Expand Down
11 changes: 6 additions & 5 deletions donation_recurring/demo/donation_recurring_demo.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2014-2016 Barroux Abbey (http://www.barroux.org)
© 2014-2016 Akretion France (Alexis de Lattre <[email protected]>)
Copyright 2014-2021 Barroux Abbey (http://www.barroux.org)
Copyright 2014-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->

<odoo noupdate="1">

<record id="donor_rec1" model="res.partner">
<field name="name">Emilie Legrand</field>
<field name="customer" eval="1"/>
<field name="donor_rank" eval="1"/>
<field name="street">24 chemin des oliviers</field>
<field name="zip">74210</field>
<field name="city">Seythenex</field>
Expand All @@ -20,7 +21,7 @@

<record id="donor_rec2" model="res.partner">
<field name="name">Marie Durand</field>
<field name="customer" eval="1"/>
<field name="donor_rank" eval="1"/>
<field name="street">9 avenue du Général de Lattre</field>
<field name="zip">75017</field>
<field name="city">Paris</field>
Expand All @@ -31,7 +32,7 @@

<record id="donor_rec3" model="res.partner">
<field name="name">Olivier Dumesnil</field>
<field name="customer" eval="1"/>
<field name="donor_rank" eval="1"/>
<field name="street">9 avenue Foch</field>
<field name="zip">92400</field>
<field name="city">Courbevoie</field>
Expand Down
2 changes: 0 additions & 2 deletions donation_recurring/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import donation
54 changes: 30 additions & 24 deletions donation_recurring/models/donation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# © 2014-2016 Barroux Abbey (http://www.barroux.org)
# © 2014-2016 Akretion France (Alexis de Lattre <[email protected]>)
# Copyright 2014-2021 Barroux Abbey (http://www.barroux.org)
# Copyright 2014-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models, fields, api, _
Expand All @@ -15,7 +16,7 @@ class DonationDonation(models.Model):
string='Recurring Template',
copy=False,
index=True,
track_visibility='onchange'
tracking=True,
)
source_recurring_id = fields.Many2one(
'donation.donation',
Expand All @@ -37,38 +38,33 @@ def _check_recurring_donation(self):
for donation in self:
if donation.recurring_template and donation.state != 'draft':
raise ValidationError(_(
"The recurring donation template of '%s' must stay in "
"draft state.") % donation.partner_id.name)
"The recurring donation template %s must stay in "
"draft state.") % donation.number)
if donation.source_recurring_id and donation.recurring_template:
raise ValidationError(_(
"The recurring donation template of '%s' cannot have "
"The recurring donation template %s cannot have "
"a Source Recurring Template")
% donation.partner_id.name)
% donation.number)
if (
donation.recurring_template and
donation.tax_receipt_option == 'each'):
raise ValidationError(_(
"The recurring donation of %s cannot have a tax "
"The recurring donation %s cannot have a tax "
"receipt option 'Each'.")
% donation.partner_id.name)
% donation.number)

@api.depends('state', 'partner_id', 'move_id', 'recurring_template')
def name_get(self):
res = []
for donation in self:
if donation.state == 'draft':
if donation.recurring_template == 'active':
name = _('Recurring Donation of %s') % (
donation.partner_id.name)
elif donation.recurring_template == 'suspended':
name = _('Suspended Recurring Donation of %s') % (
donation.partner_id.name)
else:
name = _('Draft Donation of %s') % donation.partner_id.name
elif donation.state == 'cancel':
name = _('Cancelled Donation of %s') % donation.partner_id.name
if donation.recurring_template == 'active':
name = _('Recurring Donation %s') % (
donation.number)
elif donation.recurring_template == 'suspended':
name = _('Suspended Recurring Donation %s') % (
donation.number)
else:
name = donation.number
name = super(DonationDonation, donation).name_get()[0][1]
res.append((donation.id, name))
return res

Expand All @@ -83,7 +79,17 @@ def recurring_template_change(self):
"the Tax Receipt Option has been changed from Each to "
"Annual. You may want to change it also on the Donor "
"form.")
if not self.recurring_template and self.partner_id:
if self.partner_id.tax_receipt_option != self.tax_receipt_option:
self.tax_receipt_option = self.partner_id.tax_receipt_option
if not self.recurring_template and self.commercial_partner_id:
if self.commercial_partner_id.tax_receipt_option != self.tax_receipt_option:
self.tax_receipt_option = self.commercial_partner_id.tax_receipt_option
return res

def active2suspended(self):
self.ensure_one()
assert self.recurring_template == 'active'
self.write({'recurring_template': 'suspended'})

def suspended2active(self):
self.ensure_one()
assert self.recurring_template == 'suspended'
self.write({'recurring_template': 'active'})
4 changes: 3 additions & 1 deletion donation_recurring/readme/CONFIGURE.rst
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
In the menu Donations > Donations > Recurring Donations, create a
In the menu *Donation > Donations > Recurring Donations*, create a
recurring donation template for each donor that commited to donate
monthly via direct debit.

If a donor ask to suspend it's recurring donation, click on the *Suspend* button. If he later asks to restart his recurring donations, click on the *Re-activate* button.
3 changes: 1 addition & 2 deletions donation_recurring/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
This module handles recurring donations. For example, if you have
setup a donation plan where donors can donate monthly via direct
debit, you can use this module in combination with the module
*account_banking_sepa_direct_debit* to organise your recurring donations
(and you may also use the module *account_direct_debit*).
*account_banking_sepa_direct_debit* to organise your recurring donations.
2 changes: 2 additions & 0 deletions donation_recurring/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_donation_recurring_generate,Full access on donation.recurring.generate wizard,model_donation_recurring_generate,donation.group_donation_user,1,1,1,1
2 changes: 0 additions & 2 deletions donation_recurring/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import test_recurring_donations
36 changes: 18 additions & 18 deletions donation_recurring/tests/test_recurring_donations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016-2018 Akretion France
# Copyright 2016-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

Expand All @@ -14,26 +14,26 @@ class TestDonationRecurring(TransactionCase):
at_install = False
post_install = True

def _load(self, module, *args):
tools.convert_file(
self.cr, module, get_resource_path(module, *args),
{}, 'init', False, 'test', self.registry._assertion_report)

def setUp(self):
super(TestDonationRecurring, self).setUp()
self._load('account', 'test', 'account_minimal_test.xml')

self.bank_journal = self.env.ref('account.bank_journal')
super().setUp()
self.bank_journal = self.env['account.journal'].create({
'type': 'bank',
'name': 'test bank journal',
})
self.payment_mode = self.env['account.payment.mode'].create({
'name': 'test_payment_mode',
'bank_account_link': 'fixed',
'fixed_journal_id': self.bank_journal.id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id,
})
self.product = self.env.ref(
'donation_base.product_product_donation')
self.inkind_product = self.env.ref(
'donation_base.product_product_inkind_donation')
self.ddo = self.env['donation.donation']
self.don_rec1 = self.ddo.create({
'check_total': 30,
'partner_id': self.env.ref('donation_recurring.donor_rec1').id,
'donation_date': time.strftime('%Y-01-01'),
'journal_id': self.bank_journal.id,
'payment_mode_id': self.payment_mode.id,
'tax_receipt_option': 'annual',
'recurring_template': 'active',
'line_ids': [(0, 0, {
Expand All @@ -46,7 +46,7 @@ def setUp(self):
'check_total': 25,
'partner_id': self.env.ref('donation_recurring.donor_rec2').id,
'donation_date': time.strftime('%Y-01-01'),
'journal_id': self.bank_journal.id,
'payment_mode_id': self.payment_mode.id,
'tax_receipt_option': 'annual',
'recurring_template': 'active',
'line_ids': [(0, 0, {
Expand All @@ -59,7 +59,7 @@ def setUp(self):
'check_total': 35,
'partner_id': self.env.ref('donation_recurring.donor_rec3').id,
'donation_date': time.strftime('%Y-01-01'),
'journal_id': self.bank_journal.id,
'payment_mode_id': self.payment_mode.id,
'tax_receipt_option': 'annual',
'recurring_template': 'suspended',
'line_ids': [(0, 0, {
Expand All @@ -77,11 +77,11 @@ def test_donation_recurring(self):
for don_rec in active_don_recs:
self.assertTrue(don_rec.recurring_donation_ids)
don = don_rec.recurring_donation_ids[0]
self.assertEquals(don.state, 'draft')
self.assertEquals(
self.assertEqual(don.state, 'draft')
self.assertEqual(
don.payment_ref,
'Don Abbaye Sainte Madeleine')
self.assertEquals(don.campaign_id, don_rec.campaign_id)
self.assertEqual(don.campaign_id, don_rec.campaign_id)
self.assertFalse(self.don_rec3.recurring_donation_ids)
active_ids = action['domain'][0][2]
wizard_val = self.env['donation.validate'].with_context(
Expand Down
21 changes: 13 additions & 8 deletions donation_recurring/views/donation.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
© 2014-2016 Barroux Abbey (http://www.barroux.org)
© 2014-2016 Akretion France (Alexis de Lattre <[email protected]>)
Copyright 2014-2021 Barroux Abbey (http://www.barroux.org)
Copyright 2014-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->

Expand All @@ -12,7 +13,7 @@
<field name="model">donation.donation</field>
<field name="inherit_id" ref="donation.donation_form"/>
<field name="arch" type="xml">
<group name="other" position="inside">
<group name="other-right" position="inside">
<field name="recurring_template"
attrs="{'invisible': [('source_recurring_id', '!=', False)]}"/>
<field name="source_recurring_id"
Expand All @@ -24,6 +25,13 @@
<field name="recurring_donation_ids" nolabel="1"/>
</page>
</page>
<button name="done2cancel" position="after">
<button name="active2suspended" type="object" string="Suspend" attrs="{'invisible': [('recurring_template', '!=', 'active')]}"/>
<button name="suspended2active" type="object" string="Re-activate" attrs="{'invisible': [('recurring_template', '!=', 'suspended')]}"/>
</button>
<div class="oe_title" position="before">
<widget name="web_ribbon" title="Suspended" bg_color="bg-danger" attrs="{'invisible': [('recurring_template', '!=', 'suspended')]}"/>
</div>
</field>
</record>

Expand All @@ -34,11 +42,8 @@
<field name="arch" type="xml">
<field name="state" position="after">
<field name="recurring_template"
invisible="not context.get('recurring_view')"/>
invisible="not context.get('recurring_view')" widget="badge" decoration-danger="recurring_template == 'suspended'" decoration-info="recurring_template == 'active'"/>
</field>
<xpath expr="/tree" position="attributes">
<attribute name="colors">red:recurring_template=='suspended';blue:state=='draft';purple:state=='cancel'</attribute>
</xpath>
</field>
</record>

Expand Down Expand Up @@ -69,7 +74,7 @@
<record id="donation_recurring_action" model="ir.actions.act_window">
<field name="name">Recurring Donations</field>
<field name="res_model">donation.donation</field>
<field name="view_mode">tree,form,graph</field>
<field name="view_mode">tree,form,pivot,graph</field>
<field name="context">{'default_recurring_template': 'active', 'recurring_view': True}</field>
<field name="domain">[('recurring_template', '!=', False)]</field>
</record>
Expand Down
2 changes: 0 additions & 2 deletions donation_recurring/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import donation_recurring_generate
19 changes: 11 additions & 8 deletions donation_recurring/wizard/donation_recurring_generate.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# © 2014-2016 Barroux Abbey (http://www.barroux.org)
# © 2014-2016 Akretion France (Alexis de Lattre <[email protected]>)
# Copyright 2014-2021 Barroux Abbey (http://www.barroux.org)
# Copyright 2014-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.tools.misc import format_date


class DonationRecurringGenerate(models.TransientModel):
Expand All @@ -16,6 +18,9 @@ class DonationRecurringGenerate(models.TransientModel):
default=fields.Date.context_today
)
payment_ref = fields.Char(string='Payment Reference')
company_id = fields.Many2one(
'res.company', required=True, string='Company',
default=lambda self: self.env.company)

@api.model
def _prepare_donation_default(self, donation):
Expand All @@ -31,25 +36,23 @@ def generate(self):
doo = self.env['donation.donation']
donations = doo.search([
('recurring_template', '=', 'active'),
('company_id', '=', self.env.user.company_id.id)])
('company_id', '=', self.company_id.id)])
new_donation_ids = []
existing_recur_donations = doo.search([
('donation_date', '=', self.date),
('source_recurring_id', '!=', False),
('company_id', '=', self.env.user.company_id.id)])
('company_id', '=', self.company_id.id)])
if existing_recur_donations:
raise UserError(
_('Recurring donations have already been generated for %s.')
% self.date)
% format_date(self.env, self.date))
for donation in donations:
default = self._prepare_donation_default(donation)
new_donation = donation.copy(default=default)
new_donation_ids.append(new_donation.id)
action = self.env.ref('donation.donation_action').read()[0]
action = self.env.ref('donation.donation_action').sudo().read([])[0]
action.update({
'view_mode': 'tree,form,graph',
'domain': [('id', 'in', new_donation_ids)],
'target': 'current',
'limit': 500,
})
return action
Loading

0 comments on commit 2194545

Please sign in to comment.