Add external product prices (#47)
Co-authored-by: Niklas Fondberg <niklas.fondberg@photowall.se>
This commit is contained in:
co-authored by
Niklas Fondberg
parent
f0b18c6757
commit
b1177a1e1c
+51
-1
@@ -4,6 +4,7 @@
|
||||
from api.lib.utils import round_half_up
|
||||
from api.lib.limits import calculate_canvas_limits
|
||||
from api.lib import pwinty
|
||||
from api.models.external_print_product import get_external_print_product
|
||||
|
||||
|
||||
def wallpaper_m2_price(
|
||||
@@ -297,6 +298,45 @@ def _price_for_poster_hanger_size(size):
|
||||
raise ValueError("Invalid poster hanger size: {}".format(size))
|
||||
|
||||
|
||||
def _designer_pricepremium(designer, group_id):
|
||||
if group_id in [1,3,6]:
|
||||
return designer.pricepremium_wallpaper
|
||||
if group_id == 2:
|
||||
return designer.pricepremium_canvas
|
||||
if group_id == 7:
|
||||
return designer.pricepremium_poster
|
||||
if group_id == 8:
|
||||
return designer.pricepremium_framed_print
|
||||
|
||||
raise ValueError("Unexpected group id: {}".format(group_id))
|
||||
|
||||
|
||||
def external_product_price(
|
||||
id, market, designer=None, inquiry=None, rounded=True, inc_vat=True
|
||||
):
|
||||
external_product = get_external_print_product(id)
|
||||
price = external_product["price"]
|
||||
|
||||
price *= market.price_adjustments
|
||||
|
||||
if designer:
|
||||
designer_pricepremium = _designer_pricepremium(designer, external_product["group_id"])
|
||||
price *= (float(designer_pricepremium) / 100) + 1
|
||||
|
||||
if inquiry:
|
||||
price *= (float(inquiry.pricepremium) / 100) + 1
|
||||
|
||||
price *= market.exchange_rate
|
||||
|
||||
if inc_vat:
|
||||
price *= market.vat
|
||||
|
||||
if rounded:
|
||||
price = round_half_up(price)
|
||||
|
||||
return price
|
||||
|
||||
|
||||
def framed_print_price(
|
||||
sku, market, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True
|
||||
):
|
||||
@@ -445,8 +485,18 @@ def inquiry_price(
|
||||
hanger = kwargs.get("hanger", inquiry.hanger)
|
||||
sku = kwargs.get("sku")
|
||||
reseller = kwargs.get("reseller", inquiry.dealer_store)
|
||||
external_id = kwargs.get("external_id")
|
||||
|
||||
if inquiry.product_group == "photo-wallpaper":
|
||||
if external_id:
|
||||
price = external_product_price(
|
||||
id=external_id,
|
||||
market=inquiry.market,
|
||||
designer=inquiry.designer,
|
||||
inquiry=inquiry,
|
||||
rounded=False,
|
||||
inc_vat=False,
|
||||
)
|
||||
elif inquiry.product_group == "photo-wallpaper":
|
||||
price = wallpaper_price(
|
||||
width,
|
||||
height,
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
import time
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
def round_half_up(val):
|
||||
return int(Decimal(val).quantize(0, ROUND_HALF_UP))
|
||||
|
||||
|
||||
def lru_with_ttl(*, ttl_seconds, maxsize=128):
|
||||
"""
|
||||
A decorator to apply LRU in-memory cache to a function with defined maximum(!) TTL in seconds.
|
||||
Be design an actual TTL may be shorter then the passed value (in rare randomized cases). But it can't be higher.
|
||||
:param ttl_seconds: TTL for a cache record in seconds
|
||||
:param maxsize: Maximum size of the LRU cache (a functools.lru_cache argument)
|
||||
:return: decorated function
|
||||
"""
|
||||
def deco(foo):
|
||||
@lru_cache(maxsize=maxsize)
|
||||
def cached_with_ttl(*args, ttl_hash, **kwargs):
|
||||
return foo(*args, **kwargs)
|
||||
def inner(*args, **kwargs):
|
||||
return cached_with_ttl(*args, ttl_hash=round(time.time() / ttl_seconds), **kwargs)
|
||||
return inner
|
||||
return deco
|
||||
@@ -0,0 +1,46 @@
|
||||
# coding=UTF-8
|
||||
|
||||
from api.extensions import db
|
||||
from api.lib.utils import lru_with_ttl
|
||||
|
||||
@lru_with_ttl(ttl_seconds=300)
|
||||
def get_all_external_print_products():
|
||||
sql="select external_product_id, price_sek, group_id from external_print_products"
|
||||
result = db.session.execute(sql)
|
||||
rows = result.fetchall()
|
||||
|
||||
prices = {}
|
||||
for row in rows:
|
||||
external_id = row[0]
|
||||
price = float(row[1])
|
||||
group_id = row[2]
|
||||
prices[external_id] = {"price": price, "group_id": group_id}
|
||||
|
||||
return prices
|
||||
|
||||
|
||||
def get_external_print_product(id):
|
||||
all = get_all_external_print_products()
|
||||
|
||||
if id not in all:
|
||||
raise ValueError("Invalid external product id: {}".format(id))
|
||||
|
||||
external_product = all.get(id)
|
||||
|
||||
return external_product
|
||||
|
||||
|
||||
def get_cheapest_canvas_product():
|
||||
sql = "select external_product_id from external_print_products where group_id = 2 order by price_sek limit 1"
|
||||
result = db.session.execute(sql)
|
||||
external_id = result.first()[0]
|
||||
|
||||
return external_id
|
||||
|
||||
|
||||
def get_cheapest_poster_product():
|
||||
sql = "select external_product_id from external_print_products where group_id in (7,8) order by price_sek limit 1"
|
||||
result = db.session.execute(sql)
|
||||
external_id = result.first()[0]
|
||||
|
||||
return external_id
|
||||
+98
-1
@@ -1,3 +1,4 @@
|
||||
from api.models.external_print_product import get_cheapest_canvas_product, get_cheapest_poster_product
|
||||
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
|
||||
@@ -20,6 +21,7 @@ from api.lib.prices import (
|
||||
wallpaper_m2_price,
|
||||
inquiry_price,
|
||||
wallpaper_kit_price,
|
||||
external_product_price,
|
||||
)
|
||||
from api.lib.limits import calculate_canvas_limits
|
||||
|
||||
@@ -524,6 +526,32 @@ def inquiry_poster(inquiry):
|
||||
return data
|
||||
|
||||
|
||||
def inquiry_external_product(inquiry):
|
||||
external_id = request.args.get("external_product_id", type=str)
|
||||
data = {
|
||||
"id": inquiry.id,
|
||||
"retouch_price": inquiry.local_price_retouch(rounded=False, inc_vat=True),
|
||||
"prices": [
|
||||
{
|
||||
"inquiry_price": inquiry_price(
|
||||
inquiry, external_id=external_id, rounded=False, inc_vat=True
|
||||
),
|
||||
"inquiry_price_excl_vat": inquiry_price(
|
||||
inquiry, external_id=external_id, rounded=False, inc_vat=False
|
||||
),
|
||||
"inquiry_price_excl_retouch": inquiry_price(
|
||||
inquiry, external_id=external_id, rounded=False, inc_vat=True, inc_price_retouch=False,
|
||||
),
|
||||
"inquiry_price_excl_retouch_excl_vat": inquiry_price(
|
||||
inquiry, external_id=external_id, rounded=False, inc_vat=False, inc_price_retouch=False,
|
||||
),
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def inquiry_framed_print(inquiry):
|
||||
sku = request.args.get("sku", type=str)
|
||||
data = {
|
||||
@@ -563,8 +591,11 @@ def inquiry_framed_print(inquiry):
|
||||
@mod.route("/inquiry/<int:inquiry_id>", methods=["GET"])
|
||||
def inquiry(inquiry_id):
|
||||
inquiry = Inquiry.query.get_or_404(inquiry_id)
|
||||
external_id = request.args.get("external_product_id")
|
||||
sku = request.args.get("sku", type=str)
|
||||
if inquiry.product_group == "photo-wallpaper":
|
||||
if external_id:
|
||||
data = inquiry_external_product(inquiry)
|
||||
elif inquiry.product_group == "photo-wallpaper":
|
||||
data = inquiry_wallpaper(inquiry)
|
||||
elif inquiry.product_group == "canvas":
|
||||
data = inquiry_canvas(inquiry)
|
||||
@@ -592,6 +623,40 @@ def list_prices_wallpaper(market_id):
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@mod.route("/list-prices/<int:market_id>/canvas_external")
|
||||
def list_prices_canvas_external(market_id):
|
||||
canvases = PrintProduct.query.canvases().all()
|
||||
market = Market.query.get_or_404(market_id)
|
||||
external_product_id = get_cheapest_canvas_product()
|
||||
|
||||
result = {}
|
||||
for canvas in canvases:
|
||||
result[canvas.id] = external_product_price(
|
||||
id = external_product_id,
|
||||
market=market,
|
||||
designer=canvas.product.designer
|
||||
)
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@mod.route("/list-prices/<int:market_id>/poster_external")
|
||||
def list_prices_poster_external(market_id):
|
||||
posters = PrintProduct.query.posters().all()
|
||||
market = Market.query.get_or_404(market_id)
|
||||
external_product_id = get_cheapest_poster_product()
|
||||
|
||||
result = {}
|
||||
for poster in posters:
|
||||
result[poster.id] = external_product_price(
|
||||
id = external_product_id,
|
||||
market=market,
|
||||
designer=poster.product.designer
|
||||
)
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@mod.route("/list-prices/<int:market_id>/canvas")
|
||||
def list_prices_canvas(market_id):
|
||||
canvases = PrintProduct.query.canvases().all()
|
||||
@@ -661,3 +726,35 @@ def list_prices_framed_prints(market_id):
|
||||
result[printid] = framed_print_price(sku=sku, market=market, designer=designer)
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
|
||||
@mod.route("/external-product", methods=["GET"])
|
||||
@validate_exists("market")
|
||||
@validate_exists("id")
|
||||
def external_product():
|
||||
market_id = request.args.get("market", type=int)
|
||||
market = Market.query.get_or_404(market_id)
|
||||
designer = get_designer()
|
||||
id = request.args.get("id", type=str)
|
||||
|
||||
data = [
|
||||
{
|
||||
"id": id,
|
||||
"price": external_product_price(
|
||||
id,
|
||||
market,
|
||||
designer=designer,
|
||||
rounded=False,
|
||||
inc_vat=True,
|
||||
),
|
||||
"price_excl_vat": external_product_price(
|
||||
id,
|
||||
market,
|
||||
designer=designer,
|
||||
rounded=False,
|
||||
inc_vat=False,
|
||||
),
|
||||
}
|
||||
]
|
||||
|
||||
return jsonify(data=data)
|
||||
|
||||
Reference in New Issue
Block a user