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; } }