Files
api2/api/resources/prices.py
T

511 lines
15 KiB
Python

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
from api.models.contract_customer import ContractCustomer
from api.models import market as market_model
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,
m2_price,
inquiry_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_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"))
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,
),
}
)
return jsonify(data=data)
@mod.route("/canvas", methods=["GET"])
@validate_number("width", "height")
@validate_territory("territory")
def canvas():
market = market_model.from_territory(request.args.get("territory"))
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_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"))
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_territory("territory")
def diy_frame():
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,
)
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")
def poster_hanger():
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
),
}
]
return jsonify(data=data)
@mod.route("/framed-print", methods=["GET"])
@validate_territory("territory")
@validate_any_of("sku", pwinty.SKU_CODES)
def framed_print():
sku = request.args.get("sku", type=str)
market = market_model.from_territory(request.args.get("territory"))
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": 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
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
@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)
else:
raise ValueError("Invalid group {}".format(inquiry.product_group))
return jsonify(data)