@ -1,3 +1,4 @@ | |||||
# -*- coding: utf-8 -*- | # -*- 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> |