def recv_process():
    """ Receive a Shipment """

    try:
        recv_id = long(request.args[0])
    except (__HOLE__, ValueError):
        # recv_id missing from URL or invalid
        redirect(URL(f="recv"))

    rtable = s3db.inv_recv

    if not auth.s3_has_permission("update", rtable, record_id=recv_id):
        session.error = T("You do not have permission to receive this shipment.")
        redirect(URL(c="inv", f="recv", args=[recv_id]))

    recv_record = db(rtable.id == recv_id).select(rtable.date,
                                                  rtable.status,
                                                  rtable.site_id,
                                                  rtable.recv_ref,
                                                  limitby=(0, 1),
                                                  ).first()

    # Check status
    status = recv_record.status
    inv_ship_status = s3db.inv_ship_status
    if status == inv_ship_status["RECEIVED"]:
        session.error = T("This shipment has already been received.")
        redirect(URL(c="inv", f="recv", args=[recv_id]))

    elif status == inv_ship_status["CANCEL"]:
        session.error = T("This shipment has already been received & subsequently canceled.")
        redirect(URL(c="inv", f="recv", args=[recv_id]))

    # Update Receive record & lock for editing
    data = {"status": inv_ship_status["RECEIVED"],
            "owned_by_user": None,
            "owned_by_group": ADMIN,
            }

    if not recv_record.recv_ref:
        # No recv_ref yet? => add one now
        code = s3db.supply_get_shipping_code(settings.get_inv_recv_shortname(),
                                             recv_record.site_id,
                                             s3db.inv_recv.recv_ref,
                                             )
        data["recv_ref"] = code

    if not recv_record.date:
        # Date not set? => set to now
        data["date"] = request.utcnow

    db(rtable.id == recv_id).update(**data)

    # Update the Send record & lock for editing
    stable = db.inv_send
    tracktable = db.inv_track_item
    send_row = db(tracktable.recv_id == recv_id).select(tracktable.send_id,
                                                        limitby=(0, 1)).first()
    if send_row:
        send_id = send_row.send_id
        db(stable.id == send_id).update(status = inv_ship_status["RECEIVED"],
                                        owned_by_user = None,
                                        owned_by_group = ADMIN,
                                        )

    # Change the status for all track items in this shipment to Unloading
    # the onaccept will then move the values into the site, update any request
    # record, create any adjustment if needed and change the status to Arrived
    db(tracktable.recv_id == recv_id).update(status = 3)

    # Move each item to the site
    track_rows = db(tracktable.recv_id == recv_id).select()
    for track_item in track_rows:
        row = Storage(track_item)
        s3db.inv_track_item_onaccept(Storage(vars = Storage(id=row.id),
                                             record = row,
                                             ))

    # Done => confirmation message, open the record
    session.confirmation = T("Shipment Items Received")
    redirect(URL(c="inv", f="recv", args=[recv_id]))

# -----------------------------------------------------------------------------
dataset/ETHPy150Open sahana/eden/controllers/inv.py/recv_process