Script Python pour l'asservissement de salle lors d'une réservation

Bonjour à tous,

J’ai développé un script Python assez sympa que je voulais partager avec vous. Ca permettra de voir quelques fonctions utiles et donner un aperçu des possibilités (assez énormes) offertes.

:man_office_worker: Le cas d’usage (réel)
Un tiers-lieu a deux salles de réunions : la salle 1 (1ère étage) et 2 (2e) qu’ils louent à des assos, entreprises etc. Ils souhaitent proposer la salle 1 pour du coworking lorsqu’elle n’est pas utilisée avec à terme la possibilité pour les usagers de réserver eux-mêmes en ligne.

:thinking: Problème : il faut pouvoir empêcher la réservation du coworking quand les deux salles sont louées.

:bulb: Une solution : Un script Python qui vient automatiquement réserver tout les créneaux de coworking lorsque il y a chevauchement entre les réservations de la salle 1 et 2.

Démo
script_asservissement

:man_technologist: Le code

#****Script parameters****
master_room1 = "Salle réunion 1"
master_room2 = "Salle réunion 2"
slave_room = "Salle de coworking"

# Constraint: If two master rooms are booked at the same time, then the slave room is booked too during the overlap
#****0/ Script only does something if item is one of the two master rooms****
if doc.item == master_room1 or doc.item == master_room2:
    #****1/ Get list of bookings confirmed on the same day, exclusive of the slave room****
    booking_list = frappe.db.get_list('Item Booking',
        filters=[
            ['status','=', 'Confirmed'],
            ['name','!=', doc.name],
            ['item', '!=', slave_room],
            ['starts_on','>=',frappe.utils.getdate(doc.starts_on)],
            ['starts_on' ,'<',frappe.utils.add_to_date(frappe.utils.getdate(doc.ends_on),days=1) ]
        ],
        fields=['name'],
        as_list=True
    )
    # Assign datetime data to variables for clearer code
    start1 = frappe.utils.get_datetime(doc.starts_on)
    end1 = frappe.utils.get_datetime(doc.ends_on)
    #****2/ Cycle through all the slots identified to check for overlaps****
    for x in booking_list:
        item_booking = frappe.get_doc('Item Booking', ''.join(x))
        # Assign datetime data to variables for clearer code
        start2 = frappe.utils.get_datetime(item_booking.starts_on)
        end2 = frappe.utils.get_datetime(item_booking.ends_on)
        #-- Conditions to check for overlaps (hard to get one's head around without a schematic) --
        # Initialisation of a flag to check if one of the condition is met
        overlapflag = 0
        # Initialisation of slave start and end as the same as current doc
        slavestart = start1
        slaveend = end1
        # Tail of previous slots overlaps with current doc
        if end2 > start1 and end2 < end1:
            slaveend = end2
            overlapflag = overlapflag + 1
        # Start of previous slots overlaps with tail of current doc
        if start2 > start1 and start2 < end1:
            slavestart = start2
            overlapflag = overlapflag + 1
        # Current doc is completely contained by previous slot
        if start2 < start1 and end2 > end1:
            slavestart = start1
            slaveend = end1
            overlapflag = overlapflag + 1
        #****3/Create a new slot to book the room if an overlap has been found****
        if overlapflag:
            # Get number of simultaneous bookings allowed
            slave_item = frappe.get_doc("Item", slave_room)
            n_slots = slave_item.simultaneous_bookings_allowed
            frappe.msgprint("Nombre de slots = " + str(n_slots))
            # Create enough slots to fill the slave room
            for x in range(n_slots):
                frappe.msgprint("Création d'une réservation pour l'article : " + slave_room)
                slave = frappe.get_doc({
                    "doctype": "Item Booking",
                    "title" : "résa scriptée",
                    "item" : slave_room,
                    "status" : "Confirmed",
                    "starts_on" : slavestart,
                    "ends_on" : slaveend
                    })
                slave.insert()
        overlapflag = 0
    else:
        pass

Le script est configuré pour se déclencher à l’enregistrement d’une réservation d’articles.

Pistes d’améliorations

  • Cas où il y a déjà des réservations de coworking
  • Rajouter du temps en début/fin des créneaux de coworking crées pour laisser le temps aux gens ayant réservés la salle d’arriver/partir
2 Likes