from odoo import models, fields, api,_
|
|
from odoo.exceptions import UserError, ValidationError, Warning
|
|
from psycopg2 import sql, DatabaseError
|
|
from dateutil.relativedelta import relativedelta
|
|
from datetime import datetime
|
|
from werkzeug import utils
|
|
|
|
|
|
class EventRegistration(models.Model):
|
|
_inherit = 'event.registration'
|
|
|
|
room_id = fields.Many2one(
|
|
'booking.room',
|
|
String='Room',
|
|
index=True,
|
|
group_expand='_read_group_room_ids',
|
|
track_visibility='onchange',
|
|
|
|
)
|
|
booking_event=fields.Boolean(related='event_id.booking_event',store=True)
|
|
individual_booking_event=fields.Boolean(related='event_id.individual_booking_event',store=True)
|
|
event_end=fields.Boolean(related='event_id.stage_id.pipe_end')
|
|
|
|
medical_concern=fields.Selection(
|
|
[('have medical concern','I have a medical concern to report'),
|
|
('have no medical concern','I have no medical concern to report'),
|
|
('no answer','I don\'t want to answer')],
|
|
string='Medical concern',
|
|
)
|
|
medical_information=fields.Char('Medical informations')
|
|
medical_contact_name=fields.Char('Name and Firstname of the contact')
|
|
medical_contact_phone=fields.Char('Phone of the contact')
|
|
|
|
questionnaire_ids=fields.One2many(
|
|
'event.registration_questionnaire',
|
|
'event_registration_id',
|
|
String='Questionnaire',
|
|
|
|
readonly=True
|
|
|
|
)
|
|
option_ids=fields.One2many(
|
|
'event.registration_option',
|
|
'event_registration_id',
|
|
String='Options',
|
|
|
|
readonly=True
|
|
|
|
)
|
|
donation_ids=fields.One2many(
|
|
'donation.donation',
|
|
'event_registration_id',
|
|
String='Donations',
|
|
|
|
readonly=True
|
|
|
|
)
|
|
@api.model
|
|
def _default_currency(self):
|
|
company = self.env['res.company']._company_default_get(
|
|
'event.registration')
|
|
return company.currency_id
|
|
currency_id = fields.Many2one(
|
|
'res.currency',
|
|
string='Currency',
|
|
required=True,
|
|
track_visibility='onchange',
|
|
ondelete='restrict',
|
|
default=_default_currency
|
|
)
|
|
|
|
down_payment=fields.Boolean('down payment',default=False)
|
|
firstname=fields.Char('Firstname')
|
|
age=fields.Integer('Age')
|
|
gender=fields.Selection([('male','Male'),('femelle','Femelle')],string='gender')
|
|
mobile=fields.Char('Mobile')
|
|
city=fields.Char('City')
|
|
image_right_clearance=fields.Boolean('image right clearance')
|
|
train_arrival_time=fields.Float(string="train arrival time")
|
|
train_arrival_date=fields.Date(string="train arrival date")
|
|
image_permission=fields.Boolean("Image permission")
|
|
kanban_color=fields.Char('kanban color',compute='_compute_kanban_color')
|
|
|
|
invoice_state=fields.Selection(related='invoice_id.payment_state')
|
|
|
|
down_payment_invoice_state=fields.Selection(related='down_payment_invoice_id.payment_state')
|
|
|
|
balance_invoice_state=fields.Selection(related='balance_invoice_id.payment_state')
|
|
|
|
invoice_id=fields.Many2one('account.move', readonly=True, ondelete="cascade")
|
|
#invoice_state=fields.Selection(related='invoice_id.state')
|
|
down_payment_invoice_id=fields.Many2one('account.move', ondelete="cascade")
|
|
#down_payment_invoice_state=fields.Selection(related='down_payment_order_id.state')
|
|
balance_invoice_id=fields.Many2one('account.move' ,ondelete="cascade")
|
|
#balance_invoice_state=fields.Selection(related='balance_order_id.state')
|
|
|
|
end_of_stay_invoice_id=fields.Many2one('account.move' ,string='end of stay invoice',ondelete="cascade")
|
|
|
|
|
|
payment_status=fields.Selection(string='payment status',selection=[('paid','Paid'),('not paid','Not paid'),('down payment not paid','down payment not paid'),('down payment paid','down payment paid')],compute='_compute_payment_status',translate=True)
|
|
to_be_paid_amount=fields.Monetary('to be paid amount',compute='_compute_to_be_paid_amount',currency_field='currency_id')
|
|
payment_adjustement=fields.Monetary('payment adjustement',currency_field='currency_id')
|
|
individual_room=fields.Boolean('Individual room',compute='compute_individual_room')
|
|
|
|
#individual booking fields
|
|
start_day_individual_booking=fields.Date('Start day')
|
|
end_day_individual_booking=fields.Date('End day')
|
|
days_duration=fields.Integer('Duration in days')
|
|
price_individual_booking=fields.Monetary('price individual booking',currency_field='currency_id')
|
|
|
|
exported_state=fields.Char('accounting exported state')
|
|
|
|
def compute_individual_room(self):
|
|
for rec in self:
|
|
prd=self.env['product.product'].search([('individual_room','=',True)])
|
|
rec.individual_room=False
|
|
for opt in rec.option_ids:
|
|
if prd.id==opt.booking_option_id.id : rec.individual_room=True
|
|
|
|
def _compute_to_be_paid_amount(self):
|
|
for rec in self:
|
|
rec.to_be_paid_amount=0
|
|
if rec.invoice_id : rec.to_be_paid_amount=rec.invoice_id.amount_residual
|
|
else:
|
|
if rec.down_payment_invoice_id and rec.balance_invoice_id:
|
|
rec.to_be_paid_amount=rec.down_payment_invoice_id.amount_residual+rec.balance_invoice_id.amount_residual
|
|
|
|
def action_cancel(self):
|
|
self.write({'state': 'cancel'})
|
|
#annulation de la facture liée à l'événement
|
|
if self.invoice_id: self.invoice_id.state='cancel'
|
|
#annulation des factures de retraites
|
|
if self.down_payment_invoice_id: self.down_payment_invoice_id.state='cancel'
|
|
if self.balance_invoice_id: self.balance_invoice_id.state='cancel'
|
|
|
|
def unlink(self):
|
|
if self.state!='cancel':raise UserError(_('This action is not allowed, please cancel the registration'))
|
|
if self.state=='cancel':raise UserError(_('This action is not allowed,the registration is already canceled'))
|
|
def _compute_payment_status(self):
|
|
for rec in self:
|
|
rec.payment_status='not paid'
|
|
if rec.invoice_id:
|
|
if rec.invoice_state not in ('paid'):rec.payment_status='not paid'
|
|
if rec.invoice_state=='paid':rec.payment_status='paid'
|
|
|
|
|
|
else:
|
|
if rec.down_payment_invoice_id and rec.balance_invoice_id:
|
|
if rec.down_payment_invoice_state!='paid':rec.payment_status='down payment not paid'
|
|
if rec.down_payment_invoice_state=='paid' and rec.balance_invoice_state=='paid' :rec.payment_status='paid'
|
|
if rec.down_payment_invoice_state=='paid' and rec.balance_invoice_state!='paid':rec.payment_status='down payment paid'
|
|
|
|
if rec.payment_status in('paid','down payment paid') and rec.state!='cancel':
|
|
rec.state='open'
|
|
|
|
|
|
def _compute_kanban_color(self):
|
|
for rec in self:
|
|
rec.kanban_color=''
|
|
if rec.gender=='male':rec.kanban_color="50aaf3"
|
|
if rec.gender=='femelle':rec.kanban_color="ffffff"
|
|
@api.model
|
|
def _read_group_room_ids(self, stages, domain, order):
|
|
return self.env['booking.room'].search([])
|
|
|
|
@api.model
|
|
def create(self, vals_list):
|
|
|
|
reg = super(EventRegistration, self).create(vals_list)
|
|
|
|
|
|
|
|
return reg
|
|
|
|
def action_event_registration_order(self):
|
|
return True
|
|
|
|
def create_donation(self,event_registration_id,partner_id,product_id,price_unit,invoice_id):
|
|
vals={}
|
|
vals['partner_id']=int(partner_id)
|
|
vals['invoice_id']=int(invoice_id)
|
|
vals['donation_date']=datetime.now()
|
|
vals['tax_receipt_option']='annual'
|
|
#mode de paiement CB par defaut
|
|
electronic_method=self.env['account.payment.method'].search([('code','=','electronic')],limit=1)
|
|
if electronic_method:
|
|
cb_mode=self.env['account.payment.mode'].search([('payment_method_id','=',int(electronic_method.id))],limit=1)
|
|
if cb_mode:
|
|
vals['payment_mode_id']=cb_mode.id
|
|
else:
|
|
raise Warning('please configure credit card mode')
|
|
#tant que le devis n'est pas validé (paiment effectué), le don est en brouillon
|
|
vals['state']='draft'
|
|
vals['payment_ref']='internet'
|
|
donation_draft=self.env['donation.donation'].sudo().create(vals)
|
|
#ajout du don au niveau de l'inscription
|
|
reg=self.env['event.registration'].search([('id','=',int(event_registration_id))])
|
|
if reg:
|
|
reg.write({'donation_ids':[(4,int(donation_draft.id))]})
|
|
|
|
vals={}
|
|
#create line donation
|
|
vals['donation_id']=donation_draft.id
|
|
product=self.env['product.product'].search([('id','=',int(product_id))])
|
|
|
|
vals['product_id']=int(product_id)
|
|
vals['display_name']=product.name
|
|
vals['quantity']=1
|
|
vals['unit_price']=price_unit
|
|
vals['tax_receipt_ok']=product.tax_receipt_ok
|
|
|
|
|
|
donation_line=self.env['donation.line'].sudo().create(vals)
|
|
donation_draft.state='draft'
|
|
|
|
|
|
|
|
|
|
def remove_invoice(self):
|
|
|
|
invoice=self.env['account.move'].sudo().search([('id','=',int(self.invoice_id))])
|
|
if invoice:
|
|
if invoice.payment_state!='paid':
|
|
invoice.state='draft'
|
|
invoice.posted_before=False
|
|
invoice_id=self.invoice_id
|
|
self.invoice_id=False
|
|
|
|
#suppression des lignes de paiements liés à la facture
|
|
move_line=self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))])
|
|
if move_line:
|
|
for m in move_line:
|
|
self.env['account.payment.line'].sudo().search([('move_line_id','=',int(m.id))]).unlink()
|
|
|
|
#suppression des paiements liés à la facture
|
|
self.env['account.payment'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
|
|
#suppression des écritures comptables lié à la facture
|
|
self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
#suppression de la facture
|
|
|
|
self.env['account.move'].sudo().search([('id','=',int(invoice_id))]).unlink()
|
|
|
|
if self.down_payment_invoice_id:
|
|
invoice=self.env['account.move'].sudo().search([('id','=',int(self.down_payment_invoice_id))])
|
|
if invoice:
|
|
if invoice.payment_state!='paid':
|
|
invoice.state='draft'
|
|
invoice.posted_before=False
|
|
invoice_id=self.down_payment_invoice_id
|
|
self.down_payment_invoice_id=False
|
|
#suppression des lignes de paiements liés à la facture
|
|
move_line=self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))])
|
|
if move_line:
|
|
for m in move_line:
|
|
self.env['account.payment.line'].sudo().search([('move_line_id','=',int(m.id))]).unlink()
|
|
|
|
#suppression des paiements liés à la facture
|
|
self.env['account.payment'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
|
|
#suppression des écritures comptables lié à la facture
|
|
self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
#suppression de la facture
|
|
|
|
self.env['account.move'].sudo().search([('id','=',int(invoice_id))]).unlink()
|
|
if self.balance_invoice_id:
|
|
invoice=self.env['account.move'].sudo().search([('id','=',int(self.balance_invoice_id))])
|
|
if invoice:
|
|
if invoice.payment_state!='paid':
|
|
invoice.state='draft'
|
|
invoice.posted_before=False
|
|
invoice_id=self.balance_invoice_id
|
|
self.balance_invoice_id=False
|
|
#suppression des lignes de paiements liés à la facture
|
|
move_line=self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))])
|
|
if move_line:
|
|
for m in move_line:
|
|
self.env['account.payment.line'].sudo().search([('move_line_id','=',int(m.id))]).unlink()
|
|
|
|
#suppression des paiements liés à la facture
|
|
self.env['account.payment'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
|
|
#suppression des écritures comptables lié à la facture
|
|
self.env['account.move.line'].sudo().search([('move_id','=',int(invoice_id))]).unlink()
|
|
#suppression de la facture
|
|
|
|
self.env['account.move'].sudo().search([('id','=',int(invoice_id))]).unlink()
|
|
|
|
|
|
return True
|
|
|
|
def remove_donation(self):
|
|
#suppression des dons existants lié à l'inscription et aux options
|
|
donation=self.env['donation.donation'].sudo().search([('id','in',self.donation_ids.ids)])
|
|
for d in donation:
|
|
d.state='draft'
|
|
self.env['donation.donation'].sudo().search([('id','in',self.donation_ids.ids)]).unlink()
|
|
self.donation_ids=False
|
|
return True
|
|
|
|
def action_event_registration_generate_end_of_stay_invoice(self):
|
|
return self.action_event_registration_generate_invoice(None,True,True)
|
|
|
|
def action_event_registration_generate_invoice(self,id_registration=None,backoffice=True,end_of_stay_invoice=False):
|
|
|
|
|
|
if not end_of_stay_invoice:
|
|
#suppression des factures existantes
|
|
#si les factures sont payés on les supprime pas
|
|
self.remove_invoice()
|
|
#suppression des dons existants lié aux options de l'inscription
|
|
self.remove_donation()
|
|
else:
|
|
end_invoice=self.env['account.move'].sudo().search([('id','=',int(self.end_of_stay_invoice_id))])
|
|
if end_invoice:
|
|
if end_invoice.payment_state!='paid':
|
|
invoice_id=self.end_of_stay_invoice_id
|
|
self.end_of_stay_invoice_id=False
|
|
self.env['account.move'].sudo().search([('id','=',int(invoice_id))]).unlink()
|
|
|
|
|
|
|
|
if id_registration:reg=self.env['event.registration'].search([('id','=',int(id_registration))])
|
|
else : reg=self
|
|
|
|
event=self.env['event.event'].search([('id','=',int(reg.event_id))])
|
|
selected_registrant_options=self.env['event.registration_option'].search([
|
|
('event_registration_id','=',int(reg.id))])
|
|
|
|
|
|
#controles avant traitement : un produit doit être associé à l'événement
|
|
if not event.booking_product_id: raise Warning('product missing for event booking')
|
|
|
|
#Prix à appliquer au produit en fonction du statut de l'inscrit
|
|
if reg.partner_id.email==reg.email:
|
|
status=reg.partner_id.member_status
|
|
#le participant n'est pas la personne qui s'est connecté
|
|
|
|
else:
|
|
participant=self.env['res.partner'].sudo().search([('email','=',reg.email)],limit=1)
|
|
if participant:
|
|
status=participant.member_status
|
|
else:
|
|
status='not member'
|
|
|
|
if event.individual_booking_event:
|
|
product_price=reg.price_individual_booking
|
|
membership_option=False
|
|
else:
|
|
|
|
product_price=event.booking_price
|
|
if status=='not member':product_price=event.booking_price
|
|
if status=='member':product_price=event.booking_member_price
|
|
if status=='super member':product_price=event.booking_super_member_price
|
|
|
|
#Prix à appliquer au produit si paiement de l'adhésion
|
|
membership_option=False
|
|
#membership_product=self.env['event.membership_product'].search([])
|
|
membership_product=self.env['product.product'].sudo().search([('membership_product','=',True)],limit=1)
|
|
|
|
if membership_product:
|
|
if selected_registrant_options:
|
|
for opt in selected_registrant_options:
|
|
#raise Warning("opt.booking_option_id="+str(opt.booking_option_id.id)+" membership_product.id="+str(membership_product.id))
|
|
if opt.booking_option_id.id==membership_product.id:
|
|
membership_option=True
|
|
|
|
if status!="super member":
|
|
product_price=event.booking_member_price
|
|
|
|
if self.payment_adjustement!=0:
|
|
product_price=product_price+self.payment_adjustement
|
|
|
|
#calcul du montant total à régler
|
|
if end_of_stay_invoice:product_price=0
|
|
|
|
#création du devis sans acompte
|
|
|
|
if (not reg.down_payment and reg.invoice_state!='paid') or (end_of_stay_invoice):
|
|
if not selected_registrant_options and end_of_stay_invoice :
|
|
return False
|
|
|
|
|
|
#création de la facture
|
|
vals={}
|
|
|
|
vals['partner_id']=int(reg.partner_id)
|
|
vals['invoice_date']=datetime.now()
|
|
|
|
#mode de paiement CB par defaut si frontoffice
|
|
if not backoffice:
|
|
electronic_method=self.env['account.payment.method'].sudo().search([('code','=','electronic')],limit=1)
|
|
if electronic_method:
|
|
cb_mode=self.env['account.payment.mode'].sudo().search([('payment_method_id','=',int(electronic_method.id))],limit=1)
|
|
if cb_mode:
|
|
vals['payment_mode_id']=cb_mode.id
|
|
else:
|
|
raise Warning('please configure credit card mode')
|
|
else:
|
|
check_mode=self.env['account.payment.mode'].sudo().search([('name','=','chèque')])
|
|
if check_mode:
|
|
vals['payment_mode_id']=check_mode.id
|
|
else:
|
|
raise Warning('please configure check mode')
|
|
|
|
|
|
vals['move_type']='out_invoice'
|
|
vals['state']='draft'
|
|
|
|
|
|
invoice=self.env['account.move'].sudo().create(vals)
|
|
|
|
invoice.state='posted'
|
|
invoice.name='REC'+str(invoice.id)
|
|
invoice.payment_reference=invoice.name
|
|
|
|
vals={}
|
|
account_credit=self.env['account.account'].sudo().search([('code','=','707100')])
|
|
account_debit=self.env['account.account'].sudo().search([('code','=','411100')])
|
|
|
|
vals['move_id']=invoice.id
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['quantity']=1
|
|
vals['price_unit']=product_price
|
|
if event.individual_booking_event:
|
|
vals['name']=event.booking_product_id.name+' du '+str(reg.start_day_individual_booking)+' au '+str(reg.end_day_individual_booking)+ ' - '+str(reg.days_duration)+' jours'
|
|
else:
|
|
vals['name']=event.booking_product_id.name+ ' du '+ str(event.date_begin)+' au '+str(event.date_begin)
|
|
|
|
vals['account_id']=int(account_credit.id)
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals)
|
|
|
|
|
|
# #debit_line
|
|
vals_d={}
|
|
vals_d['move_id']=invoice.id
|
|
vals_d['debit']=product_price
|
|
vals_d['credit']=0
|
|
vals_d['date']=datetime.now()
|
|
vals_d['partner_id']=int(reg.partner_id)
|
|
vals_d['product_id']=int(event.booking_product_id)
|
|
vals_d['name']=event.booking_product_id.name + ' du '+ str(event.date_begin)+' au '+str(event.date_begin)
|
|
vals_d['account_id']=int(account_debit.id)
|
|
vals_d['quantity']=1
|
|
vals_d['price_unit']=product_price
|
|
vals_d['exclude_from_invoice_tab']=True
|
|
|
|
|
|
#statut payment=paid
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals_d)
|
|
#statut payment=not_paid
|
|
l=self.env['account.move.line'].sudo().search([('move_id','=',invoice.id),('balance','<',0)])
|
|
l.partner_id=int(reg.partner_id)
|
|
|
|
|
|
#ajout des options
|
|
|
|
if selected_registrant_options:
|
|
for option in selected_registrant_options:
|
|
|
|
prd=self.env['product.product'].sudo().search([('id','=',int(option.booking_option_id.id))])
|
|
|
|
#prix à appliquer aux options en fonction du statut ou de la présence de l'option d'adhesion
|
|
event_option=self.env['booking.option'].sudo().search(['&',('event_id','=',int(reg.event_id)),('booking_option_id','=',int(option.booking_option_id.id))],limit=1)
|
|
price_unit=0
|
|
if event_option:
|
|
if status=="super member":price_unit=event_option.booking_option_super_member_price
|
|
if status=="member":price_unit=event_option.booking_option_member_price
|
|
if status=="not member" and membership_option and event_option.booking_option_id.membership_product:price_unit=event_option.booking_option_price
|
|
if status=="not member" and membership_option and not event_option.booking_option_id.membership_product:price_unit=event_option.booking_option_member_price
|
|
if status=="not member" and not membership_option:price_unit=event_option.booking_option_price
|
|
if backoffice:
|
|
if option.booking_option_id.booking_option_product_backoffice:
|
|
price_unit=option.booking_option_price
|
|
|
|
vals={}
|
|
vals['move_id']=invoice.id
|
|
#ajout du produit
|
|
vals['product_id']=int(option.booking_option_id.id)
|
|
vals['quantity']=1
|
|
vals['price_unit']=price_unit
|
|
vals['name']=prd.name
|
|
vals['account_id']=int(account_credit.id)
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals)
|
|
|
|
|
|
#debit_line
|
|
vals_d={}
|
|
vals_d['move_id']=invoice.id
|
|
if price_unit>=0:
|
|
vals_d['debit']=price_unit
|
|
vals_d['credit']=0
|
|
if price_unit<0:
|
|
vals_d['debit']=0
|
|
vals_d['credit']=-price_unit
|
|
|
|
vals_d['date']=datetime.now()
|
|
vals_d['partner_id']=int(reg.partner_id)
|
|
vals_d['product_id']=int(option.booking_option_id.id)
|
|
vals_d['name']=prd.name
|
|
vals_d['account_id']=int(account_debit.id)
|
|
vals_d['quantity']=1
|
|
vals_d['price_unit']=price_unit
|
|
vals_d['exclude_from_invoice_tab']=True
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=True).sudo().create([vals_d])
|
|
l=self.env['account.move.line'].sudo().search([('move_id','=',invoice.id),('balance','<',0)])
|
|
l.partner_id=int(reg.partner_id)
|
|
|
|
|
|
#si l'option est un produit de don on créé un don pour la personne
|
|
if prd.donation: self.sudo().create_donation(reg.id,reg.partner_id,prd.id,vals['price_unit'],invoice.id)
|
|
|
|
|
|
if not end_of_stay_invoice:
|
|
reg.invoice_id=invoice.id
|
|
else:
|
|
reg.end_of_stay_invoice_id=invoice.id
|
|
|
|
user=self.env['res.users'].search([('email','ilike',reg.partner_id.email)],limit=1)
|
|
invoice.invoice_user_id=user.id
|
|
invoice.user_id=user.id
|
|
# if event.individual_booking_event:
|
|
# mail_template = self.env['mail.template'].search([('name','=','individual_booking_confirmation')])
|
|
# mail_template.email_to = self.partner_id.email
|
|
# if mail_template:
|
|
# mail_template.with_context({'down_payment_invoice_id':self.down_payment_invoice_id}).send_mail(self.id,False)
|
|
#mail_template.send_mail(self.id,False)
|
|
return invoice
|
|
|
|
|
|
#2 factures si paiement avec acompte
|
|
else:
|
|
if reg.down_payment_invoice_state!='paid' and reg.down_payment and not end_of_stay_invoice:
|
|
#création de la 1ère facture d'acompte
|
|
vals={}
|
|
|
|
vals['partner_id']=int(reg.partner_id)
|
|
vals['invoice_date']=datetime.now()
|
|
|
|
#mode de paiement CB par defaut
|
|
if not backoffice:
|
|
electronic_method=self.env['account.payment.method'].sudo().search([('code','=','electronic')],limit=1)
|
|
if electronic_method:
|
|
cb_mode=self.env['account.payment.mode'].sudo().search([('payment_method_id','=',int(electronic_method.id))],limit=1)
|
|
if cb_mode:
|
|
vals['payment_mode_id']=cb_mode.id
|
|
else:
|
|
raise Warning('please configure credit card mode')
|
|
else:
|
|
check_mode=self.env['account.payment.mode'].sudo().search([('name','=','chèque')])
|
|
if check_mode:
|
|
vals['payment_mode_id']=check_mode.id
|
|
else:
|
|
raise Warning('please configure check mode')
|
|
|
|
vals['move_type']='out_invoice'
|
|
vals['state']='draft'
|
|
#vals['currency_id']=self.currency_id.id
|
|
invoice=self.env['account.move'].sudo().create(vals)
|
|
invoice.state='posted'
|
|
invoice.name='REC'+str(invoice.id)
|
|
invoice.payment_reference=invoice.name
|
|
user=self.env['res.users'].search([('email','ilike',reg.partner_id.email)],limit=1)
|
|
invoice.invoice_user_id=user.id
|
|
invoice.user_id=user.id
|
|
|
|
vals={}
|
|
account_credit=self.env['account.account'].sudo().search([('code','=','707100')])
|
|
account_debit=self.env['account.account'].sudo().search([('code','=','411100')])
|
|
|
|
vals['move_id']=invoice.id
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['quantity']=1
|
|
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals['price_unit']=product_price
|
|
|
|
else:
|
|
vals['price_unit']=event.booking_down_payment
|
|
|
|
vals['name']='Acompte '+event.booking_product_id.name+' du '+str(reg.start_day_individual_booking)+' au '+str(reg.end_day_individual_booking)+ '- '+str(reg.days_duration)+' jour(s)'
|
|
else:
|
|
vals['price_unit']=event.booking_down_payment
|
|
vals['name']='Acompte '+event.booking_product_id.name+ ' du '+ str(event.date_begin)+' au '+str(event.date_begin)
|
|
|
|
|
|
|
|
vals['account_id']=int(account_credit.id)
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals)
|
|
|
|
|
|
# #debit_line
|
|
vals_d={}
|
|
vals_d['move_id']=invoice.id
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals_d['debit']=product_price
|
|
else:
|
|
vals_d['debit']=event.booking_down_payment
|
|
else:
|
|
vals_d['debit']=event.booking_down_payment
|
|
vals_d['credit']=0
|
|
vals_d['date']=datetime.now()
|
|
vals_d['partner_id']=int(reg.partner_id)
|
|
vals_d['product_id']=int(event.booking_product_id)
|
|
vals_d['name']='Acompte '+event.booking_product_id.name
|
|
vals_d['account_id']=int(account_debit.id)
|
|
vals_d['quantity']=1
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals_d['price_unit']=product_price
|
|
else:
|
|
vals_d['price_unit']=event.booking_down_payment
|
|
|
|
else:
|
|
vals_d['price_unit']=event.booking_down_payment
|
|
vals_d['exclude_from_invoice_tab']=True
|
|
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals_d)
|
|
l=self.env['account.move.line'].sudo().search([('move_id','=',invoice.id),('balance','<',0)])
|
|
l.partner_id=int(reg.partner_id)
|
|
|
|
reg.down_payment_invoice_id=invoice.id
|
|
|
|
if reg.balance_invoice_state!='paid' and reg.down_payment and not end_of_stay_invoice:
|
|
#création 2ème facture de solde + paiement des options
|
|
vals={}
|
|
|
|
vals['partner_id']=int(reg.partner_id)
|
|
vals['invoice_date']=datetime.now()
|
|
|
|
|
|
vals['move_type']='out_invoice'
|
|
vals['state']='draft'
|
|
#vals['currency_id']=self.currency_id.id
|
|
invoice=self.env['account.move'].sudo().create(vals)
|
|
|
|
invoice.state='posted'
|
|
invoice.name='REC'+str(invoice.id)
|
|
invoice.payment_reference=invoice.name
|
|
user=self.env['res.users'].search([('email','ilike',reg.partner_id.email)],limit=1)
|
|
invoice.invoice_user_id=user.id
|
|
invoice.user_id=user.id
|
|
|
|
vals={}
|
|
|
|
vals['move_id']=invoice.id
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['quantity']=1
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals['price_unit']=0
|
|
else:
|
|
vals['price_unit']=product_price-event.booking_down_payment
|
|
|
|
else:
|
|
vals['price_unit']=product_price-event.booking_down_payment
|
|
vals['name']='solde '+event.booking_product_id.name
|
|
|
|
vals['account_id']=int(account_credit.id)
|
|
|
|
#mode de paiement CB par defaut
|
|
if not backoffice:
|
|
electronic_method=self.env['account.payment.method'].sudo().search([('code','=','electronic')],limit=1)
|
|
if electronic_method:
|
|
cb_mode=self.env['account.payment.mode'].sudo().search([('payment_method_id','=',int(electronic_method.id))],limit=1)
|
|
if cb_mode:
|
|
vals['payment_mode_id']=cb_mode.id
|
|
else:
|
|
raise Warning('please configure credit card mode')
|
|
else:
|
|
check_mode=self.env['account.payment.mode'].sudo().search([('name','=','chèque')])
|
|
if check_mode:
|
|
vals['payment_mode_id']=check_mode.id
|
|
else:
|
|
raise Warning('please configure check mode')
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals)
|
|
|
|
|
|
# #debit_line
|
|
vals_d={}
|
|
vals_d['move_id']=invoice.id
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals_d['debit']=0
|
|
else:
|
|
vals_d['debit']=product_price-event.booking_down_payment
|
|
else:
|
|
vals_d['debit']=product_price-event.booking_down_payment
|
|
vals_d['credit']=0
|
|
vals_d['date']=datetime.now()
|
|
vals_d['partner_id']=int(reg.partner_id)
|
|
vals_d['product_id']=int(event.booking_product_id)
|
|
vals_d['name']='solde '+event.booking_product_id.name+ ' du '+ str(event.date_begin)+' au '+str(event.date_begin)
|
|
vals_d['account_id']=int(account_debit.id)
|
|
vals_d['quantity']=1
|
|
if event.individual_booking_event:
|
|
if product_price<event.booking_down_payment:
|
|
vals['price_unit']=0
|
|
else:
|
|
vals['price_unit']=product_price-event.booking_down_payment
|
|
else:
|
|
vals_d['price_unit']=product_price-event.booking_down_payment
|
|
vals_d['exclude_from_invoice_tab']=True
|
|
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals_d)
|
|
|
|
l=self.env['account.move.line'].sudo().search([('move_id','=',invoice.id),('balance','<',0)])
|
|
l.partner_id=int(reg.partner_id)
|
|
|
|
|
|
#ajout des options
|
|
if selected_registrant_options:
|
|
for option in selected_registrant_options:
|
|
|
|
prd=self.env['product.product'].sudo().search([('id','=',int(option.booking_option_id.id))])
|
|
|
|
#prix à appliquer aux options en fonction du statut ou de la présence de l'option d'adhesion
|
|
event_option=self.env['booking.option'].search(['&',('event_id','=',int(reg.event_id)),('booking_option_id','=',int(option.booking_option_id.id))])
|
|
price_unit=0
|
|
if event_option:
|
|
if status=="super member":price_unit=event_option.booking_option_super_member_price
|
|
if status=="member":price_unit=event_option.booking_option_member_price
|
|
if status=="not member" and membership_option and event_option.booking_option_id.membership_product:price_unit=event_option.booking_option_price
|
|
if status=="not member" and membership_option and not event_option.booking_option_id.membership_product:price_unit=event_option.booking_option_member_price
|
|
if status=="not member" and not membership_option:price_unit=event_option.booking_option_price
|
|
|
|
|
|
if backoffice:
|
|
if option.booking_option_id.booking_option_product_backoffice:
|
|
price_unit=option.booking_option_price
|
|
|
|
|
|
vals={}
|
|
vals['move_id']=invoice.id
|
|
#ajout du produit
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['quantity']=1
|
|
vals['price_unit']=price_unit
|
|
vals['name']=prd.name
|
|
vals['account_id']=int(account_credit.id)
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=False).sudo().create(vals)
|
|
|
|
|
|
#debit_line
|
|
vals_d={}
|
|
vals_d['move_id']=invoice.id
|
|
if price_unit>=0:
|
|
vals_d['debit']=price_unit
|
|
vals_d['credit']=0
|
|
if price_unit<0:
|
|
vals_d['debit']=0
|
|
vals_d['credit']=-price_unit
|
|
vals_d['date']=datetime.now()
|
|
vals_d['partner_id']=int(reg.partner_id)
|
|
vals_d['product_id']=int(option.booking_option_id.id)
|
|
vals_d['name']=prd.name
|
|
vals_d['account_id']=int(account_debit.id)
|
|
vals_d['quantity']=1
|
|
vals_d['price_unit']=price_unit
|
|
vals_d['exclude_from_invoice_tab']=True
|
|
|
|
invoice_line=self.env['account.move.line'].with_context(check_move_validity=True).sudo().create([vals_d])
|
|
|
|
l=self.env['account.move.line'].search([('move_id','=',invoice.id),('balance','<',0)])
|
|
l.partner_id=int(reg.partner_id)
|
|
|
|
|
|
#si l'option est un produit de don on créé un don pour la personne
|
|
if prd.donation: self.sudo().create_donation(reg.id,reg.partner_id,prd.id,vals['price_unit'],invoice.id)
|
|
|
|
reg.balance_invoice_id=invoice.id
|
|
if event.individual_booking_event:
|
|
mail_template = self.env['mail.template'].search([('name','=','individual_booking_confirmation')])
|
|
mail_template.email_to = self.partner_id.email
|
|
if mail_template:
|
|
mail_template.with_context({'down_payment_invoice_id':int(self.down_payment_invoice_id)}).send_mail(self.id,False)
|
|
#mail_template.send_mail(self.id,False)
|
|
return reg.down_payment_invoice_id
|
|
|
|
def info_objet(self,model_id,objet_id):
|
|
field_list=request.env[model_id].sudo().fields_get()
|
|
result=[]
|
|
for key in field_list:
|
|
result.append((key,key))
|
|
result.sort()
|
|
return result
|
|
|
|
def create_payment(self,invoice_id,code_payment_method):
|
|
invoice=self.env['account.move'].search([('id','=',int(invoice_id))])
|
|
payment_method=self.env['account.payment.method'].search([('code','=',code_payment_method),('payment_type','=','inbound')])
|
|
|
|
bank=self.env['account.journal'].search([('type','=','bank')])
|
|
|
|
if not payment_method : raise Warning ('please set up the '+code_payment_method+ ' method')
|
|
if not bank : raise Warning ('please set up the bank journal !')
|
|
Payment = self.env['account.payment'].with_context(default_invoice_ids=[(4, invoice_id, False)])
|
|
payment = Payment.create({
|
|
'date': datetime.now(),
|
|
'payment_method_id': payment_method.id,
|
|
'payment_type': 'inbound',
|
|
'partner_type': 'customer',
|
|
'partner_id': invoice.partner_id.id,
|
|
'amount': invoice.amount_residual,
|
|
'journal_id': int(bank.id),
|
|
'company_id': self.env.company,
|
|
'currency_id': int(self.currency_id)
|
|
#'payment_difference_handling': 'reconcile',
|
|
#'writeoff_account_id': self.diff_income_account.id,
|
|
})
|
|
payment.state='posted'
|
|
invoice.payment_id=payment.id
|
|
invoice.payment_order_ok=True
|
|
|
|
def invoice_without_registration(self,account_description):
|
|
|
|
move=self.env['account.move'].search([])
|
|
result=''
|
|
for mv in move:
|
|
description=''
|
|
for line in mv.line_ids:
|
|
if line.product_id.name==account_description:
|
|
#recherche de l'inscription
|
|
reg=self.env['event.registration'].search([('invoice_id','=',int(mv.id))])
|
|
if not reg: result=result+mv.name+':'+mv.partner_id.name+'\nr'
|
|
break
|
|
|
|
raise UserError(result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EventRegistration_questionnaire(models.Model):
|
|
_name = 'event.registration_questionnaire'
|
|
_description = 'event registration questionnaire'
|
|
|
|
sequence = fields.Integer(string="sequence", default=10)
|
|
question=fields.Text(string='question',readonly=True)
|
|
answer=fields.Text(string='answer')
|
|
event_registration_id=fields.Many2one(
|
|
'event.registration',
|
|
String='Event registration',
|
|
index=True,
|
|
readonly=True,
|
|
track_visibility='onchange',
|
|
ondelete='cascade'
|
|
|
|
|
|
)
|
|
|
|
class EventRegistration_option(models.Model):
|
|
_name = 'event.registration_option'
|
|
_description = 'event registration option'
|
|
|
|
#booking_option_id=fields.Many2one('product.product',string='booking options',domain="[('id','in',selectable_option_ids)]")
|
|
booking_option_id=fields.Many2one('product.product',string='booking options', domain="['|',('booking_option_product_backoffice','=','True'),('booking_option_product','=','True')]")
|
|
booking_option_price=fields.Monetary('Price',currency_field='currency_id')
|
|
booking_option_backoffice=fields.Boolean(related='booking_option_id.booking_option_product_backoffice',store=True)
|
|
selectable_option_ids = fields.Many2many('product.product', compute='_compute_selectable_option')
|
|
event_registration_id=fields.Many2one(
|
|
'event.registration',
|
|
String='Event registration',
|
|
index=True,
|
|
readonly=True,
|
|
track_visibility='onchange',
|
|
|
|
)
|
|
def _compute_selectable_option(self):
|
|
selectable_options=self.env['booking.option'].search([('event_id','=',int(self.event_registration_id.event_id))])
|
|
if selectable_options:
|
|
self.selectable_option_ids=selectable_options.booking_option_id.ids
|
|
|
|
|
|
@api.model
|
|
def _default_currency(self):
|
|
company = self.env['res.company']._company_default_get(
|
|
'event.event')
|
|
return company.currency_id
|
|
|
|
currency_id = fields.Many2one(
|
|
'res.currency',
|
|
string='Currency',
|
|
required=True,
|
|
states={'done': [('readonly', True)]},
|
|
track_visibility='onchange',
|
|
ondelete='restrict',
|
|
default=_default_currency
|
|
)
|