def test_recreate_batch(): state = InventoryStateMachine() v1 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000001', owned_codes=[], props=None, sku_id=None)) state.delete_unused_batch(batch_id=v1) state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000001', owned_codes=[], props=None, sku_id=None)) state.teardown()
def batch_patch(id): try: # must be batch patch, where json["id"] is prefixed and equals id json = batch_patch_schema.extend({"id": All(prefixed_id("BAT"), id)})(request.json) forced = forced_schema(request.args).get("force") except MultipleInvalid as e: return problem.invalid_params_response(e) existing_batch = Batch.from_mongodb_doc(db.batch.find_one({"_id": id})) if not existing_batch: return problem.missing_batch_response(id) if json.get("sku_id"): existing_sku = db.sku.find_one({"_id": json['sku_id']}) if not existing_sku: return problem.invalid_params_response( problem.missing_resource_param_error( "sku_id", "must be an existing sku id")) if (existing_batch.sku_id and "sku_id" in json and existing_batch.sku_id != json["sku_id"] and not forced): return problem.dangerous_operation_unforced_response( "sku_id", "The sku of this batch has already been set. Can not change without force=true." ) if "props" in json.keys(): db.batch.update_one({"_id": id}, {"$set": {"props": json['props']}}) if "name" in json.keys(): db.batch.update_one({"_id": id}, {"$set": {"name": json['name']}}) if "sku_id" in json.keys(): db.batch.update_one({"_id": id}, {"$set": {"sku_id": json['sku_id']}}) if "owned_codes" in json.keys(): db.batch.update_one({"_id": id}, {"$set": { "owned_codes": json['owned_codes'] }}) if "associated_codes" in json.keys(): db.batch.update_one( {"_id": id}, {"$set": { "associated_codes": json['associated_codes'] }}) updated_batch = Batch.from_mongodb_doc(db.batch.find_one({"_id": id})) return BatchEndpoint.from_batch(updated_batch).redirect_response(False)
def batch_delete(id): existing = Batch.from_mongodb_doc(db.batch.find_one({"_id": id})) if not existing: return problem.missing_batch_response(id) else: db.batch.delete_one({"_id": id}) return BatchEndpoint.from_batch(existing).deleted_success_response()
def batch_bins_get(id): resp = Response() existing = Batch.from_mongodb_doc(db.batch.find_one({"_id": id})) if not existing: return problem.missing_batch_response(id) return BatchBinsEndpoint.from_id(id, retrieve=True).get_response()
def batches_post(): try: json = new_batch_schema(request.json) except MultipleInvalid as e: return problem.invalid_params_response(e) batch = Batch.from_json(json) existing_batch = db.batch.find_one({"_id": batch.id}) if existing_batch: return problem.duplicate_resource_response("id") if batch.sku_id: existing_sku = db.sku.find_one({"_id": batch.sku_id}) if not existing_sku: return problem.invalid_params_response( problem.missing_resource_param_error( "sku_id", "must be an existing sku id")) admin_increment_code("BAT", batch.id) db.batch.insert_one(batch.to_mongodb_doc()) # Add text index if not yet created # TODO: This should probably be turned into a global flag if "name_text" not in db.batch.index_information().keys(): db.sku.create_index([("name", TEXT)]) return BatchEndpoint.from_batch(batch).created_success_response()
def batch_get(id): existing = Batch.from_mongodb_doc(db.batch.find_one({"_id": id})) if not existing: return problem.missing_batch_response(id) else: return BatchEndpoint.from_batch(existing).get_response()
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_batches_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 batches for a sku that does not exist.", "invalid-params": [{ "name": "id", "reason": "must be an exisiting sku id" }] }) return resp batches = [ Batch.from_mongodb_doc(bson).id for bson in db.batch.find({"sku_id": id}) ] resp.mimetype = "application/json" resp.data = json.dumps({"state": batches}) return resp
def new_batch_bad_format_owned_codes(self, data, sku_id, bad_code): batch = data.draw(dst.batches_(sku_id=sku_id)) assume(batch.id not in self.model_batches.keys()) temp_batch = Batch.from_json(batch.to_json()) temp_batch.owned_codes.append(bad_code) resp = self.client.post('/api/batches', json=temp_batch.to_dict()) assert resp.status_code == 400 assert resp.is_json assert resp.json['type'] == 'validation-error' temp_batch = Batch.from_json(batch.to_json()) temp_batch.associated_codes.append(bad_code) resp = self.client.post('/api/batches', json=temp_batch.to_dict()) assert resp.status_code == 400 assert resp.is_json assert resp.json['type'] == 'validation-error'
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_update_batch(): state = InventoryStateMachine() v1 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000000', owned_codes=[], props=None, sku_id=None)) state.update_batch(batch_id=v1, patch={'owned_codes': []}) state.get_existing_batch(batch_id=v1) state.teardown()
def from_batch(cls, data_batch: Batch): endpoint = BatchEndpoint( resource_uri=url_for("batch.batch_get", id=data_batch.id), state=data_batch.to_dict(), operations=[ operations.batch_update(id), operations.batch_delete(id), operations.batch_bins(id), ], ) endpoint.data_batch = data_batch return endpoint
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 test_change_batch_sku(): state = InventoryStateMachine() sku0 = state.new_sku(sku=Sku(id='SKU000000', name='')) sku1 = state.new_sku(sku=Sku(id='SKU000001', name='')) data = dst.DataProxy(Batch(id='BAT000000', sku_id=sku0)) batch0 = state.new_batch_existing_sku(data=data, sku_id=sku0) state.attempt_update_nonanonymous_batch_sku_id(batch_id=batch0, patch={}, sku_id=sku1) state.teardown()
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 test_new_batch_bad_format_owned_codes(): state = InventoryStateMachine() v1 = state.new_sku(sku=Sku( associated_codes=[], id='SKU000000', name='', owned_codes=[], props={})) data = dst.DataProxy( Batch(associated_codes=[], id='BAT000000', name='', owned_codes=[], props={}, sku_id='SKU000000')) state.new_batch_bad_format_owned_codes(bad_code='', data=data, sku_id=v1) state.teardown()
def test_update_batch_existing_sku(): state = InventoryStateMachine() v1 = state.new_sku(sku=Sku( associated_codes=[], id='SKU000000', name='', owned_codes=[], props={})) data = dst.DataProxy( Batch(associated_codes=[], id='BAT000000', name='', owned_codes=[], props={}, sku_id='SKU000000')) v2 = state.new_batch_existing_sku(data=data, sku_id=v1) state.update_batch(batch_id=v2, patch={}) state.teardown()
def test_add_sku_to_anonymous_batch(): state = InventoryStateMachine() v1 = state.new_sku(sku=Sku(associated_codes=[], id='SKU000000', name='', owned_codes=[], props=None)) v2 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000000', owned_codes=[], props=None, sku_id=None)) state.update_anonymous_batch_existing_sku_id(batch_id=v2, patch={}, sku_id=v1) state.teardown()
def test_update_batch_missing_sku(): state = InventoryStateMachine() state.delete_missing_user(user_id='00') state.delete_missing_user(user_id=';') v1 = state.new_user(user={'id': '1', 'name': '', 'password': '******'}) state.delete_missing_sku(sku_id='SKU066304') state.delete_missing_sku(sku_id='SKU000256') v2 = state.new_anonymous_batch(batch=Batch(associated_codes=[], id='BAT000000', name='', owned_codes=[], props={'a': [None]}, sku_id=None)) state.attempt_update_anonymous_batch_missing_sku_id(batch_id=v2, patch={}, sku_id='SKU000000') state.teardown()
def batches_(draw: DrawFn, id=None, sku_id=0, name=None, owned_codes=None, associated_codes=None, props=None): id = id or draw(label_("BAT")) if sku_id == 0: sku_id = draw(none(), label_("SKU")) name = name or draw(text("ABC")) owned_codes = owned_codes or draw(lists(text("abc", min_size=1))) associated_codes = associated_codes or draw(lists(text("abc", min_size=1))) props = props or draw(propertyDicts) return Batch(id=id, sku_id=sku_id, name=name, owned_codes=owned_codes, associated_codes=associated_codes, props=props)
def test_update_sku_batch(): state = InventoryStateMachine() v1 = state.new_sku(sku=Sku(associated_codes=[], id='SKU000001', name='', owned_codes=[], props=None)) v2 = state.new_sku(sku=Sku(associated_codes=[], id='SKU000002', name='', owned_codes=[], props=None)) # state.delete_missing_sku(sku_id='SKU000000') data = dst.DataProxy( Batch(associated_codes=[], id='BAT000000', owned_codes=[], props={0: 0}, sku_id='SKU000001')) v2 = state.new_batch_existing_sku(data=data, sku_id=v1) state.attempt_update_nonanonymous_batch_sku_id(batch_id=v2, patch={}, sku_id='SKU000002') state.teardown()
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 get_existing_batch(self, batch_id): rp = self.client.get(f"/api/batch/{batch_id}") assert rp.status_code == 200 assert rp.is_json found_batch = Batch.from_json(rp.json['state']) assert found_batch == self.model_batches[batch_id]
def test_get_attr(): batch = Batch(id="BAT1") assert hasattr(batch, "id") assert batch.sku_id == None