get_order(); if ( isset( $fs_method['dpd_product'] ) ) { $this->set_meta( '_dpd_product', $fs_method['dpd_product'] ); } if ( isset( $fs_method['dpd_package_width'] ) ) { $this->set_meta( '_dpd_package_width', $fs_method['dpd_package_width'] ); } if ( isset( $fs_method['dpd_package_height'] ) ) { $this->set_meta( '_dpd_package_height', $fs_method['dpd_package_height'] ); } if ( isset( $fs_method['dpd_package_depth'] ) ) { $this->set_meta( '_dpd_package_depth', $fs_method['dpd_package_depth'] ); } if ( isset( $fs_method['dpd_declared_value'] ) ) { $this->set_meta( '_dpd_declared_value', $fs_method['dpd_declared_value'] ); } if ( isset( $fs_method['dpd_cod'] ) ) { $this->set_meta( self::META_DPD_COD, $fs_method['dpd_cod'] ); } if ( isset( $fs_method['dpd_pickup'] ) ) { $point_id = $order->get_meta( '_dpd_pickup_point_id' ); if ( $point_id ) { try { $this->save_pickup_details( $point_id ); $this->set_meta( self::META_DPD_PICKUP, $fs_method['dpd_pickup'] ); } catch ( HttpClientRequestException $e ) { // phpcs:ignore // TODO: write exception to log. } } } if ( isset( $fs_method['dpd_saturday'] ) ) { $this->set_meta( self::META_DPD_SATURDAY, $fs_method['dpd_saturday'] ); } if ( isset( $fs_method['dpd_next_day'] ) ) { $this->set_meta( self::META_DPD_NEXT_DAY, $fs_method['dpd_next_day'] ); } if ( isset( $fs_method['dpd_package_content'] ) ) { $this->set_meta( '_dpd_package_content', $fs_method['dpd_package_content'] ); } $this->set_meta( '_dpd_cod_value', $order->get_total() ); $this->set_meta( '_dpd_declared_value_value', $order->get_total() ); $this->set_meta( '_dpd_package_weight', wc_get_weight( fs_calculate_package_weight( $package ), 'kg' ) ); // Translators: order number. $this->set_meta( '_dpd_ref', sprintf( __( 'Zamówienie %s', 'woocommerce-dpd' ), $order->get_order_number() ) ); } /** * Get metaboc content. * * @return false|string */ public function order_metabox_content() { if ( ! function_exists( 'woocommerce_form_field' ) ) { $wc_template_functions = trailingslashit( dirname( __FILE__ ) ) . '../../woocommerce/includes/wc-template-functions.php'; if ( file_exists( $wc_template_functions ) ) { include_once $wc_template_functions; } } $settings = $this->get_shipping_method()->settings; $order = $this->get_order(); $id = $this->get_id(); $dpd_status = $this->get_meta( '_dpd_status' ); $disabled = false; if ( isset( $dpd_status ) && 'ok' === $dpd_status ) { $disabled = true; } $dpd_product = $this->get_meta( '_dpd_product' ); $dpd_package_width = $this->get_meta( '_dpd_package_width' ); $dpd_package_height = $this->get_meta( '_dpd_package_height' ); $dpd_package_depth = $this->get_meta( '_dpd_package_depth' ); $dpd_package_weight = $this->get_meta( '_dpd_package_weight' ); $dpd_package_content = $this->get_meta( '_dpd_package_content' ); $dpd_ref = $this->get_meta( '_dpd_ref' ); $dpd_declared_value = $this->get_meta( '_dpd_declared_value' ); $dpd_declared_value_value = $this->get_meta( '_dpd_declared_value_value' ); $dpd_cod = $this->get_meta( self::META_DPD_COD ); $dpd_pickup = $this->get_bool_value( $this->get_meta( self::META_DPD_PICKUP ) ); $dpd_pickup_point_id = $this->get_meta( self::META_DPD_PICKUP_POINT_ID ); $dpd_cod_value = $this->get_meta( '_dpd_cod_value' ); $dpd_saturday = $this->get_meta( self::META_DPD_SATURDAY ); $dpd_next_day = $this->get_meta( self::META_DPD_NEXT_DAY ); $additional_packages = $this->get_meta( '_additional_packages', [] ); $dpd_one_time_message = $this->get_meta( '_dpd_one_time_message', '' ); $dpd_message = $this->get_meta( '_dpd_message' ); $tracking_url = $this->get_tracking_url(); $dpd_package_id = $this->get_meta( self::DPD_PACKAGE_ID ); $dpd_package_number = $this->get_tracking_number(); $label_url = $this->get_label_url(); $label_avaliable = $this->label_avaliable(); $dpd_one_time_message = $this->dpd_one_time_message; $label_avaliable = $this->label_avaliable(); $dpd_sender_address_id = $this->get_meta( self::DPD_SENDER_ADDRESS_ID, '' ); $sender_address_options = $this->prepare_sender_address_options(); $pickup_points = array_merge( [ '' => __( '-- wybierz --', 'woocommerce-dpd' ) ], self::$pickup_points_manager->get_points( $this->get_bool_value( $dpd_cod ) ) ); ob_start(); $echo = false; include 'views/order-metabox-content.php'; $content = ob_get_contents(); ob_end_clean(); return $content; } /** * Prepare options for sender address select field in metabox. * * @return array */ private function prepare_sender_address_options() { $sender_address_options = [ '' => __( 'Adres główny', 'woocommerce-dpd' ) ]; if ( 'yes' === $this->get_shipping_method()->get_option( WPDesk_WooCommerce_DPD_Shipping_Method::ADDITIONAL_SENDER_ADDRESSES_ENABLED, 'no' ) ) { $additional_addresses = $this->get_shipping_method()->get_additional_sender_addresses(); foreach ( $additional_addresses as $additional_address ) { $sender_address_options[ $additional_address->get_address_id() ] = $additional_address->get_address_id(); } } return $sender_address_options; } /** * Order metabox. */ public function order_metabox() { echo $this->order_metabox_content(); // wpcs: XSS ok. } /** * Metabox title. * * @return string */ public function get_order_metabox_title() { return __( 'DPD', 'woocommerce-dpd' ); } /** * Ajax request. * * @param string $action . * @param array $data . * * @return array|void * @throws Exception . */ public function ajax_request( $action, $data ) { $ret = []; if ( 'save' === $action ) { $this->save_ajax_data( $data ); $this->save(); $ret['message'] = __( 'Przesyłka została zapisana.', 'woocommerce-dpd' ); } elseif ( 'send' === $action ) { $this->save_ajax_data( $data ); $this->api_create(); $ret['message'] = __( 'Przesyłka została utworzona.', 'woocommerce-dpd' ); } elseif ( 'cancel' === $action ) { $dpd_package_number = $this->get_meta( '_dpd_package_number' ); $this->save_ajax_data( $data ); $this->api_cancel(); $ret['message'] = __( 'Przesyłka została anulowana.', 'woocommerce-dpd' ); } elseif ( 'refresh' === $action ) { $this->api_refresh(); } else { // Translators: action. throw new Exception( sprintf( __( 'Nieznana akcja: %1$s', 'woocommerce-dpd' ), $action ) ); } $ret['content'] = $this->order_metabox_content(); return $ret; } /** * Api refresh. */ public function api_refresh() { } /** * Save AJAX data. * * @param array $data . */ public function save_ajax_data( $data ) { if ( isset( $data['dpd_product'] ) ) { $this->set_meta( '_dpd_product', $data['dpd_product'] ); } else { $this->delete_meta( '_dpd_product' ); } if ( isset( $data['dpd_sender_address_id'] ) ) { $this->set_meta( self::DPD_SENDER_ADDRESS_ID, wp_unslash( $data['dpd_sender_address_id'] ) ); } else { $this->delete_meta( self::DPD_SENDER_ADDRESS_ID ); } if ( isset( $data['dpd_package_weight'] ) ) { $this->set_meta( '_dpd_package_weight', $data['dpd_package_weight'] ); } else { $this->delete_meta( '_dpd_package_weight' ); } if ( isset( $data['dpd_package_width'] ) ) { $this->set_meta( '_dpd_package_width', $data['dpd_package_width'] ); } else { $this->delete_meta( '_dpd_package_width' ); } if ( isset( $data['dpd_package_height'] ) ) { $this->set_meta( '_dpd_package_height', $data['dpd_package_height'] ); } else { $this->delete_meta( '_dpd_package_height' ); } if ( isset( $data['dpd_package_depth'] ) ) { $this->set_meta( '_dpd_package_depth', $data['dpd_package_depth'] ); } else { $this->delete_meta( '_dpd_package_depth' ); } if ( isset( $data['additional_packages'] ) ) { unset( $data['additional_packages']['_additional_key_'] ); $additional_packages = []; foreach ( $data['additional_packages'] as $additional_package ) { $additional_packages[] = $additional_package; } $this->set_meta( '_additional_packages', $additional_packages ); } else { $this->delete_meta( '_additional_packages' ); } if ( isset( $data['dpd_package_content'] ) ) { $this->set_meta( '_dpd_package_content', $data['dpd_package_content'] ); } else { $this->delete_meta( '_dpd_package_content' ); } if ( isset( $data['dpd_ref'] ) ) { $this->set_meta( '_dpd_ref', $data['dpd_ref'] ); } else { $this->delete_meta( '_dpd_ref' ); } if ( isset( $data['dpd_declared_value'] ) ) { $this->set_meta( '_dpd_declared_value', $data['dpd_declared_value'] ); } else { $this->delete_meta( '_dpd_declared_value' ); } if ( isset( $data['dpd_declared_value_value'] ) ) { $this->set_meta( '_dpd_declared_value_value', $data['dpd_declared_value_value'] ); } else { $this->delete_meta( '_dpd_declared_value_value' ); } if ( isset( $data['dpd_cod'] ) ) { $this->set_meta( self::META_DPD_COD, $data['dpd_cod'] ); } else { $this->delete_meta( self::META_DPD_COD ); } if ( isset( $data['dpd_cod_value'] ) ) { $this->set_meta( '_dpd_cod_value', $data['dpd_cod_value'] ); } else { $this->delete_meta( '_dpd_cod_value' ); } if ( isset( $data['dpd_saturday'] ) ) { $this->set_meta( self::META_DPD_SATURDAY, $data['dpd_saturday'] ); } else { $this->delete_meta( self::META_DPD_SATURDAY ); } if ( isset( $data['dpd_next_day'] ) ) { $this->set_meta( self::META_DPD_NEXT_DAY, $data['dpd_next_day'] ); } else { $this->delete_meta( self::META_DPD_NEXT_DAY ); } $pickup = isset( $data['dpd_pickup'] ); $point_id = isset( $data['dpd_pickup_point_id'] ) ? $data['dpd_pickup_point_id'] : ''; if ( $pickup && $point_id ) { try { $this->save_pickup_details( $point_id ); $this->set_meta( self::META_DPD_PICKUP, $data['dpd_pickup'] ); } catch ( HttpClientRequestException $e ) { // phpcs:ignore // TODO: write exception to log. } } else { $this->delete_meta( self::META_DPD_PICKUP ); $this->delete_meta( self::DELIVERY_FIELD_ID ); $this->delete_meta( self::DELIVERY_FIELD_NAME ); $this->delete_meta( self::DELIVERY_FIELD_ADDRESS ); $this->delete_meta( self::DELIVERY_FIELD_POSTCODE ); $this->delete_meta( self::DELIVERY_FIELD_CITY ); } } /** * @param string $point_id . * * @throws HttpClientRequestException */ private function save_pickup_details( $point_id ) { if ( self::TEST_PICKUP_POINT !== $point_id ) { $point = self::$pickup_points_api->get_point_details( $point_id ); $this->set_meta( self::DELIVERY_FIELD_ID, $point->get_pudo_id() ); $this->set_meta( self::DELIVERY_FIELD_NAME, $point->get_location_hint() ); $this->set_meta( self::DELIVERY_FIELD_ADDRESS, $point->get_address_1() ); $this->set_meta( self::DELIVERY_FIELD_POSTCODE, $point->get_zipcode() ); $this->set_meta( self::DELIVERY_FIELD_CITY, $point->get_city() ); } $this->set_meta( self::META_DPD_PICKUP_POINT_ID, $point_id ); } /** * Get error message. * * @return string */ public function get_error_message() { return $this->get_meta( '_dpd_message' ); } /** * Get tracking number. * * @return string|null */ public function get_tracking_number() { return $this->get_meta( '_dpd_package_number' ); } /** * Get tracking url. * * @return string|null */ public function get_tracking_url() { $tracking_url = null; $dpd_package = $this->get_meta( self::DPD_PACKAGE, '' ); if ( '' !== $dpd_package ) { $tracking_url = 'https://tracktrace.dpd.com.pl/parcelDetails?typ=1'; $count = 1; if ( ! is_array( $dpd_package->return->Packages->Package->Parcels->Parcel ) ) { $dpd_package->return->Packages->Package->Parcels->Parcel = [ $dpd_package->return->Packages->Package->Parcels->Parcel ]; } foreach ( $dpd_package->return->Packages->Package->Parcels->Parcel as $parcel ) { $tracking_url .= '&p' . $count . '=' . $parcel->Waybill; $count++; } } return $tracking_url; } /** * Create shipment in API. * * @throws Exception . */ public function api_create() { $this->api_create_webapi(); $this->save(); $error_message = $this->get_error_message(); if ( ! empty( $error_message ) ) { throw new Exception( $error_message ); } $order = $this->get_order(); $order->add_order_note( sprintf( // Translators: package number. __( 'Do zamówienia została utworzona przesyłka %1$s DPD.', 'woocommerce-dpd' ), $this->get_meta( '_dpd_package_number' ) ), true ); } /** * Create shipment in WEB API. * * @throws Exception . */ public function api_create_webapi() { if ( 'fs-new' !== $this->get_status() && 'fs-failed' !== $this->get_status() ) { throw new Exception( sprintf( // Translators: status. __( 'Invalid status: %1$s. Package already created?', 'woocommerce-dpd' ), $this->get_status() ) ); } $order = $this->get_order(); $dpd_shipment = new WPDesk_WooCommerce_DPD_Shipment( $this ); $shipment = $dpd_shipment->prepare_shipment(); $api = $this->get_api(); try { $dpd_package = $api->create_shipment( [ $shipment ] ); if ( ! empty( $dpd_package->return ) && ! empty( $dpd_package->return->Status ) ) { if ( 'OK' === $dpd_package->return->Status ) { $this->set_meta( '_dpd_status', 'ok' ); $this->set_meta( self::DPD_PACKAGE, $dpd_package ); $this->set_meta( self::DPD_PACKAGE_ID, $dpd_package->return->Packages->Package->PackageId ); $this->set_meta( '_dpd_session_id', $dpd_package->return->SessionId ); $package_number = ''; if ( ! is_array( $dpd_package->return->Packages->Package->Parcels->Parcel ) ) { $dpd_package->return->Packages->Package->Parcels->Parcel = [ $dpd_package->return->Packages->Package->Parcels->Parcel ]; } foreach ( $dpd_package->return->Packages->Package->Parcels->Parcel as $parcel ) { if ( '' !== $package_number ) { $package_number .= ', '; } $package_number .= $parcel->Waybill; } $this->set_meta( '_dpd_package_number', $package_number ); $this->set_meta( '_dpd_session_type', $this->is_domestic() ? self::DOMESTIC : self::INTERNATIONAL ); $this->delete_meta( '_dpd_message' ); $this->update_status( 'fs-confirmed' ); $this->save(); do_action( 'flexible_shipping_shipment_confirmed', $this ); } else { throw new Exception( $api->parse_shipment_errors( $dpd_package ) ); } } else { throw new Exception( // Translators: api response. sprintf( __( 'Niepoprawna odpowiedź API DPD: %1$s', 'woocommerce-dpd' ), print_r( $dpd_package, true ) ) ); } } catch ( Exception $e ) { $this->set_meta( '_dpd_status', 'error' ); $this->set_meta( '_dpd_message', $e->getMessage() ); $this->update_status( 'fs-failed' ); $this->save(); throw $e; } } /** * Cancel package in API. * * @throws Exception . */ public function api_cancel() { if ( 'fs-confirmed' !== $this->get_status() ) { throw new Exception( // Translators: status. sprintf( __( 'Niepoprawny status przesyłki: %1$s. Przesyłka została anulaowana wcześniej lub protokół został już utworzony?', 'woocommerce-dpd' ), $this->get_status() ) ); } $dpd_package_number = $this->get_meta( '_dpd_package_number' ); $this->delete_meta( '_dpd_status' ); $this->delete_meta( self::DPD_PACKAGE ); $this->delete_meta( self::DPD_PACKAGE_ID ); $this->delete_meta( '_dpd_session_id' ); $this->delete_meta( '_dpd_package_number' ); $this->delete_meta( '_dpd_message' ); $this->update_status( 'fs-new' ); $this->save(); $order = $this->get_order(); $order->add_order_note( // Translators: package number. sprintf( __( 'Przesyłka DPD %s została usunięta.', 'woocommerce-dpd' ), $dpd_package_number ), true ); } /** * Get label. * * @return array * @throws Exception . */ public function get_label() { if ( ! $this->label_avaliable() ) { throw new Exception( // Translators: status. sprintf( __( 'Etykieta niedostępna dla statusu %1$s.', 'woocommerce-dpd' ), $this->get_status() ) ); } return $this->api_get_label(); } /** * Displays email text: after order table. */ public function get_email_after_order_table() { if ( $this->label_avaliable() ) { $args = [ 'dpd_packages' => [ [ 'tracking_url' => $this->get_tracking_url(), 'shipment_id' => $this->get_meta( '_dpd_package_number' ), ], ], ]; echo self::$woocommerce_dpd_plugin->load_template( 'email_after_order_table', 'woocommerce', $args ); // wpcs: XSS ok. } } /** * Displays after order table on page. */ public function get_after_order_table() { if ( $this->label_avaliable() ) { $args = [ 'dpd_packages' => [ [ 'tracking_url' => $this->get_tracking_url(), 'shipment_id' => $this->get_meta( '_dpd_package_number' ), ], ], ]; echo self::$woocommerce_dpd_plugin->load_template( 'order_details_after_order_table', 'woocommerce', $args ); // wpcs: XSS ok. } } /** * Get label from API. * * @return array */ public function api_get_label() { $label_data = [ 'label_format' => 'pdf', 'content' => null, 'file_name' => 'dpd_' . $this->get_tracking_number() . '.pdf', ]; $shipping_method = $this->get_shipping_method(); $settings = $shipping_method->settings; $api = $this->get_api(); $session_type = $this->get_session_type(); $label_settings = $shipping_method->get_label_settings(); $label_format = $label_settings->get_label_format(); $label = $api->get_label( $this->get_meta( self::DPD_PACKAGE_ID ), $session_type, $label_format, $label_settings->get_label_page_format(), $label_settings->get_label_type_for_api() ); $label_data['content'] = $label->return->documentData; if ( 'ZPL' === $label_format ) { $label_format = 'zpl'; } elseif ( 'EPL' === $label_format ) { $label_format = 'epl'; } else { $label_format = 'pdf'; } $label_data['label_format'] = $label_format; $label_data['file_name'] = 'dpd_' . str_replace( ', ', '-', $this->get_tracking_number() ) . '.' . $label_format; return $label_data; } /** * Get API. * * @return mixed */ public function get_api() { $shipping_method = $this->get_shipping_method(); return $shipping_method->get_api(); } /** * Get shipping method. * * @return WPDesk_WooCommerce_DPD_Shipping_Method */ public function get_shipping_method() { $shipping_methods = WC()->shipping()->shipping_methods; if ( empty( $shipping_methods ) || ! is_array( $shipping_methods ) || count( $shipping_methods ) === 0 || ! isset( $shipping_methods[ WPDesk_WooCommerce_DPD_Shipping_Method::SHIPPING_METHOD_ID ] ) ) { $shipping_methods = WC()->shipping()->load_shipping_methods(); } return $shipping_methods[ WPDesk_WooCommerce_DPD_Shipping_Method::SHIPPING_METHOD_ID ]; } /** * Add shipment from order edit page. */ public function admin_add_shipment() { $order = $this->get_order(); if ( 'cod' === $order->get_payment_method() ) { $this->set_meta( self::META_DPD_COD, '1' ); } $this->set_meta( '_dpd_product', 'classic' ); $weight = wc_get_weight( fs_calculate_order_weight( $order ), 'kg' ); $this->set_meta( '_dpd_package_weight', $weight ); // Translators: order number. $this->set_meta( '_dpd_ref', sprintf( __( 'Zamówienie %s', 'woocommerce-dpd' ), $order->get_order_number() ) ); } /** * Is domestic shipment? * * @return bool */ private function is_domestic() { if ( 'PL' === $this->get_order()->get_shipping_country() ) { return true; } return false; } /** * Get session type. * Returns meta _dpd_session_type when shipment already created, or calculated value for shipping country from * order. * * @return string */ public function get_session_type() { return $this->get_meta( '_dpd_session_type', $this->is_domestic() ? self::DOMESTIC : self::INTERNATIONAL ); } /** * Get manifest name. * * @return string */ public function get_manifest_name() { $manifest_name = $this->is_domestic() ? 'dpd_domestic' : 'dpd_international'; if ( '' !== $this->get_meta( '_dpd_session_type', '' ) ) { $manifest_name = strtolower( 'dpd_' . $this->get_meta( '_dpd_session_type', '' ) ); } return $manifest_name; } }