@ -1,3 +1,4 @@ | |||
# -*- coding: utf-8 -*- | |||
from . import kalachakra | |||
from . import kalachakra | |||
from . import booking |
@ -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) |
@ -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', | |||
) | |||
@ -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')]") | |||
@ -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 | |||
) |
@ -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 +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 | |||
@ -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' | |||
) |
@ -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 |
@ -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) | |||
@ -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()+' €'); | |||
}); | |||
}); |
@ -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> |
@ -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> |
@ -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> |
@ -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 <= (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 > 9) and 10 or tickets.seats_available + 1"/> | |||
<t t-set="seats_max_event" t-value="(not event.seats_limited or event.seats_available > 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> |
@ -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> |
@ -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> |
@ -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> |
@ -0,0 +1,2 @@ | |||
<odoo> | |||
</odoo> |
@ -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> |
@ -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> |