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')
|
|
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
|
|
|
|
)
|
|
|
|
|
|
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')
|
|
kanban_color=fields.Char('kanban color',compute='_compute_kanban_color')
|
|
order_id=fields.Many2one('sale.order')
|
|
order_state=fields.Selection(related='order_id.state')
|
|
down_payment_order_id=fields.Many2one('sale.order')
|
|
down_payment_order_state=fields.Selection(related='down_payment_order_id.state')
|
|
balance_order_id=fields.Many2one('sale.order')
|
|
balance_order_state=fields.Selection(related='balance_order_id.state')
|
|
|
|
payment_status=fields.Char(string='payment status',compute='_compute_payment_status')
|
|
|
|
|
|
def _compute_payment_status(self):
|
|
for rec in self:
|
|
rec.payment_status='undefined'
|
|
if rec.order_id:
|
|
if rec.order_state in ('draft','sent'):rec.payment_status='not paid'
|
|
if rec.order_state=='sale':rec.payment_status='paid'
|
|
if rec.order_state in ('done','cancel'):rec.payment_status=rec.order_state
|
|
|
|
else:
|
|
if rec.down_payment_order_id and balance_order_state:
|
|
if rec.down_payment_order_state in ('draft','sent'):rec.payment_status='down payment not paid'
|
|
if rec.down_payment_order_state=='sale' and rec.balance_payment_order_state=='sale' :rec.payment_status='paid'
|
|
if rec.down_payment_order_state=='sale' and rec.balance_payment_order_state!='sale':rec.payment_status='down payment paid'
|
|
|
|
|
|
|
|
|
|
|
|
def _compute_kanban_color(self):
|
|
for rec in self:
|
|
rec.kanban_color=''
|
|
if rec.gender=='male':rec.kanban_color="d0e0e3"
|
|
if rec.gender=='femelle':rec.kanban_color="eebbcc"
|
|
@api.model
|
|
def _read_group_room_ids(self, stages, domain, order):
|
|
return self.env['booking.room'].search([])
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
registrations = super(EventRegistration, self).create(vals_list)
|
|
if registrations._check_auto_confirmation():
|
|
registrations.sudo().action_confirm()
|
|
|
|
#ajout du questionnaire pour la personne inscrite
|
|
questions=self.env['event.question'].search([('event_id','=',int(registrations.event_id))])
|
|
if questions:
|
|
for question in questions:
|
|
vals={}
|
|
vals['sequence']=question.sequence
|
|
vals['question']=question.question
|
|
vals['event_registration_id']=registrations.id
|
|
res=self.env['event.registration_questionnaire'].create(vals)
|
|
|
|
#ajout des options pour la personne inscrite
|
|
options=self.env['booking.option'].search([('event_id','=',int(registrations.event_id))])
|
|
if options:
|
|
for option in options:
|
|
vals={}
|
|
vals['booking_option_id']=int(option.booking_option_id)
|
|
vals['booking_option_price']=option.booking_option_price
|
|
vals['event_registration_id']=int(registrations.id)
|
|
res=self.env['event.registration_option'].create(vals)
|
|
|
|
return registrations
|
|
|
|
def action_event_registration_order(self):
|
|
return True
|
|
|
|
def create_donation(self,event_registration_id,partner_id,product_id,price_unit):
|
|
vals={}
|
|
vals['partner_id']=int(partner_id)
|
|
#raise Warning(vals['partner_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='done'
|
|
|
|
def action_event_registration_generate_order(self,id_registration=None):
|
|
|
|
|
|
#suppression des devis existants
|
|
if self.order_id:
|
|
self.env['sale.order'].search([('id','=',int(self.order_id))]).unlink()
|
|
self.order_id=False
|
|
|
|
if self.down_payment_order_id:
|
|
self.env['sale.order'].search([('id','=',int(self.down_payment_order_id))]).unlink()
|
|
self.down_payment_order_id=False
|
|
|
|
if self.balance_order_id:
|
|
self.env['sale.order'].search([('id','=',int(self.balance_order_id))]).unlink()
|
|
self.balance_order_id=False
|
|
|
|
#suppression des dons existants
|
|
self.env['donation.donation'].search([('id','in',self.donation_ids)]).unlink()
|
|
self.donation_ids=False
|
|
|
|
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
|
|
status=reg.partner_id.member_status
|
|
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([])
|
|
if membership_product:
|
|
if selected_registrant_options:
|
|
for opt in selected_registrant_options:
|
|
if opt.booking_option_id==membership_product.id:
|
|
membership_option=True
|
|
if status!="super member":
|
|
product_price=event.booking_member_price
|
|
|
|
#calcul du montant total à régler
|
|
|
|
|
|
#création du devis sans accompte
|
|
|
|
if not reg.down_payment:
|
|
#création du devis
|
|
vals={}
|
|
|
|
vals['partner_id']=int(reg.partner_id)
|
|
order=self.env['sale.order'].create(vals)
|
|
#création des lignes de devis
|
|
vals={}
|
|
vals['order_id']=order.id
|
|
#ajout du produit
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['product_uom_qty']=1
|
|
vals['price_unit']=product_price
|
|
vals['name']=event.booking_product_id.name
|
|
order_line=self.env['sale.order.line'].create(vals)
|
|
|
|
#ajout des options
|
|
vals={}
|
|
if selected_registrant_options:
|
|
for option in selected_registrant_options:
|
|
|
|
vals['order_id']=order.id
|
|
vals['product_id']=int(option.booking_option_id.id)
|
|
vals['product_uom_qty']=1
|
|
|
|
prd=self.env['product.product'].search([('id','=',int(option.booking_option_id.id))])
|
|
|
|
|
|
vals['name']=prd.name
|
|
|
|
#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))])
|
|
|
|
if event_option:
|
|
if status=="super member":vals['price_unit']=event_option.booking_option_super_member_price
|
|
if status=="member":vals['price_unit']=event_option.booking_option_member_price
|
|
if status=="not member" and membership_option: vals['price_unit']=event_option.booking_option_member_price
|
|
if status=="not member" and not membership_option: vals['price_unit']=event_option.booking_option_price
|
|
|
|
order_line=self.env['sale.order.line'].create(vals)
|
|
#si l'option est un produit de don on créé un don pour la personne
|
|
#if prd.donation: self.create_donation(reg.id,reg.partner_id,vals['product_id'],vals['price_unit'])
|
|
|
|
order.message_subscribe(partner_ids=order.partner_id.ids)
|
|
order.state='sent'
|
|
reg.order_id=order.id
|
|
|
|
return order.id
|
|
|
|
|
|
#2 devis si paiement avec acompte
|
|
else:
|
|
#création du 1er devis d'acompte
|
|
vals={}
|
|
vals['partner_id']=int(reg.partner_id)
|
|
order=self.env['sale.order'].create(vals)
|
|
#création des lignes de devis
|
|
vals={}
|
|
vals['order_id']=order.id
|
|
#ajout du produit
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['product_uom_qty']=1
|
|
vals['price_unit']=event.booking_down_payment
|
|
vals['name']='Acompte '+event.booking_product_id.name
|
|
order_line=self.env['sale.order.line'].create(vals)
|
|
order.message_subscribe(partner_ids=order.partner_id.ids)
|
|
order.state='sent'
|
|
reg.down_payment_order_id=order.id
|
|
|
|
|
|
#création du 2ème devis de solde + paiement des options
|
|
|
|
vals={}
|
|
|
|
vals['partner_id']=int(reg.partner_id)
|
|
order2=self.env['sale.order'].create(vals)
|
|
#création des lignes de devis
|
|
vals={}
|
|
vals['order_id']=order2.id
|
|
#ajout du produit
|
|
vals['product_id']=int(event.booking_product_id)
|
|
vals['product_uom_qty']=1
|
|
vals['price_unit']=product_price-event.booking_down_payment
|
|
vals['name']='solde '+event.booking_product_id.name
|
|
order_line=self.env['sale.order.line'].create(vals)
|
|
|
|
#ajout des options
|
|
vals={}
|
|
if selected_registrant_options:
|
|
for option in selected_registrant_options:
|
|
|
|
vals['order_id']=order2.id
|
|
vals['product_id']=int(option.booking_option_id.id)
|
|
vals['product_uom_qty']=1
|
|
|
|
prd=self.env['product.product'].search([('id','=',int(option.booking_option_id.id))])
|
|
vals['name']=prd.name
|
|
|
|
#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))])
|
|
|
|
if event_option:
|
|
if status=="super member":vals['price_unit']=event_option.booking_option_super_member_price
|
|
if status=="member":vals['price_unit']=event_option.booking_option_member_price
|
|
if status=="not member" and membership_option: vals['price_unit']=event_option.booking_option_member_price
|
|
if status=="not member" and not membership_option: vals['price_unit']=event_option.booking_option_price
|
|
|
|
order_line=self.env['sale.order.line'].create(vals)
|
|
order2.message_subscribe(partner_ids=order2.partner_id.ids)
|
|
order2.state='sent'
|
|
reg.balance_order_id=order2.id
|
|
return order.id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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="[('booking_option_product','=','True')]")
|
|
booking_option_price=fields.Monetary('Price',currency_field='currency_id',readonly=True)
|
|
event_registration_id=fields.Many2one(
|
|
'event.registration',
|
|
String='Event registration',
|
|
index=True,
|
|
readonly=True,
|
|
track_visibility='onchange',
|
|
|
|
)
|
|
|
|
|
|
@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
|
|
)
|