| @ -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> | |||