diff --git a/api/core.py b/api/core.py index 8418c2d..392c48b 100644 --- a/api/core.py +++ b/api/core.py @@ -3,7 +3,7 @@ from api.extensions import db, esales from api.validators import ValidationError -def create_app(config_name='config'): +def create_app(config_name="config"): app = Flask(__name__) app.config.from_object(config_name) @@ -14,18 +14,20 @@ def create_app(config_name='config'): @app.errorhandler(404) def on_404(error): response = jsonify( - {'status': 404, 'message': 'The requested resource was not found'}) + {"status": 404, "message": "The requested resource was not found"} + ) response.status_code = 404 return response @app.errorhandler(ValidationError) def on_validation_error(error): - response = jsonify({'status': 400, 'message': error.message}) + response = jsonify({"status": 400, "message": error.message}) response.status_code = 400 return response # register resources from api.resources import server, designers, categories, prices + app.register_blueprint(server.mod) app.register_blueprint(designers.mod) app.register_blueprint(categories.mod) diff --git a/api/helpers.py b/api/helpers.py index 42b000b..c88e449 100644 --- a/api/helpers.py +++ b/api/helpers.py @@ -9,21 +9,19 @@ def check_api_key(): return auth = request.authorization if not auth or not auth.username in api_keys: - response = json.dumps( - {'status': 401, 'message': 'No valid API key provided'}) + response = json.dumps({"status": 401, "message": "No valid API key provided"}) return Response( - response, 401, - {'WWW-Authenticate': 'Basic realm="Login Required"'} + response, 401, {"WWW-Authenticate": 'Basic realm="Login Required"'} ) def pagination_to_dict(pagination): return { - 'page': pagination.page, - 'pages': pagination.pages, - 'next_num': pagination.next_num, - 'per_page': pagination.per_page, - 'has_next': pagination.has_next, - 'has_prev': pagination.has_prev, - 'total': pagination.total + "page": pagination.page, + "pages": pagination.pages, + "next_num": pagination.next_num, + "per_page": pagination.per_page, + "has_next": pagination.has_next, + "has_prev": pagination.has_prev, + "total": pagination.total, } diff --git a/api/lib/limits.py b/api/lib/limits.py index bf11fc7..f703530 100644 --- a/api/lib/limits.py +++ b/api/lib/limits.py @@ -1,31 +1,31 @@ # coding=UTF-8 CANVAS = { - 'max_long_side': 500, - 'min_long_side': 20, - 'max_short_side': 150, - 'min_short_side': 20 + "max_long_side": 500, + "min_long_side": 20, + "max_short_side": 150, + "min_short_side": 20, } CANVAS_FRAME = { - 'max_long_side': 150, - 'min_long_side': 40, - 'max_short_side': 150, - 'min_short_side': 40, + "max_long_side": 150, + "min_long_side": 40, + "max_short_side": 150, + "min_short_side": 40, } def calculate_canvas_frame_limits(width, height): if width > height: - width = min(width, CANVAS_FRAME.get('max_long_side')) - width = max(width, CANVAS_FRAME.get('min_long_side')) - height = min(height, CANVAS_FRAME.get('max_short_side')) - height = max(height, CANVAS_FRAME.get('min_short_side')) + width = min(width, CANVAS_FRAME.get("max_long_side")) + width = max(width, CANVAS_FRAME.get("min_long_side")) + height = min(height, CANVAS_FRAME.get("max_short_side")) + height = max(height, CANVAS_FRAME.get("min_short_side")) else: - height = min(height, CANVAS_FRAME.get('max_long_side')) - height = max(height, CANVAS_FRAME.get('min_long_side')) - width = min(width, CANVAS_FRAME.get('max_short_side')) - width = max(width, CANVAS_FRAME.get('min_short_side')) + height = min(height, CANVAS_FRAME.get("max_long_side")) + height = max(height, CANVAS_FRAME.get("min_long_side")) + width = min(width, CANVAS_FRAME.get("max_short_side")) + width = max(width, CANVAS_FRAME.get("min_short_side")) # round to nearest 10 width = round(width, -1) @@ -39,14 +39,14 @@ def calculate_canvas_limits(width, height, framed=False): return calculate_canvas_frame_limits(width, height) if width > height: - width = min(width, CANVAS.get('max_long_side')) - width = max(width, CANVAS.get('min_long_side')) - height = min(height, CANVAS.get('max_short_side')) - height = max(height, CANVAS.get('min_short_side')) + width = min(width, CANVAS.get("max_long_side")) + width = max(width, CANVAS.get("min_long_side")) + height = min(height, CANVAS.get("max_short_side")) + height = max(height, CANVAS.get("min_short_side")) else: - height = min(height, CANVAS.get('max_long_side')) - height = max(height, CANVAS.get('min_long_side')) - width = min(width, CANVAS.get('max_short_side')) - width = max(width, CANVAS.get('min_short_side')) + height = min(height, CANVAS.get("max_long_side")) + height = max(height, CANVAS.get("min_long_side")) + width = min(width, CANVAS.get("max_short_side")) + width = max(width, CANVAS.get("min_short_side")) return width, height diff --git a/api/lib/prices.py b/api/lib/prices.py index 4ad449f..2b82d6d 100644 --- a/api/lib/prices.py +++ b/api/lib/prices.py @@ -5,7 +5,15 @@ from api.lib.utils import round_half_up from api.lib.limits import calculate_canvas_limits -def m2_price(material, market, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): +def m2_price( + material, + market, + designer=None, + reseller=None, + inquiry=None, + rounded=True, + inc_vat=True, +): """ calculates price per square meter """ price = material.price / 100.0 @@ -30,9 +38,20 @@ def m2_price(material, market, designer=None, reseller=None, inquiry=None, round return price -def wallpaper_price(width, height, material, market, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): - price = m2_price(material, market, designer, reseller, - inquiry, rounded=rounded, inc_vat=False) +def wallpaper_price( + width, + height, + material, + market, + designer=None, + reseller=None, + inquiry=None, + rounded=True, + inc_vat=True, +): + price = m2_price( + material, market, designer, reseller, inquiry, rounded=rounded, inc_vat=False + ) sqm = (width / 100) * (height / 100) @@ -81,8 +100,8 @@ def canvas_cm2_price(cm2): def package_price(product_group, width, height, market): - if market.territory == 'US': - if product_group in ['canvas', 'poster']: + if market.territory == "US": + if product_group in ["canvas", "poster"]: if width > 110: return 150 else: @@ -90,7 +109,17 @@ def package_price(product_group, width, height, market): return 0 -def canvas_price(width, height, market, framed=True, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): +def canvas_price( + width, + height, + market, + framed=True, + designer=None, + reseller=None, + inquiry=None, + rounded=True, + inc_vat=True, +): cm2 = width * height cm2_price = canvas_cm2_price(cm2) @@ -113,7 +142,7 @@ def canvas_price(width, height, market, framed=True, designer=None, reseller=Non if inquiry: price *= (float(inquiry.pricepremium) / 100) + 1 - price += package_price('canvas', width, height, market) + price += package_price("canvas", width, height, market) price *= market.exchange_rate @@ -126,7 +155,9 @@ def canvas_price(width, height, market, framed=True, designer=None, reseller=Non return price -def canvas_frame_price(width, height, market, reseller=None, rounded=True, inc_vat=True): +def canvas_frame_price( + width, height, market, reseller=None, rounded=True, inc_vat=True +): width, height = calculate_canvas_limits(width, height, framed=True) cm2 = width * height cm2_price = canvas_cm2_price(cm2) @@ -139,7 +170,7 @@ def canvas_frame_price(width, height, market, reseller=None, rounded=True, inc_v if reseller: price *= (float(reseller.pricepremium) / 100) + 1 - price += package_price('canvas', width, height, market) + price += package_price("canvas", width, height, market) price *= market.exchange_rate @@ -178,13 +209,23 @@ def poster_cm2_price(cm2): return cm2_price -def poster_price(width, height, market, hanger=True, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): +def poster_price( + width, + height, + market, + hanger=True, + designer=None, + reseller=None, + inquiry=None, + rounded=True, + inc_vat=True, +): cm2 = width * height cm2_price = poster_cm2_price(cm2) price = cm2 * cm2_price price = max(price, 200) # the price can never go below 200 SEK - if(hanger): + if hanger: price += _price_for_poster_hanger_size(width) price *= market.price_adjustments @@ -198,7 +239,7 @@ def poster_price(width, height, market, hanger=True, designer=None, reseller=Non if inquiry: price *= (float(inquiry.pricepremium) / 100) + 1 - price += package_price('poster', width, height, market) + price += package_price("poster", width, height, market) price *= market.exchange_rate @@ -214,14 +255,16 @@ def poster_price(width, height, market, hanger=True, designer=None, reseller=Non def poster_hanger_price(width, market, reseller=None, rounded=True, inc_vat=True): """calculates price for poster hanger only""" price = _price_for_poster_hanger_size(width) - price += 50 # add 50 SEK extra since they are buying only the hanger + price += 50 # add 50 SEK extra since they are buying only the hanger price *= market.price_adjustments if reseller: price *= (float(reseller.pricepremium) / 100) + 1 - price += package_price('poster', width, 10, market) # we assume the poster hanger has a height of 10cm here + price += package_price( + "poster", width, 10, market + ) # we assume the poster hanger has a height of 10cm here price *= market.exchange_rate @@ -250,37 +293,64 @@ def _price_for_poster_hanger_size(size): if size > 125 and size <= 150: return 262 - raise ValueError('Invalid poster hanger size: {}'.format(size)) + raise ValueError("Invalid poster hanger size: {}".format(size)) -def inquiry_price(inquiry, inc_price_retouch=True, rounded=True, inc_vat=True, **kwargs): - width = kwargs.get('width', inquiry.width) - height = kwargs.get('height', inquiry.height) - material = kwargs.get('material', inquiry.material) - framed = kwargs.get('framed', inquiry.framed) - hanger = kwargs.get('hanger', inquiry.hanger) - reseller = kwargs.get('reseller', inquiry.dealer_store) +def inquiry_price( + inquiry, inc_price_retouch=True, rounded=True, inc_vat=True, **kwargs +): + width = kwargs.get("width", inquiry.width) + height = kwargs.get("height", inquiry.height) + material = kwargs.get("material", inquiry.material) + framed = kwargs.get("framed", inquiry.framed) + hanger = kwargs.get("hanger", inquiry.hanger) + reseller = kwargs.get("reseller", inquiry.dealer_store) - if inquiry.product_group == 'photo-wallpaper': - price = wallpaper_price(width, height, material, inquiry.market, - designer=inquiry.designer, reseller=reseller, inquiry=inquiry, rounded=False, inc_vat=False) - elif inquiry.product_group == 'canvas': - price = canvas_price(width, height, inquiry.market, - designer=inquiry.designer, reseller=reseller, inquiry=inquiry, framed=framed, rounded=False, inc_vat=False) - elif inquiry.product_group == 'poster': - price = poster_price(width, height, inquiry.market, - designer=inquiry.designer, reseller=reseller, inquiry=inquiry, hanger=hanger, rounded=False, inc_vat=False) + if inquiry.product_group == "photo-wallpaper": + price = wallpaper_price( + width, + height, + material, + inquiry.market, + designer=inquiry.designer, + reseller=reseller, + inquiry=inquiry, + rounded=False, + inc_vat=False, + ) + elif inquiry.product_group == "canvas": + price = canvas_price( + width, + height, + inquiry.market, + designer=inquiry.designer, + reseller=reseller, + inquiry=inquiry, + framed=framed, + rounded=False, + inc_vat=False, + ) + elif inquiry.product_group == "poster": + price = poster_price( + width, + height, + inquiry.market, + designer=inquiry.designer, + reseller=reseller, + inquiry=inquiry, + hanger=hanger, + rounded=False, + inc_vat=False, + ) else: - raise ValueError( - 'Invalid product group: {}'.format(inquiry.product_group)) + raise ValueError("Invalid product group: {}".format(inquiry.product_group)) effect_price = inquiry.price_effect if effect_price: price += float(effect_price) if inc_price_retouch: - retouch_price = inquiry.local_price_retouch( - rounded=False, inc_vat=False) + retouch_price = inquiry.local_price_retouch(rounded=False, inc_vat=False) if retouch_price: price += retouch_price diff --git a/api/lib/slugify.py b/api/lib/slugify.py index bd3bed1..2b5f5d5 100644 --- a/api/lib/slugify.py +++ b/api/lib/slugify.py @@ -13,14 +13,14 @@ def slugify(text): text = text.lower() # replace unwanted chars - numbers = re.compile('(?<=\d),(?=\d)') - text = numbers.sub('', text) - unwanted_chars = re.compile(r'[^_a-z0-9/]+') - text = unwanted_chars.sub('_', text) + numbers = re.compile("(?<=\d),(?=\d)") + text = numbers.sub("", text) + unwanted_chars = re.compile(r"[^_a-z0-9/]+") + text = unwanted_chars.sub("_", text) # remove redundant _ - duplicated_underscores = re.compile('_{2,}') - text = duplicated_underscores.sub('_', text) - text = text.strip('_') + duplicated_underscores = re.compile("_{2,}") + text = duplicated_underscores.sub("_", text) + text = text.strip("_") return text diff --git a/api/models/category.py b/api/models/category.py index c5b147c..ea49b2c 100644 --- a/api/models/category.py +++ b/api/models/category.py @@ -5,35 +5,34 @@ from api.models.locale import Locale class Category(db.Model): - __tablename__ = 'categories' + __tablename__ = "categories" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), nullable=False) - texts = db.relationship( - 'CategoryTexts', backref='category', lazy='dynamic') + texts = db.relationship("CategoryTexts", backref="category", lazy="dynamic") def to_json(self): return { - 'id': self.id, - 'name': self.name, - 'texts': [t.to_json() for t in self.texts] + "id": self.id, + "name": self.name, + "texts": [t.to_json() for t in self.texts], } class CategoryTexts(db.Model): - __tablename__ = 'category_texts' + __tablename__ = "category_texts" id = db.Column(db.Integer, primary_key=True) - category_id = db.Column(db.Integer, db.ForeignKey('categories.id')) + category_id = db.Column(db.Integer, db.ForeignKey("categories.id")) locale = db.relationship("Locale") - locale_id = db.Column(db.Integer, db.ForeignKey('locales.id')) + locale_id = db.Column(db.Integer, db.ForeignKey("locales.id")) wallpaper_name = db.Column(db.String(250)) wallpaper_h1 = db.Column(db.String(250)) wallpaper_description = db.Column(db.Text) canvas_name = db.Column(db.String(250)) canvas_h1 = db.Column(db.String(250)) canvas_description = db.Column(db.Text) - design_wallpaper_name = db.Column('name', db.String(250)) + design_wallpaper_name = db.Column("name", db.String(250)) design_wallpaper_h1 = db.Column(db.String(250)) design_wallpaper_description = db.Column(db.Text) poster_name = db.Column(db.String(250)) @@ -43,24 +42,23 @@ class CategoryTexts(db.Model): framed_print_h1 = db.Column(db.String(250)) framed_print_description = db.Column(db.Text) - def to_json(self): return { - 'id': self.id, - 'locale': self.locale.value, - 'wallpaper_name': self.wallpaper_name, - 'wallpaper_h1': self.wallpaper_h1, - 'wallpaper_description': self.wallpaper_description, - 'canvas_name': self.canvas_name, - 'canvas_h1': self.canvas_h1, - 'canvas_description': self.canvas_description, - 'design_wallpaper_name': self.design_wallpaper_name, - 'design_wallpaper_h1': self.design_wallpaper_h1, - 'design_wallpaper_description': self.design_wallpaper_description, - 'poster_name': self.poster_name, - 'poster_h1': self.poster_h1, - 'poster_description': self.poster_description, - 'framed_print_name': self.framed_print_name, - 'framed_print_h1': self.framed_print_h1, - 'framed_print_description': self.framed_print_description, + "id": self.id, + "locale": self.locale.value, + "wallpaper_name": self.wallpaper_name, + "wallpaper_h1": self.wallpaper_h1, + "wallpaper_description": self.wallpaper_description, + "canvas_name": self.canvas_name, + "canvas_h1": self.canvas_h1, + "canvas_description": self.canvas_description, + "design_wallpaper_name": self.design_wallpaper_name, + "design_wallpaper_h1": self.design_wallpaper_h1, + "design_wallpaper_description": self.design_wallpaper_description, + "poster_name": self.poster_name, + "poster_h1": self.poster_h1, + "poster_description": self.poster_description, + "framed_print_name": self.framed_print_name, + "framed_print_h1": self.framed_print_h1, + "framed_print_description": self.framed_print_description, } diff --git a/api/models/contract_customer.py b/api/models/contract_customer.py index dbb4239..01cbea6 100644 --- a/api/models/contract_customer.py +++ b/api/models/contract_customer.py @@ -5,21 +5,21 @@ from flask_sqlalchemy import BaseQuery class ContractCustomerQuery(BaseQuery): - def reseller_store(self, url, territory): return self.filter( ContractCustomer.dealerstore == True, ContractCustomer.dealerurl == url, - ContractCustomer.country == territory).first() + ContractCustomer.country == territory, + ).first() class ContractCustomer(db.Model): - __tablename__ = 'contract_customers' + __tablename__ = "contract_customers" query_class = ContractCustomerQuery - id = db.Column('contractcustomerid', db.Integer, primary_key=True) + id = db.Column("contractcustomerid", db.Integer, primary_key=True) country = db.Column(db.String(2)) pricepremium = db.Column(db.Numeric, nullable=False, default=0) dealerstore = db.Column(db.Boolean, nullable=False, default=False) @@ -27,8 +27,8 @@ class ContractCustomer(db.Model): def to_json(self): return { - 'id': self.id, - 'pricepremium': self.pricepremium, - 'dealerstore': self.dealerstore, - 'dealerurl': self.dealerurl + "id": self.id, + "pricepremium": self.pricepremium, + "dealerstore": self.dealerstore, + "dealerurl": self.dealerurl, } diff --git a/api/models/designer.py b/api/models/designer.py index f58fc2d..0c6f38a 100644 --- a/api/models/designer.py +++ b/api/models/designer.py @@ -5,9 +5,9 @@ from api.lib.slugify import slugify class Designer(db.Model): - __tablename__ = 'designers' + __tablename__ = "designers" - id = db.Column('designerid', db.Integer, primary_key=True) + id = db.Column("designerid", db.Integer, primary_key=True) commission = db.Column(db.Integer(), nullable=False) commission_resale = db.Column(db.Integer(), nullable=False) currency = db.Column(db.String(3), nullable=False) @@ -47,18 +47,18 @@ class Designer(db.Model): def to_json(self): return { - 'id': self.id, - 'commission': self.commission, - 'commission_resale': self.commission_resale, - 'currency': self.currency, - 'name': self.name, - 'no_follow': self.no_follow, - 'path': self.path, - 'sort_desc': 1 if self.sort_desc else 0, - 'territory': self.territory, - 'username': self.username, - 'visible_designerpage': self.visible_designerpage, - 'visible_list': self.visible_list, - 'visible_productpage': self.visible_productpage, - 'visible_search': self.visible_search, + "id": self.id, + "commission": self.commission, + "commission_resale": self.commission_resale, + "currency": self.currency, + "name": self.name, + "no_follow": self.no_follow, + "path": self.path, + "sort_desc": 1 if self.sort_desc else 0, + "territory": self.territory, + "username": self.username, + "visible_designerpage": self.visible_designerpage, + "visible_list": self.visible_list, + "visible_productpage": self.visible_productpage, + "visible_search": self.visible_search, } diff --git a/api/models/i18n.py b/api/models/i18n.py index d0b8f88..3900fa2 100644 --- a/api/models/i18n.py +++ b/api/models/i18n.py @@ -6,23 +6,23 @@ from datetime import datetime class Text(db.Model): - __tablename__ = 'i18n-texts' + __tablename__ = "i18n-texts" - id = db.Column('textid', db.Integer, primary_key=True) + id = db.Column("textid", db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) category = db.Column(db.String(255)) inserted = db.Column(db.DateTime, default=datetime.utcnow) updated = db.Column(db.DateTime) - data = db.relationship('TextData', lazy='dynamic') + data = db.relationship("TextData", lazy="dynamic") __table_args__ = (db.UniqueConstraint(name, category),) class TextData(db.Model): - __tablename__ = 'i18n-texts_data' + __tablename__ = "i18n-texts_data" - textid = db.Column(db.Integer, db.ForeignKey('i18n-texts.textid')) + textid = db.Column(db.Integer, db.ForeignKey("i18n-texts.textid")) language = db.Column(db.String(3), nullable=False) territory = db.Column(db.String(2), nullable=False) text = db.Column(db.Text) diff --git a/api/models/inquiry.py b/api/models/inquiry.py index f9c6d4d..08c7163 100644 --- a/api/models/inquiry.py +++ b/api/models/inquiry.py @@ -6,9 +6,9 @@ from api.lib.utils import round_half_up class Inquiry(db.Model): - __tablename__ = 'inquiries' + __tablename__ = "inquiries" - id = db.Column('inquiryid', db.Integer, primary_key=True) + id = db.Column("inquiryid", db.Integer, primary_key=True) territory = db.Column(db.String(2)) product_group = db.Column(db.String(100)) price_m2 = db.Column(db.Numeric) @@ -17,24 +17,30 @@ class Inquiry(db.Model): width = db.Column(db.Integer) height = db.Column(db.Integer) framed = db.Column(db.Integer, nullable=False, default=0) - dealer_store_id = db.Column('dealer_store', db.Integer, db.ForeignKey( - 'contract_customers.contractcustomerid')) - dealer_store = db.relationship('ContractCustomer', uselist=False) + dealer_store_id = db.Column( + "dealer_store", + db.Integer, + db.ForeignKey("contract_customers.contractcustomerid"), + ) + dealer_store = db.relationship("ContractCustomer", uselist=False) hanger = db.Column(db.String) - materialid = db.Column(db.Integer, db.ForeignKey( - 'product-materials.materialid'), default=1, nullable=False) - material = db.relationship('Material', uselist=False) + materialid = db.Column( + db.Integer, + db.ForeignKey("product-materials.materialid"), + default=1, + nullable=False, + ) + material = db.relationship("Material", uselist=False) pricepremium = db.Column(db.Numeric, nullable=False, default=0) - productId = db.Column(db.Integer, db.ForeignKey( - 'product-products.productid')) - product = db.relationship('Product', uselist=False) + productId = db.Column(db.Integer, db.ForeignKey("product-products.productid")) + product = db.relationship("Product", uselist=False) automated = db.Column(db.Integer, nullable=False, default=0) @property def market(self): market = market_model.from_territory(self.territory) if not market: - raise ValueError('Invalid territory: {}'.format(self.territory)) + raise ValueError("Invalid territory: {}".format(self.territory)) return market def local_price_retouch(self, rounded=True, inc_vat=False): diff --git a/api/models/locale.py b/api/models/locale.py index ea7f14b..3bd09cb 100644 --- a/api/models/locale.py +++ b/api/models/locale.py @@ -4,7 +4,7 @@ from api.extensions import db class Locale(db.Model): - __tablename__ = 'locales' + __tablename__ = "locales" id = db.Column(db.Integer, primary_key=True) value = db.Column(db.String(5)) diff --git a/api/models/market.py b/api/models/market.py index a807306..00f32bc 100644 --- a/api/models/market.py +++ b/api/models/market.py @@ -6,22 +6,21 @@ from .product import Currencies class PriceAdjustments(db.Model): - __tablename__ = 'price_adjustments' + __tablename__ = "price_adjustments" territory = db.Column(db.String(2), primary_key=True) adjustment = db.Column(db.Numeric) class Market(object): - def __init__(self, name, locale, currency, vat, iso3): self.name = name self.locale = locale self.currency = currency self.vat = vat self.iso3 = iso3 - self.language = locale.split('_')[0] - self.territory = locale.split('_')[1] + self.language = locale.split("_")[0] + self.territory = locale.split("_")[1] self._price_adjustments = None self._exchange_rate = None self._price_adjustments = None @@ -29,8 +28,7 @@ class Market(object): @property def price_adjustments(self): if self._price_adjustments is None: - row = PriceAdjustments.query.filter_by( - territory=self.territory).first() + row = PriceAdjustments.query.filter_by(territory=self.territory).first() if row: self._price_adjustments = float(row.adjustment) else: @@ -58,15 +56,15 @@ class Market(object): def to_json(self): return { - 'name': self.name, - 'locale': self.locale, - 'currency': self.currency, - 'vat': self.vat, - 'iso3': self.iso3, - 'language': self.language, - 'territory': self.territory, - 'price_adjustments': self.price_adjustments, - 'exchange_rate': self.exchange_rate + "name": self.name, + "locale": self.locale, + "currency": self.currency, + "vat": self.vat, + "iso3": self.iso3, + "language": self.language, + "territory": self.territory, + "price_adjustments": self.price_adjustments, + "exchange_rate": self.exchange_rate, } def __repr__(self): @@ -74,20 +72,20 @@ class Market(object): _markets = [ - ('Sweden', 'sv_SE', 'SEK', 1.25, 'SWE'), - ('Norway', 'nn_NO', 'NOK', 1.25, 'NOR'), - ('United kingdom', 'en_GB', 'GBP', 1.20, 'GBR'), - ('Denmark', 'da_DK', 'DKK', 1.25, 'DNK'), - ('Finland', 'fi_FI', 'EUR', 1.24, 'FIN'), - ('Russia', 'ru_RU', 'EUR', 1, 'RUS'), - ('Germany', 'de_DE', 'EUR', 1.19, 'DEU'), - ('Netherlands', 'nl_NL', 'EUR', 1.21, 'NLD'), - ('Austria', 'de_AT', 'EUR', 1.20, 'AUT'), - ('USA', 'en_US', 'USD', 1, 'USA'), - ('Spain', 'es_ES', 'EUR', 1.21, 'ESP'), - ('France', 'fr_FR', 'EUR', 1.20, 'FRA'), - ('Poland', 'pl_PL', 'EUR', 1.23, 'POL'), - ('International', 'en_EU', 'EUR', 1.25, None), + ("Sweden", "sv_SE", "SEK", 1.25, "SWE"), + ("Norway", "nn_NO", "NOK", 1.25, "NOR"), + ("United kingdom", "en_GB", "GBP", 1.20, "GBR"), + ("Denmark", "da_DK", "DKK", 1.25, "DNK"), + ("Finland", "fi_FI", "EUR", 1.24, "FIN"), + ("Russia", "ru_RU", "EUR", 1, "RUS"), + ("Germany", "de_DE", "EUR", 1.19, "DEU"), + ("Netherlands", "nl_NL", "EUR", 1.21, "NLD"), + ("Austria", "de_AT", "EUR", 1.20, "AUT"), + ("USA", "en_US", "USD", 1, "USA"), + ("Spain", "es_ES", "EUR", 1.21, "ESP"), + ("France", "fr_FR", "EUR", 1.20, "FRA"), + ("Poland", "pl_PL", "EUR", 1.23, "POL"), + ("International", "en_EU", "EUR", 1.25, None), ] diff --git a/api/models/product.py b/api/models/product.py index facf3a8..c7cc2a7 100644 --- a/api/models/product.py +++ b/api/models/product.py @@ -6,23 +6,22 @@ from flask_sqlalchemy import BaseQuery class Product(db.Model): - __tablename__ = 'product-products' + __tablename__ = "product-products" - id = db.Column('productid', db.Integer, primary_key=True) - designerid = db.Column(db.Integer, db.ForeignKey('designers.designerid')) - designer = db.relationship('Designer', backref='products') + id = db.Column("productid", db.Integer, primary_key=True) + designerid = db.Column(db.Integer, db.ForeignKey("designers.designerid")) + designer = db.relationship("Designer", backref="products") class Currencies(db.Model): - __tablename__ = 'product-currencies' + __tablename__ = "product-currencies" iso3char = db.Column(db.String(3), primary_key=True) exchange_rate = db.Column(db.Numeric, default=1) class MaterialQuery(BaseQuery): - def wallpapers(self): return self.filter(Material.name.in_(Material.WALLPAPER_MATERIALS)) @@ -32,25 +31,23 @@ class MaterialQuery(BaseQuery): class Material(db.Model): - __tablename__ = 'product-materials' + __tablename__ = "product-materials" query_class = MaterialQuery - WALLPAPER_MATERIALS = ['standard-wallpaper', - # 'self-adhesive-wallpaper', // isn't sold now - 'premium-wallpaper'] - CANVAS_MATERIALS = ['standard-canvas'] + WALLPAPER_MATERIALS = [ + "standard-wallpaper", + # 'self-adhesive-wallpaper', // isn't sold now + "premium-wallpaper", + ] + CANVAS_MATERIALS = ["standard-canvas"] - id = db.Column('materialid', db.Integer, primary_key=True) - name = db.Column('material', db.String(255), nullable=False) - price = db.Column('price', db.Integer) + id = db.Column("materialid", db.Integer, primary_key=True) + name = db.Column("material", db.String(255), nullable=False) + price = db.Column("price", db.Integer) def to_json(self): - return { - 'id': self.id, - 'name': self.name, - 'price': float(self.price) - } + return {"id": self.id, "name": self.name, "price": float(self.price)} def __repr__(self): return self.name diff --git a/api/resources/categories.py b/api/resources/categories.py index 6f878a3..4bd7aff 100644 --- a/api/resources/categories.py +++ b/api/resources/categories.py @@ -3,20 +3,20 @@ from api import db from api.models import Category from api.helpers import pagination_to_dict, check_api_key -mod = Blueprint('categories', __name__, url_prefix='/categories') +mod = Blueprint("categories", __name__, url_prefix="/categories") mod.before_request(check_api_key) @mod.route("/", methods=["GET"]) def list(): - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) + page = request.args.get("page", 1, type=int) + per_page = request.args.get("per_page", 10, type=int) query = Category.query.order_by(Category.name.asc()) pagination = query.paginate(page=page, per_page=per_page) j = { - 'pagination': pagination_to_dict(pagination), - 'data': [item.to_json() for item in pagination.items] + "pagination": pagination_to_dict(pagination), + "data": [item.to_json() for item in pagination.items], } return jsonify(j) diff --git a/api/resources/designers.py b/api/resources/designers.py index 5cee8eb..78d7c60 100644 --- a/api/resources/designers.py +++ b/api/resources/designers.py @@ -5,7 +5,7 @@ from api.helpers import pagination_to_dict, check_api_key from api.validators import validate_jsonschema -mod = Blueprint('designers', __name__, url_prefix='/designers') +mod = Blueprint("designers", __name__, url_prefix="/designers") mod.before_request(check_api_key) @@ -17,19 +17,19 @@ create_designer_schema = { "territory": {"type": "string"}, "currency": {"type": "string"}, }, - "required": ["username", "name", "territory", "currency"] + "required": ["username", "name", "territory", "currency"], } @mod.route("/", methods=["GET"]) def list(): - page = request.args.get('page', 1, type=int) - per_page = request.args.get('per_page', 10, type=int) + page = request.args.get("page", 1, type=int) + per_page = request.args.get("per_page", 10, type=int) query = Designer.query.order_by(Designer.name.asc()) pagination = query.paginate(page=page, per_page=per_page) j = { - 'pagination': pagination_to_dict(pagination), - 'data': [item.to_json() for item in pagination.items] + "pagination": pagination_to_dict(pagination), + "data": [item.to_json() for item in pagination.items], } return jsonify(j) diff --git a/api/resources/prices.py b/api/resources/prices.py index 9a5743c..6e1fa15 100644 --- a/api/resources/prices.py +++ b/api/resources/prices.py @@ -16,20 +16,20 @@ from api.lib.prices import ( ) from api.lib.limits import calculate_canvas_limits -mod = Blueprint('prices', __name__, url_prefix='/prices') +mod = Blueprint("prices", __name__, url_prefix="/prices") mod.before_request(check_api_key) def get_reseller(): - dealerurl = request.args.get('dealerurl') - territory = request.args.get('territory') + dealerurl = request.args.get("dealerurl") + territory = request.args.get("territory") if dealerurl and territory: return ContractCustomer.query.reseller_store(dealerurl, territory) return None def get_designer(): - product_id = request.args.get('product') + product_id = request.args.get("product") if product_id: product = Product.query.get(product_id) if product: @@ -37,36 +37,70 @@ def get_designer(): return None -@mod.route("/wallpaper", methods=['GET']) -@validate_number('width', 'height') -@validate_territory('territory') +@mod.route("/wallpaper", methods=["GET"]) +@validate_number("width", "height") +@validate_territory("territory") def wallpaper(): - width = request.args.get('width', type=int) - height = request.args.get('height', type=int) - market = market_model.from_territory(request.args.get('territory')) + width = request.args.get("width", type=int) + height = request.args.get("height", type=int) + market = market_model.from_territory(request.args.get("territory")) designer = get_designer() reseller = get_reseller() materials = Material.query.wallpapers().all() data = [] for material in materials: - data.append({ - 'material': material.name, - 'material_id': material.id, - 'm2_price': m2_price(material, market, reseller=reseller, designer=designer, rounded=False, inc_vat=True), - 'm2_price_excl_vat': m2_price(material, market, reseller=reseller, designer=designer, rounded=False, inc_vat=False), - 'price': wallpaper_price(width, height, material, market, reseller=reseller, designer=designer, rounded=False, inc_vat=True), - 'price_excl_vat': wallpaper_price(width, height, material, market, reseller=reseller, designer=designer, rounded=False, inc_vat=False), - }) + data.append( + { + "material": material.name, + "material_id": material.id, + "m2_price": m2_price( + material, + market, + reseller=reseller, + designer=designer, + rounded=False, + inc_vat=True, + ), + "m2_price_excl_vat": m2_price( + material, + market, + reseller=reseller, + designer=designer, + rounded=False, + inc_vat=False, + ), + "price": wallpaper_price( + width, + height, + material, + market, + reseller=reseller, + designer=designer, + rounded=False, + inc_vat=True, + ), + "price_excl_vat": wallpaper_price( + width, + height, + material, + market, + reseller=reseller, + designer=designer, + rounded=False, + inc_vat=False, + ), + } + ) return jsonify(data=data) -@mod.route('/canvas', methods=['GET']) -@validate_number('width', 'height') -@validate_territory('territory') +@mod.route("/canvas", methods=["GET"]) +@validate_number("width", "height") +@validate_territory("territory") def canvas(): - market = market_model.from_territory(request.args.get('territory')) + market = market_model.from_territory(request.args.get("territory")) reseller = get_reseller() designer = get_designer() @@ -74,80 +108,133 @@ def canvas(): for framed in [True, False]: width, height = calculate_canvas_limits( - request.args.get('width', type=int), - request.args.get('height', type=int), - framed + request.args.get("width", type=int), + request.args.get("height", type=int), + framed, ) - data.append({ - 'framed': framed, - 'width': width, - 'height': height, - 'price': canvas_price(width, height, market, framed=framed, designer=designer, reseller=reseller, rounded=False, inc_vat=True), - 'price_excl_vat': canvas_price(width, height, market, framed=framed, designer=designer, reseller=reseller, rounded=False, inc_vat=False), - }) + data.append( + { + "framed": framed, + "width": width, + "height": height, + "price": canvas_price( + width, + height, + market, + framed=framed, + designer=designer, + reseller=reseller, + rounded=False, + inc_vat=True, + ), + "price_excl_vat": canvas_price( + width, + height, + market, + framed=framed, + designer=designer, + reseller=reseller, + rounded=False, + inc_vat=False, + ), + } + ) return jsonify(data=data) -@mod.route('/poster', methods=['GET']) -@validate_number('width', 'height') -@validate_territory('territory') +@mod.route("/poster", methods=["GET"]) +@validate_number("width", "height") +@validate_territory("territory") def poster(): - width = request.args.get('width', type=int) - height = request.args.get('height', type=int) - market = market_model.from_territory(request.args.get('territory')) + width = request.args.get("width", type=int) + height = request.args.get("height", type=int) + market = market_model.from_territory(request.args.get("territory")) reseller = get_reseller() designer = get_designer() data = [] for hanger in [True, False]: - data.append({ - 'hanger': hanger, - 'width': width, - 'height': height, - 'price': poster_price(width, height, market, hanger=hanger, designer=designer, reseller=reseller, rounded=False, inc_vat=True), - 'price_excl_vat': poster_price(width, height, market, hanger=hanger, designer=designer, reseller=reseller, rounded=False, inc_vat=False), - }) + data.append( + { + "hanger": hanger, + "width": width, + "height": height, + "price": poster_price( + width, + height, + market, + hanger=hanger, + designer=designer, + reseller=reseller, + rounded=False, + inc_vat=True, + ), + "price_excl_vat": poster_price( + width, + height, + market, + hanger=hanger, + designer=designer, + reseller=reseller, + rounded=False, + inc_vat=False, + ), + } + ) return jsonify(data=data) -@mod.route('/diy-frame', methods=['GET']) -@validate_number('width', 'height') -@validate_territory('territory') +@mod.route("/diy-frame", methods=["GET"]) +@validate_number("width", "height") +@validate_territory("territory") def diy_frame(): - market = market_model.from_territory(request.args.get('territory')) + market = market_model.from_territory(request.args.get("territory")) reseller = get_reseller() width, height = calculate_canvas_limits( - request.args.get('width', type=int), - request.args.get('height', type=int), - framed=True + request.args.get("width", type=int), + request.args.get("height", type=int), + framed=True, ) - data = [{ - 'width': width, - 'height': height, - 'price': canvas_frame_price(width, height, market, reseller=reseller, rounded=False), - 'price_excl_vat': canvas_frame_price(width, height, market, reseller=reseller, rounded=False, inc_vat=False) - }] + data = [ + { + "width": width, + "height": height, + "price": canvas_frame_price( + width, height, market, reseller=reseller, rounded=False + ), + "price_excl_vat": canvas_frame_price( + width, height, market, reseller=reseller, rounded=False, inc_vat=False + ), + } + ] return jsonify(data=data) -@mod.route('/poster-hanger', methods=['GET']) -@validate_number('width') -@validate_territory('territory') + +@mod.route("/poster-hanger", methods=["GET"]) +@validate_number("width") +@validate_territory("territory") def poster_hanger(): - width = request.args.get('width', type=int) - market = market_model.from_territory(request.args.get('territory')) + width = request.args.get("width", type=int) + market = market_model.from_territory(request.args.get("territory")) reseller = get_reseller() - data = [{ - 'width': width, - 'price': poster_hanger_price(width, market, reseller=reseller, rounded=False), - 'price_excl_vat': poster_hanger_price(width, market, reseller=reseller, rounded=False, inc_vat=False) - }] + data = [ + { + "width": width, + "price": poster_hanger_price( + width, market, reseller=reseller, rounded=False + ), + "price_excl_vat": poster_hanger_price( + width, market, reseller=reseller, rounded=False, inc_vat=False + ), + } + ] return jsonify(data=data) @@ -157,8 +244,8 @@ def get_inquiry_measurements(inquiry): # first try to get it from the query string. If that fails try to get it # from the inquiry row in the database - width = request.args.get('width', type=int, default=inquiry.width) - height = request.args.get('height', type=int, default=inquiry.height) + width = request.args.get("width", type=int, default=inquiry.width) + height = request.args.get("height", type=int, default=inquiry.height) # if we still are missing a width/height just set them to 1 to avoid # errors in the price calculations @@ -175,26 +262,75 @@ def inquiry_wallpaper(inquiry): width, height = get_inquiry_measurements(inquiry) data = { - 'id': inquiry.id, - 'group': 'wallpaper', - 'width': width, - 'height': height, - 'retouch_price': inquiry.local_price_retouch(rounded=False, inc_vat=True), + "id": inquiry.id, + "group": "wallpaper", + "width": width, + "height": height, + "retouch_price": inquiry.local_price_retouch(rounded=False, inc_vat=True), } materials = Material.query.wallpapers().all() prices = [] for material in materials: - prices.append({ - 'material': material.name, - 'material_id': material.id, - 'm2_price': m2_price(material, inquiry.market, designer=inquiry.designer, reseller=inquiry.dealer_store, inquiry=inquiry, rounded=False, inc_vat=True), - 'm2_price_excl_vat': m2_price(material, inquiry.market, designer=inquiry.designer, reseller=inquiry.dealer_store, inquiry=inquiry, rounded=False, inc_vat=False), - 'inquiry_price_excl_retouch': inquiry_price(inquiry, material=material, width=width, height=height, rounded=False, inc_price_retouch=False, inc_vat=True), - 'inquiry_price': inquiry_price(inquiry, material=material, width=width, height=height, rounded=False, inc_vat=True), - 'inquiry_price_excl_vat': inquiry_price(inquiry, material=material, width=width, height=height, rounded=False, inc_vat=False), - 'inquiry_price_excl_price_premium': inquiry_price(inquiry, material=material, width=width, height=height, reseller=None, inc_price_retouch=False, rounded=False, inc_vat=False) - }) - data['prices'] = prices + prices.append( + { + "material": material.name, + "material_id": material.id, + "m2_price": m2_price( + material, + inquiry.market, + designer=inquiry.designer, + reseller=inquiry.dealer_store, + inquiry=inquiry, + rounded=False, + inc_vat=True, + ), + "m2_price_excl_vat": m2_price( + material, + inquiry.market, + designer=inquiry.designer, + reseller=inquiry.dealer_store, + inquiry=inquiry, + rounded=False, + inc_vat=False, + ), + "inquiry_price_excl_retouch": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + rounded=False, + inc_price_retouch=False, + inc_vat=True, + ), + "inquiry_price": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + rounded=False, + inc_vat=True, + ), + "inquiry_price_excl_vat": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + rounded=False, + inc_vat=False, + ), + "inquiry_price_excl_price_premium": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + reseller=None, + inc_price_retouch=False, + rounded=False, + inc_vat=False, + ), + } + ) + data["prices"] = prices return data @@ -202,9 +338,9 @@ def inquiry_canvas(inquiry): in_width, in_height = get_inquiry_measurements(inquiry) data = { - 'id': inquiry.id, - 'group': 'canvas', - 'retouch_price': inquiry.local_price_retouch(rounded=False, inc_vat=True) + "id": inquiry.id, + "group": "canvas", + "retouch_price": inquiry.local_price_retouch(rounded=False, inc_vat=True), } material = Material.query.canvas().first() @@ -212,16 +348,53 @@ def inquiry_canvas(inquiry): for framed in [True, False]: width, height = calculate_canvas_limits(in_width, in_height, framed) - prices.append({ - 'framed': framed, - 'width': width, - 'height': height, - 'inquiry_price_excl_retouch': inquiry_price(inquiry, material=material, width=width, height=height, framed=framed, rounded=False, inc_price_retouch=False, inc_vat=True), - 'inquiry_price': inquiry_price(inquiry, material=material, width=width, height=height, framed=framed, rounded=False, inc_vat=True), - 'inquiry_price_excl_vat': inquiry_price(inquiry, material=material, width=width, height=height, framed=framed, rounded=False, inc_vat=False), - 'inquiry_price_excl_price_premium': inquiry_price(inquiry, material=material, width=width, height=height, reseller=None, inc_price_retouch=False, framed=framed, rounded=False, inc_vat=False) - }) - data['prices'] = prices + prices.append( + { + "framed": framed, + "width": width, + "height": height, + "inquiry_price_excl_retouch": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + framed=framed, + rounded=False, + inc_price_retouch=False, + inc_vat=True, + ), + "inquiry_price": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + framed=framed, + rounded=False, + inc_vat=True, + ), + "inquiry_price_excl_vat": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + framed=framed, + rounded=False, + inc_vat=False, + ), + "inquiry_price_excl_price_premium": inquiry_price( + inquiry, + material=material, + width=width, + height=height, + reseller=None, + inc_price_retouch=False, + framed=framed, + rounded=False, + inc_vat=False, + ), + } + ) + data["prices"] = prices return data @@ -230,39 +403,72 @@ def inquiry_poster(inquiry): width, height = get_inquiry_measurements(inquiry) data = { - 'id': inquiry.id, - 'group': 'poster', - 'retouch_price': inquiry.local_price_retouch(rounded=False, inc_vat=True) + "id": inquiry.id, + "group": "poster", + "retouch_price": inquiry.local_price_retouch(rounded=False, inc_vat=True), } prices = [] for hanger in [True, False]: - prices.append({ - 'hanger': hanger, - 'width': width, - 'height': height, - 'inquiry_price_excl_retouch': inquiry_price(inquiry, width=width, height=height, hanger=hanger, rounded=False, inc_price_retouch=False, inc_vat=True), - 'inquiry_price': inquiry_price(inquiry, width=width, height=height, hanger=hanger, rounded=False, inc_vat=True), - 'inquiry_price_excl_vat': inquiry_price(inquiry, width=width, height=height, hanger=hanger, rounded=False, inc_vat=False), - 'inquiry_price_excl_price_premium': inquiry_price(inquiry, width=width, height=height, hanger=hanger, reseller=None, inc_price_retouch=False, rounded=False, inc_vat=False) - }) - data['prices'] = prices + prices.append( + { + "hanger": hanger, + "width": width, + "height": height, + "inquiry_price_excl_retouch": inquiry_price( + inquiry, + width=width, + height=height, + hanger=hanger, + rounded=False, + inc_price_retouch=False, + inc_vat=True, + ), + "inquiry_price": inquiry_price( + inquiry, + width=width, + height=height, + hanger=hanger, + rounded=False, + inc_vat=True, + ), + "inquiry_price_excl_vat": inquiry_price( + inquiry, + width=width, + height=height, + hanger=hanger, + rounded=False, + inc_vat=False, + ), + "inquiry_price_excl_price_premium": inquiry_price( + inquiry, + width=width, + height=height, + hanger=hanger, + reseller=None, + inc_price_retouch=False, + rounded=False, + inc_vat=False, + ), + } + ) + data["prices"] = prices return data -@mod.route('/inquiry/', methods=["GET"]) +@mod.route("/inquiry/", methods=["GET"]) def inquiry(inquiry_id): inquiry = Inquiry.query.get_or_404(inquiry_id) - if inquiry.product_group == 'photo-wallpaper': + if inquiry.product_group == "photo-wallpaper": data = inquiry_wallpaper(inquiry) - elif inquiry.product_group == 'canvas': + elif inquiry.product_group == "canvas": data = inquiry_canvas(inquiry) - elif inquiry.product_group == 'poster': + elif inquiry.product_group == "poster": data = inquiry_poster(inquiry) else: - raise ValueError('Invalid group {}'.format(inquiry.product_group)) + raise ValueError("Invalid group {}".format(inquiry.product_group)) return jsonify(data) diff --git a/api/resources/server.py b/api/resources/server.py index 3b7d543..d39bc0b 100644 --- a/api/resources/server.py +++ b/api/resources/server.py @@ -1,19 +1,15 @@ from flask import Blueprint, jsonify, url_for -mod = Blueprint('server', __name__) +mod = Blueprint("server", __name__) @mod.route("/", methods=["GET"]) def status(): - data = { - 'version': '0.0.1' - } + data = {"version": "0.0.1"} return jsonify(data) @mod.route("/health", methods=["GET"]) def health(): - data = { - 'status': 'ok' - } + data = {"status": "ok"} return jsonify(data) diff --git a/api/tasks/esales.py b/api/tasks/esales.py index b3b140b..c259591 100644 --- a/api/tasks/esales.py +++ b/api/tasks/esales.py @@ -17,7 +17,7 @@ def update_designer(designer): send_to_bottom=designer.send_to_bottom, no_follow=designer.no_follow, hidden=1, - path="/designers/{}".format(designer.path) + path="/designers/{}".format(designer.path), ) importfile = ImportFile() for locale in Locale.query.all(): diff --git a/api/validators.py b/api/validators.py index 12b032e..056cec4 100644 --- a/api/validators.py +++ b/api/validators.py @@ -5,7 +5,6 @@ from api.models.market import iter_markets class ValidationError(Exception): - def __init__(self, message): Exception.__init__(self) self.message = message @@ -13,7 +12,7 @@ class ValidationError(Exception): def _check_parameter_exists(param): if not param in request.args: - raise ValidationError('No {} is specified'.format(param)) + raise ValidationError("No {} is specified".format(param)) def _is_number(s): @@ -29,7 +28,7 @@ def validate_jsonschema(schema): @wraps(f) def wrapper(*args, **kwargs): if not request.json: - raise ValidationError('Payload is not valid json') + raise ValidationError("Payload is not valid json") try: j = request.json jsonschema.validate(j, schema) @@ -38,7 +37,9 @@ def validate_jsonschema(schema): except jsonschema.SchemaError as e: raise ValidationError(e.message) return f(*args, **kwargs) + return wrapper + return decorator @@ -49,7 +50,9 @@ def validate_exists(*keys): for key in keys: _check_parameter_exists(key) return f(*args, **kwargs) + return wrapper + return decorator @@ -61,9 +64,11 @@ def validate_number(*keys): _check_parameter_exists(key) value = request.args.get(key) if not _is_number(value): - raise ValidationError('{} is not a number'.format(key)) + raise ValidationError("{} is not a number".format(key)) return f(*args, **kwargs) + return wrapper + return decorator @@ -73,7 +78,7 @@ def validate_territory(*keys): def wrapper(*args, **kwargs): for key in keys: if not key in request.args: - raise ValidationError('No {} is specified'.format(key)) + raise ValidationError("No {} is specified".format(key)) value = request.args.get(key) valid = False for market in iter_markets(): @@ -82,9 +87,10 @@ def validate_territory(*keys): break if not valid: - raise ValidationError( - '{} is not a valid territory'.format(value)) + raise ValidationError("{} is not a valid territory".format(value)) return f(*args, **kwargs) + return wrapper + return decorator diff --git a/tests/config.py b/tests/config.py index cf327a1..3f31e9c 100644 --- a/tests/config.py +++ b/tests/config.py @@ -1,8 +1,8 @@ -SERVER_NAME = 'localhost' -SQLALCHEMY_DATABASE_URI = 'sqlite://' +SERVER_NAME = "localhost" +SQLALCHEMY_DATABASE_URI = "sqlite://" SQLALCHEMY_TRACK_MODIFICATIONS = True PRESERVE_CONTEXT_ON_EXCEPTION = False -ESALES_URL = '' +ESALES_URL = "" TESTING = True DEBUG = True SQLALCHEMY_ECHO = False diff --git a/tests/factories.py b/tests/factories.py index 504d32d..9215bd9 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -3,18 +3,16 @@ from api import models class DesignerFactory(factory.Factory): - class Meta: model = models.Designer - name = 'Spiderman' - username = 'spiderman' - territory = 'US' - currency = 'USD' + name = "Spiderman" + username = "spiderman" + territory = "US" + currency = "USD" class ContractCustomerFactory(factory.Factory): - class Meta: model = models.ContractCustomer @@ -22,7 +20,6 @@ class ContractCustomerFactory(factory.Factory): class InquiryFactory(factory.Factory): - class Meta: model = models.Inquiry diff --git a/tests/lib/test_limits.py b/tests/lib/test_limits.py index 485822e..24d6ed1 100644 --- a/tests/lib/test_limits.py +++ b/tests/lib/test_limits.py @@ -5,19 +5,20 @@ from api.lib.limits import calculate_canvas_limits, calculate_canvas_frame_limit class TestCalculate(unittest2.TestCase): - def test_calculate_canvas_limits(self): self.assertEqual((100, 100), calculate_canvas_limits(100, 100)) self.assertEqual((500, 100), calculate_canvas_limits(800, 100)) self.assertEqual((100, 500), calculate_canvas_limits(100, 800)) self.assertEqual((20, 20), calculate_canvas_limits(10, 10)) - self.assertEqual((150, 50), calculate_canvas_limits( - 400, 50, True), "Framed canvas") + self.assertEqual( + (150, 50), calculate_canvas_limits(400, 50, True), "Framed canvas" + ) def test_calculate_canvas_frame_limits(self): self.assertEqual((100, 100), calculate_canvas_frame_limits(100, 100)) self.assertEqual((40, 40), calculate_canvas_frame_limits(1, 1)) self.assertEqual((150, 150), calculate_canvas_frame_limits(200, 200)) self.assertEqual((150, 40), calculate_canvas_frame_limits(200, 10)) - self.assertEqual((110, 120), calculate_canvas_frame_limits( - 112, 117), "round to nearest 10") + self.assertEqual( + (110, 120), calculate_canvas_frame_limits(112, 117), "round to nearest 10" + ) diff --git a/tests/lib/test_prices.py b/tests/lib/test_prices.py index 4b5b790..340212a 100644 --- a/tests/lib/test_prices.py +++ b/tests/lib/test_prices.py @@ -10,27 +10,27 @@ from api.models import Product from api.models.product import Material -sweden = market.from_territory('SE') +sweden = market.from_territory("SE") sweden.price_adjustments = 1 sweden.exchange_rate = 1 -denmark = market.from_territory('DK') +denmark = market.from_territory("DK") denmark.price_adjustments = 1.185 denmark.exchange_rate = 0.799000 -us = market.from_territory('US') +us = market.from_territory("US") us.price_adjustments = 1.06 us.exchange_rate = 0.119800 -nl = market.from_territory('NL') +nl = market.from_territory("NL") nl.price_adjustments = 1.15 nl.exchange_rate = 0.100000 -eu = market.from_territory('EU') +eu = market.from_territory("EU") eu.price_adjustments = 1.13 eu.exchange_rate = 0.100000 -russia = market.from_territory('RU') +russia = market.from_territory("RU") russia.price_adjustments = 1 russia.exchange_rate = 0.100000 # russia uses EUR @@ -42,63 +42,172 @@ piterra = ContractCustomerFactory(pricepremium=36.029411) designer_moomin = DesignerFactory() designer_moomin.pricepremium = 2 -standard_wallpaper = Material(name='standard-wallpaper', price=23600) -premium_wallpaper = Material(name='premium-wallpaper', price=26000) -standard_canvas = Material(name='standard-canvas', price=79920) +standard_wallpaper = Material(name="standard-wallpaper", price=23600) +premium_wallpaper = Material(name="premium-wallpaper", price=26000) +standard_canvas = Material(name="standard-canvas", price=79920) class TestPrice(unittest2.TestCase): - def test_m2_price(self): - self.assertEqual(236, m2_price( - material=standard_wallpaper, market=sweden, inc_vat=False)) - self.assertEqual(260, m2_price( - material=premium_wallpaper, market=sweden, inc_vat=False)) - self.assertEqual(295, m2_price( - material=standard_wallpaper, market=sweden, inc_vat=True)) - self.assertEqual(223, m2_price( - material=standard_wallpaper, market=denmark, inc_vat=False)) - self.assertAlmostEqual(79.92, m2_price( - material=standard_canvas, market=russia, rounded=False, inc_vat=False), places=2) - self.assertAlmostEqual(81.5184, m2_price( - material=standard_canvas, market=russia, designer=designer_moomin, rounded=False, inc_vat=False), places=4) - self.assertAlmostEqual(110.88899937662403, m2_price(material=standard_canvas, market=russia, - designer=designer_moomin, reseller=piterra, rounded=False, inc_vat=False), places=4) + self.assertEqual( + 236, m2_price(material=standard_wallpaper, market=sweden, inc_vat=False) + ) + self.assertEqual( + 260, m2_price(material=premium_wallpaper, market=sweden, inc_vat=False) + ) + self.assertEqual( + 295, m2_price(material=standard_wallpaper, market=sweden, inc_vat=True) + ) + self.assertEqual( + 223, m2_price(material=standard_wallpaper, market=denmark, inc_vat=False) + ) + self.assertAlmostEqual( + 79.92, + m2_price( + material=standard_canvas, market=russia, rounded=False, inc_vat=False + ), + places=2, + ) + self.assertAlmostEqual( + 81.5184, + m2_price( + material=standard_canvas, + market=russia, + designer=designer_moomin, + rounded=False, + inc_vat=False, + ), + places=4, + ) + self.assertAlmostEqual( + 110.88899937662403, + m2_price( + material=standard_canvas, + market=russia, + designer=designer_moomin, + reseller=piterra, + rounded=False, + inc_vat=False, + ), + places=4, + ) inquiry = Inquiry(pricepremium=36.029411) - self.assertEqual(44, m2_price(material=standard_wallpaper, - market=russia, reseller=piterra, inquiry=inquiry, inc_vat=False)) + self.assertEqual( + 44, + m2_price( + material=standard_wallpaper, + market=russia, + reseller=piterra, + inquiry=inquiry, + inc_vat=False, + ), + ) def test_wallpaper_price(self): - self.assertEqual(295, wallpaper_price( - width=1, height=1, material=standard_wallpaper, market=sweden)) - self.assertEqual(295, wallpaper_price( - width=100, height=100, material=standard_wallpaper, market=sweden)) - self.assertEqual(1180, wallpaper_price( - width=200, height=200, material=standard_wallpaper, market=sweden)) - self.assertEqual(325, wallpaper_price( - width=100, height=100, material=premium_wallpaper, market=sweden)) - self.assertEqual(279, wallpaper_price( - width=100, height=100, material=standard_wallpaper, market=denmark)) - self.assertEqual(236, wallpaper_price( - width=100, height=100, material=standard_wallpaper, market=sweden, inc_vat=False)) + self.assertEqual( + 295, + wallpaper_price( + width=1, height=1, material=standard_wallpaper, market=sweden + ), + ) + self.assertEqual( + 295, + wallpaper_price( + width=100, height=100, material=standard_wallpaper, market=sweden + ), + ) + self.assertEqual( + 1180, + wallpaper_price( + width=200, height=200, material=standard_wallpaper, market=sweden + ), + ) + self.assertEqual( + 325, + wallpaper_price( + width=100, height=100, material=premium_wallpaper, market=sweden + ), + ) + self.assertEqual( + 279, + wallpaper_price( + width=100, height=100, material=standard_wallpaper, market=denmark + ), + ) + self.assertEqual( + 236, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=sweden, + inc_vat=False, + ), + ) # designer - self.assertEqual(348, wallpaper_price(width=100, height=100, - material=standard_wallpaper, market=sweden, designer=designer)) - self.assertEqual(329, wallpaper_price(width=100, height=100, - material=standard_wallpaper, market=denmark, designer=designer)) + self.assertEqual( + 348, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=sweden, + designer=designer, + ), + ) + self.assertEqual( + 329, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=denmark, + designer=designer, + ), + ) # reseller stores - self.assertEqual(339, wallpaper_price(width=100, height=100, - material=standard_wallpaper, market=sweden, reseller=reseller)) - self.assertEqual(399, wallpaper_price(width=100, height=100, - material=standard_wallpaper, market=sweden, designer=designer, reseller=reseller)) - self.assertEqual(154, wallpaper_price(width=100, height=100, material=standard_wallpaper, - market=sweden, reseller=ContractCustomerFactory(pricepremium=-47.74))) + self.assertEqual( + 339, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=sweden, + reseller=reseller, + ), + ) + self.assertEqual( + 399, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=sweden, + designer=designer, + reseller=reseller, + ), + ) + self.assertEqual( + 154, + wallpaper_price( + width=100, + height=100, + material=standard_wallpaper, + market=sweden, + reseller=ContractCustomerFactory(pricepremium=-47.74), + ), + ) def test_wallpaper_price_us(self): - self.assertEqual(60, wallpaper_price(width=100, height=100, - material=standard_wallpaper, market=us), "Minium price for US is 2 sqm") + self.assertEqual( + 60, + wallpaper_price( + width=100, height=100, material=standard_wallpaper, market=us + ), + "Minium price for US is 2 sqm", + ) def test_canvas_cm2_price(self): self.assertEqual(0.24099500000000001, canvas_cm2_price(250)) @@ -106,151 +215,270 @@ class TestPrice(unittest2.TestCase): self.assertEqual(0.22568000000000002, canvas_cm2_price(1000)) def test_canvas_price(self): - self.assertEqual(488, canvas_price(width=50, height=50, - market=sweden, framed=True, inc_vat=False)) + self.assertEqual( + 488, + canvas_price( + width=50, height=50, market=sweden, framed=True, inc_vat=False + ), + ) - self.assertEqual(960, canvas_price( - width=100, height=100, market=sweden, framed=True, inc_vat=False)) + self.assertEqual( + 960, + canvas_price( + width=100, height=100, market=sweden, framed=True, inc_vat=False + ), + ) - self.assertEqual(1359, canvas_price( - width=150, height=120, market=sweden, framed=True, inc_vat=False)) + self.assertEqual( + 1359, + canvas_price( + width=150, height=120, market=sweden, framed=True, inc_vat=False + ), + ) - self.assertEqual(256000, canvas_price( - width=2000, height=2000, market=sweden, framed=True, inc_vat=False)) + self.assertEqual( + 256000, + canvas_price( + width=2000, height=2000, market=sweden, framed=True, inc_vat=False + ), + ) - self.assertEqual(341, canvas_price(width=10, height=10, - market=sweden, framed=True, inc_vat=False)) + self.assertEqual( + 341, + canvas_price( + width=10, height=10, market=sweden, framed=True, inc_vat=False + ), + ) - self.assertEqual(427, canvas_price(width=40, height=40, - market=sweden, framed=True, inc_vat=True)) + self.assertEqual( + 427, + canvas_price(width=40, height=40, market=sweden, framed=True, inc_vat=True), + ) - self.assertEqual(299, canvas_price(width=40, height=40, - market=sweden, framed=False, inc_vat=True)) + self.assertEqual( + 299, + canvas_price( + width=40, height=40, market=sweden, framed=False, inc_vat=True + ), + ) - self.assertEqual(731, canvas_price(width=80, height=80, - market=sweden, framed=False, inc_vat=True)) + self.assertEqual( + 731, + canvas_price( + width=80, height=80, market=sweden, framed=False, inc_vat=True + ), + ) - self.assertEqual(1044, canvas_price(width=80, height=80, - market=sweden, framed=True, inc_vat=True)) + self.assertEqual( + 1044, + canvas_price(width=80, height=80, market=sweden, framed=True, inc_vat=True), + ) - self.assertEqual(1260, canvas_price(width=150, height=150, - market=sweden, framed=False, inc_vat=True)) + self.assertEqual( + 1260, + canvas_price( + width=150, height=150, market=sweden, framed=False, inc_vat=True + ), + ) - self.assertEqual(1800, canvas_price(width=150, height=150, - market=sweden, framed=True, inc_vat=True)) + self.assertEqual( + 1800, + canvas_price( + width=150, height=150, market=sweden, framed=True, inc_vat=True + ), + ) - self.assertEqual(201, canvas_price(width=150, height=150, - market=us, framed=True, inc_vat=True)) + self.assertEqual( + 201, + canvas_price(width=150, height=150, market=us, framed=True, inc_vat=True), + ) - self.assertEqual(672, canvas_price( - width=100, height=100, market=sweden, framed=False, inc_vat=False)) + self.assertEqual( + 672, + canvas_price( + width=100, height=100, market=sweden, framed=False, inc_vat=False + ), + ) - self.assertEqual(840, canvas_price( - width=100, height=100, market=sweden, framed=False, inc_vat=True)) + self.assertEqual( + 840, + canvas_price( + width=100, height=100, market=sweden, framed=False, inc_vat=True + ), + ) - self.assertEqual(462, canvas_price(width=50, height=50, - market=denmark, framed=True, inc_vat=False)) + self.assertEqual( + 462, + canvas_price( + width=50, height=50, market=denmark, framed=True, inc_vat=False + ), + ) - self.assertEqual(180, canvas_price(width=150, height=100, market=us, designer=designer_moomin, inc_vat=False)) - self.assertEqual(180, canvas_price(width=150, height=100, market=us, designer=designer_moomin, inc_vat=True)) + self.assertEqual( + 180, + canvas_price( + width=150, + height=100, + market=us, + designer=designer_moomin, + inc_vat=False, + ), + ) + self.assertEqual( + 180, + canvas_price( + width=150, height=100, market=us, designer=designer_moomin, inc_vat=True + ), + ) def test_canvas_frame_price(self): - self.assertEqual(624, canvas_frame_price( - width=100, height=100, market=sweden, inc_vat=False)) - self.assertEqual(780, canvas_frame_price( - width=100, height=100, market=sweden, inc_vat=True)) - self.assertEqual(62, canvas_frame_price( - width=100, height=100, market=russia)) - self.assertEqual(936, canvas_frame_price( - 500, 500, market=sweden, inc_vat=False)) - self.assertEqual(222, canvas_frame_price( - 1, 1, market=sweden, inc_vat=False)) - self.assertEqual(277, canvas_frame_price( - width=40, height=40, market=sweden, inc_vat=True)) - self.assertEqual(71, canvas_frame_price( - width=40, height=120, market=us)) - self.assertEqual(66, canvas_frame_price( - width=40, height=100, market=us)) - self.assertEqual(578, canvas_frame_price( - width=40, height=120, market=sweden)) + self.assertEqual( + 624, canvas_frame_price(width=100, height=100, market=sweden, inc_vat=False) + ) + self.assertEqual( + 780, canvas_frame_price(width=100, height=100, market=sweden, inc_vat=True) + ) + self.assertEqual(62, canvas_frame_price(width=100, height=100, market=russia)) + self.assertEqual( + 936, canvas_frame_price(500, 500, market=sweden, inc_vat=False) + ) + self.assertEqual(222, canvas_frame_price(1, 1, market=sweden, inc_vat=False)) + self.assertEqual( + 277, canvas_frame_price(width=40, height=40, market=sweden, inc_vat=True) + ) + self.assertEqual(71, canvas_frame_price(width=40, height=120, market=us)) + self.assertEqual(66, canvas_frame_price(width=40, height=100, market=us)) + self.assertEqual(578, canvas_frame_price(width=40, height=120, market=sweden)) def test_wallpaper_custom_inquiry_price(self): - with mock.patch.object(Inquiry, 'market', nl): - inquiry = Inquiry(product_group="photo-wallpaper", territory="NL", pricepremium=0, - width=350, height=270, price_effect=0, price_retouch=160.00, material=standard_wallpaper) + with mock.patch.object(Inquiry, "market", nl): + inquiry = Inquiry( + product_group="photo-wallpaper", + territory="NL", + pricepremium=0, + width=350, + height=270, + price_effect=0, + price_retouch=160.00, + material=standard_wallpaper, + ) self.assertEqual(333, inquiry_price(inquiry)) - self.assertEqual(310, inquiry_price( - inquiry, inc_price_retouch=False)) + self.assertEqual(310, inquiry_price(inquiry, inc_price_retouch=False)) self.assertEqual(160, inquiry.price_retouch) self.assertEqual(18.4, inquiry.local_price_retouch(rounded=False)) - self.assertEqual(22, inquiry.local_price_retouch( - rounded=True, inc_vat=True)) + self.assertEqual( + 22, inquiry.local_price_retouch(rounded=True, inc_vat=True) + ) # test with different material - self.assertEqual(342, inquiry_price( - inquiry, inc_price_retouch=False, material=premium_wallpaper)) - self.assertEqual(364, inquiry_price( - inquiry, material=premium_wallpaper)) + self.assertEqual( + 342, + inquiry_price( + inquiry, inc_price_retouch=False, material=premium_wallpaper + ), + ) + self.assertEqual(364, inquiry_price(inquiry, material=premium_wallpaper)) def test_wallpaper_product_inquiry_price(self): designer = DesignerFactory() designer.pricepremium = 4 product = Product(designer=designer) - with mock.patch.object(Inquiry, 'market', sweden): - inquiry = Inquiry(product_group="photo-wallpaper", territory="SE", pricepremium=0, - width=350, height=280, price_retouch=0, material=standard_wallpaper, product=product) + with mock.patch.object(Inquiry, "market", sweden): + inquiry = Inquiry( + product_group="photo-wallpaper", + territory="SE", + pricepremium=0, + width=350, + height=280, + price_retouch=0, + material=standard_wallpaper, + product=product, + ) self.assertEqual(3007, inquiry_price(inquiry)) - self.assertEqual(3007, inquiry_price( - inquiry, inc_price_retouch=False)) - self.assertEqual(3312, inquiry_price( - inquiry, material=premium_wallpaper)) + self.assertEqual(3007, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(3312, inquiry_price(inquiry, material=premium_wallpaper)) def test_wallpaper_product2_inquiry_price(self): designer = DesignerFactory() designer.pricepremium = 4 product = Product(designer=designer) - with mock.patch.object(Inquiry, 'market', sweden): - inquiry = Inquiry(product_group="photo-wallpaper", territory="SE", pricepremium=25, - width=250, height=400, price_retouch=200, material=standard_wallpaper, product=product) + with mock.patch.object(Inquiry, "market", sweden): + inquiry = Inquiry( + product_group="photo-wallpaper", + territory="SE", + pricepremium=25, + width=250, + height=400, + price_retouch=200, + material=standard_wallpaper, + product=product, + ) - self.assertEqual(3835, inquiry_price( - inquiry, inc_price_retouch=False)) + self.assertEqual(3835, inquiry_price(inquiry, inc_price_retouch=False)) self.assertEqual(200, inquiry.price_retouch) - self.assertEqual(250, inquiry.local_price_retouch( - rounded=True, inc_vat=True)) + self.assertEqual( + 250, inquiry.local_price_retouch(rounded=True, inc_vat=True) + ) def test_wallpaper_piterra_inquiry_price(self): product = Product(designer=None) - with mock.patch.object(Inquiry, 'market', russia): - inquiry = Inquiry(product_group="photo-wallpaper", territory="RU", width=150, height=211, dealer_store=piterra, pricepremium=36.029411, - material=standard_wallpaper, product=product) + with mock.patch.object(Inquiry, "market", russia): + inquiry = Inquiry( + product_group="photo-wallpaper", + territory="RU", + width=150, + height=211, + dealer_store=piterra, + pricepremium=36.029411, + material=standard_wallpaper, + product=product, + ) - self.assertEqual(138, inquiry_price( - inquiry, inc_price_retouch=False)) - self.assertEqual(152, inquiry_price( - inquiry, inc_price_retouch=False, material=premium_wallpaper)) + self.assertEqual(138, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual( + 152, + inquiry_price( + inquiry, inc_price_retouch=False, material=premium_wallpaper + ), + ) # test set reseller store to None to calculate inquiry price without reseller price premium - self.assertEqual(102, inquiry_price( - inquiry, inc_price_retouch=False, reseller=None)) + self.assertEqual( + 102, inquiry_price(inquiry, inc_price_retouch=False, reseller=None) + ) def test_canvas_custom_inquiry_price(self): - with mock.patch.object(Inquiry, 'market', sweden): - inquiry = Inquiry(product_group='canvas', territory='SE', width=100, height=100, - framed=True, price_retouch=200, pricepremium=0, material=standard_canvas) + with mock.patch.object(Inquiry, "market", sweden): + inquiry = Inquiry( + product_group="canvas", + territory="SE", + width=100, + height=100, + framed=True, + price_retouch=200, + pricepremium=0, + material=standard_canvas, + ) - self.assertEqual(1200, inquiry_price( - inquiry, inc_price_retouch=False)) - self.assertEqual(1450, inquiry_price( - inquiry, inc_price_retouch=True)) - self.assertEqual(840, inquiry_price( - inquiry, inc_price_retouch=False, framed=False)) + self.assertEqual(1200, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(1450, inquiry_price(inquiry, inc_price_retouch=True)) + self.assertEqual( + 840, inquiry_price(inquiry, inc_price_retouch=False, framed=False) + ) def test_canvas_piterra_inquiry_price(self): - with mock.patch.object(Inquiry, 'market', russia): - inquiry = Inquiry(product_group='canvas', territory='RU', width=100, height=100, - framed=True, dealer_store=piterra, pricepremium=0, material=standard_canvas) + with mock.patch.object(Inquiry, "market", russia): + inquiry = Inquiry( + product_group="canvas", + territory="RU", + width=100, + height=100, + framed=True, + dealer_store=piterra, + pricepremium=0, + material=standard_canvas, + ) # note: site currently calculates this as €150 which is wrong because # it does not add dealer_store.pricepremium to the frame price @@ -258,11 +486,11 @@ class TestPrice(unittest2.TestCase): self.assertEqual(91, inquiry_price(inquiry, framed=False)) def test_package_price(self): - self.assertEqual(150, package_price('canvas', 150, 40, market=us)) - self.assertEqual(0, package_price('canvas', 150, 40, market=sweden)) - self.assertEqual(150, package_price('poster', 150, 40, market=us)) - self.assertEqual(100, package_price('poster', 40, 40, market=us)) - self.assertEqual(0, package_price('poster', 150, 40, market=sweden)) + self.assertEqual(150, package_price("canvas", 150, 40, market=us)) + self.assertEqual(0, package_price("canvas", 150, 40, market=sweden)) + self.assertEqual(150, package_price("poster", 150, 40, market=us)) + self.assertEqual(100, package_price("poster", 40, 40, market=us)) + self.assertEqual(0, package_price("poster", 150, 40, market=sweden)) def test_poster_cm2_price(self): self.assertEqual(0.100789248, poster_cm2_price(1)) @@ -272,11 +500,25 @@ class TestPrice(unittest2.TestCase): self.assertEqual(0.028, poster_cm2_price(100000)) def test_poster_price(self): - self.assertEqual(354, poster_price(width=30, height=40, hanger=True, market=sweden)) - self.assertEqual(250, poster_price(width=30, height=40, hanger=False, market=sweden)) - self.assertEqual(48, poster_price(width=30, height=40, hanger=True, market=us), 'extra cost for us market') - self.assertEqual(76, poster_price(width=120, height=40, market=us), 'high extra cost for us market wide posters') - self.assertEqual(77, poster_price(width=120, height=40, market=us, designer=designer_moomin)) + self.assertEqual( + 354, poster_price(width=30, height=40, hanger=True, market=sweden) + ) + self.assertEqual( + 250, poster_price(width=30, height=40, hanger=False, market=sweden) + ) + self.assertEqual( + 48, + poster_price(width=30, height=40, hanger=True, market=us), + "extra cost for us market", + ) + self.assertEqual( + 76, + poster_price(width=120, height=40, market=us), + "high extra cost for us market wide posters", + ) + self.assertEqual( + 77, poster_price(width=120, height=40, market=us, designer=designer_moomin) + ) def test_poster_hanger_price(self): self.assertEqual(166, poster_hanger_price(30, market=sweden)) @@ -285,10 +527,19 @@ class TestPrice(unittest2.TestCase): self.assertEqual(58, poster_hanger_price(150, market=us)) def test_poster_custom_inquiry_price(self): - with mock.patch.object(Inquiry, 'market', sweden): - inquiry = Inquiry(product_group='poster', territory='SE', width=30, height=40, - hanger=True, price_retouch=200, pricepremium=0) + with mock.patch.object(Inquiry, "market", sweden): + inquiry = Inquiry( + product_group="poster", + territory="SE", + width=30, + height=40, + hanger=True, + price_retouch=200, + pricepremium=0, + ) self.assertEqual(354, inquiry_price(inquiry, inc_price_retouch=False)) self.assertEqual(604, inquiry_price(inquiry, inc_price_retouch=True)) - self.assertEqual(250, inquiry_price(inquiry, inc_price_retouch=False, hanger=False)) + self.assertEqual( + 250, inquiry_price(inquiry, inc_price_retouch=False, hanger=False) + ) diff --git a/tests/lib/test_slugify.py b/tests/lib/test_slugify.py index a0255ca..632f618 100644 --- a/tests/lib/test_slugify.py +++ b/tests/lib/test_slugify.py @@ -5,16 +5,14 @@ from api.lib.slugify import slugify class TestSlugification(unittest2.TestCase): - def test_basic(self): - self.assertEqual(slugify('HELLO'), 'hello') - self.assertEqual(slugify('this is a test'), 'this_is_a_test') - self.assertEqual(slugify('___This is a test___'), 'this_is_a_test') - self.assertEqual(slugify('this-is-a-test'), 'this_is_a_test') - self.assertEqual(slugify('this_is_a__test'), 'this_is_a_test') - self.assertEqual(slugify('404'), '404') - self.assertEqual(slugify('1,000 reasons you are #1'), - '1000_reasons_you_are_1') - self.assertEqual(slugify('Nín hǎo'), 'nin_hao') - self.assertEqual(slugify('räksmörgås'), 'raksmorgas') - self.assertEqual(slugify('RÄKSMÖRGÅS'), 'raksmorgas') + self.assertEqual(slugify("HELLO"), "hello") + self.assertEqual(slugify("this is a test"), "this_is_a_test") + self.assertEqual(slugify("___This is a test___"), "this_is_a_test") + self.assertEqual(slugify("this-is-a-test"), "this_is_a_test") + self.assertEqual(slugify("this_is_a__test"), "this_is_a_test") + self.assertEqual(slugify("404"), "404") + self.assertEqual(slugify("1,000 reasons you are #1"), "1000_reasons_you_are_1") + self.assertEqual(slugify("Nín hǎo"), "nin_hao") + self.assertEqual(slugify("räksmörgås"), "raksmorgas") + self.assertEqual(slugify("RÄKSMÖRGÅS"), "raksmorgas") diff --git a/tests/models/test_market.py b/tests/models/test_market.py index 0b38be1..ecbe0c1 100644 --- a/tests/models/test_market.py +++ b/tests/models/test_market.py @@ -5,8 +5,7 @@ from api.models import market class TestMarket(unittest2.TestCase): - def test_sweden(self): - sweden = market.from_territory('SE') - self.assertEqual('sv', sweden.language) - self.assertEqual('SE', sweden.territory) + sweden = market.from_territory("SE") + self.assertEqual("sv", sweden.language) + self.assertEqual("SE", sweden.territory) diff --git a/tests/resources/test_designers.py b/tests/resources/test_designers.py index c7e102d..3026ecc 100644 --- a/tests/resources/test_designers.py +++ b/tests/resources/test_designers.py @@ -6,9 +6,8 @@ from unittest.mock import patch class TestEndpoints(flask_testing.TestCase): - def create_app(self): - return create_app('tests.config') + return create_app("tests.config") def setUp(self): db.create_all() @@ -17,7 +16,7 @@ class TestEndpoints(flask_testing.TestCase): db.session.remove() db.drop_all() - def _add_designer(self, name, username=None, territory='SE', currency='SEK'): + def _add_designer(self, name, username=None, territory="SE", currency="SEK"): if not username: username = name.lower() designer = Designer(name, username, territory, currency) @@ -26,38 +25,45 @@ class TestEndpoints(flask_testing.TestCase): return designer def test_list_designers(self): - self._add_designer('designer1') - self._add_designer('designer2') + self._add_designer("designer1") + self._add_designer("designer2") response = self.client.get("/designers/") - self.assertEqual(2, len(response.json.get('data'))) + self.assertEqual(2, len(response.json.get("data"))) def test_get_designer(self): - designer = self._add_designer('designer1') - response = self.client.get('/designers/1') + designer = self._add_designer("designer1") + response = self.client.get("/designers/1") self.assert200(response) def test_create_designer(self): - data = {'name': 'Spider-Man', 'username': 'spiderman', - 'territory': 'US', 'currency': 'USD'} + data = { + "name": "Spider-Man", + "username": "spiderman", + "territory": "US", + "currency": "USD", + } response = self.client.post( - '/designers/', data=json.dumps(data), content_type='application/json') + "/designers/", data=json.dumps(data), content_type="application/json" + ) self.assertEqual(201, response.status_code) designer = response.json - self.assertEqual('Spider-Man', designer['name']) - self.assertEqual('spider_man', designer['path']) + self.assertEqual("Spider-Man", designer["name"]) + self.assertEqual("spider_man", designer["path"]) def test_create_designer_missing_data(self): - data = {'name': 'Only name'} + data = {"name": "Only name"} response = self.client.post( - '/designers/', data=json.dumps(data), content_type='application/json') + "/designers/", data=json.dumps(data), content_type="application/json" + ) self.assert400(response) - @patch('api.tasks.esales.update_designer') + @patch("api.tasks.esales.update_designer") def test_update_designer(self, esales_update_designer): - designer = self._add_designer('designer1') - data = {'name': 'test'} + designer = self._add_designer("designer1") + data = {"name": "test"} response = self.client.put( - '/designers/1', data=json.dumps(data), content_type='application/json') + "/designers/1", data=json.dumps(data), content_type="application/json" + ) self.assertTrue(esales_update_designer.called) - self.assertEqual('test', response.json['name']) - self.assertEqual('test', Designer.query.get(1).name) + self.assertEqual("test", response.json["name"]) + self.assertEqual("test", Designer.query.get(1).name) diff --git a/tests/resources/test_prices.py b/tests/resources/test_prices.py index 18f3243..4727901 100644 --- a/tests/resources/test_prices.py +++ b/tests/resources/test_prices.py @@ -7,9 +7,8 @@ from api.models.designer import Designer class TestEndpoints(flask_testing.TestCase): - def create_app(self): - return create_app('tests.config') + return create_app("tests.config") def setUp(self): db.create_all() @@ -26,14 +25,16 @@ class TestEndpoints(flask_testing.TestCase): def _add_inquiry(self, territory, product_group, price_retouch=100): inquiry = Inquiry( - territory=territory, product_group=product_group, price_retouch=price_retouch) + territory=territory, + product_group=product_group, + price_retouch=price_retouch, + ) db.session.add(inquiry) db.session.commit() return inquiry def _add_designer(self, pricepremium): - designer = Designer('Disney', 'disney', 'US', - 'USD', pricepremium=pricepremium) + designer = Designer("Disney", "disney", "US", "USD", pricepremium=pricepremium) db.session.add(designer) db.session.commit() return designer @@ -45,61 +46,60 @@ class TestEndpoints(flask_testing.TestCase): return product def test_wallpaper(self): - self._add_material('standard-wallpaper', 1, 23600) - self._add_material('premium-wallpaper', 1, 26000) - response = self.client.get( - '/prices/wallpaper?width=200&height=10&territory=SE') + self._add_material("standard-wallpaper", 1, 23600) + self._add_material("premium-wallpaper", 1, 26000) + response = self.client.get("/prices/wallpaper?width=200&height=10&territory=SE") self.assert200(response) expected = [ { - 'm2_price': 295.0, - 'm2_price_excl_vat': 236.0, - 'price_excl_vat': 236.0, - 'price': 295.0, - 'material': 'standard-wallpaper', - 'material_id': 1 + "m2_price": 295.0, + "m2_price_excl_vat": 236.0, + "price_excl_vat": 236.0, + "price": 295.0, + "material": "standard-wallpaper", + "material_id": 1, }, { - 'm2_price': 325.0, - 'm2_price_excl_vat': 260.0, - 'price_excl_vat': 260.0, - 'price': 325.0, - 'material': 'premium-wallpaper', - 'material_id': 2 - } + "m2_price": 325.0, + "m2_price_excl_vat": 260.0, + "price_excl_vat": 260.0, + "price": 325.0, + "material": "premium-wallpaper", + "material_id": 2, + }, ] - self.assertEqual(expected, response.json['data']) + self.assertEqual(expected, response.json["data"]) def test_wallpaper_with_product(self): - self._add_material('standard-wallpaper', 1, 23600) - self._add_material('premium-wallpaper', 1, 26000) + self._add_material("standard-wallpaper", 1, 23600) + self._add_material("premium-wallpaper", 1, 26000) designer = self._add_designer(4) product = self._add_product(designer) response = self.client.get( - '/prices/wallpaper?width=200&height=200&territory=SE&product=1') + "/prices/wallpaper?width=200&height=200&territory=SE&product=1" + ) expected = [ { - 'price': 1227.2, - 'price_excl_vat': 981.76, - 'material_id': 1, - 'm2_price': 306.8, - 'm2_price_excl_vat': 245.44, - 'material': 'standard-wallpaper' + "price": 1227.2, + "price_excl_vat": 981.76, + "material_id": 1, + "m2_price": 306.8, + "m2_price_excl_vat": 245.44, + "material": "standard-wallpaper", }, { - 'price': 1352.0000000000002, - 'price_excl_vat': 1081.6000000000001, - 'material_id': 2, - 'm2_price': 338.00000000000006, - 'm2_price_excl_vat': 270.40000000000003, - 'material': 'premium-wallpaper' - } + "price": 1352.0000000000002, + "price_excl_vat": 1081.6000000000001, + "material_id": 2, + "m2_price": 338.00000000000006, + "m2_price_excl_vat": 270.40000000000003, + "material": "premium-wallpaper", + }, ] - self.assertEqual(expected, response.json['data']) + self.assertEqual(expected, response.json["data"]) def test_canvas(self): - response = self.client.get( - '/prices/canvas?width=200&height=10&territory=SE') + response = self.client.get("/prices/canvas?width=200&height=10&territory=SE") self.assert200(response) expected = [ { @@ -107,23 +107,24 @@ class TestEndpoints(flask_testing.TestCase): "height": 40, "price": 1008.0, "price_excl_vat": 806.4, - "width": 150 + "width": 150, }, { "framed": False, "height": 20, "price": 575.47, "price_excl_vat": 460.37600000000003, - "width": 200 - } + "width": 200, + }, ] - self.assertEqual(expected, response.json['data']) + self.assertEqual(expected, response.json["data"]) def test_canvas_with_product(self): designer = self._add_designer(4) product = self._add_product(designer) response = self.client.get( - '/prices/canvas?width=200&height=10&territory=SE&product=1') + "/prices/canvas?width=200&height=10&territory=SE&product=1" + ) self.assert200(response) expected = [ { @@ -131,73 +132,72 @@ class TestEndpoints(flask_testing.TestCase): "height": 40, "price": 1048.32, "price_excl_vat": 838.656, - "width": 150 + "width": 150, }, { "framed": False, "height": 20, "price": 598.4888000000001, "price_excl_vat": 478.79104000000007, - "width": 200 - } + "width": 200, + }, ] - self.assertEqual(expected, response.json['data']) + self.assertEqual(expected, response.json["data"]) def test_diy_frame(self): - response = self.client.get( - '/prices/diy-frame?width=200&height=50&territory=SE') + response = self.client.get("/prices/diy-frame?width=200&height=50&territory=SE") self.assert200(response) - product = response.json['data'][0] - self.assertEqual(150, product['width'], "it adjusts measurements") - self.assertEqual(50, product['height']) - self.assertAlmostEqual(731.25, product['price'], places=2) + product = response.json["data"][0] + self.assertEqual(150, product["width"], "it adjusts measurements") + self.assertEqual(50, product["height"]) + self.assertAlmostEqual(731.25, product["price"], places=2) def test_poster(self): - response = self.client.get('/prices/poster?width=50&height=30&territory=SE') + response = self.client.get("/prices/poster?width=50&height=30&territory=SE") self.assert200(response) expected = [ { - 'hanger': True, - 'height': 30, - 'price': 397.5, - 'price_excl_vat': 318, - 'width': 50 + "hanger": True, + "height": 30, + "price": 397.5, + "price_excl_vat": 318, + "width": 50, }, { - 'hanger': False, - 'height': 30, - 'price': 250.0, - 'price_excl_vat': 200, - 'width': 50 - } + "hanger": False, + "height": 30, + "price": 250.0, + "price_excl_vat": 200, + "width": 50, + }, ] - self.assertEqual(expected, response.json['data']) + self.assertEqual(expected, response.json["data"]) def test_poster_hanger(self): - response = self.client.get('/prices/poster-hanger?width=50&territory=SE') + response = self.client.get("/prices/poster-hanger?width=50&territory=SE") self.assert200(response) - product = response.json['data'][0] - self.assertEqual(210.0, product['price']) - self.assertEqual(168, product['price_excl_vat']) - self.assertEqual(50, product['width']) + product = response.json["data"][0] + self.assertEqual(210.0, product["price"]) + self.assertEqual(168, product["price_excl_vat"]) + self.assertEqual(50, product["width"]) def test_inquiry_wallpaper(self): - self._add_material('standard-wallpaper', 1, 236) - self._add_material('premium-wallpaper', 1, 260) - self._add_inquiry(territory='SE', product_group='photo-wallpaper') - response = self.client.get('/prices/inquiry/1?width=100&height=100') + self._add_material("standard-wallpaper", 1, 236) + self._add_material("premium-wallpaper", 1, 260) + self._add_inquiry(territory="SE", product_group="photo-wallpaper") + response = self.client.get("/prices/inquiry/1?width=100&height=100") self.assert200(response) - self.assertEqual('wallpaper', response.json['group']) + self.assertEqual("wallpaper", response.json["group"]) def test_inquiry_canvas(self): - self._add_material('standard-canvas', 2, 799.2) - self._add_inquiry(territory='SE', product_group='canvas') - response = self.client.get('/prices/inquiry/1?width=100&height=100') + self._add_material("standard-canvas", 2, 799.2) + self._add_inquiry(territory="SE", product_group="canvas") + response = self.client.get("/prices/inquiry/1?width=100&height=100") self.assert200(response) - self.assertEqual('canvas', response.json['group']) + self.assertEqual("canvas", response.json["group"]) def test_inquiry_poster(self): - self._add_inquiry(territory='SE', product_group='poster') - response = self.client.get('/prices/inquiry/1?width=100&height=100') + self._add_inquiry(territory="SE", product_group="poster") + response = self.client.get("/prices/inquiry/1?width=100&height=100") self.assert200(response) - self.assertEqual('poster', response.json['group']) + self.assertEqual("poster", response.json["group"]) diff --git a/tests/test_web.py b/tests/test_web.py index 95081b5..c0e7beb 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -6,117 +6,135 @@ import base64 from api import create_app from flask import Flask from api.helpers import check_api_key -from api.validators import ValidationError, validate_exists, validate_number, validate_territory, validate_jsonschema +from api.validators import ( + ValidationError, + validate_exists, + validate_number, + validate_territory, + validate_jsonschema, +) class TestHttpBasicAuth(flask_testing.TestCase): - api_key = 'secret' + api_key = "secret" def create_app(self): app = Flask(__name__) app.before_request(check_api_key) - @app.route('/', methods=['GET']) + @app.route("/", methods=["GET"]) def index(): - return 'ok' + return "ok" return app def _enable_basic_auth(self): - self.app.config['API_KEYS'] = [self.api_key] + self.app.config["API_KEYS"] = [self.api_key] - def _create_auth_headers(self, username, password=''): - data = base64.b64encode( - bytes(':'.join([username, password]), 'ascii')).decode('ascii') - headers = [('Authorization', 'Basic %s' % data)] + def _create_auth_headers(self, username, password=""): + data = base64.b64encode(bytes(":".join([username, password]), "ascii")).decode( + "ascii" + ) + headers = [("Authorization", "Basic %s" % data)] return headers def test_missing_credentials(self): self._enable_basic_auth() - response = self.client.get('/') + response = self.client.get("/") self.assert401(response) def test_correct_credentials(self): self._enable_basic_auth() headers = self._create_auth_headers(self.api_key) - response = self.client.get('/', headers=headers) + response = self.client.get("/", headers=headers) self.assert200(response) def test_basic_auth_disabled(self): - response = self.client.get('/') + response = self.client.get("/") self.assert200(response) class TestValidators(flask_testing.TestCase): - def create_app(self): app = Flask(__name__) @app.errorhandler(ValidationError) def on_error(error): return error.message, 400 + return app def test_validate_exists(self): app = self.app - @app.route('/', methods=['GET']) - @validate_exists('a', 'b') + @app.route("/", methods=["GET"]) + @validate_exists("a", "b") def index(): - return 'ok' + return "ok" - self.assertEqual(b'No b is specified', self.client.get('/?a=1').data) - self.assertEqual(b'ok', self.client.get('/?a=1&b=2').data) + self.assertEqual(b"No b is specified", self.client.get("/?a=1").data) + self.assertEqual(b"ok", self.client.get("/?a=1&b=2").data) def test_validate_number(self): app = self.app - @app.route('/', methods=['GET']) - @validate_number('age') + @app.route("/", methods=["GET"]) + @validate_number("age") def index(): - return 'ok' + return "ok" - self.assertEqual(b'No age is specified', self.client.get('/').data) - self.assertEqual(b'age is not a number', - self.client.get('/?age=aaa').data) - self.assertEqual(b'ok', self.client.get('/?age=1').data) + self.assertEqual(b"No age is specified", self.client.get("/").data) + self.assertEqual(b"age is not a number", self.client.get("/?age=aaa").data) + self.assertEqual(b"ok", self.client.get("/?age=1").data) def test_validate_territory(self): app = self.app - @app.route('/', methods=['GET']) - @validate_territory('territory') + @app.route("/", methods=["GET"]) + @validate_territory("territory") def index(): - return 'ok' + return "ok" - self.assertEqual(b'No territory is specified', - self.client.get('/').data) - self.assertEqual(b'abc is not a valid territory', - self.client.get('/?territory=abc').data) - self.assertEqual(b'ok', self.client.get('/?territory=SE').data) + self.assertEqual(b"No territory is specified", self.client.get("/").data) + self.assertEqual( + b"abc is not a valid territory", self.client.get("/?territory=abc").data + ) + self.assertEqual(b"ok", self.client.get("/?territory=SE").data) def test_validate_jsonschema(self): app = self.app schema = { "type": "object", - "properties": { - "name": {"type": "string"}, - "age": {"type": "number"} - }, - "required": ["name", "age"] + "properties": {"name": {"type": "string"}, "age": {"type": "number"}}, + "required": ["name", "age"], } - @app.route('/', methods=['POST']) + @app.route("/", methods=["POST"]) @validate_jsonschema(schema) def index(): - return 'ok' + return "ok" - self.assertEqual(b'Payload is not valid json', - self.client.post('/').data) - self.assertEqual(b"'name' is a required property", self.client.post( - '/', data=json.dumps({'foo': 'bar'}), content_type='application/json').data) - self.assertEqual(b"'abc' is not of type 'number'", self.client.post( - '/', data=json.dumps({'name': 'bar', 'age': 'abc'}), content_type='application/json').data) - self.assertEqual(b'ok', self.client.post( - '/', data=json.dumps({'name': 'bar', 'age': 55}), content_type='application/json').data) + self.assertEqual(b"Payload is not valid json", self.client.post("/").data) + self.assertEqual( + b"'name' is a required property", + self.client.post( + "/", data=json.dumps({"foo": "bar"}), content_type="application/json" + ).data, + ) + self.assertEqual( + b"'abc' is not of type 'number'", + self.client.post( + "/", + data=json.dumps({"name": "bar", "age": "abc"}), + content_type="application/json", + ).data, + ) + self.assertEqual( + b"ok", + self.client.post( + "/", + data=json.dumps({"name": "bar", "age": 55}), + content_type="application/json", + ).data, + )