From e642ca2a5f74225dcf507eb9c95295d7f6c46ec6 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 24 Aug 2023 14:04:54 +0200 Subject: [PATCH 1/3] feat!: duration in minutes --- CHANGES.rst | 6 ++++++ src/redturtle/prenotazioni/adapters/booker.py | 6 +++--- src/redturtle/prenotazioni/browser/vacations.py | 3 +-- .../restapi/serializers/adapters/prenotazione.py | 16 +++++++++++----- .../prenotazioni/restapi/services/booking/add.py | 6 +++++- .../restapi/services/booking/move.py | 2 ++ .../restapi/services/booking/vacation.py | 3 +++ 7 files changed, 31 insertions(+), 11 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f703029c..4321a158 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,12 @@ Changelog - permit to force gate / duration to operator (restapi add booking) [mamico] +- duration in minutes instead of days + [mamico] + +- allow to add out-of-office in api (aka blocco prenotazione) + [mamico] + 2.0.0.dev4 (2023-08-11) ----------------------- diff --git a/src/redturtle/prenotazioni/adapters/booker.py b/src/redturtle/prenotazioni/adapters/booker.py index 815f90dd..db02e176 100644 --- a/src/redturtle/prenotazioni/adapters/booker.py +++ b/src/redturtle/prenotazioni/adapters/booker.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import math from datetime import timedelta from plone import api from plone.memoize.instance import memoize @@ -82,8 +83,7 @@ def _create(self, data, duration=-1, force_gate=""): minutes=duration ) else: - # in this case we need to deal with seconds converted in days - booking_expiration_date = params["booking_date"] + timedelta(days=duration) + booking_expiration_date = params["booking_date"] + timedelta(minutes=duration) gate = "" if not force_gate: @@ -255,7 +255,7 @@ def create_vacation(self, data): for slot in gate_free_slots: if vacation_slot.overlaps(slot): # there is a slot that overlaps with the vacation - duration = (end - start).seconds / 24 / 60 / 60 + duration = math.ceil((end - start).seconds / 60) # XXX: weird to remove the gate from data and then force it ... slot_data = {k: v for k, v in data.items() if k != "gate"} slot_data["booking_date"] = start diff --git a/src/redturtle/prenotazioni/browser/vacations.py b/src/redturtle/prenotazioni/browser/vacations.py index 199a72fc..e33565a7 100644 --- a/src/redturtle/prenotazioni/browser/vacations.py +++ b/src/redturtle/prenotazioni/browser/vacations.py @@ -195,8 +195,7 @@ def do_book(self, data): for slot in slots: booking_date = start_date + (float(slot.lower_value) / 86400) slot.__class__ = BaseSlot - duration = float(len(slot)) / 86400 - # duration = float(len(slot)) / 60 + duration = len(slot) / 60 slot_data = {k: v for k, v in data.items() if k != "gate"} slot_data["booking_date"] = booking_date booker.create(slot_data, duration=duration, force_gate=data.get("gate")) diff --git a/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py b/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py index 4c39016b..ed52f491 100644 --- a/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py +++ b/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py @@ -6,6 +6,7 @@ from redturtle.prenotazioni.interfaces import ( ISerializeToPrenotazioneSearchableItem, ) +from redturtle.prenotazioni import logger from zope.component import adapter from zope.i18n import translate from zope.interface import implementer @@ -30,7 +31,14 @@ def __call__(self, *args, **kwargs): status = api.portal.get_tool("portal_workflow").getStatusOf( "prenotazioni_workflow", self.prenotazione ) - + booking_date = self.prenotazione.booking_date + booking_expiration_date = self.prenotazione.booking_expiration_date + if booking_expiration_date and booking_date.date() != booking_expiration_date.date(): + logger.warning("Booking date and expiration date are different, fixing") + booking_date = booking_date.date() + booking_expiration_date = booking_expiration_date.replace( + booking_date.year, booking_date.month, booking_date.day + ) return { "UID": self.prenotazione.UID(), "@type": self.prenotazione.portal_type, @@ -43,10 +51,8 @@ def __call__(self, *args, **kwargs): "fiscalcode": fiscalcode, "company": self.prenotazione.company, "staff_notes": self.prenotazione.staff_notes, - "booking_date": json_compatible(self.prenotazione.booking_date), - "booking_expiration_date": json_compatible( - self.prenotazione.booking_expiration_date - ), + "booking_date": json_compatible(booking_date), + "booking_expiration_date": json_compatible(booking_expiration_date), "booking_status_label": translate( status["review_state"], context=self.request ), diff --git a/src/redturtle/prenotazioni/restapi/services/booking/add.py b/src/redturtle/prenotazioni/restapi/services/booking/add.py index a4e6b44a..b17e573d 100644 --- a/src/redturtle/prenotazioni/restapi/services/booking/add.py +++ b/src/redturtle/prenotazioni/restapi/services/booking/add.py @@ -5,6 +5,7 @@ from plone.restapi.interfaces import ISerializeToJson from redturtle.prenotazioni import _ from redturtle.prenotazioni.adapters.booker import IBooker +from redturtle.prenotazioni.content.prenotazione import VACATION_TYPE from redturtle.prenotazioni.restapi.services.booking_schema.get import BookingSchema from zExceptions import BadRequest from zope.component import queryMultiAdapter @@ -77,7 +78,10 @@ def validate(self): ) raise BadRequest(msg) - if data["booking_type"] not in [ + if data["booking_type"] in [VACATION_TYPE]: + # TODO: check permission for special booking_types ? + pass + elif data["booking_type"] not in [ _t["name"] for _t in self.context.booking_types or [] if "name" in _t ]: msg = self.context.translate( diff --git a/src/redturtle/prenotazioni/restapi/services/booking/move.py b/src/redturtle/prenotazioni/restapi/services/booking/move.py index 1c270dac..96cf7654 100644 --- a/src/redturtle/prenotazioni/restapi/services/booking/move.py +++ b/src/redturtle/prenotazioni/restapi/services/booking/move.py @@ -27,6 +27,8 @@ def reply(self): return self.reply_no_content(status=404) booker = IBooker(booking.getPrenotazioniFolder()) + + # TODO: gestire eccezioni nel caso ci sia sovrapposizione booker.move(booking=booking, data=data) alsoProvides(self.request, IDisableCSRFProtection) diff --git a/src/redturtle/prenotazioni/restapi/services/booking/vacation.py b/src/redturtle/prenotazioni/restapi/services/booking/vacation.py index 3957fb46..0399b10d 100644 --- a/src/redturtle/prenotazioni/restapi/services/booking/vacation.py +++ b/src/redturtle/prenotazioni/restapi/services/booking/vacation.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- + +### DEPRECATED #### + from plone.protect.interfaces import IDisableCSRFProtection from plone.restapi.deserializer import json_body from plone.restapi.services import Service From cef78e202b982f10b474b89416b1293d4c898ecb Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 24 Aug 2023 14:05:59 +0200 Subject: [PATCH 2/3] black --- src/redturtle/prenotazioni/adapters/booker.py | 4 +++- .../restapi/serializers/adapters/prenotazione.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/redturtle/prenotazioni/adapters/booker.py b/src/redturtle/prenotazioni/adapters/booker.py index db02e176..b5e74d22 100644 --- a/src/redturtle/prenotazioni/adapters/booker.py +++ b/src/redturtle/prenotazioni/adapters/booker.py @@ -83,7 +83,9 @@ def _create(self, data, duration=-1, force_gate=""): minutes=duration ) else: - booking_expiration_date = params["booking_date"] + timedelta(minutes=duration) + booking_expiration_date = params["booking_date"] + timedelta( + minutes=duration + ) gate = "" if not force_gate: diff --git a/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py b/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py index ed52f491..e3dd7778 100644 --- a/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py +++ b/src/redturtle/prenotazioni/restapi/serializers/adapters/prenotazione.py @@ -33,7 +33,10 @@ def __call__(self, *args, **kwargs): ) booking_date = self.prenotazione.booking_date booking_expiration_date = self.prenotazione.booking_expiration_date - if booking_expiration_date and booking_date.date() != booking_expiration_date.date(): + if ( + booking_expiration_date + and booking_date.date() != booking_expiration_date.date() + ): logger.warning("Booking date and expiration date are different, fixing") booking_date = booking_date.date() booking_expiration_date = booking_expiration_date.replace( From 0475d0faed4f31ba6402d6b97e32f404b9b006d6 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 24 Aug 2023 14:06:26 +0200 Subject: [PATCH 3/3] flake8 --- src/redturtle/prenotazioni/restapi/services/booking/vacation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redturtle/prenotazioni/restapi/services/booking/vacation.py b/src/redturtle/prenotazioni/restapi/services/booking/vacation.py index 0399b10d..79bf8927 100644 --- a/src/redturtle/prenotazioni/restapi/services/booking/vacation.py +++ b/src/redturtle/prenotazioni/restapi/services/booking/vacation.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -### DEPRECATED #### +# #### DEPRECATED #### from plone.protect.interfaces import IDisableCSRFProtection from plone.restapi.deserializer import json_body