Initial xentral_oss_20.3.c9ffacf

This commit is contained in:
Alex
2021-05-21 08:49:41 +02:00
parent 5406e4a551
commit 34e5ac43d9
18884 changed files with 2109867 additions and 0 deletions
@@ -0,0 +1,388 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use DateTimeInterface;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Data\SubscriptionCycleCacheData;
final class SubscriptionCycleArticleGateway
{
/** @var Database */
private $db;
/**
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param DateTimeInterface $nextFirstDay
*
* @return SubscriptionCycleCacheData[]
*/
public function findMonthlySubscriptionData(DateTimeInterface $nextFirstDay): array
{
$sql =
'SELECT abr.id AS `subscription_article_id`,
CASE
WHEN abr.abgerechnetbis != \'0000-00-00\' AND abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis)
THEN DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY)
WHEN abr.abgerechnetbis != \'0000-00-00\'
THEN abr.abgerechnetbis
WHEN abr.startdatum = LAST_DAY(abr.startdatum)
THEN DATE_ADD(abr.startdatum, INTERVAL 1 DAY)
ELSE abr.startdatum
END AS `start_date`,
ROUND(ROUND(
DATEDIFF(
CASE
WHEN abr.abgerechnetbis != \'0000-00-00\' AND abr.abgerechnetbis >= :next_first_day
THEN DATE_ADD(LAST_DAY(abr.abgerechnetbis), INTERVAL 1 DAY)
WHEN abr.abgerechnetbis != \'0000-00-00\' AND abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis)
THEN DATE_SUB(DATE_ADD(:next_first_day, INTERVAL 1 MONTH), INTERVAL IF(abr.zahlzyklus < 1, 0, abr.zahlzyklus - 1) MONTH)
WHEN abr.abgerechnetbis != \'0000-00-00\' AND DAY(abr.abgerechnetbis) = 1
THEN DATE_SUB(:next_first_day, INTERVAL IF(abr.zahlzyklus < 1, 0, abr.zahlzyklus - 1) MONTH)
WHEN abr.abgerechnetbis != \'0000-00-00\'
THEN DATE_ADD(:next_first_day, INTERVAL IF(abr.zahlzyklus <= 1, 1, abr.zahlzyklus) MONTH)
WHEN abr.startdatum > :next_first_day
THEN DATE_ADD(LAST_DAY(abr.startdatum), INTERVAL 1 DAY)
WHEN abr.startdatum = :next_first_day AND DAY(abr.startdatum) = 1
THEN DATE_ADD(:next_first_day, INTERVAL 1 MONTH)
WHEN abr.startdatum < :next_first_day
THEN DATE_ADD(:next_first_day, INTERVAL 1 MONTH)
ELSE :next_first_day
END,
CASE
WHEN abr.abgerechnetbis != \'0000-00-00\' AND DAY(abr.abgerechnetbis) = 1
THEN abr.abgerechnetbis
WHEN abr.abgerechnetbis != \'0000-00-00\' AND abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis)
THEN DATE_ADD(LAST_DAY(abr.abgerechnetbis), INTERVAL 1 DAY)
WHEN abr.abgerechnetbis != \'0000-00-00\'
THEN DATE_SUB(DATE_ADD(LAST_DAY(abr.abgerechnetbis), INTERVAL 1 DAY), INTERVAL 1 MONTH)
WHEN DAY(abr.startdatum) = 1
THEN abr.startdatum
WHEN abr.startdatum = LAST_DAY(abr.startdatum)
THEN DATE_ADD(abr.startdatum, INTERVAL 1 DAY)
ELSE DATE_SUB(DATE_ADD(LAST_DAY(abr.startdatum), INTERVAL 1 DAY), INTERVAL 1 MONTH)
END
) / 30
,0) / IF(abr.zahlzyklus <= 1, 1, abr.zahlzyklus)) * IF(abr.zahlzyklus <= 1, 1, abr.zahlzyklus) AS `cycles_count`,
CASE
WHEN abr.abgerechnetbis != \'0000-00-00\' AND abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis)
THEN DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY)
WHEN abr.abgerechnetbis != \'0000-00-00\'
THEN DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
WHEN DAY(abr.startdatum) = 1
THEN abr.startdatum
WHEN abr.startdatum = LAST_DAY(abr.startdatum)
THEN DATE_ADD(abr.startdatum, INTERVAL 1 DAY)
ELSE DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
END AS `calculation_base_date`,
CASE
WHEN abr.abgerechnetbis = \'0000-00-00\' AND DAY(abr.startdatum) != 1 AND abr.startdatum != LAST_DAY(abr.startdatum)
THEN ( IF(DAY(abr.startdatum) = 1,0,DAY(abr.startdatum)) / DAY(LAST_DAY(abr.startdatum)))
WHEN abr.abgerechnetbis = \'0000-00-00\'
THEN 0
WHEN abr.abgerechnetbis != LAST_DAY(abr.abgerechnetbis)
THEN (IF(DAY(abr.abgerechnetbis) = 1,0,DAY(abr.abgerechnetbis)) / DAY(LAST_DAY(abr.abgerechnetbis)))
ELSE
0
END
AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE (abr.preisart = \'monat\' OR abr.preisart = \'\')
AND (abr.startdatum IS NULL OR abr.startdatum = \'0000-00-00\'
OR (
abr.startdatum <= :next_first_day
OR (abr.preisart = \'monat\' OR abr.preisart = \'\'
AND DATE_ADD(abr.startdatum, INTERVAL 1 DAY) < DATE_ADD(:next_first_day, INTERVAL 1 MONTH))
)
)
AND (
abr.abgerechnetbis = \'0000-00-00\'
OR (abr.abgerechnetbis < :next_first_day)
OR (abr.abgerechnetbis < DATE_SUB(DATE_ADD(:next_first_day, INTERVAL 1 MONTH), INTERVAL 1 DAY)
AND (abr.preisart = \'monat\' OR abr.preisart = \'\'))
)
AND (abr.enddatum = \'0000-00-00\' OR abr.enddatum >= DATE_SUB(:next_first_day, INTERVAL 1 DAY))';
return $this->convertArrayToSubscriptionCycleCacheData(
$this->db->fetchAll($sql, ['next_first_day' => $nextFirstDay->format('Y-m-d')])
);
}
/**
* @param DateTimeInterface $nextFirstDay
*
* @return SubscriptionCycleCacheData[]
*/
public function findCustomIntervalSubscriptionData(DateTimeInterface $nextFirstDay): array
{
$sql =
'SELECT
abr.id AS `subscription_article_id`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
abr.abgerechnetbis
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
abr.startdatum
)
) AS `start_date`,
ROUND(
DATEDIFF(
IF(
abr.startdatum > :next_first_day,
DATE_ADD(LAST_DAY(abr.startdatum), INTERVAL 1 DAY),
:next_first_day
),
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
)
) / 30
,0) AS `cycles_count`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
) AS `calculation_base_date`,
0 AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE abr.preisart = \'monatx\'';
return $this->convertArrayToSubscriptionCycleCacheData(
$this->db->fetchAll($sql, ['next_first_day' => $nextFirstDay->format('Y-m-d')])
);
}
/**
* @param DateTimeInterface $nextFirstDay
*
* @return SubscriptionCycleCacheData[]
*/
public function findYearlySubscriptionData(DateTimeInterface $nextFirstDay): array
{
$sql =
'SELECT
abr.id AS `subscription_article_id`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
abr.startdatum
)
) AS `start_date`,
ROUND(
DATEDIFF(
IF(
abr.startdatum > :next_first_day,
DATE_ADD(LAST_DAY(abr.startdatum), INTERVAL 1 DAY),
:next_first_day
),
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
)
) / 365
,0) AS `cycles_count`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
) AS `calculation_base_date`,
0 AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE abr.preisart = \'jahr\'';
return $this->convertArrayToSubscriptionCycleCacheData(
$this->db->fetchAll($sql, ['next_first_day' => $nextFirstDay->format('Y-m-d')])
);
}
/**
* @param DateTimeInterface $date
*
* @return SubscriptionCycleCacheData[]
*/
public function findWeeklySubscriptionData(DateTimeInterface $date): array
{
$sql =
'SELECT
abr.id AS `subscription_article_id`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
abr.abgerechnetbis,
abr.startdatum
) AS `start_date`,
(FLOOR(
DATEDIFF(
:date,
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
)
)
/ (7 * abr.zahlzyklus)
)
* abr.zahlzyklus
) + abr.zahlzyklus AS `cycles_count`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
abr.abgerechnetbis,
abr.startdatum
) AS `calculation_base_date`,
0 AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE abr.preisart = \'wochen\'';
return $this->convertArrayToSubscriptionCycleCacheData(
$this->db->fetchAll($sql, ['date' => $date->format('Y-m-d')])
);
}
/**
* @param DateTimeInterface $date
*
* @return SubscriptionCycleCacheData[]
*/
public function find30DaysSubscriptionData(DateTimeInterface $date): array
{
$sql =
'SELECT
abr.id AS `subscription_article_id`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
abr.abgerechnetbis,
abr.startdatum
) AS `start_date`,
(FLOOR(
DATEDIFF(
:date,
IF(
abr.abgerechnetbis != \'0000-00-00\',
IF(
abr.abgerechnetbis = LAST_DAY(abr.abgerechnetbis),
DATE_ADD(abr.abgerechnetbis, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.abgerechnetbis,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
),
IF(
abr.startdatum = LAST_DAY(abr.startdatum),
DATE_ADD(abr.startdatum, INTERVAL 1 DAY),
DATE_ADD(LAST_DAY(DATE_SUB(abr.startdatum,INTERVAL 1 MONTH)), INTERVAL 1 DAY)
)
)
)
/ (30 * abr.zahlzyklus)
)
* abr.zahlzyklus
) + abr.zahlzyklus AS `cycles_count`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
abr.abgerechnetbis,
abr.startdatum
) AS `calculation_base_date`,
0 AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE abr.preisart = \'30tage\'';
return $this->convertArrayToSubscriptionCycleCacheData(
$this->db->fetchAll($sql, ['date' => $date->format('Y-m-d')])
);
}
/**
* @return SubscriptionCycleCacheData[]
*/
public function findOneTimeSubscriptionData(): array
{
$sql =
'SELECT
abr.id AS `subscription_article_id`,
\'0000-00-00\' AS `start_date`,
0 AS `cycles_count`,
IF(
abr.abgerechnetbis != \'0000-00-00\',
abr.abgerechnetbis,
abr.startdatum
) AS `calculation_base_date`,
0 AS `start_month_price_factor`
FROM `abrechnungsartikel` AS `abr`
WHERE abr.preisart = \'einmalig\'';
return $this->convertArrayToSubscriptionCycleCacheData($this->db->fetchAll($sql));
}
/**
* @param array $result
*
* @return SubscriptionCycleCacheData[]
*/
private function convertArrayToSubscriptionCycleCacheData(array $result): array
{
$return = [];
if (!empty($result)) {
foreach ($result as $row) {
$return[] = SubscriptionCycleCacheData::fromDbState($row);
}
}
return $return;
}
}
@@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Data\SubscriptionCycleArticleData;
final class SubscriptionCycleArticleService
{
/** @var Database */
private $db;
/**
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param SubscriptionCycleArticleData $article
*
* @return int
*/
public function create(SubscriptionCycleArticleData $article): int
{
$sql =
'INSERT INTO `abrechnungsartikel` (
`sort`,
`artikel`,
`bezeichnung`,
`nummer`,
`menge`,
`preis`,
`steuerklasse`,
`rabatt`,
`abgerechnet`,
`startdatum`,
`lieferdatum`,
`abgerechnetbis`,
`wiederholend`,
`zahlzyklus`,
`abgrechnetam`,
`rechnung`,
`projekt`,
`adresse`,
`status`,
`bemerkung`,
`beschreibung`,
`dokument`,
`preisart`,
`enddatum`,
`angelegtvon`,
`angelegtam`,
`experte`,
`waehrung`,
`beschreibungersetzten`,
`gruppe`
) VALUES (
:sort,
:articleId,
:articleName,
:articleNumber,
:amount,
:price,
:taxClass,
:discount,
:cleared,
:startDate,
:deliveranceDate,
:clearedTill,
:repeating,
:payCycle,
:clearedOn,
:invoiceId,
:projectId,
:adressId,
:status,
:text,
:description,
:document,
:priceType,
:endDate,
:createdBy,
:createdDate,
:expert,
:currency,
:replaceDescription,
:subscriptionCycleGroupId
)';
$values = [
'sort' => $article->getSort(),
'articleId' => $article->getArticleId(),
'articleName' => $article->getArticleName(),
'articleNumber' => $article->getArticleNumber(),
'amount' => $article->getAmount(),
'price' => $article->getPrice(),
'taxClass' => $article->getTaxClass(),
'discount' => $article->getDiscount(),
'cleared' => $article->isCleared(),
'startDate' => $article->getStartDate(),
'deliveranceDate' => $article->getDeliveranceDate(),
'clearedTill' => $article->getClearedTill(),
'repeating' => $article->isRepeating(),
'payCycle' => $article->getPayCycle(),
'clearedOn' => $article->getClearedOn(),
'invoiceId' => $article->getInvoiceId(),
'projectId' => $article->getProjectId(),
'adressId' => $article->getAdressId(),
'status' => $article->getStatus(),
'text' => $article->getText(),
'description' => $article->getDescription(),
'document' => $article->getDocument(),
'priceType' => $article->getPriceType(),
'endDate' => $article->getEndDate(),
'createdBy' => $article->getCreatedBy(),
'createdDate' => $article->getCreatedDate(),
'expert' => $article->isExpert(),
'currency' => $article->getCurrency(),
'replaceDescription' => $article->isReplaceDescription(),
'subscriptionCycleGroupId' => $article->getSubscriptionCycleGroupId(),
];
$this->db->perform($sql, $values);
return $this->db->lastInsertId();
}
}
@@ -0,0 +1,127 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Data\SubscriptionCycleAutoSubscriptionData;
use Xentral\Modules\SubscriptionCycle\Exception\AutoSubscriptionNotFoundException;
final class SubscriptionCycleAutoSubscriptionGateway
{
/** @var Database */
private $db;
/**
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param int $autoSubscriptionId
*
* @throws AutoSubscriptionNotFoundException
*
* @return SubscriptionCycleAutoSubscriptionData
*/
public function getById(int $autoSubscriptionId): SubscriptionCycleAutoSubscriptionData
{
$sql =
'SELECT
sca.id,
sca.project_id,
sca.article_id,
sca.price_cycle,
sca.document_type,
sca.subscription_group_id,
sca.position,
sca.first_date_type,
sca.prevent_auto_dispatch,
sca.auto_email_confirmation,
sca.business_letter_pattern_id,
sca.add_pdf
FROM `subscription_cycle_autosubscription` AS `sca`
WHERE sca.id = :id';
$data = $this->db->fetchRow($sql, ['id' => $autoSubscriptionId]);
if (empty($data)) {
throw new AutoSubscriptionNotFoundException('No data found for id: ' . $autoSubscriptionId);
}
return SubscriptionCycleAutoSubscriptionData::fromDbState($data);
}
/**
* @param int $docId
*
* @return array
*/
public function findAutoSubscriptionData(int $docId)
{
$sql =
'SELECT
ap.artikel,
art.nummer,
art.name_de AS `bezeichnung`,
ap.menge,
ap.preis,
ap.rabatt,
(CASE sca.first_date_type
WHEN \'monatsanfang\' THEN DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), \'%Y-%m-01\')
WHEN \'monatsmitte\' THEN (
IF(
DAY(CURDATE()) > 15,
DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), \'%Y-%m-15\'),
DATE_FORMAT(CURDATE(), \'%Y-%m-15\')
)
)
ELSE au.datum
END) AS `startdatum`,
1 AS `wiederholend`,
\'angelegt\' AS `status`,
(CASE sca.price_cycle
WHEN \'monatspreis\' THEN \'monat\'
WHEN \'jahrespreis\' THEN \'jahr\'
ELSE sca.price_cycle
END) AS `preisart`,
sca.position AS `sort`,
sca.project_id AS `projekt`,
NOW() AS `angelegtam`,
0 AS `experte`,
au.waehrung,
0 AS `beschreibungersetzten`,
art.umsatzsteuer AS `steuerklasse`,
1 AS `zahlzyklus`,
0 AS `rechnung`,
sca.document_type AS `dokument`,
sca.subscription_group_id AS `gruppe`,
0 AS `angelegtvon`,
0 AS `abgerechnet`,
sca.auto_email_confirmation,
sca.business_letter_pattern_id,
sca.add_pdf,
sca.prevent_auto_dispatch,
au.sprache,
gba.subjekt,
adr.email,
adr.abweichendeemailab,
au.adresse
FROM `auftrag_position` AS `ap`
INNER JOIN `auftrag` AS `au` ON au.id = ap.auftrag
INNER JOIN `artikel` AS `art` ON art.id = ap.artikel
INNER JOIN `adresse` AS `adr` ON au.adresse = adr.id
INNER JOIN `subscription_cycle_autosubscription` AS `sca` ON sca.article_id = ap.artikel
LEFT JOIN `geschaeftsbrief_vorlagen` AS `gba` ON gba.id = sca.business_letter_pattern_id
LEFT JOIN `abrechnungsartikel` AS `ara` ON ara.artikel = sca.article_id AND ara.adresse = au.adresse
WHERE au.id = :docId
AND IF(sca.project_id = 0, 1, au.projekt = sca.project_id)
AND ara.artikel IS NULL';
return $this->db->fetchAll($sql, ['docId' => $docId]);
}
}
@@ -0,0 +1,163 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Data\SubscriptionCycleAutoSubscriptionData;
use Xentral\Modules\SubscriptionCycle\Exception\AutoSubscriptionNotFoundException;
use Xentral\Modules\SubscriptionCycle\Exception\OrderNotFoundException;
use Xentral\Modules\SubscriptionCycle\Exception\RuntimeException;
final class SubscriptionCycleAutoSubscriptionService
{
/** @var Database */
private $db;
/**
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param SubscriptionCycleAutoSubscriptionData $autoSubscription
*
* @return int
*/
public function create(SubscriptionCycleAutoSubscriptionData $autoSubscription): int
{
$sql =
'INSERT INTO `subscription_cycle_autosubscription` (
`project_id`,
`article_id`,
`price_cycle`,
`document_type`,
`subscription_group_id`,
`position`,
`first_date_type`,
`prevent_auto_dispatch`,
`auto_email_confirmation`,
`business_letter_pattern_id`,
`add_pdf`
)
VALUES (
:projectId,
:articleId,
:priceCycle,
:documentType,
:subscriptionGroupId,
:position,
:firstDateType,
:preventAutoDispatch,
:autoEmailConfirmation,
:businessLetterPatternId,
:addPdf
)';
$values = [
'projectId' => $autoSubscription->getProjectId(),
'articleId' => $autoSubscription->getArticleId(),
'priceCycle' => $autoSubscription->getPriceCycle(),
'documentType' => $autoSubscription->getDocumentType(),
'subscriptionGroupId' => $autoSubscription->getSubscriptionGroupId(),
'position' => $autoSubscription->getPosition(),
'firstDateType' => $autoSubscription->getFirstDateType(),
'preventAutoDispatch' => $autoSubscription->getPreventAutoDispatch(),
'autoEmailConfirmation' => $autoSubscription->getAutoEmailConfirmation(),
'businessLetterPatternId' => $autoSubscription->getBusinessLetterPatternId(),
'addPdf' => $autoSubscription->getAddPdf(),
];
$this->db->perform($sql, $values);
return $this->db->lastInsertId();
}
/**
* @param SubscriptionCycleAutoSubscriptionData $autoSubscription
*
* @throws AutoSubscriptionNotFoundException
*/
public function edit(SubscriptionCycleAutoSubscriptionData $autoSubscription): void
{
if (empty($autoSubscription->getId())) {
throw new AutoSubscriptionNotFoundException('No ID is found for an update');
}
$sql =
'UPDATE `subscription_cycle_autosubscription`
SET
`project_id` = :projectId,
`article_id` = :articleId,
`price_cycle` = :priceCycle,
`document_type` = :documentType,
`subscription_group_id` = :subscriptionGroupId,
`position` = :position,
`first_date_type` = :firstDateType,
`prevent_auto_dispatch` = :preventAutoDispatch,
`auto_email_confirmation` = :autoEmailConfirmation,
`business_letter_pattern_id` = :businessLetterPatternId,
`add_pdf` = :addPdf
WHERE `id` = :id';
$values = [
'id' => $autoSubscription->getId(),
'projectId' => $autoSubscription->getProjectId(),
'articleId' => $autoSubscription->getArticleId(),
'priceCycle' => $autoSubscription->getPriceCycle(),
'documentType' => $autoSubscription->getDocumentType(),
'subscriptionGroupId' => $autoSubscription->getSubscriptionGroupId(),
'position' => $autoSubscription->getPosition(),
'firstDateType' => $autoSubscription->getFirstDateType(),
'preventAutoDispatch' => $autoSubscription->getPreventAutoDispatch(),
'autoEmailConfirmation' => $autoSubscription->getAutoEmailConfirmation(),
'businessLetterPatternId' => $autoSubscription->getBusinessLetterPatternId(),
'addPdf' => $autoSubscription->getAddPdf(),
];
$this->db->perform($sql, $values);
}
/**
* @param int $autosubscriptionId
*
* @throws AutoSubscriptionNotFoundException
* @throws RuntimeException
*/
public function removeById(int $autosubscriptionId): void
{
$sql = 'SELECT s.id FROM `subscription_cycle_autosubscription` AS `s` WHERE s.id = :id';
$data = $this->db->fetchRow($sql, ['id' => $autosubscriptionId]);
if (empty($data)) {
throw new AutoSubscriptionNotFoundException(
'The autosubscription with the following id does not exist:' . $autosubscriptionId
);
}
$sql = 'DELETE FROM `subscription_cycle_autosubscription` WHERE `id` = :id';
$numAffected = (int)$this->db->fetchAffected($sql, ['id' => $autosubscriptionId]);
if ($numAffected === 0) {
throw new RuntimeException('Autosubscription could not be deleted, id: ' . $autosubscriptionId);
}
}
/**
* @param int $orderId
*/
public function preventAutoDispatch(int $orderId): void
{
$sql = 'SELECT a.id FROM `auftrag` AS `a` WHERE a.id = :id';
$data = $this->db->fetchRow($sql, ['id' => $orderId]);
if (empty($data)) {
throw new OrderNotFoundException('The order with the following id does not exist:' . $orderId);
}
$sql = 'UPDATE `auftrag` SET `autoversand` = 0 WHERE `id` = :id';
$this->db->perform($sql, ['id' => (int)$orderId]);
}
}
@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Data\SubscriptionCycleCacheData;
final class SubscriptionCycleCacheService
{
/** @var Database */
private $db;
/** @var string TABLE_NAME */
const TABLE_NAME = 'subscription_cycle_cache';
/**
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param SubscriptionCycleCacheData[] $data
*/
public function createCacheEntries(array $data): void
{
if (!empty($data)) {
$insert = $this->db->insert()
->into(self::TABLE_NAME);
foreach ($data as $entry) {
$insert->addRow()
->cols(
[
'subscription_article_id' => $entry->getSubscriptionArticleId(),
'start_date' => $entry->getStartDate()->format('Y-m-d'),
'cycles_count' => $entry->getCyclesCount(),
'calculation_base_date' => $entry->getCalculationBaseDate()->format('Y-m-d'),
'start_month_price_factor' => $entry->getStartMonthPriceFactor(),
]
);
}
$insertSql = $insert->getStatement();
$values = $insert->getBindValues();
$this->db->perform($insertSql, $values);
}
}
public function emptyCache(): void
{
$sql = 'TRUNCATE `subscription_cycle_cache`';
$this->db->perform($sql);
}
}
@@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace Xentral\Modules\SubscriptionCycle\Service;
use DateTimeInterface;
use Xentral\Components\Database\Database;
use Xentral\Modules\SubscriptionCycle\Exception\InvalidArgumentException;
final class SubscriptionCycleJobService
{
private $db;
/**
* SubscriptionCycleJobService constructor.
*
* @param Database $db
*/
public function __construct(Database $db)
{
$this->db = $db;
}
/**
* @param int $subscriptionCycleJobId
*/
public function delete(int $subscriptionCycleJobId): void
{
$this->db->perform(
'DELETE FROM `subscription_cycle_job` WHERE `id` = :subscription_cycle_job_id',
['subscription_cycle_job_id' => $subscriptionCycleJobId]
);
}
/**
* @param int $addressId
* @param string $documentType
*
* @throws InvalidArgumentException
*/
public function deleteJobsByAddressIdAndDoctype(int $addressId, string $documentType): void
{
$this->ensureDocumentType($documentType);
$this->db->perform(
'DELETE FROM `subscription_cycle_job` WHERE `address_id` = :address_id AND `document_type` = :document_type',
[
'address_id' => $addressId,
'document_type' => $documentType,
]
);
}
/**
* @param int $addressId
* @param string $documentType
* @param string|null $jobType
* @param int|null $printerId
* @param DateTimeInterface|null $simulatedDay
*
* @throws InvalidArgumentException
*
* @return int
*/
public function create(int $addressId, string $documentType, ?string $jobType, ?int $printerId, ?DateTimeInterface $simulatedDay = null): int
{
$this->ensureDocumentType($documentType);
$this->db->perform(
'INSERT INTO `subscription_cycle_job`
(`address_id`, `document_type`, `job_type`, `printer_id`, `created_at`, `simulated_day`)
VALUES (:address_id, :document_type, :job_type, :printer_id, NOW(), :simulated_day)',
[
'address_id' => $addressId,
'document_type' => $documentType,
'job_type' => $jobType,
'printer_id' => $printerId,
'simulated_day' => $simulatedDay === null ? null : $simulatedDay->format('Y-m-d'),
]
);
return (int)$this->db->lastInsertId();
}
/**
* @param int $subscriptionCycleJobId
*
* @return array
*/
public function getJob(int $subscriptionCycleJobId): array
{
return $this->db->fetchRow(
'SELECT * FROM `subscription_cycle_job` WHERE `id` = :subscription_cycle_job_id',
['subscription_cycle_job_id' => $subscriptionCycleJobId]
);
}
/**
* @param int|null $limit
*
* @return array
*/
public function listAll(?int $limit = null): array
{
if ($limit !== null) {
return $this->db->fetchAll('SELECT * FROM `subscription_cycle_job` LIMIT :limit', ['limit' => $limit]);
}
return $this->db->fetchAll('SELECT * FROM `subscription_cycle_job`');
}
/**
* @param string $documentType
*
* @throws InvalidArgumentException
*
* @return int[]
*/
public function getAddressIdsByDocumentType(string $documentType): array
{
$this->ensureDocumentType($documentType);
return array_map(
'intval',
$this->db->fetchCol(
'SELECT `address_id` FROM `subscription_cycle_job` WHERE `document_type` = :document_type',
['document_type' => $documentType]
)
);
}
/**
* @param string $documentType
*
* @throws InvalidArgumentException
*/
private function ensureDocumentType(string $documentType): void
{
if (!in_array($documentType, ['rechnung', 'auftrag'])) {
throw new InvalidArgumentException("{$documentType} is not a valid documentType");
}
}
}