@startuml updateReservation

footer Page %page% of %lastpage%
title "Update Reservation for user, admin and company"

actor "User" as user
actor "Admin" as admin
actor "Company" as company
participant "server" as server
participant "<<router>>\nreservation" as routerReserv
participant "<<middleware>>\nauth" as middleAuth
participant "<<controllers>>\nreservation" as controllersReserv
participant "<<model>>\nTimeslot" as modelTimeslot
participant "<<model>>\nUser" as modelUser
participant "<<model>>\nReservation" as modelReserv
database "MongoDB" as mongoDB

group Loop
    'get reservations for user
    group opt 
        activate user
        activate server
        activate routerReserv
        activate middleAuth
        activate controllersReserv
        activate modelUser
        activate modelReserv
        activate mongoDB
        activate admin
        activate modelTimeslot

        user->server :updateReservation\n(token,reservationId\n,timeslotId)
        admin -> server :updateReservation\n(token,reservationId\n,timeslotId)
        server->routerReserv :use('/api/reservation'\n,reservation)
        routerReserv -> middleAuth : protect(token)
        middleAuth -> middleAuth : decode(token)
        middleAuth -> modelUser : User.findBy(decodetoken)
        modelUser -> mongoDB : findById(decodetoken)

        modelUser <-- mongoDB : user
        middleAuth <-- modelUser : user
        routerReserv <-- middleAuth : next()

        routerReserv -> controllersReserv : update('/:reservationId',updateReservation)
        controllersReserv -> modelReserv :  Reservation.findById(req.params.id);
        modelReserv -> mongoDB :  find(req.params.id);

        modelReserv <-- mongoDB : reservation
        controllersReserv <-- modelReserv : reservation

        controllersReserv -> modelUser : User.findById(req.user.id).populate\n({path:'reservation',select:'timeslot'})
        modelUser -> mongoDB : find(req.user.id).populate\n({path:'reservation',select:'timeslot'})
        
        modelUser <-- mongoDB : user
        controllersReserv <-- modelUser : user

        controllersReserv -> modelTimeslot : TimeSlot.findById(req.body.timeslot)
        modelTimeslot -> mongoDB : find(req.body.timeslot)

        modelTimeslot <-- mongoDB : timeslot
        controllersReserv <-- modelTimeslot : timeslot

        controllersReserv -> modelTimeslot : TimeSlot.findByIdAndUpdate\n(reservation.timeslot , \n{$pull : {reservation : req.params.id}})
        modelTimeslot -> mongoDB : findByIdAndUpdate\n(reservation.timeslot,{$pull:{reservation:req.params.id}})
        
        modelTimeslot <-- mongoDB : timeslot
        controllersReserv <-- modelTimeslot : timeslot

        controllersReserv -> modelTimeslot : TimeSlot.findByIdAndUpdate\n(req.body.timeslot , \n{"$push" : {"reservation" : req.params.id}})
        modelTimeslot -> mongoDB : findByIdAndUpdate\n(req.body.timeslot,{"$push":{"reservation":req.params.id}})

        modelTimeslot <-- mongoDB : timeslot
        controllersReserv <-- modelTimeslot : timeslot

        controllersReserv -> modelReserv : Reservation.findByIdAndUpdate\n(req.params.id,req.body,{new:true,runValidators:true})
        modelReserv -> mongoDB : findByIdAndUpdate\n(req.params.id,req.body,{new:true,runValidators: true})

        modelReserv <-- mongoDB : reservation
        controllersReserv <-- modelReserv : reservation
        routerReserv <-- controllersReserv : return
        server <-- routerReserv : return
        admin <-- server : return
        user <-- server : return
    end
end

@enduml