<?php
namespace App\AppBundle\Services;
use App\AppBundle\Annotations\Frontend;
use App\AppBundle\Annotations\Import;
use App\AppBundle\Annotations\Validation;
use App\AppBundle\Entity\ImportData;
use App\AppBundle\Entity\MvMycmMyamsCustomer;
use App\AppBundle\Entity\MvMycmMyamsDealerGroup;
use App\AppBundle\Entity\PSD_Action;
use App\AppBundle\Entity\PSD_Customer;
use App\AppBundle\Entity\PSD_Customer_Park;
use App\AppBundle\Entity\PSD_Customer_Park_Import;
use App\AppBundle\Entity\PSD_Customer_Type;
use App\AppBundle\Entity\PSD_Sellout;
use App\AppBundle\Entity\PSD_Vehicle_Type;
use App\AppBundle\Entity\PSD_Visit_Frequency;
use App\AppBundle\Entity\Sellout;
use App\AppBundle\Entity\User;
use App\AppBundle\Entity\UserImportHeader;
use App\AppBundle\Entity\UserImportSettings;
use App\AppBundle\Other\Constants;
use App\AppBundle\Repository\ImportDataRepository;
use DateTime;
use DateTimeZone;
use App\AppBundle\Repository\UserRepository;
use Coolshop\CoolJobBundle\Entity\JobLog;
use Coolshop\CoolJobBundle\Service\CommandAdapter;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query;
use Doctrine\Persistence\Mapping\MappingException;
use Exception;
use HttpException;
use ReflectionClass;
use ReflectionException;
use ReflectionProperty;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException as ExceptionHttpException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
ini_set('memory_limit', '2048M');
class ImportService {
private array $metadata = [];
protected ?SymfonyStyle $io = null;
protected EntityManager $em;
private ImportData $importData;
private string $type;
private array $customers = [];
private array $annotations = [];
private $customerRepo;
private array $cachedOptions = [];
private Container $container;
private $translator;
const CLASS_TYPES = array(
ImportData::TYPE_CUSTOMER => PSD_Customer::class,
ImportData::TYPE_SELLOUT => PSD_Sellout::class,
ImportData::TYPE_CUSTOMER_PARK => PSD_Customer_Park_Import::class,
);
public function __construct(
EntityManagerInterface $em,
ContainerInterface $container,
private MessageBusInterface $messageBus,
) {
$this->em = $em;
$this->annotations[] = Import::class;
$this->container = $container;
$this->customerRepo = $em->getRepository(PSD_Customer::class);
$this->translator = $this->container->get('translator');
}
public function setIO(InputInterface $input, OutputInterface $output)
{
$this->io = new SymfonyStyle($input, $output);
}
public function loadImportData(int $id, User $user, string $type):ImportService {
return $this->setImportData($this->em->getRepository(ImportData::class)->findOneBy([
"id" => $id,
"type" => $type,
"createdBy" => $user,
]));
}
public function setImportData(ImportData $importData):ImportService {
$this->importData = $importData;
$this->type = $importData->getType();
return $this;
}
public function setType(string $type):ImportService {
$this->type = $type;
return $this;
}
/**
* @throws OptimisticLockException
* @throws ORMException
* @throws MappingException
* @throws Exception
*/
public function import($importDataId)
{
$this->io->writeln([
"ImportData: #$importDataId",
"Start",
]);
$importDataRepository = $this->em->getRepository(ImportData::class);
$this->setImportData($importDataRepository->find($importDataId));
switch($this->type)
{
case ImportData::TYPE_CUSTOMER:
$this->importCustomer();
break;
case ImportData::TYPE_SELLOUT:
$this->importSellout();
break;
case ImportData::TYPE_CUSTOMER_PARK:
$this->importCustomerPark();
break;
}
$this->io->writeln("End");
}
/**
* @throws OptimisticLockException
* @throws ORMException
* @throws MappingException
* @throws Exception
*/
private function importCustomer() {
$this->io->writeln("Type: customer");
$this->io->writeln("Start at: ".$this->getDateTimeNow()->format("d/m/Y H:i:s"));
$customerRepository = $this->em->getRepository(PSD_Customer::class);
$data = $this->importData->getData();
$metadata = array_filter($this->getMetadata(), function ($value) { return !is_null($value["extra"]); });
$dmsCodes = array_column($data, 'dmsCode');
$info = $this->em
->getRepository(MvMycmMyamsDealerGroup::class)
->findOneBy(["cdDealerGroup" => $this->importData->getDealerGroup()]);
$isConnected = isset($info) && $info->getCdConnected();
$customers = $customerRepository->findByDealerGroupAndDmsCodes($this->importData->getDealerGroup(),$dmsCodes,$isConnected);
foreach($data as $i => $row) {
$customer = $customers[$isConnected ? sprintf('%08s', $row["dmsCode"]) : $row["dmsCode"]] ?? null;
if(is_null($customer)) {
$customer = PSD_Customer::fromArray([
"dmsCode" => $row["dmsCode"],
"dealerGroup" => $this->importData->getDealerGroup(),
"isConnected" => $isConnected
]);
}
$row["dmsCode"] = $isConnected ? sprintf('%08s', $row["dmsCode"]) : $row["dmsCode"];
// handle mappedBy attribute (any way to do it better??)
$row["dealerCode"] = $row["dmsDealerBranch"];
unset($row["dmsDealerBranch"]);
$customer->setFromArray($row);
$this->em->persist($customer);
$this->em->flush();
if($i && $i%50==0) {
$this->io->writeln("Insert: ".$i);
gc_collect_cycles();
}
$row = null;
$customer = null;
}
// if(in_array($_ENV['APP_ENV'], ['qua', 'dev'])){
// $message = new CommandAdapter('cool:psd_customer:process',['dealerships' => [$this->importData->getDealerGroup()]],User::class, '-1');
// $this->messageBus->dispatch($message);
// }
$this->em->flush();
$this->em->clear();
$this->io->writeln("Insert: ".count($data));
$this->io->writeln("End at: ".$this->getDateTimeNow()->format("d/n/Y H:i:s"));
}
/**
* @throws OptimisticLockException
* @throws ORMException
* @throws MappingException
* @throws Exception
*/
private function importCustomerPark(){
$this->io->writeln("Type: customer parks");
$this->io->writeln("Start at: ".$this->getDateTimeNow()->format("d/m/Y H:i:s"));
$data = $this->importData->getData();
$customerRepository = $this->em->getRepository(PSD_Customer::class);
$metadata = array_filter($this->getMetadata(), function ($value) { return !is_null($value["extra"]); });
$dmsCodes = array_column($data, 'dmsCode');
$info = $this->em
->getRepository(MvMycmMyamsDealerGroup::class)
->findOneBy(["cdDealerGroup" => $this->importData->getDealerGroup()]);
$isConnected = isset($info) && $info->getCdConnected();
$customers = $customerRepository->findByDealerGroupAndDmsCodes($this->importData->getDealerGroup(),$dmsCodes,$isConnected);
$customerParkRepository = $this->em->getRepository(PSD_Customer_Park::class);
$customersIds = array_reduce($customers, function($acc, $c) {
$acc[] = $c->getId();
return $acc;
}) ?? array();
$customerParks = $customerParkRepository->findOneByCustomerAndVehicleTypeAndCurrentYear($customersIds);
$currentCustomerParks = empty($customerParks) ? $customerParkRepository->getCurrentCustomerParkByCustomerIds($customersIds) : null;
unset($customersIds);
$this->io->writeln("Customer Park fetched ".$this->getDateTimeNow()->format("d/m/Y H:i:s"));
$vehicleTypes = [];
foreach ($metadata as $value){
$vehicleTypes[$value["extra"]] = $this->em->getReference(PSD_Vehicle_Type::class, $value["extra"]);
}
$newVehicles = 0;
$modifiedVehicles = 0;
foreach($data as $row) {
$customer = $customers[$isConnected ? sprintf('%08s', $row["dmsCode"]) : $row["dmsCode"]] ?? null;
foreach ($metadata as $key => $value) {
$customerPark = isset($customers) ? $customerParks[$customer->getId()."_".$value["extra"]] ?? null : null;
if(isset($row[$key]) && $row[$key] != ""){
if(is_null($customerPark)) {
$this->insertOrUpdateCustomerPark(true,$customerPark,$customer,$vehicleTypes[$value["extra"]],$row[$key]);
$newVehicles++;
}else{
$this->insertOrUpdateCustomerPark(false,$customerPark,$customer,$vehicleTypes[$value["extra"]],$row[$key]);
$modifiedVehicles++;
}
}else if(isset($row[$key])) {
$currentPark = isset($customers) ? $currentCustomerParks[$customer->getId()."_".$value["extra"]] ?? null : null;
if(is_null($currentPark) && is_null($customerPark)) {
$this->insertOrUpdateCustomerPark(true,$currentPark,$customer,$vehicleTypes[$value["extra"]],0);
$newVehicles++;
}else {
$currentPark
? $this->insertOrUpdateCustomerPark(true,$currentPark,$customer,$vehicleTypes[$value["extra"]],$currentPark->getNumberOfvehicles())
: $this->insertOrUpdateCustomerPark(false,$customerPark,$customer,$vehicleTypes[$value["extra"]],$customerPark->getNumberOfvehicles());
$modifiedVehicles++;
}
}
unset($row[$key]);
}
}
$this->em->flush();
$this->em->clear();
$this->io->writeln("Insert ".$newVehicles." new Vehicles");
$this->io->writeln("Modified ".$modifiedVehicles." Vehicles");
$this->io->writeln("End at: ".$this->getDateTimeNow()->format("d/n/Y H:i:s"));
}
private function insertOrUpdateCustomerPark($isInsert, $customerPark, $customer, $vehicleType, $numberOfVehicle = null){
if($isInsert){
$customerPark = PSD_Customer_Park::fromArray([
"customer" => $customer,
"vehicleType" => $vehicleType,
"year" => date("Y"),
"numberOfVehicles" => $numberOfVehicle,
]);
}else{
$customerPark->setFromArray(["numberOfVehicles" => $numberOfVehicle]);
}
$this->em->persist($customerPark);
}
private function addCustomer(string $customerDmsCode):ImportService {
$this->customers[$customerDmsCode] = $this->customers[$customerDmsCode] ?? null;
return $this;
}
private function syncCustomers():ImportService {
$this->io->writeln("sync customers");
$customerRepo = $this->em->getRepository(PSD_Customer::class);
$customerDmsCodes = [];
$customer = null;
$customerCode = null;
foreach($this->customers as $customerCode => $customer) {
if(is_null($customer)) {
$customerDmsCodes[] = $customerCode;
}else{
$this->em->persist($customer);
}
}
if(count($customerDmsCodes) > 0) {
$this->io->writeln("load ".count($customerDmsCodes)." customers");
foreach($customerRepo->findBy(["dmsCode" => $customerDmsCodes]) as $customer) {
$this->customers[$customer->getDmsCode()] = $customer;
}
}
foreach($this->customers as $customerCode => $customer) {
if(is_null($customer)) {
$this->em->persist($this->customers[$customerCode] = PSD_Customer::fromArray([
"dmsCode" => $customerCode,
"dealerGroup" => $this->importData->getDealerGroup(),
]));
}
}
// $this->em->flush();
unset($customerRepo);
unset($customerDmsCodes);
unset($customer);
unset($customerCode);
return $this;
}
private function getCustomer(string $customerDmsCode):PSD_Customer {
if(isset($this->customers[$customerDmsCode]) && !is_null($this->customers[$customerDmsCode])) return $this->customers[$customerDmsCode];
throw new Exception("Customer not loaded: $customerDmsCode");
}
/**
* @throws ORMException
* @throws MappingException
* @throws OptimisticLockException
*/
private function importSellout() {
$this->io->writeln("Type: sellout");
$this->io->writeln("Start at: ".$this->getDateTimeNow()->format("d/m/Y H:i:s"));
$selloutRepository = $this->em->getRepository(PSD_Sellout::class);
$customerRepository = $this->em->getRepository(PSD_Customer::class);
$data = $this->importData->getData();
$startAt = $this->getDateTimeNow();
$dates = [];
$this->io->writeln("Data validation...");
foreach($this->validateRows() as $indexRow => $row) {
foreach($row as $column => $error) {
if($error !== "") throw new Exception("Data not valid: #$indexRow ($column)");
}
}
$this->io->writeln("Validated");
foreach($data as $i => $row) {
$data[$i] = $this->remapProperties($row);
}
$this->em->getConfiguration()->setSQLLogger(null);
// $dmsCodes = [];
foreach($data as $i => $row) {
// if (in_array($row["customerDmsCode"], $dmsCodes)) {
// continue;
// } else {
// $dmsCodes[] = $row["customerDmsCode"];
// }
$customer = $customerRepository->findOneByDmsCodeAndDealerGroup($row["customerDmsCode"], $this->importData->getDealerGroup());
if(is_null($customer)) {
$customer = PSD_Customer::fromArray([
"dmsCode" => $row["customerDmsCode"],
"dealerGroup" => $this->importData->getDealerGroup(),
]);
$this->em->persist($customer);
}
// handle dms code
$row["cdCustomer"] = $row["customerDmsCode"];
unset($row["customerDmsCode"]);
$row["customer"] = $customer;
$row["totalInvoicedValue"] = floatval(str_replace(',', '.', (string) $row['totalInvoicedValue']));
$row["invoiceDate"] = $this->getDateTime("d/m/Y", $row["invoiceDate"]);
$row["year"] = (int) $row["invoiceDate"]->format('Y');
$row["month"] = (int) $row["invoiceDate"]->format('m');
$row["dealerGroup"] = $this->importData->getDealerGroup();
// fill codes
$row["channel"] = strtoupper($row["channelCode"]);
$row["cdChannel"] = strtoupper($row["channelCode"]);
unset($row["channelCode"]);
$row["cdWarranty"] = "Z"; //$this->getWarrantyCode($row["warranty"]);
$dates[$row["invoiceDate"]->format("Ym")] = $row["invoiceDate"];
$this->em->persist(PSD_Sellout::fromArray($row));
$this->em->flush();
$this->em->clear();
if($i && $i%1000==0) {
$this->io->writeln("Insert: ".$i);
}
$data[$i] = null;
$i = null;
$row = null;
$customer = null;
gc_collect_cycles();
}
$this->io->writeln("Insert: ".count($data));
// if(in_array($_ENV['APP_ENV'], ['qua', 'dev'])){
// $message = new CommandAdapter('cool:psd_customer:process',['dealerships' => [$this->importData->getDealerGroup()]],User::class, '-1');
// $this->messageBus->dispatch($message);
// }
$this->em->flush();
$this->em->clear();
$this->io->writeln("Delete months...");
foreach($selloutRepository->deleteBefore($startAt, $dates, $this->importData->getDealerGroup()) as $result) {
$this->io->writeln($result[0]->format("m/Y")." [".($result[1]?"v":" ")."]");
}
$this->io->writeln("End at: ".$this->getDateTimeNow()->format("d/n/Y H:i:s"));
}
function memory($size) {
return @round($size/pow(1024,floor(log($size,1024))),2).' '.["b","kb","mb","gb","tb","pb"][floor(log($size,1024))];
}
private function getDateTimeNow():DateTime {
return $this->getDateTime("U.u", sprintf('%.6F', microtime(true)));
}
private function getDateTime(string $format, string $datetime):DateTime {
$datetimeReturn = DateTime::createFromFormat($format, $datetime);
$datetimeReturn->setTimezone(new DateTimeZone(date_default_timezone_get()));
return $datetimeReturn;
}
public function getColumns($user) {
$userImportHeaderRepository = $this->em->getRepository(UserImportHeader::class);
$metadata = array_values($this->getMetadata());
$indexedHeaders = $userImportHeaderRepository->findByUserTypeIndexed($user, $this->type);
return array_map(function ($property) use($indexedHeaders) {
$property["userFieldName"] = isset($indexedHeaders[$property["fieldName"]])? $indexedHeaders[$property["fieldName"]]["headerUser"]: "";
return $property;
}, $metadata);
}
public function getIndexedUserColumns($user) {
$columns = [];
foreach($this->getColumns($user) as $column) {
if($column["userFieldName"] != "") {
$columns[$column["userFieldName"]] = $column["fieldName"];
}
}
return $columns;
}
public function addAnnotation(string $annotation):self {
$this->metadata = [];
if(!in_array($annotation, $this->annotations)) $this->annotations[] = $annotation;
return $this;
}
public function removeAnnotation(string $annotation):self {
$this->annotations = array_filter($this->annotations, function($item) use($annotation) {
return $item != $annotation;
});
return $this;
}
public function getMetadata(array $filters = [], ?string $fieldMap = null):array {
$meta = $this->calculateMetadata(self::CLASS_TYPES[$this->type], $filters, $fieldMap);
return $meta;
}
public function calculateMetadata($class, array $filters = [], ?string $fieldMap = null):array {
$metadata = [];
if(!empty($this->metadata[$class])) {
$metadata = $this->metadata[$class];
}else{
$classMetadata = $this->em->getClassMetadata($class);
$reader = new AnnotationReader();
$reflectionClass = $classMetadata->getReflectionClass();
foreach($this->annotations as $annotation) {
$reflection = $reader->getClassAnnotation($reflectionClass, $annotation) ?? new $annotation();
$metadata = $reflection->decorateMetadata($metadata, $this->em, $class);
}
$this->metadata[$class] = $metadata;
}
if(!empty($filters)) {
foreach($metadata as $fieldName => $meta) {
foreach($filters as $key => $value) {
if($meta[$key] !== $value) {
unset($metadata[$fieldName]);
break;
}
}
}
}
uasort($metadata , function($m1, $m2) {
return $m1["position"] > $m2["position"];
});
if(!is_null($fieldMap)) {
$metadata = array_values(array_map(function($meta) use($fieldMap) {
return $meta[$fieldMap];
}, $metadata));
}
return $metadata;
}
public function existsInternalColumn($internal) {
return isset($this->getMetadata()[$internal]);
}
public function convertToInternalColumns() {
$columns = $this->getIndexedUserColumns($this->importData->getCreatedBy());
$data = $this->importData->getData();
$columnNames = array_keys($columns);
foreach($data as $index => $row) {
foreach($row as $key => $value) {
if(in_array($key, $columnNames)) {
$data[$index][$columns[$key]] = $value;
}
unset($data[$index][$key]);
}
}
$this->importData->setData($data);
return $this->importData;
}
private function getIndexData(array $keys, array $row) {
return implode("", array_map(function($key) use($row) {
return $row[$key];
}, $keys));
}
public function validateRows($isEdit = null): array {
$errors = [];
$rows = $this->importData->getData();
$metadata = [];
if(count($rows) > 0){
foreach ($rows[0] as $column => $value){
$metadata[$column] = $this->getColumnMetadata($column);
}
}
foreach($rows as $id => $row) {
$errColumns = [];
foreach($row as $column => $value) {
$errColumns[$column] = $this->testColumn($column, $value, $metadata[$column], $id, $isEdit);
}
$errors[$id] = $errColumns;
}
return $errors;
}
/**
* @throws Exception
*/
public function testColumn(string $column, $value, $metadata = null, $indexRow = null, $isEdit = false):string {
if($column == "dmsCode" && $this->importData->getType() == ImportData::TYPE_CUSTOMER_PARK && !$this->customerRepo->checkCustomerExists($this->importData->getDealerGroup(),$value))
{
if(!$isEdit)
{
$row = $indexRow + 2;
throw new BadRequestHttpException("Provided dmsCode on line #$row ($column) is not related to any customer");
}
return "There is no customer with this dmsCode";
}
if(!isset($metadata))
$metadata = $this->getColumnMetadata($column);
if(isset($metadata["extra"]) && $this->importData->getType() == ImportData::TYPE_CUSTOMER_PARK){
return preg_match("/^(\d+)?$/", $value) !== 1 ? "Not castable to target type." : "";
}
if(($metadata["unique"] ?? false) && !$this->isUnique($column, $value)) return "Field not unique";
if($value === "" && !$metadata["nullable"] && !$metadata["hasDefault"]) return "Empty field not nullable";
if($value !== "" && !empty($metadata["regex"]) && preg_match($metadata["regex"], $value) !== 1) {
if($metadata["label"])
return $this->translator->trans($metadata["label"]);
return "Did not pass validation";
}
switch($metadata["type"]) {
case "text":
$metadata["type"] = "string";
case "string":
if(!is_null($metadata["length"]) && strlen($value) > $metadata["length"]) return "Too long.";
break;
case "datetime":
// todo: get format from table
if(preg_match("/^((0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/(\d{4}))*$/", $value) !== 1) return "Not castable to target type.";
break;
case "boolean":
if(preg_match("/^[01]?$/", $value) !== 1) return "Not castable to target type.";
break;
case "integer":
case "int":
if(preg_match("/^(-?\d+)?$/", $value) !== 1) return "Not castable to target type.";
if($value !== "" && is_null($metadata["extra"]) && $metadata["options"] && !in_array(intval($value), $this->findOptions($metadata["options"]))) return "Not in options.";
break;
case "float":
if(preg_match("/^(-?\d+([,.]\d+)?)?$/", $value) !== 1) return "Not castable to target type.";
break;
default:
if(!settype($value, $metadata["type"])) return "Not castable to target type.";
break;
}
return "";
}
public function setCell(int $row, string $column, $value):ImportData {
$data = $this->importData->getData();
$data[$row][$column] = $value;
$this->importData->setData($data);
return $this->importData;
}
public function getImportData():ImportData {
return $this->importData;
}
public function removeRow($row):void {
$data = $this->importData->getData();
unset($data[$row]);
$this->importData->setData($data);
}
public function removeErrors() {
$data = $this->importData->getData();
$errors = $this->validateRows(true);
foreach($errors as $row => $columns) {
foreach($columns as $error) {
if($error !== "") {
unset($data[$row]);
break;
}
}
}
$this->importData->setData($data);
}
private function getColumnMetadata(string $column):array {
if(isset($this->getMetadata()[$column])) return $this->getMetadata()[$column];
foreach($this->getMetadata() as $meta) {
if($meta["mappedBy"] === $column) return $meta;
}
throw new ExceptionHttpException("Column not found: $column");
}
private function remapProperties($row) {
$result = [];
foreach($row as $column => $meta) {
$metadata = $this->getColumnMetadata($column);
$result[$metadata["mappedBy"]] = $meta;
}
return $result;
}
public function getHeaders():array {
$headers = [];
$metadata = $this->getMetadata();
usort($metadata , function($h1, $h2) {
return $h1["position"] > $h2["position"];
});
foreach($metadata as $meta) {
if($meta["exclude"]) continue;
$headers[] = $meta["mappedBy"];
}
return $headers;
}
public function getIncludedMetadata():array {
$metadata = [];
foreach($this->getMetadata() as $key => $meta) {
if($meta["exclude"]) continue;
$metadata[$key] = $meta;
}
return $metadata;
}
public function getExposeName():string {
$reader = new AnnotationReader();
$classReflection = new ReflectionClass(self::CLASS_TYPES[$this->type]);
$frontendAnnotation = $reader->getClassAnnotation($classReflection, Frontend::class) ?? new Frontend();
return $frontendAnnotation->getExposeAs();
}
public function removeFrontendColumns():ImportData {
$data = $this->importData->getData();
foreach($data as $row => $rowData) {
foreach($rowData as $column => $value) {
if($this->isFrontendColumn($column)) {
unset($data[$row][$column]);
}
}
}
return $this->importData->setData($data);
}
public function isFrontendColumn(string $column):bool {
return $this->getColumnMetadata($column)["privacy"] === Frontend::PRIVACY_FRONTEND;
}
private function findOptions($options):array {
$optionsKey = implode($options, "-");
if(isset($this->cachedOptions[$optionsKey])) return $this->cachedOptions[$optionsKey];
if($options) if(class_exists($options[0])) {
$repository = $this->em->getRepository($options[0]);
if(isset($options[1])) $this->cachedOptions[$optionsKey] = $repository->{$options[1]}();
else $this->cachedOptions[$optionsKey] = array_column($repository->createQueryBuilder("e")->select("e.id")->getQuery()->getScalarResult(), "id");
} else if(is_callable($options[0])) {
$this->cachedOptions[$optionsKey] = $options[0]();
} else if(defined($options[0])) {
$this->cachedOptions[$optionsKey] = constant($options[0]);
}
return $this->cachedOptions[$optionsKey];
}
private function isUnique(string $column, $value):bool {
$count = 0;
foreach($this->getImportData()->getData() as $row) {
if($row[$column] == $value) $count++;
if($count > 1) return false;
}
return true;
}
private function getChannelCode(string $channel) : string
{
return array_key_exists($channel, Constants::CHANNELS) ? Constants::CHANNELS[$channel] : "X";
}
private function getWarrantyCode(string $warranty) : string
{
return array_key_exists($warranty, Constants::WARRANTIES) ? Constants::WARRANTIES[$warranty] : "X";
}
}