mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-16 21:17:14 +01:00
384 lines
13 KiB
PHP
384 lines
13 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Xentral\Modules\FiskalyApi\Service;
|
||
|
|
||
|
use Datetime;
|
||
|
use DateTimeZone;
|
||
|
use Exception;
|
||
|
use Xentral\Components\Database\Database;
|
||
|
use Xentral\Modules\FiskalyApi\Data\Export;
|
||
|
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponse;
|
||
|
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionReponseCollection;
|
||
|
use Xentral\Modules\FiskalyApi\Data\Transaction\TransactionRequest;
|
||
|
use Xentral\Modules\FiskalyApi\Exception\InvalidArgumentException;
|
||
|
use Xentral\Modules\FiskalyApi\Exception\InvalidTransactionException;
|
||
|
|
||
|
final class FiskalyTransactionPosSessionService implements FiskalyTransactionPosSessionInterface
|
||
|
{
|
||
|
/** @var Database $db */
|
||
|
private $db;
|
||
|
|
||
|
/**
|
||
|
* FiskalyTransactionPosSessionService constructor.
|
||
|
*
|
||
|
* @param Database $db
|
||
|
*/
|
||
|
public function __construct(Database $db)
|
||
|
{
|
||
|
$this->db = $db;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $trxId
|
||
|
*
|
||
|
* @return array|null
|
||
|
*/
|
||
|
public function get(string $trxId): ?array
|
||
|
{
|
||
|
return $this->db->fetchRow(
|
||
|
'SELECT * FROM `fiskaly_transaction` WHERE `trx_id` = :trx_id',
|
||
|
['trx_id' => $trxId]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param TransactionReponseCollection $transactionResponseCollection
|
||
|
*/
|
||
|
public function insertTransactions(TransactionReponseCollection $transactionResponseCollection): void
|
||
|
{
|
||
|
foreach ($transactionResponseCollection as $transactionResponse) {
|
||
|
$trxId = $transactionResponse->getId();
|
||
|
if (!empty($this->get($trxId))) {
|
||
|
continue;
|
||
|
}
|
||
|
$this->create(null, $transactionResponse);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $trxId
|
||
|
*
|
||
|
* @return int|null
|
||
|
*/
|
||
|
public function getTransactionIdFromTrxId(string $trxId): ?int
|
||
|
{
|
||
|
$fiskalyTransactionId = $this->db->fetchValue(
|
||
|
'SELECT `id` FROM `fiskaly_transaction` WHERE `trx_id` = :trx_id',
|
||
|
[
|
||
|
'trx_id' => $trxId,
|
||
|
]
|
||
|
);
|
||
|
|
||
|
return $fiskalyTransactionId === false ? null : (int)$fiskalyTransactionId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $document
|
||
|
* @param int $documentId
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getTransactionFromDocument(string $document, int $documentId): array
|
||
|
{
|
||
|
return $this->db->fetchRow(
|
||
|
'SELECT ft.*
|
||
|
FROM `fiskaly_transaction` AS `ft`
|
||
|
INNER JOIN `fiskaly_tranaction_mapping` AS `ftm` ON ft.id = ftm.fiskaly_transaction_id
|
||
|
WHERE ftm.document = :document AND ftm.document_id = :document_id',
|
||
|
[
|
||
|
'document' => $document,
|
||
|
'document_id' => $documentId,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $trxId
|
||
|
* @param string $document
|
||
|
* @param int $documentId
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function tryMapDocument(string $trxId, string $document, int $documentId): int
|
||
|
{
|
||
|
$fiskalyTransactionId = $this->getTransactionIdFromTrxId($trxId);
|
||
|
$mappingId = $fiskalyTransactionId === null ? false : $this->db->fetchValue(
|
||
|
'SELECT ftm.id
|
||
|
FROM `fiskaly_tranaction_mapping` AS `ftm`
|
||
|
WHERE ftm.fiskaly_transaction_id = :fiskaly_transaction_id
|
||
|
AND ftm.document = :document
|
||
|
AND ftm.document_id = :document_id',
|
||
|
[
|
||
|
'fiskaly_transaction_id' => $fiskalyTransactionId,
|
||
|
'document' => $document,
|
||
|
'document_id' => $documentId,
|
||
|
]
|
||
|
);
|
||
|
if ($mappingId !== false) {
|
||
|
return (int)$mappingId;
|
||
|
}
|
||
|
$this->db->perform(
|
||
|
'INSERT INTO `fiskaly_tranaction_mapping` (`fiskaly_transaction_id`, `document`, `document_id`)
|
||
|
VALUES (:fiskaly_transaction_id, :document, :document_id)',
|
||
|
[
|
||
|
'fiskaly_transaction_id' => $fiskalyTransactionId,
|
||
|
'document' => $document,
|
||
|
'document_id' => $documentId,
|
||
|
]
|
||
|
);
|
||
|
|
||
|
return $this->db->lastInsertId();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param TransactionRequest|null $request
|
||
|
* @param TransactionReponse|null $response
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
public function create(
|
||
|
?TransactionRequest $request,
|
||
|
?TransactionReponse $response
|
||
|
): int {
|
||
|
if ($request === null && $response === null) {
|
||
|
throw new InvalidArgumentException('response or request required');
|
||
|
}
|
||
|
$trxId = $request === null ? $response->getId() : $request->getId();
|
||
|
if (!empty($this->get($trxId))) {
|
||
|
throw new InvalidTransactionException('Transaction already exists');
|
||
|
}
|
||
|
$this->db->perform(
|
||
|
'INSERT INTO `fiskaly_transaction`
|
||
|
(`tss_id`, `client_id`, `trx_id`, `state`,
|
||
|
`time_start`, `time_end`, `json_request`, `json_response`)
|
||
|
VALUES (:tss_id, :client_id, :trx_id, :state,
|
||
|
NULL, NULL, :json_request, :json_response)',
|
||
|
[
|
||
|
'tss_id' => $request === null ? $response->getTssId() : $request->getTssId(),
|
||
|
'client_id' => $request === null ? $response->getClientId() : $request->getClientId(),
|
||
|
'trx_id' => $trxId,
|
||
|
'state' => $response === null ? null : $response->getState(),
|
||
|
'json_request' => $request === null ? null : json_encode($request->toArray()),
|
||
|
'json_response' => $response === null ? null : json_encode($response->toArray()),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
$fiskalyTransactionId = $this->db->lastInsertId();
|
||
|
if ($response === null) {
|
||
|
return $fiskalyTransactionId;
|
||
|
}
|
||
|
if ($response->getTimeStart() !== null) {
|
||
|
$this->db->perform(
|
||
|
'UPDATE `fiskaly_transaction`
|
||
|
SET `time_start` = FROM_UNIXTIME(:time_start)
|
||
|
WHERE `id` = :id',
|
||
|
[
|
||
|
'time_start' => $response->getTimeStart()->getTimestamp(),
|
||
|
'id' => $fiskalyTransactionId,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
if ($response->getTimeEnd() !== null) {
|
||
|
$this->db->perform(
|
||
|
'UPDATE `fiskaly_transaction`
|
||
|
SET `time_end` = FROM_UNIXTIME(:time_end)
|
||
|
WHERE `id` = :id',
|
||
|
[
|
||
|
'time_end' => $response->getTimeEnd()->getTimestamp(),
|
||
|
'id' => $fiskalyTransactionId,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return $fiskalyTransactionId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param int $fiskalyTransactionPosSessionId
|
||
|
* @param TransactionRequest $request
|
||
|
* @param TransactionReponse $response
|
||
|
*/
|
||
|
public function update(
|
||
|
int $fiskalyTransactionPosSessionId,
|
||
|
TransactionRequest $request,
|
||
|
TransactionReponse $response
|
||
|
): void {
|
||
|
if ($response->getTimeEnd() === null) {
|
||
|
$this->db->perform(
|
||
|
'UPDATE `fiskaly_transaction`
|
||
|
SET `state` = :state,
|
||
|
`time_end` = NULL,
|
||
|
`json_request` = :json_request,
|
||
|
`json_response` = :json_response
|
||
|
WHERE `id` = :id',
|
||
|
[
|
||
|
'state' => $response->getState(),
|
||
|
'json_request' => json_encode($request->toApiResult()),
|
||
|
'json_response' => json_encode($response->toApiResult()),
|
||
|
'id' => $fiskalyTransactionPosSessionId,
|
||
|
]
|
||
|
);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
$this->db->perform(
|
||
|
'UPDATE `fiskaly_transaction`
|
||
|
SET `state` = :state,
|
||
|
`time_end` = FROM_UNIXTIME(:time_end),
|
||
|
`json_request` = :json_request,
|
||
|
`json_response` = :json_response
|
||
|
WHERE `id` = :id',
|
||
|
[
|
||
|
'state' => $response->getState(),
|
||
|
'time_end' => $response->getTimeEnd()->getTimestamp(),
|
||
|
'json_request' => json_encode($request->toApiResult()),
|
||
|
'json_response' => json_encode($response->toApiResult()),
|
||
|
'id' => $fiskalyTransactionPosSessionId,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Export $export
|
||
|
*
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function createOrUpdateExport(Export $export): void
|
||
|
{
|
||
|
if ($this->getExportIdFromUuid($export->getUuId()) === null) {
|
||
|
$this->createExport($export);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
$this->updateExport($export);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Export $export
|
||
|
*
|
||
|
* @throws Exception
|
||
|
* @return int
|
||
|
*/
|
||
|
public function createExport(Export $export): int
|
||
|
{
|
||
|
$this->db->perform(
|
||
|
'INSERT INTO `fiskaly_kassensichv_export`
|
||
|
(`uuid`, `type`, `env`, `tssid`, `state`, `href`, `time_request`, `time_start`, `time_end`)
|
||
|
VALUES (:uuid, :type, :env, :tssid, :state, :href, :time_request, :time_start, :time_end)',
|
||
|
[
|
||
|
'uuid' => $export->getUuId(),
|
||
|
'type' => $export->getType(),
|
||
|
'env' => $export->getEnv(),
|
||
|
'tssid' => $export->getTssId(),
|
||
|
'state' => $export->getState(),
|
||
|
'href' => $export->getHref(),
|
||
|
'time_request' => $export->getTimeRequest() === null ? null : (new Datetime(
|
||
|
'now',
|
||
|
new DateTimeZone('UTC')
|
||
|
))->setTimeStamp(
|
||
|
$export->getTimeRequest()
|
||
|
)->format('Y-m-d H:i:s'),
|
||
|
'time_start' => $export->getTimeStart() === null ? null : (new Datetime(
|
||
|
'now', new DateTimeZone('UTC')
|
||
|
))->setTimeStamp($export->getTimeStart())
|
||
|
->format('Y-m-d H:i:s'),
|
||
|
'time_end' => $export->getTimeEnd() === null ? null : (new Datetime(
|
||
|
'now', new DateTimeZone('UTC')
|
||
|
))->setTimeStamp($export->getTimeEnd())
|
||
|
->format('Y-m-d H:i:s'),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
return $this->db->lastInsertId();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param Export $export
|
||
|
*
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function updateExport(Export $export): void
|
||
|
{
|
||
|
$this->db->perform(
|
||
|
'UPDATE `fiskaly_kassensichv_export`
|
||
|
SET `state` = :state,
|
||
|
`href` = :href,
|
||
|
`time_request` = :time_request,
|
||
|
`time_start` = :time_start,
|
||
|
`time_end` = :time_end
|
||
|
WHERE `uuid` = :uuid',
|
||
|
[
|
||
|
'uuid' => $export->getUuId(),
|
||
|
'state' => $export->getState(),
|
||
|
'href' => $export->getHref(),
|
||
|
'time_request' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp(
|
||
|
$export->getTimeRequest()
|
||
|
)->format('Y-m-d H:i:s'),
|
||
|
'time_start' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp($export->getTimeStart())
|
||
|
->format('Y-m-d H:i:s'),
|
||
|
'time_end' => (new Datetime('now', new DateTimeZone('UTC')))->setTimeStamp($export->getTimeEnd())
|
||
|
->format('Y-m-d H:i:s'),
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $tssId
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getExportUrlsNotInDms(string $tssId): array
|
||
|
{
|
||
|
return $this->db->fetchAll(
|
||
|
"SELECT fke.id, fke.href, fke.uuid
|
||
|
FROM `fiskaly_kassensichv_export` AS `fke`
|
||
|
LEFT JOIN `datei_stichwoerter` AS `ds` ON fke.id = ds.parameter AND ds.objekt = 'fiskaly_kassensichv_export'
|
||
|
WHERE `fke`.state = 'COMPLETED' AND fke.tssid = :tssid AND ds.id IS NULL",
|
||
|
['tssid' => $tssId]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $state
|
||
|
* @param string|null $tssId
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getUuIdsByState(string $state, ?string $tssId = null): array
|
||
|
{
|
||
|
if ($tssId === null) {
|
||
|
return $this->db->fetchCol(
|
||
|
'SELECT `uuid` FROM `fiskaly_kassensichv_export` WHERE `state` = :state',
|
||
|
[
|
||
|
'state' => $state,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return $this->db->fetchCol(
|
||
|
'SELECT `uuid` FROM `fiskaly_kassensichv_export` WHERE `tssid` = :tssid AND `state` = :state',
|
||
|
[
|
||
|
'tssid' => $tssId,
|
||
|
'state' => $state,
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $uuid
|
||
|
*
|
||
|
* @return int|null
|
||
|
*/
|
||
|
private function getExportIdFromUuid(string $uuid): ?int
|
||
|
{
|
||
|
$id = $this->db->fetchValue(
|
||
|
'SELECT `id` FROM `fiskaly_kassensichv_export` WHERE `uuid` = :uuid',
|
||
|
['uuid' => $uuid]
|
||
|
);
|
||
|
|
||
|
return $id === false ? null : (int)$id;
|
||
|
}
|
||
|
}
|