mirror of
https://gitee.com/ShopeX/OMS
synced 2026-03-30 21:15:34 +08:00
3525 lines
136 KiB
PHP
3525 lines
136 KiB
PHP
<?php
|
||
/**
|
||
* Copyright © ShopeX (http://www.shopex.cn). All rights reserved.
|
||
* See LICENSE file for license details.
|
||
*/
|
||
/**
|
||
* sap业务处理Lib方法
|
||
*
|
||
* @author wangbiao@shopex.cn
|
||
* @version 2023.12.25
|
||
*/
|
||
class ediws_sap
|
||
{
|
||
/**
|
||
* 生成Sap销售单记录
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
|
||
public function createSapSales($params)
|
||
{
|
||
$saleObj = app::get('vfapi')->model('sales');
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
$syncSaleLib = kernel::single('vfapi_tasks_syncsales');
|
||
|
||
//货号对照表
|
||
base_kvstore::instance('vfapi')->fetch('goodsmap.erp', $erpProductList);
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定查询条件!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $saleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的销售单!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//以shop店铺编码为下标,获取TTPOS列表
|
||
$shopTtposList = $funcLib->getShopTtposList();
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//是否读取固定折扣价
|
||
$is_read_price = false;
|
||
|
||
//getList
|
||
$tempList = $saleObj->getList('*', $filter, 0, $page_size, 'id ASC');
|
||
if(empty($tempList)){
|
||
//没有查询到销售单数据
|
||
continue;
|
||
}
|
||
|
||
//format
|
||
$soldList = array();
|
||
$dataList = array();
|
||
$productBns = array();
|
||
foreach($tempList as $key => $val)
|
||
{
|
||
$id = $val['id'];
|
||
$sale_bn = $val['sale_bn'];
|
||
$ttpos_store = $val['ttpos_store'];
|
||
$shop_bn = $val['erp_store'];
|
||
|
||
//check
|
||
if(in_array($val['status'], array('1'))){
|
||
//单据已经处理,不允许重复操作
|
||
$error_msg = '单据已经处理,不允许重复操作!';
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if(empty($ttpos_store)){
|
||
$error_msg = '没有ttpos_store编码';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//shop
|
||
$shopInfo = $shopTtposList[$shop_bn];
|
||
if(empty($shopInfo)){
|
||
$error_msg = 'ttpos_store编码没有配置店铺对照关系';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//是否生成销售文件配置开关
|
||
if($shopInfo['is_sale_file'] == 'false'){
|
||
$error_msg = '是否生成销售文件:未启用';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//unserialize
|
||
$addonData = unserialize($val['addon']);
|
||
unset($val['addon']);
|
||
|
||
//check
|
||
if(empty($addonData['sale_items']) || !is_array($addonData['sale_items'])){
|
||
$error_msg = '没有销售明细';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//收货人信息
|
||
$val['consignee'] = $addonData['consignee'];
|
||
$val['consignee_area'] = $addonData['consignee_area'];
|
||
$val['consignee_mobile'] = $addonData['consignee_mobile'];
|
||
$val['consignee_tel'] = $addonData['consignee_tel'];
|
||
|
||
//[渠道类型]是否京东云仓类型
|
||
if($addonData['shopinfo']['shop_type'] == '360buy' && $addonData['shopinfo']['business_type'] == 'jdlvmi'){
|
||
//京东云仓
|
||
$val['channel_type'] = 'jd_cloud';
|
||
|
||
//读取读取固定折扣价
|
||
$is_read_price = true;
|
||
}else{
|
||
$val['channel_type'] = 'oms'; //OMS普通销售单
|
||
}
|
||
|
||
//items
|
||
$saleItems = $addonData['sale_items'];
|
||
|
||
//格式化赠品数据
|
||
$saleItems = $this->formatSaleItems($saleItems, $erpProductList);
|
||
if(empty($saleItems)){
|
||
$error_msg = '格式化销售明细为空(只有一个SKU并且是赠品);';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>4, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//sole_bn
|
||
foreach ($saleItems as $item_id => $itemVal)
|
||
{
|
||
$product_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 货号 + item_id
|
||
$sole_bn = $sale_bn .'_'. $product_bn .'_'. $item_id;;
|
||
$soldList[$sole_bn] = $sole_bn;
|
||
|
||
//bns
|
||
$productBns[$product_bn] = $product_bn;
|
||
}
|
||
|
||
//merge
|
||
$val['sale_items'] = $saleItems;
|
||
|
||
//data
|
||
$dataList[$id] = $val;
|
||
}
|
||
|
||
//unset
|
||
unset($tempList);
|
||
|
||
//check
|
||
if(empty($dataList)){
|
||
//没有有效的数据
|
||
$error_msg = '没有有效的数据!';
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//已经存在的数据
|
||
$existData = array();
|
||
if($soldList){
|
||
$existData = $sapSaleObj->getList('id,sole_bn', array('sole_bn'=>$soldList));
|
||
if($existData){
|
||
$existData = $funcLib->_array_column($existData, null, 'sole_bn');
|
||
}
|
||
}
|
||
|
||
//固定折扣价格(获取导入的固定折扣价格)
|
||
$getPriceList = array();
|
||
if($is_read_price && $productBns){
|
||
$getPriceList = $this->getImportPriceList($productBns);
|
||
}
|
||
|
||
//list
|
||
foreach ($dataList as $saleId => $saleVal)
|
||
{
|
||
$id = $saleVal['id'];
|
||
$sale_bn = $saleVal['sale_bn'];
|
||
$sale_time = $saleVal['sale_time'];
|
||
//$ttpos_store = $saleVal['ttpos_store'];
|
||
$shop_bn = $saleVal['erp_store'];
|
||
|
||
//渠道类型
|
||
$channel_type = $saleVal['channel_type'];
|
||
|
||
//店铺配置信息
|
||
$shopInfo = $shopTtposList[$shop_bn];
|
||
|
||
//items
|
||
$linenum = 0;
|
||
foreach ($saleVal['sale_items'] as $item_id => $itemVal)
|
||
{
|
||
$product_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 货号 + item_id
|
||
$sole_bn = $sale_bn .'_'. $product_bn .'_'. $item_id;;
|
||
|
||
//check
|
||
if($existData[$sole_bn]){
|
||
$error_msg = '已经生成过Sap销售记录';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
$linenum++;
|
||
|
||
//format
|
||
$saleVal['operation'] = 'create_sap_sale'; //标记为创建Sap销售记录
|
||
$saleVal['sale_time'] = date('Y-m-d H:i:s', $sale_time);
|
||
$saleVal['sale_no'] = $sale_bn;
|
||
$saleVal['order_no'] = $saleVal['order_bn'];
|
||
|
||
//读取固定折扣价
|
||
$is_oms_price = true;
|
||
if(in_array($channel_type, array('jd_cloud', 'jd_account'))){
|
||
$priceInfo = $getPriceList[$product_bn];
|
||
if($priceInfo){
|
||
$sale_price = ($priceInfo['sale_price'] ? $priceInfo['sale_price'] : 0);
|
||
|
||
$itemVal['price'] = ($priceInfo['price'] ? $priceInfo['price'] : $itemVal['price']); //货品单价
|
||
$itemVal['sales_amount'] = ($sale_price * $itemVal['nums']); //销售金额 = 销售单价 * 数量
|
||
}else{
|
||
$itemVal['price'] = 0; //货品单价
|
||
$itemVal['sales_amount'] = 0; //销售金额 = 销售单价 * 数量
|
||
|
||
$is_oms_price = false;
|
||
}
|
||
}
|
||
|
||
//getData
|
||
$mainSdf = $syncSaleLib->get_row($saleVal, $itemVal, $linenum, $shopInfo);
|
||
|
||
//merge
|
||
$mainSdf['sole_bn'] = $sole_bn; //唯一编码
|
||
$mainSdf['shop_bn'] = $saleVal['erp_store']; //OMS店铺编码
|
||
$mainSdf['channel_type'] = $channel_type; //来源渠道:oms、jd_edi、vip_edi
|
||
$mainSdf['sale_time'] = $sale_time;
|
||
$mainSdf['create_time'] = time();
|
||
|
||
//渠道类型
|
||
$mainSdf['channel_type'] = $channel_type;
|
||
|
||
//店铺商品ID
|
||
if($priceInfo['shop_sku_id']){
|
||
$mainSdf['sku_bn'] = $priceInfo['shop_sku_id'];
|
||
}
|
||
|
||
//读取固定折扣价格失败
|
||
if(!$is_oms_price){
|
||
//读取价格失败,标记异常
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '读取导入固定折扣价格失败';
|
||
}elseif($mainSdf['XF_ORGUPRICE'] <= 0){
|
||
//货品price销售价在OMS系统里未维护
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '读取OMS货品销售价为0元';
|
||
}else{
|
||
$mainSdf['is_abnormal'] = 'false';
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapSaleObj->insert($mainSdf);
|
||
if(!$insert_id){
|
||
$error_msg = '创建Sap销售记录失败';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>1, 'last_modified'=>time()), array('id'=>$id));
|
||
}
|
||
}
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 格式化赠品数据
|
||
*
|
||
* @param $saleItems
|
||
* @param $erpProductList
|
||
* @return void
|
||
*/
|
||
public function formatSaleItems($saleItems, $erpProductList)
|
||
{
|
||
//check
|
||
if(empty($saleItems) || empty($erpProductList)){
|
||
return $saleItems; //直接返回
|
||
}
|
||
|
||
//count
|
||
$itemCount = count($saleItems);
|
||
|
||
//items
|
||
$giftData = array();
|
||
$giftBns = array();
|
||
foreach ($saleItems as $giftKey => $giftItem)
|
||
{
|
||
$product_bn = $giftItem['bn'];
|
||
|
||
//check
|
||
if(!isset($erpProductList[$product_bn])){
|
||
continue;
|
||
}
|
||
|
||
//设置了TTPOS货号对照表
|
||
if($erpProductList[$product_bn][0]){
|
||
//通过[货号对照表]替换成设置的TTPOS货号
|
||
$giftItem['bn'] = $erpProductList[$product_bn][0];
|
||
|
||
$saleItems[$giftKey] = $giftItem;
|
||
}elseif($erpProductList[$product_bn][1] == 'true'){
|
||
//配置货号是赠品类型
|
||
if($itemCount <= 1){
|
||
//如果只有一行数据,并且是赠品,则不用传给ttpos,直接跳过
|
||
}else{
|
||
//有多行数据,并且是赠品,则需要把赠品的销售额加到第一个货品上
|
||
$giftBns[] = $product_bn;
|
||
|
||
$giftData['gift_amount'] += number_format($giftItem['sales_amount'], 2, '.', '');
|
||
}
|
||
|
||
//unset
|
||
unset($saleItems[$giftKey]);
|
||
}
|
||
|
||
//匹配的赠品数据
|
||
if($giftBns){
|
||
$giftData['gift_bn'] = implode(',', $giftBns);
|
||
}
|
||
|
||
//处理替换bn与礼品逻辑
|
||
$item_i = 0;
|
||
foreach ($saleItems as $k => $item)
|
||
{
|
||
//如果有赠品,且TTPOS无对应的bn,将其销售额加到第一个商品上
|
||
if($item_i == 0 && $giftData){
|
||
$saleItems[$k]['gift_bn'] = $giftData['gift_bn'];
|
||
$saleItems[$k]['gift_amount'] = $giftData['gift_amount'];
|
||
$saleItems[$k]['sales_amount'] += $giftData['gift_amount'];
|
||
}
|
||
|
||
$item_i++;
|
||
}
|
||
|
||
//价格无法均摊的,新加一行明细商品
|
||
//@todo:金额除不尽的拆成2行:一行为(n-1)*单价,另一行为总价-(n-1)*单价;
|
||
foreach ($saleItems as $k => $item)
|
||
{
|
||
if ($item['nums'] > 1) {
|
||
$sales_amount = $item['sales_amount'];
|
||
$nums = $item['nums'];
|
||
$unit_price = number_format($sales_amount / $nums, 2, '.', '');
|
||
|
||
//无法均摊的,新加一行明细商品
|
||
if ($unit_price * $nums != $sales_amount) {
|
||
$saleItems[$k]['nums'] = $nums - 1;
|
||
$saleItems[$k]['sales_amount'] = $unit_price * ($nums - 1);
|
||
|
||
//add
|
||
$saleItems[$k.'new'] = $item;
|
||
$saleItems[$k.'new']['nums'] = 1;
|
||
$saleItems[$k.'new']['sales_amount'] = $sales_amount - $saleItems[$k]['sales_amount'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $saleItems;
|
||
}
|
||
|
||
/**
|
||
* 生成Sap售后单记录
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function createSapAftersales($params)
|
||
{
|
||
$aftersalesObj = app::get('vfapi')->model('aftersales');
|
||
$sapAftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
$syncAftersaleLib = kernel::single('vfapi_tasks_syncaftersales');
|
||
|
||
//货号对照表
|
||
base_kvstore::instance('vfapi')->fetch('goodsmap.erp', $erpProductList);
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定售后查询条件!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $aftersalesObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的售后单!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//以shop店铺编码为下标,获取TTPOS列表
|
||
$shopTtposList = $funcLib->getShopTtposList();
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//是否读取固定折扣价
|
||
$is_read_price = false;
|
||
|
||
//getList
|
||
$tempList = $aftersalesObj->getList('*', $filter, 0, $page_size, 'id ASC');
|
||
if(empty($tempList)){
|
||
//没有查询到销售单数据
|
||
continue;
|
||
}
|
||
|
||
//format
|
||
$soldList = array();
|
||
$dataList = array();
|
||
$productBns = array();
|
||
foreach($tempList as $key => $val)
|
||
{
|
||
$id = $val['id'];
|
||
$aftersale_bn = $val['aftersale_bn'];
|
||
$ttpos_store = $val['ttpos_store'];
|
||
$shop_bn = $val['erp_store'];
|
||
|
||
//check
|
||
if(in_array($val['status'], array('1'))){
|
||
//单据已经处理,不允许重复操作
|
||
$error_msg = '售后单据已经处理,不允许重复操作!';
|
||
|
||
//只有一条记录时,直接返回报错信息
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if(empty($ttpos_store)){
|
||
$error_msg = '售后单没有ttpos_store编码!';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//shop
|
||
$shopInfo = $shopTtposList[$shop_bn];
|
||
if(empty($shopInfo)){
|
||
$error_msg = '售后单中ttpos_store编码没有配置店铺对照关系!';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//是否生成售后文件配置开关
|
||
if($shopInfo['is_aftersale_file'] == 'false'){
|
||
$error_msg = '是否生成售后文件:未启用';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//unserialize
|
||
$addonData = unserialize($val['addon']);
|
||
unset($val['addon']);
|
||
|
||
//check
|
||
if(empty($addonData['aftersale_items']) || !is_array($addonData['aftersale_items'])){
|
||
$error_msg = '没有售后明细!';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//收货人信息
|
||
$val['consignee'] = $addonData['consignee'];
|
||
$val['consignee_area'] = $addonData['consignee_area'];
|
||
$val['consignee_mobile'] = $addonData['consignee_mobile'];
|
||
$val['consignee_tel'] = $addonData['consignee_tel'];
|
||
|
||
//[渠道类型]是否京东云仓类型
|
||
if($addonData['shopinfo']['shop_type'] == '360buy' && $addonData['shopinfo']['business_type'] == 'jdlvmi'){
|
||
//京东云仓
|
||
$val['channel_type'] = 'jd_cloud';
|
||
|
||
//读取读取固定折扣价
|
||
$is_read_price = true;
|
||
}else{
|
||
$val['channel_type'] = 'oms'; //OMS普通销售单
|
||
}
|
||
|
||
//items
|
||
$aftersaleItems = $addonData['aftersale_items'];
|
||
|
||
//格式化赠品数据
|
||
$aftersaleItems = $this->formatAftersaleItems($aftersaleItems, $erpProductList);
|
||
if(empty($aftersaleItems)){
|
||
$error_msg = '格式化售后明细为空';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//sole_bn
|
||
foreach ($aftersaleItems as $item_id => $itemVal)
|
||
{
|
||
$product_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 货号 + item_id
|
||
$sole_bn = $aftersale_bn .'_'. $product_bn .'_'. $item_id;
|
||
$soldList[$sole_bn] = $sole_bn;
|
||
|
||
//bns
|
||
$productBns[$product_bn] = $product_bn;
|
||
}
|
||
|
||
//merge
|
||
$val['aftersale_items'] = $aftersaleItems;
|
||
|
||
//data
|
||
$dataList[$id] = $val;
|
||
}
|
||
|
||
//unset
|
||
unset($tempList);
|
||
|
||
//check
|
||
if(empty($dataList)){
|
||
//没有有效的数据
|
||
$error_msg = '没有有效的售后数据!';
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//已经存在的数据
|
||
$existData = array();
|
||
if($soldList){
|
||
$existData = $sapAftersaleObj->getList('id,sole_bn', array('sole_bn'=>$soldList));
|
||
if($existData){
|
||
$existData = $funcLib->_array_column($existData, null, 'sole_bn');
|
||
}
|
||
}
|
||
|
||
//固定折扣价格(获取导入的固定折扣价格)
|
||
$getPriceList = array();
|
||
if($is_read_price && $productBns){
|
||
$getPriceList = $this->getImportPriceList($productBns);
|
||
}
|
||
|
||
//list
|
||
foreach ($dataList as $saleId => $saleVal)
|
||
{
|
||
$id = $saleVal['id'];
|
||
$aftersale_bn = $saleVal['aftersale_bn'];
|
||
$aftersale_time = $saleVal['aftersale_time'];
|
||
//$ttpos_store = $saleVal['ttpos_store'];
|
||
$shop_bn = $saleVal['erp_store'];
|
||
|
||
//渠道类型
|
||
$channel_type = $saleVal['channel_type'];
|
||
|
||
//店铺配置信息
|
||
$shopInfo = $shopTtposList[$shop_bn];
|
||
|
||
//items
|
||
$linenum = 0;
|
||
foreach ($saleVal['aftersale_items'] as $item_id => $itemVal)
|
||
{
|
||
$product_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 货号 + item_id
|
||
$sole_bn = $aftersale_bn .'_'. $product_bn .'_'. $item_id;
|
||
|
||
//check
|
||
if($existData[$sole_bn]){
|
||
$error_msg = '已经生成过Sap售后记录!';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
$linenum++;
|
||
|
||
//format
|
||
$saleVal['operation'] = 'create_sap_sale'; //标记为创建Sap销售记录
|
||
$saleVal['aftersale_time'] = date('Y-m-d H:i:s', $aftersale_time);
|
||
$saleVal['aftersale_no'] = $aftersale_bn;
|
||
$saleVal['order_no'] = $saleVal['order_bn'];
|
||
|
||
//读取固定折扣价
|
||
$is_oms_price = true;
|
||
if(in_array($channel_type, array('jd_cloud', 'jd_account'))){
|
||
$priceInfo = $getPriceList[$product_bn];
|
||
if($priceInfo){
|
||
$sale_price = ($priceInfo['sale_price'] ? $priceInfo['sale_price'] : 0);
|
||
|
||
$itemVal['price'] = ($priceInfo['price'] ? $priceInfo['price'] : $itemVal['price']); //货品单价
|
||
$itemVal['sales_amount'] = ($sale_price * $itemVal['nums']); //销售金额 = 销售单价 * 数量
|
||
}else{
|
||
$itemVal['price'] = 0; //货品单价
|
||
$itemVal['sales_amount'] = 0; //销售金额 = 销售单价 * 数量
|
||
|
||
$is_oms_price = false;
|
||
}
|
||
}
|
||
|
||
//getData
|
||
$mainSdf = $syncAftersaleLib->get_row($saleVal, $itemVal, $linenum, $shopInfo);
|
||
|
||
//merge
|
||
$mainSdf['sole_bn'] = $sole_bn; //唯一编码
|
||
$mainSdf['shop_bn'] = $saleVal['erp_store']; //OMS店铺编码
|
||
$mainSdf['channel_type'] = $channel_type; //来源渠道:oms、jd_edi、vip_edi
|
||
$mainSdf['aftersale_time'] = $aftersale_time;
|
||
$mainSdf['create_time'] = time();
|
||
|
||
//渠道类型
|
||
$mainSdf['channel_type'] = $channel_type;
|
||
|
||
//店铺商品ID
|
||
if($priceInfo['shop_sku_id']){
|
||
$mainSdf['sku_bn'] = $priceInfo['shop_sku_id'];
|
||
}
|
||
|
||
//读取固定折扣价格失败
|
||
if(!$is_oms_price){
|
||
//读取价格失败,标记异常
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '读取固定折扣价格失败';
|
||
}elseif($mainSdf['XF_ORGUPRICE'] <= 0){
|
||
//货品price销售价在OMS系统里未维护
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '获取OMS货品销售价为0元';
|
||
}else{
|
||
$mainSdf['is_abnormal'] = 'false';
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapAftersaleObj->insert($mainSdf);
|
||
if(!$insert_id){
|
||
$error_msg = '创建Sap售后记录失败!';
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>2, 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//update
|
||
$aftersalesObj->update(array('status'=>1, 'last_modified'=>time()), array('id'=>$id));
|
||
}
|
||
}
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 格式化赠品数据
|
||
*
|
||
* @param $aftersaleItems
|
||
* @param $erpProductList
|
||
* @return void
|
||
*/
|
||
public function formatAftersaleItems($aftersaleItems, $erpProductList)
|
||
{
|
||
//check
|
||
if(empty($aftersaleItems) || empty($erpProductList)){
|
||
return $aftersaleItems; //直接返回
|
||
}
|
||
|
||
//count
|
||
$itemCount = count($aftersaleItems);
|
||
|
||
//items
|
||
$giftData = array();
|
||
$giftBns = array();
|
||
foreach ($aftersaleItems as $giftKey => $giftItem)
|
||
{
|
||
$product_bn = $giftItem['bn'];
|
||
|
||
//check
|
||
if(!isset($erpProductList[$product_bn])){
|
||
continue;
|
||
}
|
||
|
||
//设置了TTPOS货号对照表
|
||
if($erpProductList[$product_bn][0]){
|
||
//通过[货号对照表]替换成设置的TTPOS货号
|
||
$giftItem['bn'] = $erpProductList[$product_bn][0];
|
||
|
||
$aftersaleItems[$giftKey] = $giftItem;
|
||
}elseif($erpProductList[$product_bn][1] == 'true'){
|
||
//配置货号是赠品类型
|
||
if($itemCount <= 1){
|
||
//如果只有一行数据,并且是赠品,则不用传给ttpos,直接跳过
|
||
}else{
|
||
//有多行数据,并且是赠品,则需要把赠品的销售额加到第一个货品上
|
||
$giftBns[] = $product_bn;
|
||
|
||
$giftData['gift_amount'] += number_format($giftItem['sales_amount'], 2, '.', '');
|
||
}
|
||
|
||
//unset
|
||
unset($aftersaleItems[$giftKey]);
|
||
}
|
||
|
||
//匹配的赠品数据
|
||
if($giftBns){
|
||
$giftData['gift_bn'] = implode(',', $giftBns);
|
||
}
|
||
|
||
//处理替换bn与礼品逻辑
|
||
$item_i = 0;
|
||
foreach ($aftersaleItems as $k => $item)
|
||
{
|
||
//如果有赠品,且TTPOS无对应的bn,将其销售额加到第一个商品上
|
||
if($item_i == 0 && $giftData){
|
||
$aftersaleItems[$k]['gift_bn'] = $giftData['gift_bn'];
|
||
$aftersaleItems[$k]['gift_amount'] = $giftData['gift_amount'];
|
||
$aftersaleItems[$k]['sales_amount'] += $giftData['gift_amount'];
|
||
}
|
||
|
||
$item_i++;
|
||
}
|
||
|
||
//价格无法均摊的,新加一行明细商品
|
||
//@todo:金额除不尽的拆成2行:一行为(n-1)*单价,另一行为总价-(n-1)*单价;
|
||
foreach ($aftersaleItems as $k => $item)
|
||
{
|
||
if ($item['nums'] > 1) {
|
||
$sales_amount = $item['sales_amount'];
|
||
$nums = $item['nums'];
|
||
$unit_price = number_format($sales_amount / $nums, 2, '.', '');
|
||
|
||
//无法均摊的,新加一行明细商品
|
||
if ($unit_price * $nums != $sales_amount) {
|
||
$aftersaleItems[$k]['nums'] = $nums - 1;
|
||
$aftersaleItems[$k]['sales_amount'] = $unit_price * ($nums - 1);
|
||
|
||
//add
|
||
$aftersaleItems[$k.'new'] = $item;
|
||
$aftersaleItems[$k.'new']['nums'] = 1;
|
||
$aftersaleItems[$k.'new']['sales_amount'] = $sales_amount - $aftersaleItems[$k]['sales_amount'];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $aftersaleItems;
|
||
}
|
||
|
||
/**
|
||
* SAP销售单记录生成txt文件并上传FTP(每1000条记录生成一个txt文件)
|
||
*
|
||
* @param array $params
|
||
* @return boolean
|
||
*/
|
||
public function disposeSaleFile($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$fileObj = app::get('vfapi')->model('filelist');
|
||
|
||
$cronSaleLib = kernel::single('erpapi_autotask_timer_accountsales');
|
||
$filedata = new vfapi_ttposfile;
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//page_size文件生成记录行数
|
||
$page_size = $cronSaleLib::$file_page_size;
|
||
if(empty($page_size)){
|
||
$error_msg = '没有配置文件生成记录行数';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//TTpos店铺对照列表
|
||
base_kvstore::instance('vfapi')->fetch('storemap.ttpos', $ttposList);
|
||
if(empty($ttposList)){
|
||
$error_msg = '没有配置TTPOS店铺对照关系!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有传指定的filter条件';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//count
|
||
$countNum = $sapSaleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的SAP销售单记录!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//渠道类型为[京东云仓]时,按照[销售单号]排序生成txt文件
|
||
//@todo:京东结算单明细接口,订单有多个SKU时没有按订单排序给到中间件;
|
||
if($filter['channel_type'] == 'jd_cloud' || $params['operation'] == 'manual'){
|
||
$saleList = $sapSaleObj->getList('*', $filter, 0, $page_size, 'XF_DOCNO ASC, XF_SALESLINENUM ASC');
|
||
}else{
|
||
$saleList = $sapSaleObj->getList('*', $filter, 0, $page_size, 'id ASC');
|
||
}
|
||
|
||
//check
|
||
if(empty($saleList)){
|
||
//$error_msg = '没有可以处理的SAP销售单数据';
|
||
continue;
|
||
}
|
||
|
||
//获取异常订单列表
|
||
$abnormalOrders = array();
|
||
if(in_array($saleList[0]['channel_type'], array('jd_account', 'jd_cloud'))){
|
||
$orderBns = $funcLib->_array_column($saleList, 'XF_ORGDOCNO');
|
||
$orderBns = array_unique($orderBns);
|
||
|
||
//list
|
||
$abnormalOrders = $sapSaleObj->getList('id,XF_ORGDOCNO,XF_DOCNO', array('XF_ORGDOCNO'=>$orderBns, 'is_abnormal'=>'true'));
|
||
if($abnormalOrders){
|
||
$abnormalOrders = $funcLib->_array_column($abnormalOrders, null, 'XF_ORGDOCNO');
|
||
}
|
||
}
|
||
|
||
//ids
|
||
$ids = $funcLib->_array_column($saleList, 'id');
|
||
|
||
//setting
|
||
$ttpos_bn = $saleList[0]['XF_STORECODE']; //ttpos店铺编码
|
||
$channel_type = $saleList[0]['channel_type']; //渠道类型(jd_account:京东入仓,jd_cloud:京东云仓)
|
||
$business_type = $saleList[0]['business_type']; //冲红类型(duichong:对冲单据,jiesuan:结算单据)
|
||
$file_line_num = 0;
|
||
$todayDate = date('YmdHis', time());
|
||
|
||
//按照渠道和业务设置不同的页码格式
|
||
$file_page = $page;
|
||
if($channel_type == 'jd_account'){
|
||
if($business_type == 'duichong'){
|
||
$file_page = 110000 + $page;
|
||
}elseif($business_type == 'jiesuan'){
|
||
$file_page = 120000 + $page;
|
||
}else{
|
||
$file_page = 100000 + $page;
|
||
}
|
||
}elseif($channel_type == 'jd_cloud'){
|
||
if($business_type == 'duichong'){
|
||
$file_page = 210000 + $page;
|
||
}elseif($business_type == 'jiesuan'){
|
||
$file_page = 220000 + $page;
|
||
}else{
|
||
$file_page = 200000 + $page;
|
||
}
|
||
}
|
||
|
||
//获取文件名
|
||
$fileParams = array(
|
||
'ttpos_store' => $ttpos_bn, //TTpos编码
|
||
'bill_type' => 'SO', //单据业务类型(SO:销售单,SR:售后单)
|
||
'date' => $todayDate, //日期:年月日时分秒
|
||
'file_page' => $file_page, //文件页码
|
||
);
|
||
$file_name = vfapi_filename::get_sap_sales_filename($fileParams);
|
||
|
||
//file(文件名带目录路径)
|
||
$filedata->setfile($file_name);
|
||
$filedata->open();
|
||
|
||
//list
|
||
$saleIds = array();
|
||
foreach($saleList as $saleKey => $saleInfo)
|
||
{
|
||
$id = $saleInfo['id'];
|
||
$order_bn = $saleInfo['XF_ORGDOCNO'];
|
||
|
||
//check
|
||
if($saleInfo['status'] == 'succ'){
|
||
continue;
|
||
}
|
||
|
||
if($saleInfo['is_abnormal'] == 'true'){
|
||
$error_msg = '单据是异常状态,请检查商品固定折扣价格';
|
||
|
||
//update
|
||
$sapSaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//检查订单是否有异常的SKU商品行
|
||
//@todo:订单有多个SKU行,必须生成到同一个txt文件中,否则SAP财务会报错;
|
||
if($abnormalOrders && $abnormalOrders[$order_bn]){
|
||
continue;
|
||
}
|
||
|
||
//文件行数据
|
||
$line = $this->getSaleRowLine($saleInfo);
|
||
|
||
//写入内容
|
||
$filedata->writeline($line);
|
||
|
||
//line
|
||
$file_line_num++;
|
||
|
||
$saleIds[$id] = $id;
|
||
}
|
||
|
||
//check
|
||
if($file_line_num == 0){
|
||
if($abnormalOrders){
|
||
$error_msg = '订单有多个SKU,并且SKU部分异常';
|
||
}else{
|
||
$error_msg = '没有可生成文件的销售行数据,或者订单有部分SKU异常';
|
||
}
|
||
|
||
//update
|
||
$sapSaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$ids));
|
||
|
||
//close
|
||
$filedata->close();
|
||
|
||
continue;
|
||
}
|
||
|
||
//过滤掉文件公共路径
|
||
$file_name = substr($file_name, strlen(DATA_DIR));
|
||
|
||
//保存FTP文件信息
|
||
$fileSdf = array('file'=>$file_name, 'start_time'=>time(), 'end_time'=>time(), 'type'=>'sale', 'create_time'=>time());
|
||
$file_id = $fileObj->insert($fileSdf);
|
||
$filedata->close();
|
||
|
||
//check
|
||
if(!$file_id){
|
||
$error_msg = '保存文件名:'. $file_name .'信息失败';
|
||
|
||
//update
|
||
$sapSaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$saleIds));
|
||
|
||
continue;
|
||
}
|
||
|
||
//succ
|
||
$sapSaleObj->update(array('status'=>'succ', 'filename'=>$file_name, 'last_modified'=>time()), array('id'=>$saleIds));
|
||
}
|
||
|
||
//unset
|
||
unset($ttposList, $saleList, $ids, $saleIds);
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* SAP售后单记录生成xml文件并上传FTP(每1000条记录生成一个txt文件)
|
||
*
|
||
* @param array $params
|
||
* @return boolean
|
||
*/
|
||
public function disposeAftersaleFile($params)
|
||
{
|
||
$sapAftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
$fileObj = app::get('vfapi')->model('filelist');
|
||
|
||
$cronSaleLib = kernel::single('erpapi_autotask_timer_accountsales');
|
||
$filedata = new vfapi_ttposfile;
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//page_size文件生成记录行数
|
||
$page_size = $cronSaleLib::$file_page_size;
|
||
if(empty($page_size)){
|
||
$error_msg = '没有配置文件生成记录行数;';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//TTpos店铺对照列表
|
||
base_kvstore::instance('vfapi')->fetch('storemap.ttpos', $ttposList);
|
||
if(empty($ttposList)){
|
||
$error_msg = '请先配置TTPOS店铺对照关系;';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有传指定的filter条件;';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//count
|
||
$countNum = $sapAftersaleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的SAP销售单记录;';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//渠道类型为[京东云仓]时,按照[售后单号]排序生成txt文件
|
||
//@todo:京东结算单明细接口,订单有多个SKU时没有按订单排序给到中间件;
|
||
if($filter['channel_type'] == 'jd_cloud' || $params['operation'] == 'manual'){
|
||
$aftersaleList = $sapAftersaleObj->getList('*', $filter, 0, $page_size, 'XF_DOCNO ASC, XF_SALESLINENUM ASC');
|
||
}else{
|
||
$aftersaleList = $sapAftersaleObj->getList('*', $filter, 0, $page_size, 'id ASC');
|
||
}
|
||
|
||
//check
|
||
if(empty($aftersaleList)){
|
||
//$error_msg = '没有可以处理的SAP销售单数据';
|
||
continue;
|
||
}
|
||
|
||
//获取异常订单列表
|
||
$abnormalOrders = array();
|
||
if(in_array($aftersaleList[0]['channel_type'], array('jd_account', 'jd_cloud'))){
|
||
$orderBns = $funcLib->_array_column($aftersaleList, 'XF_ORGDOCNO');
|
||
$orderBns = array_unique($orderBns);
|
||
|
||
//list
|
||
$abnormalOrders = $sapAftersaleObj->getList('id,XF_ORGDOCNO,XF_DOCNO', array('XF_ORGDOCNO'=>$orderBns, 'is_abnormal'=>'true'));
|
||
if($abnormalOrders){
|
||
$abnormalOrders = $funcLib->_array_column($abnormalOrders, null, 'XF_ORGDOCNO');
|
||
}
|
||
}
|
||
|
||
//ids
|
||
$ids = $funcLib->_array_column($aftersaleList, 'id');
|
||
|
||
//setting
|
||
$ttpos_bn = $aftersaleList[0]['XF_STORECODE']; //ttpos店铺编码
|
||
$channel_type = $aftersaleList[0]['channel_type']; //渠道类型(jd_account:京东入仓,jd_cloud:京东云仓)
|
||
$business_type = $aftersaleList[0]['business_type']; //冲红类型(duichong:对冲单据,jiesuan:结算单据)
|
||
$file_line_num = 0;
|
||
$todayDate = date('YmdHis', time());
|
||
|
||
//按照渠道和业务设置不同的页码格式
|
||
$file_page = $page;
|
||
if($channel_type == 'jd_account'){
|
||
if($business_type == 'duichong'){
|
||
$file_page = 110000 + $page;
|
||
}elseif($business_type == 'jiesuan'){
|
||
$file_page = 120000 + $page;
|
||
}else{
|
||
$file_page = 100000 + $page;
|
||
}
|
||
}elseif($channel_type == 'jd_cloud'){
|
||
if($business_type == 'duichong'){
|
||
$file_page = 210000 + $page;
|
||
}elseif($business_type == 'jiesuan'){
|
||
$file_page = 220000 + $page;
|
||
}else{
|
||
$file_page = 200000 + $page;
|
||
}
|
||
}
|
||
|
||
//获取文件名
|
||
$fileParams = array(
|
||
'ttpos_store' => $ttpos_bn, //TTpos编码
|
||
'bill_type' => 'SR', //单据业务类型(SO:销售单,SR:售后单)
|
||
'date' => $todayDate, //日期:年月日时分秒
|
||
'file_page' => $file_page, //文件页码
|
||
);
|
||
$file_name = vfapi_filename::get_sap_sales_filename($fileParams);
|
||
|
||
//file(文件名带目录路径)
|
||
$filedata->setfile($file_name);
|
||
$filedata->open();
|
||
|
||
//list
|
||
$aftersaleIds = array();
|
||
foreach($aftersaleList as $aftersaleKey => $aftersaleInfo)
|
||
{
|
||
$id = $aftersaleInfo['id'];
|
||
$order_bn = $aftersaleInfo['XF_ORGDOCNO'];
|
||
|
||
//check
|
||
if($aftersaleInfo['status'] == 'succ'){
|
||
continue;
|
||
}
|
||
|
||
if($aftersaleInfo['is_abnormal'] == 'true'){
|
||
$error_msg = '单据是异常状态,请检查';
|
||
|
||
//update
|
||
$sapAftersaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//检查订单是否有异常的SKU商品行
|
||
//@todo:订单有多个SKU行,必须生成到同一个txt文件中,否则SAP财务会报错;
|
||
if($abnormalOrders && $abnormalOrders[$order_bn]){
|
||
continue;
|
||
}
|
||
|
||
//文件行数据
|
||
$line = $this->getAftersaleRowLine($aftersaleInfo);
|
||
|
||
//写入内容
|
||
$filedata->writeline($line);
|
||
|
||
//line
|
||
$file_line_num++;
|
||
|
||
$aftersaleIds[$id] = $id;
|
||
}
|
||
|
||
//check
|
||
if($file_line_num == 0){
|
||
$error_msg = '没有可生成文件的售后行数据';
|
||
|
||
//update
|
||
$sapAftersaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$ids));
|
||
|
||
//close
|
||
$filedata->close();
|
||
|
||
continue;
|
||
}
|
||
|
||
//过滤掉文件公共路径
|
||
$file_name = substr($file_name, strlen(DATA_DIR));
|
||
|
||
//保存FTP文件信息
|
||
$fileSdf = array('file'=>$file_name, 'start_time'=>time(), 'end_time'=>time(), 'type'=>'aftersale', 'create_time'=>time());
|
||
$file_id = $fileObj->insert($fileSdf);
|
||
$filedata->close();
|
||
|
||
//check
|
||
if(!$file_id){
|
||
$error_msg = '保存文件名:'. $file_name .'信息失败';
|
||
|
||
//update
|
||
$sapAftersaleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$ids));
|
||
|
||
continue;
|
||
}
|
||
|
||
//succ
|
||
$sapAftersaleObj->update(array('status'=>'succ', 'filename'=>$file_name, 'last_modified'=>time()), array('id'=>$aftersaleIds));
|
||
}
|
||
|
||
//unset
|
||
unset($ttposList, $aftersaleList, $ids, $aftersaleIds);
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 获取销售单行数据
|
||
*
|
||
* @param array $saleInfo
|
||
* @return string
|
||
*/
|
||
public function getSaleRowLine($saleInfo)
|
||
{
|
||
$mapper = array(
|
||
'XF_TXDATE' => $saleInfo['XF_TXDATE'], //取sale_time中的日期
|
||
'XF_TXTIME' => $saleInfo['XF_TXTIME'], //取sale_time中的时间
|
||
'XF_STORECODE' => $saleInfo['XF_STORECODE'],
|
||
'XF_TILLID' => $saleInfo['XF_TILLID'], //默认值00
|
||
'XF_DOCNO' => $saleInfo['XF_DOCNO'],
|
||
'XF_VIPCODE' => $saleInfo['XF_VIPCODE'], //默认空
|
||
'XF_CASHIERSTAFFCODE' => $saleInfo['XF_CASHIERSTAFFCODE'], //默认值ECOMM
|
||
'XF_SALESMAN' => $saleInfo['XF_SALESMAN'], //销售员工号 默认空
|
||
'XF_SALESLINENUM' => $saleInfo['XF_SALESLINENUM'], //货品行号,自动生成
|
||
'XF_PLU' => $saleInfo['XF_PLU'],
|
||
'XF_ITEMLOTNUM' => $saleInfo['XF_ITEMLOTNUM'], //货品条码 默认* //@todo
|
||
'XF_INVTTYPE' => $saleInfo['XF_INVTTYPE'], //默认值0
|
||
'XF_QTYSOLD' => $saleInfo['XF_QTYSOLD'], //销售数量
|
||
'XF_AMTSOLD' => $saleInfo['XF_AMTSOLD'], //销售金额,销售商品最终成交金 额
|
||
'XF_MARKDOWNAMT' => $saleInfo['XF_MARKDOWNAMT'], //货品级的优惠总额/数量
|
||
'XF_DISCOUNTAMT' => $saleInfo['XF_DISCOUNTAMT'], //折扣金额 默认0
|
||
'XF_VIPDISCOUNTLESS' => $saleInfo['XF_VIPDISCOUNTLESS'], //贵宾折扣金额 默认0
|
||
'XF_BONUS' => $saleInfo['XF_BONUS'], //贵宾积分 默认0
|
||
'XF_SELUPRICE' => $saleInfo['XF_SELUPRICE'], //货品现销售价
|
||
'XF_ORGUPRICE' => $saleInfo['XF_ORGUPRICE'], //原销售价
|
||
'XF_ORGDOCNO' => $saleInfo['XF_ORGDOCNO'], //原始订单号
|
||
'XF_PROMID' => $saleInfo['XF_PROMID'], //TTPOS 促销ID
|
||
'XF_TAOBAO_PROMID' => $saleInfo['XF_TAOBAO_PROMID'], //淘宝促销ID
|
||
'XF_REFUNDREASONCODE' => $saleInfo['XF_REFUNDREASONCODE'], //退货原因代码
|
||
'XF_REMARK' => $saleInfo['XF_REMARK'], //备注
|
||
'XF_TENDER' => $saleInfo['XF_TENDER'], //付款方式CA
|
||
'XF_DISTRICT' => $saleInfo['XF_DISTRICT'], //收货人地区(省、市、区)
|
||
'XF_TELEPHONE' => '', //收货人电话(固定为空,平台手机号是加密的)
|
||
//'XF_FULLNAME' => '', //收货人姓名(固定为空,平台手机号是加密的)
|
||
);
|
||
|
||
return $mapper;
|
||
}
|
||
|
||
/**
|
||
* 获取销售单行数据
|
||
*
|
||
* @param array $aftersaleInfo
|
||
* @return string
|
||
*/
|
||
public function getAftersaleRowLine($aftersaleInfo)
|
||
{
|
||
$mapper = array(
|
||
'XF_TXDATE' => $aftersaleInfo['XF_TXDATE'], //取sale_time中的日期
|
||
'XF_TXTIME' => $aftersaleInfo['XF_TXTIME'], //取sale_time中的时间
|
||
'XF_STORECODE' => $aftersaleInfo['XF_STORECODE'],
|
||
'XF_TILLID' => $aftersaleInfo['XF_TILLID'], //默认值00
|
||
'XF_DOCNO' => $aftersaleInfo['XF_DOCNO'],
|
||
'XF_VIPCODE' => $aftersaleInfo['XF_VIPCODE'], //默认空
|
||
'XF_CASHIERSTAFFCODE' => $aftersaleInfo['XF_CASHIERSTAFFCODE'], //默认值ECOMM
|
||
'XF_SALESMAN' => $aftersaleInfo['XF_SALESMAN'], //销售员工号 默认空
|
||
'XF_SALESLINENUM' => $aftersaleInfo['XF_SALESLINENUM'], //货品行号,自动生成
|
||
'XF_PLU' => $aftersaleInfo['XF_PLU'],
|
||
'XF_ITEMLOTNUM' => $aftersaleInfo['XF_ITEMLOTNUM'], //货品条码 默认* //@todo
|
||
'XF_INVTTYPE' => $aftersaleInfo['XF_INVTTYPE'], //默认值0
|
||
'XF_QTYSOLD' => $aftersaleInfo['XF_QTYSOLD'], //销售数量
|
||
'XF_AMTSOLD' => $aftersaleInfo['XF_AMTSOLD'], //销售金额,销售商品最终成交金 额
|
||
'XF_MARKDOWNAMT' => $aftersaleInfo['XF_MARKDOWNAMT'], //货品级的优惠总额/数量
|
||
'XF_DISCOUNTAMT' => $aftersaleInfo['XF_DISCOUNTAMT'], //折扣金额 默认0
|
||
'XF_VIPDISCOUNTLESS' => $aftersaleInfo['XF_VIPDISCOUNTLESS'], //贵宾折扣金额 默认0
|
||
'XF_BONUS' => $aftersaleInfo['XF_BONUS'], //贵宾积分 默认0
|
||
'XF_SELUPRICE' => $aftersaleInfo['XF_SELUPRICE'], //货品现销售价
|
||
'XF_ORGUPRICE' => $aftersaleInfo['XF_ORGUPRICE'], //原销售价
|
||
'XF_ORGDOCNO' => $aftersaleInfo['XF_ORGDOCNO'], //原始订单号
|
||
'XF_PROMID' => $aftersaleInfo['XF_PROMID'], //TTPOS 促销ID
|
||
'XF_TAOBAO_PROMID' => $aftersaleInfo['XF_TAOBAO_PROMID'], //淘宝促销ID
|
||
'XF_REFUNDREASONCODE' => $aftersaleInfo['XF_REFUNDREASONCODE'], //退货原因代码
|
||
'XF_REMARK' => $aftersaleInfo['XF_REMARK'], //备注
|
||
'XF_TENDER' => $aftersaleInfo['XF_TENDER'], //付款方式CA
|
||
'XF_DISTRICT' => $aftersaleInfo['XF_DISTRICT'], //收货人地区(省、市、区)
|
||
'XF_TELEPHONE' => '', //收货人电话(固定为空,平台手机号是加密的)
|
||
//'XF_FULLNAME' => '', //收货人姓名(固定为空,平台手机号是加密的)
|
||
);
|
||
|
||
return $mapper;
|
||
}
|
||
|
||
/**
|
||
* 生成Sap销售单记录
|
||
*
|
||
* @param array $params
|
||
* @param int $page
|
||
* @return array
|
||
*/
|
||
public function createJdSapSales($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$saleObj = app::get('vfapi')->model('account_sales');
|
||
$saleItemMdl = app::get('vfapi')->model('account_sales_items');
|
||
|
||
$syncSaleLib = kernel::single('vfapi_tasks_syncsales');
|
||
$accountLib = kernel::single('vfapi_account');
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//[config配置]京东账单店铺列表
|
||
$error_msg = '';
|
||
$jdShopList = $this->getJdCloudShop($error_msg);
|
||
if(empty($jdShopList)){
|
||
$error_msg = '获取云店失败:'. $error_msg;
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//setting
|
||
$channel_type = 'jd_account';
|
||
$fields = '*';
|
||
$item_fields = '*';
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定JD销售单查询条件';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $saleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的JD销售单数据';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//getList
|
||
$saleList = $saleObj->getList($fields, $filter, 0, $page_size, 'sale_id ASC');
|
||
if(empty($saleList)){
|
||
//没有查询到销售单数据
|
||
continue;
|
||
}
|
||
|
||
//ids
|
||
$saleIds = $funcLib->_array_column($saleList, 'sale_id');
|
||
|
||
//items
|
||
$itemList = array();
|
||
$tempList = $saleItemMdl->getList($item_fields, array('sale_id'=>$saleIds), 0, -1);
|
||
foreach((array)$tempList as $itemKey => $itemVal)
|
||
{
|
||
$sale_id = $itemVal['sale_id'];
|
||
$item_id = $itemVal['item_id'];
|
||
|
||
$itemList[$sale_id][$item_id] = $itemVal;
|
||
}
|
||
|
||
//list
|
||
foreach($saleList as $saleKey => $saleVal)
|
||
{
|
||
$sale_id = $saleVal['sale_id'];
|
||
|
||
//已经生成过SAP销售记录
|
||
if($saleVal['status'] == 'succ'){
|
||
unset($saleList[$saleKey]);
|
||
|
||
//$error_msg = '销售单号:'. $saleVal['sale_no'] .'已经生成过SAP销售记录;';
|
||
continue;
|
||
}
|
||
|
||
//check商品明细
|
||
if(empty($itemList[$sale_id])){
|
||
unset($saleList[$saleKey]);
|
||
|
||
$error_msg = 'JD销售单号:'. $saleVal['sale_no'] .'没有商品明细;';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
$saleList[$saleKey]['sales_items'] = $itemList[$sale_id];
|
||
}
|
||
|
||
//unset
|
||
unset($tempList, $itemList);
|
||
|
||
//check
|
||
if(empty($saleList)){
|
||
$error_msg = '没有有效的JD销售数据;';
|
||
|
||
continue;
|
||
}
|
||
|
||
//format
|
||
$soldList = array();
|
||
$dataList = array();
|
||
$skuBns = array();
|
||
foreach($saleList as $key => $val)
|
||
{
|
||
$sale_id = $val['sale_id'];
|
||
$sale_bn = $val['sale_no'];
|
||
$order_no = $val['order_no'];
|
||
$shop_bn = $val['shop_bn'];
|
||
|
||
//shopInfo(获取ttpos编码)
|
||
$shopInfo = $jdShopList[$shop_bn];
|
||
$val['ttpos_store'] = $shopInfo['ttpos_store'];
|
||
|
||
//check
|
||
if(in_array($val['status'], array('succ'))){
|
||
//单据已经处理,不允许重复操作
|
||
$error_msg = 'JD销售单据已经处理,不允许重复操作!';
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//ttpos_store编码
|
||
if(empty($val['ttpos_store'])){
|
||
$error_msg = 'JD销售单没有ttpos_store编码!';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//是否生成销售文件配置开关
|
||
if($shopInfo['is_sale_file'] == 'false'){
|
||
$error_msg = '是否生成销售文件:未启用';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
$saleItems = $val['sales_items'];
|
||
|
||
//格式化赠品数据
|
||
//$saleItems = $this->formatSaleItems($saleItems, $erpProductList);
|
||
|
||
//check
|
||
if(empty($saleItems)){
|
||
$error_msg = '格式化销售单明细为空!';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//sole_bn
|
||
foreach ($saleItems as $itemKey => $itemVal)
|
||
{
|
||
$sku_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 订单号 + sku_bn
|
||
$sole_bn = $sale_bn .'_'. $order_no .'_'. $sku_bn;
|
||
$soldList[$sole_bn] = $sole_bn;
|
||
|
||
//skus
|
||
$skuBns[$sku_bn] = $sku_bn;
|
||
}
|
||
|
||
//merge
|
||
$val['sales_items'] = $saleItems;
|
||
|
||
//data
|
||
$dataList[$sale_id] = $val;
|
||
}
|
||
|
||
//unset
|
||
unset($saleList, $saleItems);
|
||
|
||
//check
|
||
if(empty($dataList)){
|
||
//没有有效的数据
|
||
$error_msg = 'JD销售单没有有效的数据';
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//已经存在的数据
|
||
$existData = array();
|
||
if($soldList){
|
||
$existData = $sapSaleObj->getList('id,sole_bn', array('sole_bn'=>$soldList));
|
||
if($existData){
|
||
$existData = $funcLib->_array_column($existData, null, 'sole_bn');
|
||
}
|
||
}
|
||
|
||
//固定折扣价格(这里修改相关判断条件,查询获取导入的固定折扣价格)
|
||
$getPriceList = $this->getOmsSkuPriceList($skuBns, 'shop_sku_id');
|
||
|
||
//[京东云仓]按订单号获取已经存在的销售单
|
||
$orderBns = $funcLib->_array_column($dataList, 'order_no');
|
||
$sapSaleList = $sapSaleObj->getList('id,XF_ORGDOCNO,channel_type', array('channel_type'=>'jd_cloud', 'XF_ORGDOCNO'=>$orderBns));
|
||
if($sapSaleList){
|
||
$sapSaleList = $funcLib->_array_column($sapSaleList, null, 'XF_ORGDOCNO');
|
||
}
|
||
|
||
//list
|
||
foreach ($dataList as $saleId => $saleVal)
|
||
{
|
||
$sale_id = $saleVal['sale_id'];
|
||
$sale_bn = $saleVal['sale_no'];
|
||
$order_no = $saleVal['order_no'];
|
||
$shop_bn = $saleVal['shop_bn'];
|
||
|
||
//shopInfo
|
||
$shopInfo = $jdShopList[$shop_bn];
|
||
|
||
//format
|
||
$saleVal['operation'] = 'create_sap_sale'; //标记为创建Sap销售记录
|
||
|
||
//销售时间使用当前操作的时间戳
|
||
$sale_time = time();
|
||
$saleVal['sale_time'] = date('Y-m-d H:i:s', $sale_time);
|
||
|
||
//check京东云仓已经存在销售单
|
||
if($sapSaleList[$order_no]){
|
||
$error_msg = '京东云仓已经存在销售单,不允许重复生成';
|
||
|
||
//update
|
||
$saleObj->update(array('channel_type'=>'jd_cloud', 'status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
$linenum = 0;
|
||
foreach ($saleVal['sales_items'] as $itemKey => $itemVal)
|
||
{
|
||
$sku_bn = $itemVal['bn'];
|
||
|
||
//唯一性编码 = 销售单号 + 订单号 + sku_bn
|
||
$sole_bn = $sale_bn .'_'. $order_no .'_'. $sku_bn;
|
||
|
||
//check
|
||
if($existData[$sole_bn]){
|
||
$error_msg = 'JD销售单已经生成过Sap销售记录';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
$linenum++;
|
||
|
||
//固定折扣价格(获取导入的固定折扣价格)
|
||
$is_oms_price = true;
|
||
$priceInfo = $getPriceList[$sku_bn];
|
||
$sale_price = 0;
|
||
if($priceInfo){
|
||
$sale_price = ($priceInfo['sale_price'] ? $priceInfo['sale_price'] : 0);
|
||
|
||
$itemVal['bn'] = $priceInfo['product_bn']; //OMS货号
|
||
$itemVal['barcode'] = $priceInfo['barcode']; //条形码
|
||
$itemVal['price'] = $priceInfo['price']; //货品单价
|
||
$itemVal['sales_amount'] = ($sale_price * $itemVal['nums']); //销售金额 = 销售单价 * 数量
|
||
}else{
|
||
$itemVal['bn'] = ''; //OMS货号
|
||
$itemVal['barcode'] = ''; //条形码
|
||
$itemVal['price'] = 0; //货品单价
|
||
$itemVal['sales_amount'] = $sale_price; //销售金额 = 销售单价 * 数量
|
||
|
||
$is_oms_price = false;
|
||
}
|
||
|
||
//getData
|
||
$mainSdf = $syncSaleLib->get_row($saleVal, $itemVal, $linenum, $shopInfo);
|
||
|
||
//merge
|
||
$mainSdf['sole_bn'] = $sole_bn; //唯一编码
|
||
$mainSdf['sku_bn'] = $sku_bn; //店铺商品ID
|
||
$mainSdf['channel_type'] = $channel_type; //来源渠道:oms、jd_edi、vip_edi
|
||
$mainSdf['shop_bn'] = $shop_bn; //店铺编码
|
||
$mainSdf['sale_time'] = $sale_time;
|
||
$mainSdf['create_time'] = time();
|
||
|
||
//渠道类型
|
||
$mainSdf['channel_type'] = 'jd_account'; //京东入仓
|
||
|
||
//标记固定折扣价格
|
||
if(!$is_oms_price){
|
||
//读取价格失败,标记异常
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '获取导入固定折扣价格失败';
|
||
}elseif($mainSdf['XF_ORGUPRICE'] <= 0){
|
||
//货品price销售价在OMS系统里未维护
|
||
$mainSdf['is_abnormal'] = 'true';
|
||
$mainSdf['error_msg'] = '读取OMS货品销售价为0元';
|
||
}else{
|
||
$mainSdf['is_abnormal'] = 'false';
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapSaleObj->insert($mainSdf);
|
||
if(!$insert_id){
|
||
$error_msg = 'JD销售单创建Sap销售记录失败';
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
|
||
//return error
|
||
if($countNum == 1){
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
//update
|
||
$saleObj->update(array('status'=>'succ', 'last_modified'=>time()), array('sale_id'=>$sale_id));
|
||
}
|
||
}
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 获取SKU导入的固定折扣价格(SKU不限制所属渠道类型)
|
||
*
|
||
* @param $saleInfo
|
||
* @return void
|
||
*/
|
||
public function getImportPriceList($productBns, $channel_type='京东云仓')
|
||
{
|
||
$skuObj = app::get('vfapi')->model('shop_skus');
|
||
$priceObj = app::get('edi')->model('productprice');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//check
|
||
if(empty($productBns)){
|
||
return array();
|
||
}
|
||
|
||
//getList
|
||
//$filter = array('channel_type'=>$channel_type, 'product_bn'=>$productBns);
|
||
$filter = array('product_bn'=>$productBns);
|
||
$priceList = $priceObj->getList('id,product_bn,price', $filter);
|
||
if(empty($priceList)){
|
||
return array();
|
||
}
|
||
|
||
//获取OMS货品信息
|
||
$skuList = array();
|
||
$filter = array('product_bn'=>$productBns);
|
||
$tempList = $skuObj->getList('id,shop_sku_id,product_bn,barcode,price', $filter);
|
||
if($tempList){
|
||
$skuList = $funcLib->_array_column($tempList, null, 'product_bn');
|
||
}
|
||
|
||
//format
|
||
$dataList = array();
|
||
foreach($priceList as $key => $val)
|
||
{
|
||
$product_bn = $val['product_bn'];
|
||
$skuInfo = $skuList[$product_bn];
|
||
|
||
//sku_id
|
||
$dataList[$product_bn] = array(
|
||
'product_bn' => $product_bn,
|
||
'sale_price' => $val['price'], //单个商品的销售价
|
||
);
|
||
|
||
//OMS货品信息
|
||
if($skuInfo){
|
||
$dataList[$product_bn]['shop_sku_id'] = $skuInfo['shop_sku_id']; //店铺货品ID
|
||
$dataList[$product_bn]['barcode'] = $skuInfo['barcode']; //条形码
|
||
$dataList[$product_bn]['price'] = $skuInfo['price']; //货品单价
|
||
}
|
||
}
|
||
|
||
//unset
|
||
unset($productBns, $priceList, $tempList, $skuList);
|
||
|
||
return $dataList;
|
||
}
|
||
|
||
/**
|
||
* 批量获取OMS系统里的货品价格
|
||
*
|
||
* @param $saleInfo
|
||
* @param $mode 读取模式(shop_sku_id:按店铺货号ID,product_bn:按货品编码)
|
||
* @return void
|
||
*/
|
||
public function getOmsSkuPriceList($skuBns, $mode='shop_sku_id')
|
||
{
|
||
$skuObj = app::get('vfapi')->model('shop_skus');
|
||
$priceObj = app::get('edi')->model('productprice');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//check
|
||
if(empty($skuBns)){
|
||
return array();
|
||
}
|
||
|
||
//获取OMS货品信息
|
||
if($mode == 'shop_sku_id'){
|
||
$filter = array('shop_sku_id'=>$skuBns);
|
||
}else{
|
||
$filter = array('product_bn'=>$skuBns);
|
||
}
|
||
|
||
$skuList = $skuObj->getList('id,shop_sku_id,product_bn,barcode,price', $filter);
|
||
if(empty($skuList)){
|
||
return array();
|
||
}
|
||
|
||
//product_bn
|
||
$productBns = $funcLib->_array_column($skuList, 'product_bn');
|
||
|
||
//filter
|
||
$filter = array('product_bn'=>$productBns);
|
||
//$filter['channel_type'] = '';
|
||
|
||
//getList
|
||
$priceList = $priceObj->getList('id,channel_type,product_bn,price', $filter);
|
||
if(empty($priceList)){
|
||
return array();
|
||
}
|
||
|
||
$priceList = $funcLib->_array_column($priceList, null, 'product_bn');
|
||
|
||
//format
|
||
$dataList = array();
|
||
foreach($skuList as $key => $val)
|
||
{
|
||
$shop_sku_id = $val['shop_sku_id'];
|
||
$product_bn = $val['product_bn'];
|
||
$priceInfo = $priceList[$product_bn];
|
||
|
||
//check
|
||
if(empty($priceInfo)){
|
||
continue;
|
||
}
|
||
|
||
//[渠道类型]优先使用京东云仓类型
|
||
$channel_type = '';
|
||
if($priceInfo['channel_type'] == '京东入仓' && $dataList[$shop_sku_id]['channel_type'] != 'jd_cloud'){
|
||
$channel_type = 'jd_account';
|
||
}elseif($priceInfo['channel_type'] == '京东云仓'){
|
||
$channel_type = 'jd_cloud';
|
||
}elseif($priceInfo['channel_type'] == '唯品会'){
|
||
$channel_type = 'vip';
|
||
}
|
||
|
||
//sku_id
|
||
$dataList[$shop_sku_id] = array(
|
||
'shop_sku_id' => $shop_sku_id,
|
||
'product_bn' => $product_bn,
|
||
'barcode' => $val['barcode'],
|
||
'price' => $val['price'], //货品单价
|
||
'sale_price' => $priceInfo['price'], //单个商品的销售价
|
||
'channel_type' => $channel_type, //渠道类型
|
||
);
|
||
}
|
||
|
||
//unset
|
||
unset($skuIds, $skuList, $productBns, $priceList);
|
||
|
||
return $dataList;
|
||
}
|
||
|
||
/**
|
||
* 批量获取京东实销实结SKU货品属于渠道类型(京东入仓、京东云仓)
|
||
* @todo:当SKU既是:京东入仓,又是京东云仓,则优先SKU为:京东入仓;
|
||
*
|
||
* @param $saleInfo
|
||
* @param $mode 读取模式(shop_sku_id:按店铺货号ID,product_bn:按货品编码)
|
||
* @return void
|
||
*/
|
||
public function getSapProductTypes($skuBns, $mode='shop_sku_id')
|
||
{
|
||
$skuObj = app::get('vfapi')->model('shop_skus');
|
||
$priceObj = app::get('edi')->model('productprice');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//check
|
||
if(empty($skuBns)){
|
||
return array();
|
||
}
|
||
|
||
//获取OMS货品信息
|
||
if($mode == 'shop_sku_id'){
|
||
$filter = array('shop_sku_id'=>$skuBns);
|
||
}else{
|
||
$filter = array('product_bn'=>$skuBns);
|
||
}
|
||
|
||
$skuList = $skuObj->getList('id,shop_sku_id,product_bn,barcode,price', $filter);
|
||
if(empty($skuList)){
|
||
return array();
|
||
}
|
||
|
||
//product_bn
|
||
$productBns = $funcLib->_array_column($skuList, 'product_bn');
|
||
|
||
//filter
|
||
$filter = array('product_bn'=>$productBns);
|
||
//$filter['channel_type'] = '';
|
||
|
||
//getList
|
||
$priceList = $priceObj->getList('id,product_bn,price,channel_type', $filter);
|
||
if(empty($priceList)){
|
||
return array();
|
||
}
|
||
|
||
$priceList = $funcLib->_array_column($priceList, null, 'product_bn');
|
||
|
||
//format
|
||
$dataList = array();
|
||
foreach($skuList as $key => $val)
|
||
{
|
||
$shop_sku_id = $val['shop_sku_id'];
|
||
$product_bn = $val['product_bn'];
|
||
$priceInfo = $priceList[$product_bn];
|
||
|
||
//check
|
||
if(empty($priceInfo)){
|
||
continue;
|
||
}
|
||
|
||
//check渠道类型
|
||
// if(!in_array($priceInfo['channel_type'], array('京东入仓', '京东云仓'))){
|
||
// continue;
|
||
// }
|
||
|
||
//优先使用【京东入仓】类型
|
||
if($priceInfo['channel_type'] == '京东入仓'){
|
||
$val['channel_type'] = 'jd_account';
|
||
}elseif($priceInfo['channel_type'] == '京东云仓' && $dataList[$shop_sku_id]['channel_type'] != 'jd_account'){
|
||
$val['channel_type'] = 'jd_cloud';
|
||
}else{
|
||
//无效的类型,跳过
|
||
continue;
|
||
}
|
||
|
||
//sku_id
|
||
$dataList[$shop_sku_id] = array(
|
||
'channel_type' => $val['channel_type'], //渠道类型:京东入仓、京东云仓
|
||
'shop_sku_id' => $shop_sku_id,
|
||
'product_bn' => $product_bn,
|
||
'barcode' => $val['barcode'],
|
||
//'price' => $val['price'], //货品单价
|
||
//'sale_price' => $priceList[$product_bn]['price'], //单个商品的销售价
|
||
);
|
||
}
|
||
|
||
//unset
|
||
unset($skuIds, $skuList, $productBns, $priceList);
|
||
|
||
return $dataList;
|
||
}
|
||
|
||
/**
|
||
* [对冲]生成对冲销售单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function blushSapSales($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$sapAftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
|
||
//aftersaleInfo
|
||
$sole_bn = $params['sole_bn'];
|
||
$aftersaleInfo = $sapAftersaleObj->dump(array('sole_bn'=>$sole_bn), '*');
|
||
if(empty($aftersaleInfo)){
|
||
$error_msg = '没有找到售后单数据';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//对冲必须使用当前操作的时间
|
||
$dateline = time();
|
||
|
||
//对冲单据号
|
||
//@todo:SAP支持20个字符,但SAP自己会加上4位店铺编码,中间件只能16位字符;
|
||
$dc_bill_bn = $this->getArdcBillBn($aftersaleInfo['XF_DOCNO']);
|
||
|
||
//aftersale
|
||
//$aftersaleInfo['XF_DOCNO'] = 'ARDC'. $aftersaleInfo['XF_DOCNO'];
|
||
$aftersaleInfo['XF_DOCNO'] = $dc_bill_bn;
|
||
|
||
$aftersaleInfo['business_type'] = 'duichong'; //对冲单据
|
||
$aftersaleInfo['sale_time'] = $dateline;
|
||
$aftersaleInfo['XF_TXDATE'] = date('Ymd', $dateline);
|
||
$aftersaleInfo['XF_TXTIME'] = date('His', $dateline);
|
||
$aftersaleInfo['create_time'] = $dateline;
|
||
$aftersaleInfo['last_modified'] = $dateline;
|
||
|
||
//唯一性编码 = 对冲售后单号 + 货号
|
||
$sole_bn = $aftersaleInfo['XF_DOCNO'] .'_'. $aftersaleInfo['XF_PLU'];
|
||
$aftersaleInfo['sole_bn'] = $sole_bn;
|
||
|
||
//销售数量及销售总金额转换为正数
|
||
$aftersaleInfo['XF_QTYSOLD'] = abs($aftersaleInfo['XF_QTYSOLD']);
|
||
$aftersaleInfo['XF_AMTSOLD'] = abs($aftersaleInfo['XF_AMTSOLD']);
|
||
$aftersaleInfo['XF_MARKDOWNAMT'] = abs($aftersaleInfo['XF_MARKDOWNAMT']);
|
||
$aftersaleInfo['XF_DISCOUNTAMT'] = abs($aftersaleInfo['XF_DISCOUNTAMT']);
|
||
$aftersaleInfo['XF_SELUPRICE'] = abs($aftersaleInfo['XF_SELUPRICE']);
|
||
$aftersaleInfo['XF_ORGUPRICE'] = abs($aftersaleInfo['XF_ORGUPRICE']);
|
||
|
||
//unset
|
||
unset($aftersaleInfo['id'], $aftersaleInfo['status'], $aftersaleInfo['is_abnormal']);
|
||
unset($aftersaleInfo['filename'], $aftersaleInfo['error_msg'], $aftersaleInfo['aftersale_time']);
|
||
|
||
//查询是否已存在
|
||
$sapSaleInfo = $sapSaleObj->dump(array('sole_bn'=>$aftersaleInfo['sole_bn']), 'id');
|
||
if($sapSaleInfo){
|
||
$error_msg = '对冲销售单号'. $aftersaleInfo['XF_DOCNO'] .'已经存在';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapSaleObj->insert($aftersaleInfo);
|
||
if(!$insert_id){
|
||
$error_msg = '创建对冲Sap销售单失败!';
|
||
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* [对冲]生成对冲售后单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function blushSapAftersales($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$sapAftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
|
||
//saleInfo
|
||
$sole_bn = $params['sole_bn'];
|
||
$saleInfo = $sapSaleObj->dump(array('sole_bn'=>$sole_bn), '*');
|
||
if(empty($saleInfo)){
|
||
$error_msg = '没有找到售后单数据';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//对冲必须使用当前操作的时间
|
||
$dateline = time();
|
||
|
||
//对冲单据号
|
||
//@todo:SAP支持20个字符,但SAP自己会加上4位店铺编码,中间件只能16位字符;
|
||
$dc_bill_bn = $this->getArdcBillBn($saleInfo['XF_DOCNO']);
|
||
|
||
//sale
|
||
//$saleInfo['XF_DOCNO'] = 'ARDC'. $saleInfo['XF_DOCNO'];
|
||
$saleInfo['XF_DOCNO'] = $dc_bill_bn;
|
||
|
||
$saleInfo['business_type'] = 'duichong'; //对冲单据
|
||
$saleInfo['aftersale_time'] = $dateline;
|
||
$saleInfo['XF_TXDATE'] = date('Ymd', $dateline);
|
||
$saleInfo['XF_TXTIME'] = date('His', $dateline);
|
||
$saleInfo['create_time'] = $dateline;
|
||
$saleInfo['last_modified'] = $dateline;
|
||
|
||
//唯一性编码 = 对冲售后单号 + 货号
|
||
$sole_bn = $saleInfo['XF_DOCNO'] .'_'. $saleInfo['XF_PLU'];
|
||
$saleInfo['sole_bn'] = $sole_bn;
|
||
|
||
//销售数量及销售总金额转换为负数
|
||
if($saleInfo['XF_QTYSOLD'] > 0){
|
||
$saleInfo['XF_QTYSOLD'] = $saleInfo['XF_QTYSOLD'] * -1;
|
||
}
|
||
|
||
if($saleInfo['XF_AMTSOLD']){
|
||
$saleInfo['XF_AMTSOLD'] = $saleInfo['XF_AMTSOLD'] * -1;
|
||
}
|
||
|
||
//unset
|
||
unset($saleInfo['id'], $saleInfo['status'], $saleInfo['is_abnormal']);
|
||
unset($saleInfo['filename'], $saleInfo['error_msg'], $saleInfo['sale_time']);
|
||
|
||
//查询是否已存在
|
||
$sapAfterSaleInfo = $sapAftersaleObj->dump(array('sole_bn'=>$saleInfo['sole_bn']), 'id');
|
||
if($sapAfterSaleInfo){
|
||
$error_msg = '对冲售后单号'. $saleInfo['XF_DOCNO'] .'已经存在';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapAftersaleObj->insert($saleInfo);
|
||
if(!$insert_id){
|
||
$error_msg = '生成对冲SAP售后单失败!';
|
||
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* [结算]创建对冲结算的新销售单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function createJsSales($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
|
||
//saleInfo
|
||
$sole_bn = $params['sole_bn'];
|
||
$saleInfo = $sapSaleObj->dump(array('sole_bn'=>$sole_bn), '*');
|
||
if(empty($saleInfo)){
|
||
$error_msg = '没有找到销售单数据';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//结算必须使用当前操作的时间
|
||
$dateline = time();
|
||
|
||
//quantity
|
||
$quantity = intval($params['quantity']);
|
||
|
||
//格式化金额
|
||
$price = $saleInfo['XF_ORGUPRICE'];
|
||
$sale_price = ($params['bills_amount'] / $quantity); //单件销售价格 = 单据金额 / 数量
|
||
$sale_price = number_format($sale_price, 3, '.', '');
|
||
$pmt_price = $price - $sale_price;
|
||
|
||
//获取结算单号
|
||
//@todo:SAP支持20个字符,但SAP自己会加上4位店铺编码,中间件只能16位字符;
|
||
$js_bill_bn = $this->getArjsBillBn($saleInfo['XF_DOCNO']);
|
||
|
||
//sale
|
||
//$saleInfo['XF_DOCNO'] = 'ARJS'. $saleInfo['XF_DOCNO'];
|
||
$saleInfo['XF_DOCNO'] = $js_bill_bn;
|
||
|
||
$saleInfo['business_type'] = 'jiesuan'; //对冲单据
|
||
$saleInfo['sale_time'] = $dateline;
|
||
$saleInfo['create_time'] = $dateline;
|
||
$saleInfo['last_modified'] = $dateline;
|
||
|
||
//日期时间
|
||
$saleInfo['XF_TXDATE'] = date('Ymd', $dateline);
|
||
$saleInfo['XF_TXTIME'] = date('His', $dateline);
|
||
|
||
//数量
|
||
$saleInfo['XF_QTYSOLD'] = $quantity;
|
||
|
||
//金额
|
||
$saleInfo['XF_AMTSOLD'] = $params['bills_amount']; //销售总金额(必须使用单据金额)
|
||
$saleInfo['XF_MARKDOWNAMT'] = $pmt_price; //单件货品优惠 = 货品级的优惠总额 / 数量
|
||
$saleInfo['XF_DISCOUNTAMT'] = 0; //折扣金额 默认0
|
||
$saleInfo['XF_VIPDISCOUNTLESS'] = 0; //贵宾折扣金额 默认0
|
||
$saleInfo['XF_SELUPRICE'] = $sale_price; //销售单价 = 销售总金额 / 数量
|
||
$saleInfo['XF_ORGUPRICE'] = $price; //原销售价(单价)
|
||
|
||
//唯一性编码 = 对冲售后单号 + 货号
|
||
$sole_bn = $saleInfo['XF_DOCNO'] .'_'. $saleInfo['XF_PLU'];
|
||
$saleInfo['sole_bn'] = $sole_bn;
|
||
|
||
//unset
|
||
unset($saleInfo['id'], $saleInfo['status'], $saleInfo['is_abnormal']);
|
||
unset($saleInfo['filename'], $saleInfo['error_msg']);
|
||
|
||
//查询是否已存在
|
||
$sapSaleInfo = $sapSaleObj->dump(array('sole_bn'=>$saleInfo['sole_bn']), 'id');
|
||
if($sapSaleInfo){
|
||
$error_msg = '结算销售单号'. $saleInfo['XF_DOCNO'] .'已经存在';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapSaleObj->insert($saleInfo);
|
||
if(!$insert_id){
|
||
$error_msg = '创建对冲Sap销售单失败!';
|
||
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* [结算]创建对冲结算的新售后单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function createJsAftersales($params)
|
||
{
|
||
$sapAftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
|
||
//aftersaleInfo
|
||
$sole_bn = $params['sole_bn'];
|
||
$aftersaleInfo = $sapAftersaleObj->dump(array('sole_bn'=>$sole_bn), '*');
|
||
if(empty($aftersaleInfo)){
|
||
$error_msg = '没有找到售后单数据';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//对冲必须使用当前操作的时间
|
||
$dateline = time();
|
||
|
||
//quantity
|
||
$quantity = intval($params['quantity']);
|
||
|
||
//格式化金额
|
||
$price = $aftersaleInfo['XF_ORGUPRICE'];
|
||
$sale_price = ($params['bills_amount'] / $quantity); //单件销售价格 = 单据金额 / 数量
|
||
$sale_price = number_format($sale_price, 3, '.', '');
|
||
$pmt_price = $price - $sale_price;
|
||
|
||
//获取结算单号
|
||
//@todo:SAP支持20个字符,但SAP自己会加上4位店铺编码,中间件只能16位字符;
|
||
$js_bill_bn = $this->getArjsBillBn($aftersaleInfo['XF_DOCNO']);
|
||
|
||
//sale
|
||
//$aftersaleInfo['XF_DOCNO'] = 'ARJS'. $aftersaleInfo['XF_DOCNO'];
|
||
$aftersaleInfo['XF_DOCNO'] = $js_bill_bn;
|
||
|
||
$aftersaleInfo['business_type'] = 'jiesuan'; //对冲单据
|
||
$aftersaleInfo['aftersale_time'] = $dateline;
|
||
$aftersaleInfo['create_time'] = $dateline;
|
||
$aftersaleInfo['last_modified'] = $dateline;
|
||
|
||
//日期时间
|
||
$aftersaleInfo['XF_TXDATE'] = date('Ymd', $dateline);
|
||
$aftersaleInfo['XF_TXTIME'] = date('His', $dateline);
|
||
|
||
//数量(必须为负数)
|
||
if($quantity > 0){
|
||
$aftersaleInfo['XF_QTYSOLD'] = $quantity * -1;
|
||
}else{
|
||
$aftersaleInfo['XF_QTYSOLD'] = $quantity;
|
||
}
|
||
|
||
//退货总金额(必须为负数,并且必须使用单据金额)
|
||
if($params['bills_amount'] > 0){
|
||
$aftersaleInfo['XF_AMTSOLD'] = $params['bills_amount'] * -1;
|
||
}else{
|
||
$aftersaleInfo['XF_AMTSOLD'] = $params['bills_amount'];
|
||
}
|
||
|
||
//金额
|
||
$aftersaleInfo['XF_MARKDOWNAMT'] = $pmt_price; //单件货品 = 货品级的优惠总额 / 数量
|
||
$aftersaleInfo['XF_DISCOUNTAMT'] = 0; //折扣金额 默认0
|
||
$aftersaleInfo['XF_VIPDISCOUNTLESS'] = 0; //贵宾折扣金额 默认0
|
||
$aftersaleInfo['XF_SELUPRICE'] = $sale_price; //销售单价 = 销售总金额 / 数量
|
||
$aftersaleInfo['XF_ORGUPRICE'] = $price; //原销售价(单价)
|
||
|
||
//唯一性编码 = 对冲售后单号 + 货号
|
||
$sole_bn = $aftersaleInfo['XF_DOCNO'] .'_'. $aftersaleInfo['XF_PLU'];
|
||
$aftersaleInfo['sole_bn'] = $sole_bn;
|
||
|
||
//unset
|
||
unset($aftersaleInfo['id'], $aftersaleInfo['status'], $aftersaleInfo['is_abnormal']);
|
||
unset($aftersaleInfo['filename'], $aftersaleInfo['error_msg']);
|
||
|
||
//查询是否已存在
|
||
$sapAfterSaleInfo = $sapAftersaleObj->dump(array('sole_bn'=>$aftersaleInfo['sole_bn']), 'id');
|
||
if($sapAfterSaleInfo){
|
||
$error_msg = '结算售后单号'. $aftersaleInfo['XF_DOCNO'] .'已经存在';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapAftersaleObj->insert($aftersaleInfo);
|
||
if(!$insert_id){
|
||
$error_msg = '创建对冲Sap售后单失败!';
|
||
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 通过订单号获取SAP销售单渠道类型
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function getSaleChannelType($settOrderInfo)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
|
||
//order_bn
|
||
$order_bn = $settOrderInfo['orderNo'];
|
||
|
||
//check
|
||
if(!empty($settOrderInfo['channel_type']) && $settOrderInfo['channel_type'] != 'none'){
|
||
return $settOrderInfo['channel_type'];
|
||
}
|
||
|
||
//获取最新的销售单据的渠道类型
|
||
$sapSaleInfo = $sapSaleObj->getList('id,XF_ORGDOCNO,channel_type', array('XF_ORGDOCNO'=>$order_bn), 0, 1, 'sale_time DESC');
|
||
if($sapSaleInfo[0]['channel_type']){
|
||
return $sapSaleInfo[0]['channel_type'];
|
||
}
|
||
|
||
//采购类型(售后退货时没有值)
|
||
if($settOrderInfo['xniName'] == 'VMI共享库存单'){
|
||
return 'jd_cloud';
|
||
}
|
||
|
||
return 'none';
|
||
}
|
||
|
||
/**
|
||
* 修复异常Sap销售单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function repairSalesAbnormal($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$operLogObj = app::get('erpapi')->model('operation_log');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定查询条件!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $sapSaleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的SAP销售单记录!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
$fail_count = 0;
|
||
$succ_count = 0;
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
$offset = ($page - 1) * $page_size;
|
||
|
||
//list
|
||
$saleList = $sapSaleObj->getList('*', $filter, $offset, $page_size, 'id ASC');
|
||
if(empty($saleList)){
|
||
$fail_count++;
|
||
|
||
//$error_msg = '没有可以处理的SAP销售单数据';
|
||
continue;
|
||
}
|
||
|
||
//京东SKU导入的固定折扣
|
||
//@todo:目前导入的固定折扣的SKU不管属于哪个渠道,只要有导入价格就可以;
|
||
$skuBns = $funcLib->_array_column($saleList, 'sku_bn');
|
||
$skuList = $this->getOmsSkuPriceList($skuBns, 'shop_sku_id');
|
||
|
||
//通过货号获取导入的固定折扣金额
|
||
//@todo:SKU不限制属于哪个渠道,只要有导入价格就可以;
|
||
$productBns = $funcLib->_array_column($saleList, 'XF_PLU');
|
||
$getPriceList = $this->getImportPriceList($productBns);
|
||
|
||
//list
|
||
foreach ($saleList as $key => $val)
|
||
{
|
||
$id = $val['id'];
|
||
$sku_bn = $val['sku_bn'];
|
||
$product_bn = $val['XF_PLU'];
|
||
$nums = intval($val['XF_QTYSOLD']);
|
||
$order_bn = $val['XF_ORGDOCNO'];
|
||
|
||
//check
|
||
if($val['is_abnormal'] != 'true'){
|
||
$fail_count++;
|
||
continue;
|
||
}
|
||
|
||
if(empty($sku_bn) && empty($product_bn)){
|
||
$fail_count++;
|
||
|
||
//update
|
||
$error_msg = 'XF_PLU货号、sku_bn店铺商品ID都为空,请检查!';
|
||
$sapSaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//check
|
||
if(!in_array($val['channel_type'], array('jd_account', 'jd_cloud'))){
|
||
$fail_count++;
|
||
|
||
//update
|
||
$error_msg = '渠道类型为:'. $val['channel_type'] .'无法处理';
|
||
$sapSaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//检查货号、价格、数量、条形码、price单价、销售总金额是否存在&&并且原价大于0元
|
||
if($val['XF_PLU'] && $val['XF_ITEMLOTNUM'] && $val['XF_QTYSOLD'] && $val['XF_ORGUPRICE'] && $val['XF_AMTSOLD'] && $val['XF_ORGUPRICE'] > 0){
|
||
$succ_count++; //成功更新标识
|
||
|
||
//update
|
||
$error_msg = '货号、价格、数量、条形码都存在,去除异常标识;';
|
||
|
||
//更新为当前年月日+时分秒
|
||
$updateSdf = array(
|
||
'is_abnormal' => 'false',
|
||
'status' => 'none',
|
||
'XF_TXDATE' => date('Ymd', time()),
|
||
'XF_TXTIME' => date('His', time()),
|
||
'error_msg' => $error_msg,
|
||
'last_modified' => time(),
|
||
);
|
||
|
||
$sapSaleObj->update($updateSdf, array('id'=>$id));
|
||
|
||
//logs
|
||
$operLogObj->write_log('sap_sales@vfapi', $id, $error_msg);
|
||
|
||
continue;
|
||
}
|
||
|
||
//依据渠道类型获取货品信息
|
||
if($getPriceList[$product_bn]){
|
||
//bn
|
||
$skuInfo = $getPriceList[$product_bn];
|
||
}else{
|
||
//sku
|
||
$skuInfo = $skuList[$sku_bn];
|
||
}
|
||
|
||
//check
|
||
if(empty($skuInfo)){
|
||
$fail_count++;
|
||
$error_msg = 'product_bn:'. $product_bn .'获取固定折扣价、店铺货品映射信息失败!';
|
||
|
||
//update
|
||
$sapSaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
if(empty($skuInfo['product_bn']) || empty($skuInfo['barcode']) || empty($skuInfo['shop_sku_id'])){
|
||
$fail_count++;
|
||
$error_msg = 'product_bn:'. $product_bn .'获取店铺货品ID、条形码、固定折扣价失败,请检查!';
|
||
|
||
//update
|
||
$sapSaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//金额
|
||
$sales_amount = $skuInfo['sale_price'] * $nums;
|
||
$pmt_price = $skuInfo['price'] - $skuInfo['sale_price'];
|
||
|
||
//save
|
||
$saveData = array(
|
||
'XF_PLU' => $skuInfo['product_bn'], //货号
|
||
'XF_ITEMLOTNUM' => $skuInfo['barcode'], //条形码
|
||
'XF_ORGUPRICE' => $skuInfo['price'], //Price原价
|
||
'XF_SELUPRICE' => $skuInfo['sale_price'], //实际销售单价(单件)
|
||
'XF_AMTSOLD' => $sales_amount, //销售总金额
|
||
'XF_MARKDOWNAMT' => $pmt_price, //优惠金额(单件)
|
||
'is_abnormal' => 'false',
|
||
'error_msg' => '',
|
||
'last_modified' => time(),
|
||
);
|
||
|
||
//再次检查数据
|
||
if(empty($nums) || empty($saveData['XF_PLU']) || empty($saveData['XF_ITEMLOTNUM']) || empty($saveData['XF_ORGUPRICE']) || empty($saveData['XF_SELUPRICE'])){
|
||
//设置为异常状态
|
||
$saveData['is_abnormal'] = 'true';
|
||
$saveData['error_msg'] = '再次检查数据还是异常!';
|
||
}elseif($saveData['XF_ORGUPRICE'] <= 0){
|
||
//货品price销售价在OMS系统里未维护
|
||
$saveData['is_abnormal'] = 'true';
|
||
$saveData['error_msg'] = '再次检查异常:price货品价格未维护,不能为0元!';
|
||
}
|
||
|
||
//异常已修复,更新状态为默认(失败状态task队列任务不会自动生成文件)
|
||
$date_msg = '';
|
||
if($saveData['is_abnormal']=='false' && $val['status']=='fail'){
|
||
$saveData['status'] = 'none';
|
||
|
||
//更新为当前年月日+时分秒(客户微信群里确认这样修改,财务月日期是按照美账时间决定的)
|
||
$saveData['XF_TXDATE'] = date('Ymd', time());
|
||
$saveData['XF_TXTIME'] = date('His', time());
|
||
|
||
$date_msg = '(更新销售日期为:'. date('Y-m-d H:i:s', time()) .')';
|
||
}
|
||
|
||
//update
|
||
$sapSaleObj->update($saveData, array('id'=>$id));
|
||
|
||
//更新失败订单号为:当前年月日+时分秒
|
||
if($saveData['is_abnormal']=='false' && $order_bn){
|
||
//更新为当前年月日+时分秒
|
||
$updateSdf = array(
|
||
'status' => 'none',
|
||
'XF_TXDATE' => date('Ymd', time()),
|
||
'XF_TXTIME' => date('His', time()),
|
||
);
|
||
$sapSaleObj->update($updateSdf, array('XF_ORGDOCNO'=>$order_bn, 'status'=>array('fail')));
|
||
}
|
||
|
||
//logs
|
||
$flag_msg = ($saveData['is_abnormal'] == 'true' ? '失败:'. $saveData['error_msg'] : '成功');
|
||
$operLogObj->write_log('sap_sales@vfapi', $id, '处理销售单异常'. $flag_msg . $date_msg);
|
||
|
||
$succ_count++;
|
||
}
|
||
}
|
||
|
||
$data = array('fail_count'=>$fail_count, 'succ_count'=>$succ_count);
|
||
|
||
return $this->succ('执行成功', $data);
|
||
}
|
||
|
||
/**
|
||
* 修复异常Sap售后单
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function repairAftersalesAbnormal($params)
|
||
{
|
||
$sapSaleObj = app::get('vfapi')->model('sap_sales');
|
||
$aftersaleObj = app::get('vfapi')->model('sap_aftersales');
|
||
$operLogObj = app::get('erpapi')->model('operation_log');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定查询条件!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $aftersaleObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的SAP销售单记录!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
$fail_count = 0;
|
||
$succ_count = 0;
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
$offset = ($page - 1) * $page_size;
|
||
|
||
//list
|
||
$aftersaleList = $aftersaleObj->getList('*', $filter, $offset, $page_size, 'id ASC');
|
||
if(empty($aftersaleList)){
|
||
$fail_count++;
|
||
|
||
//$error_msg = '没有可以处理的SAP销售单数据';
|
||
continue;
|
||
}
|
||
|
||
//skus
|
||
$skuBns = $funcLib->_array_column($aftersaleList, 'sku_bn');
|
||
// if(empty($skuBns[0])){
|
||
// //通过product_bn货号反查找
|
||
// $productBns = $funcLib->_array_column($aftersaleList, 'XF_PLU');
|
||
// $skuList = $this->getImportPriceList($productBns, array('京东入仓', '京东云仓'));
|
||
// if($skuList){
|
||
// $skuBns = $funcLib->_array_column($skuList, 'shop_sku_id');
|
||
// }
|
||
// }
|
||
|
||
//渠道类型
|
||
//@todo:目前导入的固定折扣的SKU只能属于一个渠道;
|
||
$skuList = $this->getOmsSkuPriceList($skuBns, 'shop_sku_id');
|
||
|
||
//list
|
||
foreach ($aftersaleList as $key => $val)
|
||
{
|
||
$id = $val['id'];
|
||
$order_bn = $val['XF_ORGDOCNO'];
|
||
$sku_bn = $val['sku_bn'];
|
||
$nums = intval($val['XF_QTYSOLD']);
|
||
|
||
//check
|
||
if($val['is_abnormal'] != 'true'){
|
||
$fail_count++;
|
||
|
||
continue;
|
||
}
|
||
|
||
if(empty($sku_bn) && empty($val['XF_PLU'])){
|
||
$fail_count++;
|
||
|
||
//update
|
||
$error_msg = 'XF_PLU货号、sku_bn店铺商品ID都为空,请检查;';
|
||
$aftersaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//[兼容]获取销售单渠道类型
|
||
if(empty($val['channel_type']) || $val['channel_type']=='none'){
|
||
$sapSaleInfo = $sapSaleObj->dump(array('XF_ORGDOCNO'=>$order_bn), 'id,XF_ORGDOCNO,channel_type');
|
||
if($sapSaleInfo){
|
||
$val['channel_type'] = $sapSaleInfo['channel_type'];
|
||
|
||
//update
|
||
$aftersaleObj->update(array('channel_type'=>$val['channel_type'], 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
//logs
|
||
$operLogObj->write_log('sap_aftersales@vfapi', $id, '更新为销售单上的渠道类型:'. $val['channel_type']);
|
||
}
|
||
}
|
||
|
||
//check
|
||
if(!in_array($val['channel_type'], array('jd_account', 'jd_cloud', 'vip'))){
|
||
$fail_count++;
|
||
|
||
//update
|
||
$error_msg = '渠道类型为:'. $val['channel_type'] .'无法处理;';
|
||
$aftersaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//检查货号、价格、数量、条形码、price单价、销售总金额是否存在
|
||
if($val['XF_PLU'] && $val['XF_ITEMLOTNUM'] && $val['XF_QTYSOLD'] && $val['XF_ORGUPRICE'] && $val['XF_AMTSOLD'] && $val['XF_ORGUPRICE'] > 0){
|
||
$succ_count++; //成功更新标识
|
||
|
||
//update
|
||
$error_msg = '货号、价格、数量、条形码都存在,去除异常标识;';
|
||
|
||
//更新为当前年月日+时分秒
|
||
$updateSdf = array(
|
||
'is_abnormal' => 'false',
|
||
'status' => 'none',
|
||
'XF_TXDATE' => date('Ymd', time()),
|
||
'XF_TXTIME' => date('His', time()),
|
||
'error_msg' => $error_msg,
|
||
'last_modified' => time(),
|
||
);
|
||
|
||
$aftersaleObj->update($updateSdf, array('id'=>$id));
|
||
|
||
//logs
|
||
$operLogObj->write_log('sap_aftersales@vfapi', $id, $error_msg);
|
||
|
||
continue;
|
||
}
|
||
|
||
//sku
|
||
$skuInfo = $skuList[$sku_bn];
|
||
if(empty($skuInfo)){
|
||
$fail_count++;
|
||
$error_msg = 'sku_bn:'. $sku_bn .'获取SKU价格信息失败;';
|
||
|
||
//update
|
||
$aftersaleObj->update(array('error_msg'=>$error_msg, 'last_modified'=>time()), array('id'=>$id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//金额
|
||
$sales_amount = $skuInfo['sale_price'] * $nums;
|
||
$pmt_price = $skuInfo['price'] - $skuInfo['sale_price'];
|
||
|
||
//save
|
||
$saveData = array(
|
||
'XF_PLU' => $skuInfo['product_bn'], //货号
|
||
'XF_ITEMLOTNUM' => $skuInfo['barcode'], //条形码
|
||
'XF_ORGUPRICE' => $skuInfo['price'], //Price原价
|
||
'XF_SELUPRICE' => $skuInfo['sale_price'], //实际销售单价(单件)
|
||
'XF_AMTSOLD' => $sales_amount, //销售总金额
|
||
'XF_MARKDOWNAMT' => $pmt_price, //优惠金额(单件)
|
||
'is_abnormal' => 'false',
|
||
'error_msg' => '',
|
||
'last_modified' => time(),
|
||
);
|
||
|
||
//再次检查数据
|
||
if(empty($nums) || empty($saveData['XF_PLU']) || empty($saveData['XF_ITEMLOTNUM']) || empty($saveData['XF_ORGUPRICE']) || empty($saveData['XF_SELUPRICE'])){
|
||
//设置为异常状态
|
||
$saveData['is_abnormal'] = 'true';
|
||
$saveData['error_msg'] = '再次检查数据还是异常;';
|
||
}elseif($saveData['XF_ORGUPRICE'] <= 0){
|
||
//货品price销售价在OMS系统里未维护
|
||
$saveData['is_abnormal'] = 'true';
|
||
$saveData['error_msg'] = '再次异常:price货品价格未维护,不能为0元;';
|
||
}
|
||
|
||
//异常已修复,更新状态为默认(失败状态task队列任务不会自动生成文件)
|
||
$date_msg = '';
|
||
if($saveData['is_abnormal']=='false' && $val['status']=='fail'){
|
||
$saveData['status'] = 'none';
|
||
|
||
//更新为当前年月日+时分秒(客户微信群里确认这样修改,财务月日期是按照美账时间决定的)
|
||
$saveData['XF_TXDATE'] = date('Ymd', time());
|
||
$saveData['XF_TXTIME'] = date('His', time());
|
||
|
||
$date_msg = '(更新销售日期为:'. date('Y-m-d H:i:s', time()) .')';
|
||
}
|
||
|
||
//update
|
||
$aftersaleObj->update($saveData, array('id'=>$id));
|
||
|
||
//更新失败订单号为:当前年月日+时分秒
|
||
if($saveData['is_abnormal']=='false' && $order_bn){
|
||
//更新为当前年月日+时分秒
|
||
$updateSdf = array(
|
||
'status' => 'none',
|
||
'XF_TXDATE' => date('Ymd', time()),
|
||
'XF_TXTIME' => date('His', time()),
|
||
);
|
||
$sapSaleObj->update($updateSdf, array('XF_ORGDOCNO'=>$order_bn, 'status'=>array('fail')));
|
||
}
|
||
|
||
//logs
|
||
$flag_msg = ($saveData['is_abnormal'] == 'true' ? '失败:'. $saveData['error_msg'] : '成功');
|
||
$operLogObj->write_log('sap_aftersales@vfapi', $id, '处理售后单异常'.$flag_msg . $date_msg);
|
||
|
||
$succ_count++;
|
||
}
|
||
}
|
||
|
||
$data = array('fail_count'=>$fail_count, 'succ_count'=>$succ_count);
|
||
|
||
return $this->succ('执行成功', $data);
|
||
}
|
||
|
||
/**
|
||
* 出入库明细生成txt文件并上传FTP
|
||
* @todo:每500条记录生成一个txt文件;
|
||
*
|
||
* @param array $params
|
||
* @return boolean
|
||
*/
|
||
public function disposeIostockFile($params)
|
||
{
|
||
$sapIostockObj = app::get('vfapi')->model('sap_iostock');
|
||
$sapIostockItemObj = app::get('vfapi')->model('sap_iostock_items');
|
||
|
||
$fileObj = app::get('vfapi')->model('filelist');
|
||
|
||
$cronIostockLib = kernel::single('erpapi_autotask_timer_iostocklist');
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//page_size文件生成记录行数
|
||
$page_size = $cronIostockLib::$xml_page_size;
|
||
if(empty($page_size)){
|
||
$error_msg = '没有配置XML文件生成记录行数';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有传指定的filter条件';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//count
|
||
$countNum = $sapIostockObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的SAP出入库记录!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//货号对照表
|
||
base_kvstore::instance('vfapi')->fetch('goodsmap.erp', $erpProductList);
|
||
|
||
//出入库类型列表
|
||
$typeList = $this->getIostckTypeList();
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//filter条件为未读状态,所以每次读取都得从0开始
|
||
$iostockList = $sapIostockObj->getList('*', $filter, 0, $page_size);
|
||
if(empty($iostockList)){
|
||
//$error_msg = '没有可以处理的出入库明细';
|
||
continue;
|
||
}
|
||
|
||
//ids
|
||
$sapIds = $funcLib->_array_column($iostockList, 'sap_id');
|
||
$iostock_type = $iostockList[0]['iostock_type'];
|
||
$type_id = $iostockList[0]['type_id'];
|
||
|
||
//出入库类型信息
|
||
$typeRow = $typeList[$type_id];
|
||
$group_id = intval($typeRow['group']);
|
||
|
||
//按照出入库类型,生成不同的页码格式
|
||
if($iostock_type == 'in_stock'){
|
||
$file_page = 1000 + $page; //入库
|
||
}else{
|
||
$file_page = 5000 + $page; //出库
|
||
}
|
||
|
||
//出入库种类,用于区别文件名
|
||
if($group_id > 0){
|
||
$file_page = $file_page + $group_id * 100;
|
||
}
|
||
|
||
//items
|
||
$tempItems = $sapIostockItemObj->getList('*', array('sap_id'=>$sapIds));
|
||
if(empty($tempItems)){
|
||
$error_msg = '没有出入库明细,请检查';
|
||
|
||
//update
|
||
$sapIostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sap_id'=>$sapIds));
|
||
|
||
continue;
|
||
}
|
||
|
||
//format
|
||
$itemList = array();
|
||
foreach ($tempItems as $itemKey => $itemVal)
|
||
{
|
||
$sap_id = $itemVal['sap_id'];
|
||
$product_bn = $itemVal['product_bn'];
|
||
|
||
//check过滤出入库数量为0的明细
|
||
if(empty($itemVal['nums'])){
|
||
continue;
|
||
}
|
||
|
||
//过滤赠品
|
||
if($erpProductList[$product_bn][1] == 'true'){
|
||
continue;
|
||
}
|
||
|
||
$itemList[$sap_id][] = $itemVal;
|
||
}
|
||
|
||
//XML公共头标签
|
||
$doc = new DOMDocument('1.0', 'utf-8');
|
||
$doc->formatOutput = true; //格式化输出xml格式
|
||
|
||
//ns0根标签
|
||
$xmlRoot = $doc->createElement('ns0:MT_ShipmentDetails_I0552_OMS');
|
||
|
||
//ns0根标签的属性值
|
||
$xmlns = $doc->createAttribute('xmlns:ns0');
|
||
$xmlnsVal = $doc->createTextNode("urn:KATALYST.com:PTP:ShipmentDetails");
|
||
$xmlns->appendChild($xmlnsVal);
|
||
$xmlRoot->appendChild($xmlns);
|
||
|
||
//Shipment标签
|
||
$Shipment = $doc->createElement('Shipment');
|
||
|
||
//first
|
||
$masterFirstInfo = current($iostockList);
|
||
|
||
//XML文件中REF_DOC_NO字段值
|
||
$fileParams = array(
|
||
'file_page' => $file_page, //文件页码
|
||
);
|
||
$masterFirstInfo['ref_doc_no'] = vfapi_filename::get_iostock_ref_doc_no($fileParams);
|
||
|
||
//格式化数据(XML文件中公共头部节点)
|
||
$sdf = $this->getFormatShipmentHead($masterFirstInfo);
|
||
foreach ($sdf as $keyCode => $keyVal)
|
||
{
|
||
$itemType = $doc->createElement($keyCode);
|
||
$itemText = $doc->createTextNode($keyVal);
|
||
|
||
$itemType->appendChild($itemText);
|
||
$Shipment->appendChild($itemType);
|
||
}
|
||
|
||
//list
|
||
$file_line_num = 0;
|
||
foreach ($iostockList as $marterKey => $masterInfo)
|
||
{
|
||
$sap_id = $masterInfo['sap_id'];
|
||
|
||
//check
|
||
if(in_array($masterInfo['status'], array('succ'))){
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
$iostockItems = $itemList[$sap_id];
|
||
if(empty($iostockItems)){
|
||
$error_msg = '出入库明细为空,请检查';
|
||
|
||
//update
|
||
$sapIostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sap_id'=>$sap_id));
|
||
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
foreach ($iostockItems as $itemKey => $itemInfo)
|
||
{
|
||
//ShipmentDetails标签
|
||
$shipDetail = $doc->createElement('ShipmentDetails');
|
||
$sdf = $this->getFormatShipmentDetails($masterInfo, $itemInfo);
|
||
foreach ($sdf as $keyCode => $keyVal)
|
||
{
|
||
$itemType = $doc->createElement($keyCode);
|
||
$itemText = $doc->createTextNode($keyVal);
|
||
|
||
$itemType->appendChild($itemText);
|
||
$shipDetail->appendChild($itemType);
|
||
}
|
||
|
||
$Shipment->appendChild($shipDetail);
|
||
}
|
||
|
||
$file_line_num++;
|
||
}
|
||
|
||
//将标签内容赋给root标签
|
||
$xmlRoot->appendChild($Shipment);
|
||
|
||
//创建ns0根标签
|
||
$doc->appendChild($xmlRoot);
|
||
|
||
//生成XML内容
|
||
$content = $doc->saveXML();
|
||
|
||
//生成XML文件名
|
||
$fileParams = array(
|
||
'file_page' => $file_page, //文件页码
|
||
);
|
||
$file_name = vfapi_filename::get_sap_iostocklist_filename($fileParams);
|
||
|
||
//file_name是完整的路径及文件名
|
||
$local_address = $file_name;
|
||
|
||
//本地临时文件夹写文件
|
||
$handle = fopen($local_address, "a");
|
||
fwrite($handle, $content);
|
||
fclose($handle);
|
||
|
||
//check
|
||
if($file_line_num == 0){
|
||
$error_msg = '没有可生成文件的行数据';
|
||
|
||
//update
|
||
$sapIostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sap_id'=>$sapIds));
|
||
|
||
continue;
|
||
}
|
||
|
||
//过滤掉文件公共路径
|
||
$file_name = substr($file_name, strlen(DATA_DIR));
|
||
|
||
//保存FTP文件信息
|
||
$fileSdf = array('file'=>$file_name, 'start_time'=>time(), 'end_time'=>time(), 'type'=>'iostocklist', 'create_time'=>time());
|
||
$file_id = $fileObj->insert($fileSdf);
|
||
if(!$file_id){
|
||
$error_msg = '保存文件名:'. $file_name .'信息失败';
|
||
|
||
//update
|
||
$sapIostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('sap_id'=>$sapIds));
|
||
|
||
continue;
|
||
}
|
||
|
||
//succ
|
||
$sapIostockObj->update(array('status'=>'succ', 'filename'=>$file_name, 'last_modified'=>time()), array('sap_id'=>$sapIds));
|
||
}
|
||
|
||
//unset
|
||
unset($iostockList, $sapIds, $itemList);
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 格式化Shipment节点字段
|
||
*
|
||
* @param $masterInfo
|
||
* @return array
|
||
*/
|
||
public function getFormatShipment($masterInfo)
|
||
{
|
||
$mapper = array(
|
||
'PSTNG_DATE' => 'YYYYMMDD', //生成XML文件时间:年月日
|
||
'DOC_DATE' => 'YYYYMMDD', //OMS创建出入库明细时间:年月日
|
||
'REF_DOC_NO' => 'iostock_bn', //SALES:销售单,SALES RETURN:退货单;
|
||
'HEADER_TXT' => 'OMS reference', //原始单据号,例如:发货单号、退货单号
|
||
'GM_CODE' => '04', //固定值
|
||
);
|
||
|
||
//格式化数据
|
||
foreach ($mapper as $field => &$value)
|
||
{
|
||
switch ($field) {
|
||
case 'PSTNG_DATE':
|
||
$value = date('Ymd', $masterInfo['create_time']);
|
||
break;
|
||
case 'DOC_DATE':
|
||
$value = date('Ymd', $masterInfo['iostock_time']);
|
||
break;
|
||
case 'REF_DOC_NO':
|
||
//sales OR sales return
|
||
//@todo:客户要求在REF_DOC_NO字段值后面加上random不重复的数字
|
||
if($masterInfo['iostock_type'] == 'out_stock'){
|
||
$value = 'SALES '. $masterInfo['sap_id'];
|
||
}else{
|
||
$value = 'SALES RETURN '. $masterInfo['sap_id'];
|
||
}
|
||
break;
|
||
case 'HEADER_TXT':
|
||
$value = $masterInfo['original_bn'];
|
||
break;
|
||
default:
|
||
//--
|
||
break;
|
||
}
|
||
}
|
||
|
||
return $mapper;
|
||
}
|
||
|
||
/**
|
||
* 格式化Shipment节点字段(XML文件中公共头部节点)
|
||
*
|
||
* @param $masterInfo
|
||
* @return array
|
||
*/
|
||
public function getFormatShipmentHead($masterInfo)
|
||
{
|
||
$mapper = array(
|
||
'PSTNG_DATE' => 'YYYYMMDD', //生成XML文件时间:年月日
|
||
'DOC_DATE' => 'YYYYMMDD', //OMS创建出入库明细时间:年月日
|
||
'REF_DOC_NO' => '', //以XML文件名中后16位字符
|
||
'HEADER_TXT' => '', //sales OR sales return
|
||
'GM_CODE' => '04', //固定值
|
||
);
|
||
|
||
//格式化数据
|
||
foreach ($mapper as $field => &$value)
|
||
{
|
||
switch ($field) {
|
||
case 'PSTNG_DATE':
|
||
$value = date('Ymd', $masterInfo['create_time']);
|
||
break;
|
||
case 'DOC_DATE':
|
||
$value = date('Ymd', $masterInfo['iostock_time']);
|
||
break;
|
||
case 'REF_DOC_NO':
|
||
//以XML文件名中后16位字符
|
||
$value = $masterInfo['ref_doc_no'];
|
||
break;
|
||
case 'HEADER_TXT':
|
||
//sales OR sales return
|
||
//@todo:客户要求在REF_DOC_NO字段值后面加上random不重复的数字
|
||
if($masterInfo['iostock_type'] == 'out_stock'){
|
||
$value = 'SALES '. $masterInfo['sap_id'];
|
||
}else{
|
||
$value = 'SALES RETURN '. $masterInfo['sap_id'];
|
||
}
|
||
break;
|
||
default:
|
||
//--
|
||
break;
|
||
}
|
||
}
|
||
|
||
return $mapper;
|
||
}
|
||
|
||
/**
|
||
* 格式化ShipmentDetails节点字段
|
||
* 备注信息:
|
||
* 1、销售出库时:
|
||
* PLANT字段:1161(LEE品牌)/1217(WRG品牌)
|
||
* MOVE_PLANT字段:TTPOS店铺,例如:00Z575、1439、1500、1581;
|
||
* 2、退货入库时:
|
||
* PLANT字段:TTPOS店铺,例如:00Z575、1439、1500、1581;
|
||
* MOVE_PLANT字段:1161(LEE品牌)/1217(WRG品牌)
|
||
*
|
||
* @param $masterInfo
|
||
* @param $itemInfo
|
||
* @return string[]
|
||
*/
|
||
public function getFormatShipmentDetails($masterInfo, $itemInfo)
|
||
{
|
||
$mapper = array(
|
||
'MATERIAL' => 'product_bn', //货号
|
||
'PLANT' => '1161', //LEE发1161,WRG发1217
|
||
'STGE_LOC' => '0001', //固定值
|
||
'MOVE_TYPE' => '301', //固定值
|
||
'ENTRY_QNT' => '1', //出入库数量
|
||
'MOVE_MAT' => 'product_bn', //货号,与MATERIAL字段保持一致
|
||
'MOVE_PLANT' => 'store code', //ttpos_store
|
||
'MOVE_STLOC' => '0001', //固定值
|
||
);
|
||
|
||
//brand code
|
||
$brand_code = '';
|
||
if(strtolower(ERP_BRAND) == 'lee'){
|
||
$brand_code = '1161';
|
||
}elseif(strtolower(ERP_BRAND) == 'wrg' || strtolower(ERP_BRAND) == 'wrangler'){
|
||
$brand_code = '1217';
|
||
}
|
||
|
||
//入库 OR 出库
|
||
if($masterInfo['iostock_type'] == 'in_stock'){
|
||
$plant = $masterInfo['ttpos_store'];
|
||
$move_plant = $brand_code;
|
||
}else{
|
||
$plant = $brand_code;
|
||
$move_plant = $masterInfo['ttpos_store'];
|
||
}
|
||
|
||
//格式化数据
|
||
foreach ($mapper as $field => &$value)
|
||
{
|
||
switch ($field) {
|
||
case 'MATERIAL':
|
||
$value = $itemInfo['product_bn'];
|
||
break;
|
||
case 'PLANT':
|
||
$value = $plant;
|
||
break;
|
||
case 'ENTRY_QNT':
|
||
$value = $itemInfo['nums'];
|
||
break;
|
||
case 'MOVE_MAT':
|
||
$value = $itemInfo['product_bn'];
|
||
break;
|
||
case 'MOVE_PLANT':
|
||
$value = $move_plant;
|
||
break;
|
||
default:
|
||
//--
|
||
break;
|
||
}
|
||
}
|
||
|
||
return $mapper;
|
||
}
|
||
|
||
/**
|
||
* 生成Sap出入库明细记录
|
||
*
|
||
* @param array $params
|
||
* @return array
|
||
*/
|
||
public function createSapIostock($params)
|
||
{
|
||
$iostockObj = app::get('vfapi')->model('iostocklist');
|
||
$sapIostockObj = app::get('vfapi')->model('sap_iostock');
|
||
$sapIostockItemObj = app::get('vfapi')->model('sap_iostock_items');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//filter
|
||
$filter = $params['filter'];
|
||
if(empty($filter)){
|
||
$error_msg = '没有指定查询条件!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//page_size
|
||
$page_size = $this->_page_size;
|
||
|
||
//count
|
||
$countNum = $iostockObj->count($filter);
|
||
if(empty($countNum)){
|
||
$error_msg = '没有可操作的出入库记录!';
|
||
return $this->error($error_msg);
|
||
}
|
||
|
||
//货号对照表
|
||
base_kvstore::instance('vfapi')->fetch('goodsmap.erp', $erpProductList);
|
||
|
||
//page
|
||
$pageNum = ceil($countNum / $page_size);
|
||
$tempList = $iostockBns = $iostockList = $existData = array();
|
||
for($page=1; $page<=$pageNum; $page++)
|
||
{
|
||
//getList
|
||
$tempList = $iostockObj->getList('id,iostock_bn,type_id,bill_type,branch_bn,product_bn,nums', $filter, 0, $page_size, 'id ASC');
|
||
if(empty($tempList)){
|
||
//没有查询到销售单数据
|
||
continue;
|
||
}
|
||
|
||
$iostockBns = array();
|
||
foreach ($tempList as $tempKey => $tempVal)
|
||
{
|
||
$id = $tempVal['id'];
|
||
$type_id = $tempVal['type_id'];
|
||
$bill_type = $tempVal['bill_type'];
|
||
$iostock_bn = $tempVal['iostock_bn'];
|
||
$branch_bn = $tempVal['branch_bn'];
|
||
$product_bn = trim($tempVal['product_bn']);
|
||
|
||
//check
|
||
if(in_array($tempVal['status'], array('succ', 'needless'))){
|
||
continue;
|
||
}
|
||
|
||
//检查是否需要生成SAP单据
|
||
$isDispose = $this->checkTypeidIsDispose($type_id, $bill_type, $branch_bn);
|
||
if(!$isDispose){
|
||
//update
|
||
$iostockObj->update(array('status'=>'needless', 'last_modified'=>time()), array('id'=>$id));
|
||
continue;
|
||
}
|
||
|
||
//check出入库数量为0
|
||
if(empty($tempVal['nums'])){
|
||
//update
|
||
$iostockObj->update(array('status'=>'needless', 'last_modified'=>time(), 'error_msg'=>'出入库数量为0'), array('id'=>$id));
|
||
continue;
|
||
}
|
||
|
||
//过滤赠品
|
||
if($erpProductList[$product_bn][1] == 'true'){
|
||
//update
|
||
$iostockObj->update(array('status'=>'needless', 'last_modified'=>time(), 'error_msg'=>'出入库为赠品'), array('id'=>$id));
|
||
continue;
|
||
}
|
||
|
||
//iostock_bn
|
||
$iostockBns[$iostock_bn] = $iostock_bn;
|
||
}
|
||
|
||
//获取组织好的出入库明细列表
|
||
$iostockList = $this->_formatIostockList($iostockBns);
|
||
if(empty($iostockList)){
|
||
continue;
|
||
}
|
||
|
||
//已经存在的数据
|
||
$existData = $sapIostockObj->getList('sap_id,iostock_bn', array('iostock_bn'=>$iostockBns));
|
||
if($existData){
|
||
$existData = $funcLib->_array_column($existData, null, 'iostock_bn');
|
||
}
|
||
|
||
//list
|
||
$iostockBns = array();
|
||
foreach ($iostockList as $iostockKey => $iostockInfo)
|
||
{
|
||
$iostock_bn = $iostockInfo['iostock_bn'];
|
||
|
||
//check
|
||
if($existData[$iostock_bn]){
|
||
$error_msg = '已经生成过Sap出入库记录';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'is_abnormal'=>'true', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
continue;
|
||
}
|
||
|
||
//items
|
||
$iostockItems = $iostockInfo['items'];
|
||
if(empty($iostockItems)){
|
||
$error_msg = '格式化出入库明细记录为空';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'is_abnormal'=>'true', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
continue;
|
||
}
|
||
unset($iostockInfo['items']);
|
||
|
||
//检查ttpos_store编码
|
||
if(empty($iostockInfo['ttpos_store'])){
|
||
$error_msg = 'TTPOS店铺号为空,请检查!';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'is_abnormal'=>'true', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
continue;
|
||
}
|
||
|
||
$iostockInfo['create_time'] = time();
|
||
$iostockInfo['last_modified'] = time();
|
||
|
||
//save master
|
||
$sap_id = $sapIostockObj->insert($iostockInfo);
|
||
if(!$sap_id){
|
||
$error_msg = '创建Sap出入库记录失败';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
continue;
|
||
}
|
||
|
||
//save items
|
||
$isSaveItems = true;
|
||
foreach ($iostockItems as $itemKey => $itemVal)
|
||
{
|
||
$itemVal['sap_id'] = $sap_id;
|
||
$product_bn = $itemVal['product_bn'];
|
||
|
||
//check出入库数量为0,则跳过
|
||
if(empty($itemVal['nums'])){
|
||
continue;
|
||
}
|
||
|
||
//过滤赠品
|
||
if($erpProductList[$product_bn][1] == 'true'){
|
||
continue;
|
||
}
|
||
|
||
//insert
|
||
$insert_id = $sapIostockItemObj->insert($itemVal);
|
||
if(!$insert_id){
|
||
$error_msg = '创建item出入库明细失败';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
$isSaveItems = false;
|
||
}
|
||
}
|
||
|
||
//fail
|
||
if(!$isSaveItems){
|
||
$error_msg = '保存item出入库明细失败';
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'fail', 'error_msg'=>$error_msg, 'last_modified'=>time()), array('iostock_bn'=>$iostock_bn));
|
||
|
||
continue;
|
||
}
|
||
|
||
//merge
|
||
$iostockBns[$iostock_bn] = $iostock_bn;
|
||
}
|
||
|
||
//update
|
||
$iostockObj->update(array('status'=>'succ', 'last_modified'=>time()), array('iostock_bn'=>$iostockBns));
|
||
}
|
||
|
||
//unset
|
||
unset($tempList, $iostockBns, $iostockList, $existData);
|
||
|
||
return $this->succ();
|
||
}
|
||
|
||
/**
|
||
* 按照出入库单号组织数据
|
||
*
|
||
* @param $iostockBns
|
||
* @return void
|
||
*/
|
||
public function _formatIostockList($iostockBns)
|
||
{
|
||
$iostockObj = app::get('vfapi')->model('iostocklist');
|
||
|
||
$funcLib = kernel::single('vfapi_func');
|
||
|
||
//getList
|
||
$dataList = $iostockObj->getList('*', array('iostock_bn'=>$iostockBns));
|
||
if(empty($dataList)){
|
||
return array();
|
||
}
|
||
|
||
//货号对照表
|
||
base_kvstore::instance('vfapi')->fetch('goodsmap.erp', $erpProductList);
|
||
|
||
//以shop店铺编码为下标,获取TTPOS列表
|
||
$shopTtposList = $funcLib->getShopTtposList();
|
||
|
||
//format
|
||
$iostockList = array();
|
||
foreach ($dataList as $key => $val)
|
||
{
|
||
$iostock_id = $val['iostock_id'];
|
||
$iostock_bn = $val['iostock_bn'];
|
||
$product_bn = $val['product_bn'];
|
||
|
||
//OMS外部仓库编码(与OMS店铺编码一致)
|
||
$shop_bn = $val['extrabranch_bn'];
|
||
|
||
//check
|
||
if(in_array($val['status'], array('needless', 'succ'))){
|
||
continue;
|
||
}
|
||
|
||
//check出入库数量为0,则跳过
|
||
if(empty($val['nums'])){
|
||
continue;
|
||
}
|
||
|
||
//过滤赠品
|
||
if($erpProductList[$product_bn][1] == 'true'){
|
||
continue;
|
||
}
|
||
|
||
//item Info
|
||
$itemInfo = array(
|
||
'iostock_id' => $iostock_id,
|
||
'iostock_bn' => $iostock_bn,
|
||
'product_bn' => $product_bn,
|
||
'barcode' => $val['barcode'],
|
||
'product_name' => $val['product_name'],
|
||
'nums' => $val['nums'],
|
||
);
|
||
|
||
//master info
|
||
if(empty($iostockList[$iostock_bn])){
|
||
//sales OR sales return
|
||
if($val['iostock_type'] == 'out_stock'){
|
||
$sap_type = 'SALES';
|
||
}else{
|
||
$sap_type = 'SALES RETURN';
|
||
}
|
||
|
||
//ttpos_store
|
||
$branch_ttpos_code = $shopTtposList[$shop_bn]['branch_ttpos_code'];
|
||
if(empty($branch_ttpos_code)){
|
||
$branch_ttpos_code = $shopTtposList[$shop_bn]['ttpos_store'];
|
||
}
|
||
|
||
//master
|
||
$iostockList[$iostock_bn] = array(
|
||
'iostock_bn' => $iostock_bn,
|
||
'iostock_type' => $val['iostock_type'],
|
||
'stock_type' => ($val['stock_type'] ? $val['stock_type'] : 'normal'), //库存类型(良品 or 不良品)
|
||
'type_id' => $val['type_id'],
|
||
'bill_type' => $val['bill_type'],
|
||
'sap_type' => $sap_type,
|
||
'branch_bn' => $val['branch_bn'],
|
||
'extrabranch_bn' => $val['extrabranch_bn'],
|
||
'original_bn' => $val['original_bn'],
|
||
'ttpos_store' => $branch_ttpos_code,
|
||
'iostock_time' => $val['iostock_time'],
|
||
);
|
||
}
|
||
|
||
//items
|
||
$iostockList[$iostock_bn]['items'][$iostock_id] = $itemInfo;
|
||
}
|
||
|
||
//unset
|
||
unset($iostockBns, $dataList);
|
||
|
||
return $iostockList;
|
||
}
|
||
|
||
/**
|
||
* 检测出入库类型,是否需要处理
|
||
*
|
||
* @param $type_id
|
||
* @param $bill_type
|
||
* @param $branch_bn
|
||
* @return true
|
||
*/
|
||
public function checkTypeidIsDispose($type_id, $bill_type='', $branch_bn='')
|
||
{
|
||
//出入库类型列表
|
||
$typeList = $this->getIostckTypeList();
|
||
|
||
//获取所有出入库类型ID
|
||
$typeIds = array_keys($typeList);
|
||
if(empty($typeIds)){
|
||
return true;
|
||
}
|
||
|
||
//检查出入库类型是否需要生成SAP单据
|
||
if(!in_array($type_id, $typeIds)){
|
||
return false;
|
||
}
|
||
|
||
//出入库类型信息
|
||
$typeRow = $typeList[$type_id];
|
||
|
||
//检查相应的场景
|
||
if($typeRow['bill_types']){
|
||
//检查bill_type出入库业务类型,是否需要生成SAP单据
|
||
if(!in_array($bill_type, $typeRow['bill_types'])){
|
||
return false;
|
||
}
|
||
}elseif($typeRow['not_branch_bns']){
|
||
//指定仓库编码:无需生成SAP单据
|
||
if(in_array($branch_bn, $typeRow['not_branch_bns'])){
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
} |