diff --git a/api/lib/prices.py b/api/lib/prices.py index b2a7302..73f32b1 100644 --- a/api/lib/prices.py +++ b/api/lib/prices.py @@ -54,7 +54,7 @@ def wallpaper_price(width, height, material, market, designer=None, reseller=Non def canvas_cm2_price(cm2): - price_cm2_at_1cm2 = 0.224 + price_cm2_at_1cm2 = 0.2461 price_cm2_at_5000cm2 = 0.144 price_cm2_at_10000cm2 = 0.096 price_cm2_at_22500cm2 = 0.064 @@ -78,64 +78,30 @@ def canvas_cm2_price(cm2): return cm2_price -def canvas_price(width, height, market, framed=True, designer=None, reseller=None, inc_vat=True): +def canvas_price(width, height, market, framed=True, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): cm2 = width * height - # get the price per cm2 cm2_price = canvas_cm2_price(cm2) # calculate price for canvas with frame - price = (cm2 * cm2_price) - price = max(price, 396.8) # the price can never go below 396.8 SEK + price = cm2 * cm2_price + price = max(price, 341.4848) # the price can never go below 341.4848 SEK if not framed: price *= 0.7 - # add designer price premium if designer: price *= (float(designer.pricepremium) / 100) + 1 - # add reseller price premium if reseller: price *= (float(reseller.pricepremium) / 100) + 1 - # exchange to local currency - price *= market.exchange_rate + if inquiry: + price *= (float(inquiry.pricepremium) / 100) + 1 - # multiply price with market price adjustments + price *= market.exchange_rate price *= market.price_adjustments - # add vat - if inc_vat: - price *= market.vat - - return round(price) - - -def canvas_frame_price(width, height, stock_price, market, additional_price=None, reseller=None, rounded=True, inc_vat=True): - width, height = calculate_canvas_limits(width, height, framed=True) - circumference = (2 * width) + (2 * height) - circumference = max(circumference, 170) - - price = stock_price * circumference - - # if width or height goes above this limit additional costs are added - if additional_price: - additional_price_limit = 120 - if width > additional_price_limit or height > additional_price_limit: - price += additional_price - - # exchange to local currency - price *= market.exchange_rate - - # multiply price with market price adjustments - price *= market.price_adjustments - - # add reseller price premium - if reseller: - price *= (float(reseller.pricepremium) / 100) + 1 - - # add vat if inc_vat: price *= market.vat @@ -145,33 +111,20 @@ def canvas_frame_price(width, height, stock_price, market, additional_price=None return price -def old_canvas_diy_frame_price(width, height, market, reseller=None, rounded=True, inc_vat=True): - # todo: when product models are in place we should use stockproduct ""Do it yourself frame"" - # instead of hardcoded values - stock_price = 1.61084 - additional_price = 94.750000 - return canvas_frame_price(width, height, stock_price, market, additional_price, reseller=reseller, rounded=rounded, inc_vat=inc_vat) +def canvas_frame_price(width, height, market, reseller=None, rounded=True, inc_vat=True): + width, height = calculate_canvas_limits(width, height, framed=True) + cm2 = width * height + cm2_price = canvas_cm2_price(cm2) + price = cm2 * cm2_price + price = max(price, 317.44) + price *= 0.65 + if reseller: + price *= (float(reseller.pricepremium) / 100) + 1 -def old_canvas_price(width, height, material, market, framed=True, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): - width, height = calculate_canvas_limits(width, height, framed) - price = m2_price(material, market, designer, reseller, - inquiry, rounded=False, inc_vat=False) + price *= market.exchange_rate + price *= market.price_adjustments - # calculate square meter - sqm = (width / 100) * (height / 100) - sqm = max(sqm, 0.2) # sqm can never go below 0.2 - price *= sqm - - if framed: - # todo: when product models are in place we should use stockproduct - # "Canvasframe" instead of hardcoded values - stock_price = 1.04230824 - additional_price = 94.750000 - price += canvas_frame_price(width, height, stock_price, market, - additional_price=additional_price, reseller=reseller, rounded=False, inc_vat=False) - - # add vat if inc_vat: price *= market.vat @@ -191,8 +144,8 @@ def inquiry_price(inquiry, inc_price_retouch=True, rounded=True, inc_vat=True, * price = wallpaper_price(width, height, material, inquiry.market, designer=inquiry.designer, reseller=inquiry.dealer_store, inquiry=inquiry, rounded=False, inc_vat=False) elif inquiry.product_group == 'canvas': - price = old_canvas_price(width, height, material, inquiry.market, - designer=inquiry.designer, reseller=inquiry.dealer_store, inquiry=inquiry, framed=framed, rounded=False, inc_vat=False) + price = canvas_price(width, height, inquiry.market, + designer=inquiry.designer, reseller=inquiry.dealer_store, inquiry=inquiry, framed=framed, rounded=False, inc_vat=False) else: raise ValueError( 'Invalid product group: {}'.format(inquiry.product_group)) diff --git a/api/models/product.py b/api/models/product.py index 42f2829..facf3a8 100644 --- a/api/models/product.py +++ b/api/models/product.py @@ -45,7 +45,6 @@ class Material(db.Model): name = db.Column('material', db.String(255), nullable=False) price = db.Column('price', db.Integer) - def to_json(self): return { 'id': self.id, @@ -54,4 +53,4 @@ class Material(db.Model): } def __repr__(self): - return self.name \ No newline at end of file + return self.name diff --git a/api/resources/prices.py b/api/resources/prices.py index a9974fc..e88bab3 100644 --- a/api/resources/prices.py +++ b/api/resources/prices.py @@ -5,7 +5,7 @@ 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.prices import wallpaper_price, old_canvas_price, old_canvas_diy_frame_price, m2_price, inquiry_price +from api.lib.prices import wallpaper_price, canvas_price, canvas_frame_price, m2_price, inquiry_price from api.lib.limits import calculate_canvas_limits mod = Blueprint('prices', __name__, url_prefix='/prices') @@ -61,7 +61,6 @@ def canvas(): market = market_model.from_territory(request.args.get('territory')) reseller = get_reseller() designer = get_designer() - material = Material.query.canvas().first() data = [] @@ -71,14 +70,14 @@ def canvas(): request.args.get('height', type=int), framed ) + # def canvas_price(width, height, market, framed=True, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True): + data.append({ 'framed': framed, 'width': width, 'height': height, - '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': old_canvas_price(width, height, material, market, reseller=reseller, designer=designer, framed=framed, rounded=False, inc_vat=True), - 'price_excl_vat': old_canvas_price(width, height, material, market, reseller=reseller, designer=designer, framed=framed, rounded=False, inc_vat=False) + '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) @@ -99,8 +98,8 @@ def diy_frame(): data = [{ 'width': width, 'height': height, - 'price': old_canvas_diy_frame_price(width, height, market, reseller=reseller, rounded=False), - 'price_excl_vat': old_canvas_diy_frame_price(width, height, market, reseller=reseller, rounded=False, inc_vat=False) + '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) @@ -169,8 +168,6 @@ def inquiry_canvas(inquiry): 'framed': framed, 'width': width, 'height': height, - '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, 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) diff --git a/tests/lib/test_prices.py b/tests/lib/test_prices.py index ab68d0f..a93f20d 100644 --- a/tests/lib/test_prices.py +++ b/tests/lib/test_prices.py @@ -97,87 +97,75 @@ class TestPrice(unittest2.TestCase): material=standard_wallpaper, market=us), "Minium price for US is 2 sqm") def test_canvas_cm2_price(self): - self.assertEqual(0.22, canvas_cm2_price(250)) - self.assertEqual(0.22384, canvas_cm2_price(10)) - self.assertEqual(0.208, canvas_cm2_price(1000)) + self.assertEqual(0.24099500000000001, canvas_cm2_price(250)) + self.assertEqual(0.24589580000000003, canvas_cm2_price(10)) + self.assertEqual(0.22568000000000002, canvas_cm2_price(1000)) def test_canvas_price(self): - self.assertEqual(460, canvas_price(width=50, height=50, + self.assertEqual(488, canvas_price(width=50, height=50, market=sweden, framed=True, inc_vat=False)) + self.assertEqual(960, canvas_price( width=100, height=100, market=sweden, framed=True, inc_vat=False)) + self.assertEqual(1359, canvas_price( width=150, height=120, market=sweden, framed=True, inc_vat=False)) + self.assertEqual(256000, canvas_price( width=2000, height=2000, market=sweden, framed=True, inc_vat=False)) - self.assertEqual(397, canvas_price(width=10, height=10, + + self.assertEqual(341, canvas_price(width=10, height=10, market=sweden, framed=True, inc_vat=False)) + + self.assertEqual(427, canvas_price(width=40, height=40, + market=sweden, framed=True, inc_vat=True)) + + self.assertEqual(299, canvas_price(width=40, height=40, + market=sweden, framed=False, inc_vat=True)) + self.assertEqual(277, canvas_frame_price( + width=40, height=40, market=sweden, inc_vat=True)) + + self.assertEqual(731, canvas_price(width=80, height=80, + market=sweden, framed=False, inc_vat=True)) + + self.assertEqual(1044, canvas_price(width=80, height=80, + market=sweden, framed=True, inc_vat=True)) + + self.assertEqual(1260, canvas_price(width=150, height=150, + market=sweden, framed=False, inc_vat=True)) + + self.assertEqual(1800, canvas_price(width=150, height=150, + market=sweden, framed=True, inc_vat=True)) + self.assertEqual(672, canvas_price( width=100, height=100, market=sweden, framed=False, inc_vat=False)) + self.assertEqual(840, canvas_price( width=100, height=100, market=sweden, framed=False, inc_vat=True)) - self.assertEqual(436, canvas_price(width=50, height=50, + self.assertEqual(462, canvas_price(width=50, height=50, market=denmark, framed=True, inc_vat=False)) def test_canvas_frame_price(self): - self.assertAlmostEqual(416.923, canvas_frame_price(width=100, height=100, stock_price=1.04230824, - additional_price=94.75, market=sweden, rounded=False, inc_vat=False), places=2) - self.assertAlmostEqual(177.19, canvas_frame_price( - 1, 1, stock_price=1.04230824, additional_price=94.750000, market=sweden, rounded=False, inc_vat=False), places=2) - self.assertAlmostEqual(625.38, canvas_frame_price( - 500, 500, stock_price=1.04230824, additional_price=None, market=sweden, rounded=False, inc_vat=False), places=2) - self.assertAlmostEqual(41.692, canvas_frame_price( - width=100, height=100, stock_price=1.04230824, additional_price=94.75, rounded=False, market=russia), places=2) - - def test_old_canvas_diy_frame_price(self): - self.assertEqual( - 403, old_canvas_diy_frame_price(50, 50, market=sweden)) - self.assertEqual(801, old_canvas_diy_frame_price( - 100, 110, market=denmark)) - self.assertEqual(463, old_canvas_diy_frame_price( - 50, 50, market=sweden, reseller=reseller)) - self.assertEqual(1327, old_canvas_diy_frame_price( - 500, 500, market=sweden)) - self.assertEqual(88, old_canvas_diy_frame_price( - 100, 100, market=russia, reseller=piterra)) - - def test_old_canvas_price(self): - self.assertEqual(250, old_canvas_price( - width=50, height=50, material=standard_canvas, market=sweden, framed=False)) - self.assertEqual(200, old_canvas_price( - width=1, height=1, material=standard_canvas, market=sweden, framed=False)) - self.assertEqual(7493, old_canvas_price( - width=500, height=500, material=standard_canvas, market=sweden, framed=False)) - self.assertEqual(5994, old_canvas_price(width=500, height=500, - material=standard_canvas, market=sweden, framed=False, inc_vat=False)) - self.assertEqual(7493, old_canvas_price( - width=500, height=500, material=standard_canvas, market=sweden, framed=False)) - self.assertEqual(236, old_canvas_price( - width=50, height=50, material=standard_canvas, market=denmark, framed=False)) - self.assertEqual(294, old_canvas_price( - width=50, height=50, material=standard_canvas, market=sweden, designer=designer, framed=False)) - self.assertEqual(510, old_canvas_price( - width=50, height=50, material=standard_canvas, market=sweden, framed=True)) - self.assertEqual(2972, old_canvas_price( - width=150, height=140, material=standard_canvas, market=sweden, framed=True)) - - self.assertEqual(168, old_canvas_price(width=100, height=100, material=standard_canvas, market=russia, framed=True, - designer=designer_moomin, reseller=piterra)) - - self.assertEqual(287, old_canvas_price( - width=50, height=50, material=standard_canvas, market=sweden, framed=False, reseller=reseller)) - self.assertEqual(111, old_canvas_price(width=100, height=100, material=standard_canvas, market=russia, framed=False, - designer=designer_moomin, reseller=piterra)) - + self.assertEqual(624, canvas_frame_price( + width=100, height=100, market=sweden, inc_vat=False)) + self.assertEqual(780, canvas_frame_price( + width=100, height=100, market=sweden, inc_vat=True)) + self.assertEqual(62, canvas_frame_price( + width=100, height=100, market=russia)) + self.assertEqual(936, canvas_frame_price( + 500, 500, market=sweden, inc_vat=False)) + self.assertEqual(222, canvas_frame_price( + 1, 1, market=sweden, inc_vat=False)) def test_wallpaper_custom_inquiry_price(self): with mock.patch.object(Inquiry, 'market', nl): inquiry = Inquiry(product_group="photo-wallpaper", territory="NL", pricepremium=0, - width=350, height=270, price_effect=0, price_retouch=160.00, material=standard_wallpaper) + width=350, height=270, price_effect=0, price_retouch=160.00, material=standard_wallpaper) self.assertEqual(333, inquiry_price(inquiry)) - self.assertEqual(310, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(310, inquiry_price( + inquiry, inc_price_retouch=False)) self.assertEqual(160, inquiry.price_retouch) self.assertEqual(18.4, inquiry.local_price_retouch(rounded=False)) self.assertEqual(22, inquiry.local_price_retouch( @@ -195,10 +183,11 @@ class TestPrice(unittest2.TestCase): product = Product(designer=designer) with mock.patch.object(Inquiry, 'market', sweden): inquiry = Inquiry(product_group="photo-wallpaper", territory="SE", pricepremium=0, - width=350, height=280, price_retouch=0, material=standard_wallpaper, product=product) + width=350, height=280, price_retouch=0, material=standard_wallpaper, product=product) self.assertEqual(3007, inquiry_price(inquiry)) - self.assertEqual(3007, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(3007, inquiry_price( + inquiry, inc_price_retouch=False)) self.assertEqual(3312, inquiry_price( inquiry, material=premium_wallpaper)) @@ -210,7 +199,8 @@ class TestPrice(unittest2.TestCase): inquiry = Inquiry(product_group="photo-wallpaper", territory="SE", pricepremium=25, width=250, height=400, price_retouch=200, material=standard_wallpaper, product=product) - self.assertEqual(3835, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(3835, inquiry_price( + inquiry, inc_price_retouch=False)) self.assertEqual(200, inquiry.price_retouch) self.assertEqual(250, inquiry.local_price_retouch( rounded=True, inc_vat=True)) @@ -221,7 +211,8 @@ class TestPrice(unittest2.TestCase): inquiry = Inquiry(product_group="photo-wallpaper", territory="RU", width=150, height=211, dealer_store=piterra, pricepremium=36.029411, material=standard_wallpaper, product=product) - self.assertEqual(138, inquiry_price(inquiry, inc_price_retouch=False)) + self.assertEqual(138, inquiry_price( + inquiry, inc_price_retouch=False)) self.assertEqual(152, inquiry_price( inquiry, inc_price_retouch=False, material=premium_wallpaper)) @@ -230,9 +221,11 @@ class TestPrice(unittest2.TestCase): inquiry = Inquiry(product_group='canvas', territory='SE', width=100, height=100, framed=True, price_retouch=200, pricepremium=0, material=standard_canvas) - self.assertEqual(1520, inquiry_price(inquiry, inc_price_retouch=False)) - self.assertEqual(1770, inquiry_price(inquiry, inc_price_retouch=True)) - self.assertEqual(999, inquiry_price( + self.assertEqual(1200, inquiry_price( + inquiry, inc_price_retouch=False)) + self.assertEqual(1450, inquiry_price( + inquiry, inc_price_retouch=True)) + self.assertEqual(840, inquiry_price( inquiry, inc_price_retouch=False, framed=False)) def test_canvas_piterra_inquiry_price(self): @@ -242,5 +235,5 @@ class TestPrice(unittest2.TestCase): # note: site currently calculates this as €150 which is wrong because # it does not add dealer_store.pricepremium to the frame price - self.assertEqual(165, inquiry_price(inquiry)) - self.assertEqual(109, inquiry_price(inquiry, framed=False)) + self.assertEqual(131, inquiry_price(inquiry)) + self.assertEqual(91, inquiry_price(inquiry, framed=False)) diff --git a/tests/resources/test_prices.py b/tests/resources/test_prices.py index 73ad5ba..cff593d 100644 --- a/tests/resources/test_prices.py +++ b/tests/resources/test_prices.py @@ -98,34 +98,28 @@ class TestEndpoints(flask_testing.TestCase): self.assertEqual(expected, response.json['data']) def test_canvas(self): - self._add_material('standard-canvas', 2, 79920) response = self.client.get( '/prices/canvas?width=200&height=10&territory=SE') self.assert200(response) expected = [ { - 'price_excl_vat': 970.3471312000001, - 'price': 1212.9339140000002, - 'width': 150, - 'height': 40, - 'framed': True, - 'm2_price': 999.0, - 'm2_price_excl_vat': 799.2, + "framed": True, + "height": 40, + "price": 1008.0, + "price_excl_vat": 806.4, + "width": 150 }, { - 'price_excl_vat': 319.68000000000006, - 'price': 399.6000000000001, - 'width': 200, - 'height': 20, - 'framed': False, - 'm2_price': 999.0, - 'm2_price_excl_vat': 799.2, + "framed": False, + "height": 20, + "price": 575.47, + "price_excl_vat": 460.37600000000003, + "width": 200 } ] self.assertEqual(expected, response.json['data']) def test_canvas_with_product(self): - self._add_material('standard-canvas', 2, 79920) designer = self._add_designer(4) product = self._add_product(designer) response = self.client.get( @@ -133,22 +127,18 @@ class TestEndpoints(flask_testing.TestCase): self.assert200(response) expected = [ { - 'height': 40, - 'price_excl_vat': 989.5279312000002, - 'price': 1236.9099140000003, - 'framed': True, - 'm2_price': 1038.96, - 'm2_price_excl_vat': 831.1680000000001, - 'width': 150 + "framed": True, + "height": 40, + "price": 1048.32, + "price_excl_vat": 838.656, + "width": 150 }, { - 'height': 20, - 'price_excl_vat': 332.46720000000005, - 'price': 415.58400000000006, - 'framed': False, - 'm2_price': 1038.96, - 'm2_price_excl_vat': 831.1680000000001, - 'width': 200 + "framed": False, + "height": 20, + "price": 598.4888000000001, + "price_excl_vat": 478.79104000000007, + "width": 200 } ] self.assertEqual(expected, response.json['data']) @@ -160,7 +150,7 @@ class TestEndpoints(flask_testing.TestCase): product = response.json['data'][0] self.assertEqual(150, product['width'], "it adjusts measurements") self.assertEqual(50, product['height']) - self.assertAlmostEqual(923.857, product['price'], places=2) + self.assertAlmostEqual(731.25, product['price'], places=2) def test_inquiry_wallpaper(self): self._add_material('standard-wallpaper', 1, 236)