Skip to content

Commit

Permalink
Merge branch '2.4-develop' into 2.4-bugfix/date_login_customer_issue3…
Browse files Browse the repository at this point in the history
…0328
  • Loading branch information
engcom-Hotel committed Jan 5, 2021
2 parents a48886c + 427f9bf commit 1afe3db
Show file tree
Hide file tree
Showing 25 changed files with 1,201 additions and 99 deletions.
151 changes: 107 additions & 44 deletions app/code/Magento/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Magento\Bundle\Model\Sales\Order\Pdf\Items;

use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\DataObject;
use Magento\Framework\Filesystem;
use Magento\Framework\Filter\FilterManager;
use Magento\Framework\Model\Context;
Expand Down Expand Up @@ -69,50 +70,52 @@ public function __construct(
}

/**
* Draw item line
* Draw bundle product item line
*
* @return void
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function draw()
{
$order = $this->getOrder();
$item = $this->getItem();
$pdf = $this->getPdf();
$page = $this->getPage();
$draw = $this->drawChildrenItems();
$draw = $this->drawCustomOptions($draw);

$page = $this->getPdf()->drawLineBlocks($this->getPage(), $draw, ['table_header' => true]);

$this->setPage($page);
}

/**
* Draw bundle product children items
*
* @return array
*/
private function drawChildrenItems(): array
{
$this->_setFontRegular();
$items = $this->getChildren($item);

$prevOptionId = '';
$drawItems = [];

foreach ($items as $childItem) {
$line = [];

$optionId = 0;
$lines = [];
foreach ($this->getChildren($this->getItem()) as $childItem) {
$index = array_key_last($lines) !== null ? array_key_last($lines) + 1 : 0;
$attributes = $this->getSelectionAttributes($childItem);
if (is_array($attributes)) {
$optionId = $attributes['option_id'];
} else {
$optionId = 0;
}

if (!isset($drawItems[$optionId])) {
$drawItems[$optionId] = ['lines' => [], 'height' => 15];
}

if ($childItem->getOrderItem()->getParentItem() && $prevOptionId != $attributes['option_id']) {
$line[0] = [
$lines[$index][] = [
'font' => 'italic',
'text' => $this->string->split($attributes['option_label'], 45, true, true),
'feed' => 35,
];

$drawItems[$optionId] = ['lines' => [$line], 'height' => 15];

$line = [];
$index++;
$prevOptionId = $attributes['option_id'];
}

Expand All @@ -124,35 +127,97 @@ public function draw()
$feed = 35;
$name = $childItem->getName();
}
$line[] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed];
$lines[$index][] = ['text' => $this->string->split($name, 35, true, true), 'feed' => $feed];

// draw SKUs
if (!$childItem->getOrderItem()->getParentItem()) {
$text = [];
foreach ($this->string->split($item->getSku(), 17) as $part) {
$text[] = $part;
}
$line[] = ['text' => $text, 'feed' => 255];
}
$lines = $this->drawSkus($childItem, $lines);

// draw prices
if ($this->canShowPriceInfo($childItem)) {
$price = $order->formatPriceTxt($childItem->getPrice());
$line[] = ['text' => $price, 'feed' => 395, 'font' => 'bold', 'align' => 'right'];
$line[] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'font' => 'bold'];
$lines = $this->drawPrices($childItem, $lines);
}
$drawItems[$optionId]['lines'] = $lines;

$tax = $order->formatPriceTxt($childItem->getTaxAmount());
$line[] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right'];
return $drawItems;
}

$row_total = $order->formatPriceTxt($childItem->getRowTotal());
$line[] = ['text' => $row_total, 'feed' => 565, 'font' => 'bold', 'align' => 'right'];
/**
* Draw sku parts
*
* @param DataObject $childItem
* @param array $lines
* @return array
*/
private function drawSkus(DataObject $childItem, array $lines): array
{
$index = array_key_last($lines);
if (!$childItem->getOrderItem()->getParentItem()) {
$text = [];
foreach ($this->string->split($this->getItem()->getSku(), 17) as $part) {
$text[] = $part;
}
$lines[$index][] = ['text' => $text, 'feed' => 255];
}

return $lines;
}

$drawItems[$optionId]['lines'][] = $line;
/**
* Draw prices for bundle product children items
*
* @param DataObject $childItem
* @param array $lines
* @return array
*/
private function drawPrices(DataObject $childItem, array $lines): array
{
$index = array_key_last($lines);
if ($this->canShowPriceInfo($childItem)) {
$lines[$index][] = ['text' => $childItem->getQty() * 1, 'feed' => 435, 'align' => 'right'];

$tax = $this->getOrder()->formatPriceTxt($childItem->getTaxAmount());
$lines[$index][] = ['text' => $tax, 'feed' => 495, 'font' => 'bold', 'align' => 'right'];

$item = $this->getItem();
$this->_item = $childItem;
$feedPrice = 380;
$feedSubtotal = $feedPrice + 185;
foreach ($this->getItemPricesForDisplay() as $priceData) {
if (isset($priceData['label'])) {
// draw Price label
$lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right'];
// draw Subtotal label
$lines[$index][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right'];
$index++;
}
// draw Price
$lines[$index][] = [
'text' => $priceData['price'],
'feed' => $feedPrice,
'font' => 'bold',
'align' => 'right',
];
// draw Subtotal
$lines[$index][] = [
'text' => $priceData['subtotal'],
'feed' => $feedSubtotal,
'font' => 'bold',
'align' => 'right',
];
$index++;
}
$this->_item = $item;
}

// custom options
$options = $item->getOrderItem()->getProductOptions();
return $lines;
}

/**
* Draw bundle product custom options
*
* @param array $draw
* @return array
*/
private function drawCustomOptions(array $draw): array
{
$options = $this->getItem()->getOrderItem()->getProductOptions();
if ($options && isset($options['options'])) {
foreach ($options['options'] as $option) {
$lines = [];
Expand Down Expand Up @@ -180,12 +245,10 @@ public function draw()
$lines[][] = ['text' => $text, 'feed' => 40];
}

$drawItems[] = ['lines' => $lines, 'height' => 15];
$draw[] = ['lines' => $lines, 'height' => 15];
}
}

$page = $pdf->drawLineBlocks($page, $drawItems, ['table_header' => true]);

$this->setPage($page);
return $draw;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items;

use Magento\Bundle\Model\Sales\Order\Pdf\Items\Invoice;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\DataObject;
use Magento\Framework\Filesystem;
use Magento\Framework\Filter\FilterManager;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Stdlib\StringUtils;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Pdf\Invoice as InvoicePdf;
use Magento\Tax\Helper\Data;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Zend_Pdf_Page;

/**
* Covers bundle order item invoice print logic
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class InvoiceTest extends TestCase
{
/**
* @var Invoice|MockObject
*/
private $model;

/**
* @var Data|MockObject
*/
private $taxDataMock;

/**
* @inheritdoc
*/
protected function setUp(): void
{
$contextMock = $this->createMock(Context::class);
$registryMock = $this->createMock(Registry::class);
$this->taxDataMock = $this->createMock(Data::class);
$directoryMock = $this->createMock(Filesystem\Directory\Read::class);
$directoryMock->expects($this->any())->method('getAbsolutePath')->willReturn('');
$filesystemMock = $this->createMock(Filesystem::class);
$filesystemMock->expects($this->any())->method('getDirectoryRead')->willReturn($directoryMock);
$filterManagerMock = $this->createMock(FilterManager::class);
$stringUtilsMock = $this->createMock(StringUtils::class);
$stringUtilsMock->expects($this->any())->method('split')->willReturnArgument(0);
$resourceMock = $this->createMock(AbstractResource::class);
$collectionMock = $this->createMock(AbstractDb::class);
$serializerMock = $this->createMock(Json::class);

$this->model = $this->getMockBuilder(Invoice::class)
->setConstructorArgs(
[
$contextMock,
$registryMock,
$this->taxDataMock,
$filesystemMock,
$filterManagerMock,
$stringUtilsMock,
$serializerMock,
$resourceMock,
$collectionMock,
[],
]
)
->onlyMethods(
[
'_setFontRegular',
'getChildren',
'isShipmentSeparately',
'isChildCalculated',
'getValueHtml',
'getSelectionAttributes',
]
)
->getMock();
}

/**
* @dataProvider \Magento\Bundle\Test\Unit\Model\Sales\Order\Pdf\Items\InvoiceTestProvider::getData
* @param array $expected
* @param string $method
*/
public function testDrawPrice(array $expected, string $method): void
{
$this->taxDataMock->expects($this->any())->method($method)->willReturn(true);
$pageMock = $this->createMock(Zend_Pdf_Page::class);
$this->model->setPage($pageMock);
$pdfMock = $this->createMock(InvoicePdf::class);
$pdfMock->expects($this->any())->method('drawLineBlocks')->with(
$pageMock,
$expected,
['table_header' => true]
)->willReturn($pageMock);
$this->model->setPdf($pdfMock);

$this->prepareModel();
$this->model->draw();
}

/**
* Prepare invoice draw model for test execution
*
* @return void
*/
private function prepareModel(): void
{
$parentItem = new DataObject(
[
'sku' => 'bundle-simple',
'name' => 'Bundle',
'order_item' => new DataObject(
[
'product_options' => [],
]
),
]
);
$items = [
new DataObject(
[
'name' => 'Simple1',
'sku' => 'simple1',
'price' => '10.00',
'price_incl_tax' => '10.83',
'row_total' => '20.00',
'row_total_incl_tax' => '21.66',
'qty' => '2',
'tax_amount' => '1.66',
'order_item' => new DataObject(
[
'parent_item' => $parentItem,
]
),
]
),
new DataObject(
[
'name' => 'Simple2',
'sku' => 'simple2',
'price' => '5.00',
'price_incl_tax' => '5.41',
'row_total' => '10.00',
'row_total_incl_tax' => '10.83',
'qty' => '2',
'tax_amount' => '0.83',
'order_item' => new DataObject(
[
'parent_item' => $parentItem,
]
),
]
),
];
$orderMock = $this->createMock(Order::class);

$this->model->expects($this->any())->method('getChildren')->willReturn($items);
$this->model->expects($this->any())->method('isShipmentSeparately')->willReturn(false);
$this->model->expects($this->any())->method('isChildCalculated')->willReturn(true);
$this->model->expects($this->at(2))->method('getSelectionAttributes')->willReturn(
['option_id' => 1, 'option_label' => 'test option']
);
$this->model->expects($this->at(3))->method('getValueHtml')->willReturn($items[0]->getName());
$this->model->expects($this->at(5))->method('getSelectionAttributes')->willReturn(
['option_id' => 1, 'option_label' => 'second option']
);
$this->model->expects($this->at(6))->method('getValueHtml')->willReturn($items[1]->getName());

$orderMock->expects($this->any())->method('formatPriceTxt')->willReturnArgument(0);
$this->model->setOrder($orderMock);
$this->model->setItem($parentItem);
}
}
Loading

0 comments on commit 1afe3db

Please sign in to comment.