Files
kupshop/bundles/KupShop/PricelistBundle/Tests/PricelistTest.php
2025-08-02 16:30:27 +02:00

309 lines
13 KiB
PHP

<?php
namespace KupShop\PricelistBundle\Tests;
use KupShop\DevelopmentBundle\Util\Tests\CartTestTrait;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\OrderingBundle\Util\CartFactory;
use KupShop\PricelistBundle\Context\PricelistContext;
use KupShop\PricelistBundle\Entity\Pricelist;
class PricelistTest extends \DatabaseTestCase
{
use CartTestTrait;
protected function setUp(): void
{
$this->createCart();
parent::setUp();
}
/*
* HACK
* Prazdny test - prvni test vzdycky spadl s chybou:
* No database selected
* nevime proc, ale tohle to fixnulo
*/
public function testFixSetUp()
{
$this->assertTrue(true);
}
public function testPricelistEurPrice()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$pricelistContext->activate(2);
$currencyContext->activate('EUR');
$productList = new \ProductList();
$products = $productList->getProducts();
$this->assertEquals('46,60 €', $products[1]->price);
$this->assertEquals('115,40 €', $products[6]->price);
}
public function testPricelistCzkPrice()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$pricelistContext->activate(1);
$productList = new \ProductList();
$product = $productList->getProducts()[1];
$this->assertEquals('1 210 Kč', $product->price);
}
public function testPricelistCzkVariationPrice()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$pricelistContext->activate(1);
$productList = new \ProductList();
$productList->fetchVariations(null);
$product = $productList->getProducts()[4];
$this->assertEquals('315 Kč', $product->price);
$variation = $product->variations[1];
$this->assertEquals('315 Kč', printPrice($variation['price']));
$variation = $product->variations[2];
$this->assertEquals('299 Kč', printPrice($variation['price'])); // 315 - 5% (variation pricelist discount)
}
public function testPricelistEurVariationPrice()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$pricelistContext->activate(2);
$currencyContext->activate('EUR');
$productList = new \ProductList();
$productList->fetchVariations(null);
$product = $productList->getProducts()[4];
// Zakomentováno, varianty nemají na sobě cenu, a tak se nedokáže správně dofetchovat na produkt správná pricelist cena se slevou.
// Vzhledem ke komplexnosti problému a jeho malému use-casu jsme se to rozhodli neřešit.
// $this->assertEquals('9,70 €', $product->price); // 12,10 - 20% (variation pricelist discount from cheapest variation)
$variation = $product->variations[1];
$this->assertEquals('10,90 €', printPrice($variation['price'])); // 12,10 - 10% (product pricelist discount)
$variation = $product->variations[2];
$this->assertEquals('9,70 €', printPrice($variation['price'])); // 12,10 - 20% (variation pricelist discount)
}
public function testCartCZK()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$pricelistContext->activate(1);
$this->loginUser(1);
// insert product id 3, 2 pieces
$this->insertProduct(3, null, 2);
$this->cart->createFromDB();
$this->assertEquals(\Decimal::create('566.0000', 4), $this->cart->totalPriceWithVat);
$this->checkOrderPriceIsSameAsCart();
}
public function testCartVariationCZK()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$pricelistContext->activate(1);
$this->loginUser(1);
// insert product id 4, id variation 1
$this->insertProduct(4, 1); // price = 315 (no discount)
// insert product id 4, id variation 2
$this->insertProduct(4, 2); // price = 299 = 315 - 5% (variation pricelist discount)
$this->cart->createFromDB();
$this->assertEquals(\Decimal::create('614.0000', 4), $this->cart->totalPriceWithVat); // 315 + 299
$this->checkOrderPriceIsSameAsCart();
}
public function testCartEUR()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$pricelistContext->activate(2);
$this->loginUser(1);
$currencyContext->activate('EUR');
// insert product id 3, 2 pieces
$this->insertProduct(3, null, 2);
$this->cart->createFromDB();
$this->assertEquals(\Decimal::create('21.8000', 4), $this->cart->totalPriceWithVat);
$this->checkOrderPriceIsSameAsCart();
}
public function testCartVariationEUR()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$pricelistContext->activate(2);
$this->loginUser(1);
$currencyContext->activate('EUR');
// insert product id 4, id variation 1
$this->insertProduct(4, 1); // price = 10,90 € = 12,10 - 10% (product pricelist discount)
// insert product id 4, id variation 2
$this->insertProduct(4, 2); // price = 9,70 € = 12,10 - 20% (variation pricelist discount)
$this->cart->createFromDB();
$this->assertEquals(\Decimal::create('20.6000', 4), $this->cart->totalPriceWithVat); // 10,90 + 9,70
$this->checkOrderPriceIsSameAsCart();
}
public function testProductListFetchVariations()
{
$productList = new \ProductList(false);
$productList->fetchVariations([11]);
$product = $productList->getProducts()[1];
$this->assertEquals(20, $product->discount->asFloat());
// activate pricelist
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$pricelistContext->activate(1);
$productList = new \ProductList(false);
$productList->fetchVariations(null);
$product = $productList->getProducts()[1];
$this->assertEquals(0, $product->discount->asFloat());
$product = $productList->getProducts()[4];
$this->assertEquals(0, $product->discount->asFloat());
$variation = $product->variations[1];
$this->assertNull($variation['pricelistDiscount']);
$variation = $product->variations[2];
$this->assertEquals(5, $variation['pricelistDiscount']);
$productList = new \ProductList(true); // variationsAsResult
$products = $productList->getProducts();
$product = $products['4/1'];
$this->assertEquals(315, $product->getProductPrice()->getPriceWithVat()->asFloat()); // pricelist price, no discount
$this->assertEquals(0, $product->discount->asFloat());
$product = $products['4/2'];
$this->assertEquals(299, $product->getProductPrice()->getPriceWithVat()->asFloat()); // 315 - 5% (variation pricelist discount)
$this->assertEquals(5, $product->discount->asFloat());
}
public function testApplyPriceListCoefficient()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$pricelistContext->activate(2);
$currencyContext->activate('EUR');
sqlQueryBuilder()->update('pricelists_products')->directValues(['discount' => 25])->andWhere('id_product=6')->execute();
$this->insertProduct(8); // produkt se zakladni cenou 191.9€
$this->insertProduct(7, 6); // varianta se zakladni cenou 48.2€
$this->insertProduct(10); // produkt s pevou cenikovou cenou 23€
$this->insertProduct(11, 22); // varianta s pevou cenikovou cenou 12.1€*/
$this->insertProduct(6, 17); // varianta se slevou 25% ze zakl. ceny 115.4€
$this->insertProduct(9); // produkt se slevou 25% ze zakl. ceny 241.9€
$this->cart->createFromDB();
$expected = 191.9 + 48.2 + 23 + 12.1 + 115.4 * 0.75 + 241.9 * 0.75;
self::assertEquals($expected, $this->cart->totalPriceWithVat->asFloat(), 'Porovnani cen pred nastavenim koeficientu ceniku', 0.1);
/** @var Pricelist $activePricelist */
$activePricelist = Contexts::get(PricelistContext::class)->getActive();
$activePricelist?->setCoefficient(2);
$this->cart = $this->get(CartFactory::class)->create();
$this->cart->createFromDB();
$expected = 191.9 * 2 + 48.2 * 2 + 23 + 12.1 + (115.4 * 2) * 0.75 + (241.9 * 2) * 0.75;
self::assertEquals($expected, $this->cart->totalPriceWithVat->asFloat(), 'Porovnani cen po nastaveni koeficientu ceniku', 0.1);
}
public function testApplyPriceListCoefficientProduct()
{
$pricelistContext = ServiceContainer::getService(PricelistContext::class);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$priceConverter = ServiceContainer::getService(\KupShop\I18nBundle\Util\PriceConverter::class);
$pricelistContext->activate(2);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$priceConverter = ServiceContainer::getService(\KupShop\I18nBundle\Util\PriceConverter::class);
$pricelistContext->activate(2);
$currencyContext->activate('EUR');
$product = new \Product(); // produkt se zakladni cenou 191.9€
$product->createFromDB('8');
self::assertEquals('191,90 €', $product->price, 'Porovnani cen pred nastavenim koeficientu ceniku');
self::assertEquals('191.92', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->getProductPrice()->getPriceWithVat())->asFloat(), 2), 'Porovnani cen pred nastavenim koeficientu ceniku');
self::assertEquals('191.92', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->priceOriginal->getValue()->addVat(21))->asFloat(), 2), 'Porovnani cen pred nastavenim koeficientu ceniku - price original');
self::assertEquals('191.92', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->priceForDiscount->getValue()->addVat(21))->asFloat(), 2), 'Porovnani cen pred nastavenim koeficientu ceniku - price for discount');
/** @var Pricelist $activePricelist */
$activePricelist = Contexts::get(PricelistContext::class)->getActive();
$activePricelist?->setCoefficient(2);
$product->createFromDB('8');
self::assertEquals('383,85 €', $product->price, 'Porovnani cen po nastavenim koeficientu ceniku');
self::assertEquals('383.85', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->getProductPrice()->getPriceWithVat())->asFloat(), 2), 'Porovnani cen po nastavenim koeficientu ceniku');
self::assertEquals('383.85', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->priceOriginal->getValue()->addVat(21))->asFloat(), 2), 'Porovnani cen po nastavenim koeficientu ceniku - price original');
self::assertEquals('383.85', round($priceConverter->convert($product->getProductPrice()->getCurrency(), $currencyContext->getActive(), $product->priceForDiscount->getValue()->addVat(21))->asFloat(), 2), 'Porovnani cen po nastavenim koeficientu ceniku - price for discount');
}
public function getDataSet()
{
return $this->getJsonDataSetFromFile();
}
private function insertProduct($id_product, $id_variation = null, $pieces = 1)
{
$item = [
'id_product' => $id_product,
'id_variation' => $id_variation,
'pieces' => $pieces,
];
$this->assertGreaterThan(0, $this->cart->addItem($item));
}
private function loginUser($id_user)
{
$user = \User::createFromId($id_user);
$user->activateUser();
}
private function checkOrderPriceIsSameAsCart()
{
// je to fuj, ale je to kvuli spravnym cenam... aby se zapocitala i cena DeliveryType
$this->cart->max_step = 1;
$this->cart->createFromDB();
$order = $this->cart->submitOrder();
$this->assertInstanceOf(\Order::class, $order);
$this->assertEquals($order->total_price->asFloat(), $this->cart->totalPricePay->asFloat(), '', 0.01);
}
}