reformat code with black

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