public function testGetSubtotals() { $this->translator->expects($this->once())->method('trans')->with(sprintf('orob2b.order.subtotals.%s', Subtotal::TYPE_SUBTOTAL))->willReturn(ucfirst(Subtotal::TYPE_SUBTOTAL)); $order = new Order(); $perUnitLineItem = new OrderLineItem(); $perUnitLineItem->setPriceType(OrderLineItem::PRICE_TYPE_UNIT); $perUnitLineItem->setPrice(Price::create(20, 'USD')); $perUnitLineItem->setQuantity(2); $bundledUnitLineItem = new OrderLineItem(); $bundledUnitLineItem->setPriceType(OrderLineItem::PRICE_TYPE_BUNDLED); $bundledUnitLineItem->setPrice(Price::create(2, 'USD')); $bundledUnitLineItem->setQuantity(10); $otherCurrencyLineItem = new OrderLineItem(); $otherCurrencyLineItem->setPriceType(OrderLineItem::PRICE_TYPE_UNIT); $otherCurrencyLineItem->setPrice(Price::create(10, 'EUR')); $otherCurrencyLineItem->setQuantity(10); $emptyLineItem = new OrderLineItem(); $order->addLineItem($perUnitLineItem); $order->addLineItem($bundledUnitLineItem); $order->addLineItem($emptyLineItem); $order->addLineItem($otherCurrencyLineItem); $order->setCurrency('USD'); $subtotals = $this->provider->getSubtotals($order); $this->assertInstanceOf('Doctrine\\Common\\Collections\\ArrayCollection', $subtotals); $subtotal = $subtotals->get(Subtotal::TYPE_SUBTOTAL); $this->assertInstanceOf('OroB2B\\Bundle\\OrderBundle\\Model\\Subtotal', $subtotal); $this->assertEquals(Subtotal::TYPE_SUBTOTAL, $subtotal->getType()); $this->assertEquals(ucfirst(Subtotal::TYPE_SUBTOTAL), $subtotal->getLabel()); $this->assertEquals($order->getCurrency(), $subtotal->getCurrency()); $this->assertInternalType('float', $subtotal->getAmount()); $this->assertEquals(142.0, $subtotal->getAmount()); }
/** * @param array $productUnitQuantities * @param string $currency * @param PriceList|null $priceList * @return array|Price[] */ public function getMatchedPrices(array $productUnitQuantities, $currency, PriceList $priceList = null) { if (!$priceList) { $priceList = $this->requestHandler->getPriceList(); } $productIds = []; $productUnitCodes = []; /** @var ProductUnitQuantity[] $productUnitQuantities */ foreach ($productUnitQuantities as $productUnitQuantity) { $productIds[] = $productUnitQuantity->getProduct()->getId(); $productUnitCodes[] = $productUnitQuantity->getProductUnit()->getCode(); } $prices = $this->getRepository()->getPricesBatch($priceList->getId(), $productIds, $productUnitCodes, []); $result = []; foreach ($productUnitQuantities as $productUnitQuantity) { $id = $productUnitQuantity->getProduct()->getId(); $code = $productUnitQuantity->getProductUnit()->getCode(); $quantity = $productUnitQuantity->getQuantity(); $productPrices = array_filter($prices, function (array $price) use($id, $code, $currency) { return $price['id'] === $id && $price['code'] === $code && $price['currency'] === $currency; }); $price = $this->matchPriceByQuantity($productPrices, $quantity); $result[$productUnitQuantity->getIdentifier()] = $price ? Price::create($price, $currency) : null; } return $result; }
/** * {@inheritdoc} */ public function submitDataProvider() { /** @var Product $product */ $product = $this->getEntity('OroB2B\\Bundle\\ProductBundle\\Entity\\Product', 1, 'id'); $date = \DateTime::createFromFormat('Y-m-d H:i:s', '2015-02-03 00:00:00', new \DateTimeZone('UTC')); return ['default' => ['options' => ['currency' => 'USD'], 'submittedData' => ['product' => 1, 'productSku' => '', 'freeFormProduct' => '', 'quantity' => 10, 'productUnit' => 'item', 'productUnitCode' => '', 'price' => ['value' => '5', 'currency' => 'USD'], 'priceType' => OrderLineItem::PRICE_TYPE_BUNDLED, 'shipBy' => '2015-02-03', 'comment' => 'Comment'], 'expectedData' => (new OrderLineItem())->setProduct($product)->setQuantity(10)->setProductUnit($this->getEntity('OroB2B\\Bundle\\ProductBundle\\Entity\\ProductUnit', 'item', 'code'))->setPrice(Price::create(5, 'USD'))->setPriceType(OrderLineItem::PRICE_TYPE_BUNDLED)->setShipBy($date)->setComment('Comment')], 'free form entry' => ['options' => ['currency' => 'USD'], 'submittedData' => ['product' => null, 'productSku' => 'SKU02', 'freeFormProduct' => 'Service', 'quantity' => 1, 'productUnit' => 'item', 'price' => ['value' => 5, 'currency' => 'USD'], 'priceType' => OrderLineItem::PRICE_TYPE_UNIT, 'shipBy' => '2015-02-03', 'comment' => 'Comment'], 'expectedData' => (new OrderLineItem())->setQuantity(1)->setFreeFormProduct('Service')->setProductSku('SKU02')->setProductUnit($this->getEntity('OroB2B\\Bundle\\ProductBundle\\Entity\\ProductUnit', 'item', 'code'))->setPrice(Price::create(5, 'USD'))->setPriceType(OrderLineItem::PRICE_TYPE_UNIT)->setShipBy($date)->setComment('Comment')]]; }
/** * @return array */ public function reverseTransformDataProvider() { $zeroPrice = Price::create(0, 'USD'); $price = Price::create(100, 'USD'); $lessZeroPrice = Price::create('-1', 'USD'); return ['zero price' => ['input' => $zeroPrice, 'expected' => $zeroPrice], 'price' => ['input' => $price, 'expected' => $price], 'null' => ['data' => null, 'expected' => null], 'invalid price' => ['input' => 'string', 'expected' => null], 'invalid price value' => ['input' => Price::create('price', 'USD'), 'expected' => null], 'price value less than zero' => ['input' => $lessZeroPrice, 'expected' => $lessZeroPrice]]; }
/** * {@inheritdoc} */ public function load(ObjectManager $manager) { $locator = $this->container->get('file_locator'); $filePath = $locator->locate('@OroB2BPricingBundle/Migrations/Data/Demo/ORM/data/product_prices.csv'); if (is_array($filePath)) { $filePath = current($filePath); } $handler = fopen($filePath, 'r'); $headers = fgetcsv($handler, 1000, ','); while (($data = fgetcsv($handler, 1000, ',')) !== false) { $row = array_combine($headers, array_values($data)); $product = $this->getProductBySku($manager, $row['sku']); $productUnit = $this->getProductUnit($manager, $row['unitCode']); $priceList = $this->getPriceList($manager, $row['priceListName']); $price = Price::create($row['price'], $row['currency']); $productPrice = new ProductPrice(); $productPrice->setProduct($product)->setUnit($productUnit)->setPriceList($priceList)->setQuantity($row['quantity'])->setPrice($price); $manager->persist($productPrice); $productPrice10 = clone $productPrice; $productPrice10->setQuantity($row['quantity'] * 10)->setPrice($price->setValue($price->getValue() * 0.95)); $manager->persist($productPrice10); $productPrice20 = clone $productPrice; $productPrice20->setQuantity($row['quantity'] * 20)->setPrice($price->setValue($price->getValue() * 0.9)); $manager->persist($productPrice20); $productPrice50 = clone $productPrice; $productPrice50->setQuantity($row['quantity'] * 50)->setPrice($price->setValue($price->getValue() * 0.85)); $manager->persist($productPrice50); $productPrice100 = clone $productPrice; $productPrice100->setQuantity($row['quantity'] * 100)->setPrice($price->setValue($price->getValue() * 0.8)); $manager->persist($productPrice100); } fclose($handler); $manager->flush(); }
public function testCreate() { $price = Price::create(self::VALUE, self::CURRENCY); $this->assertInstanceOf('Oro\\Bundle\\CurrencyBundle\\Model\\Price', $price); $this->assertEquals(self::VALUE, $price->getValue()); $this->assertEquals(self::CURRENCY, $price->getCurrency()); }
public function testSetPrice() { $price = Price::create(22, 'EUR'); $item = new QuoteProductOffer(); $item->setPrice($price); $this->assertEquals($price, $item->getPrice()); $this->assertEquals(22, $this->getProperty($item, 'value')); $this->assertEquals('EUR', $this->getProperty($item, 'currency')); }
/** * {@inheritdoc} */ public function load(ObjectManager $manager) { foreach ($this->data as $data) { /** @var Product $product */ $product = $this->getReference($data['product']); /** @var PriceList $priceList */ $priceList = $this->getReference($data['priceList']); /** @var ProductUnit $unit */ $unit = $this->getReference($data['unit']); $price = Price::create($data['price'], $data['currency']); $productPrice = new ProductPrice(); $productPrice->setPriceList($priceList)->setUnit($unit)->setQuantity($data['qty'])->setPrice($price)->setProduct($product); $manager->persist($productPrice); $this->setReference($data['reference'], $productPrice); } $manager->flush(); }
public function testPrePersist() { $entity = new OrderLineItem(); $entity->setPrice(Price::create(42, 'USD')); $this->assertEquals(42, $entity->getValue()); $this->assertEquals('USD', $entity->getCurrency()); $entity->getPrice()->setValue(84); $entity->getPrice()->setCurrency('EUR'); $this->assertEmpty($entity->getProductSku()); $this->assertEmpty($entity->getProductUnitCode()); $entity->setProduct((new Product())->setSku('SKU')); $entity->setProductUnit((new ProductUnit())->setCode('kg')); $entity->preSave(); $this->assertEquals(84, $entity->getValue()); $this->assertEquals('EUR', $entity->getCurrency()); $this->assertEquals('SKU', $entity->getProductSku()); $this->assertEquals('kg', $entity->getProductUnitCode()); }
public function testSetGetPrice() { $productPrice = new ProductPrice(); $this->assertNull($productPrice->getPrice()); $value = 11; $currency = 'EUR'; $this->setProperty($productPrice, 'value', $value); $this->setProperty($productPrice, 'currency', $currency); $productPrice->loadPrice(); $price = $productPrice->getPrice(); $this->assertInstanceOf('Oro\\Bundle\\CurrencyBundle\\Model\\Price', $price); $this->assertEquals($value, $price->getValue()); $this->assertEquals($currency, $price->getCurrency()); $price = Price::create(12, 'USD'); $productPrice->setPrice($price); $this->assertEquals($price, $productPrice->getPrice()); $productPrice->updatePrice(); $this->assertAttributeEquals($price->getValue(), 'value', $productPrice); $this->assertAttributeEquals($price->getCurrency(), 'currency', $productPrice); }
/** * @return array */ public function submitProvider() { $quoteProductOffer = $this->getQuoteProductOffer(2, 33, 'kg', self::QPO_PRICE_TYPE1, Price::create(44, 'USD')); $quoteProduct = $this->getQuoteProduct(2, self::QP_TYPE1, 'comment1', 'comment2', [], [$quoteProductOffer]); return ['empty owner' => ['isValid' => false, 'submittedData' => [], 'expectedData' => new Quote()], 'valid data' => ['isValid' => true, 'submittedData' => ['owner' => 1, 'accountUser' => 1, 'account' => 2, 'locked' => false, 'quoteProducts' => [['product' => 2, 'type' => self::QP_TYPE1, 'comment' => 'comment1', 'commentAccount' => 'comment2', 'quoteProductOffers' => [['quantity' => 33, 'productUnit' => 'kg', 'priceType' => self::QPO_PRICE_TYPE1, 'price' => ['value' => 44, 'currency' => 'USD']]]]]], 'expectedData' => $this->getQuote(1, 1, 2, [$quoteProduct], false)]]; }
/** * @param float $value * @param string $currency * @return Price */ protected function createPrice($value, $currency) { return Price::create($value, $currency); }
/** * @param int $productId * @param float $value * @param string $currency * @return ProductPrice */ protected function createPrice($productId, $value, $currency) { $product = new Product(); $reflection = new \ReflectionProperty(get_class($product), 'id'); $reflection->setAccessible(true); $reflection->setValue($product, $productId); $price = new ProductPrice(); $price->setProduct($product)->setPrice(Price::create($value, $currency)); return $price; }
/** * @ORM\PostLoad */ public function loadPrice() { $this->price = Price::create($this->value, $this->currency); }
/** * @return ProductPrice */ protected function createProductPrice() { /** @var Product $product */ $product = $this->getReference('product.1'); /** @var PriceList $priceList */ $priceList = $this->getReference('price_list_1'); /** @var ProductUnit $unit */ $unit = $this->getReference('product_unit.liter'); $price = Price::create(1.2, 'USD'); $newProductPrice = new ProductPrice(); $newProductPrice->setPriceList($priceList)->setProduct($product)->setQuantity(1)->setPrice($price)->setUnit($unit); return $newProductPrice; }
/** * @param Quote $quote * @param ObjectManager $manager */ protected function processQuoteProducts(Quote $quote, ObjectManager $manager) { $products = $this->getProducts($manager); $currencies = $this->getCurrencies(); $types = [QuoteProduct::TYPE_REQUESTED]; $priceTypes = [QuoteProductOffer::PRICE_TYPE_UNIT]; if ($quote->getRequest()) { foreach ($quote->getRequest()->getRequestProducts() as $requestProduct) { $type = $types[rand(0, count($types) - 1)]; $quoteProduct = $this->createQuoteProduct($requestProduct->getProduct(), $type); $this->processRequestProductItems($quoteProduct, $requestProduct); $quote->addQuoteProduct($quoteProduct); } } else { $numProducts = rand(1, 3); for ($i = 0; $i < $numProducts; $i++) { $product = $products[rand(1, count($products) - 1)]; $quote->addQuoteProduct($this->createQuoteProduct($product, QuoteProduct::TYPE_OFFER)); } } foreach ($quote->getQuoteProducts() as $quoteProduct) { $unitPrecisions = $quoteProduct->getProduct()->getUnitPrecisions(); $numProductOffers = rand(1, 3); for ($j = 0; $j < $numProductOffers; $j++) { if (!count($unitPrecisions)) { continue; } $productUnit = $unitPrecisions[rand(0, count($unitPrecisions) - 1)]->getUnit(); $currency = $currencies[rand(0, count($currencies) - 1)]; $priceType = $priceTypes[rand(0, count($priceTypes) - 1)]; $quoteProductOffer = new QuoteProductOffer(); $quoteProductOffer->setPrice(Price::create(rand(1, 100), $currency))->setQuantity(rand(1, 100))->setProductUnit($productUnit)->setPriceType($priceType)->setAllowIncrements((bool) rand(0, 1)); if ($quoteProduct->isTypeNotAvailable()) { $productReplacement = $products[rand(1, count($products) - 1)]; $unitPrecisionsRepl = $productReplacement->getUnitPrecisions(); $productUnitRepl = $unitPrecisionsRepl[rand(0, count($unitPrecisionsRepl) - 1)]->getUnit(); $quoteProduct->setProductReplacement($productReplacement); $quoteProductOffer->setProductUnit($productUnitRepl); } $quoteProduct->addQuoteProductOffer($quoteProductOffer); } } }
/** * @return array */ public function getMatchedPricesDataProvider() { $prodUnitQty1 = $this->getProductUnitQuantity(1); $prodUnitQty105 = $this->getProductUnitQuantity(10.5); $prodUnitQty50 = $this->getProductUnitQuantity(50); $prodUnitQty200 = $this->getProductUnitQuantity(200); $prodUnitQty01 = $this->getProductUnitQuantity(0.1); $repositoryData = $this->getRepositoryData($prodUnitQty50); return ['with priceList' => ['productUnitQuantities' => [$prodUnitQty1, $prodUnitQty105], 'currency' => 'USD', 'withPriceList' => true, 'repositoryData' => $repositoryData, 'expectedData' => [$prodUnitQty1->getIdentifier() => null, $prodUnitQty105->getIdentifier() => Price::create(15, 'USD')]], 'without priceList' => ['productUnitQuantities' => [$prodUnitQty50, $prodUnitQty200, $prodUnitQty01], 'currency' => 'USD', 'withPriceList' => false, 'repositoryData' => $repositoryData, 'expectedData' => [$prodUnitQty50->getIdentifier() => Price::create(300, 'USD'), $prodUnitQty200->getIdentifier() => Price::create(1400, 'USD'), $prodUnitQty01->getIdentifier() => null]]]; }
/** * @ORM\PostLoad */ public function postLoad() { if (null !== $this->value && null !== $this->currency) { $this->price = Price::create($this->value, $this->currency); } }
/** * @return array * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function submitProvider() { $quoteProductOffer = $this->getQuoteProductOffer(2, 10, 'kg', self::QPO_PRICE_TYPE1, Price::create(20, 'USD')); return ['empty form' => ['isValid' => false, 'submittedData' => [], 'expectedData' => $this->getQuoteProduct(2)->setProduct(null), 'inputData' => $this->getQuoteProduct(2)->setProduct(null)], 'empty quote' => ['isValid' => false, 'submittedData' => ['product' => 2, 'type' => self::QP_TYPE1, 'comment' => 'comment1', 'commentAccount' => 'comment2', 'quoteProductOffers' => [['quantity' => 10, 'productUnit' => 'kg', 'priceType' => self::QPO_PRICE_TYPE1, 'price' => ['value' => 20, 'currency' => 'USD']]]], 'expectedData' => $this->getQuoteProduct(2, self::QP_TYPE1, 'comment1', 'comment2', [], [clone $quoteProductOffer])->setQuote(null), 'inputData' => $this->getQuoteProduct(2)->setQuote(null)->setProduct(null)], 'empty product' => ['isValid' => false, 'submittedData' => ['type' => self::QP_TYPE1, 'comment' => 'comment1', 'commentAccount' => 'comment2', 'quoteProductOffers' => [['quantity' => 10, 'productUnit' => 'kg', 'priceType' => self::QPO_PRICE_TYPE1, 'price' => ['value' => 20, 'currency' => 'USD']]]], 'expectedData' => $this->getQuoteProduct(2, self::QP_TYPE1, 'comment1', 'comment2', [], [clone $quoteProductOffer])->setProduct(null), 'inputData' => $this->getQuoteProduct(2)->setProduct(null)], 'empty type' => ['isValid' => false, 'submittedData' => ['product' => 2, 'comment' => 'comment1', 'commentAccount' => 'comment2', 'quoteProductOffers' => [['quantity' => 10, 'productUnit' => 'kg', 'priceType' => self::QPO_PRICE_TYPE1, 'price' => ['value' => 20, 'currency' => 'USD']]]], 'expectedData' => $this->getQuoteProduct(2, null, 'comment1', 'comment2', [], [clone $quoteProductOffer]), 'inputData' => $this->getQuoteProduct(2)->setProduct(null)], 'empty offers' => ['isValid' => false, 'submittedData' => ['product' => 2, 'comment' => 'comment1', 'commentAccount' => 'comment2'], 'expectedData' => $this->getQuoteProduct(2, null, 'comment1', 'comment2', [], []), 'inputData' => $this->getQuoteProduct(2)->setProduct(null)], 'valid data' => ['isValid' => true, 'submittedData' => ['product' => 2, 'type' => self::QP_TYPE1, 'comment' => 'comment1', 'commentAccount' => 'comment2', 'quoteProductOffers' => [['quantity' => 10, 'productUnit' => 'kg', 'priceType' => self::QPO_PRICE_TYPE1, 'price' => ['value' => 20, 'currency' => 'USD']]]], 'expectedData' => $this->getQuoteProduct(2, self::QP_TYPE1, 'comment1', 'comment2', [], [clone $quoteProductOffer]), 'inputData' => $this->getQuoteProduct(2)->setProduct(null)]]; }
/** * @return array */ public function formatOfferProvider() { return ['existing product unit and bundled price type' => ['inputData' => ['item' => (new QuoteProductOffer())->setPriceType(QuoteProductOffer::PRICE_TYPE_BUNDLED), 'quantity' => 15, 'unitCode' => 'kg', 'price' => Price::create(10, 'USD'), 'unit' => (new ProductUnit())->setCode('kg')], 'expectedData' => ['formattedUnits' => '15 kilogram', 'formattedPrice' => '10.00 USD', 'formattedUnit' => 'kilogram', 'transConstant' => 'orob2b.sale.quoteproductoffer.item_bundled', 'transIndex' => 0]], 'existing product unit and default price type' => ['inputData' => ['item' => new QuoteProductOffer(), 'quantity' => 15, 'unitCode' => 'kg', 'price' => Price::create(10, 'USD'), 'unit' => (new ProductUnit())->setCode('kg')], 'expectedData' => ['formattedUnits' => '15 kilogram', 'formattedPrice' => '10.00 USD', 'formattedUnit' => 'kilogram', 'transConstant' => 'orob2b.sale.quoteproductoffer.item', 'transIndex' => 0]], 'existing product unit and allowed increments' => ['inputData' => ['item' => (new QuoteProductOffer())->setAllowIncrements(true), 'quantity' => 15, 'unitCode' => 'kg', 'price' => Price::create(10, 'USD'), 'unit' => (new ProductUnit())->setCode('kg')], 'expectedData' => ['formattedUnits' => '15 kilogram', 'formattedPrice' => '10.00 USD', 'formattedUnit' => 'kilogram', 'transConstant' => 'orob2b.sale.quoteproductoffer.item', 'transIndex' => 1]], 'deleted product unit' => ['inputData' => ['item' => new QuoteProductOffer(), 'quantity' => 25, 'unitCode' => 'item', 'price' => Price::create(20, 'EUR'), 'unit' => null], 'expectedData' => ['formattedUnits' => '25 item', 'formattedPrice' => '20.00 EUR', 'formattedUnit' => 'item', 'transConstant' => 'orob2b.sale.quoteproductoffer.item', 'transIndex' => 0]]]; }
/** * @return array */ public function validateDataProvider() { return [[new OrderLineItem(), ['orob2b.order.orderlineitem.product.blank', 'orob2b.order.orderlineitem.product_price.blank']], [(new OrderLineItem())->setProduct(new Product()), 'orob2b.order.orderlineitem.product_price.blank'], [(new OrderLineItem())->setPrice(Price::create(1, 'USD')), 'orob2b.order.orderlineitem.product.blank']]; }
/** * @param string $sku * @param string $unitCode * @param float $qty * @param int $priceType * @param float $priceValue * @param string $priceCurrency * @return OrderLineItem */ protected function createOrderLineItem($sku, $unitCode, $qty, $priceType, $priceValue, $priceCurrency) { $orderLineItem = new OrderLineItem(); $orderLineItem->setProduct((new Product())->setSku($sku))->setProductUnit((new ProductUnit())->setCode($unitCode))->setQuantity($qty)->setPriceType($priceType)->setPrice(Price::create($priceValue, $priceCurrency))->setFromExternalSource(true); return $orderLineItem; }
/** * @param Product $product * @param ProductUnit $productUnit * @param float $quantity * @param string $currency * @param PriceList $priceList * @return Price */ protected function getPrice(Product $product, ProductUnit $productUnit, $quantity, $currency, PriceList $priceList) { $productUnitQuantity = new ProductUnitQuantity($product, $productUnit, $quantity); $identifier = $productUnitQuantity->getIdentifier(); if (!isset($this->prices[$priceList->getId()][$currency][$identifier])) { $prices = $this->productPriceProvider->getMatchedPrices([$productUnitQuantity], $currency, $priceList); $this->prices[$priceList->getId()][$currency][$identifier] = $prices[$identifier]; } $price = $this->prices[$priceList->getId()][$currency][$identifier]; return $price ?: Price::create(mt_rand(10, 1000), $currency); }