发货单区分BC单

This commit is contained in:
ZweiCD 2020-07-13 18:57:14 +08:00
parent 23b3edbf8c
commit de0e7ecaae
5 changed files with 134 additions and 786 deletions

View File

@ -2,6 +2,16 @@
return [ return [
'address_list' => ['浙江省', '江苏省', '上海市'], 'address_list' => ['浙江省', '江苏省', '上海市'],
'jzh_express_weight' => 35, 'jzh_express_weight' => 30,
'other_express_weight' => 50, 'other_express_weight' => 50,
'logistics' => [
'toB' => [
'code' => 'YTO',
'name' => '圆通',
],
'toC' => [
'code' => 'STO',
'name' => '申通',
]
],
]; ];

View File

@ -12,31 +12,6 @@ class BaseWms
'40' => 'QTRK', '40' => 'QTRK',
]; ];
/**
* 选择物流公司
* @param string $province
* @param string $weight
* @return string
*/
public function chooseLogisticsCompany($province, $weight)
{
$expressChooseConf = require(dirname(dirname(__FILE__)) . '/config/express_choose.php');
if (in_array($province, $expressChooseConf['address_list'])) {
if ($weight >= $expressChooseConf['jzh_express_weight']) {
$logisticsCode = 'KYE';
} else {
$logisticsCode = 'STO';
}
} else {
if ($weight >= $expressChooseConf['other_express_weight']) {
$logisticsCode = 'KYE';
} else {
$logisticsCode = 'STO';
}
}
return $logisticsCode;
}
function filterEmoji(string $str): string function filterEmoji(string $str): string
{ {
if (!empty($str)) { if (!empty($str)) {
@ -51,61 +26,6 @@ class BaseWms
return $str; return $str;
} }
/**
* 金额转换分=》元
*
* @param mixed $data
* @param array $fields 一层数组字段转化
* @param array $multi 两层数组转化
*
* @return float|array
*/
function cent2yuan($data, $fields = [], $multi = [])
{
if (is_array($data) && !empty($data)) {
if (!empty($multi)) {
foreach ($multi as $key => $val) {
$data[$key] = $this->cent2yuan($data[$key], $val);
}
}
if (!empty($fields)) {
foreach ($fields as $key => &$val) {
if (is_int($key) && isset($data[$val])) {
$data[$val] = $this->formatMoneyDiv($data[$val], 100, 2);
}
if (!is_int($key) && isset($data[$key]) && is_array($val)) {
foreach ($data[$key] as &$datum) {
foreach ($val as $item) {
$datum[$item] = $this->formatMoneyDiv(
$datum[$item],
100,
2
);
}
}
}
}
return $data;
}
}
if (is_numeric($data) || is_string($data)) {
if ($data === 0 || $data === '0') {
return '0.00';
} else {
return $this->formatMoneyDiv($data, 100, 2);
}
}
return $data;
}
/** 除法 */
function formatMoneyDiv($param1, $param2, $scale = 2)
{
return bcdiv($param1, $param2, $scale);
}
//格式化金额 //格式化金额
function formatNumber($number, $decimals = 2) function formatNumber($number, $decimals = 2)
{ {

View File

@ -51,7 +51,7 @@ class QimenWms extends BaseWms implements WmsInterface
'shopNick' => $order['order_sender_info']['shop_name'] ?? static::$default_shop_name, 'shopNick' => $order['order_sender_info']['shop_name'] ?? static::$default_shop_name,
'sellerNick' => $order['order_sender_info']['shop_name'] ?? static::$default_seller_nick, 'sellerNick' => $order['order_sender_info']['shop_name'] ?? static::$default_seller_nick,
'remark' => $order['remark'], 'remark' => $order['remark'],
'logisticsCode' => $order['order_sender_info']['logistics_code'] ?? '', 'logisticsCode' => $order['order_sender_info']['logistics_code'],
//发货人信息 //发货人信息
'senderInfo' => [ 'senderInfo' => [
'name' => $order['order_sender_info']['name'] ?? static::$default_sender_name, 'name' => $order['order_sender_info']['name'] ?? static::$default_sender_name,
@ -76,11 +76,10 @@ class QimenWms extends BaseWms implements WmsInterface
]; ];
$orderLine = []; $orderLine = [];
$skuTotalWeight = 0;
$ownerCode = $this->config['shipper_code']; //货主编码 $ownerCode = $this->config['shipper_code']; //货主编码
foreach ($order['order_goods'] as $item) { foreach ($order['order_goods'] as $item) {
$itemName = $item['goods_name'] . '(' . $item['sku_name'] . ')'; //商品名称 $itemName = $item['goods_name'] . '(' . $item['sku_name'] . ')'; //商品名称
$actualPrice = $this->cent2yuan($item['sku_pay_fee']); //实际成交价 $actualPrice = $item['sku_pay_fee']; //实际成交价
if ($item['sku_type'] == 0) { if ($item['sku_type'] == 0) {
array_push($orderLine, [ array_push($orderLine, [
'ownerCode' => $ownerCode, 'ownerCode' => $ownerCode,
@ -90,7 +89,6 @@ class QimenWms extends BaseWms implements WmsInterface
'planQty' => $item['sku_quantity'], //应发商品数量 'planQty' => $item['sku_quantity'], //应发商品数量
'actualPrice' => $actualPrice, 'actualPrice' => $actualPrice,
]); ]);
$skuTotalWeight += ($item['weight'] * $item['sku_quantity']) / 1000;
} elseif ($item['sku_type'] == 1) { } elseif ($item['sku_type'] == 1) {
foreach ($item['sku_nexus_snapshot'] as $gv) { foreach ($item['sku_nexus_snapshot'] as $gv) {
array_push($orderLine, [ array_push($orderLine, [
@ -100,16 +98,11 @@ class QimenWms extends BaseWms implements WmsInterface
'itemName' => $itemName, 'itemName' => $itemName,
'planQty' => $gv['sku_quantity'] * $item['sku_quantity'], 'planQty' => $gv['sku_quantity'] * $item['sku_quantity'],
'actualPrice' => $actualPrice, 'actualPrice' => $actualPrice,
]); ]);
$skuTotalWeight += ($gv['weight'] * $gv['sku_quantity'] * $item['sku_quantity']) / 1000;
} }
} }
} }
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]); $postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);
if (!isset($order['order_sender_info']['logistics_code']) || !$order['order_sender_info']['logistics_code']) {
$postData['deliveryOrder'] = array_merge($postData['deliveryOrder'], ['logisticsCode' => $this->chooseLogisticsCompany($order['order_address']['receive_province'], $skuTotalWeight)]);
}
$result = $this->xmlPost($method, $postData); $result = $this->xmlPost($method, $postData);
return $result; return $result;
@ -327,12 +320,12 @@ class QimenWms extends BaseWms implements WmsInterface
'deliveryOrderCode' => $params['out_warehouse_number'], //出库单号 'deliveryOrderCode' => $params['out_warehouse_number'], //出库单号
'orderType' => 'DBCK', //出库单类型 'orderType' => 'DBCK', //出库单类型
'warehouseCode' => $this->config['warehouse_code'], //仓库编码 'warehouseCode' => $this->config['warehouse_code'], //仓库编码
'logisticsCode' => 'SF', 'logisticsCode' => $params['order_sender_info']['logistics_code'] ?? 'SF',
'logisticsName' => '顺丰', 'logisticsName' => $params['order_sender_info']['logistics_name'] ?? '顺丰',
'createTime' => date('Y-m-d H:i:s'), //出库单创建时间 'createTime' => date('Y-m-d H:i:s'), //出库单创建时间
'receiverInfo' => [ 'receiverInfo' => [
'name' => $params['address_name'], 'name' => $this->filterEmoji($params['address_name']),
'zipCode' => $params['receive_zip_code'] ?? self::DEFAULT_ZIP_CODE, 'zipCode' => $params['receive_zip_code'] ?? self::$default_zip_code,
'mobile' => $params['address_telephone'], 'mobile' => $params['address_telephone'],
'province' => $params['address_province'], 'province' => $params['address_province'],
'city' => $params['address_city'], 'city' => $params['address_city'],
@ -346,12 +339,16 @@ class QimenWms extends BaseWms implements WmsInterface
$ownerCode = $this->config['shipper_code']; $ownerCode = $this->config['shipper_code'];
$orderLine = []; $orderLine = [];
foreach ($params['order_goods'] as $item) { foreach ($params['order_goods'] as $item) {
$itemName = $item['product_name'] . "(" . $item['sku_name'] . ")"; //商品名称
$actualPrice = $item['sku_pay_fee'] ?? 0;
if (!isset($item['sku_type']) || $item['sku_type'] == 0) {
$goodsZP = [ $goodsZP = [
'ownerCode' => $ownerCode, //货主编码 'ownerCode' => $ownerCode, //货主编码
'itemCode' => $item['wms_code'], //商品编码 'itemCode' => $item['wms_code'], //商品编码
'itemId' => $item['wms_code'], //仓储系统商品编码 'itemId' => $item['wms_code'], //仓储系统商品编码
'itemName' => $item['product_name'] . "(" . $item['sku_name'] . ")", //商品名称 'itemName' => $itemName,
'planQty' => $item['number'], //应发商品数量 'planQty' => $item['number'], //应发商品数量
'actualPrice' => $actualPrice,
'inventoryType' => 'ZP', //库存类型ZP=正品, CC=残次,JS=机损, XS= 箱损 'inventoryType' => 'ZP', //库存类型ZP=正品, CC=残次,JS=机损, XS= 箱损
]; ];
if ($item['number'] > 0) { if ($item['number'] > 0) {
@ -364,6 +361,19 @@ class QimenWms extends BaseWms implements WmsInterface
]); ]);
array_push($orderLine, $goodsCC); array_push($orderLine, $goodsCC);
} }
} elseif ($item['sku_type'] == 1) {
foreach ($item['sku_nexus_snapshot'] as $gv) {
array_push($orderLine, [
'ownerCode' => $ownerCode,
'itemCode' => $gv['wms_code'],
'itemId' => $gv['wms_code'],
'itemName' => $itemName,
'planQty' => $gv['sku_quantity'] * $item['sku_quantity'],
'actualPrice' => $actualPrice,
'inventoryType' => 'ZP',
]);
}
}
} }
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]); $postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);

View File

@ -11,9 +11,6 @@ class WmsStrategy
$config = require(dirname(dirname(__FILE__)) . '/config/wms.php'); $config = require(dirname(dirname(__FILE__)) . '/config/wms.php');
switch ($warehouseId) switch ($warehouseId)
{ {
case $config['xinyi']['warehouse_id']:
$this->wmsClient = new XinyiWms($config['xinyi']);
break;
case $config['fineex']['warehouse_id']: case $config['fineex']['warehouse_id']:
$this->wmsClient = new FineexWms($config['fineex']); $this->wmsClient = new FineexWms($config['fineex']);
break; break;
@ -22,6 +19,38 @@ class WmsStrategy
} }
} }
public function saleOrderCreate($params) {
//计算商品重量
$skuTotalWeight = $this->getSkuTotalWeight($params['order_goods']);
$logistics = $this->chooseLogisticsCompany($params['order_address']['receive_province'], $skuTotalWeight);
$params['order_sender_info']['logistics_code'] = $logistics['code'];
$params['order_sender_info']['logistics_name'] = $logistics['name'];
if ($logistics['type'] == 'toC') {
// 2C订单发货
$res = $this->deliveryOrderCreate($params);
$type = 1;
} else {
// 2B订单发货
$params['out_warehouse_number'] = $params['order_no'];
$params['address_name'] = $params['order_address']['receive_name'];
$params['address_telephone'] = $params['order_address']['receive_mobile'];
$params['address_province'] = $params['order_address']['receive_province'];
$params['address_city'] = $params['order_address']['receive_city'];
$params['address_area'] = $params['order_address']['receive_district'];
$params['address_detail'] = $params['order_address']['receive_address'];
foreach ($params['order_goods'] as &$item) {
$item['product_name'] = $item['goods_name'];
$item['number'] = $item['sku_quantity'];
}
$res = $this->stockOutCreate($params);
$type = 0;
}
$res['response']['type'] = $type;
return $res;
}
public function deliveryOrderCreate($params) { public function deliveryOrderCreate($params) {
return $this->wmsClient->deliveryOrderCreate($params); return $this->wmsClient->deliveryOrderCreate($params);
} }
@ -53,4 +82,55 @@ class WmsStrategy
public function stockOutCreate($params) { public function stockOutCreate($params) {
return $this->wmsClient->stockOutCreate($params); return $this->wmsClient->stockOutCreate($params);
} }
/**
* 获取sku总重量
* @param $orderGoods
* @return float|int
*/
public function getSkuTotalWeight($orderGoods)
{
$skuTotalWeight = 0;
foreach ($orderGoods as $item) {
$item['product_name'] = $item['goods_name'];
$item['number'] = $item['sku_quantity'];
if ($item['sku_type'] == 0) {
$skuTotalWeight += ($item['weight'] * $item['sku_quantity']) / 1000;
} elseif ($item['sku_type'] == 1) {
foreach ($item['sku_nexus_snapshot'] as $gv) {
$skuTotalWeight += ($gv['weight'] * $gv['sku_quantity'] * $item['sku_quantity']) / 1000;
}
}
}
return $skuTotalWeight;
}
/**
* 选择物流公司
* @param string $province
* @param string $weight
* @return array
*/
public function chooseLogisticsCompany($province, $weight)
{
$expressChooseConf = require(dirname(dirname(__FILE__)) . '/config/express_choose.php');
if (in_array($province, $expressChooseConf['address_list'])) {
if ($weight >= $expressChooseConf['jzh_express_weight']) {
$type = 'toB';
} else {
$type = 'toC';
}
} else {
if ($weight >= $expressChooseConf['other_express_weight']) {
$type = 'toB';
} else {
$type = 'toC';
}
}
return [
'type' => $type,
'code' => $expressChooseConf['logistics'][$type]['code'],
'name' => $expressChooseConf['logistics'][$type]['name'],
];
}
} }

View File

@ -1,672 +0,0 @@
<?php
namespace PdWms;
use App\Service\Goods\GoodsWarehouseService;
use App\Service\Order\OrderItemLackReportService;
use App\Service\Order\OrderProcessReportService;
use App\Service\Order\OrderService;
use App\Service\Order\RefundService;
use PdWms\Service\Array2XML;
use PdWms\Service\XML2Array;
use GuzzleHttp\Client;
class XinyiWms extends BaseWms implements WmsInterface
{
const DEFAULT_SHOP_NAME = '北京拍店';
const DEFAULT_SELLER_NICK = '北京拍店';
const DEFAULT_SENDER_NAME = '北京拍店';
const DEFAULT_SENDER_MOBILE = '18816537510';
const DEFAULT_SENDER_PROVINCE = '浙江省';
const DEFAULT_SENDER_CITY = '嘉兴市';
const DEFAULT_SENDER_AREA = '秀洲区';
const DEFAULT_SENDER_ADDRESS = '岗山路75号维龙仓储3号库';
const DEFAULT_ZIP_CODE = '000000';
protected $config = [];
public function __construct($config = null)
{
$wmsConf = $config ?? (require(dirname(dirname(__FILE__)) . '/config/wms.php'))['xinyi'];
$this->config = $wmsConf;
}
/**
* 销售发货单创建
* @param array $order
* @return array|\DOMDocument
*/
public function deliveryOrderCreate($order)
{
$method = 'deliveryorder.create';
$postData = [
'deliveryOrder' => [
'deliveryOrderCode' => $order['order_no'], //出库单号
'orderType' => 'JYCK', //出库单类型, string (50) , 必填, JYCK=一般交易出库单, HHCK=换货出库单,BFCK=补发出库单QTCK=其他出库单
'warehouseCode' => $this->config['warehouse_code'], //仓库编码
'sourcePlatformCode' => 'OTHER', //订单来源平台编码
'createTime' => date('Y-m-d H:i:s'), //发货单创建时间
'placeOrderTime' => $order['created_at'], //前台订单 (店铺订单) 创建时间 (下单时间)
'operateTime' => date('Y-m-d H:i:s'), //操作 (审核) 时间
'shopNick' => $order['order_sender_info']['shop_name'] ?? self::DEFAULT_SHOP_NAME,
'sellerNick' => $order['order_sender_info']['shop_name'] ?? self::DEFAULT_SELLER_NICK,
'remark' => $order['remark'],
'logisticsCode' => $order['order_sender_info']['logistics_code'] ?? '',
//发货人信息
'senderInfo' => [
'name' => $order['order_sender_info']['name'] ?? self::DEFAULT_SENDER_NAME,
'mobile' => $order['order_sender_info']['tel'] ?? self::DEFAULT_SENDER_MOBILE,
'province' => self::DEFAULT_SENDER_PROVINCE,
'city' => self::DEFAULT_SENDER_CITY,
'area' => self::DEFAULT_SENDER_AREA,
'detailAddress' => self::DEFAULT_SENDER_ADDRESS,
],
//收件人信息
'receiverInfo' => [
'name' => $this->filterEmoji($order['order_address']['receive_name']),
'zipCode' => $order['order_address']['receive_zip_code'] ?? self::DEFAULT_ZIP_CODE,
'mobile' => trim($order['order_address']['receive_mobile']),
'province' => $order['order_address']['receive_province'],
'city' => $order['order_address']['receive_city'],
'area' => $order['order_address']['receive_district'],
'detailAddress' => $order['order_address']['receive_address'],
],
],
'orderLines' => [],
'stock_out_create' => 0,
];
$orderLine = [];
$skuTotalWeight = 0;
$orderLineNo = 0; //单据行号
$ownerCode = $this->config['shipper_code']; //货主编码
foreach ($order['order_goods'] as $item) {
$itemName = $item['goods_name'] . '(' . $item['sku_name'] . ')'; //商品名称
$actualPrice = $this->cent2yuan($item['sku_pay_fee']); //实际成交价
if ($item['sku_type'] == 0) {
array_push($orderLine, [
'orderLineNo' => $orderLineNo,
'ownerCode' => $ownerCode,
'itemCode' => $item['wms_code'], //商品编码
'itemId' => $item['wms_code'], //仓储系统商品编码
'itemName' => $itemName,
'planQty' => $item['sku_quantity'], //应发商品数量
'actualPrice' => $actualPrice,
]);
$skuTotalWeight += ($item['weight'] * $item['sku_quantity']) / 1000;
$orderLineNo++;
} elseif ($item['sku_type'] == 1) {
foreach ($item['sku_nexus_snapshot'] as $gv) {
array_push($orderLine, [
'orderLineNo' => $orderLineNo,
'ownerCode' => $ownerCode,
'itemCode' => $gv['wms_code'],
'itemId' => $gv['wms_code'],
'itemName' => $itemName,
'planQty' => $gv['sku_quantity'] * $item['sku_quantity'],
'actualPrice' => $actualPrice,
]);
$skuTotalWeight += ($gv['weight'] * $gv['sku_quantity'] * $item['sku_quantity']) / 1000;
$orderLineNo++;
}
}
}
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);
if (!isset($order['order_sender_info']['logistics_code']) || !$order['order_sender_info']['logistics_code']) {
$postData['deliveryOrder'] = array_merge($postData['deliveryOrder'], ['logisticsCode' => $this->chooseLogisticsCompany($order['order_address']['receive_province'], $skuTotalWeight)]);
}
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* 商品库存查询(单个)
* @param $wmsCode
* @param string $inventoryType
* @return array|\DOMDocument
*/
public function inventoryQuerySingle($wmsCode, $inventoryType = 'ZP')
{
return $this->inventoryQuery([['wms_code' => $wmsCode]], $inventoryType);
}
/**
* 商品库存查询(批量)
* @param array $params
* @param string $inventoryType
* @return array|\DOMDocument
*/
public function inventoryQuery($params, $inventoryType = 'ZP')
{
$method = 'inventory.query';
$postData = [
'criteriaList' => [
'criteria' => [],
],
];
foreach ($params as $item) {
array_push($postData['criteriaList']['criteria'], [
'warehouseCode' => $this->config['warehouse_code'],
'ownerCode' => $this->config['shipper_code'],
'itemCode' => $item['wms_code'],
'itemId' => $item['wms_code'],
'inventoryType' => $inventoryType,
]);
}
$result = $this->xmlPost($method, $postData);
return $result['success']
? array_merge($result, ['response' => $result['response']['items']['item']])
: $result;
}
/**
* 商品同步(商品创建或修改)
* @param array $params
* @return array|\DOMDocument
*/
public function goodsSkuSync($params)
{
$method = 'singleitem.synchronize';
$postData = [
'actionType' => $params['action_type'],
'warehouseCode' => $this->config['warehouse_code'],
'ownerCode' => $this->config['shipper_code'],
'item' => [
[
'itemCode' => $params['wms_code'],
'itemId' => $params['wms_code'],
'itemName' => $params['name'],
'barCode' => $params['upc_code'] ?? $params['wms_code'],
//商品类型 (ZC=正常商品, FX=分销商品, ZH=组合商品, ZP=赠品, BC=包材, HC=耗材, FL=辅料, XN=虚拟品,
//FS=附属品, CC=残次品, OTHER=其它) , string (10) , 必填, (只传英文编码)
'itemType' => 'ZC',
'retailPrice' => $params['unit_price'],
'isValid' => 'Y',
]
],
];
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* 单据取消
* @param array $params
* @return array|\DOMDocument
*/
public function orderCancel($params)
{
$method = 'order.cancel';
$postData = [
'warehouseCode' => $this->config['warehouse_code'],
'orderCode' => $params['order_code'],
'orderId' => $params['order_code'],
'orderType' => $params['order_type'],
'cancelReason' => $params['cancel_reason'],
];
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* 退货入库单创建(新增销售退货计划)
* @param array $params
* @return array|\DOMDocument
*/
public function returnOrderCreate($params)
{
$method = 'returnorder.create';
$postData = [
'returnOrder' => [
'returnOrderCode' => $params['refund_no'],
'warehouseCode' => $this->config['warehouse_code'],
'orderType' => 'THRK',
'preDeliveryOrderCode' => $params['order_info']['order_no'],
'preDeliveryOrderId' => $params['order_info']['order_no'],
'logisticsCode' => strtoupper($params['express_code']),
'logisticsName' => $params['express_company'],
'expressCode' => $params['express_no'],
'returnReason' => $params['desc'],
'senderInfo' => [
'name' => $params['order_address_info']['receive_name'],
'mobile' => $params['order_address_info']['receive_mobile'],
'province' => $params['order_address_info']['receive_province'],
'city' => $params['order_address_info']['receive_city'],
'area' => $params['order_address_info']['receive_district'],
'detailAddress' => $params['order_address_info']['receive_address'],
],
],
'orderLines' => [],
];
$orderLine = [];
$ownerCode = $this->config['shipper_code'];
foreach ($params['refund_goods'] as $item) {
if ($item['sku_type'] == 0) {
array_push($orderLine, [
'ownerCode' => $ownerCode,
'itemCode' => $item['wms_code'],
'itemId' => $item['wms_code'],
'planQty' => $item['sku_quantity'],
'inventoryType' => 'ZP',
]);
} elseif ($item['sku_type'] == 1) {
foreach ($item['combined_sku'] as $v) {
array_push($orderLine, [
'ownerCode' => $ownerCode,
'itemCode' => $v['wms_code'],
'itemId' => $v['wms_code'],
'planQty' => $v['sku_quantity'],
'inventoryType' => 'ZP',
]);
}
}
}
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* 新增入库计划
* @param array $params
* @param int $type
* @return array|\DOMDocument
*/
public function stockInCreate($params, $type = 0)
{
$method = 'entryorder.create';
$ownerCode = $this->config['shipper_code'];
$postData = [
'entryOrder' => [
'entryOrderCode' => $params['number'],
'ownerCode' => $ownerCode,
'purchaseOrderCode' => $this->goodsWarehouseCgrkNumber(),
'warehouseCode' => $this->config['warehouse_code'],
'orderType' => self::RK_TYPE[$params['type']] ?? 'DBRK',
],
'orderLines' => [],
];
$orderLineNo = 1;
$orderLine = [];
foreach ($params['sku_info'] as $skuV) {
$stockZP = [
'orderLineNo' => $orderLineNo,
'ownerCode' => $ownerCode,
'itemCode' => $skuV['wms_code'],
'itemId' => $skuV['wms_code'],
'planQty' => $skuV['apply_stock'] * 1,
'purchasePrice' => $this->formatNumber($skuV['price']),
'inventoryType' => 'ZP',
];
$orderLineNo++;
array_push($orderLine, $stockZP);
if (!empty($skuV["apply_bad_stock"])) {
$stockCC = array_merge($stockZP, [
'orderLineNo' => $orderLineNo,
'planQty' => $skuV['apply_bad_stock'] * 1,
'inventoryType' => 'CC',
]);
array_push($orderLine, $stockCC);
$orderLineNo++;
}
}
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* 新增出库计划
* @param array $params
* @return array|\DOMDocument
*/
public function stockOutCreate($params)
{
$method = 'stockout.create';
$postData = [
'deliveryOrder' => [
'deliveryOrderCode' => $params['out_warehouse_number'], //出库单号
'orderType' => 'DBCK', //出库单类型
'warehouseCode' => $this->config['warehouse_code'], //仓库编码
'logisticsCode' => 'SF',
'logisticsName' => '顺丰',
'createTime' => date('Y-m-d H:i:s'), //出库单创建时间
'receiverInfo' => [
'name' => $params['address_name'],
'zipCode' => $params['receive_zip_code'] ?? self::DEFAULT_ZIP_CODE,
'mobile' => $params['address_telephone'],
'province' => $params['address_province'],
'city' => $params['address_city'],
'area' => $params['address_area'],
'detailAddress' => $params['address_detail'],
],
],
'orderLines' => [],
];
$ownerCode = $this->config['shipper_code'];
$orderLine = [];
foreach ($params['order_goods'] as $item) {
$goodsZP = [
'ownerCode' => $ownerCode, //货主编码
'itemCode' => $item['wms_code'], //商品编码
'itemId' => $item['wms_code'], //仓储系统商品编码
'itemName' => $item['product_name'] . "(" . $item['sku_name'] . ")", //商品名称
'planQty' => $item['number'], //应发商品数量
'inventoryType' => 'ZP', //库存类型ZP=正品, CC=残次,JS=机损, XS= 箱损
];
if ($item['number'] > 0) {
array_push($orderLine, $goodsZP);
}
if (isset($item['bad_num']) && $item['bad_num'] > 0) {
$goodsCC = array_merge($goodsZP, [
'planQty' => $item['number'],
'inventoryType' => 'CC',
]);
array_push($orderLine, $goodsCC);
}
}
$postData = array_merge($postData, ['orderLines' => ['orderLine' => $orderLine]]);
$result = $this->xmlPost($method, $postData);
return $result;
}
/**
* @生产签名
*
* @param $method
* @param string $body
* @param string $timestamp
* @return []
*/
public function createSign($method, $body = '', $timestamp = '') {
$timestamp = $timestamp ?? date('Y-m-d H:i:s', time());
$app_key = $this->config['app_key'];
$app_secret = $this->config['app_secret'];
$version = $this->config['version'];
$customer_id = $this->config['customerId'];
$format = $this->config['format'];
$sign_method = $this->config['sign_method'];
$treeMap['method'] = $method;
$treeMap['timestamp'] = $timestamp;
$treeMap['format'] = $format;
$treeMap['app_key'] = $app_key;
$treeMap['v'] = $version;
$treeMap['sign_method'] = $sign_method;
$treeMap['customerId'] = $customer_id;
ksort($treeMap);
$info = '';
foreach ($treeMap as $key => $val) {
$info .= $key;
$info .= $val;
}
$info .= $body;
$info = $app_secret . '' . $info . '' . $app_secret;
$sign = strtoupper(md5($info));
$params['method'] = $method;
$params['timestamp'] = $timestamp;
$params['format'] = $format;
$params['app_key'] = $app_key;
$params['v'] = $version;
$params['sign'] = $sign;
$params['sign_method'] = $sign_method;
$params['customerId'] = $customer_id;
return $params;
}
final protected function post($body, $params = [], $headers = ['content-type' => 'text/xml; charset = utf-8'], $ret = []) {
$url = $this->config['base_uri'];
$url = $url . http_build_query($params);
$data = [
'body' => $body,
'headers' => $headers,
];
$client = new Client();
$response = $client->request('POST', $url, $data);
$content = $response->getBody()->getContents();
return $content;
}
function getResponse($content) {
$result = XML2Array::createArray($content);
$isSuccess = (empty($result) || !is_array($result) || $result['response']['flag'] != 'success') ? false : true;
$response = [
'success' => $isSuccess,
'response' => $isSuccess ? $result['response'] : $result,
];
return $response;
}
public function xmlPost($method, $params)
{
$xml = Array2XML::createXML('request', $params);
$body = $xml->saveXML();
$res = $this->createSign($method, $body);
$content = $this->post($body, $res);
return $this->getResponse($content);
}
/**
* 确认回传方法
* @var array
*/
private static $callbackMethods = [
'taobao.qimen.deliveryorder.confirm' => 'deliveryOrderConfirm',
'taobao.qimen.entryorder.confirm' => 'stockInConfirm',
'taobao.qimen.itemlack.report' => 'itemLackReport',
'taobao.qimen.orderprocess.report' => 'orderProcessReport',
'taobao.qimen.returnorder.confirm' => 'returnOrderConfirm',
'taobao.qimen.stockchange.report' => 'stockChangeReport',
'taobao.qimen.stockout.confirm' => 'stockOutConfirm',
];
public function callback($params)
{
if (!isset($params['method']) || empty($params['method'])) {
return $this->response('缺少参数method', false);
}
if (!isset($params['timestamp']) || empty($params['timestamp'])) {
return $this->response('缺少参数timestamp', false);
}
if (!isset($params['format']) || empty($params['format'])) {
return $this->response('缺少参数format', false);
}
if (!isset($params['app_key']) || empty($params['app_key'])) {
return $this->response('缺少参数key', false);
}
if (!isset($params['v']) || empty($params['v'])) {
return $this->response('缺少版本参数', false);
}
if (!isset($params['sign']) || empty($params['sign'])) {
return $this->response('缺少参数sign', false);
}
if (!isset($params['sign_method']) || empty($params['sign_method'])) {
return $this->response('缺少加密方式', false);
}
if (!isset($params['customerId']) || empty($params['customerId'])) {
return $this->response('缺少参数customerId', false);
}
if (empty(($params['body']))) {
return $this->response('缺少消息body', false);
}
$method = $params['method'];
if (!array_key_exists($method, self::$callbackMethods)) {
return $this->response('调用的方法不存在', false);
}
if (!$this->checkSign($params)) {
return $this->response('签名错误', false);
}
$body = XML2Array::createArray($params['body']);
if (!isset($body['request']) || empty($body['request'])) {
return $this->response('消息body错误', false);
}
$result = call_user_func([$this, self::$callbackMethods[$method]], $body['request']);
return $result;
}
/**
* 发货单确认
* @param $params
* @return array
*/
private function deliveryOrderConfirm ($params)
{
$service = new OrderService();
$result = $service->deliverOrderConfirm($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 入库单确认
* @param $params
* @return array
*/
private function stockInConfirm($params)
{
$service = new GoodsWarehouseService();
$result = $service->entryorderConfirm($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 发货单缺货通知
* @param $params
* @return array
*/
private function itemLackReport($params)
{
$service = new OrderItemLackReportService();
$result = $service->createReceipts($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 订单流水通知
* @param $params
* @return array
*/
private function orderProcessReport($params)
{
$service = new OrderProcessReportService();
$result = $service->orderProcessReport($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 退货入库单确认
* @param $params
* @return array
*/
private function returnOrderConfirm($params)
{
$service = new RefundService();
$result = $service->refundOrderConfirm($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 库存异动通知
* @param $params
* @return array
*/
private function stockChangeReport($params)
{
$service = new GoodsWarehouseService();
$result = $service->StockChangeReport($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* 出库单确认
* @param $params
* @return array
*/
private function stockOutConfirm($params)
{
$service = new OrderService();
$result = $service->stockOutOrderConfirm($params);
if (!$result) {
return $this->response('失败', false);
}
return $this->response();
}
/**
* @检查签名
* @param $params
* @return bool
*/
public function checkSign($params)
{
if (empty($params)) {
return false;
}
$sign = $params['sign'];
$new_sign = $this->createSign(
$params['method'],
$params['body'],
$params['timestamp']
);
if (!hash_equals((string) $new_sign['sign'], (string) $sign)) {
return false;
}
return true;
}
public function response($message = '成功', $flag = true)
{
$response = [
'flag' => $flag ? 'success' : 'failure',
'code' => $flag ? '001' : '002',
'message' => $message,
];
$xml = Array2XML::createXML('response', $response);
$body = $xml->saveXML();
return [
'content' => $body,
'status' => 200,
'headers' => ['Content-Type' => 'xml'],
];
}
}