czlexpress-for-woocommerce/includes/class-czl-order.php
wood chen 16965b29e1 Enhance CZL Express for WooCommerce Plugin Functionality
- Updated plugin URI for better branding consistency.
- Added environment checks to ensure WooCommerce is installed and meets version requirements.
- Improved AJAX handling for shipment creation and tracking updates, including enhanced error messages.
- Streamlined order management with new custom order statuses and improved logging for better tracking.
- Removed deprecated API test page and updated admin interface for clarity.
- Enhanced localization by ensuring all translatable strings use esc_html functions for security.

These changes improve the robustness, usability, and maintainability of the CZL Express plugin.
2025-01-15 00:08:34 +08:00

313 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// 确保没有命名空间冲突
if (!class_exists('CZL_Order')) {
class CZL_Order {
private $api;
public function __construct() {
$this->api = new CZL_API();
}
/**
* 创建运单
*/
public function create_shipment($order_id) {
global $wpdb;
try {
CZL_Logger::info('Starting create shipment', array('order_id' => $order_id));
// 更新订单备注以显示处理状态
$order = wc_get_order($order_id);
if (!$order) {
throw new Exception('订单未找到');
}
// 添加处理中的状态提示
$order->add_order_note('正在创建运单,请稍候...');
$order->save();
// 检查是否已有运单
$existing_shipment = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}czl_shipments WHERE order_id = %d",
$order_id
));
if ($existing_shipment) {
$order->add_order_note('Shipment already exists for this order');
throw new Exception('Shipment already exists for this order');
}
// 获取运输方式信息
$shipping_methods = $order->get_shipping_methods();
$shipping_method = current($shipping_methods);
$product_id = $shipping_method->get_meta('product_id');
if (empty($product_id)) {
throw new Exception('Shipping method not found');
}
// 准备运单数据
$shipment_data = array(
'buyerid' => strval($order->get_id()),
'consignee_address' => $order->get_shipping_address_1() . ' ' . $order->get_shipping_address_2(),
'consignee_city' => $order->get_shipping_city(),
'consignee_mobile' => $order->get_billing_phone(),
'consignee_telephone' => $order->get_billing_phone(),
'consignee_name' => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
'consignee_postcode' => $order->get_shipping_postcode(),
'consignee_state' => $order->get_shipping_state(),
'country' => $order->get_shipping_country(),
'order_piece' => strval($this->get_order_items_count($order)),
'product_id' => strval($product_id),
'trade_type' => 'ZYXT',
'weight' => strval($this->get_order_weight($order)),
'length' => '10',
'width' => '10',
'height' => '10',
'orderInvoiceParam' => $this->prepare_invoice_items($order)
);
// 调用API创建运单
$result = $this->api->create_shipment($shipment_data);
CZL_Logger::info('API response for shipment creation', array(
'order_id' => $order_id,
'response' => $result
));
// 检查API响应状态
if ($result['ack'] !== 'true') {
$error_msg = isset($result['message']) && !empty($result['message'])
? urldecode($result['message'])
: '创建运单失败,请稍后重试或联系客服';
// 如果有订单号但API返回失败记录警告并继续
if (!empty($result['order_id']) || !empty($result['tracking_number'])) {
$order->add_order_note(sprintf(
'Shipment Creation Warning: %s (Order ID: %s, Tracking Number: %s)',
$error_msg,
$result['order_id'],
$result['tracking_number']
));
} else {
// 如果没有订单号,抛出异常
throw new Exception($error_msg);
}
}
// 检查是否有订单号或跟踪号
if (!empty($result['order_id']) || !empty($result['tracking_number'])) {
// 保存运单信息到数据库
$wpdb->insert(
$wpdb->prefix . 'czl_shipments',
array(
'order_id' => $order_id,
'tracking_number' => $result['tracking_number'],
'czl_order_id' => $result['order_id'],
'reference_number' => $result['reference_number'],
'is_remote' => $result['is_remote'],
'is_residential' => $result['is_residential'],
'shipping_method' => $shipping_method->get_method_id(),
'status' => $result['ack'] === 'true' ? 'pending' : 'warning',
'created_at' => current_time('mysql'),
'updated_at' => current_time('mysql')
),
array('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
);
// 更新订单元数据
$order->update_meta_data('_czl_tracking_number', $result['tracking_number']);
$order->update_meta_data('_czl_order_id', $result['order_id']);
$order->update_meta_data('_czl_reference_number', $result['reference_number']);
$order->save();
// 添加成功提示
$order->add_order_note(sprintf(
'Shipment created successfully (Order ID: %s, Tracking Number: %s)',
$result['order_id'],
$result['tracking_number']
));
return true;
} else {
throw new Exception('API未返回运单号或跟踪号');
}
} catch (Exception $e) {
CZL_Logger::error('Create shipment failed', array(
'order_id' => $order_id,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
));
// 添加错误提示到订单备注
if (isset($order)) {
$order->add_order_note('运单创建失败: ' . esc_html($e->getMessage()));
}
// 抛出异常以便上层处理
throw new Exception(esc_html($e->getMessage()));
}
}
/**
* 获取订单总重量
*/
private function get_order_weight($order) {
$total_weight = 0;
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->get_weight()) {
$total_weight += ($product->get_weight() * $item->get_quantity());
}
}
return max(0.1, $total_weight); // 最小重量0.1kg
}
private function get_order_items_count($order) {
$count = 0;
foreach ($order->get_items() as $item) {
$count += $item->get_quantity();
}
return max(1, $count);
}
private function prepare_invoice_items($order) {
$items = array();
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product) {
continue;
}
// 获取产品尺寸,确保是数字类型
$length = floatval($product->get_length() ?: 10);
$width = floatval($product->get_width() ?: 10);
$height = floatval($product->get_height() ?: 10);
$items[] = array(
'invoice_amount' => strval($item->get_total()), // 转为字符串
'invoice_pcs' => intval($item->get_quantity()), // 确保是整数
'invoice_title' => $item->get_name(),
'invoice_weight' => floatval($product->get_weight() * $item->get_quantity()), // 确保是数字
'sku' => $product->get_meta('_czl_name_cn'),
'hs_code' => $product->get_meta('_czl_hs_code'),
'invoice_material' => $product->get_meta('_czl_material'),
'invoice_purpose' => $product->get_meta('_czl_usage'),
'item_id' => strval($product->get_id()), // 转为字符串
'sku_code' => $product->get_sku(),
'length' => strval($length), // 转为字符串
'width' => strval($width), // 转为字符串
'height' => strval($height) // 转为字符串
);
}
return $items;
}
/**
* 更新运单轨迹信息
*/
public function update_tracking_info($order_id) {
global $wpdb;
// 获取运单信息
$shipment = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}czl_shipments WHERE order_id = %d",
$order_id
));
if (!$shipment || empty($shipment->tracking_number)) {
throw new Exception('未找到运单信息');
}
// 获取轨迹信息
$api = new CZL_API();
$tracking_info = $api->get_tracking_info($shipment->tracking_number);
CZL_Logger::info('Tracking API response', array(
'tracking_number' => $shipment->tracking_number,
'response' => $tracking_info
));
// 处理API响应
if (!empty($tracking_info) && isset($tracking_info['success']) && $tracking_info['success'] == 1) {
// 检查API返回的状态
$api_status = isset($tracking_info['data']['status']) ? strtolower(trim($tracking_info['data']['status'])) : '';
$is_delivered = ($api_status === 'delivered');
// 如果API状态不是delivered再检查轨迹详情
if (!$is_delivered && isset($tracking_info[0]['data'][0]['trackDetails']) && is_array($tracking_info[0]['data'][0]['trackDetails'])) {
$latest_track = $tracking_info[0]['data'][0]['trackDetails'][0];
$track_signdate = isset($latest_track['track_signdate']) ? trim($latest_track['track_signdate']) : '';
$track_signperson = isset($latest_track['track_signperson']) ? trim($latest_track['track_signperson']) : '';
// 如果有签收时间和签收人,也认为是已签收
if (!empty($track_signdate) && !empty($track_signperson)) {
$is_delivered = true;
}
}
// 更新运单表状态
$wpdb->update(
$wpdb->prefix . 'czl_shipments',
array(
'status' => $is_delivered ? 'delivered' : 'in_transit',
'last_sync_time' => current_time('mysql')
),
array('order_id' => $order_id),
array('%s', '%s'),
array('%d')
);
// 获取订单对象
$order = wc_get_order($order_id);
if ($order) {
// 根据签收状态更新订单状态
if ($is_delivered && $order->get_status() !== 'completed') {
$order->update_status('completed', sprintf('包裹已签收(%s订单自动完成',
$tracking_info['data']['track_content']
));
}
try {
// 构建轨迹信息
$note_content = array();
$note_content[] = 'Package Status Update:';
if (!empty($tracking_info['data']['track_content'])) {
$note_content[] = sprintf('Status: %s', $tracking_info['data']['track_content']);
}
if (!empty($tracking_info['data']['track_location'])) {
$note_content[] = sprintf('Location: %s', $tracking_info['data']['track_location']);
}
if (!empty($tracking_info['data']['track_time'])) {
$note_content[] = sprintf('Time: %s', $tracking_info['data']['track_time']);
}
$note_content[] = sprintf('Tracking Number: %s', $shipment->tracking_number);
$note_content[] = '';
$note_content[] = sprintf('Track your package: https://exp.czl.net/track/?query=%s', $shipment->tracking_number);
// 添加新的轨迹信息
$note = implode("\n", array_filter($note_content));
$comment_id = $order->add_order_note($note, 1);
if (!$comment_id) {
throw new Exception('Failed to add order note');
}
$order->save();
return true;
} catch (Exception $e) {
error_log('CZL Express: Error updating tracking info - ' . $e->getMessage());
throw $e;
}
}
}
return false;
}
}
}