from odoo import models, fields, api,_
|
|
from odoo.exceptions import UserError, ValidationError,Warning
|
|
from psycopg2 import sql, DatabaseError
|
|
from datetime import date,datetime
|
|
|
|
from werkzeug import utils
|
|
import base64
|
|
import logging
|
|
import csv
|
|
import base64
|
|
import io
|
|
import json
|
|
import re
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
# class PaymentTransaction(models.Model):
|
|
# _inherit = 'payment.transaction'
|
|
|
|
# donation_ids = fields.Many2many('donation.donation', 'donation_transaction_rel', 'transaction_id', 'donation_id',
|
|
# string='Donations', copy=False, readonly=True)
|
|
|
|
# def render_donation_button(self, donation, submit_txt=None, render_values=None):
|
|
# values = {
|
|
# 'partner_id': donation.partner_id.id,
|
|
# 'type': self.type,
|
|
# }
|
|
# if render_values:
|
|
# values.update(render_values)
|
|
# # Not very elegant to do that here but no choice regarding the design.
|
|
# self._log_payment_transaction_sent()
|
|
# return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render(
|
|
# self.reference,
|
|
# donation.amount_total,
|
|
# donation.currency_id.id,
|
|
# values=values,
|
|
# )
|
|
|
|
|
|
|
|
|
|
class DonationDonation(models.Model):
|
|
_inherit = 'donation.donation'
|
|
|
|
invoice_id=fields.Many2one('account.move','invoice')
|
|
transaction_id=fields.Many2one('payment.transaction','payment transaction')
|
|
state_done=fields.Boolean(compute='_compute_donation_state',store=True)
|
|
affectation=fields.Char(compute='_compute_affectation')
|
|
source_import=fields.Char('source import')
|
|
date_import=fields.Date('date import',default=False)
|
|
date_compta=fields.Datetime('date import',default=False)
|
|
# @api.depends('transaction_id.state')
|
|
# def transaction_state(self):
|
|
# _logger.error("onchange_transaction_state")
|
|
# if self.state=='done':
|
|
# if self.donation_ids:
|
|
# for donation_id in donation_ids:
|
|
# _logger.error("donation_id="+str(donation_id))
|
|
# donation=request.env['donation.donation'].sudo().search([('id','=',int(donation_id))])
|
|
# if donation:donation.state='done'
|
|
|
|
# if self.membership_ids:
|
|
# for membership_id in membership_ids:
|
|
# membership=request.env['kalachakra.membership'].sudo().search([('id','=',int(membership_id))])
|
|
# if membership:membership.state='done'
|
|
|
|
def _compute_affectation(self):
|
|
|
|
i=1
|
|
for d in self:
|
|
affectation=''
|
|
for line in d.line_ids:
|
|
if i==1:
|
|
affectation=line.product_id.name
|
|
else:
|
|
affectation=affectation+ ' ' +line.product_id.name
|
|
i=i+1
|
|
d.affectation=affectation
|
|
|
|
@api.depends('invoice_id.payment_state','transaction_id.state')
|
|
def _compute_donation_state(self):
|
|
for d in self:
|
|
if d.invoice_id:
|
|
if d.invoice_id.payment_state=='paid':
|
|
|
|
d.state='done'
|
|
d.state_done=True
|
|
else:
|
|
d.state='draft'
|
|
d.state_done=False
|
|
if d.transaction_id:
|
|
if d.transaction_id.state=='done':
|
|
if d.state!='done':
|
|
d.state='done'
|
|
d.state_done=True
|
|
d.email_confirmation()
|
|
|
|
|
|
def email_confirmation(self):
|
|
|
|
mail_template = self.env['mail.template'].search([('name','=','confirmation_donation')])
|
|
|
|
mail_template.email_to = self.partner_id.email
|
|
|
|
#mail_template.with_context({'end_date':self.end_date}).send_mail(self.id,False)
|
|
mail_template.send_mail(self.id,False)
|
|
|
|
return True
|
|
|
|
def bulk_remove_draft_donation(self):
|
|
payment_transaction=self.env['payment.transaction'].search([('state','=','draft')])
|
|
if payment_transaction:
|
|
for p in payment_transaction:
|
|
if p.donation_ids:
|
|
for d in p.donation_ids:
|
|
#on ne supprime que les dons brouillons
|
|
if d.state=='draft':
|
|
today=date.today()
|
|
b_date = date(d.create_date.year,d.create_date.month, d.create_date.day)
|
|
#b_date = date(2022,8, 12)
|
|
e_date = date(today.year,today.month, today.day)
|
|
diff=e_date-b_date
|
|
|
|
_logger.error("errK2-diff days="+str(diff.days))
|
|
if diff.days>15:self.env['donation.donation'].search([('id','=',int(d.id))]).unlink()
|
|
|
|
#on supprime également les dons brouillon de plus de 15 jours non lié à une retraite, donc sans facture
|
|
donation=self.env['donation.donation'].search([('state','=','draft')])
|
|
if donation:
|
|
for d in donation:
|
|
if not d.invoice_id:
|
|
today=date.today()
|
|
b_date = date(d.create_date.year,d.create_date.month, d.create_date.day)
|
|
e_date = date(today.year,today.month, today.day)
|
|
diff=e_date-b_date
|
|
_logger.error("errK2-diff days m="+str(diff.days))
|
|
if diff.days>15:self.env['donation.donation'].search([('id','=',int(d.id))]).unlink()
|
|
|
|
|
|
|
|
def _get_payment_type(self, tokenize=False):
|
|
self.ensure_one()
|
|
return 'form_save' if tokenize else 'form'
|
|
|
|
def _create_payment_transaction(self, vals):
|
|
'''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the
|
|
current donation fields (e.g. the partner or the currency).
|
|
:param vals: The values to create a new payment.transaction.
|
|
:return: The newly created payment.transaction record.
|
|
'''
|
|
# Ensure the currencies are the same.
|
|
currency = self[0].currency_id
|
|
# if any(so.pricelist_id.currency_id != currency for so in self):
|
|
# raise ValidationError(_('A transaction can\'t be linked to sales orders having different currencies.'))
|
|
|
|
# Ensure the partner are the same.
|
|
partner = self[0].partner_id
|
|
if any(so.partner_id != partner for so in self):
|
|
raise ValidationError(_('A transaction can\'t be linked to sales orders having different partners.'))
|
|
|
|
# Try to retrieve the acquirer. However, fallback to the token's acquirer.
|
|
acquirer_id = vals.get('acquirer_id')
|
|
acquirer = False
|
|
payment_token_id = vals.get('payment_token_id')
|
|
|
|
if payment_token_id:
|
|
payment_token = self.env['payment.token'].sudo().browse(payment_token_id)
|
|
|
|
# Check payment_token/acquirer matching or take the acquirer from token
|
|
if acquirer_id:
|
|
acquirer = self.env['payment.acquirer'].browse(acquirer_id)
|
|
if payment_token and payment_token.acquirer_id != acquirer:
|
|
raise ValidationError(_('Invalid token found! Token acquirer %s != %s') % (
|
|
payment_token.acquirer_id.name, acquirer.name))
|
|
if payment_token and payment_token.partner_id != partner:
|
|
raise ValidationError(_('Invalid token found! Token partner %s != %s') % (
|
|
payment_token.partner.name, partner.name))
|
|
else:
|
|
acquirer = payment_token.acquirer_id
|
|
|
|
# Check an acquirer is there.
|
|
if not acquirer_id and not acquirer:
|
|
raise ValidationError(_('A payment acquirer is required to create a transaction.'))
|
|
|
|
if not acquirer:
|
|
acquirer = self.env['payment.acquirer'].browse(acquirer_id)
|
|
|
|
# Check a journal is set on acquirer.
|
|
if not acquirer.journal_id:
|
|
raise ValidationError(_('A journal must be specified for the acquirer %s.', acquirer.name))
|
|
|
|
if not acquirer_id and acquirer:
|
|
vals['acquirer_id'] = acquirer.id
|
|
|
|
vals.update({
|
|
'amount': sum(self.mapped('amount_total')),
|
|
'currency_id': currency.id,
|
|
'partner_id': partner.id,
|
|
'donation_ids': [(6, 0, self.ids)],
|
|
'type': self[0]._get_payment_type(vals.get('type')=='form_save'),
|
|
})
|
|
|
|
|
|
transaction = self.env['payment.transaction'].create(vals)
|
|
|
|
|
|
# Process directly if payment_token
|
|
if transaction.payment_token_id:
|
|
transaction.s2s_do_transaction()
|
|
|
|
return transaction
|
|
|
|
def _import_donation(self):
|
|
files= self.env["opendons.partnerdraftfile"].search([('source_name','=','donation')])
|
|
|
|
for f in files:
|
|
|
|
decrypted = base64.b64decode(f.file).decode('utf-8-sig')
|
|
source_name=f.source_name
|
|
|
|
|
|
with io.StringIO(decrypted) as fp:
|
|
reader = csv.DictReader(fp, delimiter=",", quotechar='"')
|
|
for row in reader:
|
|
|
|
vals={}
|
|
lig_vals={}
|
|
vals_p={}
|
|
vals_part={}
|
|
|
|
for key, value in row.items():
|
|
#on cherche le type de don
|
|
if key=='Destination don':
|
|
#dons dans la base:
|
|
dbdonpdt=['Activités en ligne','Aide à la sangha ordonnée','Autre','Don selon les besoins du centre','Rituels et prières','Soutien aux lamas','Travaux au centre de retraite']
|
|
#mapping avec les valeur du fichier
|
|
if value=='Soutien Lamas':
|
|
value='Soutien aux lamas'
|
|
if value=='Soutien Lamas':
|
|
value='Soutien aux lamas'
|
|
if value=='':
|
|
value="Autre"
|
|
donation_product=self.env['product.product'].sudo().search([('name','=',value)],limit=1)
|
|
if not donation_product:
|
|
vals_p={}
|
|
vals_p['name']=value
|
|
vals_p['donation']=True
|
|
vals_p['tax_receipt_ok']=True
|
|
vals_p['type']='service'
|
|
vals_p['taxes_id']=False
|
|
res=self.env['product.product'].create(vals_p)
|
|
lig_vals['product_id']=res.id
|
|
lig_vals['display_name']=res.display_name
|
|
lig_vals['tax_receipt_ok']=res.tax_receipt_ok
|
|
else:
|
|
lig_vals['product_id']=donation_product.id
|
|
lig_vals['display_name']=donation_product.display_name
|
|
lig_vals['tax_receipt_ok']=donation_product.tax_receipt_ok
|
|
|
|
|
|
if key=='Email':
|
|
vals_part['email']=value.strip()
|
|
|
|
|
|
|
|
if key=='Nom': vals_part['name']=value.strip()
|
|
if key=='Prénom':vals_part['firstname']=value.strip()
|
|
|
|
if key=='Date':
|
|
year_m=value[0:4]
|
|
month_m=value[5:7]
|
|
day_m=value[8:10]
|
|
vals['donation_date']=datetime.strptime(year_m+'-'+month_m+'-'+day_m, '%Y-%m-%d')
|
|
|
|
if key=='Montant':
|
|
lig_vals['unit_price']=value
|
|
|
|
#création du contact si pas trouvé dans la base
|
|
partner=self.env['res.partner'].sudo().search([('email','=',vals_part['email'])],limit=1)
|
|
if not partner:
|
|
vals_part['origine']='import_don2022'
|
|
vals_part['tax_receipt_option']='annual'
|
|
|
|
_logger.error(vals_part)
|
|
|
|
new_partner=self.env['res.partner'].create(vals_part)
|
|
vals['partner_id']=new_partner.id
|
|
else:
|
|
vals['partner_id']=partner.id
|
|
#creation du don avec Chèque comme mode de paiement
|
|
check_mode=self.env['account.payment.mode'].sudo().search([('name','=','chèque')],limit=1)
|
|
vals['payment_mode_id']=int(check_mode.id)
|
|
vals['state']='draft'
|
|
vals['payment_ref']='import'
|
|
vals['tax_receipt_option']='annual'
|
|
vals['source_import']='import dons 2022'
|
|
vals['date_import']=fields.datetime.now()
|
|
donation_draft=self.env['donation.donation'].sudo().create(vals)
|
|
#create line donation
|
|
lig_vals['donation_id']=donation_draft.id
|
|
lig_vals['quantity']=1
|
|
donation_line=self.env['donation.line'].sudo().create(lig_vals)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return True
|
|
def _cancel_donation(self):
|
|
#annulation des dons créés aujourd'hui
|
|
today=date.today()
|
|
donation=self.env['donation.donation'].search([('create_date','>=',today)])
|
|
for d in donation:
|
|
d.state='cancel'
|
|
|
|
def fix_donation(self):
|
|
#tax_receipt_total=0 for Donation pour favoriser le séjour des personnes à revenu modeste
|
|
donation=self.env['donation.donation'].search([('tax_receipt_total','=',0),('state','=','done')])
|
|
raise UserError(donation)
|