P5-6491 use market instead of territory for price calculations (#37)

This commit is contained in:
Martin Carlsson
2021-01-25 09:24:26 +01:00
committed by GitHub
parent dee7344ba5
commit 464e2f1fa6
11 changed files with 127 additions and 256 deletions
+3 -3
View File
@@ -56,7 +56,7 @@ def wallpaper_price(
sqm = (width / 100) * (height / 100)
if market.territory == "US":
if market.name == "US":
min_sqm = 2
else:
min_sqm = 1
@@ -101,7 +101,7 @@ def canvas_cm2_price(cm2):
def package_price(product_group, width, height, market):
if market.territory == "US":
if market.name == "US":
if product_group in ["canvas", "poster"]:
if width > 110:
return 150
@@ -411,7 +411,7 @@ def framed_print_price(
},
}
price += extra_shipping_price[sku].get(market.territory, 0)
price += extra_shipping_price[sku].get(market.name, 0)
price *= market.price_adjustments
+1 -1
View File
@@ -4,7 +4,7 @@ from .designer import Designer
from .category import Category
from .contract_customer import ContractCustomer
from .inquiry import Inquiry
from .product import Material, Product, Currencies
from .product import Material, Product, Currencies, PrintProduct
from .order import (
Order,
OrderField,
-1
View File
@@ -1,7 +1,6 @@
# coding=UTF-8
from api.extensions import db
from api.models import market as market_model
from api.lib.utils import round_half_up
+4 -114
View File
@@ -14,8 +14,11 @@ class Market(db.Model):
vat = db.Column(db.Float, nullable=False)
price_adjustments = db.Column("price_adjustment", db.Float, nullable=False)
currency = db.Column(db.String(3), db.ForeignKey("product-currencies.iso3char"))
exchange_rate = db.Column(db.Float)
_pc = db.relationship(Currencies, uselist=False)
exchange_rate = association_proxy("_pc", "exchange_rate")
exchange_rate = association_proxy(
"_pc", "exchange_rate", creator=lambda kw: Currencies(exchange_rate=kw)
)
def to_json(self):
return {
@@ -26,116 +29,3 @@ class Market(db.Model):
"currency": self.currency,
"exchange_rate": str(self.exchange_rate),
}
# hack: market need a territory to make it compatible with current price calculations code
# this will be removed in P5-6491
@property
def territory(self):
if self.name == 'GLOBAL':
return 'EU'
return self.name
class PriceAdjustments(db.Model):
__tablename__ = "price_adjustments"
territory = db.Column(db.String(2), primary_key=True)
adjustment = db.Column(db.Numeric)
# P5-6490 deprecated market model. Will be replaced with Market
class LegacyMarket(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._price_adjustments = None
self._exchange_rate = None
self._price_adjustments = None
@property
def price_adjustments(self):
if self._price_adjustments is None:
row = PriceAdjustments.query.filter_by(territory=self.territory).first()
if row:
self._price_adjustments = float(row.adjustment)
else:
self._price_adjustments = 1
return self._price_adjustments
@price_adjustments.setter
def price_adjustments(self, value):
self._price_adjustments = value
@property
def exchange_rate(self):
if self._exchange_rate is None:
row = Currencies.query.filter_by(iso3char=self.currency).first()
if row:
self._exchange_rate = row.exchange_rate
else:
self._exchange_rate = 1
return self._exchange_rate
@exchange_rate.setter
def exchange_rate(self, value):
self._exchange_rate = value
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,
}
def __repr__(self):
return self.locale
_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"),
("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),
("Italy", "it_IT", "EUR", 1.22, "ITA"),
]
def iter_markets():
for market in _markets:
yield LegacyMarket(*market)
def from_locale(locale):
for market in iter_markets():
if market.locale == locale:
return market
return None
def from_territory(territory):
for market in iter_markets():
if market.territory == territory.upper():
return market
return None
+39 -29
View File
@@ -1,10 +1,14 @@
from flask import Blueprint, request, jsonify, abort
from api.helpers import check_api_key
from api.validators import validate_territory, validate_number, validate_any_of
from api.models.inquiry import Inquiry
from api.models.product import Material, Product, PrintProduct
from api.models.contract_customer import ContractCustomer
from api.models import market as market_model
from api.validators import validate_number, validate_any_of, validate_exists
from api.models import (
Inquiry,
Market,
Material,
Product,
PrintProduct,
ContractCustomer,
)
from api.lib import pwinty
from api.lib.prices import (
wallpaper_price,
@@ -41,11 +45,12 @@ def get_designer():
@mod.route("/wallpaper", methods=["GET"])
@validate_number("width", "height")
@validate_territory("territory")
@validate_exists("market")
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"))
market_id = request.args.get("market", type=int)
market = Market.query.get_or_404(market_id)
designer = get_designer()
reseller = get_reseller()
@@ -100,9 +105,10 @@ def wallpaper():
@mod.route("/canvas", methods=["GET"])
@validate_number("width", "height")
@validate_territory("territory")
@validate_exists("market")
def canvas():
market = market_model.from_territory(request.args.get("territory"))
market_id = request.args.get("market", type=int)
market = Market.query.get_or_404(market_id)
reseller = get_reseller()
designer = get_designer()
@@ -148,11 +154,12 @@ def canvas():
@mod.route("/poster", methods=["GET"])
@validate_number("width", "height")
@validate_territory("territory")
@validate_exists("market")
def poster():
market_id = request.args.get("market", type=int)
width = request.args.get("width", type=int)
height = request.args.get("height", type=int)
market = market_model.from_territory(request.args.get("territory"))
market = Market.query.get_or_404(market_id)
reseller = get_reseller()
designer = get_designer()
@@ -192,9 +199,10 @@ def poster():
@mod.route("/diy-frame", methods=["GET"])
@validate_number("width", "height")
@validate_territory("territory")
@validate_exists("market")
def diy_frame():
market = market_model.from_territory(request.args.get("territory"))
market_id = request.args.get("market", type=int)
market = Market.query.get_or_404(market_id)
reseller = get_reseller()
width, height = calculate_canvas_limits(
request.args.get("width", type=int),
@@ -220,10 +228,11 @@ def diy_frame():
@mod.route("/poster-hanger", methods=["GET"])
@validate_number("width")
@validate_territory("territory")
@validate_exists("market")
def poster_hanger():
market_id = request.args.get("market", type=int)
width = request.args.get("width", type=int)
market = market_model.from_territory(request.args.get("territory"))
market = Market.query.get_or_404(market_id)
reseller = get_reseller()
data = [
@@ -242,11 +251,12 @@ def poster_hanger():
@mod.route("/framed-print", methods=["GET"])
@validate_territory("territory")
@validate_any_of("sku", pwinty.SKU_CODES)
@validate_exists("market")
def framed_print():
market_id = request.args.get("market", type=int)
sku = request.args.get("sku", type=str)
market = market_model.from_territory(request.args.get("territory"))
market = Market.query.get_or_404(market_id)
reseller = get_reseller()
designer = get_designer()
@@ -547,12 +557,12 @@ def inquiry(inquiry_id):
return jsonify(data)
@mod.route("/list-prices/<string:territory>/wallpaper")
def list_prices_wallpaper(territory):
@mod.route("/list-prices/<int:market_id>/wallpaper")
def list_prices_wallpaper(market_id):
wallpapers = PrintProduct.query.wallpapers().all()
result = {}
material = Material.query.filter(Material.name == "standard-wallpaper").one()
market = market_model.from_territory(territory)
market = Market.query.get_or_404(market_id)
for wallpaper in wallpapers:
result[wallpaper.id] = wallpaper_m2_price(
@@ -561,10 +571,10 @@ def list_prices_wallpaper(territory):
return jsonify(result)
@mod.route("/list-prices/<string:territory>/canvas")
def list_prices_canvas(territory):
@mod.route("/list-prices/<int:market_id>/canvas")
def list_prices_canvas(market_id):
canvases = PrintProduct.query.canvases().all()
market = market_model.from_territory(territory)
market = Market.query.get_or_404(market_id)
result = {}
for canvas in canvases:
@@ -578,10 +588,10 @@ def list_prices_canvas(territory):
return jsonify(result)
@mod.route("/list-prices/<string:territory>/poster")
def list_prices_posters(territory):
@mod.route("/list-prices/<int:market_id>/poster")
def list_prices_posters(market_id):
posters = PrintProduct.query.posters().all()
market = market_model.from_territory(territory)
market = Market.query.get_or_404(market_id)
result = {}
for poster in posters:
@@ -595,8 +605,8 @@ def list_prices_posters(territory):
return jsonify(result)
@mod.route("/list-prices/<string:territory>/framed-print")
def list_prices_framed_prints(territory):
@mod.route("/list-prices/<int:market_id>/framed-print")
def list_prices_framed_prints(market_id):
from api.extensions import db
from types import SimpleNamespace
@@ -611,7 +621,7 @@ def list_prices_framed_prints(territory):
)
rows = db.session.execute(query, {"group": 8})
market = market_model.from_territory(territory)
market = Market.query.get_or_404(market_id)
result = {}
for row in rows:
-25
View File
@@ -1,7 +1,6 @@
from functools import wraps
from flask import request
import jsonschema
from api.models.market import iter_markets
class ValidationError(Exception):
@@ -72,30 +71,6 @@ def validate_number(*keys):
return decorator
def validate_territory(*keys):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
for key in keys:
if not key in request.args:
raise ValidationError("No {} is specified".format(key))
value = request.args.get(key)
valid = False
for market in iter_markets():
if market.territory == value:
valid = True
break
if not valid:
raise ValidationError("{} is not a valid territory".format(value))
return f(*args, **kwargs)
return wrapper
return decorator
def validate_any_of(key, values):
def decorator(f):
@wraps(f)