def update(id: int):
    d = db.select(table="deliveries", conditions={"id": id}, multiple=False)
    if d is None:
        return jsonify(info="Delivery not found"), 404

    args = request.get_json(force=True)
    delivery = Delivery.parse(args, "update")
    if "errors" in delivery:
        return jsonify(errors=delivery["errors"]), 400
    delivery = delivery["delivery"]

    delivery["company_id"] = session["user"]["company_id"]

    # customer_id
    if "customer_id" in delivery:
        if not db.is_existing(table="customers", conditions={"id": delivery["customer_id"]}):
            return jsonify(info="Customer not found"), 404

        # sender_id
    if "sender_id" in delivery:
        if not db.is_existing(table="customers", conditions={"id": delivery["sender_id"]}):
            return jsonify(info="Sender not found"), 404

        # receiver_id
    if "receiver_id" in delivery:
        if not db.is_existing(table="customers", conditions={"id": delivery["receiver_id"]}):
            return jsonify(info="Receiver not found"), 404

    if "date_due" in delivery and d["driver_id"] is not None:
        db.delete(table="delivery_orders", conditions={"delivery_id": id})  # delete old date
        insert_at_last_order(id, delivery["date_due"], d["driver_id"])

    db.update(table="deliveries", params=delivery, conditions={"id": id})

    return jsonify(info="Delivery updated successfully"), 200
def update(id:int):
    company_id = session["user"]["company_id"]
    if not db.is_existing(table="users", conditions={"id":id, "type":"driver", "company_id": company_id}):
        return jsonify(info="Driver not found"), 404

    driver = request.get_json(force=True)
    driver = Driver.parse(driver, "update")
    
    if "errors" in driver:
        return jsonify(errors=driver["errors"]),400
    driver = driver["driver"]
    driver_data = {}

    if "name" in driver:
        if db.is_existing(table="users",
                      conditions={"name": driver["name"], "type":"driver", "company_id": company_id}):
            return jsonify(info="Driver with the same name already exist"),400
        driver_data["name"] = driver["name"]

    if "email" in driver:
        if db.is_existing(table="users",
                      conditions={"email": driver["email"], "type":"driver", "company_id": company_id}):
            return jsonify(info="Driver with the same email already exist"),400
        driver_data["email"] = driver["email"]

    if "phone" in driver:
        driver_data["phone"] = driver["phone"]

    db.update(table="users", params=driver_data, conditions={"id": id})
    return jsonify(info="Driver updated successfully"),200
def set_vehicle(driver_id:int):

    def reset_vehicle(index, driver_id):
        _sql = """
                  UPDATE vehicles
                  SET vehicles.driver_id = NULL
                  WHERE vehicles.id = (
                    SELECT users.vehicle_id_""" + str(index) +"""
                    FROM users
                    WHERE users.id = %(id)s );
                """
        db.query(_sql, params={"id" : driver_id}, fetch=False)


    company_id = session["user"]["company_id"]
    if not db.is_existing(table="users",conditions={"id":driver_id, "type":"driver", "company_id": company_id}):
        return jsonify(info="Driver not found"), 404

    vehicles = request.get_json(force=True)
    vehicles = Driver.parse(vehicles, "set_vehicle")

    if "errors" in vehicles:
        return jsonify(errors=vehicles["errors"]),400

    vehicles = vehicles["vehicles"]

    for k,v in vehicles.items():

        if v is not None:

            if not db.is_existing(table="vehicles", conditions={"company_id": company_id, "id":v}):
                return jsonify(info="Vehicle " + str(k) + " not found"), 404

            _sql = """ SELECT 1 FROM vehicles WHERE company_id=%(company_id)s AND id= %(v_id)s AND (driver_id IS NULL OR driver_id=%(id)s); """

            # if wished vehicle is available
            if db.query(_sql,params={"company_id" : company_id, "id": driver_id, "v_id" : v}, multiple=False) is not None:

                # reset old vehicle
                reset_vehicle(k[1], driver_id)

                # update vehicle
                db.update(table="vehicles", params={"driver_id": driver_id}, conditions={"id":v})

            else :
                return jsonify(info="Vehicle " + str(k) + " already taken"), 400

        else :
            # reset old vehicle
            reset_vehicle(k[1], driver_id)

        # update user
        db.update(table="users", params={"vehicle_id_"+k[1]: v}, conditions={"id" : driver_id})

    return jsonify(info="Vehicles set successfully"), 200
def assign_driver(delivery_id: int, driver_id: int):
    company_id = session["user"]["company_id"]
    if not db.is_existing(table="users", conditions={"id": driver_id, "type": "driver", "company_id": company_id}):
        return jsonify(info="Driver not found"), 404

    def get_valid_delivery(delivery_id, company_id):
        sql = "SELECT date_due FROM deliveries WHERE id=%(id)s AND company_id=%(company_id)s AND (state='not taken' OR state='not assigned');"
        return db.query(sql, params={"id": delivery_id, "company_id": company_id}, multiple=False)

    delivery = get_valid_delivery(delivery_id, company_id)
    if delivery is None:
        return jsonify(info="Delivery not found or not assignable"), 404

    db.update(
        table="deliveries",
        params={"driver_id": driver_id, "state": "not taken"},
        conditions={"id": delivery_id, "company_id": company_id},
    )

    insert_at_last_order(delivery_id, delivery["date_due"], driver_id)

    return jsonify(info="Driver has been assigned"), 200
def update_state():
    args = request.get_json(force=True)
    req = Delivery.parse(args, "update_state")
    if "errors" in req:
        return jsonify(errors=req["errors"]), 400

    state = req["state"]
    conditions = {"id": req["delivery_id"], "company_id": session["user"]["company_id"]}

    if session["user"]["type"] == "driver":
        conditions["driver_id"] = session["user"]["id"]

    delivery = db.is_existing(table="deliveries", conditions=conditions)

    if not delivery:
        return jsonify(info="Delivery not found"), 404

    if state == "canceled":
        db.update(table="deliveries", params={"canceled": 1}, conditions=conditions)
    else:
        db.update(table="deliveries", params={"state": state}, conditions=conditions)

    return jsonify(info="Delivery state has been updated"), 200
def update(id: int):
    company_id = session["user"]["company_id"]

    if not db.is_existing(table="vehicles", conditions={"id": id, "company_id": company_id}):
        return jsonify(info="Vehicle not found"), 404

    rq = request.get_json(force=True)
    vehicle = Vehicle.parse(rq, "update")
    if "errors" in vehicle:
        return jsonify(errors=vehicle["errors"]), 400
    vehicle = vehicle["vehicle"]
    vehicle_data = {}

    if "registration" in vehicle:
        if db.is_existing(
            table="vehicles", conditions={"registration": vehicle["registration"], "company_id": company_id}
        ):
            return jsonify(info="Vehicle with the same registration already exist"), 400
        vehicle_data["registration"] = vehicle["registration"]

    if "type" in vehicle:
        vehicle_data["type"] = vehicle["type"]

    if "max_weight" in vehicle:
        max_weight = vehicle["max_weight"]
        if not (isinstance(max_weight, float) or isinstance(max_weight, int)) or max_weight > 100000 or max_weight < 0:
            abort(400)
        vehicle_data["max_weight"] = vehicle["max_weight"]

    if "max_area" in vehicle:
        max_area = vehicle["max_area"]
        if not (isinstance(max_area, float) or isinstance(max_area, int)) or max_area > 150 or max_area < 0:
            abort(400)
        vehicle_data["max_area"] = vehicle["max_area"]

    db.update(table="vehicles", params=vehicle_data, conditions={"id": id})
    return jsonify(info="Vehicle updated successfully"), 200
def update(id:int):
    company_id = session["user"]["company_id"]
    ### check existing customer
    if not db.is_existing(table="customers", conditions={"id":id, "company_id": company_id}):
        return jsonify(info="Customer not found"),404

    req = request.get_json(force=True)
    req = Customer.parse(req, "update")

    if "errors" in req:
        return jsonify(errors=req["errors"]),400
    req = req["customer"]
        
    customer = {}
    #name
    if "name" in req:
        if db.is_existing(table="customers", conditions={"name":req["name"],"company_id": company_id}):
            return jsonify(info="Customer with the same name already exists"),400

        customer["name"] = req["name"]

    #address
    if "address" in req:
        customer["address"] = req["address"]

    #location
    if "location" in req :
        customer["location_lat"] = req["location"]["lat"]
        customer["location_lng"] = req["location"]["lng"]

    #phone
    if "phone" in req:
        customer["phone"] = req["phone"]

    db.update(table="customers", params=customer, conditions={"id":id})
    return jsonify(info="Customer data updated successfully"),200
def updateLocation(lat:int,lng:int):
    driver_id = session["user"]["id"]
    db.update(table="users", params={"location_lat": lat, "location_lng":lng}, conditions={"id": driver_id})
    return jsonify(info="Location successfully updated")