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