forked from OCA/donation
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG] donation_recurring from v12 to v14
Add buttons to suspend/re-activate Add a red banner on suspended recurring donations
- Loading branch information
1 parent
7c800d3
commit 2194545
Showing
14 changed files
with
96 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)', | ||
|
@@ -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' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
|
@@ -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> | ||
|
@@ -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> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, _ | ||
|
@@ -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', | ||
|
@@ -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 | ||
|
||
|
@@ -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'}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). | ||
|
||
|
@@ -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, { | ||
|
@@ -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, { | ||
|
@@ -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, { | ||
|
@@ -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( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). | ||
--> | ||
|
||
|
@@ -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" | ||
|
@@ -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> | ||
|
||
|
@@ -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> | ||
|
||
|
@@ -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> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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): | ||
|
@@ -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): | ||
|
@@ -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 |
Oops, something went wrong.