663 lines
20 KiB
Python
663 lines
20 KiB
Python
from flask import Blueprint, request, jsonify, abort
|
|
from api.helpers import check_api_key
|
|
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,
|
|
canvas_price,
|
|
canvas_frame_price,
|
|
poster_price,
|
|
poster_hanger_price,
|
|
framed_print_price,
|
|
wallpaper_m2_price,
|
|
inquiry_price,
|
|
wallpaper_kit_price,
|
|
)
|
|
from api.lib.limits import calculate_canvas_limits
|
|
|
|
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")
|
|
if dealerurl and territory:
|
|
return ContractCustomer.query.reseller_store(dealerurl, territory)
|
|
return None
|
|
|
|
|
|
def get_designer():
|
|
product_id = request.args.get("product")
|
|
if product_id:
|
|
product = Product.query.get(product_id)
|
|
if product:
|
|
return product.designer
|
|
return None
|
|
|
|
|
|
@mod.route("/wallpaper", methods=["GET"])
|
|
@validate_number("width", "height")
|
|
@validate_exists("market")
|
|
def wallpaper():
|
|
width = request.args.get("width", type=int)
|
|
height = request.args.get("height", type=int)
|
|
market_id = request.args.get("market", type=int)
|
|
market = Market.query.get_or_404(market_id)
|
|
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": wallpaper_m2_price(
|
|
material,
|
|
market,
|
|
reseller=reseller,
|
|
designer=designer,
|
|
rounded=False,
|
|
inc_vat=True,
|
|
),
|
|
"m2_price_excl_vat": wallpaper_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_exists("market")
|
|
def canvas():
|
|
market_id = request.args.get("market", type=int)
|
|
market = Market.query.get_or_404(market_id)
|
|
reseller = get_reseller()
|
|
designer = get_designer()
|
|
|
|
data = []
|
|
|
|
for framed in [True, False]:
|
|
width, height = calculate_canvas_limits(
|
|
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,
|
|
),
|
|
}
|
|
)
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
@mod.route("/poster", methods=["GET"])
|
|
@validate_number("width", "height")
|
|
@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.query.get_or_404(market_id)
|
|
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,
|
|
),
|
|
}
|
|
)
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
@mod.route("/diy-frame", methods=["GET"])
|
|
@validate_number("width", "height")
|
|
@validate_exists("market")
|
|
def diy_frame():
|
|
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),
|
|
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
|
|
),
|
|
}
|
|
]
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
@mod.route("/wallpaper-kit", methods=["GET"])
|
|
@validate_exists("market")
|
|
def wallpaper_kit():
|
|
market_id = request.args.get("market", type=int)
|
|
market = Market.query.get_or_404(market_id)
|
|
reseller = get_reseller()
|
|
|
|
data = [
|
|
{
|
|
"price": wallpaper_kit_price(market, reseller=reseller, rounded=False),
|
|
"price_excl_vat": wallpaper_kit_price(
|
|
market, reseller=reseller, rounded=False, inc_vat=False
|
|
),
|
|
}
|
|
]
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
@mod.route("/poster-hanger", methods=["GET"])
|
|
@validate_number("width")
|
|
@validate_exists("market")
|
|
def poster_hanger():
|
|
market_id = request.args.get("market", type=int)
|
|
width = request.args.get("width", type=int)
|
|
market = Market.query.get_or_404(market_id)
|
|
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
|
|
),
|
|
}
|
|
]
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
@mod.route("/framed-print", methods=["GET"])
|
|
@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.query.get_or_404(market_id)
|
|
reseller = get_reseller()
|
|
designer = get_designer()
|
|
|
|
data = [
|
|
{
|
|
"sku": sku,
|
|
"price": framed_print_price(
|
|
sku,
|
|
market,
|
|
designer=designer,
|
|
reseller=reseller,
|
|
rounded=False,
|
|
inc_vat=True,
|
|
),
|
|
"price_excl_vat": framed_print_price(
|
|
sku,
|
|
market,
|
|
designer=designer,
|
|
reseller=reseller,
|
|
rounded=False,
|
|
inc_vat=False,
|
|
),
|
|
}
|
|
]
|
|
|
|
return jsonify(data=data)
|
|
|
|
|
|
def get_inquiry_measurements(inquiry):
|
|
""" this function returns width and height to be used in the price calculations """
|
|
|
|
# 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)
|
|
|
|
# if we still are missing a width/height just set them to 1 to avoid
|
|
# errors in the price calculations
|
|
if not width:
|
|
width = 1
|
|
|
|
if not height:
|
|
height = 1
|
|
|
|
return width, height
|
|
|
|
|
|
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),
|
|
}
|
|
materials = Material.query.wallpapers().all()
|
|
prices = []
|
|
for material in materials:
|
|
prices.append(
|
|
{
|
|
"material": material.name,
|
|
"material_id": material.id,
|
|
"m2_price": wallpaper_m2_price(
|
|
material,
|
|
inquiry.market,
|
|
designer=inquiry.designer,
|
|
reseller=inquiry.dealer_store,
|
|
inquiry=inquiry,
|
|
rounded=False,
|
|
inc_vat=True,
|
|
),
|
|
"m2_price_excl_vat": wallpaper_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
|
|
|
|
|
|
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),
|
|
}
|
|
material = Material.query.canvas().first()
|
|
|
|
prices = []
|
|
|
|
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
|
|
|
|
return data
|
|
|
|
|
|
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),
|
|
}
|
|
|
|
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
|
|
|
|
return data
|
|
|
|
|
|
def inquiry_framed_print(inquiry):
|
|
sku = request.args.get("sku", type=str)
|
|
data = {
|
|
"id": inquiry.id,
|
|
"group": "framed-print",
|
|
"retouch_price": inquiry.local_price_retouch(rounded=False, inc_vat=True),
|
|
"prices": [
|
|
{
|
|
"inquiry_price_excl_retouch": inquiry_price(
|
|
inquiry,
|
|
sku=sku,
|
|
rounded=False,
|
|
inc_price_retouch=False,
|
|
inc_vat=True,
|
|
),
|
|
"inquiry_price": inquiry_price(
|
|
inquiry, sku=sku, rounded=False, inc_vat=True
|
|
),
|
|
"inquiry_price_excl_vat": inquiry_price(
|
|
inquiry, sku=sku, rounded=False, inc_vat=False
|
|
),
|
|
"inquiry_price_excl_price_premium": inquiry_price(
|
|
inquiry,
|
|
sku=sku,
|
|
reseller=None,
|
|
inc_price_retouch=False,
|
|
rounded=False,
|
|
inc_vat=False,
|
|
),
|
|
}
|
|
],
|
|
}
|
|
|
|
return data
|
|
|
|
|
|
@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":
|
|
data = inquiry_wallpaper(inquiry)
|
|
elif inquiry.product_group == "canvas":
|
|
data = inquiry_canvas(inquiry)
|
|
elif inquiry.product_group == "poster":
|
|
data = inquiry_poster(inquiry)
|
|
elif inquiry.product_group == "framed-print":
|
|
data = inquiry_framed_print(inquiry)
|
|
else:
|
|
raise ValueError("Invalid group {}".format(inquiry.product_group))
|
|
|
|
return jsonify(data)
|
|
|
|
|
|
@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.query.get_or_404(market_id)
|
|
|
|
for wallpaper in wallpapers:
|
|
result[wallpaper.id] = wallpaper_m2_price(
|
|
material=material, market=market, designer=wallpaper.product.designer
|
|
)
|
|
return jsonify(result)
|
|
|
|
|
|
@mod.route("/list-prices/<int:market_id>/canvas")
|
|
def list_prices_canvas(market_id):
|
|
canvases = PrintProduct.query.canvases().all()
|
|
market = Market.query.get_or_404(market_id)
|
|
|
|
result = {}
|
|
for canvas in canvases:
|
|
result[canvas.id] = canvas_price(
|
|
width=40,
|
|
height=40,
|
|
market=market,
|
|
framed=True,
|
|
designer=canvas.product.designer,
|
|
)
|
|
return jsonify(result)
|
|
|
|
|
|
@mod.route("/list-prices/<int:market_id>/poster")
|
|
def list_prices_posters(market_id):
|
|
posters = PrintProduct.query.posters().all()
|
|
market = Market.query.get_or_404(market_id)
|
|
|
|
result = {}
|
|
for poster in posters:
|
|
result[poster.id] = poster_price(
|
|
width=30,
|
|
height=30,
|
|
market=market,
|
|
hanger=True,
|
|
designer=poster.product.designer,
|
|
)
|
|
return jsonify(result)
|
|
|
|
|
|
@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
|
|
|
|
query = (
|
|
"SELECT prints.printid, designers.pricepremium_framed_print, "
|
|
'width.value AS width, height.value AS height FROM "product-printproducts" prints '
|
|
'JOIN "product-products" products ON prints.productid = products.productid '
|
|
'LEFT JOIN "product-products_fields" width ON width.fieldid = 5 and width.productid = products.productid '
|
|
'LEFT JOIN "product-products_fields" height ON height.fieldid = 3 and height.productid = products.productid '
|
|
"LEFT JOIN designers ON designers.designerid = products.designerid "
|
|
"WHERE prints.groupid = :group"
|
|
)
|
|
rows = db.session.execute(query, {"group": 8})
|
|
|
|
market = Market.query.get_or_404(market_id)
|
|
|
|
result = {}
|
|
for row in rows:
|
|
printid, pricepremium_framed_print, width, height = row
|
|
|
|
if not pricepremium_framed_print:
|
|
pricepremium_framed_print = 0
|
|
|
|
designer = SimpleNamespace(pricepremium_framed_print=pricepremium_framed_print)
|
|
|
|
if width == height:
|
|
sku = pwinty.GLOBAL_CFP_12x12
|
|
else:
|
|
sku = pwinty.GLOBAL_CFP_11x14
|
|
|
|
result[printid] = framed_print_price(sku=sku, market=market, designer=designer)
|
|
|
|
return jsonify(result)
|