wpdbAdapter = $wpdbAdapter; $this->entityFactory = $entityFactory; } /** * Gets customs declaration ID by order ID. * * @param string $orderNumber Order ID. * @return string|null */ private function getIdByOrderNumber( string $orderNumber ): ?string { return $this->wpdbAdapter->get_var( $this->wpdbAdapter->prepare( 'SELECT `id` FROM `' . $this->wpdbAdapter->packeteryCustomsDeclaration . '` WHERE `order_id` = %d', $orderNumber ) ); } /** * Gets customs declaration by order. * * @param string $orderNumber Order. * * @return CustomsDeclaration|null */ public function getByOrderNumber( string $orderNumber ): ?CustomsDeclaration { $customsDeclarationRow = $this->wpdbAdapter->get_row( sprintf( 'SELECT `id`, `order_id`, `ead`, `delivery_cost`, `invoice_number`, `invoice_issue_date`, `mrn`, `invoice_file_id`, `ead_file_id`, `invoice_file` IS NOT NULL AS `has_invoice_file_content`, `ead_file` IS NOT NULL AS `has_ead_file_content` FROM `%s` WHERE `order_id` = %d', $this->wpdbAdapter->packeteryCustomsDeclaration, $orderNumber ), ARRAY_A ); if ( $customsDeclarationRow === null ) { return null; } $customsDeclaration = $this->entityFactory->fromStandardizedStructure( $customsDeclarationRow, $orderNumber ); $customsDeclaration->setInvoiceFile( function () use ( $orderNumber ): ?string { return $this->wpdbAdapter->get_var( $this->wpdbAdapter->prepare( 'SELECT `invoice_file` FROM `' . $this->wpdbAdapter->packeteryCustomsDeclaration . '` WHERE `order_id` = %d', $orderNumber ) ); }, (bool) $customsDeclarationRow['has_invoice_file_content'] ); $customsDeclaration->setEadFile( function () use ( $orderNumber ): ?string { return $this->wpdbAdapter->get_var( $this->wpdbAdapter->prepare( 'SELECT `ead_file` FROM `' . $this->wpdbAdapter->packeteryCustomsDeclaration . '` WHERE `order_id` = %d', $orderNumber ) ); }, (bool) $customsDeclarationRow['has_ead_file_content'] ); $customsDeclaration->setItems( $this->getItemsByCustomsDeclarationId( $customsDeclaration->getId() ) ); return $customsDeclaration; } /** * Gets customs declaration items by order. * * @param string|null $customsDeclarationId Customs declaration ID. * @return CustomsDeclarationItem[] */ public function getItemsByCustomsDeclarationId( ?string $customsDeclarationId ): array { if ( $customsDeclarationId === null ) { return []; } $customsDeclarationItemRows = $this->getCustomsDeclarationItemRows( $customsDeclarationId ); if ( $customsDeclarationItemRows === null ) { return []; } $customsDeclarationItems = []; foreach ( $customsDeclarationItemRows as $row ) { $customsDeclarationItems[] = $this->entityFactory->createItemFromStandardizedStructure( $row ); } return $customsDeclarationItems; } public function getCustomsDeclarationItemRows( ?string $customsDeclarationId ): ?array { return $this->wpdbAdapter->get_results( sprintf( 'SELECT `id`, `customs_declaration_id`, `customs_code`, `value`, `product_name_en`, `product_name`, `units_count`, `country_of_origin`, `weight`, `is_food_or_book`, `is_voc` FROM `%s` WHERE `customs_declaration_id` = %d', $this->wpdbAdapter->packeteryCustomsDeclarationItem, $customsDeclarationId ), ARRAY_A ); } /** * Saves customs declaration. * * @param CustomsDeclaration $customsDeclaration Customs declaration. * @param array $fieldsToOmit Fields to omit. * @return int|false The number of rows updated, or false on error. */ public function save( CustomsDeclaration $customsDeclaration, array $fieldsToOmit = [ 'invoice_file', 'ead_file' ] ) { if ( $customsDeclaration->getId() === null ) { $updatedRowCount = $this->wpdbAdapter->insertReplaceHelper( $this->wpdbAdapter->packeteryCustomsDeclaration, $this->declarationToDbArray( $customsDeclaration, $fieldsToOmit ) ); if ( $updatedRowCount !== false ) { $customsDeclaration->setId( $this->wpdbAdapter->getLastInsertId() ); } } else { $updatedRowCount = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclaration, $this->declarationToDbArray( $customsDeclaration, $fieldsToOmit ), [ 'id' => (int) $customsDeclaration->getId() ] ); } if ( $customsDeclaration->getId() !== null ) { $omitInvoiceFile = in_array( 'invoice_file', $fieldsToOmit, true ); if ( $omitInvoiceFile === false && $customsDeclaration->hasInvoiceFileContent() ) { $fileQueryResult = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclaration, [ 'invoice_file' => $customsDeclaration->getInvoiceFile() ], [ 'id' => (int) $customsDeclaration->getId() ] ); if ( $fileQueryResult === false ) { $updatedRowCount = false; } } if ( $omitInvoiceFile === false && $customsDeclaration->hasInvoiceFileContent() === false ) { $fileQueryResult = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclaration, [ 'invoice_file' => null ], [ 'id' => (int) $customsDeclaration->getId() ] ); if ( $fileQueryResult === false ) { $updatedRowCount = false; } } $omitEadFile = in_array( 'ead_file', $fieldsToOmit, true ); if ( $omitEadFile === false && $customsDeclaration->hasEadFileContent() ) { $fileQueryResult = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclaration, [ 'ead_file' => $customsDeclaration->getEadFile() ], [ 'id' => (int) $customsDeclaration->getId() ] ); if ( $fileQueryResult === false ) { $updatedRowCount = false; } } if ( $omitEadFile === false && $customsDeclaration->hasEadFileContent() === false ) { $fileQueryResult = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclaration, [ 'ead_file' => null ], [ 'id' => (int) $customsDeclaration->getId() ] ); if ( $fileQueryResult === false ) { $updatedRowCount = false; } } } return $updatedRowCount; } /** * Saves customs declaration item. * * @param CustomsDeclarationItem $customsDeclarationItem Customs declaration item. * @return int|false The number of rows updated, or false on error. */ public function saveItem( CustomsDeclarationItem $customsDeclarationItem ) { if ( $customsDeclarationItem->getId() === null ) { $updatedRowCount = $this->wpdbAdapter->insert( $this->wpdbAdapter->packeteryCustomsDeclarationItem, $this->declarationItemToDbArray( $customsDeclarationItem ) ); $customsDeclarationItem->setId( $this->wpdbAdapter->getLastInsertId() ); } else { $updatedRowCount = $this->wpdbAdapter->update( $this->wpdbAdapter->packeteryCustomsDeclarationItem, $this->declarationItemToDbArray( $customsDeclarationItem ), [ 'id' => (int) $customsDeclarationItem->getId() ] ); } return $updatedRowCount; } /** * @throws DeleteErrorException */ public function deleteItem( int $itemId ): void { $this->wpdbAdapter->delete( $this->wpdbAdapter->packeteryCustomsDeclarationItem, [ 'id' => $itemId ], '%d' ); } /** * @throws DeleteErrorException */ private function deleteItems( string $customsDeclarationId ): void { $items = $this->getItemsByCustomsDeclarationId( $customsDeclarationId ); if ( count( $items ) === 0 ) { return; } foreach ( $items as $item ) { $this->deleteItem( (int) $item->getId() ); } } /** * Completely deletes Customs Declaration with all its items. * * @throws DeleteErrorException */ public function delete( string $orderId ): void { $customsDeclarationId = $this->getIdByOrderNumber( $orderId ); if ( $customsDeclarationId === null ) { return; } $this->deleteItems( $customsDeclarationId ); $this->wpdbAdapter->delete( $this->wpdbAdapter->packeteryCustomsDeclaration, [ 'id' => $customsDeclarationId ], '%d' ); } /** * Converts customs declaration to DB array. * * @param CustomsDeclaration $customsDeclaration Customs declaration. * @param array $fieldsToOmit Fields to omit. * @return array */ public function declarationToDbArray( CustomsDeclaration $customsDeclaration, array $fieldsToOmit = [] ): array { $data = [ 'id' => $customsDeclaration->getId(), 'order_id' => $customsDeclaration->getOrderId(), 'ead' => $customsDeclaration->getEad(), 'delivery_cost' => $customsDeclaration->getDeliveryCost(), 'invoice_number' => $customsDeclaration->getInvoiceNumber(), 'invoice_issue_date' => $customsDeclaration->getInvoiceIssueDate()->format( CoreHelper::MYSQL_DATE_FORMAT ), 'invoice_file_id' => $customsDeclaration->getInvoiceFileId(), 'mrn' => $customsDeclaration->getMrn(), 'ead_file_id' => $customsDeclaration->getEadFileId(), ]; foreach ( $fieldsToOmit as $fieldToOmit ) { unset( $data[ $fieldToOmit ] ); } return $data; } /** * Converts customs declaration item to DB array. * * @param CustomsDeclarationItem $customsDeclarationItem Customs declaration item. * @return array */ public function declarationItemToDbArray( CustomsDeclarationItem $customsDeclarationItem ): array { return [ 'id' => $customsDeclarationItem->getId(), 'customs_declaration_id' => $customsDeclarationItem->getCustomsDeclarationId(), 'customs_code' => $customsDeclarationItem->getCustomsCode(), 'value' => $customsDeclarationItem->getValue(), 'product_name_en' => $customsDeclarationItem->getProductNameEn(), 'product_name' => $customsDeclarationItem->getProductName(), 'units_count' => $customsDeclarationItem->getUnitsCount(), 'country_of_origin' => strtoupper( $customsDeclarationItem->getCountryOfOrigin() ), 'weight' => $customsDeclarationItem->getWeight(), 'is_food_or_book' => (int) $customsDeclarationItem->isFoodOrBook(), 'is_voc' => (int) $customsDeclarationItem->isVoc(), ]; } /** * Creates main table. * * @return bool */ public function createOrAlterTable(): bool { $createTableQuery = sprintf( 'CREATE TABLE `%s` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `order_id` bigint(20) UNSIGNED NOT NULL, `ead` varchar(50) NOT NULL, `delivery_cost` decimal(13,2) UNSIGNED NOT NULL, `invoice_number` varchar(255) NOT NULL, `invoice_issue_date` date NOT NULL, `invoice_file` mediumblob NULL DEFAULT NULL, `invoice_file_id` varchar(255) NULL DEFAULT NULL, `mrn` varchar(32) NULL DEFAULT NULL, `ead_file` mediumblob NULL DEFAULT NULL, `ead_file_id` varchar(255) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) %s', $this->wpdbAdapter->packeteryCustomsDeclaration, $this->wpdbAdapter->get_charset_collate() ); return $this->wpdbAdapter->dbDelta( $createTableQuery, $this->wpdbAdapter->packeteryCustomsDeclaration ); } /** * Creates item table. * * @return bool */ public function createOrAlterItemTable(): bool { $createItemTableQuery = sprintf( 'CREATE TABLE `%s` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `customs_declaration_id` int(11) UNSIGNED NOT NULL, `customs_code` varchar(8) NOT NULL, `value` decimal(13,2) UNSIGNED NOT NULL, `product_name_en` varchar(255) NOT NULL, `product_name` varchar(255) NULL DEFAULT NULL, `units_count` int(11) UNSIGNED NOT NULL, `country_of_origin` char(2) NOT NULL, `weight` decimal(10,3) UNSIGNED NOT NULL, `is_food_or_book` tinyint(1) NOT NULL, `is_voc` tinyint(1) NOT NULL, PRIMARY KEY (`id`) ) %s', $this->wpdbAdapter->packeteryCustomsDeclarationItem, $this->wpdbAdapter->get_charset_collate() ); return $this->wpdbAdapter->dbDelta( $createItemTableQuery, $this->wpdbAdapter->packeteryCustomsDeclarationItem ); } }