def post(self, promotion_id): """ Apply a promotion on a given set of products together with their prices This endpoint will return those given products with their updated price. Products that are not eligible to the given promotion will be returned without any update """ app.logger.info('Apply promotion {%s} to products', promotion_id) check_content_type('application/json') data = request.get_json() # Get promotion data promotion = Promotion.find(promotion_id) if not promotion: api.abort( status.HTTP_404_NOT_FOUND, 'Promotion with id "{}" was not found.'.format(promotion_id)) # Check promotion availability if not promotion.is_active(): api.abort( status.HTTP_409_CONFLICT, 'Promotion with id "{}" is not active.'.format(promotion_id)) # Get product data try: products = data['products'] assert isinstance(products, list) except KeyError: raise DataValidationError('Missing products key in request data') except AssertionError: raise DataValidationError('The given products in request data \ should be a list of serialized product objects') # Apply promotion on products products_with_new_prices = [] eligible_ids = promotion.products non_eligible_ids = [] print(eligible_ids) for product in products: product_id = product['product_id'] try: new_price = float(product['price']) except ValueError: raise DataValidationError( 'The given product prices cannot convert to a float number' ) if product_id in eligible_ids: new_price = new_price * (promotion.percentage / 100.0) else: non_eligible_ids.append(product_id) product['price'] = new_price products_with_new_prices.append(product) if len(non_eligible_ids) > 0: app.logger.info( 'The following products are not \ eligible to the given promotion: %s', non_eligible_ids) return {"products": products_with_new_prices}, status.HTTP_200_OK
def delete_promotion(promotion_id): """ Delete a Promotion This endpoint will delete a Promotion based the id specified in the path """ app.logger.info("Request to delete promotion with id: %s", promotion_id) promotion = Promotion.find(promotion_id) if promotion: promotion.delete() return make_response("", status.HTTP_204_NO_CONTENT)
def read_promotions(promotion_id): """ Reads a single promotion This endpoint will read an promotion based on it's promotion id """ app.logger.info("Request to read an promotion with id: {}".format(promotion_id)) promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("promotion with id '{}' was not found.".format(promotion_id)) return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def test_find_promotion(self): """ Find a Promotion by id """ Promotion("A002", "dog").save() # saved_promotion = Promotion("kitty", "cat").save() saved_promotion = Promotion("kitty", "cat") saved_promotion.save() promotion = Promotion.find(saved_promotion.id) self.assertIsNot(promotion, None) self.assertEqual(promotion.id, saved_promotion.id) self.assertEqual(promotion.productid, "kitty")
def get_promotions(promotion_id): """ Retrieve a single Promotion This endpoint will return a Promotion based on it's id """ app.logger.info("Request for promotion with id: %s", promotion_id) promotion = Promotion.find(promotion_id) if not promotion: raise NotFound( "Promotion with id '{}' was not found.".format(promotion_id)) return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def test_find(self): """ Find a Promotion by ID """ PromotionFactory(code="SAVE30").save() save50 = PromotionFactory(code="SAVE50") save50.save() promotion = Promotion.find(save50.id) self.assertIsNot(promotion, None) self.assertEqual(promotion.id, save50.id) self.assertEqual(promotion.code, save50.code) self.assertEqual(promotion.percentage, save50.percentage)
def delete(self, promotion_id): """ Delete a Promotion This endpoint will delete a Promotion based the id specified in the path """ app.logger.info('Request to Delete a promotion with id [%s]', promotion_id) promotion = Promotion.find(promotion_id) if promotion: promotion.delete() return '', status.HTTP_204_NO_CONTENT
def delete(self, promotion_id): """ Delete a Promotion This endpoint will delete a Promotion based the id specified in the path """ # pylint: disable=R1705 app.logger.info('Request to Delete a promotion with id [%s]', promotion_id) promo = Promotion.find(promotion_id) if promo: promo.delete() return '', status.HTTP_204_NO_CONTENT else: return '', status.HTTP_200_OK
def put(self, promotion_id): """ Cancel a Promotion """ promotion = Promotion.find(promotion_id) if not promotion: abort(status.HTTP_404_NOT_FOUND, "Promotion with id '{}' was not found.".format(promotion_id)) promotion.available = False promotion.save() return promotion.serialize(), status.HTTP_200_OK
def cancel_promotion(promotion_id): """ Cancel a promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info("Request to cancel promotion with id: %s", promotion_id) check_content_type("application/json") promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("Promotion with id '{}' was not found.".format(promotion_id)) promotion.end_date = datetime.datetime.now() promotion.save() return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def post(self, promotion_id): """ Cancels a single Promotion This endpoint will cancel a Promotion based on it's id """ app.logger.info("Request to cancel Promotion with id: %s", promotion_id) promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("Promotion with id '{}' was not found.".format(promotion_id)) promotion.end_date = datetime.now() promotion.update() app.logger.info("Promotion with ID [%s] cancelled", promotion_id) return make_response("", status.HTTP_200_OK)
def get(self, promotion_id): """ Retrieve a single Promotion This endpoint will return a Promotion based on it's id """ app.logger.info("Request to Retrieve a promotion with id [%s]", promotion_id) promotion = Promotion.find(promotion_id) if not promotion: abort(status.HTTP_404_NOT_FOUND, "Promotion with id '{}' was not found.".format(promotion_id)) return promotion.serialize(), status.HTTP_200_OK
def update_promotion(promotion_id): """ Update a promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info("Request to update promotion with id: %s", promotion_id) check_content_type("application/json") promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("Promotion with id '{}' was not found.".format(promotion_id)) promotion.deserialize(request.get_json()) promotion.id = promotion_id promotion.save() return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def test_find_promotion(self): """ Find a Promotion by ID """ promotions = PromotionFactory.create_batch(3) for promotion in promotions: promotion.create() logging.debug(promotions) # make sure they got saved self.assertEqual(len(Promotion.all()), 3) # find the 2nd promotion in the list promotion = Promotion.find(promotions[1].id) self.assertIsNot(promotion, None) self.assertEqual(promotion.id, promotions[1].id) self.assertEqual(promotion.name, promotions[1].name) self.assertEqual(promotion.description, promotions[1].description) self.assertEqual(promotion.end_date, promotions[1].end_date) self.assertEqual(promotion.start_date, promotions[1].start_date)
def test_find_promotion(self): """ Find a Promotion by ID """ promotions = PromotionFactory.create_batch(3) for promotion in promotions: promotion.create() logging.debug(promotions) # find the 2nd promotion in the list promotion = Promotion.find(promotions[1].id) self.assertIsNot(promotion, None) self.assertEqual(promotion.id, promotions[1].id) self.assertEqual(promotion.title, promotions[1].title) self.assertEqual(promotion.description, promotions[1].description) self.assertEqual(promotion.promo_code, promotions[1].promo_code) self.assertEqual(promotion.promo_type, promotions[1].promo_type) self.assertEqual(promotion.amount, promotions[1].amount) self.assertEqual(promotion.start_date, promotions[1].start_date) self.assertEqual(promotion.end_date, promotions[1].end_date) self.assertEqual(promotion.is_site_wide, promotions[1].is_site_wide)
def put(self, promotion_id): """ Update a Promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info( 'Request to update promotion with promotion id {}'.format( promotion_id)) check_content_type('application/json') promotion = Promotion.find(promotion_id) if not promotion: api.abort( status.HTTP_404_NOT_FOUND, "Promotion with id '{}' was not found.".format(promotion_id)) promotion.deserialize(request.get_json()) promotion.id = promotion_id promotion.save() app.logger.info( 'Promotion with id {} successfully updated'.format(promotion_id)) return promotion.serialize(), status.HTTP_200_OK
def put(self, promotion_id): """ Update a Promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info('Request to Update a promotion with id [%s]', promotion_id) #check_content_type('application/json') promotion = Promotion.find(promotion_id) if not promotion: abort(status.HTTP_404_NOT_FOUND, "Promotion with id '{}' was not found.".format(promotion_id)) payload = request.get_json() try: promotion.deserialize(payload) except DataValidationError as error: raise BadRequest(str(error)) promotion.id = promotion_id promotion.save() return promotion.serialize(), status.HTTP_200_OK
def put(self, promotion_id): """ Update a Promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info("Request to update promotion with id: %s", promotion_id) check_content_type("application/json") json = request.get_json() promotion = Promotion.find(promotion_id) if not promotion: api.abort( status.HTTP_404_NOT_FOUND, "Promotion with id '{}' was not found.".format(promotion_id), ) json = request.get_json() if "products" in json: for product_id in json["products"]: if product_id != "" and Product.query.get(product_id) is None: Product(id=product_id).create() promotion.deserialize(json) promotion.id = promotion_id promotion.update() app.logger.info("Promotion with ID [%s] updated.", promotion.id) return promotion.serialize(), status.HTTP_200_OK
def test_promotion_not_found(self): """ Find a Promotion that doesnt exist """ Promotion("A002", "dog").save() promotion = Promotion.find("2") self.assertIs(promotion, None)
def test_find_with_no_promotions(self): """ Find a Promotion with empty database """ promotion = Promotion.find("1") self.assertIs(promotion, None)