263 lines
9.7 KiB
PHP
263 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace Stemcell\Sales\Model\Export;
|
|
|
|
use Magento\Framework\Exception\FileSystemException;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use \PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use PhpOffice\PhpSpreadsheet\Reader\Exception;
|
|
use Magento\Framework\App\ObjectManager;
|
|
use Magento\Framework\Filesystem;
|
|
use Magento\Sales\Model\ResourceModel\Order\Item;
|
|
use Magento\Ui\Component\MassAction\Filter;
|
|
use Magento\Ui\Model\Export\MetadataProvider;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class ConvertToCsv extends \Magento\Ui\Model\Export\ConvertToCsv
|
|
{
|
|
private Item\Collection $itemCollection;
|
|
private Filesystem\DirectoryList $directoryList;
|
|
|
|
public function __construct(
|
|
Filesystem $filesystem,
|
|
Filter $filter,
|
|
MetadataProvider $metadataProvider,
|
|
Item\Collection $itemCollection,
|
|
Filesystem\DirectoryList $directoryList,
|
|
protected LoggerInterface $logger,
|
|
$pageSize = 200
|
|
) {
|
|
parent::__construct($filesystem, $filter, $metadataProvider, $pageSize);
|
|
$this->itemCollection = $itemCollection;
|
|
$this->directoryList = $directoryList;
|
|
}
|
|
|
|
/**
|
|
* @return string[]
|
|
*/
|
|
protected function getHeaders() {
|
|
return [
|
|
'订单编号',
|
|
'订单金额',
|
|
'经销商',
|
|
'销售',
|
|
'下单时间',
|
|
'订单状态',
|
|
'货号',
|
|
'商品名称',
|
|
'经销商价格(¥)',
|
|
'数量',
|
|
'CD号',
|
|
'Quote号',
|
|
'折扣',
|
|
'总金额(¥)',
|
|
'订货账户',
|
|
'账户名称',
|
|
'PI SAP ID',
|
|
// '最终用户单位',
|
|
// 'PI',
|
|
// '最终使用人',
|
|
// '联系电话',
|
|
// '邮箱地址',
|
|
'终端类型',
|
|
'备注',
|
|
'订单备注',
|
|
];
|
|
}
|
|
|
|
protected function getOrderStatusLabel(\Magento\Sales\Model\Order $order)
|
|
{
|
|
try {
|
|
return $order->getStatusLabel();
|
|
} catch (LocalizedException $e) {
|
|
$this->logger->critical(
|
|
sprintf(
|
|
'获取订单:: %s 的status: %s label失败, 原因:%s',
|
|
$order->getIncrementId(),
|
|
$order->getStatus(),
|
|
$e->getMessage()
|
|
)
|
|
);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @param \Magento\Sales\Model\Order\Item $orderItem
|
|
* @param array $fields
|
|
* @return array
|
|
*/
|
|
public function getRowData(\Magento\Sales\Model\Order\Item $orderItem, array $fields): array
|
|
{
|
|
$timezone = ObjectManager::getInstance()->get(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
|
|
$row = [];
|
|
foreach ($fields as $column) {
|
|
|
|
$value = match ($column) {
|
|
'booking_account' => $orderItem->getData('booking_account'),
|
|
'user_type' => $orderItem->getData('user_type') == 0 ? '终端' : '二级经销商',
|
|
'customer_discount_percent' => $this->getCustomerDiscountPercent($orderItem),
|
|
'grand_total' => '¥'.number_format($orderItem->getData('grand_total'), 2),
|
|
'price' => number_format(floatval($orderItem->getPrice()), 2),
|
|
'status' => $this->getOrderStatusLabel($orderItem->getOrder()),
|
|
'row_total' => $this->getRowTotal($orderItem),
|
|
'name' => $orderItem->getProductOptionByCode('simple_name')?? $orderItem->getName(),
|
|
'created_at' => $timezone->date($orderItem->getData($column))->format('Y-m-d H:i:s'),
|
|
default => $orderItem->getData($column),
|
|
};
|
|
if ($value!=null && trim($value)=='-') $value = null;
|
|
$row[] = $value;
|
|
}
|
|
|
|
return $row;
|
|
}
|
|
|
|
protected function getCustomerDiscountPercent(\Magento\Sales\Model\Order\Item $orderItem): string
|
|
{
|
|
$discountPercent = $orderItem->getData('customer_discount_percent');
|
|
return $discountPercent == 0 ? '' : number_format($discountPercent, 2).'%';
|
|
}
|
|
|
|
protected function getRowTotal(\Magento\Sales\Model\Order\Item $orderItem): string
|
|
{
|
|
return number_format($orderItem->getRowTotal(), 2);
|
|
}
|
|
|
|
/**
|
|
* @return Item\Collection
|
|
*/
|
|
protected function getCollection(array $ordersId) {
|
|
$this->itemCollection->addFieldToSelect([
|
|
'sku', 'name', 'qty_ordered', 'row_total', 'cd', 'quote', 'lab_code', 'company', 'user', 'pi', 'pi_sap_id',
|
|
'user_tel', 'user_email', 'note', 'user_type', 'order_id', 'price', 'customer_discount_percent', 'product_options'
|
|
])
|
|
->addFieldToFilter('main_table.order_id', ['in'=>$ordersId])
|
|
->addFieldToFilter('main_table.parent_item_id', ['null' => true])
|
|
->getSelect()
|
|
->join(
|
|
'sales_order',
|
|
'main_table.order_id=sales_order.entity_id',
|
|
[
|
|
'increment_id', 'grand_total', 'customer_firstname', 'created_at', 'status', 'salesperson_id', 'customer_note'
|
|
]
|
|
)
|
|
->joinLeft(
|
|
'salesperson',
|
|
'salesperson.salesperson_id=sales_order.salesperson_id',
|
|
[
|
|
'salesperson_name' => 'salesperson.name'
|
|
|
|
]
|
|
)
|
|
->joinLeft(
|
|
'lab',
|
|
'lab.lab_id=main_table.lab_id',
|
|
[
|
|
'lab_code' => 'lab.lab_code',
|
|
'booking_account' => 'lab.booking_account',
|
|
'pi_sap_id' => 'lab.pi_sap_id',
|
|
]
|
|
);
|
|
|
|
return $this->itemCollection;
|
|
}
|
|
|
|
protected function getFields() {
|
|
return [
|
|
'increment_id', 'grand_total', 'customer_firstname', 'salesperson_name', 'created_at', 'status', 'sku',
|
|
'name', 'price', 'qty_ordered', 'cd', 'quote', 'customer_discount_percent', 'row_total', 'lab_code', 'booking_account', 'pi_sap_id',
|
|
// 'company', 'pi', 'user', 'user_tel', 'user_email',
|
|
'user_type', 'note', 'customer_note'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @throws FileSystemException
|
|
* @throws LocalizedException
|
|
* @throws Exception
|
|
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
|
*/
|
|
public function getCsvFile()
|
|
{
|
|
/* @var $logger LoggerInterface */
|
|
$logger = ObjectManager::getInstance()->get(LoggerInterface::class);
|
|
/* @var $component \Magento\Ui\Component\Listing */
|
|
$component = $this->filter->getComponent();
|
|
|
|
// md5() here is not for cryptographic use.
|
|
// phpcs:ignore Magento2.Security.InsecureFunction
|
|
$name = md5(microtime());
|
|
$file = 'export/'. $component->getName() . $name . '.xlsx';
|
|
|
|
$this->filter->prepareComponent($component);
|
|
$this->filter->applySelectionOnTargetProvider();
|
|
|
|
/* @var $dataProvider \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider */
|
|
$dataProvider = $component->getContext()->getDataProvider();
|
|
$fields = $this->getFields();
|
|
|
|
$this->directory->create('export');
|
|
$filePath = $this->directoryList->getPath('var').'/'.$file;
|
|
$dataProvider->setLimit(0, 100);
|
|
$ordersId = [];
|
|
$items = $dataProvider->getSearchResult()->getItems();
|
|
foreach ($items as $item) {
|
|
/* @var $item \Magento\Framework\View\Element\UiComponent\DataProvider\Document */
|
|
$ordersId[] = $item->getId();
|
|
}
|
|
|
|
$collection = $this->getCollection($ordersId);
|
|
|
|
$dataGroupByOrderId = [];
|
|
foreach ($collection as $item) {
|
|
/* @var $item \Magento\Sales\Model\Order\Item */
|
|
$dataGroupByOrderId[$item->getOrderId()][] = $this->getRowData($item, $fields);
|
|
}
|
|
$styles = [
|
|
'alignment' => [
|
|
'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
|
|
'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
|
|
],
|
|
];
|
|
$rowIndex = 2;
|
|
$spreadSheet = new Spreadsheet();
|
|
$writer = IOFactory::createWriter($spreadSheet, 'Xlsx');
|
|
$worksheet = $spreadSheet->getActiveSheet();
|
|
$columnIndex = 'A';
|
|
foreach ($this->getHeaders() as $row) {
|
|
$cell = $worksheet->getCell($columnIndex.'1');
|
|
$cell->getAppliedStyle()->applyFromArray($styles);
|
|
$cell->setValue($row);
|
|
$columnIndex++;
|
|
}
|
|
$worksheet->getRowDimension(1)->setRowHeight(20);
|
|
krsort($dataGroupByOrderId);
|
|
foreach ($dataGroupByOrderId as $rows) {
|
|
$rowCount = count($rows);
|
|
$mergeColumnsIndex = ['A', 'B', 'C', 'D', 'E', 'F', 'T'];
|
|
foreach ($mergeColumnsIndex as $index) {
|
|
$worksheet->mergeCells($index.$rowIndex.':'.$index.$rowIndex+$rowCount-1);
|
|
}
|
|
foreach ($rows as $row) {
|
|
$columnIndex = 'A';
|
|
foreach ($row as $value) {
|
|
$worksheet->getColumnDimension($columnIndex)->setWidth(15);
|
|
$worksheet->getRowDimension($rowIndex)->setRowHeight(20);
|
|
$cell = $worksheet->getCell($columnIndex.$rowIndex);
|
|
$cell->getAppliedStyle()->applyFromArray($styles);
|
|
$cell->setValue($value);
|
|
$columnIndex++;
|
|
}
|
|
$rowIndex++;
|
|
}
|
|
}
|
|
$writer->save($filePath);
|
|
return [
|
|
'type' => 'filename',
|
|
'value' => $file,
|
|
'rm' => true // can delete file after use
|
|
];
|
|
}
|
|
}
|