This commit is contained in:
2026-04-15 01:24:42 +02:00
parent 6786665cbf
commit 596b7a995e
15 changed files with 1206 additions and 115 deletions

View File

@@ -48,6 +48,19 @@ class FakturowniaImportRepository
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
);
$this -> mdb -> query(
'CREATE TABLE IF NOT EXISTS `fakturownia_skipped_positions` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`external_id` VARCHAR(64) NOT NULL,
`document_type` VARCHAR(32) NOT NULL,
`external_item_key` VARCHAR(191) NOT NULL,
`item_name` VARCHAR(255) NOT NULL,
`created_at` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_doc_item` (`external_id`, `document_type`, `external_item_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
);
$this -> mdb -> query(
'CREATE TABLE IF NOT EXISTS `fakturownia_imported_documents` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -168,6 +181,89 @@ class FakturowniaImportRepository
$this -> resolveQueueItem( 'item', $externalItemKey );
}
public function markDocumentPositionSkipped( $externalId, $documentType, $externalItemKey, $itemName )
{
$this -> ensureTables();
$existing = $this -> mdb -> get( 'fakturownia_skipped_positions', 'id', [
'AND' => [
'external_id' => (string)$externalId,
'document_type' => (string)$documentType,
'external_item_key' => (string)$externalItemKey
]
] );
if ( $existing )
return;
$this -> mdb -> insert( 'fakturownia_skipped_positions', [
'external_id' => (string)$externalId,
'document_type' => (string)$documentType,
'external_item_key' => (string)$externalItemKey,
'item_name' => (string)$itemName,
'created_at' => date( 'Y-m-d H:i:s' )
] );
}
public function isDocumentPositionSkipped( $externalId, $documentType, $externalItemKey )
{
$this -> ensureTables();
return (bool)$this -> mdb -> has( 'fakturownia_skipped_positions', [
'AND' => [
'external_id' => (string)$externalId,
'document_type' => (string)$documentType,
'external_item_key' => (string)$externalItemKey
]
] );
}
public function removeOccurrenceFromItemQueue( $externalItemKey, $externalId )
{
$this -> ensureTables();
$row = $this -> mdb -> get( 'fakturownia_unmapped_queue', '*', [
'AND' => [
'queue_type' => 'item',
'external_key' => (string)$externalItemKey
]
] );
if ( !$row )
return;
$payload = [];
if ( isset( $row['payload_json'] ) && $row['payload_json'] )
{
$decoded = json_decode( $row['payload_json'], true );
if ( is_array( $decoded ) )
$payload = $decoded;
}
$occurrences = [];
if ( isset( $payload['occurrences'] ) && is_array( $payload['occurrences'] ) )
{
foreach ( $payload['occurrences'] as $occ )
{
if ( !is_array( $occ ) )
continue;
if ( (string)( $occ['document_id'] ?? '' ) === (string)$externalId )
continue;
$occurrences[] = $occ;
}
}
if ( empty( $occurrences ) )
{
$this -> mdb -> delete( 'fakturownia_unmapped_queue', [ 'id' => (int)$row['id'] ] );
return;
}
$payload['occurrences'] = $occurrences;
$this -> mdb -> update( 'fakturownia_unmapped_queue', [
'payload_json' => json_encode( $payload, JSON_UNESCAPED_UNICODE ),
'hits' => count( $occurrences ),
'last_seen_at' => date( 'Y-m-d H:i:s' )
], [ 'id' => (int)$row['id'] ] );
}
public function isDocumentImported( $externalDocumentKey )
{
$this -> ensureTables();
@@ -219,6 +315,64 @@ class FakturowniaImportRepository
] );
$now = date( 'Y-m-d H:i:s' );
// Dla queue_type='item' agregujemy occurrences per (document_id, item_key).
// Kazde wystapienie pozycji na innej fakturze to osobny wpis w payload.occurrences,
// zeby UI mogl pokazac liste i pozwolic na pomijanie per konkretna faktura.
if ( $queueType === 'item' )
{
$occurrence = $payload;
$payloadToStore = [ 'occurrences' => [ $occurrence ] ];
if ( $existing )
{
$existingPayload = [];
if ( isset( $existing['payload_json'] ) && $existing['payload_json'] )
{
$decoded = json_decode( $existing['payload_json'], true );
if ( is_array( $decoded ) )
$existingPayload = $decoded;
}
$occurrences = ( isset( $existingPayload['occurrences'] ) && is_array( $existingPayload['occurrences'] ) )
? $existingPayload['occurrences']
: [];
// Dedup po document_id — powtorny import nadpisuje istniejace wystapienie.
$occurrences = array_values( array_filter( $occurrences, function( $occ ) use ( $occurrence )
{
if ( !is_array( $occ ) )
return false;
return (string)( $occ['document_id'] ?? '' ) !== (string)( $occurrence['document_id'] ?? '' );
} ) );
$occurrences[] = $occurrence;
$payloadToStore = [ 'occurrences' => $occurrences ];
$this -> mdb -> update( 'fakturownia_unmapped_queue', [
'external_name' => $externalName,
'payload_json' => json_encode( $payloadToStore, JSON_UNESCAPED_UNICODE ),
'hits' => count( $occurrences ),
'resolved' => 0,
'last_seen_at' => $now
], [ 'id' => (int)$existing['id'] ] );
return;
}
$this -> mdb -> insert( 'fakturownia_unmapped_queue', [
'queue_type' => $queueType,
'external_key' => $externalKey,
'external_name' => $externalName,
'payload_json' => json_encode( $payloadToStore, JSON_UNESCAPED_UNICODE ),
'hits' => 1,
'resolved' => 0,
'first_seen_at' => $now,
'last_seen_at' => $now
] );
return;
}
// Pozostale queue_type (client) — zachowanie bez zmian.
$payloadJson = json_encode( $payload, JSON_UNESCAPED_UNICODE );
if ( $existing )