def test_recreate_bin(): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(id='BIN000000', props=None)) print(state) state.delete_empty_bin(bin_id=v1) state.new_bin(bin=Bin(id='BIN000000', props=None)) state.teardown()
def test_move_sku(data): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(contents={}, id='BIN000000', props=None)) v2 = state.new_bin(bin=Bin(contents={}, id='BIN000001', props=None)) v3 = state.new_sku(sku=Sku(id='SKU000000')) state.receive_sku(bin_id=v1, sku_id=v3, quantity=1) state.move(data=data, destination_binId=v2, source_binId=v1) state.get_existing_bin(bin_id=v1) state.get_existing_bin(bin_id=v2) state.teardown()
def json_to_data_model(in_json_dict): if in_json_dict['id'].startswith("BIN"): return Bin.from_json(in_json_dict) if in_json_dict['id'].startswith("SKU"): return Sku.from_json(in_json_dict) if in_json_dict['id'].startswith("BAT"): return Batch.from_json(in_json_dict)
def sku_bins_get(id): resp = Response() existing = Sku.from_mongodb_doc(db.sku.find_one({"_id": id})) if not existing: resp.status_code = 404 resp.mimetype = "application/problem+json" resp.data = json.dumps({ "type": "missing-resource", "title": "Can not get locations of sku that does not exist.", "invalid-params": [{ "name": "id", "reason": "must be an exisiting sku id" }] }) return resp contained_by_bins = [ Bin.from_mongodb_doc(bson) for bson in db.bin.find({f"contents.{id}": { "$exists": True }}) ] locations = {bin.id: {id: bin.contents[id]} for bin in contained_by_bins} resp.status_code = 200 resp.mimetype = "application/json" resp.data = json.dumps({"state": locations}) return resp
def get_existing_bin(self, bin_id): assert bin_id in self.model_bins.keys() rp = self.client.get(f'/api/bin/{bin_id}') assert rp.status_code == 200 assert rp.is_json assert self.model_bins[bin_id].props == rp.json['state'].get('props') found_bin = Bin.from_json(rp.json['state']) assert found_bin == self.model_bins[bin_id]
def test_receive_batch(): state = InventoryStateMachine() v1 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000000', owned_codes=[], props=None, sku_id=None)) v2 = state.new_bin(bin=Bin(contents={}, id='BIN000000', props=None)) state.receive_batch(batch_id=v1, bin_id=v2, quantity=1) state.get_existing_bin(v2)
def test_delete_used_sku(): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(contents={}, id='BIN000000', props=None)) v2 = state.new_sku(sku=Sku(associated_codes=[], id='SKU000000', name='', owned_codes=[], props=None)) state.receive_sku(bin_id=v1, quantity=1, sku_id=v2) state.attempt_delete_used_sku(sku_id=v2) state.teardown()
def test_delete_bin_with_batch(): state = InventoryStateMachine() # state.delete_missing_bin(bin_id='BIN000000') v1 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000000', owned_codes=[], props=None, sku_id=None)) v2 = state.new_bin(bin=Bin(contents={}, id='BIN000000', props=None)) state.receive_batch(batch_id=v1, bin_id=v2, quantity=1) state.delete_nonempty_bin_noforce(bin_id=v2) state.teardown()
def bin_delete(id): existing = Bin.from_mongodb_doc(db.bin.find_one({"_id": id})) if existing is None: return problem.missing_bin_response(id) if request.args.get('force', 'false') == 'true' or len( existing.contents.keys()) == 0: db.bin.delete_one({"_id": id}) return success.bin_deleted_response(id) else: return problem.dangerous_operation_unforced_response( "id", "bin must be empty")
def test_bin(bin): assert json.loads(bin.to_json())['id'] == bin.id assert json.loads( bin.to_json(mask_default=False)).get('props') == bin.props assert json.loads(bin.to_json(mask_default=False)).get('contents') == {} bin_jsoned = Bin.from_json(bin.to_json()) assert bin_jsoned == bin assert bin == bin_jsoned assert bin.to_mongodb_doc()['_id'] == bin.id assert bin.to_mongodb_doc().get('props') == bin.props assert bin.to_mongodb_doc().get('contents') == {}
def test_was_undefined_key_error_01(): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(contents={}, id='BIN000000', props={'_': None})) v2 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT575165', name='A', owned_codes=[], props={'': None}, sku_id=None)) state.batch_locations(batch_id=v2) state.receive_batch(batch_id=v2, bin_id=v1, quantity=1) state.batch_locations(batch_id=v2) state.teardown()
def bin_patch(id): try: json = bin_patch_schema(request.json) except MultipleInvalid as e: return problem.invalid_params_response(e) existing = Bin.from_mongodb_doc(db.bin.find_one({"_id": id})) if existing is None: problem.missing_bin_response(id) if "props" in json.keys(): db.bin.update_one({"_id": id}, {"$set": {"props": json['props']}}) return BinEndpoint.from_bin(existing).updated_success_response()
def bins_post(): try: json = new_bin_schema(request.json) except MultipleInvalid as e: return problem.invalid_params_response(e) existing = db.bin.find_one({'_id': json['id']}) if existing: return problem.duplicate_resource_response("id") bin = Bin.from_json(json) admin_increment_code("BIN", bin.id) db.bin.insert_one(bin.to_mongodb_doc()) return BinEndpoint.from_bin(bin).created_success_response()
def from_id(cls, batch_id, retrieve=False): if not retrieve: raise NotImplementedError() contained_by_bins = [ Bin.from_mongodb_doc(bson) for bson in db.bin.find({ f"contents.{batch_id}": {"$exists": True} })] locations = {bin.id: {batch_id: bin.contents[batch_id]} for bin in contained_by_bins} endpoint = BatchBinsEndpoint( resource_uri=url_for("batch.batch_bins_get", id=batch_id), state=locations ) return endpoint
def bins_(draw, id=None, props=None, contents=None): id = id or draw(label_("BIN")) # f"BIN{draw(integers(0, 6)):06d}" props = props or draw(propertyDicts) contents = contents or {} return Bin(id=id, props=props, contents=contents)
def bin_get(id): existing = Bin.from_mongodb_doc(db.bin.find_one({"_id": id})) if existing is None: return problem.missing_bin_response(id) else: return BinEndpoint.from_bin(existing).get_response()
def search(): query = request.args['query'] limit = getIntArgs(request.args, "limit", 20) startingFrom = getIntArgs(request.args, "startingFrom", 0) resp = Response() results = [] # debug flags if query == '!ALL': results.extend([Sku.from_mongodb_doc(e) for e in db.sku.find()]) results.extend([Batch.from_mongodb_doc(e) for e in db.batch.find()]) results.extend([Bin.from_mongodb_doc(e) for e in db.bin.find()]) if query == '!BINS': results.extend([Bin.from_mongodb_doc(e) for e in db.bin.find()]) if query == '!SKUS': results.extend([Sku.from_mongodb_doc(e) for e in db.sku.find()]) if query == '!BATCHES': results.extend([Batch.from_mongodb_doc(e) for e in db.batch.find()]) # search by label if query.startswith('SKU'): results.append(Sku.from_mongodb_doc(db.sku.find_one({'_id': query}))) if query.startswith('BIN'): results.append(Bin.from_mongodb_doc(db.bin.find_one({'_id': query}))) if query.startswith('BAT'): results.append( Batch.from_mongodb_doc(db.batch.find_one({'_id': query}))) results = [result for result in results if result != None] # search for skus with owned_codes cursor = db.sku.find({"owned_codes": query}) for sku_doc in cursor: results.append(Sku.from_mongodb_doc(sku_doc)) # search for skus with associated codes cursor = db.sku.find({"associated_codes": query}) for sku_doc in cursor: results.append(Sku.from_mongodb_doc(sku_doc)) # search for skus with owned_codes cursor = db.batch.find({"owned_codes": query}) for batch_doc in cursor: results.append(Batch.from_mongodb_doc(batch_doc)) # search for batchs with associated codes cursor = db.batch.find({"associated_codes": query}) for batch_doc in cursor: results.append(Batch.from_mongodb_doc(batch_doc)) # if not DEV_ENV: # maybe use global flag + env variable instead. Shouldn't need to check this every time in production/ if "name_text" in db.sku.index_information().keys(): cursor = db.sku.find({"$text": {"$search": query}}) for sku_doc in cursor: results.append(Sku.from_mongodb_doc(sku_doc)) if "name_text" in db.batch.index_information().keys(): cursor = db.batch.find({"$text": {"$search": query}}) for batch_doc in cursor: results.append(Batch.from_mongodb_doc(batch_doc)) if results != []: paged = results[startingFrom:(startingFrom + limit)] resp.status_code = 200 resp.mimetype = "application/json" # TODO: Add next page / prev page operations resp.data = json.dumps( { 'state': { "total_num_results": len(results), "starting_from": startingFrom, "limit": limit, "returned_num_results": len(paged), "results": paged }, "operations": [] }, cls=Encoder) return resp resp.status_code = 200 resp.mimetype = "application/json" resp.data = json.dumps( { 'state': { "total_num_results": len(results), "starting_from": startingFrom, "limit": limit, "returned_num_results": 0, "results": [] }, "operations": [] }, cls=Encoder) return resp
def bin_contents_post(id): into_bin = Bin.from_mongodb_doc(db.bin.find_one({"_id": id})) item_id = request.json['id'] quantity = request.json['quantity'] resp = Response() resp.headers.add("Cache-Control", "no-cache") if not into_bin: resp.status_code = 404 resp.mimetype = "application/problem+json" resp.data = json.dumps({ "type": "missing-resource", "title": "Can not receive items into a bin that does not exist.", "invalid-params": [{ "name": "id", "reason": "must be an exisiting bin id" }] }) return resp if item_id.startswith("SKU"): exisiting_sku = Sku.from_mongodb_doc(db.sku.find_one({"_id": item_id})) if not exisiting_sku: resp.status_code = 409 resp.mimetype = "application/problem+json" resp.data = json.dumps({ "type": "missing-resource", "title": "Can not receive sku that does not exist.", "invalid-params": [{ "name": "item_id", "reason": "must be an exisiting batch or sku id" }] }) return resp else: db.bin.update_one({"_id": into_bin.id}, {"$inc": { f"contents.{item_id}": quantity }}) resp.status_code = 201 return resp elif item_id.startswith("BAT"): existing_batch = Batch.from_mongodb_doc( db.batch.find_one({"_id": item_id})) if not existing_batch: resp.status_code = 409 resp.mimetype = "application/problem+json" resp.data = json.dumps({ "type": "missing-resource", "title": "Can not receive batch that does not exist.", "invalid-params": [{ "name": "item_id", "reason": "must be an exisiting batch or sku id" }] }) return resp else: db.bin.update_one({"_id": into_bin.id}, {"$inc": { f"contents.{item_id}": quantity }}) resp.status_code = 201 return resp else: resp.status_code = 409 resp.mimetype = "application/problem+json" resp.data = json.dumps({ "type": "bad-id-format", "title": "Received item id must be a batch or sku.", "invalid-params": [{ "name": "item_id", "reason": "must be an exisiting batch or sku id" }] }) return resp
def test_bin_default_contents(): bin = Bin(contents=None, id='BIN000000', props=None) assert json.loads(bin.to_json(mask_default=False)).get('contents') == {}
def test_bin(): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(id='BIN000000', props=None)) state.get_existing_bin(bin_id=v1) state.teardown()
def test_update_bin(): state = InventoryStateMachine() v1 = state.new_bin(bin=Bin(id='BIN000000', props=None)) state.update_bin(bin_id=v1, newProps={"1": "New props"}) state.get_existing_bin(bin_id=v1)