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.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, ) 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": 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_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": 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/", 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//wallpaper") def list_prices_wallpaper(territory): wallpapers = PrintProduct.query.wallpapers().all() result = {} material = Material.query.filter(Material.name == "standard-wallpaper").one() market = market_model.from_territory(territory) 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//canvas") def list_prices_canvas(territory): canvases = PrintProduct.query.canvases().all() market = market_model.from_territory(territory) 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//poster") def list_prices_posters(territory): posters = PrintProduct.query.posters().all() market = market_model.from_territory(territory) 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//framed-print") def list_prices_framed_prints(territory): 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_model.from_territory(territory) 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)