Browse Source

PA

master
root 3 years ago
parent
commit
cc84c66e37
7 changed files with 236 additions and 59 deletions
  1. +1
    -0
      __manifest__.py
  2. +2
    -1
      models/__init__.py
  3. +132
    -11
      models/donation.py
  4. +1
    -26
      models/partner.py
  5. +2
    -0
      security/ir.model.access.csv
  6. +1
    -1
      views/address.xml
  7. +97
    -20
      views/donation.xml

+ 1
- 0
__manifest__.py View File

@ -32,6 +32,7 @@
'views/phone.xml', 'views/phone.xml',
'views/partner.xml', 'views/partner.xml',
'views/donation.xml', 'views/donation.xml',
'data/recurring_donation_configuration.xml',
'views/relationship.xml', 'views/relationship.xml',
'views/operation.xml', 'views/operation.xml',
'views/templates.xml', 'views/templates.xml',


+ 2
- 1
models/__init__.py View File

@ -16,4 +16,5 @@ from . import aggregate
from . import duplicate from . import duplicate
from . import template_rf from . import template_rf
from . import donation_tax_receipt from . import donation_tax_receipt
from . import laposte_ref
from . import laposte_ref
from . import res_partner_bank

+ 132
- 11
models/donation.py View File

@ -6,6 +6,12 @@ from datetime import datetime
from werkzeug import utils from werkzeug import utils
import base64 import base64
class opendons_recurring_donation(models.Model):
_name = 'opendons.recurring_donation_configuration'
_description = 'recurring donation management'
generation_day=fields.Integer('Generation day in the month')
limite_days_before=fields.Integer('Limite_days before generation day')
class DonationDonation(models.Model): class DonationDonation(models.Model):
_inherit = 'donation.donation' _inherit = 'donation.donation'
@ -61,6 +67,26 @@ class DonationDonation(models.Model):
ondelete='set null' ondelete='set null'
) )
@api.model
def create(self, vals):
vals['tax_receipt_option']='annual'
res = super(DonationDonation, self).create(vals)
#res.tax_receipt_option='annual'
sepa_payment_method=self.env['account.payment.method'].search([('code','=','sepa_direct_debit')])
if sepa_payment_method:
sepa_payment_mode=self.env['account.payment.mode'].search([('payment_method_id','=',int( sepa_payment_method))])
if sepa_payment_mode:
res.payment_mode_id=sepa_payment_mode.id
else:
raise Warning('Please configure mode sepa payment')
else:
raise Warning('Please configure method sepa payment')
return res
def _default_payment_mode_id(self): def _default_payment_mode_id(self):
#if self.recurring_template=='active': #if self.recurring_template=='active':
@ -96,6 +122,8 @@ class DonationDonation(models.Model):
def generate_recurring_payment(self): def generate_recurring_payment(self):
#self.ensure_one() #self.ensure_one()
doo = self.env["donation.donation"] doo = self.env["donation.donation"]
#chercher les templates de dons récurrents actifs #chercher les templates de dons récurrents actifs
@ -110,6 +138,7 @@ class DonationDonation(models.Model):
#pour chaque template de don récurrent #pour chaque template de don récurrent
#création d'un don si les dates sont bonnes #création d'un don si les dates sont bonnes
for donation in donations: for donation in donations:
generate=True generate=True
existing_recur_donations = doo.search([("source_recurring_id", "=",int(donation.id))]) existing_recur_donations = doo.search([("source_recurring_id", "=",int(donation.id))])
@ -147,19 +176,39 @@ class DonationDonation(models.Model):
new_donation = donation.copy(default=default) new_donation = donation.copy(default=default)
#ajout du don à la collection des dons générés pour affichage #ajout du don à la collection des dons générés pour affichage
new_donation_ids.append(new_donation.id) new_donation_ids.append(new_donation.id)
#mise à jour de la date de dernière génération
donation.lastexecution_date=datetime.now().date()
payment_mode_id=donation.payment_mode_id.id payment_mode_id=donation.payment_mode_id.id
if not new_donation_ids : raise Warning ("aucun don n'a été généré")
#création de l'ordre de paiement SEPA avec tous les dons générés
self.create_direct_debit_payment_order(new_donation_ids,payment_mode_id)
#on teste l'existence d'un ordre de paiement en status brouillon
#si plusieurs, c'est le dernier créé qui sera alimenté
#payorder=self.env['account.payment.order'].search([('state','=','draft')],order='create_date desc', limit=2)
#if payorder[0]:
# payorder_id=self.update_direct_debit_payment_order(new_donation_ids,payment_mode_id,payorder[0])
#sinon création de l'ordre de paiement SEPA avec tous les dons générés
#else:
payorder_id=self.create_direct_debit_payment_order(new_donation_ids,payment_mode_id)
#affichage des dons générés #affichage des dons générés
action = self.env.ref("donation.donation_action").sudo().read([])[0]
# action = self.env.ref("donation.donation_action").sudo().read([])[0]
# action.update(
# {
# "domain": [("id", "in", new_donation_ids)],
# "limit": 500,
# }
# )
action = self.env.ref("account_payment_order.account_payment_order_inbound_action").sudo().read([])[0]
action.update( action.update(
{ {
"domain": [("id", "in", new_donation_ids)],
"limit": 500,
"view_mode": "form",
"view_type":"list",
"res_id": payorder_id if payorder_id else False
} }
) )
#affichage de l'ordre de prélèvement
#action = self.env.ref("account_payment_order.account_payment_order_inbound_action").sudo().read([])[0]
return action return action
def create_direct_debit_payment_order(self,donation_ids,payment_mode_id): def create_direct_debit_payment_order(self,donation_ids,payment_mode_id):
@ -167,9 +216,10 @@ class DonationDonation(models.Model):
an existing draft Direct Debit pay order""" an existing draft Direct Debit pay order"""
apoo = self.env["account.payment.order"].sudo() apoo = self.env["account.payment.order"].sudo()
payorder_vals = {"payment_mode_id": payment_mode_id}
payorder = apoo.create(payorder_vals)
vals={}
vals['payment_mode_id']=payment_mode_id
vals['sepa']=True
payorder = apoo.create(vals)
msg = _( msg = _(
@ -205,8 +255,48 @@ class DonationDonation(models.Model):
break break
if donations:donation.message_post(body=msg) if donations:donation.message_post(body=msg)
return True
return int(payorder.id)
def update_direct_debit_payment_order(self,donation_ids,payment_mode_id,payorder):
payorder_vals = {"payment_mode_id": payment_mode_id}
msg = _(
"A new draft direct debit order "
"<a href=# data-oe-model=account.payment.order "
"data-oe-id=%d>%s</a> has been automatically created"
) % (payorder.id, payorder.name)
# add payment lines
donations=self.env["donation.donation"].search([("id", "in",donation_ids)])
for donation in donations:
#validation du don et génération des écritures comptables
self.validate_donation(donation)
if donation.payment_mode_id.payment_type == "inbound":
#génération de la ligne de paiement dans l'ordre de prélèvement
payment_account_id = (
donation.payment_mode_id.fixed_journal_id.payment_debit_account_id.id
)
for mline in donation.move_id.line_ids:
if mline.account_id.id == payment_account_id:
mline.sudo().create_payment_line_from_move_line(payorder)
break
if donations:donation.message_post(body=msg)
return int(payorder.id)
def validate_donation(self,donations): def validate_donation(self,donations):
check_total = self.env["res.users"].has_group( check_total = self.env["res.users"].has_group(
@ -297,4 +387,35 @@ class DonationDonation(models.Model):
if donation.bank_statement_line_id: if donation.bank_statement_line_id:
donation._reconcile_donation_from_bank_statement() donation._reconcile_donation_from_bank_statement()
donation.partner_id._update_donor_rank() donation.partner_id._update_donor_rank()
return
return
def recurring_donation_action(self):
action = self.env.ref("opendons.donation_recurring_action").sudo().read([])[0]
action.update(
{
"res_model": 'donation.donation',
"name": 'Prélèvements automatiques : mai 2022',
"view_mode": 'tree,form,pivot,graph',
"context": {'default_recurring_template': 'active', 'recurring_view': True,'default_tax_receipt_option':'annual'},
"domain": [('recurring_template', '!=', False)]
}
)
return action
def payment_order_action(self):
payorder=self.env['account.payment.order'].search([('state','=','draft')],order='create_date desc', limit=2)
action = self.env.ref("account_payment_order.account_payment_order_inbound_action").sudo().read([])[0]
action.update(
{
"view_mode": "form",
"view_type":"list",
"res_id": payorder[0].id if payorder[0].id else False
}
)
return action

+ 1
- 26
models/partner.py View File

@ -286,29 +286,4 @@ class partner(models.Model):
raise ValidationError('Invalid mobile') raise ValidationError('Invalid mobile')
class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank'
@api.onchange('acc_number')
def _onchange_acc_number(self):
#validation IBAN
#https://www.regextester.com/115565
if self.acc_number:
regex = re.compile(r'(^(?:(?:IT|SM)\d{2}[A-Z]\d{22}|CY\d{2}[A-Z]\d{23}|NL\d{2}[A-Z]{4}\d{10}|LV\d{2}[A-Z]{4}\d{13}|(?:BG|BH|GB|IE)\d{2}[A-Z]{4}\d{14}|GI\d{2}[A-Z]{4}\d{15}|RO\d{2}[A-Z]{4}\d{16}|KW\d{2}[A-Z]{4}\d{22}|MT\d{2}[A-Z]{4}\d{23}|NO\d{13}|(?:DK|FI|GL|FO)\d{16}|MK\d{17}|(?:AT|EE|KZ|LU|XK)\d{18}|(?:BA|HR|LI|CH|CR)\d{19}|(?:GE|DE|LT|ME|RS)\d{20}|IL\d{21}|(?:AD|CZ|ES|MD|SA)\d{22}|PT\d{23}|(?:BE|IS)\d{24}|(?:FR|MR|MC)\d{25}|(?:AL|DO|LB|PL)\d{26}|(?:AZ|HU)\d{27}|(?:GR|MU)\d{28})$)+')
if not re.fullmatch(regex, self.acc_number):
raise Warning('Invalid IBAN')
@api.constrains('acc_number')
def _onchange_acc_number(self):
#validation IBAN
#https://www.regextester.com/115565
if self.acc_number:
regex = re.compile(r'(^(?:(?:IT|SM)\d{2}[A-Z]\d{22}|CY\d{2}[A-Z]\d{23}|NL\d{2}[A-Z]{4}\d{10}|LV\d{2}[A-Z]{4}\d{13}|(?:BG|BH|GB|IE)\d{2}[A-Z]{4}\d{14}|GI\d{2}[A-Z]{4}\d{15}|RO\d{2}[A-Z]{4}\d{16}|KW\d{2}[A-Z]{4}\d{22}|MT\d{2}[A-Z]{4}\d{23}|NO\d{13}|(?:DK|FI|GL|FO)\d{16}|MK\d{17}|(?:AT|EE|KZ|LU|XK)\d{18}|(?:BA|HR|LI|CH|CR)\d{19}|(?:GE|DE|LT|ME|RS)\d{20}|IL\d{21}|(?:AD|CZ|ES|MD|SA)\d{22}|PT\d{23}|(?:BE|IS)\d{24}|(?:FR|MR|MC)\d{25}|(?:AL|DO|LB|PL)\d{26}|(?:AZ|HU)\d{27}|(?:GR|MU)\d{28})$)+')
if not re.fullmatch(regex, self.acc_number):
raise Warning('Invalid IBAN')

+ 2
- 0
security/ir.model.access.csv View File

@ -34,3 +34,5 @@ access_opendons_duplicate_partner,opendons_duplicate_partner,model_opendons_dupl
access_opendons_template_rf,opendons_template_rf,model_opendons_template_rf,donation.group_donation_manager,1,1,1,1 access_opendons_template_rf,opendons_template_rf,model_opendons_template_rf,donation.group_donation_manager,1,1,1,1
access_opendons_laposte_ref,opendons_laposte_ref,model_opendons_laposte_ref,donation.group_donation_manager,1,1,1,1 access_opendons_laposte_ref,opendons_laposte_ref,model_opendons_laposte_ref,donation.group_donation_manager,1,1,1,1
access_opendons_recurring_donation_configuration,opendons_recurring_donation_configuration,model_opendons_recurring_donation_configuration,donation.group_donation_manager,1,1,1,1

+ 1
- 1
views/address.xml View File

@ -75,7 +75,7 @@
</record> </record>
<!-- actions opening views on models --> <!-- actions opening views on models -->
<record model="ir.actions.act_window" id="partneraddress_action"> <record model="ir.actions.act_window" id="partneraddress_action">


+ 97
- 20
views/donation.xml View File

@ -21,35 +21,49 @@
</xpath> </xpath>
<xpath expr="//field[@name='payment_ref']" position="replace"> <xpath expr="//field[@name='payment_ref']" position="replace">
</xpath> </xpath>
<xpath expr="//label[@for='tax_receipt_option']" position="replace">
</xpath>
<xpath expr="//div[@name='tax_receipt_option']" position="attributes">
<attribute name="invisible">context.get('recurring_view')</attribute>
</xpath>
<xpath expr="//field[@name='payment_mode_id']" position="replace">
<field name="payment_mode_id" invisible="context.get('recurring_view')"/>
</xpath>
<xpath expr="//field[@name='company_id']" position="replace">
<field name="company_id" invisible="context.get('recurring_view')"/>
</xpath>
</field> </field>
</record> </record>
</data> </data>
<record id="opendons_donation_tree" model="ir.ui.view">
<field name="name">opendons.donation.recurring.tree</field>
<field name="model">donation.donation</field>
<field name="inherit_id" ref="donation.donation_tree" />
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field
name="frequency"
invisible="not context.get('recurring_view')"/>
</field>
</field>
</record>
<record id="opendons_donation_tree2" model="ir.ui.view"> <record id="opendons_donation_tree2" model="ir.ui.view">
<field name="name">opendons.donation.recurring.tree</field> <field name="name">opendons.donation.recurring.tree</field>
<field name="model">donation.donation</field> <field name="model">donation.donation</field>
<field name="inherit_id" ref="donation.donation_tree" /> <field name="inherit_id" ref="donation.donation_tree" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="partner_id" position="before">
<field
name="donor_id"/>
</field>
<xpath expr="//field[@name='partner_id']" position="before">
<field name="donor_id"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="after">
<field name="frequency" invisible="not context.get('recurring_view')"/>
</xpath>
<xpath expr="//field[@name='frequency']" position="after">
<field name="lastexecution_date" invisible="not context.get('recurring_view')"/>
</xpath>
</field> </field>
</record> </record>
@ -106,16 +120,79 @@
<field name="state">code</field> <field name="state">code</field>
<field name="code">action=model.generate_recurring_payment()</field> <field name="code">action=model.generate_recurring_payment()</field>
</record> </record>
<record model="ir.actions.server" id="recurring_action_tmp">
<field name="name">resume res_id action</field>
<field name="model_id" ref="opendons.model_donation_donation"/>
<field name="state">code</field>
<field name="code">
action = model.sudo().recurring_donation_action()
</field>
</record>
<record model="ir.actions.server" id="ir_action_payment_order">
<field name="name">Payment order</field>
<field name="model_id" ref="opendons.model_donation_donation"/>
<field name="state">code</field>
<field name="code">
action = model.sudo().payment_order_action()
</field>
</record>
<menuitem id="recurring_donation_top_menu" sequence="15" <menuitem id="recurring_donation_top_menu" sequence="15"
name="Recurring donations" web_icon="opendons,static/description/recurring_donation.png"/>
name="Recurring donations" action="recurring_action_tmp" web_icon="opendons,static/description/recurring_donation.png"/>
<menuitem id="recurring_donation_title_menu" parent="recurring_donation_top_menu" <menuitem id="recurring_donation_title_menu" parent="recurring_donation_top_menu"
sequence="15" name="Recurring donations"/> sequence="15" name="Recurring donations"/>
<menuitem id="recurring_donation_menu" action="donation_recurring_action"
parent="recurring_donation_title_menu" sequence="10"/>
<menuitem id="recurring_generate_menu" action="ir_action_generate_recurring_payment" <menuitem id="recurring_generate_menu" action="ir_action_generate_recurring_payment"
parent="recurring_donation_title_menu" sequence="11"/>
<menuitem id="recurring_payment_order_menu" action="ir_action_payment_order"
parent="recurring_donation_title_menu" sequence="30"/> parent="recurring_donation_title_menu" sequence="30"/>
<menuitem id="recurring_donation_configuration_menu" parent="recurring_donation_top_menu"
sequence="16" name="Configuration"/>
<record model="ir.ui.view" id="opendons.recurring_donation_configuration_list">
<field name="name">opendons.recurring_donation_configuration list</field>
<field name="model">opendons.recurring_donation_configuration</field>
<field name="arch" type="xml">
<tree>
<field name="generation_day"/>
<field name="limite_days_before"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="opendons.recurring_donation_configuration_form">
<field name="name">opendons.recurring_donation_configuration form</field>
<field name="model">opendons.recurring_donation_configuration</field>
<field name="arch" type="xml">
<form>
<group>
<field name="generation_day"/>
<field name="limite_days_before"/>
</group>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_recurring_payment_configuration">
<field name="name">configuration</field>
<field name="res_model">opendons.recurring_donation_configuration</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="recurring_donation_configuration_menu2" action="action_recurring_payment_configuration"
parent="recurring_donation_configuration_menu" sequence="30"/>
</odoo> </odoo>

Loading…
Cancel
Save