Browse Source

integration module booking dans module kalachakra

dev-rcn
root 3 years ago
parent
commit
c4712c703a
31 changed files with 3764 additions and 85 deletions
  1. +13
    -1
      __manifest__.py
  2. +2
    -1
      controllers/__init__.py
  3. +401
    -0
      controllers/booking.py
  4. +4
    -4
      controllers/kalachakra.py
  5. +1285
    -24
      i18n/fr.po
  6. +9
    -1
      models/__init__.py
  7. +18
    -0
      models/booking_donation.py
  8. +185
    -0
      models/booking_event.py
  9. +392
    -0
      models/booking_event_registration.py
  10. +14
    -0
      models/booking_location.py
  11. +0
    -0
      models/booking_partner.py
  12. +26
    -0
      models/booking_product.py
  13. +33
    -0
      models/booking_questionnaire.py
  14. +46
    -0
      models/booking_room.py
  15. +39
    -0
      models/booking_sale_order.py
  16. +49
    -4
      models/event.py
  17. +15
    -0
      security/ir.model.access.csv
  18. +111
    -0
      static/js/booking.js
  19. +155
    -0
      views/booking_event.xml
  20. +208
    -0
      views/booking_event_registration.xml
  21. +33
    -0
      views/booking_event_templates_list.xml
  22. +62
    -0
      views/booking_event_templates_page_registration.xml
  23. +32
    -0
      views/booking_location.xml
  24. +38
    -0
      views/booking_product.xml
  25. +57
    -0
      views/booking_questionnaire.xml
  26. +2
    -0
      views/booking_registration.xml
  27. +101
    -0
      views/booking_room.xml
  28. +319
    -0
      views/booking_website_registration.xml
  29. +41
    -40
      views/event.xml
  30. +5
    -0
      views/event_templates_page_registration.xml
  31. +69
    -10
      views/website_event_registration.xml

+ 13
- 1
__manifest__.py View File

@ -41,7 +41,19 @@
'views/event_templates_list.xml',
'views/membership.xml',
'views/website_event_registration.xml',
'views/event_templates_page_registration.xml'
'views/event_templates_page_registration.xml',
'views/booking_product.xml',
'views/booking_event.xml',
'views/booking_event_registration.xml',
'views/booking_website_registration.xml',
'views/booking_registration.xml',
'views/booking_event_templates_list.xml',
#'views/booking_event_templates_page_registration.xml',
'views/booking_location.xml',
'views/booking_room.xml',
'views/booking_questionnaire.xml',
],
# only loaded in demonstration mode


+ 2
- 1
controllers/__init__.py View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import kalachakra
from . import kalachakra
from . import booking

+ 401
- 0
controllers/booking.py View File

@ -0,0 +1,401 @@
from odoo import fields, http, _
from odoo.http import request
import werkzeug
from odoo.tools import format_datetime, format_date, is_html_empty
from odoo.exceptions import UserError,AccessError, MissingError,Warning
from odoo.addons.website_event.controllers.main import WebsiteEventController
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
from odoo.addons.sale.controllers.portal import CustomerPortal
from odoo.addons.portal.controllers.portal import pager as portal_pager, get_records_pager
import json
import binascii
from odoo.addons.payment.controllers.portal import PaymentProcessing
from odoo.addons.portal.controllers.mail import _message_post_helper
from odoo.osv import expression
class booking(WebsiteEventController,AuthSignupHome):
@http.route(['/booking/registration/options'], type='http', auth='user', website=True, sitemap=False,csrf=False)
def bookingregistration_options(self,event_id,*args,**kw):
data={}
#contact lié à l'utilisateur
userid=request.env.context.get('uid')
user=request.env['res.users'].search([('id','=',int(userid))])
partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))])
request.session['partner_id']=int(partner.id)
#si le pays n'est pas renseigné, on le renseigne avec France
#c'est indispensable pour pouvoir régléer le devis
if not partner.country_id:
country=request.env['res.country'].search([('name','=','France')])
partner.country_id=country.id
data['partner']=partner
#évenement
request.session['event_id']=int(event_id)
event=request.env['event.event'].sudo().search([('id','=',int(event_id))])
data['event']=event
#status
# category_ids=partner.category_id
# data['status']='standard'
# if category_ids:
# for c in category_ids:
# category=request.env['event.partner_category'].sudo().search([('partner_category_id','=',c.id)])
# #category=request.env['res.partner.category'].search([('id','=',c.id)])
# if category:data['status']=category.status
data['status']=partner.member_status
if data['status']=='not member':data['status']='standard'
#prix
data['price']=''
if data['status']=='standard':data['price']=event.booking_price
if data['status']=='member':data['price']=event.booking_member_price
if data['status']=='super member':data['price']=event.booking_super_member_price
#membership product
membership_product=request.env['event.membership_product'].sudo().search([])
if not membership_product: raise Warning('no membership product find')
data['membership_product']=membership_product
#options
data['options']=[]
for opt in event.booking_option_ids:
if opt.booking_option_id==membership_product.membership_product_id:
if data['status']!='member' and data['status']!='super member':data['options'].append(opt)
else:data['options'].append(opt)
#data['options']=event.booking_option_ids
#questions
data['questions']=event.question_ids
return http.request.render('booking.registration_options_form',data)
@http.route(['/booking/registration/questionnaire'], type='http', auth='user', website=True, sitemap=False,csrf=False)
def bookingregistration_questionnaire(self,**post):
vals={}
data={}
vals['event_id']=post.get('event_id')
vals['name']=post.get('name')
vals['phone']=post.get('phone')
vals['email']=post.get('email')
vals['firstname']=post.get('firstname')
vals['age']=post.get('age')
vals['gender']=post.get('gender')
vals['mobile']=post.get('mobile')
request.session['registrant'] = vals
request.session['down_payment'] =False
if post.get('down_payment')=="false":request.session['down_payment'] = False
if post.get('down_payment')=="true":request.session['down_payment'] = True
#options
if post.get('nb_o')!="0":
vals3={}
i=1
k=1
while i <= int(post.get('nb_o')):
if post.get('o['+str(i)+']'):
vals3[k]=post.get('o['+str(i)+']')
k=k+1
i=i+1
request.session['options']=vals3
request.session['nb_o']=k-1
else:
request.session['options']=None
request.session['nb_o']=0
#questions
event=request.env['event.event'].sudo().search([('id','=',int(post.get('event_id')))])
data['event']=event
data['questions']=False
if event.question_ids:
data['questions']=event.question_ids
#return vals3
return http.request.render('booking.registration_questionnaire_form',data)
@http.route(['/booking/payment_choice'], type='http',auth='user', website=True, sitemap=False,csrf=False)
def bookinginvoice(self,**post):
vals={}
vals['event_id']=request.session['event_id']
vals['partner_id']=request.session['partner_id']
vals['name']=request.session['registrant']['name']
vals['phone']=request.session['registrant']['phone']
vals['email']=request.session['registrant']['email']
vals['firstname']=request.session['registrant']['firstname']
vals['age']=request.session['registrant']['age']
vals['gender']=request.session['registrant']['gender']
vals['mobile']=request.session['registrant']['mobile']
vals['medical_concern']=post.get('medical_concern')
vals['medical_information']=post.get('medical_information')
vals['medical_contact_name']=post.get('medical_contact_name')
vals['medical_contact_phone']=post.get('medical_contact_phone')
vals['down_payment']=request.session['down_payment']
vals['state']='draft'
res=request.env['event.registration'].sudo().create(vals)
vals2={}
#questionnaire'
i=1
vals2['event_registration_id']=res.id
#suppression du questionnaire de la personne inscrite
request.env['event.registration_questionnaire'].sudo().search([('event_registration_id','=',int(res.id))]).unlink()
if post.get('nb_q')!="0":
while i < int(post.get('nb_q')):
vals2['sequence']=i
vals2['question']=post.get('q['+str(i)+']')
vals2['answer']=post.get('a['+str(i)+']')
#ajout du questionnaire avec les réponses
res2=request.env['event.registration_questionnaire'].sudo().create(vals2)
res.write({'questionnaire_ids':[(4,res2.id)]})
i=i+1
#options
if request.session['nb_o']!=0 :
vals3={}
i=1
#suppression des options de la personne inscrite
request.env['event.registration_option'].sudo().search([('event_registration_id','=',int(res.id))]).unlink()
while i <= int(request.session['nb_o']):
vals3['booking_option_id']=request.session['options'][i]
vals3['event_registration_id']=res.id
#ajout des options
res3=request.env['event.registration_option'].sudo().create(vals3)
res.write({'option_ids':[(4,res3.id)]})
i=i+1
#création du devis
order_id=request.env['event.registration'].sudo().action_event_registration_generate_order(res.id)
order=request.env['sale.order'].sudo().search([("id","=",int(order_id))])
data={}
data['submit_txt']='Pay now'
data['success_url']='/booking/payment/success'
data['error_url']='/booking/payment/error'
data['acquirers'] = list(request.env['payment.acquirer'].search([
('state', 'in', ['enabled', 'test']),
('company_id', '=', request.env.company.id)
]))
userid=request.env.context.get('uid')
user=request.env['res.users'].search([('id','=',int(userid))])
partner=request.env['res.partner'].sudo().search([('id','=',int(user.partner_id))])
request.session['partner_id']=int(partner.id)
payment_tokens = partner.payment_token_ids
payment_tokens |= partner.commercial_partner_id.sudo().payment_token_ids
data['payment_tokens']=payment_tokens
data['order_id']=order_id
return http.request.render('booking.payment_choice_form',data)
#return http.request.redirect(order.access_url)
@http.route(['/booking/payment/transaction/',
'/booking/payment/transaction/<int:so_id>',
'/booking/payment/transaction/<int:so_id>/<string:access_token>'], type='json', auth="public", website=True)
def booking_payment_transaction(self, acquirer_id,order_id, save_token=False, so_id=None, access_token=None, token=None, **kwargs):
""" Json method that creates a payment.transaction, used to create a
transaction when the user clicks on 'pay now' button. After having
created the transaction, the event continues and the user is redirected
to the acquirer website.
:param int acquirer_id: id of a payment.acquirer record. If not set the
user is redirected to the checkout page
"""
# Ensure a payment acquirer is selected
if not acquirer_id:
return False
try:
acquirer_id = int(acquirer_id)
except:
return False
order_id=order_id
order=request.env['sale.order'].search([('id','=',int(order_id))], limit=1)
# Ensure there is something to proceed
if not order or (order and not order.order_line):
return False
assert order.partner_id.id != request.website.partner_id.id
# Create transaction
vals = {'acquirer_id': acquirer_id,
'return_url': '/booking/payment/validate'}
if save_token:
vals['type'] = 'form_save'
if token:
vals['payment_token_id'] = int(token)
transaction = order._create_payment_transaction(vals)
# store the new transaction into the transaction list and if there's an old one, we remove it
# until the day the ecommerce supports multiple orders at the same time
last_tx_id = request.session.get('__website_sale_last_tx_id')
last_tx = request.env['payment.transaction'].browse(last_tx_id).sudo().exists()
if last_tx:
PaymentProcessing.remove_payment_transaction(last_tx)
PaymentProcessing.add_payment_transaction(transaction)
request.session['__website_sale_last_tx_id'] = transaction.id
request.session['order_id']=order.id
return transaction.render_sale_button(order)
http.route('/booking/payment/token', type='http', auth='public', website=True, sitemap=False)
def booking_payment_token(self, pm_id=None, **kwargs):
""" Method that handles payment using saved tokens
:param int pm_id: id of the payment.token that we want to use to pay.
"""
try:
pm_id = int(pm_id)
except ValueError:
return request.redirect('/shop/?error=invalid_token_id')
# We retrieve the token the user want to use to pay
if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]):
return request.redirect('/shop/?error=token_not_found')
# Create transaction
vals = {'payment_token_id': pm_id, 'return_url': '/booking/payment/validate'}
tx = order._create_payment_transaction(vals)
request.session['transaction_id']=tx.id
PaymentProcessing.add_payment_transaction(tx)
return request.redirect('booking/payment/process')
@http.route(['/booking/payment/process'], type="http", auth="public", website=True, sitemap=False)
def booking_payment_status_page(self, **kwargs):
# When the customer is redirect to this website page,
# we retrieve the payment transaction list from his session
tx_ids_list = self.get_payment_transaction_ids()
payment_transaction_ids = request.env['payment.transaction'].sudo().browse(tx_ids_list).exists()
render_ctx = {
'payment_tx_ids': payment_transaction_ids.ids,
}
return request.render("payment.payment_process_page", render_ctx)
@http.route('/booking/payment/validate', type='http', auth="public", website=True, sitemap=False)
def booking_payment_validate(self, transaction_id=None, sale_order_id=None, **post):
""" Method that should be called by the server when receiving an update
for a transaction. State at this point :
- UDPATE ME
"""
order_id=int(request.session['order_id'])
order=request.env['sale.order'].search([('id','=',order_id)])
order.state='sale'
request.session['order_id']=None
transaction_id=int(request.session['__website_sale_last_tx_id'] )
tx = request.env['payment.transaction'].sudo().browse(transaction_id)
PaymentProcessing.remove_payment_transaction(tx)
return request.redirect('/booking/payment/confirmation')
@http.route(['/booking/payment/confirmation'], type='http', auth="public", website=True, sitemap=False)
def booking_payment_confirmation(self, **post):
return request.render("booking.thankyou")
# class CustomerPortal(CustomerPortal):
# #affichage de la page de paiement
# @http.route(['/my/quotes', '/my/quotes/page/<int:page>'], type='http', auth="user", website=True)
# def portal_my_quotes(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
# values = self._prepare_portal_layout_values()
# partner = request.env.user.partner_id
# SaleOrder = request.env['sale.order']
# #return str(len(SaleOrder))
# domain = [('partner_id','=',int(partner.id)),('state','in',('draft','sent'))]
# searchbar_sortings = {
# 'date': {'label': _('Order Date'), 'order': 'date_order desc'},
# 'name': {'label': _('Reference'), 'order': 'name'},
# 'stage': {'label': _('Stage'), 'order': 'state'},
# }
# # default sortby order
# if not sortby:
# sortby = 'date'
# sort_order = searchbar_sortings[sortby]['order']
# if date_begin and date_end:
# domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
# # count for pager
# quotation_count = SaleOrder.search_count(domain)
# # make pager
# pager = portal_pager(
# url="/my/quotes",
# url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
# total=quotation_count,
# page=page,
# step=self._items_per_page
# )
# # search the count to display, according to the pager data
# quotations = SaleOrder.search(domain, order=sort_order, limit=self._items_per_page, offset=pager['offset'])
# request.session['my_quotations_history'] = quotations.ids[:100]
# values.update({
# 'date': date_begin,
# 'quotations': quotations.sudo(),
# 'page_name': 'quote',
# 'pager': pager,
# 'default_url': '/my/quotes',
# 'searchbar_sortings': searchbar_sortings,
# 'sortby': sortby,
# })
# return request.render("sale.portal_my_quotations", values)

+ 4
- 4
controllers/kalachakra.py View File

@ -8,12 +8,12 @@ from dateutil.relativedelta import relativedelta
from odoo.exceptions import UserError
from odoo.addons.website_event.controllers.main import WebsiteEventController
from odoo.addons.payment.controllers.portal import PaymentProcessing
from odoo.addons.auth_signup.controllers.main import AuthSignupHome
#from odoo.addons.auth_signup.controllers.main import AuthSignupHome
from odoo.addons.sale.controllers.portal import CustomerPortal
from odoo.addons.portal.controllers.portal import pager as portal_pager, get_records_pager
class kalachakra_event(WebsiteEventController,PaymentProcessing,AuthSignupHome):
class kalachakra_event(WebsiteEventController,PaymentProcessing):
def _extract_searched_event_tags(self, searches):
tags = request.env['event.tag']
@ -76,8 +76,8 @@ class kalachakra_event(WebsiteEventController,PaymentProcessing,AuthSignupHome):
if data['status']=='member':data['price']=event.booking_member_price
if data['status']=='super member':data['price']=event.booking_super_member_price
request.session['status']=data['status']
if event.online_event:
return http.request.render('kalachakra.registration_step1',data)
return http.request.render('kalachakra.registration_step1',data)
@http.route(['/event/registration/step2'], type='http', auth='user', website=True, sitemap=False,csrf=False)
def event_registration_step2(self,**post):


+ 1285
- 24
i18n/fr.po
File diff suppressed because it is too large
View File


+ 9
- 1
models/__init__.py View File

@ -7,4 +7,12 @@ from . import event
from . import product
from . import membership
from . import payment_transaction
from . import partner
from . import partner
from . import booking_product
from . import booking_event
from . import booking_location
from . import booking_room
from . import booking_questionnaire
from . import booking_event_registration
from . import booking_donation
from . import booking_sale_order

+ 18
- 0
models/booking_donation.py View File

@ -0,0 +1,18 @@
from odoo import models, fields, api
class DonationDonation(models.Model):
_inherit = 'donation.donation'
event_registration_id=fields.Many2one(
'event.registration',
String='Event registration',
index=True,
readonly=True,
track_visibility='onchange',
)

+ 185
- 0
models/booking_event.py View File

@ -0,0 +1,185 @@
from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError,Warning
from psycopg2 import sql, DatabaseError
from werkzeug import utils
class EventType(models.Model):
_inherit = "event.type"
_description = 'Event Template'
booking_event = fields.Boolean(string="Booking event", tracking=True)
booking_option_ids=fields.One2many('booking.option','event_type_id','booking options')
booking_questionnaire_id=fields.Many2one(
'booking.questionnaire',
String='Questionnaire',
index=True,
track_visibility='onchange',
ondelete='cascade'
)
class EventBookingOptions(models.Model):
_name='booking.option'
_description='booking options for events'
booking_option_id=fields.Many2one('product.product',string='booking options',domain="[('booking_option_product','=','True')]")
name=fields.Char(related='booking_option_id.name')
booking_option_price=fields.Monetary('Price',currency_field='currency_id')
booking_option_member_price=fields.Monetary('Member price',currency_field='currency_id')
booking_option_super_member_price=fields.Monetary('Super member price',currency_field='currency_id')
event_type_id = fields.Many2one(
'event.type',
String='Event type',
index=True,
readonly=True,
track_visibility='onchange',
ondelete='cascade'
)
event_id = fields.Many2one(
'event.event',
String='Event',
index=True,
readonly=True,
track_visibility='onchange',
ondelete='cascade'
)
@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,
track_visibility='onchange',
ondelete='restrict',
default=_default_currency
)
@api.onchange('booking_option_id')
def onchange_booking_option(self):
#for option in self:
if self.booking_option_id:
bo= self.env['product.product'].search([('id',"=",int(self.booking_option_id))])
self.booking_option_price= bo.lst_price
# class BookingEvent(models.Model):
# _inherit = "event.event"
# _description = 'Event'
# booking_event = fields.Boolean(string="Booking event", tracking=True)
# question_ids=fields.One2many(
# 'event.question',
# 'event_id',
# string='Questions'
# )
# booking_option_ids=fields.One2many('booking.option','event_id','booking options')
# @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
#)
# booking_price=fields.Monetary('Price',currency_field='currency_id')
# booking_member_price=fields.Monetary('Member price',currency_field='currency_id')
# booking_super_member_price=fields.Monetary('Super member price',currency_field='currency_id')
# booking_down_payment=fields.Monetary('Down payment',currency_field='currency_id')
# booking_product_id=fields.Many2one('product.product',string='booking product',domain="[('booking_product','=','True')]")
# @api.depends('event_type_id')
# def _compute_booking_event(self):
# self.booking_event=self.event_type_id.booking_event
# @api.onchange('event_type_id')
# def onchange_state(self):
# self.booking_event=self.event_type_id.booking_event
# booking_option=self.env['booking.option'].search([('event_type_id','=',int(self.event_type_id))])
# if booking_option:
# on supprime les options existantes:
# self.booking_option_ids=False
# on rappatrie les options du modèle
# for option in booking_option:
# vals={}
# vals['event_id']=self.id
# vals['booking_option_id']=option.booking_option_id
# vals['booking_option_price']=option.booking_option_price
# vals['currency_id']=option.currency_id
# self.booking_option_ids = [(0, 0, vals)]
# if self.event_type_id.booking_questionnaire_id:
# on supprime les question existantes:
# self.question_ids=False
# questions=self.env['booking.question'].search([('questionnaire_id','=',int(self.event_type_id.booking_questionnaire_id))])
# on rappatrie les question
# for question in questions:
# vals={}
# vals['event_id']=self.id
# vals['sequence']=question.sequence
# vals['question']=question.question
# self.question_ids = [(0, 0, vals)]
#super(event, self).write(vals)
#self.booking_option_ids=self.event_type_id.booking_option_ids
class event_question(models.Model):
_name = 'event.question'
_description = 'event question'
question=fields.Text(string='question')
sequence = fields.Integer(string="sequence", default=10)
event_id = fields.Many2one(
'event.event',
String='Questionnaire',
index=True,
readonly=True,
track_visibility='onchange',
ondelete='cascade'
)
class event_partner_category(models.Model):
_name = 'event.partner_category'
_description = 'map partner categories vs member or super-member for pricing'
partner_category_id=fields.Many2one(
'res.partner.category',
String='Category',
index=True,
track_visibility='onchange',
ondelete='cascade'
)
status=fields.Selection(selection=[('member','Member'),('supermember','Super Member')])
class event_membership_product(models.Model):
_name = 'event.membership_product'
_description = 'membership product'
membership_product_id=fields.Many2one('product.product',string='Membership product',domain="[('booking_option_product','=','True')]")

+ 392
- 0
models/booking_event_registration.py View File

@ -0,0 +1,392 @@
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
)

+ 14
- 0
models/booking_location.py View File

@ -0,0 +1,14 @@
from odoo import models, fields, api
class booking_location(models.Model):
_name = 'booking.location'
_description = 'booking location'
name = fields.Char('name',required=True)
description = fields.Text('description')
capacity = fields.Integer('max capacity')
available_seats = fields.Integer('available seats')

+ 0
- 0
models/booking_partner.py View File


+ 26
- 0
models/booking_product.py View File

@ -0,0 +1,26 @@
from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError
from psycopg2 import sql, DatabaseError
from werkzeug import utils
class ProductTemplate(models.Model):
_inherit = "product.template"
booking_product = fields.Boolean(string="booking product", tracking=True)
booking_option_product = fields.Boolean(string="booking option product", tracking=True)
# def _get_special_price(self, combination=False, product_id=False, add_qty=1, pricelist=False, parent_combination=False, only_template=False):
# special_price={}
# special_price['price_adherent']=100
# special_price['price_soutien']=100
# return special_price

+ 33
- 0
models/booking_questionnaire.py View File

@ -0,0 +1,33 @@
from odoo import models, fields, api,_
from odoo.exceptions import UserError, ValidationError,Warning
from psycopg2 import sql, DatabaseError
class booking_questionnaire(models.Model):
_name = 'booking.questionnaire'
_description = 'questionnaire pour inscription'
name=fields.Char(string='Name')
description=fields.Text(string='Description')
question_ids = fields.One2many(
'booking.question',
'questionnaire_id',
string='Questions'
)
class booking_question(models.Model):
_name = 'booking.question'
_description = 'question'
question=fields.Text(string='question')
sequence = fields.Integer(string="sequence", default=10)
questionnaire_id = fields.Many2one(
'booking.questionnaire',
String='Questionnaire',
index=True,
readonly=True,
track_visibility='onchange',
ondelete='cascade'
)

+ 46
- 0
models/booking_room.py View File

@ -0,0 +1,46 @@
from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError,Warning
class booking_room(models.Model):
_name = 'booking.room'
_description = 'booking room'
name2 = fields.Char('name',required=True)
name=fields.Char('room name',compute='_compute_room_name')
description = fields.Text('description')
capacity = fields.Integer('max capacity')
available_seats = fields.Integer('available seats')
location_id=fields.Many2one('booking.location', string='location')
def _compute_room_name(self):
for rec in self:
rec.name=''
if rec.name2:
rec.name=rec.name2+'('+str(rec.capacity)+')'
class booking_room_occupation(models.Model):
_name = 'booking.room.occupation'
_description = 'room occupation'
room_id = fields.Many2one('booking.room', string='room')
event_id=fields.Many2one('event.event',domain="[('date_begin','>=',context_today().strftime('%Y-%m-%d 00:00:00'))]")
event_registration_id = fields.Many2one('event.registration', string='event registration',domain="['&',('event_id', '=', event_id),('room_id', '=', False),('event_id.booking_event', '=', True)]")
name=fields.Char(related='event_registration_id.name')
date_begin=fields.Datetime(related='event_registration_id.event_id.date_begin')
date_end=fields.Datetime(related='event_registration_id.event_id.date_begin')
@api.model
def create(self,vals):
res=super(booking_room_occupation, self).create(vals)
#event_reg=self.env['booking.room.occupation'].search([])
event_reg=self.env['event.registration'].search([('id','=',int(res.event_registration_id))])
event_reg.room_id= res.room_id
return res

+ 39
- 0
models/booking_sale_order.py View File

@ -0,0 +1,39 @@
from odoo import models, fields, api
class SaleOrder(models.Model):
_inherit = 'sale.order'
def write(self,vals):
res = super(SaleOrder, self).write(vals)
if self.state=='sale':
#on recherche si le devis est lié à une booking inscription
event_registration=self.env['event.registration'].search(['|','|',('order_id','=',int(self.id)),('down_payment_order_id','=',int(self.id)),('balance_order_id','=',int(self.id))])
#event_registration=self.env['event.registration'].search([('order_id','=',int(self.id))])
if event_registration:
if event_registration.payment_status=='paid':
amount=0
for option in event_registration.option_ids:
prd=self.env['product.product'].search([('id','=',int(option.booking_option_id)),('donation','=',True)])
if prd:
#au niveau de l'événement,on recherche le montant du don en fonction du statut:
booking_option=self.env['booking.option'].search([('event_id','=',int(event_registration.event_id)),('booking_option_id','=',int(option.booking_option_id))])
if booking_option:
if event_registration.partner_id.member_status=='not member' : amount=booking_option.booking_option_price
if event_registration.partner_id.member_status=='member': amount=booking_option.booking_option_member_price
if event_registration.partner_id.member_status=='super member': amount=booking_option.booking_option_super_member_price
self.env['event.registration'].create_donation(event_registration.id,event_registration.partner_id,option.booking_option_id,amount)

+ 49
- 4
models/event.py View File

@ -1,6 +1,3 @@
from odoo import models, fields, api
from odoo.exceptions import UserError, ValidationError,Warning
from psycopg2 import sql, DatabaseError
@ -26,7 +23,7 @@ class EventTagCategory(models.Model):
calendar_id=fields.Char('google calendar id')
class EventEvent(models.Model):
class KalachakraEvent(models.Model):
_inherit = "event.event"
_description = 'Event'
@ -48,6 +45,54 @@ class EventEvent(models.Model):
online_link=fields.Char('link')
online_id=fields.Char('id')
online_password=fields.Char('password')
booking_event = fields.Boolean(string="Booking event", tracking=True)
question_ids=fields.One2many(
'event.question',
'event_id',
string='Questions'
)
booking_option_ids=fields.One2many('booking.option','event_id','booking options')
booking_price=fields.Monetary('Price',currency_field='currency_id')
booking_member_price=fields.Monetary('Member price',currency_field='currency_id')
booking_super_member_price=fields.Monetary('Super member price',currency_field='currency_id')
booking_down_payment=fields.Monetary('Down payment',currency_field='currency_id')
booking_product_id=fields.Many2one('product.product',string='booking product',domain="[('booking_product','=','True')]")
@api.onchange('event_type_id')
def onchange_state(self):
self.booking_event=self.event_type_id.booking_event
booking_option=self.env['booking.option'].search([('event_type_id','=',int(self.event_type_id))])
if booking_option:
#on supprime les options existantes:
self.booking_option_ids=False
#on rappatrie les options du modèle
for option in booking_option:
vals={}
vals['event_id']=self.id
vals['booking_option_id']=option.booking_option_id
vals['booking_option_price']=option.booking_option_price
vals['currency_id']=option.currency_id
self.booking_option_ids = [(0, 0, vals)]
if self.event_type_id.booking_questionnaire_id:
#on supprime les question existantes:
self.question_ids=False
questions=self.env['booking.question'].search([('questionnaire_id','=',int(self.event_type_id.booking_questionnaire_id))])
#on rappatrie les question
for question in questions:
vals={}
vals['event_id']=self.id
vals['sequence']=question.sequence
vals['question']=question.question
self.question_ids = [(0, 0, vals)]
@api.model
def _default_currency(self):


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

@ -2,3 +2,18 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_kalachakra_membership,kalachakra.membership,model_kalachakra_membership,base.group_user,1,1,1,1
access_booking_booking_option,booking.booking_option,model_booking_option,base.group_user,1,1,1,1
access_booking_location,booking.booking_location,model_booking_location,base.group_user,1,1,1,1
access_booking_room,booking.booking_room,model_booking_room,base.group_user,1,1,1,1
access_booking_room_occupation,booking.booking_room_occupation,model_booking_room_occupation,base.group_user,1,1,1,1
access_booking_questionnaire,booking.booking_questionnaire,model_booking_questionnaire,base.group_user,1,1,1,1
access_booking_questionnaire_question,booking.booking_question,model_booking_question,base.group_user,1,1,1,1
access_booking_event_question,booking.event_question,model_event_question,base.group_user,1,1,1,1
access_event_registration,event.registration,model_event_registration,base.group_user,1,1,1,1
access_event_registration_questionnaire,event.registration_questionnaire,model_event_registration_questionnaire,base.group_user,1,1,1,1
access_event_registration_option,event.registration_option,model_event_registration_option,base.group_user,1,1,1,1
access_event_partner_category,event.partner_category,model_event_partner_category,base.group_user,1,1,1,1
access_event_membership_product,event.membership_product,model_event_membership_product,base.group_user,1,1,1,1

+ 111
- 0
static/js/booking.js View File

@ -0,0 +1,111 @@
odoo.define('booking.main', function (require) {
$(document).ready(function() {
$('#medical_info').hide()
$('#booking_total_price').text(
$('#booking_price_product').val()+' €'
);
});
$( "#medical_concern" ).change(function() {
if (this.value=='have medical concern')
{
$('#medical_info').show()
$("medical_info_div").addClass("s_website_form_required");
$("medical_information").prop('required',true);
}
else
{
$('#medical__info').hide()
$("medical_info_div").removeClass("s_website_form_required");
$("medical_information").prop('required',false);
}
});
$( "#back_button2" ).click(function() {
history.back()
});
$( "#back_button1" ).click(function() {
history.back()
});
$(":checkbox").change(function() {
if(this.value==$("#membership_product").val() && this.checked)
{
if ($("#status").val()=='standard') {$("#status2").val('member')}
}
if(this.value==$("#membership_product").val() && this.checked==false)
{
if ($("#status").val()=='standard'){$("#status2").val('standard')}
}
//recalcul du prix total
if ($("#status2").val()=='standard')
{
$("#your_status").text('standard')
$("#price_of_the_stay").text($("#booking_price").val()+' €')
$("#total_price").val($("#booking_price").val())
}
if ($("#status2").val()=='member')
{
$("#your_status").text('member')
$("#price_of_the_stay").text($("#booking_member_price").val()+' €')
$("#total_price").val($("#booking_member_price").val())
}
if ($("#status2").val()=='super member')
{
$("#your_status").text('super member')
$("#price_of_the_stay").text($("#booking_super_member_price").val()+' €')
$("#total_price").val($("#booking_super_member_price").val())
}
$( ":checkbox" ).each(function( index ) {
var l=this.name.length
var i=this.name.substring(2,l-1)
if (this.value==$("#membership_product").val())
{
var option_price_str='#o_standard'+i
}
else
{
var option_price_str='#o_'+$("#status2").val()+i
}
option_price=$(option_price_str).val()
total_price=$("#total_price").val()
if(this.checked) {
$("#total_price").val(parseInt(total_price)+parseInt(option_price))
}
});
$("#booking_total_price").text($("#total_price").val()+' €');
});
});

+ 155
- 0
views/booking_event.xml View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record model="ir.ui.view" id="partner_category_list">
<field name="name">partner category list</field>
<field name="model">event.partner_category</field>
<field name="arch" type="xml">
<tree>
<field name="partner_category_id"/>
<field name="status"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="membership_product_list">
<field name="name">Membership product list</field>
<field name="model">event.membership_product</field>
<field name="arch" type="xml">
<tree>
<field name="membership_product_id"/>
</tree>
</field>
</record>
<record id="booking_event_type_view_form" model="ir.ui.view">
<field name="name">event.type.view.form.inherit.booking</field>
<field name="model">event.type</field>
<field name="inherit_id" ref="event.view_event_type_form" />
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_title']" position="after">
<div class="row o_settings_container" name="event_type_booking">
<div class="col-12 col-lg-8 o_setting_box">
<div class="o_setting_left_pane">
<field name="booking_event"/>
</div>
<div class="o_setting_right_pane">
<label for="booking_event"/>
<div class="row mt16" attrs="{'invisible': [('booking_event', '=', False)]}">
<div class="col-12">
<label for="booking_questionnaire_id"/>
<field name="booking_questionnaire_id"/>
<field name="booking_option_ids" style="width: 100%;">
<tree string="Options" editable="bottom">
<field name="booking_option_id"/>
<field name="booking_option_price" />
<field name="booking_option_member_price" />
<field name="booking_option_super_member_price" />
</tree>
</field>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="booking_event_view_form" model="ir.ui.view">
<field name="name">event.view.form.inherit.booking</field>
<field name="model">event.event</field>
<field name="inherit_id" ref="event.view_event_form" />
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_title']" position="after">
<div class="row o_settings_container" name="event_type_booking">
<div class="col-12 col-lg-2 o_setting_box">
<div class="o_setting_left_pane">
<field name="booking_event"/>
</div>
<div class="o_setting_right_pane">
<label for="booking_event"/>
</div>
</div>
</div>
</xpath>
<xpath expr="//page[@name='tickets']" position="before">
<page string="Prices" name="booking" attrs="{'invisible':[('booking_event','=',False)]}">
<group style="width:25%%">
<field name="booking_product_id" attrs="{'required': [('booking_event','=', True)]}"/>
<field name="booking_price" attrs="{'required': [('booking_event','=', True)]}"/>
<field name="booking_member_price" attrs="{'required': [('booking_event','=', True)]}"/>
<field name="booking_super_member_price" attrs="{'required': [('booking_event','=', True)]}"/>
<field name="booking_down_payment" attrs="{'required': [('booking_event','=', True)]}"/>
</group>
</page>
</xpath>
<xpath expr="//page[@name='booking']" position="after">
<page string="Options" name="booking_options" attrs="{'invisible':[('booking_event','=',False)]}">
<group style="width:100%%">
<field name="booking_option_ids" style="width: 100%;">
<tree string="Options" editable="bottom">
<field name="booking_option_id"/>
<field name="booking_option_price" />
<field name="booking_option_member_price" />
<field name="booking_option_super_member_price" />
</tree>
</field>
</group>
</page>
<page string="Questions" name="booking_questions" attrs="{'invisible':[('booking_event','=',False)]}">
<group style="width:100%%">
<field name="question_ids" style="width: 100%;">
<tree string="Questions" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="question" />
</tree>
</field>
</group>
</page>
</xpath>
<xpath expr="//page[@name='tickets']" position="replace">
</xpath>
</field>
</record>
<record model="ir.actions.act_window" id="partner_category_action">
<field name="name">Partner categories</field>
<field name="res_model">event.partner_category</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.actions.act_window" id="membership_product_action">
<field name="name">Membership product</field>
<field name="res_model">event.membership_product</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="booking_title_menu" name ="Booking"
parent="event.event_main_menu" groups="event.group_event_user" sequence="99"/>
<menuitem id="booking_partner_category_menu" action="partner_category_action"
parent="booking_title_menu" groups="event.group_event_user" sequence="2"/>
<menuitem id="booking_membership_product__menu" action="membership_product_action"
parent="booking_title_menu" groups="event.group_event_user" sequence="3"/>
</odoo>

+ 208
- 0
views/booking_event_registration.xml View File

@ -0,0 +1,208 @@
<odoo>
<record model="ir.actions.act_window" id="action_view_event_registration_questionnaire">
<field name="name">Booking Questionnaire</field>
<field name="res_model">event.registration_questionnaire</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_event_registration_id': active_id}</field>
</record>
<record id="event_registration_questionnaire_search" model="ir.ui.view">
<field name="name">event_registration_questionnaire.search</field>
<field name="model">event.registration_questionnaire</field>
<field name="arch" type="xml">
<search string="Search registrant">
<field name="event_registration_id"/>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_view_event_registration_option">
<field name="name">Booking Options</field>
<field name="res_model">event.registration_option</field>
<field name="view_mode">tree,form</field>
<field name="context">{'search_default_event_registration_id': active_id}</field>
</record>
<record id="registration_action_orders" model="ir.actions.act_window">
<field name="name">Sales Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="search_view_id" ref="sale.sale_order_view_search_inherit_sale"/>
<field name="context">{}</field>
<field name="domain">[('state', 'not in', ('draft', 'sent', 'cancel'))]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<record id="event_registration_option_search" model="ir.ui.view">
<field name="name">event_registration_option.search</field>
<field name="model">event.registration_option</field>
<field name="arch" type="xml">
<search string="Search registrant">
<field name="event_registration_id"/>
</search>
</field>
</record>
<record id="event_registration_view_form" model="ir.ui.view">
<field name="name">event.type.view.form.inherit.booking</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_event_registration_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='attendee']" position="inside">
<field name="gender"/>
<field name="age"/>
<field name="medical_concern"/>
<field name="medical_information"/>
<field name="medical_contact_name"/>
<field name="medical_contact_phone"/>
<field name="room_id"/>
<field name="down_payment"/>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(action_view_event_registration_questionnaire)d" type="action"
class="oe_stat_button" icon="fa-question" string="Questionnaire">
</button>
</xpath>
<xpath expr="//div[@name='button_box']" position="inside">
<button name="%(action_view_event_registration_option)d" type="action"
class="oe_stat_button" icon="fa-bed" string="Options">
</button>
</xpath>
<xpath expr="//button[@name='action_cancel']" position="after">
<button name="action_event_registration_generate_order" type="object"
states="open" string="Generate quotation(s)">
</button>
</xpath>
<xpath expr="//group[@name='event']" position="after">
<group string="Payments" name="payments">
<field name="order_id"/>
<field name="down_payment_order_id"/>
<field name="balance_order_id"/>
</group>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="event_registration_questionnaire_list" >
<field name="name">event registration questionnaire List</field>
<field name="model">event.registration_questionnaire</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="question"/>
<field name="answer"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="event_registration_option_list" >
<field name="name">event registration option List</field>
<field name="model">event.registration_option</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="booking_option_id"/>
<!-- <field name="booking_option_price"/> -->
</tree>
</field>
</record>
<record id="event_registration_view_kanban" model="ir.ui.view">
<field name="name">booking.event.registration.kanban.inherit</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.event_registration_view_kanban"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='email']" position="after">
<field name="room_id" />
</xpath>
<xpath expr="//field[@name='event_ticket_id']" position="after">
<field name="kanban_color" />
</xpath>
<xpath expr="//kanban[@class='o_event_attendee_kanban_view']" position="attributes">
<attribute name="default_group_by">room_id</attribute>
</xpath>
<!-- <xpath expr="/kanban/templates/t[3]/div/div/div/div/div/span" position="replace">
<span attrs="{'invisible': [('partner_id', '=', False)]}">Booked by <field name="partner_id" /> (<field name="gender" />)</span>
</xpath> -->
<xpath expr="/kanban/templates/t[3]/div" position="replace">
<!-- <attribute name="style">background-color:red</attribute> -->
<div t-attf-class="oe_kanban_global_click oe_kanban_color_#{record.kanban_color.raw_value} o_event_registration_kanban container-fluid p-0" t-attf-style="background-color:##{record.kanban_color.raw_value};">
<div class="row h-100">
<div class="col-9 pr-0">
<div class="oe_kanban_content h-100">
<div class="o_kanban_record_body pt-1 pl-2 h-100 d-flex flex-column">
<b class="o_kanban_record_title"><field name="name"/></b>
<field name="event_id" invisible="context.get('default_event_id')" />
<span attrs="{'invisible': [('partner_id', '=', False)]}">Booked by <field name="partner_id" /></span>
<div id="event_ticket_id" class="o_field_many2manytags o_field_widget d-flex mt-auto">
<t t-if="record.event_ticket_id.raw_value">
<div t-attf-class="badge badge-pill o_tag_color_#{(record.event_ticket_id.raw_value % 11) + 1}" >
<b><span class="o_badge_text"><t t-esc="record.event_ticket_id.value"/></span></b>
</div>
</t>
</div>
</div>
</div>
</div>
<div id="event_attendees_kanban_icons" class="col-3 pl-0">
<t t-call="event_attendees_kanban_icons_desktop"/>
<t t-call="event_attendees_kanban_icons_mobile"/>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="event_registration_view_tree" model="ir.ui.view">
<field name="name">booking.event.registration.tree.inherit</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_event_registration_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='event_ticket_id']" position="replace">
<field name="room_id" />
<field name="payment_status" />
</xpath>
</field>
</record>
<record id="view_registration_search" model="ir.ui.view">
<field name="name">event.registration.search.inherit</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_registration_search"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='partner']" position="after">
<filter string="Room" name="room_id" domain="[]" context="{'group_by':'room_id'}"/>
</xpath>
</field>
</record>
</odoo>

+ 33
- 0
views/booking_event_templates_list.xml View File

@ -0,0 +1,33 @@
<odoo>
<template id="events_list" inherit_id="website_event.events_list">
<xpath expr="//time[@itemprop='startDate']" position="after">
<t t-if="event.booking_event">
<time itemprop="endDate" t-att-datetime="event.date_end">
<span t-field="event.with_context(tz=event.date_tz).date_end" t-options="{'date_only': 'true', 'format': 'long'}"/>
</time>
<br/>
<b><font style="color: rgb(255, 0, 0); font-size: 11px;">Non adhérent : <span t-esc="int(event.booking_price)"/></font>
<font style="color: rgb(255, 0, 0); font-size: 11px;"> Adhérent et autres : <span t-esc="int(event.booking_member_price)"/></font>
<br/><font style="color: rgb(255, 0, 0); font-size: 11px;">Soutien et Sangha : <span t-esc="int(event.booking_super_member_price)"/></font></b>
</t>
</xpath>
<xpath expr="//time[@itemprop='startDate']" position="replace">
<t t-if="event.booking_event">
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'long'}"/> -
</t>
<t t-if="not event.booking_event">
<time itemprop="startDate" t-att-datetime="event.date_begin">
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'date_only': 'true', 'format': 'long'}"/> -
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'time_only': 'true', 'format': 'short'}"/>
</time>
</t>
</xpath>
</template>
</odoo>

+ 62
- 0
views/booking_event_templates_page_registration.xml View File

@ -0,0 +1,62 @@
<odoo>
<!-- on affiche pas les informations de tickets comme le prix ou gratuit -->
<!-- <template id="booking.event_sale_registration_template" inherit_id="website_event_sale.registration_template">
<xpath expr="//div[@class='px-2 text-dark mr-2 border-right d-flex align-items-center align-self-stretch']" position="replace">
</xpath>
</template> -->
<template id="event_registration_template" inherit_id="website_event.registration_template">
<xpath expr="//div[@class='col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0']" position="replace">
<t t-if="event.booking_event">
<div class="col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0">
<a t-attf-id="#{event.id}" t-attf-href="/booking/registration/options?event_id={{event.id}}" class="btn btn-primary btn-block" data-original-title="" title="" aria-describedby="tooltip34075">Register</a>
</div>
</t>
<t t-if="not event.booking_event">
<div class="col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0">
<a t-attf-id="#{event.id}" t-attf-href="/event/registration/step1?event_id={{event.id}}" class="btn btn-primary btn-block" data-original-title="" title="" aria-describedby="tooltip34075">Register</a>
</div>
<t t-if="event.seats_limited and event.seats_max and event.seats_available &lt;= (event.seats_max * 0.2)">
(only <t t-esc="event.seats_available"/> available)
</t>
</t>
</xpath>
<!-- on bloque la qte à 1 -->
<xpath expr="//select[@class='w-auto custom-select']" position="replace">
<select t-att-name="'nb_register-%s' % (tickets.id if tickets else 0)" class="w-auto custom-select">
<t t-set="seats_max_ticket" t-value="(not tickets or not tickets.seats_limited or tickets.seats_available &gt; 9) and 10 or tickets.seats_available + 1"/>
<t t-set="seats_max_event" t-value="(not event.seats_limited or event.seats_available &gt; 9) and 10 or event.seats_available + 1"/>
<t t-set="seats_max" t-value="min(seats_max_ticket, seats_max_event) if tickets else seats_max_event"/>
<option t-esc="1"/>
</select>
</xpath>
</template>
<template id="booking.event_description_full" inherit_id="website_event.event_description_full">
<xpath expr="//div[@class='o_wevent_sidebar_block'][1]" position="before">
<t t-if="event.booking_event">
<div class="o_wevent_sidebar_block">
<h6 class="o_wevent_sidebar_title">Participation</h6>
<h7 t-esc="'Non adhérent : '+str(int(event.booking_price))+' €'"/>
<br/>
<h7 t-esc="'Adhérent et autres : '+str(int(event.booking_member_price))+' €'"/>
<br/>
<h7 t-esc="'Soutien et Sangha : '+str(int(event.booking_super_member_price))+' €'"/>
</div>
</t>
</xpath>
</template>
</odoo>

+ 32
- 0
views/booking_location.xml View File

@ -0,0 +1,32 @@
<odoo>
<data>
<!-- explicit list view definition -->
<record model="ir.ui.view" id="location_list">
<field name="name">booking_location list</field>
<field name="model">booking.location</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="description"/>
<field name="capacity"/>
<field name="available_seats"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="location_action">
<field name="name">Locations</field>
<field name="res_model">booking.location</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="booking_location_menu" action="location_action"
parent="booking_title_menu" groups="event.group_event_user" sequence="1"/>
<menuitem action="product.product_template_action" id="menu_booking_product_template_action"
parent="booking_title_menu" sequence="1"/>
</data>
</odoo>

+ 38
- 0
views/booking_product.xml View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="product_template_search_view" model="ir.ui.view">
<field name="name">booking.product.template.search</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_search_view" />
<field name="arch" type="xml">
<filter name="filter_to_purchase" position="after">
<filter
name="filter_booking_product"
string="Booking products"
domain="[('booking_product', '=', True)]"
/>
<filter
name="filter_booking_product_options"
string="Booking option products"
domain="[('booking_option_product', '=', True)]"
/>
</filter>
</field>
</record>
<record id="product_template_form_view" model="ir.ui.view">
<field name="name">booking.product.template.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<div name="options" position="inside">
<field name="booking_product" />
<label for="booking_product" />
<field name="booking_option_product" />
<label for="booking_option_product" />
</div>
</field>
</record>
</odoo>

+ 57
- 0
views/booking_questionnaire.xml View File

@ -0,0 +1,57 @@
<odoo>
<data>
<record model="ir.ui.view" id="questionnaire_list">
<field name="name">booking_questionnaire list</field>
<field name="model">booking.questionnaire</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="description"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="questionnaire_form" >
<field name="name">booking_questionnaire Form</field>
<field name="model">booking.questionnaire</field>
<field name="arch" type="xml">
<form string="questionnaire_form" delete="0" create="0">
<sheet>
<group name="questionnaire">
<field name="name"/>
<field name="description"/>
</group>
<group name="questions">
<field name="question_ids">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="question"/>
</tree>
</field>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="questionnaire_action">
<field name="name">questionnaire</field>
<field name="res_model">booking.questionnaire</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="questionnaire"
id="menu_event_questionnaire"
sequence="10"
parent="event.event_main_menu"
action="questionnaire_action"
groups="event.group_event_user"/>
</data>
</odoo>

+ 2
- 0
views/booking_registration.xml View File

@ -0,0 +1,2 @@
<odoo>
</odoo>

+ 101
- 0
views/booking_room.xml View File

@ -0,0 +1,101 @@
<odoo>
<data>
<!-- explicit list view definition -->
<record model="ir.ui.view" id="room_list">
<field name="name">booking_room list</field>
<field name="model">booking.room</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="location_id"/>
<field name="description"/>
<field name="capacity"/>
<field name="available_seats"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="room_action">
<field name="name">Rooms</field>
<field name="res_model">booking.room</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="booking_room_menu" action="room_action"
parent="booking_title_menu" groups="event.group_event_user" sequence="2"/>
<record model="ir.ui.view" id="room_occupation_list">
<field name="name">booking_room_occupation list</field>
<field name="model">booking.room.occupation</field>
<field name="arch" type="xml">
<tree>
<field name="room_id"/>
<field name="name"/>
<field name="event_id"/>
<field name="date_begin"/>
<field name="date_end"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="room_occupation_form" >
<field name="name">booking_room_occupation Form</field>
<field name="model">booking.room.occupation</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group name="main">
<field name="room_id"/>
<field name="event_id"/>
<field name="event_registration_id"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_room_occupation_search" model="ir.ui.view">
<field name="name">room.occupation.search</field>
<field name="model">booking.room.occupation</field>
<field name="priority">1</field>
<field name="arch" type="xml">
<search string="Search Room">
<field string="Room" name="room_id"/>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="room_occupation_action">
<field name="name">Rooms occupation</field>
<field name="res_model">booking.room.occupation</field>
<field name="view_mode">tree,form,pivot</field>
</record>
<record id="action_registration" model="ir.actions.act_window">
<field name="name">Room occupation</field>
<field name="res_model">event.registration</field>
<field name="domain"></field>
<field name="view_mode">kanban,pivot,graph,tree,form</field>
<field name="context">{}</field>
<field name="domain">[('booking_event','=',True),('event_end','=',False)]</field>
<field name="search_view_id" ref="event.view_registration_search"/>
</record>
<menuitem id="booking_room_occupation_menu" action="action_registration"
parent="booking_title_menu" groups="event.group_event_user" sequence="3"/>
</data>
</odoo>

+ 319
- 0
views/booking_website_registration.xml View File

@ -0,0 +1,319 @@
<odoo>
<template id="assets_frontend" name="booking assets" inherit_id="web.assets_frontend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/booking/static/js/booking.js"></script>
</xpath>
</template>
<template id="registration_options_form" name="Registration options form">
<t t-call="website.layout">
<div class="container-fluid">
<h4 style="display: inline">Registering to : </h4><h4 style="display: inline" t-esc="event.name"></h4>
<h6>From <span t-field="event.date_begin" t-options='{"format": "dd/mm/yyyy hh:mm"}'/> to <span t-field="event.date_end" t-options='{"format": "dd/MM/yyyy hh:mm"}'/> </h6>
<h6> Your status : <span id="your_status" t-esc='status'></span></h6>
<h6>Price of the stay : <span id="price_of_the_stay" t-esc="str(int(price))+ ' €'"></span>
(standard price : <span t-esc="str(int(int(event.booking_price)))+ ' €'"></span>
, member price : <span t-esc="str(int(int(event.booking_member_price)))+ ' €'"></span>
, super member price : <span t-esc="str(int(int(event.booking_super_member_price)))+ ' €'"></span>)</h6>
<h6>Please select your booking options :</h6>
<form action="questionnaire" method="post" class="form js_website_submit_form">
<input type="hidden" id="booking_price_product" name="price_product" t-att-value="int(price)"/>
<input type="hidden" id="booking_price" name="booking_price" t-att-value="int(event.booking_price)"/>
<input type="hidden" id="booking_member_price" name="booking_member_price" t-att-value="int(event.booking_member_price)"/>
<input type="hidden" id="booking_super_member_price" name="booking_super_member_price" t-att-value="int(event.booking_super_member_price)"/>
<input type="hidden" id="total_price" name="total_price" t-att-value="int(price)"/>
<input type="hidden" name="event_id" t-att-value="event.id"/>
<input type="hidden" id="status" name="status" t-att-value="status"/>
<input type="hidden" id="status2" name="status2" t-att-value="status"/>
<input type="hidden" id="membership_product" name="membership_product" t-att-value="int(membership_product.membership_product_id)"/>
<t t-if="options">
<table class='table' width='50%'>
<thead>
<tr>
<th>Selection</th>
<th>Option</th>
<th>Standard price</th>
<th>Member price</th>
<th>Super member price</th>
</tr>
</thead>
<t t-set="i" t-value="1"/>
<t t-foreach="options" t-as="option">
<tr>
<td><input type="checkbox" t-att-name="'o['+str(i)+']'" t-att-value="int(option.booking_option_id)" t-att-id="'o['+str(i)+']'" /></td>
<td><span t-field="option.name"/></td>
<td><span t-esc="str(int(option.booking_option_price))+' €'"/></td>
<td><span t-esc="str(int(option.booking_option_member_price))+' €'"/></td>
<td><span t-esc="str(int(option.booking_option_super_member_price))+' €'"/></td>
</tr>
<input type="hidden" t-att-id="'o_standard'+str(i)" t-att-name="'o_standard['+str(i)+']'" t-att-value="int(option.booking_option_price)"/>
<input type="hidden" t-att-id="'o_member'+str(i)" t-att-name="'o_member['+str(i)+']'" t-att-value="int(option.booking_option_member_price)"/>
<input type="hidden" t-att-id="'o_super_member'+str(i)" t-att-name="'o_super_member['+str(i)+']'" t-att-value="int(option.booking_option_super_member_price)"/>
<t t-set="i" t-value="i+1"/>
</t>
<input type="hidden" name="nb_o" t-att-value="i-1"/>
</table>
</t>
<t t-if="not options">
<input type="hidden" name="nb_o" value="0"/>
</t>
<h4>Total Price : <span id="booking_total_price"></span></h4>
<span>Do you want to pay only the deposit </span><span style="display:inline" t-esc="'('+str(int(event.booking_down_payment))+' €) ?'"/>
<div class="form-group s_website_form_field col-2 s_website_form_custom s_website_form_required" data-type="char" data-name="Field">
<select id="down_payment" name="down_payment" class="form-control s_website_form_input">
<option name="yes" value="true" label="Oui"></option>
<option name="no" selected="false" value="false" label="Non"></option>
</select>
</div>
<section class="s_website_form pt16 pb16 o_colored_level">
<h6>Participant :</h6>
<div class="form-group s_website_form_field col-4 s_website_form_custom s_website_form_required " data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Name</span>
<span class="s_website_form_mark"> *</span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="name" t-att-value="partner.name" required="1" id="name" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-4 s_website_form_custom s_website_form_required " data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">First name</span>
<span class="s_website_form_mark"> *</span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="firstname" t-att-value="partner.firstname" required="1" id="firstname" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-3 s_website_form_custom s_website_form_required" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Age</span>
<span class="s_website_form_mark"> *</span>
</label>
<div class="col-sm">
<input type="number" class="form-control s_website_form_input" name="age" required="1" id="age" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-4 s_website_form_custom s_website_form_required" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Gender</span>
<span class="s_website_form_mark"> *</span>
</label>
<div class="col-sm">
<select id="gender" name="gender" class="form-control s_website_form_input">
<option name="male" value="male" label="Homme"></option>
<option name="femelle" value="femelle" label="Femme"></option>
</select>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-4 s_website_form_custom " data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Phone</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="phone" t-att-value="partner.phone" id="phone" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-4 s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Mobile</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="mobile" t-att-value="partner.mobile" id="mobile" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-5 s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">email</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="email" readonly="readonly" t-att-value="partner.email" id="email" style="cursor: auto;"/>
</div>
</div>
</div>
<button id="back_button1" type="button" class="btn btn-warning" >back</button>
<button type="submit" class="btn btn-primary" >Continue</button>
<br/>
</section>
</form>
</div>
</t>
</template>
<template id="registration_questionnaire_form" name="Registration questionnaire form">
<t t-call="website.layout">
<div class="container-fluid">
<h4 t-esc="'Inscription à : '+event.name"></h4>
<h6><u>Health quiz</u></h6>
<form action="/booking/payment_choice" method="post" class="form js_website_submit_form">
<input type="hidden" name="event_id" t-att-value="event.id"/>
<div class="form-group s_website_form_field col-6 s_website_form_custom s_website_form_required" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Medical concern</span>
<span class="s_website_form_mark"> *</span>
</label>
<div class="col-sm">
<select id="medical_concern" name="medical_concern" class="form-control s_website_form_input">
<option name="medical_concern" value="have medical concern" label="J'ai un soucis médical à signaler"></option>
<option name="medical_concern" selected="selected" value="have no medical concern" label="Je n'ai pas de soucis médical à signaler"></option>
<option name="medical_concern" value="no answer" label="Je ne veux pas répondre"></option>
</select>
</div>
</div>
</div>
<div id='medical_info'>
<div id="medical_info_div" class="form-group s_website_form_field col-6 s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Informations de nature médicale utiles à connaître (allergies, prise de médicaments, contre-indications…)</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<textarea class="form-control s_website_form_input" rows="5" name="medical_information" value="" id="medical_information" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-6 s_website_form_custom" data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Name of the medical contact</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="medical_contact_name" value="" id="medical_contact_name" style="cursor: auto;"/>
</div>
</div>
</div>
<div class="form-group s_website_form_field col-6 s_website_form_custom " data-type="char" data-name="Field">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="9ois9pkv0wv">
<span class="s_website_form_label_content">Phone of the medical contact</span>
<span class="s_website_form_mark"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" name="medical_contact_phone" value="" id="medical_contact_phone" style="cursor: auto;"/>
</div>
</div>
</div>
</div>
<br/>
<t t-if="questions">
<h6><u>Questionnaire :</u></h6>
<t t-set="i" t-value="1"/>
<t t-foreach="questions" t-as="question">
<div class="form-group s_website_form_field col-6 s_website_form_custom s_website_form_required ">
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px">
<span class="s_website_form_label_content" t-esc="question.question"></span>
</label>
<div class="col-sm">
<input type="text" class="form-control s_website_form_input" t-att-name="'a['+str(i)+']'" t-att-id="'#a'+str(question.id)"/>
</div>
</div>
</div>
<input type="hidden" t-att-name="'q['+str(i)+']'" t-att-value="question.question"/>
<t t-set="i" t-value="i+1"/>
</t>
<input type="hidden" name="nb_q" t-att-value="i"/>
</t>
<t t-if="not questions">
<input type="hidden" name="nb_q" value="0"/>
</t>
<div class="row">
<div class="col">
<br/>
<button id="back_button2" type="button" class="btn btn-warning" >back</button>
<button type="submit" class="btn btn-primary" >Continue</button>
<br/>
</div>
</div>
</form>
</div>
</t>
</template>
<template id="payment_choice_form" name="payment choice form">
<t t-call="website.layout">
<div class="container-fluid">
<div id="payment_method" class="mt-3 col-lg-6">
<h4 class="mb24">Pay with </h4>
<t t-call="payment.payment_tokens_list">
<t t-set="mode" t-value="'payment'"/>
<t t-set="submit_txt" t-value="submit_txt"/>
<t t-set="icon_right" t-value="1"/>
<t t-set="icon_class" t-value="'fa-chevron-right'"/>
<t t-set="submit_class" t-value="'btn btn-primary fa fa-gift'"/>
<t t-set="pms" t-value="tokens"/>
<t t-set="acquirers" t-value="acquirers"/>
<t t-set="order_id" t-value="order_id"/>
<t t-set="form_action" t-value="'/booking/payment/token'"/>
<t t-set="prepare_tx_url" t-value="'/booking/payment/transaction/'"/>
<t t-set="partner_id" t-value="partner"/>
<t t-set="back_button_icon_class" t-value="'fa-chevron-left'"/>
<t t-set="back_button_class" t-value="'btn btn-secondary'"/>
<t t-set="back_button_link" t-value="'/shop/cart'"/>
</t>
</div>
</div>
</t>
</template>
<template id="thankyou" name="booking form">
<t t-call="website.layout">
<div class="container-fluid">
<h2>Thank you for your registration !</h2>
<a href="/" class="ml-4 btn btn-secondary">back Home</a>
</div>
</t>
</template>
</odoo>

+ 41
- 40
views/event.xml View File

@ -15,7 +15,7 @@
</record>
<record id="kalachakra.event_view_form" model="ir.ui.view">
<record id="kalachakra_event_view_form" model="ir.ui.view">
<field name="name">event.view.form.inherit.kalachakra</field>
<field name="model">event.event</field>
<field name="inherit_id" ref="event.view_event_form" />
@ -28,53 +28,54 @@
<xpath expr="//field[@name='tag_ids']" position="after">
<field name="online_event"/>
<field name="free_participation"/>
<field name="recurring_event"/>
<field name="recurring_event_newsletter_id" attrs="{'invisible':[('recurring_event','=',False)]}"/>
<field name="online_event" attrs="{'invisible':[('booking_event','=',True)]}"/>
<field name="free_participation" attrs="{'invisible':[('booking_event','=',True)]}"/>
<field name="recurring_event" attrs="{'invisible':[('booking_event','=',True)]}"/>
<field name="recurring_event_newsletter_id" attrs="{'invisible':[('recurring_event','=',False),('booking_event','=',True)]}"/>
</xpath>
<xpath expr="//page[@name='event_communication']" position="before">
<page string="Participations" name="Participations" attrs="{'invisible':[('free_participation','=',True)]}">
<group style="width:40%%">
<field name="participation_product_id" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_standard_price" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_member_price" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_super_member_price" attrs="{'required': [('free_participation','=', False)]}"/>
</group>
</page>
</xpath>
<xpath expr="//page[@name='Participations']" position="after">
<page string="Subscriptions" name="Subscriptions" attrs="{'invisible':[('recurring_event','=',False)]}">
<group style="width:40%%">
<field name="subscription_product_id" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_standard_price" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_member_price" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_super_member_price" attrs="{'required': [('recurring_event','=', False)]}"/>
</group>
</page>
</xpath>
<page string="Participations" name="Participations" attrs="{'invisible':['|',('free_participation','=',True),('booking_event','=',True)]}">
<group style="width:40%%">
<field name="participation_product_id" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_standard_price" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_member_price" attrs="{'required': [('free_participation','=', False)]}"/>
<field name="participation_super_member_price" attrs="{'required': [('free_participation','=', False)]}"/>
</group>
</page>
<page string="Subscriptions" name="Subscriptions" attrs="{'invisible':['|',('free_participation','=',True),('booking_event','=',True)]}">
<group style="width:40%%">
<field name="subscription_product_id" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_standard_price" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_member_price" attrs="{'required': [('recurring_event','=', False)]}"/>
<field name="subscription_super_member_price" attrs="{'required': [('recurring_event','=', False)]}"/>
</group>
</page>
<page string="Online options" name="Online" attrs="{'invisible':['|',('online_event','=',False),('booking_event','=',True)]}">
<group style="width:80%%">
<field name="online_link" attrs="{'required': [('online_event','=', True)]}"/>
<field name="online_id"/>
<field name="online_password" attrs="{'required': [('online_event','=', True)]}"/>
</group>
</page>
<xpath expr="//page[@name='Subscriptions']" position="after">
<page string="Online options" name="Online" attrs="{'invisible':[('online_event','=',False)]}">
<group style="width:80%%">
<field name="online_link" attrs="{'required': [('online_event','=', True)]}"/>
<field name="online_id"/>
<field name="online_password" attrs="{'required': [('online_event','=', True)]}"/>
</group>
</page>
</xpath>
</field>
</record>


+ 5
- 0
views/event_templates_page_registration.xml View File

@ -2,6 +2,11 @@
<template id="kalachakra.event_registration_template" inherit_id="website_event.registration_template">
<xpath expr="//div[@class='col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0']" position="replace">
<t t-if="event.booking_event">
<div class="col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0">
<a t-attf-id="#{event.id}" t-attf-href="/booking/registration/options?event_id={{event.id}}" class="btn btn-primary btn-block" data-original-title="" title="" aria-describedby="tooltip34075">Register</a>
</div>
</t>
<t t-if="not event.booking_event">
<div class="col-lg-4 pt-3 pt-lg-0 pl-2 pl-lg-0">
<a t-attf-id="#{event.id}" t-attf-href="/event/registration/step1?event_id={{event.id}}" class="btn btn-primary btn-block" data-original-title="" title="" aria-describedby="tooltip34075">Register</a>


+ 69
- 10
views/website_event_registration.xml View File

@ -57,23 +57,82 @@
<div class="container-fluid">
<h4 style="display: inline">Registering to : </h4><h4 style="display: inline" t-esc="event.name"></h4>
<h6>From <span t-field="event.date_begin" t-options='{"format": "dd/mm/yyyy hh:mm"}'/> to <span t-field="event.date_end" t-options='{"format": "dd/MM/yyyy hh:mm"}'/> </h6>
<h6> Your status : <span id="your_status" t-esc='status'></span></h6>
<h6>your registration is taken into account</h6>
<b><h7 style="display: inline">Registering to : </h7><h7 style="display: inline" t-esc="event.name"></h7></b>
<br></br>
<h7>From <span t-field="event.date_begin" t-options='{"format": "dd/mm/yyyy hh:mm"}'/> to <span t-field="event.date_end" t-options='{"format": "dd/MM/yyyy hh:mm"}'/> </h7>
<br></br>
<h7> Your status : <span id="your_status" t-esc='status'></span></h7>
<br></br>
<br></br>
<h7>your registration is taken into account !</h7>
<br></br>
<br></br>
<t t-if="event.online_event">
<h6>Here is the information to attend on Zoom :</h6>
<ul class="list-group">
<li class="list-group-item">link : <span t-esc="event.online_link"></span></li>
<li class="list-group-item">id : <span t-esc="event.online_id"></span></li>
<li class="list-group-item">password : <span t-esc="event.online_password"></span></li>
<h7>Here is the information to attend on Zoom :</h7>
<br></br>
<ul>
<li>link : <span t-esc="event.online_link"></span></li>
<li>id : <span t-esc="event.online_id"></span></li>
<li>password : <span t-esc="event.online_password"></span></li>
</ul>
<br></br>
<br></br>
</t>
<h6>Afin de recevoir les information</h6>
<t t-if="event.free_participation">
<h7> The participation is free.</h7>
<br></br>
<br></br>
<h7>If you want to make a donation, click here : </h7><button type="submit" class="btn btn-primary" >Make a donation</button>
<br></br>
<br></br>
<t t-if="status=='standard'">
<h7>If you want to be a member, click here : </h7><button type="submit" class="btn btn-primary" >Become a member</button>
<br></br>
<br></br>
</t>
<t t-if="status=='member'">
<h7>If you want to be a super member, click here : </h7><button type="submit" class="btn btn-primary" >Become a super member</button>
<br></br>
<br></br>
</t>
</t>
<t t-if="not event.free_participation">
<button type="submit" class="btn btn-primary" >I pay the participation now</button>
<br></br>
<br></br>
<button type="submit" class="btn btn-primary" >I will pay the participation on the spot</button>
<br></br>
<br></br>
<t t-if="status=='standard'">
<h7>If you want to be a member, click here : </h7><button type="submit" class="btn btn-primary" >Become a member</button>
<br></br>
<br></br>
</t>
<t t-if="status=='member'">
<h7>If you want to be a super member, click here : </h7><button type="submit" class="btn btn-primary" >Become a super member</button>
<br></br>
<br></br>
</t>
</t>
<br></br>
<div class="row s_col_no_resize s_col_no_bgcolor">
<label class=" col-sm-auto s_website_form_label " for="pm84usjk8cf">
<span class="s_website_form_label_content">To stay informed I subscribe to the newsletter of the center</span>
</label>
<div class="col-sm">
<input type="checkbox" value="Yes" checked="checked" class="s_website_form_input" name="newsletter" required="1" id="pm84usjk8cf"/>
</div>
</div>
</div>
</t>
</template>
</odoo>

Loading…
Cancel
Save