def list_inventories(): """ Returns a list of all inventories in the inventory GET /inventory """ app.logger.info("A GET request for ALL inventories") inventories = [] params = request.args if len(params) > 0: pid = params.get("product_id") if pid: inventories = Inventory.find_by_product_id(pid) else: return bad_request( "Invalid request parameters: missing (product_id)") else: inventories = Inventory.all() results = [] for inv in inventories: json = inv.serialize() # if json['available'] == 1: results.append(json) if len(results) == 0: return not_found("Inventories were not found") app.logger.info("Returning {} inventories".format(len(results))) return make_response(jsonify(results), status.HTTP_200_OK)
def post(self): """ Creates a Inventory This endpoint will create a Inventory based the data in the body that is posted """ try: app.logger.info("Request to create an Inventory record") inventory = Inventory() inventory.deserialize(api.payload) inventory.validate_data() if Inventory.find_by_product_id_condition( api.payload[keys.KEY_PID], api.payload[keys.KEY_CND]): api.abort( status.HTTP_409_CONFLICT, "Inventory with ({}, {})".format(inventory.product_id, inventory.condition)) inventory.create() location_url = api.url_for(InventoryResource, product_id=inventory.product_id, condition=inventory.condition, _external=True) app.logger.info("Inventory ({}, {}) created."\ .format(inventory.product_id, inventory.condition)) return inventory.serialize(), status.HTTP_201_CREATED, { 'Location': location_url } except DataValidationError as err: api.abort(status.HTTP_400_BAD_REQUEST, err)
def test_delete(self): """Delete an Inventory""" inventory = Inventory(product_id=777, condition="new", quantity=1, restock_level=10, available=1) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() self.assertEqual(len(Inventory.find_all()), 1) inventory.delete() self.assertEqual(len(Inventory.find_all()), 0)
def call_create(self,pid,cnd,qty,lvl,avl,err): inventory = Inventory(product_id=pid, condition=cnd, quantity=qty, restock_level=lvl, available=avl) if err==1: self.assertRaises(DataValidationError, inventory.validate_data) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() self.assertTrue(inventory is not None) self.assertTrue(inventory.product_id, int(pid)) self.assertEqual(inventory.condition, cnd) self.assertEqual(inventory.quantity, int(qty)) self.assertEqual(inventory.restock_level, int(lvl)) self.assertEqual(inventory.available, int(avl))
def test_update(self): """Update an Inventory""" inventory = Inventory(product_id=666, condition="new", quantity=1, restock_level=10, available=1) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() inventory.product_id = 667 inventory.update() inventories = Inventory.find_all() self.assertEqual(len(inventories), 1) self.assertEqual(inventories[0].product_id, 667)
def test_deserialize_bad_data(self): """ Test deserialization of bad data """ data = "this is not a dictionary" inventory = Inventory() self.assertRaises(DataValidationError, inventory.deserialize, data) data = {} self.assertRaises(DataValidationError, inventory.deserialize, data)
def put(self, product_id, condition): """ Update an Inventory This endpoint will update a Inventory based the body that is posted """ app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) try: inventory = Inventory.find_by_product_id_condition( product_id, condition) if not inventory: api.abort( status.HTTP_404_NOT_FOUND, "Inventory with ({}, {})".format(product_id, condition)) resp_old = inventory.serialize() resp_new = api.payload for key in resp_old.keys(): if key in resp_new: resp_old[key] = resp_new[key] inventory.deserialize(resp_old) inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) updated.".format( product_id, condition)) return inventory.serialize(), status.HTTP_200_OK except DataValidationError as err: api.abort(status.HTTP_400_BAD_REQUEST, err)
def update_inventory_restock(product_id, condition): """- Given the product_id, condition and amount (body) this updates quantity += amount""" app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) # Checking for Content-Type check_content_type("application/json") # Checking for 'amount' keyword json = request.get_json() print(json.keys()) if "amount" not in json.keys(): return bad_request("Invalid data: Amount missing") # Checking for amount >= 0 amount = json['amount'] if amount < 0: return forbidden("Invalid data: Amount <= 0") # If there is no matching inventory inventory = Inventory.find(product_id, condition) if not inventory: return not_found("Inventory with ({}, {})".format( product_id, condition)) inventory.quantity += amount inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) updated.".format( product_id, condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_200_OK)
def update_inventory(product_id, condition): """ Regular Update Updates the inventory with the given product_id and condition """ app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) check_content_type("application/json") inventory = Inventory.find(product_id, condition) if not inventory: return not_found("Inventory with ({}, {})".format( product_id, condition)) resp_old = inventory.serialize() resp_new = request.get_json() for key in resp_old.keys(): if key in resp_new: resp_old[key] = resp_new[key] if inventory.quantity == 0: inventory.available = 0 inventory.deserialize(resp_old) inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) updated.".format( product_id, condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_200_OK)
def call_serialize(self,pid,cnd,qty,lvl,avl,err): inventory = Inventory(product_id=pid, condition=cnd, quantity=qty, restock_level=lvl, available=avl) if err==1: self.assertRaises(DataValidationError, inventory.validate_data) data = inventory.serialize() self.assertNotEqual(data, None) self.assertIn(keys.KEY_PID, data) self.assertEqual(data[keys.KEY_PID], pid) self.assertIn(keys.KEY_CND, data) self.assertEqual(data[keys.KEY_CND], cnd) self.assertIn(keys.KEY_QTY, data) self.assertEqual(data[keys.KEY_QTY], qty) self.assertIn(keys.KEY_LVL, data) self.assertEqual(data[keys.KEY_LVL], lvl) self.assertIn(keys.KEY_AVL, data) self.assertEqual(data[keys.KEY_AVL], avl)
def call_deserialize(self,pid,cnd,qty,lvl,avl,err): data = { keys.KEY_PID: pid, keys.KEY_CND: cnd, keys.KEY_QTY: qty, keys.KEY_LVL: lvl, keys.KEY_AVL: avl } inventory = Inventory() inventory.deserialize(data) if err==1: self.assertRaises(DataValidationError, inventory.validate_data) self.assertNotEqual(inventory, None) self.assertEqual(inventory.product_id, pid) self.assertEqual(inventory.condition, cnd) self.assertEqual(inventory.quantity, qty) self.assertEqual(inventory.restock_level, lvl) self.assertEqual(inventory.available, avl)
def delete_inventory(product_id, condition): """Deletes an inventory with the given product_id and condition""" inventory = Inventory.find(product_id, condition) app.logger.info("Request to delete inventory with key ({}, {})"\ .format(product_id, condition)) if inventory: inventory.delete() app.logger.info( "Inventory with product_id {} and condition {} deleted".format( product_id, condition)) return make_response("", status.HTTP_204_NO_CONTENT)
def get(self): """ Returns a collection of the inventory records """ msg = "A GET request for ALL inventories." inventories = [] params = inventory_args.parse_args() if params[keys.KEY_PID]: pid = params[keys.KEY_PID] query = 'Filtering by category: {}'.format(params[keys.KEY_PID]) app.logger.info(query) msg = "{} {}".format(msg, query) inventories = Inventory.find_by_product_id(pid) elif params[keys.KEY_CND]: cnd = params[keys.KEY_CND] query = 'Filtering by category: {}'.format(params[keys.KEY_CND]) app.logger.info(query) msg = "{} {}".format(msg, query) inventories = Inventory.find_by_condition(cnd) elif params[keys.KEY_QTY] and params[keys.KEY_QTY] >= 0: qty = params[keys.KEY_QTY] query = 'Filtering by category: {}'.format(params[keys.KEY_QTY]) app.logger.info(query) msg = "{} {}".format(msg, query) inventories = Inventory.find_by_quantity(qty) elif params[keys.KEY_AVL] in [ keys.AVAILABLE_TRUE, keys.AVAILABLE_FALSE ]: avl = params[keys.KEY_AVL] query = 'Filtering by category: {}'.format(params[keys.KEY_AVL]) app.logger.info(query) msg = "{} {}".format(msg, query) inventories = Inventory.find_by_available(avl) else: inventories = Inventory.find_all() app.logger.info(msg) results = [inv.serialize() for inv in inventories] app.logger.info("Returning {} inventories".format(len(results))) return results, status.HTTP_200_OK
def create_inventory(): """ Creates a new inventory in the Inventory DB based the data in the body POST /inventory """ app.logger.info("Request to create an Inventory record") check_content_type("application/json") json = request.get_json() inventory = Inventory() inventory.deserialize(json) inventory.validate_data() if Inventory.find(json['product_id'], json['condition']): return create_conflict_error( "The Record you're trying to create already exists!") inventory.create() location_url = url_for("get_inventory_by_pid_condition",\ product_id=inventory.product_id, condition=inventory.condition, _external=True) app.logger.info("Inventory ({}, {}) created."\ .format(inventory.product_id, inventory.condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_201_CREATED, {"Location": location_url})
def get_inventory_by_pid_condition(product_id, condition): """ Returns the inventory with the given product_id and condition GET /inventory/<int:product_id>/condition/<string:condition> """ app.logger.info("A GET request for inventories with product_id {} and condition {}"\ .format(product_id, condition)) inventory = Inventory.find(product_id, condition) # if (not inventory) or\ # (inventory and inventory.serialize()['available'] == 0): if not inventory: return not_found("Inventory ({}, {})".format(product_id, condition)) app.logger.info("Return inventory with product_id {} and condition {}"\ .format(product_id, condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_200_OK)
def update_inventory_deactivate(product_id, condition): """Given the product_id and condition this updates available = 0""" app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) inventory = Inventory.find(product_id, condition) if not inventory: return not_found("Inventory with ({}, {})".format( product_id, condition)) inventory.available = 0 inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) updated.".format( product_id, condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_200_OK)
def delete(self, product_id, condition): """ Delete a Inventory This endpoint will delete a Inventory based the id specified in the path """ app.logger.info("Request to delete inventory with key ({}, {})"\ .format(product_id, condition)) inventory = Inventory.find_by_product_id_condition( product_id, condition) if inventory: inventory.delete() app.logger.info( "Inventory with product_id {} and condition {} deleted".format( product_id, condition)) return '', status.HTTP_204_NO_CONTENT
def call_validate_data(self,pid,cnd,qty,lvl,avl,res): inventory = Inventory(product_id=pid, condition=cnd, quantity=qty, restock_level=lvl, available=avl) self.assertTrue(inventory != None) res_pid = inventory.validate_data_product_id() self.assertEqual(res_pid,res) res_cnd = inventory.validate_data_condition() self.assertEqual(res_cnd,res) res_qty = inventory.validate_data_quantity() self.assertEqual(res_qty,res) res_lvl = inventory.validate_data_restock_level() self.assertEqual(res_lvl,res) res_avl = inventory.validate_data_available() self.assertEqual(res_avl,res) try: err = inventory.validate_data() except DataValidationError as err: print(err)
def get(self, product_id, condition): """ Retrieve a single Inventory This endpoint will return a Inventory based on it's id """ app.logger.info("A GET request for inventories with product_id {} and condition {}"\ .format(product_id, condition)) inventory = Inventory.find_by_product_id_condition( product_id, condition) if not inventory: api.abort( status.HTTP_404_NOT_FOUND, "Inventory ({}, {}) NOT FOUND".format(product_id, condition)) app.logger.info("Return inventory with product_id {} and condition {}"\ .format(product_id, condition)) return inventory.serialize(), status.HTTP_200_OK
def put(self, product_id, condition): """ Restock an Inventory's Quantity """ app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) # Check if the record exists inventory = Inventory.find_by_product_id_condition( product_id, condition) if not inventory: api.abort(status.HTTP_404_NOT_FOUND, "Inventory with ({}, {})".format(product_id, condition)) inventory.available = 0 inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) restocked.".format( product_id, condition)) return inventory.serialize(), status.HTTP_200_OK
def update_inventory_activate(product_id, condition): """Given the product_id and condition this updates available = 1""" app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) inventory = Inventory.find(product_id, condition) if not inventory: return not_found("Inventory with ({}, {})".format( product_id, condition)) if inventory.quantity == 0: return forbidden( "This product is currently out of stock and cannot be made available" ) inventory.available = 1 inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) updated.".format( product_id, condition)) return make_response(jsonify(inventory.serialize()), status.HTTP_200_OK)
def put(self, product_id, condition): """ Restock an Inventory's Quantity """ app.logger.info("Request to update inventory with key ({}, {})"\ .format(product_id, condition)) # Check if the record exists inventory = Inventory.find_by_product_id_condition( product_id, condition) if not inventory: api.abort(status.HTTP_404_NOT_FOUND, "Inventory with ({}, {})".format(product_id, condition)) # Checking for keys.KEY_AMT keyword json = request.get_json() json = api.payload if "amount" not in json.keys(): api.abort(status.HTTP_400_BAD_REQUEST, "Invalid data: Amount missing") # Checking for amount >= 0 amount = json[keys.KEY_AMT] regex = "^\-?\d+$" if not re.search(regex, str(amount)): api.abort(status.HTTP_400_BAD_REQUEST, "Invalid data: Amount must be an integer") else: if int(amount) <= 0: api.abort(status.HTTP_400_BAD_REQUEST, "Invalid data: Amount <= 0") inventory.quantity += int(amount) inventory.validate_data() inventory.update() app.logger.info("Inventory ({}, {}) restocked.".format( product_id, condition)) return inventory.serialize(), status.HTTP_200_OK
def init_db(): """ Initialies the SQLAlchemy app """ # global app Inventory.init_db(app)
def init_db(dbname=keys.KEY_DB_NAME): """ Initlaize the model """ Inventory.init_db(app)
def test_repr(self): """ Test Inventory __repr__ """ pid = 1234567 inventory = Inventory(product_id=pid) inventory.__repr__()
def test_find_by_quantity(self): inventory = Inventory(product_id=333, condition="new", quantity=4, restock_level=10, available=1) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() inventory = Inventory(product_id=444, condition="new", quantity=2, restock_level=10, available=0) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() inventories = Inventory.find_by_quantity(2) self.assertEqual(len(list(inventories)), 2)
def setUpClass(cls): """ These run once before Test suite """ app.debug = False # Set up the test database app.config[keys.KEY_SQL_ALC] = DATABASE_URI Inventory.init_db(app)
def test_find_by_product_id_condition(self): """Find an Inventory by product_id and condition""" inventory = Inventory(product_id=555, condition="new", quantity=1, restock_level=10, available=1) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() inventory = Inventory(product_id=666, condition="new", quantity=1, restock_level=10, available=0) if not Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition): inventory.create() result = Inventory.find_by_product_id_condition(inventory.product_id, inventory.condition) self.assertIsNot(result, None) self.assertEqual(result.product_id, 666) self.assertEqual(result.condition, "new") self.assertEqual(result.quantity, 1) self.assertEqual(result.restock_level, 10) self.assertEqual(result.available, 0)