PluginProbe
MBE eShip / trunk
MBE eShip vtrunk
2.8.1 trunk 1.0.0 1.1.0 1.1.3 1.2.1 1.2.2 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.6.0 1.7.0 1.7.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.0 2.1.1 2.1.2 2.2.1 All 37 releases
mail-boxes-etc / includes / class-mbe-order.php

class-mbe-order.php in MBE eShip trunk, at includes/class-mbe-order.php

982 lines 42.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Dompdf\Dompdf;
4 use \iio\libmergepdf\Merger;
5 use \iio\libmergepdf\Driver\TcpdiDriver;
6
7 if ( ! class_exists( 'WP_List_Table' ) ) {
8 require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
9 }
10
11 class Mbe_E_Link_Order_List_Table extends WP_List_Table {
12
13 use \Traits\ShipmentActions;
14
15 protected $helper;
16 protected $logger;
17 protected $ws;
18 protected $mustCloseShipments;
19
20 function __construct() {
21 global $status, $page;
22
23 parent::__construct( array(
24 'singular' => 'order', //singular name of the listed records
25 'plural' => 'orders', //plural name of the listed records
26 'ajax' => true //does this table support ajax?
27 ) );
28 $this->ws = new Mbe_Shipping_Model_Ws();
29 $this->helper = new Mbe_Shipping_Helper_Data();
30 $this->logger = new Mbe_Shipping_Helper_Logger();
31 }
32
33 function column_ID( $item ) {
34
35 $actions = array(
36 'edit' => sprintf( '<a href="' . get_home_url() . '/wp-admin/post.php?post=%s&action=edit">%s</a>', $this->itemId( $item ), __( 'Edit', 'mail-boxes-etc' ) ),
37 );
38
39 return sprintf( '%s %s',
40 $this->itemId( $item ),
41 $this->row_actions( $actions )
42 );
43
44 return sprintf( '%1$s <span style="color:silver"></span>%2$s', $this->itemId( $item ), $this->row_actions( $actions ) );
45 }
46
47 function column_post_author( $item ) {
48 $order = wc_get_order( $this->itemId( $item ) );
49
50 if ( version_compare( WC()->version, '3', '>=' ) ) {
51 $billingFirstName = $order->get_billing_first_name();
52 $billingLastName = $order->get_billing_last_name();
53 } else {
54 $billingFirstName = $order->billing_first_name;
55 $billingLastName = $order->billing_last_name;
56 }
57
58 return sprintf( '%1$s %2$s', $billingFirstName, $billingLastName );
59 }
60
61 function column_carrier( $item ) {
62 //TODO: verify
63 $order = wc_get_order( $this->itemId( $item ) );
64 $serviceName = $this->helper->getServiceName( $order );
65
66 return $serviceName;
67 //return sprintf('%s', get_post_meta($this->itemId($item), 'woocommerce_mbe_tracking_name', true));
68 }
69
70
71 function column_tracking( $item ) {
72 $trackings = $this->helper->getTrackings( $this->itemId( $item ) );
73 if ( empty( $trackings ) ) {
74 return '';
75 } else {
76 $returnTracking = $this->helper->getReturnTrackings( $this->itemId( $item ) ) ?? null;
77 $html = '';
78
79 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
80 $order = wc_get_order( $this->itemId( $item ) );
81 $url = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL);
82 } else {
83 $url = get_post_meta( $this->itemId( $item ), Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL, true );
84 }
85
86 $trackingString = $this->helper->getTrackingsString( $this->itemId( $item ) );
87 if ( count( $trackings ) > 1 ) {
88 $html .= "<a target='_blank' href=" . $url . $trackingString . ">" . __( 'Track all', 'mail-boxes-etc' ) . "</a><br/>";
89 }
90
91
92 $i = 0;
93 foreach ( $trackings as $t ) {
94 if ( $i > 0 ) {
95 $html .= "<br/>";
96 }
97 $html .= "<a target='_blank' href=" . $url . $t . ">" . $t . "</a>";
98 $i ++;
99 }
100
101 return '<table style="height: 100%">
102 <tbody>
103 <tr style="height: 50%"><td>' . $html . '</td></tr>'
104 . ( $returnTracking ? ( '<tr style="height: 50%"><td><span style="font-style: normal; font-weight: bold; color: #666;">' . __( 'Return shipment', 'mail-boxes-etc' ) . ':</span> <span style="font-style: italic;">' . $returnTracking . '</span></td></tr>' ) : '' )
105 . '</tbody>
106 </table>';
107 // return $html;
108 }
109 }
110
111 function column_courier_tracking( $item ) {
112 $courierName = $this->helper->getCourierName( $this->itemId( $item ) );
113 $trackings = $this->helper->getCourierTrackings( $this->itemId( $item ) );
114
115 if ( $courierName === 'MBE' ) {
116 return 'N/A';
117 }
118
119 if ( empty( $trackings ) ) {
120 return '';
121 } else {
122 $returnCourierTracking = $this->helper->getReturnCourierTrackings( $this->itemId( $item ) ) ?? null;
123 $html = '';
124 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
125 $order = wc_get_order( $this->itemId( $item ) );
126 $url = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL);
127 } else {
128 $url = get_post_meta( $this->itemId( $item ), Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL, true );
129 }
130
131 $trackingString = $this->helper->getCourierTrackingsString( $this->itemId( $item ) );
132 if ( count( $trackings ) > 1 ) {
133 $html .= "<a style=' word-wrap:anywhere;' target='_blank' href=" . $url . $trackingString . ">" . __( 'Track all', 'mail-boxes-etc' ) . "</a><br/>";
134 }
135
136 $i = 0;
137 foreach ( $trackings as $t ) {
138 if ( $i > 0 ) {
139 $html .= "<br/>";
140 }
141 $html .= "<a style=' word-wrap:anywhere;' target='_blank' href=" . $url . $t . ">" . $t . "</a>";
142 $i ++;
143 }
144
145 return '<table style="height: 100%">
146 <tbody>
147 <tr style="height: 50%"><td>' . $html . '</td></tr>'
148 . ( $returnCourierTracking ? ( '<tr style="height: 50%"><td><span style="font-style: normal; font-weight: bold; color: #666;">' . __( 'Return shipment', 'mail-boxes-etc' ) . ':</span> <span style="font-style: italic; word-wrap:anywhere;">' . $returnCourierTracking . '</span></td></tr>' ) : '' )
149 . '</tbody>
150 </table>';
151
152 // return $html;
153 }
154 }
155
156 function column_courier_name( $item ) {
157 return '<table style="height: 100%">
158 <tbody>
159 <tr style="height: 50%"><td>' . $this->helper->getCourierName( $this->itemId( $item ) ) . '</td></tr>'
160 . ( $this->helper->getReturnCourierName( $this->itemId( $item ) ) ? ( '<tr style="height: 50%"><td><span style="font-style: normal; font-weight: bold; color: #666;">' . __( 'Return shipment', 'mail-boxes-etc' ) . ':</span> <span style="font-style: italic; word-wrap:anywhere;">' . $this->helper->getReturnCourierName( $this->itemId( $item ) ) . '</span></td></tr>' ) : '' )
161 . '</tbody>
162 </table>';
163 }
164
165 function column_tracking_status( $item ) {
166 $trackingFullData = $this->helper->getTrackingFullData( $this->itemId( $item ) );
167 $trackingAdvancedReturnFullData = $this->helper->getAdvancedReturnTrackingFullData( $this->itemId( $item ) );
168
169 $trackingMBEstatus = sanitize_text_field( $trackingFullData['mbeStatusDescription'] ?? '' );
170 $trackingMBEAdvancedReturnStatus = sanitize_text_field( $trackingAdvancedReturnFullData['mbeStatusDescription'] ?? '' );
171
172 if ( empty( $trackingMBEstatus ) && empty( $trackingMBEAdvancedReturnStatus ) ) {
173 return '';
174 } else {
175 $color = $this->helper->getTrackingStatusColor( $trackingMBEstatus );
176 $colorAdvancedReturn = $this->helper->getTrackingStatusColor( $trackingMBEAdvancedReturnStatus );
177 $trackingcourierStatusDescription = sanitize_text_field( __( $trackingFullData['courierStatusDescription'] ?? '', 'mail-boxes-etc' ) );
178 $trackingcourierAdvancedReturnStatusDescription = sanitize_text_field( __( $trackingAdvancedReturnFullData['courierStatusDescription'] ?? '', 'mail-boxes-etc' ) );
179
180 $htmlTrackingStatus = "<span style='font-size: small; font-weight: bold; float: left; color:$color; padding:4px ;text-align: center;border-radius: 5px; margin: 3px;' title='" . esc_attr( $trackingcourierStatusDescription ) . "'>" .
181 esc_html( __( $trackingMBEstatus, 'mail-boxes-etc' ) )
182 . "</span>";
183
184 $htmlAdvancedReturnTrackingStatus = "<span style='font-size: small; font-weight: bold; float: left; color:$colorAdvancedReturn; padding:4px ;text-align: center;border-radius: 5px; margin: 3px;' title='" . esc_attr( $trackingcourierAdvancedReturnStatusDescription ) . "'>" .
185 esc_html( __( $trackingMBEAdvancedReturnStatus, 'mail-boxes-etc' ) )
186 . "</span>";
187
188
189 return '<table style="height: 100%">
190 <tbody>
191 <tr style="min-height: 50%"><td>&nbsp;' . $htmlTrackingStatus . '</td></tr>'
192
193 . ( $trackingMBEAdvancedReturnStatus ? '<tr style="min-height: 50%"><td><span style="font-style: normal; font-weight: bold; color: #666;">' . __( 'Return shipment', 'mail-boxes-etc' ) . ':</span> <span style="font-style: italic;">' . $htmlAdvancedReturnTrackingStatus . '</span></td></tr>' : '' )
194 . '</tbody>
195 </table>';
196
197 }
198 }
199
200 function column_post_date( $item ) {
201 $order = wc_get_order( $this->itemId( $item ) );
202 $date = new DateTimeImmutable( $order->get_date_created() );
203
204 return wp_date( get_option( 'date_format' ), $date->getTimestamp() );
205 }
206
207 function column_total( $item ) {
208 $order = wc_get_order( $this->itemId( $item ) );
209
210 return $order->get_total() . ' &euro;';
211 }
212
213 function column_payment( $item ) {
214 $order = wc_get_order( $this->itemId( $item ) );
215 if ( version_compare( WC()->version, '3', '>=' ) ) {
216 $paymentMethodTitle = $order->get_payment_method_title();
217 } else {
218 $paymentMethodTitle = $order->payment_method_title;
219 }
220
221 return $paymentMethodTitle;
222 }
223
224 function column_status( $item ) {
225 return $this->helper->isShippingOpen( $this->itemId( $item ) ) ? __( 'Opened', 'mail-boxes-etc' ) : __( 'Closed', 'mail-boxes-etc' );
226 }
227
228 function column_files( $item ) {
229 if ( $this->helper->isDeliveryPointOrder( $this->itemId( $item ) ) && $this->helper->hasTracking( $this->itemId( $item ) ) ) {
230 $actionUrl = sprintf( "%sadmin-post.php?action=mbe_download_delivery_point_waybill&mbe_delivery_point_postid=%s&nonce=%s", get_admin_url(), $this->itemId( $item ), wp_create_nonce( 'mbe_download_delivery_point_waybill' ) );
231 return ' <button style="margin: 0px 5px 0px 5px; color:#778899FF; cursor:pointer" type="button" title="' . __( 'Download waybill', 'mail-boxes-etc' ) . '"
232 onclick="mbeButtonAction(this, \'' . $actionUrl . '\',\'_self\', \'false\')">
233 <svg style="height: 20px;width: 20px; padding-top: 4px" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
234 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 9h6m-6 3h6m-6 3h6M7 9h0m0 3h0m0 3h0M4 5h16c.6 0 1 .4 1 1v12c0 .6-.4 1-1 1H4a1 1 0 0 1-1-1V6c0-.6.4-1 1-1Z"/>
235 </svg>
236 </input>';
237 } else {
238 $files = $this->helper->getFileNames( $this->itemId( $item ));
239 $filesReturn = $this->helper->getFileNames( $this->itemId( $item ), Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_RETURN_TRACKING_FILENAME );
240
241 $trackings = $this->helper->getTrackings( $this->itemId( $item ) );
242 $trackingReturn = $this->helper->getReturnTrackings( $this->itemId( $item ) );
243
244 $filesHtml = $this->getFilesHtmlBlock( $files, $trackings );
245 $filesReturnHtml = $this->getFilesHtmlBlock( $filesReturn, [$trackingReturn] );
246
247 return '<table style="height: 100%">
248 <tbody>
249 <tr style="min-height: 50%"><td>&nbsp;' . $filesHtml . '</td></tr>'
250
251 . ( $filesReturnHtml ? '<tr style="min-height: 50%"><td><span style="font-style: normal; font-weight: bold; color: #666;">' . __( 'Return shipment', 'mail-boxes-etc' ) . ':</span> <span style="font-style: italic;">' . $filesReturnHtml . '</span></td></tr>' : '' )
252 . '</tbody>
253 </table>';
254 }
255 }
256
257 function column_pickup_manifest( $item ) {
258 if ( $this->helper->isPickupShipped( $this->itemId( $item ) ) && $this->helper->hasTracking( $this->itemId( $item ) ) ) {
259 return '<a href="' . get_admin_url() . 'admin-post.php?action=mbe_download_pickup_manifest&mbe_pickup_postid=' . $this->itemId( $item ) . '&nonce=' . wp_create_nonce( 'mbe_download_pickup_manifest' ) . '">
260 <button style="margin: 0px 5px 0px 5px; color:#778899FF; cursor:pointer" type="button" title="' . __( 'Download manifest', 'mail-boxes-etc' ) . '">
261 <svg style="height: 20px;width: 20px; padding-top: 4px" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
262 <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.5 10.25a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Zm0 0a2.225 2.225 0 0 0-1.666.75H12m3.5-.75a2.225 2.225 0 0 1 1.666.75H19V7m-7 4V3h5l2 4m-7 4H6.166a2.225 2.225 0 0 0-1.666-.75M12 11V2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v9h1.834a2.225 2.225 0 0 1 1.666-.75M19 7h-6m-8.5 3.25a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"/>
263 </svg>
264 </button>
265 </a>';
266 // return '<form action="' . esc_url( admin_url( 'admin-post.php' ) ) .'" method="post" id="mbe_download_pickup_manifest" style="display: inline-flex">
267 // <input type="hidden" name="action" value="mbe_download_pickup_manifest"/>
268 // <input type="hidden" name="nonce" value="'.wp_create_nonce('mbe_download_pickup_manifest') .'"/>
269 // <input type="hidden" name="mbe_pickup_postid" value="'. urlencode( $this->itemId($item) ).'"/>
270 //
271 // <button type="button" style="margin: 0px 5px 0px 5px; color:#778899FF" title="'.__('Download manifest', 'mail-boxes-etc').'">
272 // <svg style="height: 16px;width: 16px; padding-top: 4px" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
273 // <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.5 10.25a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Zm0 0a2.225 2.225 0 0 0-1.666.75H12m3.5-.75a2.225 2.225 0 0 1 1.666.75H19V7m-7 4V3h5l2 4m-7 4H6.166a2.225 2.225 0 0 0-1.666-.75M12 11V2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v9h1.834a2.225 2.225 0 0 1 1.666-.75M19 7h-6m-8.5 3.25a2.25 2.25 0 1 0 0 4.5 2.25 2.25 0 0 0 0-4.5Z"/>
274 // </svg>
275 // </button>
276 // </form>';
277 }
278 }
279
280 function column_cb( $item ) {
281 return sprintf(
282 '<input type="checkbox" name="id[]" value="%s" />',
283 // $this->itemId($item)
284 $this->itemId( $item )
285 );
286 }
287
288 function get_columns() {
289 $columns = array( 'cb' => '<input type="checkbox" />' );
290 $columns['id'] = __( 'Id', 'mail-boxes-etc' );
291
292 if ( $this->mustCloseShipments ) {
293 $columns['status'] = __( 'Status', 'mail-boxes-etc' );
294 }
295 $columns['post_author'] = __( 'Customer', 'mail-boxes-etc' );
296 $columns['payment'] = __( 'Payment', 'mail-boxes-etc' );
297 $columns['post_date'] = __( 'Date', 'mail-boxes-etc' );
298 $columns['total'] = __( 'Total', 'mail-boxes-etc' );
299 $columns['carrier'] = __( 'Carrier', 'mail-boxes-etc' );
300 $columns['tracking_status'] = __( 'Status', 'mail-boxes-etc' );
301 $columns['tracking'] = __( 'Tracking', 'mail-boxes-etc' );
302 if ( $this->helper->getCanCreateCourierWaybill() ) {
303 $columns['courier_tracking'] = __( 'Courier Tracking', 'mail-boxes-etc' );
304 $columns['courier_name'] = __( 'Courier', 'mail-boxes-etc' );
305 }
306 $columns['files'] = __( 'Downloads', 'mail-boxes-etc' );
307 $columns['pickup_manifest'] = __( 'Pickup manifest', 'mail-boxes-etc' );
308
309 return $columns;
310 }
311
312 function get_sortable_columns() {
313 $sortable_columns = array(
314 'id' => array( 'id', true ),
315 'post_date' => array( 'date', true ),
316 );
317
318 return $sortable_columns;
319 }
320
321 function get_bulk_actions() {
322 $actions = array();
323 if ( ! ( $this->helper->isCreationAutomatically() ||
324 ( $this->helper->getPickupRequestEnabled() && Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC === $this->helper->getPickupRequestMode() )
325 )
326 ) {
327 $actions['creation'] = __( 'Shipment creation (no pickup)', 'mail-boxes-etc' );
328 }
329
330 if ($this->helper->canEditDynamicPackageData()
331 ) {
332 $actions['edit_packages'] = __( 'Edit packages', 'mail-boxes-etc' );
333 }
334
335 if ( $this->helper->canSelectDepartmentForOrders() ) {
336 $actions['department'] = __( 'Associate department data', 'mail-boxes-etc' );
337 }
338
339 if ( ! $this->helper->isClosureAutomatically() ) {
340 if ( $this->mustCloseShipments ) {
341 $actions['closure'] = __( 'Close shipments in MBE Online', 'mail-boxes-etc' );
342 }
343 }
344 if ( ! $this->helper->isOnlineMBE() ) {
345 if ( $this->helper->canAdvancedReturn() ) {
346 $actions['advanced_return'] = __( 'Create return shipment - pickup', 'mail-boxes-etc' );
347 } else {
348 $actions['return'] = __( 'Create return shipment', 'mail-boxes-etc' );
349 }
350 }
351 $actions['downloadLabels'] = __( 'Download shipping Labels', 'mail-boxes-etc' );
352 $actions['downloadPickupManifest'] = __( 'Download pickup manifest', 'mail-boxes-etc' );
353
354 if ( $this->helper->getPickupRequestEnabled() && ! $this->helper->isCreationAutomatically() ) {
355 $actions['creation_pickup'] = __( 'Shipments creation (with pickup data)', 'mail-boxes-etc' );
356 }
357
358 return $actions;
359 }
360
361 function process_bulk_action() {
362
363 if ( isset( $_REQUEST['id'] ) ) {
364 $post_ids = array_map( 'absint', (array) wc_clean( $_REQUEST['id'] ) );
365
366 switch ( $this->current_action() ) {
367 case 'creation':
368 $this->processShipmentCreation( $post_ids );
369 wp_redirect( admin_url( 'admin.php?page=' . WOOCOMMERCE_MBE_TABS_PAGE ) );
370 exit;
371 break;
372 case 'edit_packages':
373 try {
374 $this->checkIfAlreadyShipped( $post_ids );
375 // Open the default data editor and add details to the order
376 do_action( MBE_ESHIP_ID . '_edit_dynamic_packages_data', $post_ids );
377 } catch ( \MbeExceptions\ValidationException $e ) {
378 $this->logger->log( 'MBE Edit dynamic packages - ' . $e->getMessage() );
379 $this->helper->setWpAdminMessages( [
380 'message' => urlencode( $e->getMessage() ),
381 'status' => urlencode( 'error' )
382 ] );
383 break;
384 }
385 break;
386 case 'department':
387 try {
388 $this->checkIfAlreadyShipped( $post_ids );
389 // Open default data editor and add details to the order
390 do_action( MBE_ESHIP_ID . '_add_department_data', $post_ids );
391 exit;
392 } catch ( \MbeExceptions\ValidationException $e ) {
393 $this->logger->log( 'MBE Add department - ' . $e->getMessage() );
394 $this->helper->setWpAdminMessages( [
395 'message' => urlencode( $e->getMessage() ),
396 'status' => urlencode( 'error' )
397 ] );
398 }
399 break;
400 case 'closure':
401 if ( ! $this->helper->isClosureAutomatically() ) {
402 if ( $this->mustCloseShipments ) {
403
404 $toClosedIds = array();
405 $alreadyClosedIds = array();
406 $withoutTracking = array();
407 $pickupIds = array();
408
409 foreach ( $post_ids as $post_id ) {
410 if ( ! $this->helper->hasTracking( $post_id ) ) {
411 $withoutTracking[] = $post_id;
412 } elseif ( ! empty( $this->helper->getOrderPickupCustomDataId( $post_id ) ) ) {
413 $pickupIds[] = $post_id;
414 } elseif ( $this->helper->isShippingOpen( $post_id ) && empty( $this->helper->getOrderPickupCustomDataId( $post_id ) ) ) { // additional check to be sure that pickup shipment won't be closed
415 $toClosedIds[] = $post_id;
416 } else {
417 $alreadyClosedIds[] = $post_id;
418 }
419 }
420 $this->ws->closeShipping( $toClosedIds );
421 if ( count( $withoutTracking ) > 0 ) {
422 $this->helper->setWpAdminMessages( [
423 'message' => sprintf( __( '%s - Total of %d order(s) without tracking number yet.', 'mail-boxes-etc' ), date( 'Y-m-d H:i:s' ), count( $withoutTracking ) ),
424 'status' => 'warning'
425 ] );
426 }
427 if ( count( $pickupIds ) > 0 ) {
428 $this->helper->setWpAdminMessages( [
429 'message' => sprintf( __( '%s - Total of %d order(s) are pickup shipment.', 'mail-boxes-etc' ), date( 'Y-m-d H:i:s' ), count( $pickupIds ) ),
430 'status' => 'warning'
431 ] );
432 }
433 if ( count( $toClosedIds ) > 0 ) {
434 $this->helper->setWpAdminMessages( [
435 'message' => sprintf( __( '%s - Total of %d order(s) have been closed.', 'mail-boxes-etc' ), date( 'Y-m-d H:i:s' ), count( $toClosedIds ) ),
436 'status' => 'warning'
437 ] );
438 }
439
440 if ( count( $alreadyClosedIds ) > 0 ) {
441 $this->helper->setWpAdminMessages( [
442 'message' => sprintf( __( '%s - Total of %d order(s) was already closed', 'mail-boxes-etc' ), date( 'Y-m-d H:i:s' ), count( $alreadyClosedIds ) ),
443 'status' => 'warning'
444 ] );
445 }
446 }
447 }
448 break;
449 case 'downloadLabels':
450 try {
451 $labelsPdf = [];
452 foreach ( $post_ids as $post_id ) {
453 if ( $this->helper->isDeliveryPointOrder( $post_id ) ) {
454
455 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
456 $order = wc_get_order( $post_id );
457 $masterTrackingNumber = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER);
458 } else {
459 $masterTrackingNumber = get_post_meta( $post_id, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER, true );
460 }
461
462 $response = $this->ws->getDeliveryPointShippingDocument( $masterTrackingNumber );
463
464 if ( $response !== false && empty( $response->Errors ) ) {
465 $outputPdf = file_get_contents( $response->CourierWaybill ); // load the remote pdf
466 $labelsPdf[] = $this->convertShippingLabelToPdf( 'pdf', $outputPdf );
467 } else {
468 // $errMsg = sprintf( __( "Download waybill", 'mail-boxes-etc' ) . " - " . __("waybill for order %s is still generating. Please try again in 1 minute", 'mail-boxes-etc' ), $post_id );
469 $errMsg = __( "Download waybill", 'mail-boxes-etc' ) . " $post_id - " . __( $response->Errors->Error->Description ?? '', 'mail-boxes-etc' );
470 $this->helper->logErrorAndSetWpAdminMessage( $errMsg, $this->logger );
471 }
472 } else {
473 $labels = $this->helper->getFileNames( $post_id);
474 if ( is_array( $labels ) ) {
475 foreach ( $labels as $l ) {
476 $labelType = preg_replace( '/.*\./', '', $l );
477 $labelsPdf[] = $this->convertShippingLabelToPdf( $labelType, file_get_contents( $this->helper->mbeUploadDir() . DIRECTORY_SEPARATOR . $l ) );
478 }
479 }
480 }
481 }
482 if ( ! empty( $labelsPdf ) ) {
483 $outputPdf = $this->combineLabelsPdf( $labelsPdf );
484 $outputPdfPath = $this->helper->mbeUploadDir() . DIRECTORY_SEPARATOR . current_datetime()->getTimestamp() . rand( 0, 999 ) . '.pdf';
485 $this->helper->setWpAdminMessages( [
486 'message' => urlencode( sprintf( __( "Download waybill", 'mail-boxes-etc' ) . " - " . __( "%s Downloaded waybills", 'mail-boxes-etc' ), count( $labelsPdf ) ) ),
487 'status' => urlencode( 'info' )
488 ] );
489
490 if ( file_put_contents( $outputPdfPath, $outputPdf ) !== false ) {
491 wp_redirect( admin_url( 'admin.php?page=' . WOOCOMMERCE_MBE_TABS_PAGE . '&reload-download=' . urlencode( $outputPdfPath ) . '&nonce=' . wp_create_nonce( WOOCOMMERCE_MBE_TABS_PAGE ) ) );
492 exit;
493 } else {
494 $errMess = __( 'MBE Download shipping labels - error writing to file ' . $outputPdfPath, 'mail-boxes-etc' );
495 $this->logger->log( $errMess );
496 }
497 } else {
498 $this->logger->log( __( 'MBE Download shipping labels - no label to download ', 'mail-boxes-etc' ) );
499 }
500 // } catch (\MbeExceptions\ShippingDocumentException $e) {
501 // $errMsg = sprintf( __( "Download waybill", 'mail-boxes-etc' ) . " - " . __("%s", 'mail-boxes-etc' ), $e->getMessage() );
502 // $this->helper->logErrorAndSetWpAdminMessage( $errMsg, $this->logger );
503 } catch ( \Exception $e ) {
504 $errMess = __( "Download waybill", 'mail-boxes-etc' ) . " - " . __( 'Unexpected error', 'mail-boxes-etc' ) . ' - ' . $e->getMessage();
505 $this->logger->log( $errMess );
506 }
507 break;
508 case 'return' :
509 $this->createReturnShipment( $post_ids );
510 // remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), wp_unslash( $_SERVER['REQUEST_URI'] ) );
511 wp_redirect( admin_url( 'admin.php?page=' . WOOCOMMERCE_MBE_TABS_PAGE ) );
512 exit;
513 break;
514 case 'advanced_return':
515 try {
516 // if one order only
517 if ( count( $post_ids ) > 1 || ! $this->helper->hasTracking( $post_ids[0] ) ) {
518 throw new \MbeExceptions\ValidationException( __('Please select only one shipped order', 'mail-boxes-etc') );
519 }
520
521 // //if not already returned
522 // if($this->helper->isReturned($post_ids[0])) {
523 // throw new \MbeExceptions\ValidationException( 'Please select only an order not already returned' );
524 // }
525
526 // Open address selection form
527 do_action( MBE_ESHIP_ID . '_before_create_advanced_return', $post_ids[0] );
528 exit;
529 } catch ( \MbeExceptions\ValidationException $e ) {
530 $this->logger->log( 'MBE Creation advanced return - ' . $e->getMessage() );
531 $this->helper->setWpAdminMessages( [
532 'message' => urlencode( $e->getMessage() ),
533 'status' => urlencode( 'error' )
534 ] );
535 }
536 break;
537 case 'downloadPickupManifest' :
538 try {
539 $masterTrackingIds = [];
540 foreach ( $post_ids as $post_id ) {
541 if ( ! $this->helper->isPickupShipped( $post_id ) ) {
542 throw new \MbeExceptions\ValidationException( __( 'Please select only pickup batches', 'mail-boxes-etc' ) );
543 }
544
545 if ( ! $this->helper->hasTracking( $post_id ) ) {
546 throw new \MbeExceptions\ValidationException( sprintf( __( 'Order %s does not have a tracking number', 'mail-boxes-etc' ), $post_id ) );
547 }
548
549 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
550 $order = wc_get_order( $post_id );
551 $masterTrackingNumber = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER, false);
552 } else {
553 $masterTrackingNumber = get_post_meta( $post_id, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER );
554 }
555
556 // This shouldn't be necessary, but we check it just to avoid unexpected issues
557 if ( $masterTrackingNumber ) {
558 $masterTrackingIds = array_merge( $masterTrackingIds, $masterTrackingNumber );
559 }
560 // else {
561 // $masterTrackingIds[] = $masterTrackingNumber;
562 // }
563 }
564 if ( ! empty( $masterTrackingIds ) ) {
565 $manifestPdf = [];
566 foreach ( $masterTrackingIds as $masterTrackingId ) {
567 $response = $this->ws->getPickupManifest( $masterTrackingId );
568 $manifestPdf[] = $response->Label->Stream;
569 }
570
571 if ( ! empty( $manifestPdf ) ) {
572 $outputPdf = $this->combineLabelsPdf( $manifestPdf );
573
574
575 $outputPdfPath = $this->helper->mbeUploadDir() . DIRECTORY_SEPARATOR . current_datetime()->getTimestamp() . rand( 0, 999 ) . '.pdf';
576 if ( file_put_contents( $outputPdfPath, $outputPdf ) !== false ) {
577 // dowload the files
578 header( 'Content-Description: File Transfer' );
579 header( 'Content-Type: application/pdf' );
580 header( "Content-Disposition: attachment; filename=mbe-pickup-manifest.pdf" );
581 header( 'Content-Transfer-Encoding: binary' );
582 header( 'Expires: 0' );
583 header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
584 header( 'Pragma: public' );
585 header( 'Content-Length: ' . filesize( $outputPdfPath ) );
586 ob_clean();
587 flush();
588 readfile( $outputPdfPath );
589 wp_delete_file( $outputPdfPath );
590 exit;
591 } else {
592 $errMess = __( 'MBE Download pickup manifest - error writing to file ' . $outputPdfPath, 'mail-boxes-etc' );
593 $this->logger->log( $errMess );
594 $this->helper->setWpAdminMessages( [
595 'message' => urlencode( $errMess ),
596 'status' => urlencode( 'error' )
597 ] );
598 }
599 }
600 } else {
601 $errMess = __( 'MBE Download pickup manifest - no document to download', 'mail-boxes-etc' );
602 $this->logger->log( $errMess );
603 $this->helper->setWpAdminMessages( [
604 'message' => urlencode( $errMess ),
605 'status' => urlencode( 'error' )
606 ] );
607 }
608 } catch ( \MbeExceptions\ValidationException $e ) {
609 $errMess = __( 'MBE Download pickup manifest - ' . $e->getMessage(), 'mail-boxes-etc' );
610 $this->logger->log( $errMess );
611 $this->helper->setWpAdminMessages( [
612 'message' => urlencode( $errMess ),
613 'status' => urlencode( 'error' )
614 ] );
615 } catch ( \Exception $e ) {
616 $errMess = __( 'MBE Download pickup manifest - Unexpected error', 'mail-boxes-etc' ) . ' - ' . $e->getMessage();
617 $this->logger->log( $errMess );
618 $this->helper->setWpAdminMessages( [
619 'message' => urlencode( $errMess ),
620 'status' => urlencode( 'error' )
621 ] );
622 }
623 break;
624 case 'creation_pickup' :
625 try {
626 $this->checkIfAlreadyShipped( $post_ids );
627 // Open default data editor and create a row for the batch ( pre-fill with default values from remote )
628 do_action( MBE_ESHIP_ID . '_before_create_pickup', $post_ids );
629 exit;
630 } catch ( \MbeExceptions\ValidationException $e ) {
631 $this->logger->log( 'MBE Creation pickup - ' . $e->getMessage() );
632 $this->helper->setWpAdminMessages( [
633 'message' => urlencode( $e->getMessage() ),
634 'status' => urlencode( 'error' )
635 ] );
636 }
637 break;
638 }
639 } else {
640 if ( $this->current_action() ) {
641 echo '<div class="error"><p>' . esc_html__( 'Please select items.', 'mail-boxes-etc' ) . '</p></div>';
642 }
643 }
644 }
645
646 function prepare_items() {
647 global $wpdb;
648
649 $this->mustCloseShipments = $this->ws->mustCloseShipments(); // Use a local parameter to avoid calling the function multiple times for each row
650
651 // Set the warning for department if needed
652 if ( $this->helper->getCustomerAddressAsSender() && $this->helper->getMandatoryDepartment() ) {
653 $departmentWarning = null;
654 $hasDepartmentDefault = $this->helper->hasDepartmentDefault();
655 if ( $this->helper->isCreationAutomatically() ) {
656 // Automatic creation
657 // No department default address, check for MOL department default
658 $departmentWarning = $hasDepartmentDefault
659 ? "Department is mandatory for shipments. However, we detected that a default department is already configured in your MOL user settings. If you don't specify an eShip default department here, the system will automatically use your MOL default department. You can override it by selecting a different eShip default department"
660 : "Department is mandatory for shipments. To create shipments successfully, please specify, in the plugin Shipping section, an eShip Default Department. If you proceed without setting an eShip Default Department, shipment creation will fail";
661 } else {
662 // Manual creation
663 $departmentWarning = $hasDepartmentDefault
664 ? "Department is mandatory for shipments. However, we detected that a default department is already configured in your MOL user settings. If you don't specify a department, the system will automatically use your MOL default department. You can override this by selecting a different department, when creating the shipment"
665 : "Department is mandatory for shipments. To create shipments successfully, please specify a department manually for each shipment. If you proceed without setting a department, shipment creation will fail";
666 }
667
668 // Add warning message if any
669 if ( $departmentWarning ) {
670 $this->helper->setWpAdminMessages( [ 'message' => __( $departmentWarning, 'mail-boxes-etc' ), 'status' => 'warning' ] );
671 }
672 }
673
674 $per_page = 10;
675 $max_num_pages = 0;
676 $columns = $this->get_columns();
677 $hidden = array();
678 $sortable = $this->get_sortable_columns();
679
680 $this->_column_headers = array( $columns, $hidden, $sortable );
681
682 $orders_pickup_batch_ids = $this->helper->select_pickup_orders_ids();
683
684 $this->process_bulk_action();
685
686 // if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
687 // $table_name = $wpdb->prefix . 'wc_orders';
688 // $postmetaTableName = $wpdb->prefix . 'wc_orders_meta';
689 // $postmetaTableJoin = ' AS pm ON pm.order_id = p.ID ';
690 // $postTypeWhere = "type = 'shop_order'";
691
692 $order_ids = array(
693 'limit' => - 1,
694 // 'type' => 'shop_order',
695 'return' => 'ids',
696 // 'meta_key' => '_shipping_method',
697 // 'meta_value' => 'mbe_eship|wf_mbe_shipping',
698 // 'comparison' => 'REGEXP'
699 'meta_query' =>
700 // array(
701 array(
702 'key' => '_shipping_method',
703 'value' => 'mbe_eship|wf_mbe_shipping',
704 'compare' => 'REGEXP'
705 )
706 // )
707 );
708
709 $orders_custom_mapping_ids = array(
710 'limit' => - 1,
711 // 'type' => 'shop_order',
712 'return' => 'ids',
713 'meta_key' => 'woocommerce_mbe_tracking_custom_mapping',
714 'meta_value' => 'yes',
715 // 'meta_query' => array(
716 // 'key' => 'woocommerce_mbe_tracking_custom_mapping',
717 // 'value' => 'yes',
718 // 'compare' => '='
719 // )
720 );
721
722
723 // $order_query_args = array(
724 // 'limit' => $per_page,
725 // 'page' => $this->get_pagenum(),
726 // 'type' => 'shop_order',
727 // 'paginate' => true,
728 // 'field_query' => array(
729 // 'relation' => 'AND',
730 // array(
731 // 'relation' => 'OR',
732 // array(
733 // 'field' => 'id',
734 // 'value' => wc_get_orders($order_ids),
735 // 'compare' => 'IN'
736 // ),
737 // array(
738 // 'field' => 'id',
739 // 'value' => wc_get_orders($orders_custom_mapping_ids),
740 // 'compare' => 'IN'
741 // )
742 // ),
743 // array(
744 // 'field' => 'id',
745 // 'value' => array_column($wpdb->get_results($orders_pickup_batch_ids), 'order_id'),
746 // 'compare' => 'NOT IN'
747 // )
748 // )
749 // );
750
751 $order_query_args = array(
752 'limit' => $per_page,
753 'page' => $this->get_pagenum(),
754 'post_type' => 'shop_order',
755 'paginate' => true,
756 // 'relations' => 'AND',
757 'meta_query' => array(
758 array(
759 'relation' => 'OR',
760 array(
761 'key' => '_shipping_method',
762 'value' => 'mbe_eship|wf_mbe_shipping',
763 'compare' => 'REGEXP'
764 ),
765 array(
766 'key' => 'woocommerce_mbe_tracking_custom_mapping',
767 'value' => 'yes',
768 )
769 // OR method_id in order_itemmeta regexp 'mbe_eship|wf_mbe_shipping'
770 )
771 ),
772 'field_query' => array(
773 array(
774 'field' => 'id',
775 'value' => array_column( $wpdb->get_results( $orders_pickup_batch_ids ), 'order_id' ),
776 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
777 'compare' => 'NOT IN'
778 )
779 )
780 );
781 // TODO : wc_get_orders must be used only for HPOS, as for legacy it discards meta_query and field_query
782 $mbeOrders = wc_get_orders( $order_query_args );
783
784 // $newOrders = wc_get_orders( $order_query_args );
785 // TODO : Check - Filter all the orders not only the already filtered ones
786 // $mbeOrders = [];
787 // foreach ($newOrders->orders as $order) {
788 // foreach ($order->get_items('shipping') as $item_id => $item) {
789 // if (preg_match("/MBE_ESHIP_ID.'|wf_mbe_shipping'/", $item->get_method_id()) ) {
790 // $mbeOrders[] = $order;
791 // break;
792 // }
793 // }
794 // }
795
796 $max_num_pages = $mbeOrders->max_num_pages;
797 // $total_items = $mbeOrders->total??0;
798 // $total_items = count($mbeOrders);
799 $this->items = []; // this will be overwritten below
800
801 // Check in case the user has attempted to page beyond the available range of orders.
802 if ( 0 === $max_num_pages && $order_query_args['page'] > 1 ) {
803 $count_query_args = $order_query_args;
804 $count_query_args['page'] = 1;
805 $count_query_args['limit'] = 1;
806 $order_count = wc_get_orders( $count_query_args );
807 $max_num_pages = (int) ceil( $order_count->total / $order_query_args['limit'] );
808 }
809
810 // $this->set_pagination_args(
811 // array(
812 // 'total_items' => $newOrders->total ?? 0,
813 // 'per_page' => $per_page,
814 // 'total_pages' => $max_num_pages,
815 // )
816 // );
817
818
819 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
820 $table_name = $wpdb->prefix . 'wc_orders';
821 $postmetaTableName = $wpdb->prefix . 'wc_orders_meta';
822 $postmetaTableJoin = ' AS pm ON pm.order_id = p.ID ';
823 $postTypeWhere = "type = 'shop_order'";
824 } else {
825 $table_name = $wpdb->prefix . 'posts';
826 $postmetaTableName = $wpdb->prefix . 'postmeta';
827 $postmetaTableJoin = ' AS pm ON pm.post_id = p.ID ';
828 $postTypeWhere = "post_type = 'shop_order'";
829 }
830
831 $paged = isset( $_REQUEST['paged'] ) ? max( 0, intval( sanitize_text_field( $_REQUEST['paged'] ) ) - 1 ) : 0;
832 $paged = $paged * $per_page;
833 $orderby = ( isset( $_REQUEST['orderby'] ) && in_array( $_REQUEST['orderby'], array_keys( $this->get_sortable_columns() ) ) ) ? sanitize_sql_orderby( $_REQUEST['orderby'] ) : 'id';
834 $order = ( isset( $_REQUEST['order'] ) && in_array( $_REQUEST['order'], array(
835 'asc',
836 'desc'
837 ) ) ) ? sanitize_text_field( $_REQUEST['order'] ) : 'desc';
838
839 $order_ids = $this->helper->select_mbe_ids();
840 $orders_custom_mapping_ids = $this->helper->select_custom_mapping_ids();
841
842 $order_filter = 'AND ((ID IN (' . $order_ids . ') OR ID IN (' . $orders_custom_mapping_ids . ')) AND ID NOT IN (' . $orders_pickup_batch_ids . '))';
843
844 $searchTerm = sanitize_text_field( $_REQUEST["s"] ?? null );
845 if ( isset( $searchTerm ) && $searchTerm != "" ) {
846 $search = esc_sql( $searchTerm );
847
848 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
849 $total_items = $wpdb->get_var( "SELECT COUNT(DISTINCT(p.ID)) FROM $table_name AS p
850 LEFT JOIN $postmetaTableName . $postmetaTableJoin
851 WHERE $postTypeWhere
852 {$order_filter}
853 AND pm.meta_value LIKE '%$search%'
854 " );
855
856 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
857 $query = $wpdb->prepare( "SELECT p.*, p.ID as ID FROM $table_name AS p
858 LEFT JOIN $postmetaTableName . $postmetaTableJoin
859 WHERE $postTypeWhere
860 {$order_filter}
861 AND pm.meta_key IN ('_billing_last_name', '_billing_first_name', 'woocommerce_mbe_tracking_name','woocommerce_mbe_tracking_number', '_order_total', '_payment_method_title')
862 AND (pm.meta_value LIKE '%%$search%%')
863 GROUP BY p.ID
864 ORDER BY $orderby $order LIMIT %d OFFSET %d", array( $per_page, $paged ) );
865
866 $this->items = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
867 } else {
868
869 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
870 $total_items = $wpdb->get_var( "SELECT COUNT(id) FROM $table_name
871 WHERE $postTypeWhere
872 {$order_filter}" );
873 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
874 $this->items = $wpdb->get_results( $wpdb->prepare( "SELECT id as ID, $table_name.* FROM $table_name
875 WHERE $postTypeWhere
876 {$order_filter}
877 ORDER BY $orderby $order LIMIT %d OFFSET %d", $per_page, $paged ), ARRAY_A );
878 }
879
880 $max_num_pages = ceil( $total_items / $per_page );
881
882 // }
883
884 $this->set_pagination_args( array(
885 'total_items' => $total_items, // total items defined above
886 'per_page' => $per_page, // per page constant defined at top of method
887 'total_pages' => $max_num_pages// calculate pages count
888 ) );
889 }
890
891 public function convertShippingLabelToPdf( string $labelType, $label ) {
892 $dompdf = new Dompdf();
893
894 switch ( $labelType ) {
895 case 'html':
896 $domOptions = $dompdf->getOptions();
897 // $domOptions->setIsHtml5ParserEnabled(true);
898 $domOptions->setIsRemoteEnabled( true );
899 $domOptions->setDefaultMediaType( 'print' );
900 $dompdf->setPaper( 'A4', 'landscape' );
901 $dompdf->setOptions( $domOptions );
902 $dompdf->loadHtml( $label );
903 $dompdf->render();
904
905 return $dompdf->output();
906 case 'gif':
907 $gifHtml = '<img style="min-width:90%; max-height:90%" src="data:image/gif;base64,' . base64_encode( $label ) . '">';
908 $dompdf->loadHtml( $gifHtml );
909 $dompdf->render();
910
911 return $dompdf->output();
912 default: //pdf
913 return $label;
914 }
915 }
916
917 /**
918 * Merge an array of PDF stream labels
919 *
920 * @param array $labelsContent
921 *
922 * @return string
923 */
924 public function combineLabelsPdf( array $labelsContent ) {
925 $outputPdf = new Merger( new TcpdiDriver() );
926 foreach ( $labelsContent as $item ) {
927 $outputPdf->addRaw( $item );
928 }
929
930 return $outputPdf->merge();
931 }
932
933 function itemId( $item ) {
934 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
935 //return $item->get_id();
936 return $item['id'];
937 } else {
938 return $item['ID'];
939 }
940 }
941
942 /**
943 * @param array $post_ids
944 * Check if any of the selected orders has already been shipped and throw a ValidationException
945 *
946 * @return void
947 * @throws \MbeExceptions\ValidationException
948 */
949 private function checkIfAlreadyShipped( array $post_ids ): void {
950 foreach ( $post_ids as $post_id ) {
951 if ( $this->helper->hasTracking( $post_id ) ) {
952 throw new \MbeExceptions\ValidationException( __( 'Please select only not shipped orders', 'mail-boxes-etc' ) );
953 }
954 }
955 }
956
957 /**
958 * @param array $files
959 * @param array $trackings
960 *
961 * @return string
962 */
963 private function getFilesHtmlBlock( array $files, array $trackings ): string {
964 if ( empty( $files ) ) {
965 return '';
966 } else {
967 $html = '';
968 for ( $i = 0; $i < count( $files ); $i ++ ) {
969 $filename = __( 'Label', 'mail-boxes-etc' ) . " " . ( $i + 1 );
970 $path = $this->helper->mbeUploadUrl() . DIRECTORY_SEPARATOR . $files[ $i ];
971 $html .= "<a target='_blank' href=" . $path . " style='margin-bottom:5px;display: inline-block;'>" . $filename . "</a></br>";
972 }
973 if ( isset( $trackings[0] ) && ! $this->helper->isTrackingOpen( $trackings[0] ) ) {
974 $path = $this->helper->mbeUploadUrl() . DIRECTORY_SEPARATOR . 'MBE_' . $trackings[0] . "_closed.pdf";
975 $html .= "<a target='_blank' href=" . $path . " style='margin-bottom:5px;display: inline-block;'>" . __( 'Closure file', 'mail-boxes-etc' ) . "</a></br>";
976 }
977
978 return $html;
979 }
980 }
981
982 }