def make_pack_requests(world_comm_data):
    pending = db_interface.get_matching_state_orders('pending')
    for o in pending:
        ship_id = o[0]
        x, y = o[4], o[5]
        prodname = o[2]
        count = o[7]
        whid = db_interface.get_matching_wh(x, y)
        prodid = db_interface.get_matching_prodid(prodname)

        prod_desc = db_interface.get_prod_desc(prodid)
        prod_pb = wapb2.AProduct()
        prod_pb.id = prodid
        prod_pb.description = prod_desc
        prod_pb.count = count
        try:
            db_interface.increment_inventory(whid, prodid, -count)
        except db_interface.NoInventoryError:
            continue

        db_interface.adjust_order_status(ship_id, 'pending', 'to pack')
        db_interface.set_pack_loc(ship_id, whid)
        pack_pb = wapb2.APack()
        pack_pb.whnum = whid
        pack_pb.shipid = ship_id
        seqnum = get_seqnum()
        pack_pb.seqnum = seqnum
        world_comm_data.track_new_message(seqnum, 'APack', pack_pb)
def ups_response_handler(serialized_msg, ups_comm_data, world_comm_data):
    ups_response_pb = uapb2.UtoACommand()
    ups_response_pb.ParseFromString(serialized_msg)
    print("ups response ----")
    print(ups_response_pb)
    print("------")

    # print(world_response_pb)
    if ups_response_pb.errMsg:
        print(ups_response_pb.errMsg)
        raise AssertionError("I don't know how to handle errors")
    awaiting_confirm = ups_comm_data.await_pickup_confirm_dict
    for a_seqnum in ups_response_pb.ack:
        ups_comm_data.handle_acked_message(a_seqnum)

    seen_set = ups_comm_data.all_seen_seqnums

    for msg in utils.filter_ups_unseen(seen_set, ups_response_pb.usrVlid):
        ups_comm_data.register_incoming_seqnum(msg.seqNum)
        success = msg.result
        id = msg.shipId
        if success:
            db_interface.adjust_order_status(id, 'val_req_sent', 'pending')
        else:
            db_interface.adjust_order_status(id, 'val_req_sent', 'invalid')

    truckload_lock.acquire()
    for idx, msg in enumerate(
            utils.filter_ups_unseen(seen_set, ups_response_pb.loadReq)):
        #print(f"loadreq{idx}:",msg)
        wh_id = msg.warehouseId
        truckid = msg.truckId
        not_loaded = ups_comm_data.truck_notloaded
        expecting = ups_comm_data.truck_expecting
        try:
            #pass #because they send multiple
            assert truckid not in not_loaded and truckid not in expecting
        except Exception as e:
            import pdb
            pdb.set_trace()
            raise e
        for shipid in msg.shipId:
            snum = get_seqnum()
            put_on_truck_pb = wapb2.APutOnTruck()
            put_on_truck_pb.whnum = wh_id
            put_on_truck_pb.truckid = msg.truckId
            put_on_truck_pb.seqnum = snum
            put_on_truck_pb.shipid = shipid
            world_comm_data.track_new_message(snum, 'APutOnTruck',
                                              put_on_truck_pb)
            db_interface.adjust_order_status(shipid, 'request_pickup', 'load')
            ups_comm_data.track_loading_package(shipid, msg.truckId)
        ups_comm_data.register_incoming_seqnum(msg.seqNum)
    truckload_lock.release()

    for msg in utils.filter_ups_unseen(seen_set, ups_response_pb.delivery):
        db_interface.adjust_order_status(msg.shipId, 'delivering', 'delivered')
        name, email = db_interface.get_notify_info(msg.shipId)
        mail_notifier.notify_arrival(name, email)
        ups_comm_data.register_incoming_seqnum(msg.seqNum)
def create_val_requests(ups_comm_data):
    need_valids = db_interface.get_matching_state_orders('await_valid')
    for row in need_valids:
        valid_pb = uapb2.UserValidationRequest()
        seqnum = get_seqnum()
        valid_pb.seqNum = seqnum
        valid_pb.UPSaccount = row[3]
        valid_pb.shipId = row[0]
        ups_comm_data.track_new_message(seqnum, 'UserValidationRequest',
                                        valid_pb)
        db_interface.adjust_order_status(row[0], 'await_valid', 'val_req_sent')
def create_refill_request(world_comm_data, minimum=500):
    inv = db_interface.view_inventory()
    for wh_id in db_interface.get_whids():
        seqnum = get_seqnum()
        purchase_pb = wapb2.APurchaseMore()
        purchase_pb.whnum = wh_id
        purchase_pb.seqnum = seqnum
        for prodid in db_interface.get_prodids():
            if inv[wh_id][prodid] < minimum:
                print("refill needed")
                prod_pb = wapb2.AProduct()
                prod_pb.id, prod_pb.description, prod_pb.count = prodid, 'UNUSED FIELD', minimum
                purchase_pb.things.append(prod_pb)
                world_comm_data.track_new_message(seqnum, 'APurchaseMore',
                                                  purchase_pb)
def create_loadfinish_requests(ups_comm_data):
    truckload_lock.acquire()
    expecting = ups_comm_data.truck_expecting

    ready_ids = ups_comm_data.ready_truckids()
    for truckid in ready_ids:
        finish_pb = uapb2.AtoULoadFinishRequest()
        snum = get_seqnum()
        finish_pb.seqNum = snum
        finish_pb.truckId = truckid
        finish_pb.shipId.extend(expecting[truckid])
        print("finished loading for truck: ", truckid, "shipids:",
              expecting[truckid])
        for shipid in expecting[truckid]:
            db_interface.adjust_order_status(shipid, 'loaded', 'delivering')
        ups_comm_data.clear_truck_data(truckid)
        ups_comm_data.track_new_message(snum, 'AtoULoadFinishRequest',
                                        finish_pb)

    truckload_lock.release()
def world_response_handler(serialized_msg, world_comm_data, ups_comm_data):
    world_response_pb = wapb2.AResponses()
    world_response_pb.ParseFromString(serialized_msg)
    print("world response:-------", world_response_pb)
    print("----------------------------")
    if world_response_pb.error:
        for x in world_response_pb.error:
            print(x.err, world_comm_data._all_messages[x.originseqnum])
        raise AssertionError("world returned error")

    for a_seqnum in world_response_pb.acks:
        world_comm_data.handle_acked_message(a_seqnum)

    seen_seqnums = world_comm_data.all_seen_seqnums
    should_ack = set()
    for purchase_pb in filter_world_unseen(seen_seqnums,
                                           world_response_pb.arrived):
        for mul_prod in purchase_pb.things:
            db_interface.increment_inventory(purchase_pb.whnum, mul_prod.id,
                                             mul_prod.count)
        world_comm_data.register_incoming_seqnum(purchase_pb.seqnum)

    pickup_requests = {}
    for wh_id in db_interface.get_whids():
        seqnum = get_seqnum()
        pickup_req_pb = uapb2.AtoUPickupRequest()
        pickup_req_pb.seqNum = seqnum
        pickup_req_pb.warehouseId = wh_id
        pickup_requests[wh_id] = pickup_req_pb

    for packed_pb in filter_world_unseen(seen_seqnums,
                                         world_response_pb.ready):
        #db_lock.acquire() locking unecessary
        shipid = packed_pb.shipid
        shipinfo = uapb2.ShipInfo()
        wh_id, ups_acc, dest_x, \
        dest_y, prod_name, prod_num = db_interface.get_ship_info(shipid)
        shipinfo.shipId = shipid
        shipinfo.destination_x = dest_x
        shipinfo.destination_y = dest_y
        if ups_acc:
            shipinfo.UPSaccount = ups_acc
        product = uapb2.Product()
        product.description = prod_name
        product.count = prod_num
        shipinfo.products.append(product)
        pickup_requests[wh_id].shipment.append(shipinfo)
        #TODO: change this to accomodate ack in the future- here i assume requests are noted
        db_interface.adjust_order_status(packed_pb.shipid, "to pack",
                                         "request_pickup")
        world_comm_data.register_incoming_seqnum(packed_pb.seqnum)
    for wh_id in pickup_requests:
        req = pickup_requests[wh_id]
        if req.shipment:
            ups_comm_data.track_new_message(req.seqNum, 'AtoUPickupRequest',
                                            req)

    for loaded_pb in filter_world_unseen(seen_seqnums,
                                         world_response_pb.loaded):
        db_interface.adjust_order_status(loaded_pb.shipid, "load", "loaded")
        shipid = loaded_pb.shipid
        ups_comm_data.track_loaded_package(shipid)
        world_comm_data.register_incoming_seqnum(loaded_pb.seqnum)