PluginProbe
Route ‑ Shipping Protection / 2.4.18
Route ‑ Shipping Protection v2.4.18
2.4.19 2.4.18 2.4.17 2.4.16 2.4.15 2.4.14 2.4.13 2.4.12 2.4.11 2.4.10 2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.2.4 2.2.5 2.2.6 2.2.8 2.2.9 2.3.0 2.3.1 All 153 releases
← All changes | admin/class-routeapp-order-recover.php +102 -4 2.4.12 → 2.4.18 View file →
@@ -62,12 +62,16 @@
62 62
63 63 $orders = $this->getOrdersBatch($batchSize, $offset, $recoverTo, $recoverFrom);
64 64
65 65 if (!empty($orders)) {
66 - $this->processOrders($orders);
67 - wp_send_json_success(array(
66 + $process_result = $this->processOrders($orders);
67 + $response = array(
68 68 'processed' => count($orders),
69 - ));
69 + );
70 + if (!empty($process_result['tracking_warning'])) {
71 + $response['tracking_warning'] = $process_result['tracking_warning'];
72 + }
73 + wp_send_json_success($response);
70 74 } else {
71 75 wp_send_json_error(array(
72 76 'message' => __('No more orders to process.', 'routeapp'),
73 77 ));
@@ -110,16 +114,110 @@
110 114 }
111 115
112 116 /**
113 117 * Processes the fetched orders by either updating order post meta or performing a massive order save operation.
118 + * Optionally syncs tracking/shipments when the Sync tracking numbers checkbox is enabled.
114 119 *
115 120 * @param array $orders The fetched orders to be processed.
121 + * @return array{
122 + * tracking_warning?: string
123 + * }
116 124 */
117 125 private function processOrders($orders) {
118 - if (isset($_POST['routeapp_order_recover_reconcile_backend'])) {
126 + $result = array();
127 +
128 + if (isset($_POST['routeapp_order_recover_reconcile_backend']) && $_POST['routeapp_order_recover_reconcile_backend']) {
119 129 $this->updateOrderPostMeta($orders);
120 130 } else {
121 131 $this->massiveOrderSave($orders);
132 + }
133 +
134 + if (isset($_POST['routeapp_order_recover_sync_tracking']) && $_POST['routeapp_order_recover_sync_tracking']) {
135 + $tracking_warning = $this->syncOrderTrackings($orders);
136 + if ($tracking_warning) {
137 + $result['tracking_warning'] = $tracking_warning;
138 + }
139 + }
140 +
141 + return $result;
142 + }
143 +
144 + /**
145 + * Force-sync tracking numbers / shipments to Route for the given orders.
146 + * Clears local shipment sync flags first so providers re-check Route and
147 + * create missing shipments, then runs the original provider update paths.
148 + *
149 + * @param array $orders Orders to sync tracking for.
150 + * @return string|null Warning message when tracking sync could not run, otherwise null.
151 + */
152 + private function syncOrderTrackings($orders) {
153 + $routeapp = Routeapp_Cron_Schedules::get_route_public_instance();
154 + if (!$routeapp) {
155 + $warning = __( 'Tracking sync skipped: Route App instance is unavailable. Confirm the plugin is active and configured.', 'routeapp' );
156 + error_log( '[routeapp] order_recover_sync_tracking: ' . $warning );
157 + return $warning;
158 + }
159 +
160 + $shipment_tracking = new Routeapp_Shipment_Tracking();
161 +
162 + foreach ($orders as $order) {
163 + if (!$order) {
164 + continue;
165 + }
166 +
167 + $order_id = $order->get_id();
168 +
169 + try {
170 + $this->clearLocalShipmentSyncMeta($order);
171 + $shipment_tracking->update($order_id, $routeapp);
172 + $shipment_tracking->parse_order_notes($order_id, $routeapp);
173 + } catch (Exception $exception) {
174 + // Keep processing the rest of the batch if one order fails.
175 + $routeapp->routeapp_log($exception, array(
176 + 'endpoint' => 'order_recover_sync_tracking',
177 + 'params' => array(
178 + 'source_order_id' => $order_id,
179 + ),
180 + 'method' => 'POST',
181 + ));
182 + continue;
183 + }
184 + }
185 +
186 + return null;
187 + }
188 +
189 + /**
190 + * Remove local meta that marks shipment sync as already completed.
191 + * Needed to force a resync when Woo meta says success but Route has no shipment.
192 + *
193 + * @param \WC_Order $order Order to clear.
194 + * @return void
195 + */
196 + private function clearLocalShipmentSyncMeta($order) {
197 + $meta_keys = array(
198 + 'routeapp_shipment_api_called',
199 + 'routeapp_shipment_tracking_number',
200 + 'routeapp_shipment_tracking_provider',
201 + 'routeapp_shipment_cron_api_called',
202 + );
203 +
204 + if ( $this->is_hpos_enabled() ) {
205 + $deleted = false;
206 + foreach ( $meta_keys as $meta_key ) {
207 + if ( $order->meta_exists( $meta_key ) ) {
208 + $order->delete_meta_data( $meta_key );
209 + $deleted = true;
210 + }
211 + }
212 + if ( $deleted ) {
213 + $order->save();
214 + }
215 + return;
216 + }
217 +
218 + foreach ( $meta_keys as $meta_key ) {
219 + delete_post_meta( $order->get_id(), $meta_key );
122 220 }
123 221 }
124 222
125 223 /**