Пример #1
0
def sku_patch(id):
    try:
        json = sku_patch_schema.extend({"id": prefixed_id("SKU",
                                                          id)})(request.json)
    except MultipleInvalid as e:
        return problem.invalid_params_response(e)

    existing = Sku.from_mongodb_doc(db.sku.find_one({"_id": id}))
    if not existing:
        return problem.invalid_params_response(
            problem.missing_resource_param_error("id"))

    if "owned_codes" in json:
        db.sku.update_one({"_id": id},
                          {"$set": {
                              "owned_codes": json["owned_codes"]
                          }})
    if "associated_codes" in json:
        db.sku.update_one(
            {"_id": id},
            {"$set": {
                "associated_codes": json["associated_codes"]
            }})
    if "name" in json:
        db.sku.update_one({"_id": id}, {"$set": {"name": json["name"]}})
    if "props" in json:
        db.sku.update_one({"_id": id}, {"$set": {"props": json["props"]}})

    updated_sku = Sku.from_mongodb_doc(db.sku.find_one({"_id": id}))
    return SkuEndpoint.from_sku(updated_sku).updated_success_response()
def test_sku_equality(original_sku):
    serde1_sku = Sku.from_json(original_sku.to_json())
    serde2_sku = Sku.from_mongodb_doc(original_sku.to_mongodb_doc())

    assert original_sku == serde1_sku
    assert serde1_sku == original_sku
    assert original_sku == serde2_sku
    assert serde2_sku == original_sku
    assert serde1_sku == serde2_sku
    assert original_sku == original_sku
Пример #3
0
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 new_sku_bad_format_owned_codes(self, sku, bad_code):
        assume(sku.id not in self.model_skus.keys())
        temp_sku = Sku.from_json(sku.to_json())
        temp_sku.owned_codes.append(bad_code)
        resp = self.client.post('/api/skus', json=temp_sku.to_dict())
        assert resp.status_code == 400
        assert resp.is_json
        assert resp.json['type'] == 'validation-error'

        temp_sku = Sku.from_json(sku.to_json())
        temp_sku.associated_codes.append(bad_code)
        resp = self.client.post('/api/skus', json=temp_sku.to_dict())
        assert resp.status_code == 400
        assert resp.is_json
        assert resp.json['type'] == 'validation-error'
Пример #5
0
def test_update_sku():
    state = InventoryStateMachine()
    v1 = state.new_sku(sku=Sku(
        associated_codes=[], id='SKU000000', name='', owned_codes=[],
        props={}))
    state.update_sku(patch={}, sku_id=v1)
    state.teardown()
Пример #6
0
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
Пример #7
0
def sku_get(id):
    # detailed = request.args.get("details") == "true"

    sku = Sku.from_mongodb_doc(db.sku.find_one({"_id": id}))
    if sku is None:
        return problem.missing_bin_response(id)
    return SkuEndpoint.from_sku(sku).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)
Пример #9
0
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
Пример #10
0
def test_delete_sku():
    state = InventoryStateMachine()
    v1 = state.new_sku(sku=Sku(associated_codes=[],
                               id='SKU000000',
                               name='',
                               owned_codes=[],
                               props=None))
    state.delete_unused_sku(sku_id=v1)
    state.teardown()
Пример #11
0
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()
Пример #12
0
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()
Пример #13
0
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()
Пример #14
0
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()
Пример #15
0
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()
Пример #16
0
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()
Пример #17
0
def skus_(draw,
          id=None,
          owned_codes=None,
          name=None,
          associated_codes=None,
          props=None):
    id = id or draw(label_("SKU"))
    owned_codes = owned_codes or draw(lists(text("abc", min_size=1)))
    associated_codes = associated_codes or draw(lists(text("abc", min_size=1)))
    name = name or draw(text("ABC"))
    props = props or draw(propertyDicts)
    return Sku(id=id,
               owned_codes=owned_codes,
               name=name,
               associated_codes=associated_codes,
               props=props)
Пример #18
0
def sku_delete(id):
    existing = Sku.from_mongodb_doc(db.sku.find_one({"_id": id}))

    resp = Response()
    resp.headers.add("Cache-Control", "no-cache")

    if existing is None:
        resp.status_code = 404
        resp.mimetype = "application/problem+json"
        resp.data = json.dumps({
            "type":
            "missing-resource",
            "title":
            "Can not delete sku that does not exist.",
            "invalid-params": [{
                "name": "id",
                "reason": "must be an exisiting sku id"
            }]
        })
        return resp

    num_contained_by_bins = db.bin.count_documents(
        {f"contents.{id}": {
            "$exists": True
        }})
    if num_contained_by_bins > 0:
        resp.status_code = 403
        resp.mimetype = "application/problem+json"
        resp.data = json.dumps({
            "type": "resource-in-use",
            "title":
            "Can not delete sku that is being used. Try releasing all instances of this sku.",
            "invalid-params": {
                "name": "id",
                "reason": "must be an unused sku"
            }
        })
        return resp

    db.sku.delete_one({"_id": existing.id})
    resp.status_code = 204
    return resp
Пример #19
0
def skus_post():
    try:
        json = new_sku_schema(request.json)
    except MultipleInvalid as e:
        return problem.invalid_params_response(e)

    if db.sku.find_one({'_id': json['id']}):
        return problem.duplicate_resource_response("id")

    sku = Sku.from_json(json)
    admin_increment_code("SKU", sku.id)
    db.sku.insert_one(sku.to_mongodb_doc())
    # dbSku = Sku.from_mongodb_doc(db.sku.find_one({'id': sku.id}))

    # Add text index if not yet created
    # TODO: This should probably be turned into a global flag
    if "name_text" not in db.sku.index_information().keys():
        # print("Creating text index for sku#name") # was too noisy
        db.sku.create_index([("name", TEXT)])
    return SkuEndpoint.from_sku(sku).created_success_response()
Пример #20
0
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
Пример #21
0
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_sku(self, sku_id):
     rp = self.client.get(f"/api/sku/{sku_id}")
     assert rp.status_code == 200
     assert rp.is_json
     found_sku = Sku(**rp.json['state'])
     assert found_sku == self.model_skus[sku_id]