erp/app/Services/WayBill/JingDong/WayBillService.php

287 lines
10 KiB
PHP
Raw Normal View History

2024-12-26 14:32:02 +08:00
<?php
namespace App\Services\WayBill\JingDong;
use App\Events\CreateLogisticEvent;
2024-12-27 11:05:33 +08:00
use App\Http\Enum\BusinessOrderShippingStatus;
use App\Models\BusinessOrder;
2024-12-26 14:32:02 +08:00
use App\Models\GoodsSku;
use App\Models\ShopSender;
use App\Models\ShopShip;
use App\Models\Waybill;
use App\Services\Business\KuaiTuanTuan\FaceSheet;
class WayBillService
{
public $orders;
public $objectId;
public $adminUser;
// 标准模板
2024-12-26 19:19:43 +08:00
public $templateUrl = 'https://template-content.jd.com/template-oss?tempCode=jdkd76x130';
2024-12-30 14:09:39 +08:00
// 标准模板
public $customerTempUrl = "https://template-content.jd.com/template-open?templateCode=customerInfo";
2024-12-26 14:32:02 +08:00
// 时效类型
public $timedDeliveryCode;
/**
* 新版京东打印-下单
* @return array
*/
public function getWayBillContents()
{
// 已下单过的订单不再下单
$contents = [];
$this->adminUser = auth('api')->user();
2024-12-26 19:19:43 +08:00
$jingDongService = new JingDongService();
2024-12-26 14:32:02 +08:00
foreach ($this->orders as $shopId => $order) {
// 订单取消的情况暂不处理
$shopSend = $this->getShopSend($shopId);
foreach ($order as $item) {
[$sender, $orderInfo, $senderConfig] = $this->prepareRequest($item, $shopSend);
$waybill = $this->saveWayBill($item, $shopSend, $senderConfig);
2024-12-26 19:19:43 +08:00
if (empty($waybill->waybill_code)) {
2024-12-26 14:32:02 +08:00
$resp = $jingDongService->createOrder($waybill);
2024-12-26 19:19:43 +08:00
if (isset($resp['waybillNo'])) {
2024-12-27 11:05:33 +08:00
$waybill->status = Waybill::$STATUS_CREATE_WAYBILL_CODE;
2024-12-26 19:19:43 +08:00
$waybill->waybill_code = $resp['waybillNo'];
$waybill->save();
//物流发货
2024-12-28 11:13:17 +08:00
event(new CreateLogisticEvent($waybill->shop_id, $waybill->order_sn, $waybill->waybill_code));
2024-12-26 19:19:43 +08:00
}
}
//返回面单待打印数据
if (empty($waybill->encryptedData)) {
// 延时0.5秒 防止订单查询不到
usleep(0.5 * 1000000);
$resp = $jingDongService->pullData($waybill);
if (!empty($resp[0]['perPrintData'])) {
2024-12-27 11:05:33 +08:00
$waybill->status = Waybill::$STATUS_CREATE_WAYBILL_ENCRYPTED_DATA;
2024-12-26 19:19:43 +08:00
$waybill->templateUrl = $this->templateUrl;
2024-12-30 14:09:39 +08:00
$waybill->customer_temp_url = $this->customerTempUrl;
$waybill->customer_temp_data = json_encode(['productInfo' => $item['productInfo']], 256);
2024-12-26 19:19:43 +08:00
$waybill->encryptedData = $resp[0]['perPrintData'];
2024-12-26 14:32:02 +08:00
$waybill->save();
}
}
2024-12-26 19:19:43 +08:00
$contents[$item['id']] = $waybill;
2024-12-26 14:32:02 +08:00
}
}
return $contents;
}
public function getDocumentsAndOrderIds($contents)
{
// 打印单,根据商品排序
$items = [];
foreach ($contents as $docId => $content) {
foreach ($content['items'] as $item) {
if ($item['is_single']) {
$items[$item['external_sku_id']][] = $docId;
}
}
}
ksort($items);
$documents = $orderIds = $hasIds = [];
foreach ($items as $docIds) {
$docIds = array_unique($docIds);
$docIds = array_diff($docIds, $hasIds);
$hasIds = array_merge($hasIds, $docIds);
foreach ($docIds as $docId) {
$orderIds[] = $contents[$docId]['order_id'];
$documents[] = $contents[$docId];
}
}
return [$documents, $orderIds];
}
private function saveWayBill($order, $shopShip, $senderConfig)
{
$waybill = Waybill::query()->firstOrNew(
['order_sn' => $order['order_sn']]
);
2024-12-26 19:19:43 +08:00
$waybill->shop_id = $order['shop_id'];
2024-12-26 14:32:02 +08:00
$waybill->object_id = $this->objectId;
$waybill->sender_country = $senderConfig['country'];
$waybill->sender_province = $senderConfig['province'];
$waybill->sender_city = $senderConfig['city'];
$waybill->sender_district = $senderConfig['district'];
$waybill->sender_detail = $senderConfig['detail'];
$waybill->sender_name = $senderConfig['name'];
2024-12-26 19:19:43 +08:00
$waybill->sender_mobile = (int)$senderConfig['mobile'];
2024-12-26 14:32:02 +08:00
$waybill->recipient_province = $order['recipient_province'];
$waybill->recipient_city = $order['recipient_city'];
$waybill->recipient_district = $order['recipient_district'];
$waybill->recipient_detail = $order['recipient_detail'];
$waybill->recipient_name = $order['recipient_name'];
$waybill->recipient_mobile = $order['recipient_mobile'];
$waybill->user_id = $this->adminUser->id ?? 0;
$waybill->wp_code = $senderConfig['wp_code'];
$waybill->order_sn = $order['order_sn'];
$waybill->order_id = $order['id'];
$waybill->participate_no = $order['participate_no'];
$waybill->note = $order['note'];
$waybill->items = json_encode($order['items'], 256);
2024-12-26 19:19:43 +08:00
$waybill->save();
2024-12-26 14:32:02 +08:00
return $waybill;
}
private function getTimedDelivery($order)
{
$this->timedDeliveryCode = Waybill::$BUSINESS_EXPRESS_CODE;
$address = [
'辽宁省' => [],
'吉林省' => [],
'黑龙江省' => [],
'甘肃省' => [],
'海南省' => [],
'宁夏回族自治区' => [
'银川市', '石嘴山市', '吴忠市', '固原市'
],
'青海省' => [
'西宁市', '海东市', '海北藏族自治州', '黄南藏族自治州', '海南藏族自治州', '玉树藏族自治州'
],
];
if (isset($address[$order['recipient_province']])) {
if (empty($address[$order['recipient_province']])) {
$this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
}
if ($address[$order['recipient_province']] && in_array($order['recipient_city'], $address[$order['recipient_province']], true)) {
$this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
}
}
}
private function prepareRequest($order, $shopSend)
{
$this->setObjectId();
$items = [];
foreach ($order['items'] as $item) {
$items[] = [
'name' => $item['name'],
'count' => $item['count'],
];
}
if (empty($shopSend)) {
abort(404, '发货人信息未匹配');
}
$senderConfig = $shopSend;
$sender = [
'address' => [
'city' => $senderConfig['city'],
'country' => $senderConfig['country'],
'detail' => $senderConfig['detail'],
'district' => $senderConfig['district'],
'province' => $senderConfig['province'],
],
'name' => $senderConfig['name'],
'mobile' => $senderConfig['mobile'],
];
$orderInfo = [
'object_id' => $this->objectId,
'order_info' => [
'order_channels_type' => 'PDD',
'trade_order_list' => [$order['order_sn']],
],
'package_info' => [
'items' => $items,
],
'recipient' => [
'address' => [
'city' => $order['recipient_city'],
'detail' => $order['recipient_detail'],
'district' => $order['recipient_district'],
'province' => $order['recipient_province'],
],
'name' => $order['recipient_name'],
'mobile' => $order['recipient_mobile'],
],
2024-12-26 19:19:43 +08:00
'template_url' => $this->templateUrl,
2024-12-26 14:32:02 +08:00
];
return [$sender, $orderInfo, $senderConfig];
}
public function setObjectId()
{
$this->objectId = date('YmdHis') . str_pad(mt_rand(1, 9999999), 7, '0', STR_PAD_LEFT);
return $this;
}
public function setOrders($orders)
{
$orders = $orders->toArray();
// 订单拆分组合
foreach ($orders as $order) {
2024-12-27 11:05:33 +08:00
if ($order['shipping_status'] != BusinessOrderShippingStatus::UNSHIP) {
continue;
}
if ($order['cancel_status'] == 1) {
continue;
}
2024-12-26 14:32:02 +08:00
$info = [
'id' => $order['id'],
2024-12-26 19:19:43 +08:00
'shop_id' => $order['shop_id'],
2024-12-26 14:32:02 +08:00
'order_sn' => $order['order_sn'],
'recipient_province' => $order['receiver_address_province'],
'recipient_city' => $order['receiver_address_city'],
'recipient_district' => $order['receiver_address_district'],
'recipient_detail' => $order['receiver_address_detail'],
'recipient_name' => $order['receiver_name'],
'recipient_mobile' => $order['receiver_mobile'],
'participate_no' => $order['is_supplier'] ? $order['participate_no'] : $order['supply_participate_no'],
'note' => $order['business_note'] ? $order['business_note'] . ',' . $order['buyer_memo'] : $order['buyer_memo'],
'items' => []
];
2024-12-28 11:13:17 +08:00
$note = "";
2024-12-26 14:32:02 +08:00
foreach ($order['items'] as $item) {
$count = $item['goods_number'] - $item['already_cancel_number'];
$info['items'][] = [
'is_single' => true,
'should_print' => true,
'name' => $item['goods_name'],
'count' => $count,
'external_sku_id' => $item['external_sku_id'],
];
2024-12-28 11:13:17 +08:00
$note .= $item['goods_name'] . " " . $count . "件,";
2024-12-26 14:32:02 +08:00
}
2024-12-30 14:09:39 +08:00
$info['productInfo'] = $note;
2024-12-26 14:32:02 +08:00
$this->orders[$order['shop_id']][] = $info;
}
return $this;
}
private function getShopSend($shopId)
{
return ShopSender::query()
2024-12-30 14:09:39 +08:00
->where('shop_id', $shopId)
->where('status', 1)->orderByDesc('sort')
2024-12-26 14:32:02 +08:00
->first();
}
private function getShopShip($shopId)
{
return ShopShip::query()
->select(['id', 'shop_id', 'access_token', 'owner_id'])
->where('shop_id', $shopId)
->with([
'senders' => function ($query) {
$query->where('status', 1)->orderBy('sort');
}
])
->first();
}
}