| @@ -8,15 +8,22 @@ | ||
| 8 | 8 | declare( strict_types=1 ); |
| 9 | 9 | |
| 10 | 10 | namespace Packetery\Module\Order; |
| 11 | 11 | |
| 12 | -use Packetery\Core\Helper; | |
| 12 | +use DateTimeImmutable; | |
| 13 | +use Exception; | |
| 14 | +use Packetery\Core\CoreHelper; | |
| 15 | +use Packetery\Core\Entity; | |
| 13 | 16 | use Packetery\Core\Entity\Order; |
| 14 | 17 | use Packetery\Core\Entity\PickupPoint; |
| 15 | -use Packetery\Core\Entity\Size; | |
| 16 | -use Packetery\Core\Entity\Address; | |
| 17 | 18 | use Packetery\Module\Carrier; |
| 18 | -use Packetery\Module\ShippingMethod; | |
| 19 | +use Packetery\Module\Carrier\PacketaPickupPointsConfig; | |
| 20 | +use Packetery\Module\CustomsDeclaration; | |
| 21 | +use Packetery\Module\Exception\InvalidCarrierException; | |
| 22 | +use Packetery\Module\ModuleHelper; | |
| 23 | +use Packetery\Module\Shipping\ShippingProvider; | |
| 24 | +use Packetery\Module\WpdbAdapter; | |
| 25 | +use WC_Order; | |
| 19 | 26 | use WP_Post; |
| 20 | 27 | |
| 21 | 28 | /** |
| 22 | 29 | * Class Repository. |
| @@ -25,13 +32,13 @@ | ||
| 25 | 32 | */ |
| 26 | 33 | class Repository { |
| 27 | 34 | |
| 28 | 35 | /** |
| 29 | - * Wpdb. | |
| 36 | + * WpdbAdapter. | |
| 30 | 37 | * |
| 31 | - * @var \wpdb | |
| 38 | + * @var WpdbAdapter | |
| 32 | 39 | */ |
| 33 | - private $wpdb; | |
| 40 | + private $wpdbAdapter; | |
| 34 | 41 | |
| 35 | 42 | /** |
| 36 | 43 | * Order factory. |
| 37 | 44 | * |
| @@ -39,28 +46,71 @@ | ||
| 39 | 46 | */ |
| 40 | 47 | private $builder; |
| 41 | 48 | |
| 42 | 49 | /** |
| 50 | + * CoreHelper. | |
| 51 | + * | |
| 52 | + * @var CoreHelper | |
| 53 | + */ | |
| 54 | + private $coreHelper; | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * Internal pickup points config. | |
| 58 | + * | |
| 59 | + * @var PacketaPickupPointsConfig | |
| 60 | + */ | |
| 61 | + private $pickupPointsConfig; | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Carrier repository. | |
| 65 | + * | |
| 66 | + * @var Carrier\EntityRepository | |
| 67 | + */ | |
| 68 | + private $carrierRepository; | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Customs declaration repository. | |
| 72 | + * | |
| 73 | + * @var CustomsDeclaration\Repository | |
| 74 | + */ | |
| 75 | + private $customsDeclarationRepository; | |
| 76 | + | |
| 77 | + /** | |
| 43 | 78 | * Repository constructor. |
| 44 | 79 | * |
| 45 | - * @param \wpdb $wpdb Wpdb. | |
| 46 | - * @param Builder $orderFactory Order factory. | |
| 80 | + * @param WpdbAdapter $wpdbAdapter WpdbAdapter. | |
| 81 | + * @param Builder $orderFactory Order factory. | |
| 82 | + * @param CoreHelper $coreHelper CoreHelper. | |
| 83 | + * @param PacketaPickupPointsConfig $pickupPointsConfig Internal pickup points config. | |
| 84 | + * @param Carrier\EntityRepository $carrierRepository Carrier repository. | |
| 85 | + * @param CustomsDeclaration\Repository $customsDeclarationRepository Customs declaration repository. | |
| 47 | 86 | */ |
| 48 | - public function __construct( \wpdb $wpdb, Builder $orderFactory ) { | |
| 49 | - $this->wpdb = $wpdb; | |
| 50 | - $this->builder = $orderFactory; | |
| 87 | + public function __construct( | |
| 88 | + WpdbAdapter $wpdbAdapter, | |
| 89 | + Builder $orderFactory, | |
| 90 | + CoreHelper $coreHelper, | |
| 91 | + PacketaPickupPointsConfig $pickupPointsConfig, | |
| 92 | + Carrier\EntityRepository $carrierRepository, | |
| 93 | + CustomsDeclaration\Repository $customsDeclarationRepository | |
| 94 | + ) { | |
| 95 | + $this->wpdbAdapter = $wpdbAdapter; | |
| 96 | + $this->builder = $orderFactory; | |
| 97 | + $this->coreHelper = $coreHelper; | |
| 98 | + $this->pickupPointsConfig = $pickupPointsConfig; | |
| 99 | + $this->carrierRepository = $carrierRepository; | |
| 100 | + $this->customsDeclarationRepository = $customsDeclarationRepository; | |
| 51 | 101 | } |
| 52 | 102 | |
| 53 | 103 | /** |
| 54 | 104 | * Applies custom order status filter. |
| 55 | 105 | * |
| 56 | - * @param array $clauses Query clauses. | |
| 57 | - * @param \WP_Query $queryObject WP Query. | |
| 58 | - * @param array $paramValues Param values. | |
| 106 | + * @param array<string, string|null> $clauses Query clauses. | |
| 107 | + * @param \WP_Query|null $queryObject WP Query. | |
| 108 | + * @param array<string, string|null> $paramValues Param values. | |
| 59 | 109 | * |
| 60 | 110 | * @return void |
| 61 | 111 | */ |
| 62 | - private function applyCustomFilters( array &$clauses, \WP_Query $queryObject, array $paramValues ): void { | |
| 112 | + private function applyCustomFilters( array &$clauses, ?\WP_Query $queryObject, array $paramValues ): void { | |
| 63 | 113 | /** |
| 64 | 114 | * Filters order statuses to exclude in Packeta order list filtering. |
| 65 | 115 | * |
| 66 | 116 | * @since 1.4 |
| @@ -65,72 +115,71 @@ | ||
| 65 | 115 | * |
| 66 | 116 | * @since 1.4 |
| 67 | 117 | * |
| 68 | 118 | * @param array $orderStatusesToExclude Order statuses to exclude. |
| 69 | - * @param \WP_Query $queryObject WP Query. | |
| 119 | + * @param \WP_Query|null $queryObject WP Query. | |
| 70 | 120 | * @param array $paramValues Param values. |
| 71 | 121 | */ |
| 72 | - $orderStatusesToExclude = apply_filters( 'packetery_exclude_orders_with_status', [], $queryObject, $paramValues ); | |
| 73 | - if ( ! $orderStatusesToExclude ) { | |
| 122 | + $orderStatusesToExclude = (array) apply_filters( 'packetery_exclude_orders_with_status', [], $queryObject, $paramValues ); | |
| 123 | + if ( count( $orderStatusesToExclude ) === 0 ) { | |
| 74 | 124 | return; |
| 75 | 125 | } |
| 76 | 126 | |
| 77 | - $sqlStatusesToExclude = implode( | |
| 78 | - ',', | |
| 79 | - array_map( | |
| 80 | - function ( string $orderStatus ): string { | |
| 81 | - return sprintf( '"%s"', $this->wpdb->_real_escape( $orderStatus ) ); | |
| 82 | - }, | |
| 83 | - $orderStatusesToExclude | |
| 84 | - ) | |
| 85 | - ); | |
| 86 | - | |
| 87 | - $clauses['where'] .= sprintf( ' AND `%s`.`post_status` NOT IN (%s)', $this->wpdb->posts, $sqlStatusesToExclude ); | |
| 127 | + if ( ModuleHelper::isHposEnabled() ) { | |
| 128 | + $clauses['where'] .= sprintf( ' AND `%s`.`status` NOT IN (%s)', $this->wpdbAdapter->wcOrders, $this->wpdbAdapter->prepareInClause( $orderStatusesToExclude ) ); | |
| 129 | + } else { | |
| 130 | + $clauses['where'] .= sprintf( ' AND `%s`.`post_status` NOT IN (%s)', $this->wpdbAdapter->posts, $this->wpdbAdapter->prepareInClause( $orderStatusesToExclude ) ); | |
| 131 | + } | |
| 88 | 132 | } |
| 89 | 133 | |
| 90 | 134 | /** |
| 91 | - * Extends WP_Query to include custom table. | |
| 135 | + * Extends SQL query clauses. | |
| 92 | 136 | * |
| 93 | - * @link https://wordpress.stackexchange.com/questions/50305/how-to-extend-wp-query-to-include-custom-table-in-query | |
| 137 | + * @param array<string, string> $clauses Clauses. | |
| 138 | + * @param \WP_Query|null $queryObject Query object. | |
| 139 | + * @param array<string, string|null> $paramValues Param values. | |
| 94 | 140 | * |
| 95 | - * @param array $clauses Clauses. | |
| 96 | - * @param \WP_Query $queryObject WP_Query. | |
| 97 | - * @param array $paramValues Param values. | |
| 98 | - * | |
| 99 | - * @return array | |
| 141 | + * @return array<string, string> | |
| 100 | 142 | */ |
| 101 | - public function processPostClauses( array $clauses, \WP_Query $queryObject, array $paramValues ): array { | |
| 102 | - if ( isset( $queryObject->query['post_type'] ) && | |
| 103 | - ( | |
| 104 | - 'shop_order' === $queryObject->query['post_type'] || | |
| 105 | - ( is_array( $queryObject->query['post_type'] ) && in_array( 'shop_order', $queryObject->query['post_type'], true ) ) | |
| 106 | - ) | |
| 107 | - ) { | |
| 108 | - // TODO: Introduce variable. | |
| 109 | - $clauses['join'] .= ' LEFT JOIN `' . $this->wpdb->packetery_order . '` ON `' . $this->wpdb->packetery_order . '`.`id` = `' . $this->wpdb->posts . '`.`id`'; | |
| 143 | + public function processClauses( array $clauses, ?\WP_Query $queryObject, array $paramValues ): array { | |
| 144 | + if ( ModuleHelper::isHposEnabled() ) { | |
| 145 | + $clauses['join'] .= ' LEFT JOIN `' . $this->wpdbAdapter->packeteryOrder . '` ON `' . $this->wpdbAdapter->packeteryOrder . '`.`id` = `' . $this->wpdbAdapter->wcOrders . '`.`id`'; | |
| 146 | + } else { | |
| 147 | + $clauses['join'] .= ' LEFT JOIN `' . $this->wpdbAdapter->packeteryOrder . '` ON `' . $this->wpdbAdapter->packeteryOrder . '`.`id` = `' . $this->wpdbAdapter->posts . '`.`id`'; | |
| 148 | + } | |
| 110 | 149 | |
| 111 | - if ( $paramValues['packetery_carrier_id'] ) { | |
| 112 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`carrier_id` = "' . $this->wpdb->_real_escape( $paramValues['packetery_carrier_id'] ) . '"'; | |
| 113 | - $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 150 | + if ( isset( $paramValues['packetery_carrier_id'] ) && $paramValues['packetery_carrier_id'] !== '' ) { | |
| 151 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` = "' . esc_sql( $paramValues['packetery_carrier_id'] ) . '"'; | |
| 152 | + $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 153 | + } | |
| 154 | + if ( isset( $paramValues['packetery_to_submit'] ) && $paramValues['packetery_to_submit'] !== '' ) { | |
| 155 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` IS NOT NULL '; | |
| 156 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`is_exported` = false '; | |
| 157 | + $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 158 | + } | |
| 159 | + if ( isset( $paramValues['packetery_to_print'] ) && $paramValues['packetery_to_print'] !== '' ) { | |
| 160 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`packet_id` IS NOT NULL '; | |
| 161 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`is_label_printed` = false '; | |
| 162 | + $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 163 | + } | |
| 164 | + if ( isset( $paramValues['packetery_order_type'] ) && $paramValues['packetery_order_type'] !== '' ) { | |
| 165 | + if ( $paramValues['packetery_order_type'] === Entity\Carrier::INTERNAL_PICKUP_POINTS_ID ) { | |
| 166 | + $comparison = 'IN'; | |
| 167 | + } else { | |
| 168 | + $comparison = 'NOT IN'; | |
| 114 | 169 | } |
| 115 | - if ( $paramValues['packetery_to_submit'] ) { | |
| 116 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`carrier_id` IS NOT NULL '; | |
| 117 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`is_exported` = false '; | |
| 118 | - $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 170 | + $internalCarriers = array_keys( $this->carrierRepository->getNonFeedCarriers() ); | |
| 171 | + $internalCarriers[] = Entity\Carrier::INTERNAL_PICKUP_POINTS_ID; | |
| 172 | + $clauses['where'] .= ' AND `' . $this->wpdbAdapter->packeteryOrder . '`.`carrier_id` ' . $comparison . ' (' . $this->wpdbAdapter->prepareInClause( $internalCarriers ) . ')'; | |
| 173 | + $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 174 | + } | |
| 175 | + if ( isset( $paramValues['orderby'] ) && $paramValues['orderby'] === 'packetery_packet_stored_until' ) { | |
| 176 | + if ( $paramValues['order'] === 'asc' ) { | |
| 177 | + $clauses['orderby'] = '`' . $this->wpdbAdapter->packeteryOrder . '`.`stored_until` ASC'; | |
| 119 | 178 | } |
| 120 | - if ( $paramValues['packetery_to_print'] ) { | |
| 121 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`packet_id` IS NOT NULL '; | |
| 122 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`is_label_printed` = false '; | |
| 123 | - $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 179 | + if ( $paramValues['order'] === 'desc' ) { | |
| 180 | + $clauses['orderby'] = '`' . $this->wpdbAdapter->packeteryOrder . '`.`stored_until` DESC'; | |
| 124 | 181 | } |
| 125 | - if ( $paramValues['packetery_order_type'] ) { | |
| 126 | - if ( Carrier\Repository::INTERNAL_PICKUP_POINTS_ID === $paramValues['packetery_order_type'] ) { | |
| 127 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`carrier_id` = "' . $this->wpdb->_real_escape( Carrier\Repository::INTERNAL_PICKUP_POINTS_ID ) . '"'; | |
| 128 | - } else { | |
| 129 | - $clauses['where'] .= ' AND `' . $this->wpdb->packetery_order . '`.`carrier_id` != "' . $this->wpdb->_real_escape( Carrier\Repository::INTERNAL_PICKUP_POINTS_ID ) . '"'; | |
| 130 | - } | |
| 131 | - $this->applyCustomFilters( $clauses, $queryObject, $paramValues ); | |
| 132 | - } | |
| 133 | 182 | } |
| 134 | 183 | |
| 135 | 184 | return $clauses; |
| 136 | 185 | } |
| @@ -139,38 +188,43 @@ | ||
| 139 | 188 | * Create table to store orders. |
| 140 | 189 | * |
| 141 | 190 | * @return bool |
| 142 | 191 | */ |
| 143 | - public function createTable(): bool { | |
| 144 | - $wpdb = $this->wpdb; | |
| 192 | + public function createOrAlterTable(): bool { | |
| 193 | + $createTableQuery = 'CREATE TABLE ' . $this->wpdbAdapter->packeteryOrder . ' ( | |
| 194 | + `id` bigint(20) unsigned NOT NULL, | |
| 195 | + `carrier_id` varchar(15) NOT NULL, | |
| 196 | + `is_exported` tinyint(1) NOT NULL, | |
| 197 | + `packet_id` varchar(15) NULL, | |
| 198 | + `packet_claim_id` varchar(15) NULL, | |
| 199 | + `packet_claim_password` varchar(10) NULL, | |
| 200 | + `is_label_printed` tinyint(1) NOT NULL, | |
| 201 | + `point_id` varchar(50) NULL, | |
| 202 | + `point_name` varchar(150) NULL, | |
| 203 | + `point_url` varchar(255) NULL, | |
| 204 | + `point_street` varchar(120) NULL, | |
| 205 | + `point_zip` varchar(10) NULL, | |
| 206 | + `point_city` varchar(70) NULL, | |
| 207 | + `address_validated` tinyint(1) NOT NULL, | |
| 208 | + `delivery_address` text NULL, | |
| 209 | + `weight` float NULL, | |
| 210 | + `length` float NULL, | |
| 211 | + `width` float NULL, | |
| 212 | + `height` float NULL, | |
| 213 | + `adult_content` tinyint(1) NULL, | |
| 214 | + `value` double NULL, | |
| 215 | + `cod` double NULL, | |
| 216 | + `api_error_message` text NULL, | |
| 217 | + `api_error_date` datetime NULL, | |
| 218 | + `carrier_number` varchar(50) NULL, | |
| 219 | + `packet_status` varchar(30) NULL, | |
| 220 | + `stored_until` date NULL, | |
| 221 | + `deliver_on` date NULL, | |
| 222 | + `car_delivery_id` varchar(15) NULL, | |
| 223 | + PRIMARY KEY (`id`) | |
| 224 | + ) ' . $this->wpdbAdapter->get_charset_collate(); | |
| 145 | 225 | |
| 146 | - return $wpdb->query( | |
| 147 | - 'CREATE TABLE IF NOT EXISTS `' . $wpdb->packetery_order . '` ( | |
| 148 | - `id` bigint(20) unsigned NOT NULL, | |
| 149 | - `carrier_id` varchar(255) NOT NULL, | |
| 150 | - `is_exported` boolean NOT NULL, | |
| 151 | - `packet_id` varchar(255) NULL, | |
| 152 | - `is_label_printed` boolean NOT NULL, | |
| 153 | - `point_id` varchar(255) NULL, | |
| 154 | - `point_name` varchar(255) NULL, | |
| 155 | - `point_url` varchar(255) NULL, | |
| 156 | - `point_street` varchar(255) NULL, | |
| 157 | - `point_zip` varchar(255) NULL, | |
| 158 | - `point_city` varchar(255) NULL, | |
| 159 | - `address_validated` boolean NOT NULL, | |
| 160 | - `delivery_address` TEXT NULL, | |
| 161 | - `weight` float NULL, | |
| 162 | - `length` float NULL, | |
| 163 | - `width` float NULL, | |
| 164 | - `height` float NULL, | |
| 165 | - `adult_content` boolean NULL, | |
| 166 | - `value` double NULL, | |
| 167 | - `cod` double NULL, | |
| 168 | - `carrier_number` varchar(255) NULL, | |
| 169 | - `packet_status` varchar(255) NULL, | |
| 170 | - PRIMARY KEY (`id`) | |
| 171 | - ) ' . $wpdb->get_charset_collate() | |
| 172 | - ); | |
| 226 | + return $this->wpdbAdapter->dbDelta( $createTableQuery, $this->wpdbAdapter->packeteryOrder ); | |
| 173 | 227 | } |
| 174 | 228 | |
| 175 | 229 | /** |
| 176 | 230 | * Drop table used to store orders. |
| @@ -175,22 +229,17 @@ | ||
| 175 | 229 | /** |
| 176 | 230 | * Drop table used to store orders. |
| 177 | 231 | */ |
| 178 | 232 | public function drop(): void { |
| 179 | - $wpdb = $this->wpdb; | |
| 180 | - $wpdb->query( 'DROP TABLE IF EXISTS `' . $wpdb->packetery_order . '`' ); | |
| 233 | + $this->wpdbAdapter->query( 'DROP TABLE IF EXISTS `' . $this->wpdbAdapter->packeteryOrder . '`' ); | |
| 181 | 234 | } |
| 182 | 235 | |
| 183 | 236 | /** |
| 184 | - * Gets order data. | |
| 185 | - * | |
| 186 | - * @param int $id Order id. | |
| 187 | - * | |
| 188 | - * @return Order|null | |
| 237 | + * @throws InvalidCarrierException InvalidCarrierException. | |
| 189 | 238 | */ |
| 190 | 239 | public function getById( int $id ): ?Order { |
| 191 | - $wcOrder = wc_get_order( $id ); | |
| 192 | - if ( ! $wcOrder instanceof \WC_Order ) { | |
| 240 | + $wcOrder = $this->getWcOrderById( $id ); | |
| 241 | + if ( $wcOrder === null ) { | |
| 193 | 242 | return null; |
| 194 | 243 | } |
| 195 | 244 | |
| 196 | 245 | return $this->getByWcOrder( $wcOrder ); |
| @@ -196,127 +245,102 @@ | ||
| 196 | 245 | return $this->getByWcOrder( $wcOrder ); |
| 197 | 246 | } |
| 198 | 247 | |
| 199 | 248 | /** |
| 200 | - * Gets order by wc order. | |
| 249 | + * Ignores InvalidCarrierException. | |
| 250 | + */ | |
| 251 | + public function getByIdWithValidCarrier( int $id ): ?Order { | |
| 252 | + $wcOrder = $this->getWcOrderById( $id ); | |
| 253 | + if ( $wcOrder === null ) { | |
| 254 | + return null; | |
| 255 | + } | |
| 256 | + | |
| 257 | + return $this->getByWcOrderWithValidCarrier( $wcOrder ); | |
| 258 | + } | |
| 259 | + | |
| 260 | + /** | |
| 261 | + * Returns Packeta order, or null. | |
| 201 | 262 | * |
| 202 | - * @param \WC_Order $wcOrder WC Order. | |
| 263 | + * @param int $id Order ID. | |
| 203 | 264 | * |
| 204 | 265 | * @return Order|null |
| 205 | 266 | */ |
| 206 | - public function getByWcOrder( \WC_Order $wcOrder ): ?Order { | |
| 207 | - if ( ! $wcOrder->has_shipping_method( ShippingMethod::PACKETERY_METHOD_ID ) ) { | |
| 267 | + public function findById( int $id ): ?Order { | |
| 268 | + $wcOrder = $this->getWcOrderById( $id ); | |
| 269 | + if ( $wcOrder === null ) { | |
| 208 | 270 | return null; |
| 209 | 271 | } |
| 210 | 272 | |
| 211 | - $wpdb = $this->wpdb; | |
| 273 | + $result = $this->getDataById( $wcOrder->get_id() ); | |
| 274 | + if ( $result === null ) { | |
| 275 | + return null; | |
| 276 | + } | |
| 212 | 277 | |
| 213 | - $result = $wpdb->get_row( | |
| 214 | - $wpdb->prepare( | |
| 215 | - ' | |
| 216 | - SELECT o.* FROM `' . $wpdb->packetery_order . '` o | |
| 217 | - JOIN `' . $wpdb->posts . '` as wp_p ON wp_p.ID = o.id | |
| 218 | - WHERE o.`id` = %d', | |
| 219 | - $wcOrder->get_id() | |
| 220 | - ) | |
| 221 | - ); | |
| 222 | - | |
| 223 | - if ( ! $result ) { | |
| 278 | + try { | |
| 279 | + return $this->builder->build( $wcOrder, $result ); | |
| 280 | + } catch ( InvalidCarrierException $invalidCarrierException ) { | |
| 224 | 281 | return null; |
| 225 | 282 | } |
| 226 | - | |
| 227 | - $partialOrder = $this->createPartialOrder( $result ); | |
| 228 | - return $this->builder->finalize( $wcOrder, $partialOrder ); | |
| 229 | 283 | } |
| 230 | 284 | |
| 231 | 285 | /** |
| 232 | - * Creates partial order. | |
| 286 | + * Gets Packeta order data by id. | |
| 233 | 287 | * |
| 234 | - * @param \stdClass $result DB result. | |
| 288 | + * @param int $id Order id. | |
| 235 | 289 | * |
| 236 | - * @return Order | |
| 290 | + * @return object|null | |
| 237 | 291 | */ |
| 238 | - private function createPartialOrder( \stdClass $result ): Order { | |
| 239 | - $partialOrder = new Order( | |
| 240 | - $result->id, | |
| 241 | - $result->carrier_id | |
| 292 | + public function getDataById( int $id ): ?object { | |
| 293 | + return $this->wpdbAdapter->get_row( | |
| 294 | + $this->wpdbAdapter->prepare( | |
| 295 | + ' | |
| 296 | + SELECT `o`.* FROM `' . $this->wpdbAdapter->packeteryOrder . '` `o` | |
| 297 | + ' . $this->getWcOrderJoinClause() . ' | |
| 298 | + WHERE `o`.`id` = %d', | |
| 299 | + $id | |
| 300 | + ) | |
| 242 | 301 | ); |
| 302 | + } | |
| 243 | 303 | |
| 244 | - $orderWeight = $this->parseFloat( $result->weight ); | |
| 245 | - if ( null !== $orderWeight ) { | |
| 246 | - $partialOrder->setWeight( $orderWeight ); | |
| 304 | + private function getDataByWcOrder( WC_Order $wcOrder ): ?object { | |
| 305 | + if ( ! ShippingProvider::wcOrderHasOurMethod( $wcOrder ) ) { | |
| 306 | + return null; | |
| 247 | 307 | } |
| 248 | - $partialOrder->setPacketId( $result->packet_id ); | |
| 249 | - $partialOrder->setSize( new Size( $this->parseFloat( $result->length ), $this->parseFloat( $result->width ), $this->parseFloat( $result->height ) ) ); | |
| 250 | - $partialOrder->setIsExported( (bool) $result->is_exported ); | |
| 251 | - $partialOrder->setIsLabelPrinted( (bool) $result->is_label_printed ); | |
| 252 | - $partialOrder->setCarrierNumber( $result->carrier_number ); | |
| 253 | - $partialOrder->setPacketStatus( $result->packet_status ); | |
| 254 | - $partialOrder->setAddressValidated( (bool) $result->address_validated ); | |
| 255 | - $partialOrder->setAdultContent( $this->parseBool( $result->adult_content ) ); | |
| 256 | - $partialOrder->setValue( $this->parseFloat( $result->value ) ); | |
| 257 | - $partialOrder->setCod( $this->parseFloat( $result->cod ) ); | |
| 258 | 308 | |
| 259 | - if ( $result->delivery_address ) { | |
| 260 | - $deliveryAddressDecoded = json_decode( $result->delivery_address, false ); | |
| 261 | - $deliveryAddress = new Address( | |
| 262 | - $deliveryAddressDecoded->street, | |
| 263 | - $deliveryAddressDecoded->city, | |
| 264 | - $deliveryAddressDecoded->zip | |
| 265 | - ); | |
| 266 | - | |
| 267 | - $deliveryAddress->setHouseNumber( $deliveryAddressDecoded->houseNumber ); | |
| 268 | - $deliveryAddress->setLongitude( $deliveryAddressDecoded->longitude ); | |
| 269 | - $deliveryAddress->setLatitude( $deliveryAddressDecoded->latitude ); | |
| 270 | - $deliveryAddress->setCounty( $deliveryAddressDecoded->county ); | |
| 271 | - | |
| 272 | - $partialOrder->setDeliveryAddress( $deliveryAddress ); | |
| 309 | + $packeteryOrderData = $this->getDataById( $wcOrder->get_id() ); | |
| 310 | + if ( ! is_object( $packeteryOrderData ) ) { | |
| 311 | + return null; | |
| 273 | 312 | } |
| 274 | 313 | |
| 275 | - if ( null !== $result->point_id ) { | |
| 276 | - $pickUpPoint = new PickupPoint( | |
| 277 | - $result->point_id, | |
| 278 | - $result->point_name, | |
| 279 | - $result->point_city, | |
| 280 | - $result->point_zip, | |
| 281 | - $result->point_street, | |
| 282 | - $result->point_url | |
| 283 | - ); | |
| 284 | - | |
| 285 | - $partialOrder->setPickupPoint( $pickUpPoint ); | |
| 286 | - } | |
| 287 | - | |
| 288 | - return $partialOrder; | |
| 314 | + return $packeteryOrderData; | |
| 289 | 315 | } |
| 290 | 316 | |
| 291 | 317 | /** |
| 292 | - * Parses string value as float. | |
| 293 | - * | |
| 294 | - * @param string|float|null $value Value. | |
| 295 | - * | |
| 296 | - * @return float|null | |
| 318 | + * @throws InvalidCarrierException | |
| 297 | 319 | */ |
| 298 | - private function parseFloat( $value ): ?float { | |
| 299 | - if ( null === $value || '' === $value ) { | |
| 320 | + public function getByWcOrder( WC_Order $wcOrder ): ?Order { | |
| 321 | + $packeteryOrderData = $this->getDataByWcOrder( $wcOrder ); | |
| 322 | + if ( $packeteryOrderData === null ) { | |
| 300 | 323 | return null; |
| 301 | 324 | } |
| 302 | 325 | |
| 303 | - return (float) $value; | |
| 326 | + return $this->builder->build( $wcOrder, $packeteryOrderData ); | |
| 304 | 327 | } |
| 305 | 328 | |
| 306 | 329 | /** |
| 307 | - * Parses string value as float. | |
| 308 | - * | |
| 309 | - * @param string|int|null $value Value. | |
| 310 | - * | |
| 311 | - * @return bool|null | |
| 330 | + * Ignores InvalidCarrierException. | |
| 312 | 331 | */ |
| 313 | - private function parseBool( $value ): ?bool { | |
| 314 | - if ( null === $value || '' === $value ) { | |
| 332 | + public function getByWcOrderWithValidCarrier( WC_Order $wcOrder ): ?Order { | |
| 333 | + $packeteryOrderData = $this->getDataByWcOrder( $wcOrder ); | |
| 334 | + if ( $packeteryOrderData === null ) { | |
| 315 | 335 | return null; |
| 316 | 336 | } |
| 317 | 337 | |
| 318 | - return (bool) $value; | |
| 338 | + try { | |
| 339 | + return $this->builder->build( $wcOrder, $packeteryOrderData ); | |
| 340 | + } catch ( InvalidCarrierException $invalidCarrierException ) { | |
| 341 | + return null; | |
| 342 | + } | |
| 319 | 343 | } |
| 320 | 344 | |
| 321 | 345 | /** |
| 322 | 346 | * Transforms order to DB array. |
| @@ -322,44 +346,56 @@ | ||
| 322 | 346 | * Transforms order to DB array. |
| 323 | 347 | * |
| 324 | 348 | * @param Order $order Order. |
| 325 | 349 | * |
| 326 | - * @return array | |
| 350 | + * @return array<string, bool|float|int|string|null> | |
| 327 | 351 | */ |
| 328 | 352 | private function orderToDbArray( Order $order ): array { |
| 329 | 353 | $point = $order->getPickupPoint(); |
| 330 | - if ( null === $point ) { | |
| 354 | + if ( $point === null ) { | |
| 331 | 355 | $point = new PickupPoint(); |
| 332 | 356 | } |
| 333 | 357 | |
| 334 | 358 | $deliveryAddress = null; |
| 335 | - if ( $order->isAddressValidated() && $order->getDeliveryAddress() ) { | |
| 359 | + if ( $order->isAddressValidated() && $order->getDeliveryAddress() !== null ) { | |
| 336 | 360 | $deliveryAddress = wp_json_encode( $order->getDeliveryAddress()->export() ); |
| 337 | 361 | } |
| 338 | 362 | |
| 363 | + $apiErrorDateTime = $order->getLastApiErrorDateTime(); | |
| 364 | + if ( $apiErrorDateTime !== null ) { | |
| 365 | + $apiErrorDateTime = $apiErrorDateTime->format( CoreHelper::MYSQL_DATETIME_FORMAT ); | |
| 366 | + } | |
| 367 | + | |
| 339 | 368 | $data = [ |
| 340 | - 'id' => (int) $order->getNumber(), | |
| 341 | - 'carrier_id' => $order->getCarrierId(), | |
| 342 | - 'is_exported' => (int) $order->isExported(), | |
| 343 | - 'packet_id' => $order->getPacketId(), | |
| 344 | - 'packet_status' => $order->getPacketStatus(), | |
| 345 | - 'is_label_printed' => (int) $order->isLabelPrinted(), | |
| 346 | - 'carrier_number' => $order->getCarrierNumber(), | |
| 347 | - 'weight' => $order->getWeight(), | |
| 348 | - 'point_id' => $point->getId(), | |
| 349 | - 'point_name' => $point->getName(), | |
| 350 | - 'point_url' => $point->getUrl(), | |
| 351 | - 'point_street' => $point->getStreet(), | |
| 352 | - 'point_zip' => $point->getZip(), | |
| 353 | - 'point_city' => $point->getCity(), | |
| 354 | - 'address_validated' => (int) $order->isAddressValidated(), | |
| 355 | - 'delivery_address' => $deliveryAddress, | |
| 356 | - 'length' => $order->getLength(), | |
| 357 | - 'width' => $order->getWidth(), | |
| 358 | - 'height' => $order->getHeight(), | |
| 359 | - 'adult_content' => $order->containsAdultContent(), | |
| 360 | - 'cod' => $order->getCod(), | |
| 361 | - 'value' => $order->getValue(), | |
| 369 | + 'id' => (int) $order->getNumber(), | |
| 370 | + 'carrier_id' => $order->getCarrier()->getId(), | |
| 371 | + 'is_exported' => (int) $order->isExported(), | |
| 372 | + 'packet_id' => $order->getPacketId(), | |
| 373 | + 'packet_claim_id' => $order->getPacketClaimId(), | |
| 374 | + 'packet_claim_password' => $order->getPacketClaimPassword(), | |
| 375 | + 'packet_status' => $order->getPacketStatus(), | |
| 376 | + 'stored_until' => $this->coreHelper->getStringFromDateTime( $order->getStoredUntil(), CoreHelper::DATEPICKER_FORMAT ), | |
| 377 | + 'is_label_printed' => (int) $order->isLabelPrinted(), | |
| 378 | + 'carrier_number' => $order->getCarrierNumber(), | |
| 379 | + 'weight' => $order->getWeight(), | |
| 380 | + 'car_delivery_id' => $order->getCarDeliveryId(), | |
| 381 | + 'point_id' => $point->getId(), | |
| 382 | + 'point_name' => $point->getName(), | |
| 383 | + 'point_url' => $point->getUrl(), | |
| 384 | + 'point_street' => $point->getStreet(), | |
| 385 | + 'point_zip' => $point->getZip(), | |
| 386 | + 'point_city' => $point->getCity(), | |
| 387 | + 'address_validated' => (int) $order->isAddressValidated(), | |
| 388 | + 'delivery_address' => $deliveryAddress, | |
| 389 | + 'length' => $order->getLength(), | |
| 390 | + 'width' => $order->getWidth(), | |
| 391 | + 'height' => $order->getHeight(), | |
| 392 | + 'adult_content' => $order->containsAdultContent(), | |
| 393 | + 'cod' => $order->getManualCod(), | |
| 394 | + 'value' => $order->getManualValue(), | |
| 395 | + 'api_error_message' => $order->getLastApiErrorMessage(), | |
| 396 | + 'api_error_date' => $apiErrorDateTime, | |
| 397 | + 'deliver_on' => $this->coreHelper->getStringFromDateTime( $order->getDeliverOn(), CoreHelper::DATEPICKER_FORMAT ), | |
| 362 | 398 | ]; |
| 363 | 399 | |
| 364 | 400 | return $data; |
| 365 | 401 | } |
| @@ -371,37 +407,101 @@ | ||
| 371 | 407 | * |
| 372 | 408 | * @return void |
| 373 | 409 | */ |
| 374 | 410 | public function save( Order $order ): void { |
| 375 | - $this->wpdb->_insert_replace_helper( $this->wpdb->packetery_order, $this->orderToDbArray( $order ), null, 'REPLACE' ); | |
| 411 | + $this->saveData( $this->orderToDbArray( $order ) ); | |
| 376 | 412 | } |
| 377 | 413 | |
| 378 | 414 | /** |
| 415 | + * Saves order data. | |
| 416 | + * | |
| 417 | + * @param array<string, int|string|null|DateTimeImmutable> $orderData Order data. | |
| 418 | + * | |
| 419 | + * @return void | |
| 420 | + */ | |
| 421 | + public function saveData( array $orderData ): void { | |
| 422 | + $this->onBeforeDataInsertion( $orderData ); | |
| 423 | + $this->wpdbAdapter->insertReplaceHelper( $this->wpdbAdapter->packeteryOrder, $orderData, null, 'REPLACE' ); | |
| 424 | + } | |
| 425 | + | |
| 426 | + /** | |
| 427 | + * Calls logic before order data replace/insert. | |
| 428 | + * | |
| 429 | + * @param array<string, string|null|DateTimeImmutable> $orderData Order data. | |
| 430 | + * @return void | |
| 431 | + */ | |
| 432 | + private function onBeforeDataInsertion( array $orderData ): void { | |
| 433 | + $pointId = $orderData['point_id'] ?? null; | |
| 434 | + $carrierId = $orderData['carrier_id'] ?? null; | |
| 435 | + /** | |
| 436 | + * Tells if Packeta debug logs are enabled. | |
| 437 | + * | |
| 438 | + * @since 1.7.2 | |
| 439 | + */ | |
| 440 | + $isLoggingActive = (bool) apply_filters( 'packeta_enable_debug_logs', false ); | |
| 441 | + | |
| 442 | + if ( ( $pointId !== null && $pointId !== '' ) || ! $isLoggingActive || ! $this->pickupPointsConfig->isInternalPickupPointCarrier( $carrierId ) ) { | |
| 443 | + return; | |
| 444 | + } | |
| 445 | + | |
| 446 | + $wcLogger = wc_get_logger(); | |
| 447 | + $dataToLog = [ | |
| 448 | + 'order' => $orderData, | |
| 449 | + 'trace' => array_map( | |
| 450 | + static function ( array $item ): array { | |
| 451 | + return [ | |
| 452 | + 'file' => sprintf( '%s(%s)', $item['file'], $item['line'] ), | |
| 453 | + 'method' => sprintf( '%s%s%s(...)', $item['class'] ?? '', $item['type'] ?? '', $item['function'] ), | |
| 454 | + ]; | |
| 455 | + }, | |
| 456 | + ( new Exception() )->getTrace() | |
| 457 | + ), | |
| 458 | + ]; | |
| 459 | + $wcLogger->warning( | |
| 460 | + sprintf( | |
| 461 | + 'Required value for the pickup point order is not set: %s', | |
| 462 | + wp_json_encode( $dataToLog, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) | |
| 463 | + ), | |
| 464 | + [ 'source' => 'packeta' ] | |
| 465 | + ); | |
| 466 | + } | |
| 467 | + | |
| 468 | + /** | |
| 379 | 469 | * Loads order entities by list of ids. |
| 380 | 470 | * |
| 381 | - * @param array $orderIds Order ids. | |
| 471 | + * @param string[] $orderIds Order ids. | |
| 382 | 472 | * |
| 383 | 473 | * @return Order[] |
| 384 | 474 | */ |
| 385 | 475 | public function getByIds( array $orderIds ): array { |
| 476 | + if ( count( $orderIds ) === 0 ) { | |
| 477 | + return []; | |
| 478 | + } | |
| 479 | + | |
| 480 | + $wpdbAdapter = $this->wpdbAdapter; | |
| 481 | + $ordersIdsPlaceholder = implode( ', ', array_fill( 0, count( $orderIds ), '%d' ) ); | |
| 482 | + $packeteryOrdersResult = $wpdbAdapter->get_results( | |
| 483 | + $wpdbAdapter->prepare( | |
| 484 | + 'SELECT * FROM `' . $wpdbAdapter->packeteryOrder . '` | |
| 485 | + WHERE `id` IN (' . $ordersIdsPlaceholder . ')', | |
| 486 | + $orderIds | |
| 487 | + ), | |
| 488 | + OBJECT_K | |
| 489 | + ); | |
| 490 | + | |
| 386 | 491 | $orderEntities = []; |
| 387 | - $posts = get_posts( | |
| 388 | - [ | |
| 389 | - 'post_type' => 'shop_order', | |
| 390 | - 'post__in' => $orderIds, | |
| 391 | - 'post_status' => [ 'any', 'trash' ], | |
| 392 | - 'nopaging' => true, | |
| 393 | - ] | |
| 394 | - ); | |
| 395 | - foreach ( $posts as $post ) { | |
| 396 | - $wcOrder = wc_get_order( $post ); | |
| 397 | - // In case WC_Order does not exist, result set is limited to existing records. | |
| 398 | - if ( ! $wcOrder ) { | |
| 492 | + foreach ( $orderIds as $orderId ) { | |
| 493 | + if ( ! isset( $packeteryOrdersResult[ $orderId ] ) ) { | |
| 399 | 494 | continue; |
| 400 | 495 | } |
| 401 | - $order = $this->getByWcOrder( $wcOrder ); | |
| 402 | - if ( $order ) { | |
| 403 | - $orderEntities[ $order->getNumber() ] = $order; | |
| 496 | + | |
| 497 | + $wcOrder = $this->getWcOrderById( (int) $orderId ); | |
| 498 | + assert( $wcOrder !== null, 'WC order has to be present' ); | |
| 499 | + | |
| 500 | + try { | |
| 501 | + $orderEntities[ $orderId ] = $this->builder->build( $wcOrder, $packeteryOrdersResult[ $orderId ] ); | |
| 502 | + } catch ( InvalidCarrierException $exception ) { | |
| 503 | + continue; | |
| 404 | 504 | } |
| 405 | 505 | } |
| 406 | 506 | |
| 407 | 507 | return $orderEntities; |
| @@ -407,87 +507,79 @@ | ||
| 407 | 507 | return $orderEntities; |
| 408 | 508 | } |
| 409 | 509 | |
| 410 | 510 | /** |
| 411 | - * Quote array of strings. | |
| 412 | - * | |
| 413 | - * @param array $input Input. | |
| 414 | - * | |
| 415 | - * @return array | |
| 416 | - */ | |
| 417 | - private function quoteArrayOfStrings( array $input ): array { | |
| 418 | - return array_map( | |
| 419 | - function ( string $item ) { | |
| 420 | - $wpdb = $this->wpdb; | |
| 421 | - return $wpdb->prepare( '%s', $item ); | |
| 422 | - }, | |
| 423 | - $input | |
| 424 | - ); | |
| 425 | - } | |
| 426 | - | |
| 427 | - /** | |
| 428 | 511 | * Finds orders. |
| 429 | 512 | * |
| 430 | - * @param array $allowedPacketStatuses Allowed packet statuses. | |
| 431 | - * @param array $allowedOrderStatuses Allowed order statuses. | |
| 432 | - * @param int $maxDays Max number of days of single packet sync. | |
| 433 | - * @param int $limit Number of records. | |
| 513 | + * @param string[] $allowedPacketStatuses Allowed packet statuses. | |
| 514 | + * @param string[] $allowedOrderStatuses Allowed order statuses. | |
| 515 | + * @param int $maxDays Max number of days of single packet sync. | |
| 516 | + * @param int $limit Number of records. | |
| 434 | 517 | * |
| 435 | - * @return iterable|Order[] | |
| 518 | + * @return \Generator<int> | |
| 519 | + * @throws Exception Exception. | |
| 436 | 520 | */ |
| 437 | - public function findStatusSyncingOrders( array $allowedPacketStatuses, array $allowedOrderStatuses, int $maxDays, int $limit ): iterable { | |
| 438 | - $wpdb = $this->wpdb; | |
| 439 | - $dateLimit = Helper::now()->modify( '- ' . $maxDays . ' days' )->format( 'Y-m-d H:i:s' ); | |
| 521 | + public function findStatusSyncingOrderIds( array $allowedPacketStatuses, array $allowedOrderStatuses, int $maxDays, int $limit ): \Generator { | |
| 522 | + $dateLimit = CoreHelper::now()->modify( '- ' . $maxDays . ' days' )->format( 'Y-m-d H:i:s' ); | |
| 440 | 523 | |
| 441 | - $andWhere = []; | |
| 524 | + $andWhere = [ '`o`.`packet_id` IS NOT NULL' ]; | |
| 525 | + $hposEnabled = ModuleHelper::isHposEnabled(); | |
| 442 | 526 | |
| 443 | - $andWhere[] = 'o.`packet_id` IS NOT NULL'; | |
| 444 | - $andWhere[] = $wpdb->prepare( 'wp_p.`post_date_gmt` >= %s', $dateLimit ); | |
| 527 | + if ( $hposEnabled ) { | |
| 528 | + $andWhere[] = $this->wpdbAdapter->prepare( '`wc_o`.`date_created_gmt` >= %s', $dateLimit ); | |
| 529 | + } else { | |
| 530 | + $andWhere[] = $this->wpdbAdapter->prepare( '`wp_p`.`post_date_gmt` >= %s', $dateLimit ); | |
| 531 | + } | |
| 445 | 532 | |
| 446 | 533 | $orPacketStatus = []; |
| 447 | - $orPacketStatus[] = 'o.`packet_status` IS NULL'; | |
| 534 | + $orPacketStatus[] = '`o`.`packet_status` IS NULL'; | |
| 448 | 535 | |
| 449 | - if ( $allowedPacketStatuses ) { | |
| 450 | - $orPacketStatus[] = 'o.`packet_status` IN (' . implode( ',', $this->quoteArrayOfStrings( $allowedPacketStatuses ) ) . ')'; | |
| 536 | + if ( count( $allowedPacketStatuses ) > 0 ) { | |
| 537 | + $orPacketStatus[] = '`o`.`packet_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedPacketStatuses ) . ')'; | |
| 451 | 538 | } |
| 452 | 539 | |
| 453 | - if ( $orPacketStatus ) { | |
| 540 | + if ( count( $orPacketStatus ) > 0 ) { | |
| 454 | 541 | $andWhere[] = '(' . implode( ' OR ', $orPacketStatus ) . ')'; |
| 455 | 542 | } |
| 456 | 543 | |
| 457 | - if ( $allowedOrderStatuses ) { | |
| 458 | - $andWhere[] = 'wp_p.`post_status` IN (' . implode( ',', $this->quoteArrayOfStrings( $allowedOrderStatuses ) ) . ')'; | |
| 544 | + if ( count( $allowedOrderStatuses ) > 0 && $hposEnabled ) { | |
| 545 | + $andWhere[] = '`wc_o`.`status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')'; | |
| 546 | + } elseif ( count( $allowedOrderStatuses ) > 0 && $hposEnabled === false ) { | |
| 547 | + $andWhere[] = '`wp_p`.`post_status` IN (' . $this->wpdbAdapter->prepareInClause( $allowedOrderStatuses ) . ')'; | |
| 459 | 548 | } else { |
| 460 | 549 | $andWhere[] = '1 = 0'; |
| 461 | 550 | } |
| 462 | 551 | |
| 463 | 552 | $where = ''; |
| 464 | - if ( $andWhere ) { | |
| 553 | + if ( count( $andWhere ) > 0 ) { | |
| 465 | 554 | $where = ' WHERE ' . implode( ' AND ', $andWhere ); |
| 466 | 555 | } |
| 467 | 556 | |
| 468 | - // @codingStandardsIgnoreStart | |
| 469 | - $sql = $wpdb->prepare( | |
| 557 | + if ( $hposEnabled ) { | |
| 558 | + $orderBy = ' ORDER BY `wc_o`.`date_created_gmt` '; | |
| 559 | + } else { | |
| 560 | + $orderBy = ' ORDER BY `wp_p`.`post_date_gmt` '; | |
| 561 | + } | |
| 562 | + | |
| 563 | + $sql = $this->wpdbAdapter->prepare( | |
| 470 | 564 | ' |
| 471 | - SELECT o.* FROM `' . $wpdb->packetery_order . '` o | |
| 472 | - JOIN `' . $wpdb->posts . '` wp_p ON wp_p.`ID` = o.`id` | |
| 565 | + SELECT `o`.`id` FROM `' . $this->wpdbAdapter->packeteryOrder . '` `o` | |
| 566 | + ' . $this->getWcOrderJoinClause() . ' | |
| 473 | 567 | ' . $where . ' |
| 474 | - ORDER BY wp_p.`post_date` | |
| 568 | + ' . $orderBy . ' | |
| 475 | 569 | LIMIT %d', |
| 476 | 570 | $limit |
| 477 | 571 | ); |
| 478 | 572 | |
| 479 | - $rows = $wpdb->get_results( $sql ); | |
| 480 | - // @codingStandardsIgnoreEnd | |
| 573 | + $rows = $this->wpdbAdapter->get_results( $sql ); | |
| 481 | 574 | |
| 482 | 575 | foreach ( $rows as $row ) { |
| 483 | - $wcOrder = wc_get_order( $row->id ); | |
| 484 | - if ( false === $wcOrder || ! $wcOrder->has_shipping_method( ShippingMethod::PACKETERY_METHOD_ID ) ) { | |
| 576 | + $wcOrder = $this->getWcOrderById( (int) $row->id ); | |
| 577 | + if ( $wcOrder === null || ! ShippingProvider::wcOrderHasOurMethod( $wcOrder ) ) { | |
| 485 | 578 | continue; |
| 486 | 579 | } |
| 487 | 580 | |
| 488 | - $partial = $this->createPartialOrder( $row ); | |
| 489 | - yield $this->builder->finalize( $wcOrder, $partial ); | |
| 581 | + yield (int) $row->id; | |
| 490 | 582 | } |
| 491 | 583 | } |
| 492 | 584 | |
| 493 | 585 | /** |
| @@ -495,15 +587,9 @@ | ||
| 495 | 587 | * |
| 496 | 588 | * @return int |
| 497 | 589 | */ |
| 498 | 590 | public function countOrdersToSubmit(): int { |
| 499 | - $wpdb = $this->wpdb; | |
| 500 | - | |
| 501 | - return (int) $wpdb->get_var( | |
| 502 | - 'SELECT COUNT(DISTINCT o.id) FROM `' . $wpdb->packetery_order . '` o | |
| 503 | - JOIN `' . $wpdb->posts . '` wp_p ON wp_p.`ID` = o.`id` | |
| 504 | - WHERE o.`carrier_id` IS NOT NULL AND o.`is_exported` = false' | |
| 505 | - ); | |
| 591 | + return $this->countOrders( [ 'packetery_to_submit' => '1' ] ); | |
| 506 | 592 | } |
| 507 | 593 | |
| 508 | 594 | /** |
| 509 | 595 | * Counts order to be printed. |
| @@ -510,76 +596,104 @@ | ||
| 510 | 596 | * |
| 511 | 597 | * @return int |
| 512 | 598 | */ |
| 513 | 599 | public function countOrdersToPrint(): int { |
| 514 | - $wpdb = $this->wpdb; | |
| 515 | - | |
| 516 | - return (int) $wpdb->get_var( | |
| 517 | - 'SELECT COUNT(DISTINCT o.id) FROM `' . $wpdb->packetery_order . '` o | |
| 518 | - JOIN `' . $wpdb->posts . '` wp_p ON wp_p.`ID` = o.`id` | |
| 519 | - WHERE o.`packet_id` IS NOT NULL AND o.`is_label_printed` = false' | |
| 520 | - ); | |
| 600 | + return $this->countOrders( [ 'packetery_to_print' => '1' ] ); | |
| 521 | 601 | } |
| 522 | 602 | |
| 523 | 603 | /** |
| 524 | - * Deletes all custom table records linked to permanently deleted orders. | |
| 604 | + * Counts orders by given params. | |
| 525 | 605 | * |
| 526 | - * @return void | |
| 606 | + * @param array<string, string> $params Params. | |
| 607 | + * | |
| 608 | + * @return int | |
| 527 | 609 | */ |
| 528 | - public function deleteOrphans(): void { | |
| 529 | - $wpdb = $this->wpdb; | |
| 610 | + private function countOrders( array $params ): int { | |
| 611 | + $clauses = [ 'join' => '' ]; | |
| 530 | 612 | |
| 531 | - $wpdb->query( | |
| 532 | - 'DELETE `' . $wpdb->packetery_order . '` FROM `' . $wpdb->packetery_order . '` | |
| 533 | - LEFT JOIN `' . $wpdb->posts . '` ON `' . $wpdb->posts . '`.`ID` = `' . $wpdb->packetery_order . '`.`id` | |
| 534 | - WHERE `' . $wpdb->posts . '`.`ID` IS NULL' | |
| 613 | + if ( ModuleHelper::isHposEnabled() ) { | |
| 614 | + $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->wcOrders . '`.`id`) '; | |
| 615 | + $clauses['from'] = ' FROM `' . $this->wpdbAdapter->wcOrders . '` '; | |
| 616 | + } else { | |
| 617 | + $clauses['select'] = ' SELECT COUNT(DISTINCT `' . $this->wpdbAdapter->posts . '`.`ID`) '; | |
| 618 | + $clauses['from'] = ' FROM `' . $this->wpdbAdapter->posts . '` '; | |
| 619 | + } | |
| 620 | + | |
| 621 | + $clauses['where'] = ' WHERE `' . $this->wpdbAdapter->packeteryOrder . '`.`id` IS NOT NULL '; | |
| 622 | + $clauses = $this->processClauses( $clauses, null, $params ); | |
| 623 | + | |
| 624 | + return (int) $this->wpdbAdapter->get_var( | |
| 625 | + $clauses['select'] . | |
| 626 | + $clauses['from'] . | |
| 627 | + $clauses['join'] . | |
| 628 | + $clauses['where'] | |
| 535 | 629 | ); |
| 536 | 630 | } |
| 537 | 631 | |
| 538 | 632 | /** |
| 539 | - * Adds adult content column. | |
| 633 | + * Gets WC Order join clause. | |
| 540 | 634 | * |
| 541 | - * @return void | |
| 635 | + * @return string | |
| 542 | 636 | */ |
| 543 | - public function addAdultContentColumn(): void { | |
| 544 | - $wpdb = $this->wpdb; | |
| 637 | + public function getWcOrderJoinClause(): string { | |
| 638 | + $packeteryTableAlias = 'o'; | |
| 545 | 639 | |
| 546 | - $wpdb->query( 'ALTER TABLE `' . $wpdb->packetery_order . '` ADD COLUMN `adult_content` boolean NULL DEFAULT NULL AFTER `height`' ); | |
| 547 | - } | |
| 640 | + if ( ModuleHelper::isHposEnabled() ) { | |
| 641 | + $sourceTableAlias = 'wc_o'; | |
| 548 | 642 | |
| 549 | - /** | |
| 550 | - * Adds value column. | |
| 551 | - * | |
| 552 | - * @return void | |
| 553 | - */ | |
| 554 | - public function addValueColumn(): void { | |
| 555 | - $wpdb = $this->wpdb; | |
| 643 | + return sprintf( | |
| 644 | + 'JOIN `%s` `%s` ON `%s`.`id` = `%s`.`id`', | |
| 645 | + $this->wpdbAdapter->wcOrders, | |
| 646 | + $sourceTableAlias, | |
| 647 | + $sourceTableAlias, | |
| 648 | + $packeteryTableAlias | |
| 649 | + ); | |
| 650 | + } | |
| 556 | 651 | |
| 557 | - $wpdb->query( 'ALTER TABLE `' . $wpdb->packetery_order . '` ADD COLUMN `value` double NULL DEFAULT NULL AFTER `adult_content`' ); | |
| 652 | + $sourceTableAlias = 'wp_p'; | |
| 653 | + | |
| 654 | + return sprintf( | |
| 655 | + 'JOIN `%s` `%s` ON `%s`.`ID` = `%s`.`id`', | |
| 656 | + $this->wpdbAdapter->posts, | |
| 657 | + $sourceTableAlias, | |
| 658 | + $sourceTableAlias, | |
| 659 | + $packeteryTableAlias | |
| 660 | + ); | |
| 558 | 661 | } |
| 559 | 662 | |
| 560 | 663 | /** |
| 561 | - * Adds COD column. | |
| 664 | + * Deletes all custom table records linked to permanently deleted orders. | |
| 562 | 665 | * |
| 563 | 666 | * @return void |
| 564 | 667 | */ |
| 565 | - public function addCodColumn(): void { | |
| 566 | - $wpdb = $this->wpdb; | |
| 668 | + public function deleteOrphans(): void { | |
| 669 | + if ( ModuleHelper::isHposEnabled() ) { | |
| 670 | + $this->wpdbAdapter->query( | |
| 671 | + 'DELETE `' . $this->wpdbAdapter->packeteryOrder . '` FROM `' . $this->wpdbAdapter->packeteryOrder . '` | |
| 672 | + LEFT JOIN `' . $this->wpdbAdapter->wcOrders . '` ON `' . $this->wpdbAdapter->wcOrders . '`.`id` = `' . $this->wpdbAdapter->packeteryOrder . '`.`id` | |
| 673 | + WHERE `' . $this->wpdbAdapter->wcOrders . '`.`id` IS NULL' | |
| 674 | + ); | |
| 567 | 675 | |
| 568 | - $wpdb->query( 'ALTER TABLE `' . $wpdb->packetery_order . '` ADD COLUMN `cod` double NULL DEFAULT NULL AFTER `value`' ); | |
| 676 | + return; | |
| 677 | + } | |
| 678 | + | |
| 679 | + $this->wpdbAdapter->query( | |
| 680 | + 'DELETE `' . $this->wpdbAdapter->packeteryOrder . '` FROM `' . $this->wpdbAdapter->packeteryOrder . '` | |
| 681 | + LEFT JOIN `' . $this->wpdbAdapter->posts . '` ON `' . $this->wpdbAdapter->posts . '`.`ID` = `' . $this->wpdbAdapter->packeteryOrder . '`.`id` | |
| 682 | + WHERE `' . $this->wpdbAdapter->posts . '`.`ID` IS NULL' | |
| 683 | + ); | |
| 569 | 684 | } |
| 570 | 685 | |
| 571 | 686 | /** |
| 572 | - * Deletes data from custom table. | |
| 687 | + * Deletes order data including customs declaration and its items from custom tables. | |
| 573 | 688 | * |
| 574 | 689 | * @param int $orderId Order id. |
| 575 | 690 | * |
| 576 | 691 | * @return void |
| 577 | 692 | */ |
| 578 | - private function delete( int $orderId ): void { | |
| 579 | - $wpdb = $this->wpdb; | |
| 580 | - | |
| 581 | - $wpdb->delete( $wpdb->packetery_order, [ 'id' => $orderId ], '%d' ); | |
| 693 | + public function delete( int $orderId ): void { | |
| 694 | + $this->customsDeclarationRepository->delete( (string) $orderId ); | |
| 695 | + $this->wpdbAdapter->delete( $this->wpdbAdapter->packeteryOrder, [ 'id' => $orderId ], '%d' ); | |
| 582 | 696 | } |
| 583 | 697 | |
| 584 | 698 | /** |
| 585 | 699 | * Fires after post deletion. |
| @@ -589,10 +703,26 @@ | ||
| 589 | 703 | * |
| 590 | 704 | * @return void |
| 591 | 705 | */ |
| 592 | 706 | public function deletedPostHook( int $postId, WP_Post $post ): void { |
| 593 | - if ( 'shop_order' === $post->post_type ) { | |
| 707 | + // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps | |
| 708 | + if ( $post->post_type === 'shop_order' ) { | |
| 594 | 709 | $this->delete( $postId ); |
| 595 | 710 | } |
| 596 | 711 | } |
| 597 | 712 | |
| 713 | + /** | |
| 714 | + * Gets WC_Order object. | |
| 715 | + * | |
| 716 | + * @param int $id Order id. | |
| 717 | + * | |
| 718 | + * @return WC_Order|null | |
| 719 | + */ | |
| 720 | + public function getWcOrderById( int $id ): ?WC_Order { | |
| 721 | + $result = wc_get_order( $id ); | |
| 722 | + if ( $result instanceof WC_Order ) { | |
| 723 | + return $result; | |
| 724 | + } | |
| 725 | + | |
| 726 | + return null; | |
| 727 | + } | |
| 598 | 728 | } |