Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
+127
@@ -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]);
|
||||
}
|
||||
}
|
||||
+163
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user