OpenXE/classes/Modules/AmaInvoice/Scheduler/AmaInvoiceTask.php
2021-05-21 08:49:41 +02:00

298 lines
8.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Xentral\Modules\AmaInvoice\Scheduler;
use Exception;
use Xentral\Modules\AmaInvoice\Exception\ThrottlingException;
use Xentral\Modules\AmaInvoice\Service\AmaInvoiceService;
use Xentral\Modules\AmaInvoice\Exception\SchedulerTaskAlreadyRunningException;
use Xentral\Modules\SuperSearch\Wrapper\CompanyConfigWrapper;
final class AmaInvoiceTask
{
/** @var AmaInvoiceService $service */
private $service;
/** @var CompanyConfigWrapper $config */
private $config;
/** @var bool */
private $useFtp = false;
/**
* AmaInvoiceService constructor.
*
* @param AmaInvoiceService $service
* @param CompanyConfigWrapper $config
*/
public function __construct($service, $config)
{
$this->service = $service;
$this->config = $config;
}
/**
* @throws Exception
*
* @return void
*/
public function execute(): void
{
$taskActive = (int)$this->config->get('amainvoice_task_mutex');
if ($taskActive > 0) {
throw new SchedulerTaskAlreadyRunningException(
'Amainvoice task is already running. Task can only run once at a time.'
);
}
$this->config->set('amainvoice_task_mutex', '1');
$this->syncNewFiles();
$this->config->set('amainvoice_task_mutex', '1');
$this->service->executeImportDateDbEntries(false, false);
$this->config->set('amainvoice_task_mutex', '1');
$this->service->executeImportDateDbEntries(false, true);
$this->config->set('amainvoice_task_mutex', '1');
$this->service->executeImportDateDbEntries(true, false);
}
/**
* @throws Exception
*/
private function syncNewFiles(): void
{
$files = $this->service->getNewFiles();
$csvFiles = [];
$datevFiles = [];
$positions = [];
$datevs = [];
$pdfFiles = [];
$dateFiles = $this->getFirstApiFiles($files);
if ($this->useFtp) {
$csvFiles = $this->getExportCsvs($files);
$datevFiles = $this->getDatevFiles($files);
[$invoicePdfFiles, $returnOrderPdfFiles] = $this->getPdfFiles($files);
$pdfFiles = array_merge($invoicePdfFiles, $returnOrderPdfFiles);
foreach ($csvFiles as $csvFile) {
$position = $this->syncExportCsv($csvFile);
if (!empty($position)) {
foreach ($position as $pos) {
$positions[] = $pos;
}
}
}
foreach ($datevFiles as $datevFile) {
$datev = $this->syncDatevCsv($datevFile);
if (!empty($datev)) {
foreach ($datev as $pos) {
$datevs[] = $pos;
}
}
}
}
foreach (['invoice', 'returnorder'] as $type) {
foreach ($dateFiles[$type] as $file) {
try {
$this->service->executeImportDateFile($file);
}
catch(ThrottlingException $e) {
break 2;
}
}
if ($this->useFtp) {
$datev = empty($datevs[$type]) ? [] : $datevs[$type];
if (empty($positions[$type])) {
continue;
}
foreach ($datev as $amazonOrderId => $documents) {
if (empty($positions[$type][$amazonOrderId])) {
continue;
}
foreach ($documents as $number => $document) {
$numberInvoice = $number;
if (empty($positions[$type][$amazonOrderId][$number])) {
$numberInvoice = substr($number, 3);
if (empty($positions[$type][$amazonOrderId][$numberInvoice])) {
continue;
}
}
try {
$pdfFile = in_array($number . '.pdf', $pdfFiles, true) ? $number . '.pdf' : null;
if (
$this->service->createDocument(
$type,
$amazonOrderId,
$number,
$document,
$positions[$type][$amazonOrderId][$numberInvoice],
$pdfFile
)
) {
if ($pdfFile !== null) {
$this->service->markFile($pdfFile, 'pdf', 'imported');
}
} elseif ($pdfFile !== null) {
$this->service->markFile($pdfFile, 'pdf', 'error');
}
} catch (Exception $e) {
}
}
}
}
}
if ($this->useFtp) {
foreach ($datevFiles as $datevFile) {
$this->service->markFile($datevFile, 'datev', 'imported');
$this->service->cleanFile($datevFile);
}
foreach ($csvFiles as $csvFile) {
$this->service->markFile($csvFile, 'csv', 'imported');
$this->service->cleanFile($csvFile);
}
foreach ($pdfFiles as $pdfFile) {
$this->service->cleanFile($pdfFile);
}
}
}
/**
* @param string $file
*
* @throws Exception
*
* @return array
*/
private function syncDatevCsv($file): array
{
$csvFile = $this->service->getFile($file);
return $this->service->getPositionFromDatevCsv($csvFile);
}
/**
* @param string $file
*
* @throws Exception
* @return array
*/
private function syncExportCsv($file): array
{
$csvFile = $this->service->getFile($file);
return $this->service->getPositionFromExportCsv($csvFile);
}
/**
* @param array $files
*
* @return array[]
*/
private function getPdfFiles($files): array
{
if (empty($files)) {
return [[], []];
}
$ret = [[], []];
foreach ($files as $file) {
if (substr($file, -4) === '.pdf') {
if (strpos($file, 'GS') === 0) {
$ret[1][] = $file;
}
$ret[0][] = $file;
}
}
return $ret;
}
/**
* @param array $files
*
* @return array
*/
private function getDatevFiles($files): array
{
if (empty($files)) {
return [];
}
$ret = [];
foreach ($files as $file) {
if (strpos($file, 'EXTF_ERLOESE') === 0 && substr($file, -4) === '.csv') {
$ret[] = $file;
}
}
return $ret;
}
/**
* @param array $files
*
* @return array|array[]
*/
private function getFirstApiFiles($files): array
{
$ret = [
'invoice' => [],
'returnorder' => [],
];
if (empty($files)) {
return $ret;
}
foreach ($files as $file) {
if (substr($file, -4) === '.inv') {
$ret['invoice'][] = $file;
return $ret;
}
if (substr($file, -4) === '.rem') {
$ret['returnorder'][] = $file;
return $ret;
}
}
return $ret;
}
/**
* @param array $files
*
* @return array
*/
private function getExportCsvs($files): array
{
if (empty($files)) {
return [];
}
$ret = [];
foreach ($files as $file) {
if (strpos($file, 'export_') === 0 && substr($file, -4) === '.csv') {
$ret[] = $file;
}
}
return $ret;
}
/**
* @return void
*/
public function cleanup(): void
{
$this->config->set('amainvoice_task_mutex', '0');
}
}