diff --git a/__manifest__.py b/__manifest__.py index 814e4543fcd04ea2db88abf773fd90692cc0c8a1..787be351f2b3a15ffe021c1147e51cfeca647593 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,6 +1,6 @@ { "name": "VRACOOP - Processus Click&Collect", - "summary": "CG SCOP - Processus Click&Collect", + "summary": "VRACOOP - Processus Click&Collect", "version": "12.0.1.0.1", "development_status": "Beta", "author": "Le Filament", @@ -18,7 +18,8 @@ "views/vracoop_retrait_views.xml", "views/vracoop_retrait_suivi_views.xml", "views/vracoop_templates.xml", - "views/sale_order.xml" + "views/sale_order.xml", + "views/delivery_views.xml" # "views/templates.xml" ] } diff --git a/controllers/main.py b/controllers/main.py index 4993bd641a69b5ac470543e1380b0c7655b052e4..fcb4e1a7010a609aeeb75edae456383ff1a997bb 100644 --- a/controllers/main.py +++ b/controllers/main.py @@ -17,6 +17,14 @@ class VracoopWebsiteSaleDelivery(WebsiteSale): return results + @http.route(['/shop/check_type_carrier'], type='json', auth='public', methods=['POST'], website=True, csrf=False) + def check_type_carrier(self, **post): + results = {} + if hasattr(self, '_check_carrier_type'): + results.update(self._check_carrier_type(**post)) + + return results + def _get_shop_payment_values(self, order, **kwargs): values = super(VracoopWebsiteSaleDelivery, self)._get_shop_payment_values(order, **kwargs) points_retrait = request.env['vracoop.point.retrait'].sudo().search([('website_published', '=', True)]) @@ -59,3 +67,14 @@ class VracoopWebsiteSaleDelivery(WebsiteSale): 'hour_retrait': hour_retrait } return {} + + def _check_carrier_type(self, **post): + order = request.website.sale_get_order() + carrier_id = int(post['carrier_id']) + carrier = request.env['delivery.carrier'].browse(carrier_id) + point_retrait = carrier.point_retrait + if order: + return {'carrier_id': carrier_id, + 'point_retrait': point_retrait + } + return {} diff --git a/controllers/main2.py b/controllers/main2.py deleted file mode 100644 index 903bf74387912df8977e7a882756fa160d3c61f5..0000000000000000000000000000000000000000 --- a/controllers/main2.py +++ /dev/null @@ -1,144 +0,0 @@ -# © 2019 Le Filament (<http://www.le-filament.com>) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields, http, tools, _ -from odoo.http import request -from odoo.addons.website_sale.controllers.main import WebsiteSale - - -class VracoopWebsiteSale(WebsiteSale): - - @http.route(['/shop/retrait'], type='http', auth="public", website=True) - def retrait(self, **post): - points_retrait = request.env['vracoop.point.retrait'].search([]) - print("--- points_retrait ---", str(points_retrait)) - order = request.website.sale_get_order() - # redirection = self.checkout_redirection(order) - # if redirection: - # return redirection - render_values = { - 'points_retrait': points_retrait, - } - # render_values = self._get_shop_payment_values(order, **post) - # render_values['only_services'] = order and order.only_services or False - - # if render_values['errors']: - # render_values.pop('acquirers', '') - # render_values.pop('tokens', '') - - return request.render("vracoop_click_and_collect.vracoop_retrait", render_values) - - @http.route(['/shop/checkout'], type='http', auth="public", website=True) - def checkout(self, **post): - res = super(VracoopWebsiteSale, self).checkout(**post) - order = request.website.sale_get_order() - - redirection = self.checkout_redirection(order) - if redirection: - return redirection - - if order.partner_id.id == request.website.user_id.sudo().partner_id.id: - return request.redirect('/shop/address') - - for f in self._get_mandatory_billing_fields(): - if not order.partner_id[f]: - return request.redirect('/shop/address?partner_id=%d' % order.partner_id.id) - - values = self.checkout_values(**post) - - if post.get('express'): - return request.redirect('/shop/retrait') - - values.update({'website_sale_order': order}) - - # Avoid useless rendering if called in ajax - if post.get('xhr'): - return 'ok' - return request.render("website_sale.checkout", values) - - - @http.route(['/shop/address'], type='http', methods=['GET', 'POST'], auth="public", website=True) - def address(self, **kw): - res = super(VracoopWebsiteSale, self).address(**kw) - Partner = request.env['res.partner'].with_context(show_address=1).sudo() - order = request.website.sale_get_order() - - redirection = self.checkout_redirection(order) - if redirection: - return redirection - - mode = (False, False) - can_edit_vat = False - def_country_id = order.partner_id.country_id - values, errors = {}, {} - - partner_id = int(kw.get('partner_id', -1)) - - # IF PUBLIC ORDER - if order.partner_id.id == request.website.user_id.sudo().partner_id.id: - mode = ('new', 'billing') - can_edit_vat = True - country_code = request.session['geoip'].get('country_code') - if country_code: - def_country_id = request.env['res.country'].search([('code', '=', country_code)], limit=1) - else: - def_country_id = request.website.user_id.sudo().country_id - # IF ORDER LINKED TO A PARTNER - else: - if partner_id > 0: - if partner_id == order.partner_id.id: - mode = ('edit', 'billing') - can_edit_vat = order.partner_id.can_edit_vat() - else: - shippings = Partner.search([('id', 'child_of', order.partner_id.commercial_partner_id.ids)]) - if partner_id in shippings.mapped('id'): - mode = ('edit', 'shipping') - else: - return Forbidden() - if mode: - values = Partner.browse(partner_id) - elif partner_id == -1: - mode = ('new', 'shipping') - else: # no mode - refresh without post? - return request.redirect('/shop/checkout') - - # IF POSTED - if 'submitted' in kw: - pre_values = self.values_preprocess(order, mode, kw) - errors, error_msg = self.checkout_form_validate(mode, kw, pre_values) - post, errors, error_msg = self.values_postprocess(order, mode, pre_values, errors, error_msg) - - if errors: - errors['error_message'] = error_msg - values = kw - else: - partner_id = self._checkout_form_save(mode, post, kw) - if mode[1] == 'billing': - order.partner_id = partner_id - order.onchange_partner_id() - if not kw.get('use_same'): - kw['callback'] = kw.get('callback') or \ - (not order.only_services and (mode[0] == 'edit' and '/shop/checkout' or '/shop/address')) - elif mode[1] == 'shipping': - order.partner_shipping_id = partner_id - - order.message_partner_ids = [(4, partner_id), (3, request.website.partner_id.id)] - if not errors: - return request.redirect(kw.get('callback') or '/shop/retrait') - - country = 'country_id' in values and values['country_id'] != '' and request.env['res.country'].browse(int(values['country_id'])) - country = country and country.exists() or def_country_id - render_values = { - 'website_sale_order': order, - 'partner_id': partner_id, - 'mode': mode, - 'checkout': values, - 'can_edit_vat': can_edit_vat, - 'country': country, - 'countries': country.get_website_sale_countries(mode=mode[1]), - "states": country.get_website_sale_states(mode=mode[1]), - 'error': errors, - 'callback': kw.get('callback'), - 'only_services': order and order.only_services, - } - return request.render("website_sale.address", render_values) diff --git a/datas/vracoop.time.csv b/datas/vracoop.time.csv index 29309b1c0edb1a2ebf0b881b1054e71593acfb75..415c5ff86bb2b3e21606f9cc307c498a42039609 100644 --- a/datas/vracoop.time.csv +++ b/datas/vracoop.time.csv @@ -1,8 +1,8 @@ id,name,first_noon_heure,first_morning_heure,last_noon_heure,last_morning_heure,availability_time,preparation_time -__export__.vracoop_time_lundi,Lundi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_mardi,Mardi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_mercredi,Mercredi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_jeudi,Jeudi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_vendredi,Vendredi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_samedi,Samedi,14.0,9.0,17.0,12.0,3.0,0.30 -__export__.vracoop_time_dimanche,Dimanche,14.0,9.0,17.0,12.0,3.0,0.30 +__export__.vracoop_time_lundi,Lundi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_mardi,Mardi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_mercredi,Mercredi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_jeudi,Jeudi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_vendredi,Vendredi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_samedi,Samedi,14.0,9.0,17.0,12.0,2.0,1.0 +__export__.vracoop_time_dimanche,Dimanche,14.0,9.0,17.0,12.0,2.0,1.0 diff --git a/models/__init__.py b/models/__init__.py index 4ed1947c3f03a6c998ec360b58b5292eb7fa7b27..bf52ecf5312fdb04e8afcac333a80dbaf101be9a 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -4,4 +4,5 @@ from . import vracoop_point_retrait from . import vracoop_retrait_time from . import vracoop_retrait_suivi -from . import sale_order \ No newline at end of file +from . import sale_order +from . import delivery \ No newline at end of file diff --git a/models/delivery.py b/models/delivery.py new file mode 100644 index 0000000000000000000000000000000000000000..30ba824d5279aec73e3855cf8a339359852ecdb8 --- /dev/null +++ b/models/delivery.py @@ -0,0 +1,10 @@ +# © 2019 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class VracoopDeliveryCarrier(models.Model): + _inherit = 'delivery.carrier' + + point_retrait = fields.Boolean(string='Point retrait') diff --git a/models/sale_order.py b/models/sale_order.py index 9f289fa5a9737a8acc7c4536a93537d98554818d..7937a027e32cdce6f56afab81c4077d9183d28b2 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -36,7 +36,6 @@ class SaleOrder(models.Model): def _update_hour(self, hour_retrait=None): self.ensure_one() # PointRetrait = self.env['vracoop.point.retrait'] - print("---- day retrait ---", str(hour_retrait)) hour = hour_retrait.split(":") hour_retrait = float('%s.%s' % (hour[0], hour[1])) self.write({'hour_retrait': hour_retrait}) diff --git a/models/vracoop_point_retrait.py b/models/vracoop_point_retrait.py index f78e579551450d1a8a1113de17035d8189763f4a..f6ca67476c21eef00be131f7572d4e76bec48a21 100644 --- a/models/vracoop_point_retrait.py +++ b/models/vracoop_point_retrait.py @@ -6,9 +6,10 @@ from odoo import models, fields, api # from datetime import date from dateutil.relativedelta import * from dateutil.easter import * -from dateutil.rrule import * +from dateutil.rrule import rrule, DAILY, MINUTELY, rruleset from dateutil.parser import * -from datetime import * +# from datetime import * +from datetime import datetime, timedelta class VracoopPointRetrait(models.Model): _name = "vracoop.point.retrait" @@ -68,85 +69,153 @@ class VracoopPointRetrait(models.Model): def slot_calculate(self): self.ensure_one() LIST_WEEK_DAY = [ - ('lundi',0), - ('mardi',1), - ('mercredi',2), - ('jeudi',3), - ('vendredi',4), - ('samedi',5), - ('dimanche',6), + ('lundi', 0), + ('mardi', 1), + ('mercredi', 2), + ('jeudi', 3), + ('vendredi', 4), + ('samedi', 5), + ('dimanche', 6), ] for rec in self: my_datetime = datetime.today() return_slot_list = [] vals = [] - list_week = list(rrule(DAILY, count=rec.nb_day_available, dtstart=datetime.today())) + exclure_days_nb = rec.vracoop_retrait_time_ids.search_count([ + ('vracoop_point_retrait_id', '=', rec.id), + ('active_day', '=', False)]) + count_day = rec.nb_day_available + exclure_days_nb + + list_week = list(rrule( + DAILY, + count=count_day, + dtstart=datetime.today())) + for week in list_week: - corresponding_line = rec.vracoop_retrait_time_ids.search([ - ('vracoop_point_retrait_id', '=', rec.id), ('name', '=', week.strftime("%A"))]) - for week_day in LIST_WEEK_DAY: - if week_day[0] == week.strftime("%A"): - byweekday = week_day[1] - time_available_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.availability_time) - hour = time_available_week.strftime("%H") - minute = time_available_week.strftime("%M") - interval = int(hour)*60 + int(minute) + exclure_the_day = rec.vracoop_retrait_time_ids.search([ + ('vracoop_point_retrait_id', '=', rec.id), + ('active_day', '=', False), + ('name', '=', week.strftime("%A"))]) + if exclure_the_day: + pass + else: + corresponding_line = rec.vracoop_retrait_time_ids.search([ + ('vracoop_point_retrait_id', '=', rec.id), + ('name', '=', week.strftime("%A"))]) + for week_day in LIST_WEEK_DAY: + if week_day[0] == week.strftime("%A"): + byweekday = week_day[1] + time_available_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.availability_time) + hour = time_available_week.strftime("%H") + minute = time_available_week.strftime("%M") + interval = int(hour)*60 + int(minute) - if week.day == my_datetime.day: - first_morning_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.first_morning_heure) - last_morning_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.last_morning_heure) - first_noon_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.first_noon_heure) - last_noon_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.last_noon_heure) - today_hour_available = my_datetime + timedelta(hours=corresponding_line.preparation_time) - if (today_hour_available > first_morning_hour_week) and (today_hour_available < last_morning_hour_week): - dtstart_morning = today_hour_available - dtstart_noon = first_noon_hour_week - elif (today_hour_available > first_noon_hour_week) and (today_hour_available < last_noon_hour_week): - dtstart_morning = today_hour_available - dtstart_noon = today_hour_available - elif (today_hour_available > last_morning_hour_week) and (today_hour_available < first_noon_hour_week): - dtstart_morning = today_hour_available - dtstart_noon = first_noon_hour_week - else: - dtstart_morning = today_hour_available - dtstart_noon = today_hour_available + if week.day == my_datetime.day: + first_morning_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.first_morning_heure) + last_morning_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.last_morning_heure) + first_noon_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.first_noon_heure) + last_noon_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.last_noon_heure) + today_hour_available = my_datetime + timedelta( + hours=corresponding_line.preparation_time) + if (today_hour_available > first_morning_hour_week) and (today_hour_available < last_morning_hour_week): + dtstart_morning = today_hour_available + dtstart_noon = first_noon_hour_week + elif (today_hour_available > first_noon_hour_week) and (today_hour_available < last_noon_hour_week): + dtstart_morning = today_hour_available + dtstart_noon = today_hour_available + elif (today_hour_available > last_morning_hour_week) and (today_hour_available < first_noon_hour_week): + dtstart_morning = today_hour_available + dtstart_noon = first_noon_hour_week + else: + dtstart_morning = today_hour_available + dtstart_noon = today_hour_available - list_slot_per_day_morning = list(rrule(MINUTELY, interval=interval, - byweekday=byweekday, - dtstart=dtstart_morning, - until=last_morning_hour_week)) - list_slot_per_day_noon = list(rrule(MINUTELY, interval=interval, - byweekday=byweekday, - dtstart=dtstart_noon, - until=last_noon_hour_week)) - else: - first_morning_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.first_morning_heure) - last_morning_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.last_morning_heure) - first_noon_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.first_noon_heure) - last_noon_hour_week = datetime(week.year, week.month, week.day) + timedelta(hours=corresponding_line.last_noon_heure) - list_slot_per_day_morning = list(rrule(MINUTELY, interval=interval, - byweekday=byweekday, - dtstart=first_morning_hour_week, - until=last_morning_hour_week)) - list_slot_per_day_noon = list(rrule(MINUTELY, interval=interval, - byweekday=byweekday, - dtstart=first_noon_hour_week, - until=last_noon_hour_week)) - slots = [] - for slot_per_day_morning in list_slot_per_day_morning: - first_slot = slot_per_day_morning.strftime("%H:%M") - slot_per_day_morning = slot_per_day_morning + timedelta(hours=corresponding_line.availability_time) - last_slot = slot_per_day_morning.strftime("%H:%M") - slots.append((first_slot,last_slot)) + list_slot_per_day_morning = list( + rrule( + MINUTELY, + interval=interval, + byweekday=byweekday, + dtstart=dtstart_morning, + until=last_morning_hour_week)) + list_slot_per_day_noon = list( + rrule( + MINUTELY, + interval=interval, + byweekday=byweekday, + dtstart=dtstart_noon, + until=last_noon_hour_week)) + else: + first_morning_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.first_morning_heure) + last_morning_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.last_morning_heure) + first_noon_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.first_noon_heure) + last_noon_hour_week = datetime( + week.year, week.month, week.day) + timedelta( + hours=corresponding_line.last_noon_heure) + list_slot_per_day_morning = list( + rrule( + MINUTELY, + interval=interval, + byweekday=byweekday, + dtstart=first_morning_hour_week, + until=last_morning_hour_week)) + list_slot_per_day_noon = list( + rrule( + MINUTELY, interval=interval, + byweekday=byweekday, + dtstart=first_noon_hour_week, + until=last_noon_hour_week)) + slots = [] + nb_sale_slot = 0 + for slot_per_day_morning in list_slot_per_day_morning: + first_slot = slot_per_day_morning.strftime("%H:%M") + slot_per_day_morning = slot_per_day_morning + timedelta( + hours=corresponding_line.availability_time) + last_slot = slot_per_day_morning.strftime("%H:%M") + + first_slot_hour = first_slot.split(":") + first_slot_float = float( + '%s.%s' % (first_slot_hour[0], first_slot_hour[1])) + nb_sale_slot = self.env['sale.order'].search_count( + [('vracoop_point_retrait_id', '=', rec.id), + ('day_retrait', '=', week.date()), + ('hour_retrait', '=', first_slot_float)]) + if nb_sale_slot < rec.nb_max_retrait: + slots.append((first_slot, last_slot)) - for slot_per_day_noon in list_slot_per_day_noon: - first_slot = slot_per_day_noon.strftime("%H:%M") - slot_per_day_noon = slot_per_day_noon + timedelta(hours=corresponding_line.availability_time) - last_slot = slot_per_day_noon.strftime("%H:%M") - slots.append((first_slot,last_slot)) + nb_sale_slot = 0 + for slot_per_day_noon in list_slot_per_day_noon: + first_slot = slot_per_day_noon.strftime("%H:%M") + slot_per_day_noon = slot_per_day_noon + timedelta( + hours=corresponding_line.availability_time) + last_slot = slot_per_day_noon.strftime("%H:%M") + nb_sale_slot = self.env['sale.order'].search_count( + [('vracoop_point_retrait_id', '=', rec.id), + ('day_retrait', '=', week.date()), + ('hour_retrait', '=', first_slot_float)]) + if nb_sale_slot < rec.nb_max_retrait: + slots.append((first_slot, last_slot)) - return_slot_list = slots - - vals.append((week.strftime("%a"), week, week.strftime("%b"), return_slot_list)) + return_slot_list = slots + if return_slot_list: + vals.append( + (week.strftime("%a"), + week, + week.strftime("%b"), return_slot_list)) return vals \ No newline at end of file diff --git a/static/src/js/vracoop_retrait.js b/static/src/js/vracoop_retrait.js index aef99a6d7f244d77abe23cc2ca4b6b8e91530be3..84f4daa01895389554ffc173608f788bdfa25dbf 100644 --- a/static/src/js/vracoop_retrait.js +++ b/static/src/js/vracoop_retrait.js @@ -32,9 +32,11 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var _onRetraitUpdateAnswer = function(result) { var $retrait_badge = $('#point_retrait input[name="point_retrait_type"][value=' + result.vracoop_point_retrait_id + ']'); - + // var $retrait_bloc = $('#slots_point_retrait_' + result.vracoop_point_retrait_id) + // console.log($retrait_bloc); if (result.status === true) { - $pay_button.data('disabled_reasons').carrier_selection = false; + // $retrait_bloc.removeClass('d-none'); + $pay_button.data('disabled_reasons').retrait_selection = false; $pay_button.prop('disabled', _.contains($pay_button.data('disabled_reasons'), true)); } else { @@ -45,6 +47,7 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var _onRetraitClick = function(ev) { $pay_button.data('disabled_reasons', $pay_button.data('disabled_reasons') || {}); $pay_button.prop('disabled', true); + $pay_button.data('disabled_reasons').retrait_selection = true; var vracoop_point_retrait_id = $(ev.currentTarget).val(); console.log(vracoop_point_retrait_id); var values = {'vracoop_point_retrait_id': vracoop_point_retrait_id}; @@ -54,16 +57,15 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var $retraits = $("#point_retrait input[name='point_retrait_type']"); $retraits.click(_onRetraitClick); - console.log($retraits); if ($retraits.length > 0) { $retraits.filter(':checked').click(); } - + var _onDayUpdateAnswer = function(result) { if (result.status === true) { - $pay_button.data('disabled_reasons').carrier_selection = false; + $pay_button.data('disabled_reasons').day_selection = false; $pay_button.prop('disabled', _.contains($pay_button.data('disabled_reasons'), true)); } else { @@ -73,6 +75,7 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var _onDayClick = function(ev) { $pay_button.data('disabled_reasons', $pay_button.data('disabled_reasons') || {}); + $pay_button.data('disabled_reasons').day_selection = true; $pay_button.prop('disabled', true); var day_retrait = $(ev.currentTarget).val(); console.log(day_retrait); @@ -91,7 +94,7 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var _onHourUpdateAnswer = function(result) { if (result.status === true) { - $pay_button.data('disabled_reasons').carrier_selection = false; + $pay_button.data('disabled_reasons').hour_selection = false; $pay_button.prop('disabled', _.contains($pay_button.data('disabled_reasons'), true)); } else { @@ -101,6 +104,7 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { var _onHourClick = function(ev) { $pay_button.data('disabled_reasons', $pay_button.data('disabled_reasons') || {}); + $pay_button.data('disabled_reasons').hour_selection = true; $pay_button.prop('disabled', true); var hour_retrait = $(ev.currentTarget).val(); var values = {'hour_retrait': hour_retrait}; @@ -115,4 +119,25 @@ odoo.define('vracoop_click_and_collect.vracoop_retrait', function (require) { $hours.filter(':checked').click(); } + var _onCarrierCheckType = function(result) { + var $carrier_badge = $('#delivery_carrier input[name="delivery_type"][value=' + result.carrier_id + '] ~ .badge.d-none'); + var $point_retrait = $('#point_retrait'); + if (result.point_retrait === true) { + $point_retrait.removeClass('d-none'); + } + else { + $point_retrait.addClass('d-none'); + } + }; + + var _onCarrierClick2 = function(ev) { + var carrier_id = $(ev.currentTarget).val(); + var values = {'carrier_id': carrier_id}; + dp.add(ajax.jsonRpc('/shop/check_type_carrier', 'call', values)) + .then(_onCarrierCheckType); + }; + + var $carriers = $("#delivery_carrier input[name='delivery_type']"); + $carriers.click(_onCarrierClick2); + }); diff --git a/static/src/scss/style.css b/static/src/scss/style.css index 1805a1709680527062d0075f1e2d76232ff8f29c..5409d6f3cbaa49e43ffa0c3e53fec319d4488142 100644 --- a/static/src/scss/style.css +++ b/static/src/scss/style.css @@ -18,10 +18,6 @@ text-align: center; } -.card label{ - margin: 0.5rem; -} - #point_retrait a.card-link{ font-size: 14px; font-weight: normal !important; @@ -181,4 +177,16 @@ content: '<'; font-size: 20px; color: #000; -} \ No newline at end of file +} + +#retrait_method .nav-tabs{ + border-bottom: 0px solid #dee2e6; +} + +#retrait_method h5, #retrait_method span{ + margin: 0.5rem; +} + +.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 160, 157, 0); +} diff --git a/views/delivery_views.xml b/views/delivery_views.xml new file mode 100644 index 0000000000000000000000000000000000000000..85da21e45289f5c4ddf5fba71a348a1905d24551 --- /dev/null +++ b/views/delivery_views.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + + <record id="vracoop_view_delivery_carrier_form" model="ir.ui.view"> + <field name="name">vracoop.delivery.carrier.website.form</field> + <field name="model">delivery.carrier</field> + <field name="inherit_id" ref="delivery.view_delivery_carrier_form"/> + <field name="arch" type="xml"> + <xpath expr="//group//group" position="inside"> + <field name="point_retrait"/> + </xpath> + </field> + </record> + +</odoo> \ No newline at end of file diff --git a/views/vracoop_retrait_views.xml b/views/vracoop_retrait_views.xml index cecb039a9c043fdddb32e68633deb7bcb4b2f536..26de969c93ce541045dbc222fb0bc4ada106c9c9 100644 --- a/views/vracoop_retrait_views.xml +++ b/views/vracoop_retrait_views.xml @@ -94,6 +94,8 @@ <field name="zip" placeholder="Code Postal" class="o_address_zip"/> <field name="country_id" placeholder="Pays" class="o_address_country" options='{"no_open": True, "no_create": True}'/> </div> + </group> + <group> <field name="nb_max_retrait"/> <field name="nb_day_available"/> </group> diff --git a/views/vracoop_templates.xml b/views/vracoop_templates.xml index a0be3dd5607722786e11cea3ba74d80d8a98f3a6..dea42f79e29949ee558a7148fea5f05854175997 100644 --- a/views/vracoop_templates.xml +++ b/views/vracoop_templates.xml @@ -2,20 +2,111 @@ <odoo> <template id="point_retrait_choose"> - <a class="card-link" data-toggle="collapse" t-att-href="'#slots_point_retrait_%i' % point_retrait.id"> - <label class="label-optional" t-field="point_retrait.name" t-att-for="'point_retrait_%i' % point_retrait.id"> - <!-- <input t-att-value="point_retrait.id" t-att-id="'point_retrait_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False"/> --> - <input t-att-value="point_retrait.id" t-att-id="'point_retrait_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False" t-att-class="'d-none' if point_retrait_nb == 1 else ''"/> - <span class="span_radio_button"> - <t t-esc="point_retrait.name"/> - </span> - </label> + + <a class="card-link " data-toggle="collapse" t-att-href="'#slots_point_retrait_%i' % point_retrait.id" t-att-id="'point_retrait_%i' % point_retrait.id"> + <input t-att-value="point_retrait.id" t-att-id="'point_retrait2_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False" t-att-class="'d-none' if point_retrait_nb == 1 else ''"/> </a> - <div class="collapse" data-parent="#retrait_method" t-att-id="'slots_point_retrait_%i' % point_retrait.id"> - <h4>Sélectionner le jour et le créneau pour votre retrait</h4> + <label class="label-optional" t-field="point_retrait.name" t-att-for="'point_retrait2_%i' % point_retrait.id"/> + + + <div class="collapse" data-parent="#retrait_method" t-att-id="'slots_point_retrait_%i' % point_retrait.id"> + <h5>Sélectionner le jour et le créneau pour votre retrait</h5> + <t t-set="list_slots" t-value="point_retrait.slot_calculate()"/> + + <div class="top-content mt-4 mb-4"> + <div class="container-fluid"> + <div t-att-id="'carousel_%i' % point_retrait.id" class="carousel slide" data-ride="carousel" data-interval="false"> + <ul class="nav nav-tabs carousel-inner row w-100 mx-auto" role="tablist"> + <t t-foreach="list_slots" t-as="slot"> + <t t-if="slot_first"> + <li class="nav-item carousel-item col-12 col-sm-6 col-md-4 col-lg-3 active"> + <a data-toggle="tab" class="nav-link active btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> + <label class=" label_radio_button" role="radio"> + <input t-attf-id='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}' name="day_select" type="radio" class="radio_hide" t-attf-value='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}'/> + <span class="span_radio_button"> + <t class="week_day" t-esc="slot[0]"/><br/> + <t t-esc="slot[1].day"/><br/> + <t t-esc="slot[2]"/> + </span> + </label> + </a> + </li> + </t> + <t t-else=""> + <li class="nav-item carousel-item col-12 col-sm-6 col-md-4 col-lg-3"> + <a data-toggle="tab" class="nav-link btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> + <label class=" label_radio_button" role="radio"> + <input t-attf-id='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}' name="day_select" type="radio" class="radio_hide" t-attf-value='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}'/> + <span class="span_radio_button"> + <t class="week_day" t-esc="slot[0]"/><br/> + <t t-esc="slot[1].day"/><br/> + <t t-esc="slot[2]"/> + </span> + </label> + </a> + </li> + </t> + </t> + </ul> + <a class="carousel-control-prev" t-att-href="'#carousel_%i' % point_retrait.id" role="button" data-slide="prev"> + <span class="carousel-control-prev-icon"></span> + <span class="sr-only">Previous</span> + </a> + <a class="carousel-control-next" t-att-href="'#carousel_%i' % point_retrait.id" role="button" data-slide="next"> + <span class="carousel-control-next-icon" ></span> + <span class="sr-only">Next</span> + </a> + </div> + </div> + </div> + + <div class="tab-content"> + <t t-foreach="list_slots" t-as="slot"> + <t t-if="slot_first"> + <div class="container tab-pane active" t-attf-id='#{slot[1].strftime("%A")}#{point_retrait.id}'> + <t t-foreach="slot[3]" t-as="slot_by_day"> + <label class="label_radio_button" role="radio"> + <input name="hour_select" type="radio" class="radio_hide" t-att-value="slot_by_day[0]" t-attf-id="#{slot_by_day_index}"/> + <span class="btn btn-outline-primary span_radio_button"> + <t t-esc="slot_by_day[0]"/> : + <t t-esc="slot_by_day[1]"/> + </span> + </label> + </t> + </div> + </t> + <t t-else=""> + <div class="container tab-pane fade" t-attf-id='#{slot[1].strftime("%A")}#{point_retrait.id}'> + <t t-foreach="slot[3]" t-as="slot_by_day"> + <label class=" label_radio_button" role="radio"> + <input t-attf-id="#{slot_by_day_index}" name="hour_select" type="radio" class="radio_hide" t-att-value="slot_by_day[0]"/> + <span class="btn btn-outline-primary span_radio_button"> + <t t-esc="slot_by_day[0]"/> : + <t t-esc="slot_by_day[1]"/> + </span> + </label> + </t> + </div> + </t> + </t> + </div> + </div> + <!-- <input t-att-value="point_retrait.id" t-att-id="'point_retrait2_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False" t-att-class="'d-none' if point_retrait_nb == 1 else ''"/> + <label class="label-optional" t-field="point_retrait.name" t-att-for="'point_retrait2_%i' % point_retrait.id"/> + <t t-if="point_retrait.street"> + <br/><span><t t-esc="point_retrait.street"/></span><br/> + </t> + <t t-if="point_retrait.street2"> + <span><t t-esc="point_retrait.street2"/></span><br/> + </t> + <span><t t-esc="point_retrait.city"/> + <t t-esc="point_retrait.zip"/></span> + + <div t-att-id="'slots_point_retrait_%i' % point_retrait.id"> + <h5>Sélectionner le jour et le créneau pour votre retrait</h5> <t t-set="list_slots" t-value="point_retrait.slot_calculate()"/> - <div class="top-content"> + <div class="top-content mt-4 mb-4"> <div class="container-fluid"> <div t-att-id="'carousel_%i' % point_retrait.id" class="carousel slide" data-ride="carousel" data-interval="false"> <ul class="nav nav-tabs carousel-inner row w-100 mx-auto" role="tablist"> @@ -93,40 +184,88 @@ </t> </div> </div> + --> </template> -<!-- <template id="day_point_retrait_choose"> - <div class="card collapse" t-att-id="'slots_point_retrait_%i' % point_retrait.id"> + <template id="point_retrait_one"> + + <!-- Si 1 seul point relais --> + <a class="card-link point_retrait_type" t-att-href="'#slots_point_retrait_%i' % point_retrait.id" t-att-id="'point_retrait_%i' % point_retrait.id"> + <label class="label-optional" t-field="point_retrait.name" t-att-for="'point_retrait_%i' % point_retrait.id"> + <!-- <input t-att-value="point_retrait.id" t-att-id="'point_retrait_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False"/> --> + <input t-att-value="point_retrait.id" t-att-id="'point_retrait2_%i' % point_retrait.id" type="radio" name="point_retrait_type" t-att-checked="order.vracoop_point_retrait_id and order.vracoop_point_retrait_id.id == point_retrait.id and 'checked' or False" t-att-class="'d-none' if point_retrait_nb == 1 else ''"/> + <span class="span_radio_button"> + <t t-esc="point_retrait.name"/><br/> + </span> + </label> + <t t-if="point_retrait.street"> + <br/><span><t t-esc="point_retrait.street"/></span><br/> + </t> + <t t-if="point_retrait.street2"> + <span><t t-esc="point_retrait.street2"/></span><br/> + </t> + <span><t t-esc="point_retrait.city"/> + <t t-esc="point_retrait.zip"/></span> + </a> + + <div t-att-id="'slots_point_retrait_%i' % point_retrait.id"> + <h5>Sélectionner le jour et le créneau pour votre retrait</h5> <t t-set="list_slots" t-value="point_retrait.slot_calculate()"/> - <ul class="nav nav-tabs justify-content-center" role="tablist"> - <t t-foreach="list_slots" t-as="slot"> - <t t-if="slot_first"> - <li class="nav-item"> - <a data-toggle="tab" class="nav-link active btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> - <t class="week_day" t-esc="slot[0]"/><br/> - <t t-esc="slot[1].day"/><br/> - <t t-esc="slot[2]"/> - </a> - </li> - </t> - <t t-else=""> - <li class="nav-item"> - <a data-toggle="tab" class="nav-link btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> - <t class="week_day" t-esc="slot[0]"/><br/> - <t t-esc="slot[1].day"/><br/> - <t t-esc="slot[2]"/> - </a> - </li> - </t> - </t> - </ul> + + <div class="top-content mt-4 mb-4"> + <div class="container-fluid"> + <div t-att-id="'carousel_%i' % point_retrait.id" class="carousel slide" data-ride="carousel" data-interval="false"> + <ul class="nav nav-tabs carousel-inner row w-100 mx-auto" role="tablist"> + <t t-foreach="list_slots" t-as="slot"> + <t t-if="slot_first"> + <li class="nav-item carousel-item col-12 col-sm-6 col-md-4 col-lg-3 active"> + <a data-toggle="tab" class="nav-link active btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> + <label class=" label_radio_button" role="radio"> + <input t-attf-id='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}' name="day_select" type="radio" class="radio_hide" t-attf-value='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}'/> + <span class="span_radio_button"> + <t class="week_day" t-esc="slot[0]"/><br/> + <t t-esc="slot[1].day"/><br/> + <t t-esc="slot[2]"/> + </span> + </label> + </a> + </li> + </t> + <t t-else=""> + <li class="nav-item carousel-item col-12 col-sm-6 col-md-4 col-lg-3"> + <a data-toggle="tab" class="nav-link btn btn-primary" t-attf-href='##{slot[1].strftime("%A")}#{point_retrait.id}'> + <label class=" label_radio_button" role="radio"> + <input t-attf-id='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}' name="day_select" type="radio" class="radio_hide" t-attf-value='#{slot[1].day}-#{slot[1].month}-#{point_retrait.id}'/> + <span class="span_radio_button"> + <t class="week_day" t-esc="slot[0]"/><br/> + <t t-esc="slot[1].day"/><br/> + <t t-esc="slot[2]"/> + </span> + </label> + </a> + </li> + </t> + </t> + </ul> + <a class="carousel-control-prev" t-att-href="'#carousel_%i' % point_retrait.id" role="button" data-slide="prev"> + <span class="carousel-control-prev-icon"></span> + <span class="sr-only">Previous</span> + </a> + <a class="carousel-control-next" t-att-href="'#carousel_%i' % point_retrait.id" role="button" data-slide="next"> + <span class="carousel-control-next-icon" ></span> + <span class="sr-only">Next</span> + </a> + </div> + </div> + </div> + <div class="tab-content"> <t t-foreach="list_slots" t-as="slot"> <t t-if="slot_first"> <div class="container tab-pane active" t-attf-id='#{slot[1].strftime("%A")}#{point_retrait.id}'> <t t-foreach="slot[3]" t-as="slot_by_day"> <label class="label_radio_button" role="radio"> - <input name="hour_select" type="radio" class="radio_hide" value="10:00" t-attf-id="#{slot_by_day_index}"/> + <input name="hour_select" type="radio" class="radio_hide" t-att-value="slot_by_day[0]" t-attf-id="#{slot_by_day_index}"/> <span class="btn btn-outline-primary span_radio_button"> <t t-esc="slot_by_day[0]"/> : <t t-esc="slot_by_day[1]"/> @@ -139,7 +278,7 @@ <div class="container tab-pane fade" t-attf-id='#{slot[1].strftime("%A")}#{point_retrait.id}'> <t t-foreach="slot[3]" t-as="slot_by_day"> <label class=" label_radio_button" role="radio"> - <input t-attf-id="#{slot_by_day_index}" name="hour_select" type="radio" class="radio_hide" value="10:00"/> + <input t-attf-id="#{slot_by_day_index}" name="hour_select" type="radio" class="radio_hide" t-att-value="slot_by_day[0]"/> <span class="btn btn-outline-primary span_radio_button"> <t t-esc="slot_by_day[0]"/> : <t t-esc="slot_by_day[1]"/> @@ -151,23 +290,14 @@ </t> </div> </div> - </template> --> + </template> <template id="vracoop_payment_delivery" inherit_id="website_sale_delivery.payment_delivery"> - <xpath expr="//div[@id='delivery_carrier']" position="replace"> - <div t-if="delivery_nb == 1" id="delivery_carrier" class="mt4"> - <b>Shipping Method: </b> - <t t-foreach="deliveries" t-as="delivery"> - <t t-call="website_sale_delivery.payment_delivery_methods"/> - </t> - <button>Choisir un point de retrait</button> - </div> - </xpath> <xpath expr="//div[@id='payment_method']" position="before"> - <div t-if="points_retrait" id="point_retrait"> + <div t-if="points_retrait" id="point_retrait" class="d-none mt-3"> <t t-set="point_retrait_nb" t-value="len(points_retrait)"/> - <h3 t-if="point_retrait_nb > 1" class="mb24">Choisir un point de retrait</h3> + <h3 t-if="point_retrait_nb" class="mb24">Choisir un point de retrait</h3> <div t-if="point_retrait_nb > 1" class="card border-0" id="retrait_method"> <ul class="list-group"> <t t-foreach="points_retrait" t-as="point_retrait"> @@ -177,6 +307,16 @@ </t> </ul> </div> + + <div t-if="point_retrait_nb == 1" class="card border-0" id="retrait_method"> + <ul class="list-group"> + <t t-foreach="points_retrait" t-as="point_retrait"> + <li class="list-group-item"> + <t t-call="vracoop_click_and_collect.point_retrait_one"/> + </li> + </t> + </ul> + </div> </div> </xpath>