<?php declare(strict_types=1);
namespace NrbnImportCsv\Storefront\Controller;
use Exception;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItemFactoryRegistry;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Storefront\Page\Account\Overview\AccountOverviewPageLoader;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* @RouteScope(scopes={"storefront"})
*/
class ImportCsvController extends StorefrontController
{
/**
* @var LineItemFactoryRegistry
*/
private LineItemFactoryRegistry $factory;
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $productRepository;
/**
* @var CartService
*/
private CartService $cartService;
/**
* @var AccountOverviewPageLoader
*/
private AccountOverviewPageLoader $overviewPageLoader;
/**
* @var string
*/
private string $productErr = "";
public function __construct(
LineItemFactoryRegistry $factory,
CartService $cartService,
EntityRepositoryInterface $productRepository,
AccountOverviewPageLoader $overviewPageLoader
){
$this->factory = $factory;
$this->cartService = $cartService;
$this->productRepository = $productRepository;
$this->overviewPageLoader = $overviewPageLoader;
}
/**
* @Route("/account/importcsv", name="frontend.netz_reform_import_csv.upload", methods={"GET", "POST"})
* @return Response
*/
public function upload(Request $request, SalesChannelContext $context) : Response
{
$submitBtn = $request->request->get("submit");
if($submitBtn) {
$file = $request->files->get("upload_file");
if(
$file &&
($file->getMimeType() === 'text/csv' || $file->getMimeType() === "text/plain")
){
$this->importFile($file, $context);
return $this->redirectToRoute("frontend.checkout.cart.page");
}
}
$page = $this->overviewPageLoader->load($request, $context, $context->getCustomer());
return $this->renderStorefront("@NrbnImportCsv/storefront/page/import.html.twig",
['error'=>$this->productErr,'page'=>$page]
);
}
/**
* @Route("/account/exportcsv",name="frontend.netz_reform_import_csv.export", methods={"GET"})
* @param Cart $cart
* @param SalesChannelContext $context
* @return void
*/
public function exportFile(Cart $cart, SalesChannelContext $context) {
if($cart){
$file = fopen("php://output", "w");
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename=cart.csv;');
$lineItems = $cart->getLineItems();
foreach ($lineItems as $lineItem){
$product["productNr"] = $lineItem->getPayload()["productNumber"];
$product["quantity"] = $lineItem->getQuantity();
fputcsv($file, $product, ";");
}
die();
}
}
/**
* @param $file
* @param $context
* @return bool|string
*/
private function importFile($file, $context) {
if (!is_file($file->getPathname())) {
return $this->productErr = "File not found!";
}
if($file->getMimeType() === 'text/csv' || $file->getMimeType() === "text/plain") {
$csv = $file->getPathname();
if (($handle = fopen($csv, "r")) !== false) {
while (($data = fgetcsv($handle, 0, ";")) !== false) {
$orderNumber = trim($data[0]);
$quantity = trim($data[1]);
try {
$this->addProductToCart($this->cartService->getCart($context->getToken(), $context), $context, $orderNumber, (int) $quantity);
} catch (Exception $e) {
fclose($handle);
throw new Exception($e->getMessage());
}
}
fclose($handle);
}
}
return true;
}
private function addProductToCart(Cart $cart, SalesChannelContext $context, $productNr, int $quantity = 1)
{
// Create product line item
try {
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter("productNumber", $productNr)
);
$product = $this->productRepository->search($criteria, $context->getContext())->first();
$checkBasket = false;
if($product){
$isInBasket = $cart->getLineItems()->filterType(LineItem::PRODUCT_LINE_ITEM_TYPE);
$checkBasket = $this->checkCart($cart, $isInBasket, $product, $quantity, $context);
}
if(
!$checkBasket &&
$product &&
$quantity > 0
) {
$lineItem = $this->factory->create([
'id' => $product->getId(),
'type' => LineItem::PRODUCT_LINE_ITEM_TYPE,
'referencedId' => $product->getId(),
'quantity' => $quantity
], $context);
$this->cartService->add($cart, $lineItem, $context);
} elseif(!$checkBasket) {
$this->productErr .= "Product with " . $productNr . " not found <br>";
}
} catch(\Exception $e) {
}
}
private function checkCart($cart, $isInBasket, $product, $quantity, $context){
foreach ($isInBasket as $basket){
if($basket->getReferencedId() == $product->getId()){
$newQuantity = $basket->getQuantity() + $quantity;
$this->cartService->changeQuantity($cart, $basket->getId(), $newQuantity, $context);
return true;
}
}
return false;
}
}