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