From 677d749c0a28db9cf37c94643be4cc8b1d8c1893 Mon Sep 17 00:00:00 2001 From: chenping Date: Tue, 7 Jul 2026 20:57:38 +0800 Subject: [PATCH] [TBID:opensource] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、支持天猫加急发货功能 2、支持京东厂直售后 3、优化视频号订单金额 4、优化失败订单恢复逻辑 --- .gitignore | 4 + app/console/controller/admin/delivery.php | 192 ++--- app/console/controller/admin/iostockorder.php | 286 +++++--- app/console/controller/admin/stockdump.php | 88 +-- app/console/model/delivery.php | 205 +++--- .../admin/stockdump/stockdump_more_item.html | 61 -- app/dealer/view/admin/order/order_button.html | 35 +- app/eccommon/dbschema/platform_regions.php | 3 + app/eccommon/dbschema/regions.php | 3 + app/erpapi/lib/apiname.php | 1 + app/erpapi/lib/autotask/task/retryapi.php | 1 + .../logistics/matrix/pdd/request/electron.php | 12 +- .../lib/shop/matrix/360buy/response/order.php | 17 +- .../lib/shop/matrix/jd/request/aftersale.php | 93 +++ .../shop/matrix/jd/response/aftersalev2.php | 42 +- .../lib/shop/matrix/jd/response/order.php | 5 +- .../lib/shop/matrix/luban/response/order.php | 27 + .../shop/matrix/taobao/request/logistics.php | 34 +- .../shop/matrix/tmall/request/logistics.php | 30 +- .../shop/response/components/order/items.php | 79 +- app/erpapi/lib/shop/response/delivergoods.php | 181 ++++- app/erpapi/lib/shop/response/order.php | 6 + .../lib/shop/response/params/aftersalev2.php | 2 +- .../lib/shop/response/process/aftersalev2.php | 7 + .../shop/response/process/delivergoods.php | 212 +++++- app/erpapi/lib/shop/whitelist.php | 2 + app/erpapi/lib/system/response/msg.php | 7 +- .../lib/system/response/process/msg.php | 60 +- .../lib/wms/matrix/qimen/request/delivery.php | 137 ++-- app/erpapi/lib/wms/response/stockout.php | 9 +- app/erpapi/model/api/fail.php | 60 +- .../controller/monthend/verification.php | 318 ++++++--- app/finance/dbschema/monthly_report.php | 20 +- app/finance/lib/finder/monthly/report.php | 7 +- app/finance/lib/monthly/report.php | 29 +- app/finance/lib/monthly/report/items.php | 10 +- app/finance/lib/verification.php | 3 + .../view/monthed/batch_verification.html | 213 ++++++ .../view/monthed/verificate_detail.html | 25 +- .../lib/autotask/timer/makeoutinvoice.php | 23 +- app/material/lib/finder/material/basic.php | 0 app/material/lib/sales/material/import.php | 26 +- .../view/admin/material/sales/add.html | 26 +- .../view/admin/material/sales/detail.html | 24 +- .../view/admin/material/sales/edit.html | 40 +- app/monitor/lib/event/template.php | 2 +- app/ome/controller/admin/delivery.php | 23 + app/ome/controller/admin/order.php | 428 ++++++----- app/ome/controller/admin/order/fail.php | 25 +- app/ome/controller/admin/order/lack.php | 4 +- app/ome/controller/admin/receipts/print.php | 8 +- app/ome/controller/admin/return/rchange.php | 46 +- app/ome/dbschema/orders.php | 7 + app/ome/dbschema/sales.php | 2 + app/ome/lib/aftersale/request/jd.php | 25 + app/ome/lib/auth/config.php | 11 + app/ome/lib/bill/label.php | 64 +- .../trigger/shop/data/delivery/common.php | 11 + app/ome/lib/event/trigger/shop/order.php | 82 +++ app/ome/lib/finder/orders.php | 66 +- app/ome/lib/order/fail.php | 128 +++- app/ome/lib/order/urgent.php | 672 ++++++++++++++++++ app/ome/lib/receipt/reship.php | 13 +- app/ome/lib/sales/price.php | 15 +- app/ome/lib/service/aftersale.php | 4 +- app/ome/model/delivery.php | 397 ++++++++--- app/ome/model/delivery/order.php | 11 +- app/ome/model/misc/task.php | 15 + app/ome/model/order/items.php | 35 + app/ome/model/order/retrial.php | 9 +- app/ome/model/orders.php | 179 ++--- app/ome/view/admin/order/fail/batchsave.html | 5 +- app/ome/view/admin/order/order_edit.html | 30 +- .../view/admin/order/order_edit_split.html | 29 +- .../return_product/rchange/do_cancel.html | 18 +- app/omeauto/lib/auto/group/item.php | 21 +- app/omevirtualwms/controller/admin/wms.php | 22 +- app/sales/lib/aftersale/type/change.php | 49 +- app/siso/lib/receipt/sales/abstract.php | 15 +- app/wms/model/delivery.php | 48 ++ assets/static/logo-5ckfAmJf.png | Bin 35145 -> 35146 bytes config/deploy.xml | 2 +- 82 files changed, 3675 insertions(+), 1511 deletions(-) delete mode 100644 app/console/view/admin/stockdump/stockdump_more_item.html create mode 100644 app/erpapi/lib/shop/matrix/jd/request/aftersale.php create mode 100644 app/finance/view/monthed/batch_verification.html create mode 100644 app/material/lib/finder/material/basic.php create mode 100644 app/ome/lib/aftersale/request/jd.php create mode 100644 app/ome/lib/order/urgent.php diff --git a/.gitignore b/.gitignore index 8d3c51a3..bc540be4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,7 @@ composer.lock .sisyphus AGENTS.md /tools + +/upgrade +/script +/docker diff --git a/app/console/controller/admin/delivery.php b/app/console/controller/admin/delivery.php index 3e188351..b9da7a19 100644 --- a/app/console/controller/admin/delivery.php +++ b/app/console/controller/admin/delivery.php @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class console_ctl_admin_delivery extends desktop_controller { + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; var $name = "发货单列表"; var $workground = "console_center"; @@ -26,7 +26,7 @@ class console_ctl_admin_delivery extends desktop_controller { function index(){ $_GET['view'] = intval($_GET['view']); $user = kernel::single('desktop_user'); - + $actions = array(); $base_filter = array( 'type' => array('normal'), @@ -34,7 +34,7 @@ class console_ctl_admin_delivery extends desktop_controller { 'parent_id' => 0, 'disabled' => 'false', ); - + $base_filter = array_merge($base_filter,$_GET); switch ($_GET['view']) { @@ -68,7 +68,7 @@ class console_ctl_admin_delivery extends desktop_controller { 'confirm' => '你确定要对勾选的发货单更新WMS发货状态为签收吗?', 'target' => 'refresh', ); - + /*** * @todo:[禁止使用此按钮]升级大版本,sdb_ome_delivery表中logi_status字段加属性,好莱客户刷不动; * @@ -106,9 +106,15 @@ class console_ctl_admin_delivery extends desktop_controller { ); } + // count + $operationOrgObj = app::get('ome')->model('operation_organization'); + $countNum = $operationOrgObj->count(); + //check shop permission $organization_permissions = kernel::single('desktop_user')->get_organization_permission(); - if($organization_permissions){ + + //@todo:只有一个运营组织时,不需要查询org_id,否则查询很慢; + if($organization_permissions && $countNum > 1){ $base_filter['org_id'] = $organization_permissions; } @@ -132,7 +138,11 @@ class console_ctl_admin_delivery extends desktop_controller { $this->finder('console_mdl_delivery', $params); } - //未发货 已发货 全部 + /** + * 构建发货单 Finder 视图,包括基于发货单标签的加急发货页签。 + * + * @return array + */ function _views(){ $oDelivery = app::get('ome')->model('delivery'); $base_filter = array( @@ -150,6 +160,20 @@ class console_ctl_admin_delivery extends desktop_controller { 4 => array('label' => app::get('base')->_('已揽收'), 'filter' => array('logi_status' => array('1'), 'process' => array('true'), 'status' => 'succ'), 'optional' => false), 5 => array('label' => app::get('base')->_('已签收'), 'filter' => array('logi_status' => array('3'), 'process' => array('true'), 'status' => 'succ'), 'optional' => false), 8 => array('label' => app::get('base')->_('截单失败'), 'filter' => array('logi_status' => array('8'), 'process' => array('true'), 'status' => 'succ'), 'optional' => false), + 9 => array( + 'label'=>app::get('base')->_('加急发货'), + 'filter'=>array( + 'status' => array('ready','progress','succ'), + 'order_label_code' => self::URGENT_LABEL_CODE, + ), + 'optional'=>false + ), + + /* + 3 => array('label'=>app::get('base')->_('待取件'),'filter'=>array('logi_status'=>array('0'),'process'=>array('TRUE'),'status'=>'succ'),'optional'=>false), + 4 => array('label'=>app::get('base')->_('已揽收'),'filter'=>array('logi_status'=>array('1'),'process'=>array('TRUE'),'status'=>'succ'),'optional'=>false), + 5 => array('label'=>app::get('base')->_('已签收'),'filter'=>array('logi_status'=>array('3'),'process'=>array('TRUE'),'status'=>'succ'),'optional'=>false),*/ + ); $branch_ids = $this->getSearchBranchids(); @@ -157,10 +181,16 @@ class console_ctl_admin_delivery extends desktop_controller { $sub_menu[6] = array('label'=>app::get('base')->_('京仓待发货'),'filter'=>array('process'=>array('false'),'status'=>array('progress','ready'),'branch_id'=>$branch_ids),'optional'=>false); $sub_menu[7] = array('label'=>app::get('base')->_('京仓失败'),'filter'=>array('process'=>array('false'),'status'=>array('progress','ready'),'branch_id'=>$branch_ids,'sync_status'=>array('9')),'optional'=>false); } - + + // count + $operationOrgObj = app::get('ome')->model('operation_organization'); + $countNum = $operationOrgObj->count(); + //check shop permission $organization_permissions = kernel::single('desktop_user')->get_organization_permission(); - if($organization_permissions){ + + //@todo:只有一个运营组织时,不需要查询org_id,否则查询很慢; + if($organization_permissions && $countNum > 1){ $base_filter['org_id'] = $organization_permissions; } @@ -375,7 +405,7 @@ class console_ctl_admin_delivery extends desktop_controller { /** * 打回操作 - * + * */ function doReback() { @@ -413,7 +443,7 @@ class console_ctl_admin_delivery extends desktop_controller { $order_ids = $dlyObj->getOrderIdByDeliveryId($deliveryInfo['delivery_id']); $err_msg = ''; - + //是否是合并发货单 if($deliveryInfo['is_bind'] == 'true'){ //取关联发货单号进行暂停 @@ -477,7 +507,7 @@ class console_ctl_admin_delivery extends desktop_controller { /** * 填写打回备注 - * + * * @param bigint $dly_id */ function showmemo($dly_id){ @@ -508,7 +538,7 @@ class console_ctl_admin_delivery extends desktop_controller { /** * 强制撤销第三方仓储发货单 - * + * * return */ public function deliveryCancel() @@ -565,10 +595,6 @@ class console_ctl_admin_delivery extends desktop_controller { - /** - * toBatchSearch - * @return mixed 返回值 - */ public function toBatchSearch() { $base_filter = array( @@ -591,9 +617,9 @@ class console_ctl_admin_delivery extends desktop_controller { } /** - * 查询京东沧海发货结果 - * sunjing - */ + * 查询京东沧海发货结果 + * sunjing + */ public function doBatchSearch() { @@ -641,10 +667,6 @@ class console_ctl_admin_delivery extends desktop_controller { } - /** - * 获取SearchBranchids - * @return mixed 返回结果 - */ public function getSearchBranchids(){ $channelObj = app::get('channel')->model('channel'); $channel_list = $channelObj->getlist('channel_id',array('node_type'=>array('yph','jd_wms_cloud'))); @@ -659,12 +681,12 @@ class console_ctl_admin_delivery extends desktop_controller { return $branch_ids; } - /** - * 加密字段显示明文 - * - * @return void - * @author - * */ + /** + * 加密字段显示明文 + * + * @return void + * @author + **/ public function showSensitiveData($delivery_id, $fieldType='') { // if (!kernel::single('desktop_user')->has_permission('sensitive_data_show')) { @@ -1084,7 +1106,7 @@ class console_ctl_admin_delivery extends desktop_controller { { @ini_set('memory_limit','512M'); set_time_limit(0); - + $deliveryIds = $_POST['delivery_id']; //check @@ -1107,7 +1129,7 @@ class console_ctl_admin_delivery extends desktop_controller { } $deliveryIds = array_column($dataList, 'delivery_id'); $_POST['delivery_id'] = $deliveryIds; - + $this->pagedata['GroupList'] = json_encode($deliveryIds); $this->pagedata['request_url'] = $this->url .'&act=ajaxSyncWms'; @@ -1116,10 +1138,6 @@ class console_ctl_admin_delivery extends desktop_controller { parent::dialog_batch('ome_mdl_delivery', false, 50, 'incr'); } - /** - * ajaxSyncWms - * @return mixed 返回值 - */ public function ajaxSyncWms() { $deliveryObj = app::get('ome')->model('delivery'); @@ -1253,15 +1271,11 @@ class console_ctl_admin_delivery extends desktop_controller { parent::dialog_batch('ome_mdl_delivery', false, 50, 'incr'); } - /** - * ajaxDeliveryCancel - * @return mixed 返回值 - */ public function ajaxDeliveryCancel() { $deliveryObj = app::get('ome')->model('delivery'); $operLogObj = app::get('ome')->model('operation_log'); - + $retArr = array( 'itotal' => 0, 'isucc' => 0, @@ -1406,7 +1420,7 @@ class console_ctl_admin_delivery extends desktop_controller { $this->end(true, '强制修复发货单成功'); } - + /** * 批量对勾选的发货单进行物流拦截 */ @@ -1414,45 +1428,41 @@ class console_ctl_admin_delivery extends desktop_controller { { @ini_set('memory_limit','512M'); set_time_limit(0); - + $deliveryObj = app::get('ome')->model('delivery'); - + $deliveryIds = $_POST['delivery_id']; - + //check if($_POST['isSelectedAll'] == '_ALL_'){ die('不能使用全选功能,每次最多选择500条;'); } - + if(empty($deliveryIds)){ die('请选择需要操作的发货单;'); } - + if(count($deliveryIds) > 500){ die('每次最多只能选择500条;'); } - + //data $filter = array('delivery_id'=>$deliveryIds, 'status'=>array('succ'), 'parent_id'=>0, 'logi_status'=>array('0','1','2','3','4','5','6','8')); $dataList = $deliveryObj->getList('delivery_id', $filter); if(empty($dataList)){ die('没有可拦截的发货单,或者发货单已经通知WMS进行拦截中!'); } - + $deliveryIds = array_column($dataList, 'delivery_id'); - + $this->pagedata['GroupList'] = json_encode($deliveryIds); - + $this->pagedata['request_url'] = $this->url .'&act=ajaxLogisticsInterception'; - + //调用desktop公用进度条(第4个参数是增量传offset,否则默认一直为0) parent::dialog_batch('ome_mdl_delivery', false, 50, 'incr'); } - - /** - * ajaxLogisticsInterception - * @return mixed 返回值 - */ + public function ajaxLogisticsInterception() { $ordermdl = app::get('ome')->model('orders'); @@ -1460,47 +1470,47 @@ class console_ctl_admin_delivery extends desktop_controller { $deliveryObj = app::get('ome')->model('delivery'); $operLogObj = app::get('ome')->model('operation_log'); $returnProductMdl = app::get('ome')->model('return_product'); - + $reshipLib = kernel::single('ome_reship'); $productLib = kernel::single('ome_return_product'); - + $retArr = array( 'itotal' => 0, 'isucc' => 0, 'ifail' => 0, 'err_msg' => array(), ); - + //获取发货单号 parse_str($_POST['primary_id'], $postdata); if(!$postdata){ echo 'Error: 请先选择发货单'; exit; } - + //filter $filter = $postdata['f']; $offset = intval($postdata['f']['offset']); $limit = intval($postdata['f']['limit']); - + if(empty($filter)){ echo 'Error: 没有找到查询条件'; exit; } - + //物流跟踪状态 $filter['logi_status'] = array('0','1','2','3','4','5','6','8'); - + //data $dataList = $deliveryObj->getList('delivery_id,delivery_bn,logi_name,logi_no,status,logi_status', $filter, $offset, $limit); if(empty($dataList)){ echo 'Error: 没有可操作的发货单,或者发货单已经通知WMS进行拦截'; exit; } - + //count $retArr['itotal'] = count($dataList); - + //list $error_msg = ''; foreach ($dataList as $key => $deliveryInfo) @@ -1508,56 +1518,56 @@ class console_ctl_admin_delivery extends desktop_controller { $delivery_id = $deliveryInfo['delivery_id']; $logi_name = $deliveryInfo['logi_name']; $logi_no = $deliveryInfo['logi_no']; - + //check if(!in_array($deliveryInfo['status'], array('succ'))){ continue; } - + if(empty($logi_no)){ continue; } - + //请求WMS进行物流拦截 $requestParams = ['logi_no'=>$logi_no]; $res = ome_delivery_notice::cut($requestParams); if ($res['rsp'] == 'success' || $res['rsp'] == 'succ') { //更新发货单状态为:拦截通知已发送 $deliveryObj->update(array('logi_status'=>'7'), array('delivery_id'=>$delivery_id)); - + //logs $operLogObj->write_log('delivery_back@ome', $delivery_id, '拦截通知已发送'); - + //根据发货单信息获取售后服务单数据 $returnProductList = $productLib->getReturnProductByDelivery($delivery_id, $error_msg); if(empty($returnProductList)){ //error $retArr['ifail'] += 1; $retArr['err_msg'][] = 'Error:'. $error_msg; - + continue; } - + //[按订单纬度]新建售后申请单,自动审核生成售后退货单,并且自动退货完成 $returnIds = array(); foreach ($returnProductList as $order_id => $returnProductSdf) { //是否检测明细已经创建过售后申请单 $returnProductSdf['is_check_items'] = true; - + //exec $return_id = $productLib->autoCreateReturnProduct($returnProductSdf, $error_msg); if(empty($return_id)){ //error $retArr['ifail'] += 1; $retArr['err_msg'][] = 'Error:'. $error_msg; - + continue 2; } - + $returnIds[$return_id] = $return_id; } - + //exec $reshipIds = array(); if($returnIds){ @@ -1575,34 +1585,34 @@ class console_ctl_admin_delivery extends desktop_controller { //error $retArr['ifail'] += 1; $retArr['err_msg'][] = 'Error:创建退货单失败,'. $error_msg; - + continue 2; } } - + //获取创建成功的售后退货单ID $reshipList = $reshipMdl->getList('reship_id,reship_bn,order_id,tmoney,totalmoney,had_refund', array('return_id'=>$returnIds, 'is_check'=>'0')); if($reshipList){ $reshipIds = array_column($reshipList, 'reship_id'); - + //order_id $orderIds = array_column($reshipList, 'order_id'); - + $orderList = $ordermdl->getList('order_id,order_bn,process_status,pay_status,ship_status,payed', ['order_id'=>$orderIds]); $orderList = array_column($orderList, null, 'order_id'); - + //update foreach ($reshipList as $reshipKey => $reshipInfo) { $order_id = $reshipInfo['order_id']; $reship_id = $reshipInfo['reship_id']; - + //使用发货单上的退回物流公司、退回物流单号进行更新 $updateData = [ 'return_logi_name' => $logi_name, 'return_logi_no' => $logi_no ]; - + //订单如果是全额退款,需要更新:已退金额 if(isset($orderList[$order_id])){ if($orderList[$order_id]['pay_status'] == '5' || $orderList[$order_id]['payed'] <= 0){ @@ -1618,42 +1628,42 @@ class console_ctl_admin_delivery extends desktop_controller { } } } - + $reshipMdl->update($updateData, array('reship_id'=>$reship_id)); } } } - + //售后退换货自动审批 $is_auto_approve = app::get('ome')->getConf('return.auto_approve'); if($reshipIds && $is_auto_approve == 'on'){ $reshipLib = kernel::single('ome_reship'); - + //使用queue例任务自动审核退货单 foreach ($reshipIds as $reshipKey => $reship_id) { $reshipLib->batch_reship_queue($reship_id); } } - + //succ $retArr['isucc'] += 1; - + //log $operLogObj->write_log('delivery_back@ome', $delivery_id, '自动创建售后申请单成功'); }else{ //error $retArr['ifail'] += 1; $retArr['err_msg'][] = $deliveryInfo['delivery_bn'].'请求物流拦截失败:'. $res['msg']; - + //拦截失败 $deliveryObj->update(array('logi_status'=>'8'), array('delivery_id'=>$delivery_id)); - + //log $operLogObj->write_log('delivery_back@ome', $delivery_id, '请求物流拦截发货单,失败:'.$res['msg']); } } - + echo json_encode($retArr),'ok.'; exit; } diff --git a/app/console/controller/admin/iostockorder.php b/app/console/controller/admin/iostockorder.php index 67eb0a9a..3830c34d 100644 --- a/app/console/controller/admin/iostockorder.php +++ b/app/console/controller/admin/iostockorder.php @@ -14,19 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class console_ctl_admin_iostockorder extends desktop_controller { public $name = "出入库计划"; public $workground = "console_purchasecenter"; - /** - * index - * @return mixed 返回值 - */ public function index() {} /** - * + * * 其他入库列表 */ public function other_iostock() @@ -50,10 +45,12 @@ class console_ctl_admin_iostockorder extends desktop_controller 'submit' => 'index.php?app=console&ctl=admin_iostockorder&act=batch_sync&io=' . $io, 'confirm' => '你确定要对勾选的单子发送至仓储吗?', 'target' => 'refresh'), - array('label' => '批量审核', - 'submit' => 'index.php?app=console&ctl=admin_iostockorder&act=batch_check&io=' . $io, - 'confirm' => '你确定要对勾选的单子批量审核吗?', - 'target' => 'refresh'), + array( + 'label' => '批量审核', + 'href' => 'javascript:void(0);', + 'submit' => 'index.php?app=console&ctl=admin_iostockorder&act=batch_check_dialog&io=' . $io, + 'target' => 'dialog::{width:600,height:280,title:\'批量审核\'}', + ), array( 'label' => sprintf('%s导入',$title), 'href' => sprintf('%s&act=displayImportIso&io=%s', $this->url,$io), @@ -96,10 +93,6 @@ class console_ctl_admin_iostockorder extends desktop_controller $this->finder('taoguaniostockorder_mdl_iso', $params); } - /** - * allocate_iostock - * @return mixed 返回值 - */ public function allocate_iostock() { $io = $_GET['io']; @@ -143,12 +136,6 @@ class console_ctl_admin_iostockorder extends desktop_controller $this->finder('taoguaniostockorder_mdl_iso', $params); } - /** - * iostock_add - * @param mixed $type type - * @param mixed $io io - * @return mixed 返回值 - */ public function iostock_add($type, $io) { if ($io) { @@ -200,13 +187,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } } - /** - * iostock_edit - * @param mixed $iso_id ID - * @param mixed $io io - * @param mixed $act act - * @return mixed 返回值 - */ public function iostock_edit($iso_id, $io, $act) { $order_label = $io ? '入库单' : '出库单'; @@ -254,11 +234,6 @@ class console_ctl_admin_iostockorder extends desktop_controller $this->singlepage("admin/iostock/instock_edit.html"); } - /** - * 获取EditProducts - * @param mixed $iso_id ID - * @return mixed 返回结果 - */ public function getEditProducts($iso_id) { if ($iso_id == '') { @@ -298,10 +273,6 @@ class console_ctl_admin_iostockorder extends desktop_controller echo json_encode($rows); } - /** - * do_edit_iostock - * @return mixed 返回值 - */ public function do_edit_iostock() { @@ -448,10 +419,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } } - /** - * do_save_iostockorder - * @return mixed 返回值 - */ public function do_save_iostockorder() { $libBranchProduct = kernel::single('ome_branch_product'); @@ -526,10 +493,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } } - /** - * 获取ProductStore - * @return mixed 返回结果 - */ public function getProductStore() { $libBranchProduct = kernel::single('ome_branch_product'); @@ -673,11 +636,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } #导出模板 - /** - * exportTemplate - * @param mixed $p p - * @return mixed 返回值 - */ public function exportTemplate($p) { if ($p) { @@ -698,7 +656,7 @@ class console_ctl_admin_iostockorder extends desktop_controller /** * 审核出入库单据 - * + * */ public function check($iso_id, $io, $act) { @@ -744,7 +702,7 @@ class console_ctl_admin_iostockorder extends desktop_controller /** * 保存出入库审核单据 - * + * */ public function doCheck() { @@ -942,10 +900,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } //调拨入库 取消操作 生成入库单 打回原始仓库 - /** - * cancelIostockin - * @return mixed 返回值 - */ public function cancelIostockin() { $iso_id = intval($_GET['iso_id']); @@ -1012,10 +966,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } //生成入库单 打回原始仓库 - /** - * doCancelIostockin - * @return mixed 返回值 - */ public function doCancelIostockin() { $this->begin(''); @@ -1093,7 +1043,7 @@ class console_ctl_admin_iostockorder extends desktop_controller /** * 调拔入库列表 - * + * * @access public * @author cyyr24@sina.cn */ @@ -1183,43 +1133,189 @@ class console_ctl_admin_iostockorder extends desktop_controller } /** - * batch_check - * @return mixed 返回值 + * 批量审核(弹窗进度条):打开 dialog_batch。 */ - public function batch_check() + public function batch_check_dialog() { - // $this->begin(''); - // kernel::database()->exec('commit'); - $isoObj = app::get('taoguaniostockorder')->model('iso'); - $ids = $_POST['iso_id']; - $isoList = $isoObj->getList('iso_id', array('iso_id' => $ids, 'check_status' => '1', 'confirm' => 'N', 'iso_status' => '1')); - - $io = $_GET['io']; - - if ($io == '1' || $io == '0') {// 等于1是入库单 等于0是出库单 - foreach ($isoList as $iso) { - $iso_id = $iso['iso_id']; - $iso_data = array('check_status' => '2'); - $result = $isoObj->update($iso_data, array('iso_id' => $iso_id)); - - if ($io == '1') { - kernel::single('console_event_trigger_otherstockin')->create(array('iso_id' => $iso_id), false); - }else{ - kernel::single('console_event_trigger_otherstockout')->create(array('iso_id' => $iso_id), false); - } - } + if (isset($_POST['isSelectedAll']) && $_POST['isSelectedAll'] == '_ALL_') { + die(app::get('console')->_('暂不支持全选')); } - $this->splash('success', null, '命令已经被成功发送!'); + $ids = isset($_POST['iso_id']) ? $_POST['iso_id'] : null; + if (!is_array($ids)) { + if ($ids !== null && $ids !== '') { + $ids = array($ids); + } + } + if (empty($ids) || !is_array($ids)) { + die(app::get('console')->_('请先选择要审核的单据')); + } + $ids = array_values(array_unique(array_map('intval', $ids))); + $ids = array_filter($ids); + if (count($ids) === 0) { + die(app::get('console')->_('请先选择要审核的单据')); + } + + $io = isset($_GET['io']) ? $_GET['io'] : ''; + if ($io !== '1' && $io !== '0') { + die('参数 io 无效'); + } + + $this->pagedata['GroupList'] = json_encode($ids); + $this->pagedata['request_url'] = 'index.php?app=console&ctl=admin_iostockorder&act=batch_check_step&io=' . $io; + $this->pagedata['maxNum'] = 1; + $this->pagedata['input_hidden'] = array(); + parent::dialog_batch(); } /** - * iostockConfirm - * @param mixed $iso_id ID - * @param mixed $io io - * @return mixed 返回值 + * 批量审核分块执行(供 taskrunner 调用,返回 JSON + ok.)。 */ + public function batch_check_step() + { + $io = isset($_GET['io']) ? $_GET['io'] : ''; + if ($io !== '1' && $io !== '0') { + echo 'Error: 参数 io 无效;'; + exit; + } + + $primary = isset($_POST['primary_id']) ? trim($_POST['primary_id']) : ''; + if ($primary === '') { + echo 'Error: 缺少待处理数据;'; + exit; + } + + $chunkIds = array_values(array_unique(array_filter(array_map('intval', explode(',', $primary))))); + if (count($chunkIds) === 0) { + echo 'Error: 缺少待处理数据;'; + exit; + } + + $ret = $this->_batchCheckIsoIds($chunkIds, $io); + echo json_encode($ret), 'ok.'; + exit; + } + + /** + * 对给定 iso_id 列表执行审核(与单笔 doCheck 一致走 doCkeck),每单独立事务。 + * + * @param array $ids + * @param string $io + * @return array itotal, isucc, ifail, err_msg(与 dialog_batch / allAudit 约定一致) + */ + protected function _batchCheckIsoIds(array $ids, $io) + { + $isoObj = app::get('taoguaniostockorder')->model('iso'); + $ids = array_values(array_unique(array_map('intval', $ids))); + $ids = array_filter($ids); + + $ret = array( + 'itotal' => count($ids), + 'isucc' => 0, + 'ifail' => 0, + 'err_msg' => array(), + ); + if (count($ids) === 0) { + return $ret; + } + + $isoList = $isoObj->getList('iso_id,iso_bn,type_id', array( + 'iso_id' => $ids, + 'check_status' => '1', + 'confirm' => 'N', + 'iso_status' => '1', + )); + + $rowById = array(); + foreach ($isoList as $row) { + $rowById[intval($row['iso_id'])] = $row; + } + + $skippedIds = array_diff($ids, array_keys($rowById)); + $skippedBnById = array(); + if (!empty($skippedIds)) { + $skippedRows = $isoObj->getList('iso_id,iso_bn', array('iso_id' => array_values($skippedIds))); + foreach ($skippedRows as $sr) { + $sid = intval($sr['iso_id']); + $skippedBnById[$sid] = !empty($sr['iso_bn']) ? $sr['iso_bn'] : (string) $sid; + } + } + + $typeMap = kernel::single('ome_iostock')->get_iostock_types(); + $iostockorderLib = kernel::single('console_iostockorder'); + $oplog = app::get('ome')->model('operation_log'); + + foreach ($ids as $iso_id) { + if (!isset($rowById[$iso_id])) { + $bn = isset($skippedBnById[$iso_id]) ? $skippedBnById[$iso_id] : (string) $iso_id; + $ret['ifail']++; + $ret['err_msg'][] = 'ERROR:' . $bn . ':不符合批量审核条件(需待审核、未确认、进行中的单据)'; + $oplog->write_log( + 'docheck_iostock@taoguaniostockorder', + $iso_id, + sprintf('审核单据:%s', $bn . ':不符合批量审核条件(需待审核、未确认、进行中的单据)') + ); + continue; + } + $row = $rowById[$iso_id]; + $iso_bn = !empty($row['iso_bn']) ? $row['iso_bn'] : (string) $iso_id; + + $db = kernel::database(); + $trx = $db->beginTransaction(); + if ($trx === false) { + $ret['ifail']++; + $ret['err_msg'][] = 'ERROR:' . $iso_bn . ':无法开启数据库事务'; + $typeInfo = isset($typeMap[$row['type_id']]['info']) ? $typeMap[$row['type_id']]['info'] : '单据'; + $oplog->write_log( + 'docheck_iostock@taoguaniostockorder', + $iso_id, + sprintf('审核%s:%s', $typeInfo, '无法开启数据库事务') + ); + continue; + } + + $rs = false; + $rsData = array('msg' => ''); + try { + list($rs, $rsData) = $iostockorderLib->doCkeck($iso_id, $io); + } catch (Exception $e) { + $db->rollBack(); + $ret['ifail']++; + $ret['err_msg'][] = 'ERROR:' . $iso_bn . ':' . $e->getMessage(); + $typeInfo = isset($typeMap[$row['type_id']]['info']) ? $typeMap[$row['type_id']]['info'] : '单据'; + $oplog->write_log( + 'docheck_iostock@taoguaniostockorder', + $iso_id, + sprintf('审核%s:%s', $typeInfo, $e->getMessage()) + ); + continue; + } + + if ($rs) { + $db->commit($trx); + $ret['isucc']++; + $typeInfo = isset($typeMap[$row['type_id']]['info']) ? $typeMap[$row['type_id']]['info'] : '单据'; + $log_msg = sprintf('审核%s:成功', $typeInfo); + $oplog->write_log('docheck_iostock@taoguaniostockorder', $iso_id, $log_msg); + continue; + } + + $db->rollBack(); + $ret['ifail']++; + $msg = (isset($rsData['msg']) && $rsData['msg'] !== '') ? $rsData['msg'] : '审核失败'; + $ret['err_msg'][] = 'ERROR:' . $iso_bn . ':' . $msg; + $typeInfo = isset($typeMap[$row['type_id']]['info']) ? $typeMap[$row['type_id']]['info'] : '单据'; + $oplog->write_log( + 'docheck_iostock@taoguaniostockorder', + $iso_id, + sprintf('审核%s:%s', $typeInfo, $msg) + ); + } + + return $ret; + } + public function iostockConfirm($iso_id, $io) { $iso_itemsObj = app::get('taoguaniostockorder')->model('iso_items'); @@ -1232,10 +1328,6 @@ class console_ctl_admin_iostockorder extends desktop_controller $this->singlepage('admin/iostock/iostock_confirm.html'); } - /** - * doIostockconfirm - * @return mixed 返回值 - */ public function doIostockconfirm() { $this->begin("index.php?app=console&ctl=admin_iostockorder"); @@ -1318,12 +1410,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } - /** - * 添加Same - * @param mixed $iso_id ID - * @param mixed $io io - * @return mixed 返回值 - */ public function addSame($iso_id,$io) { $this->begin('index.php?app=console&ctl=admin_iostockorder&act=other_iostock&io='.$io); @@ -1374,10 +1460,6 @@ class console_ctl_admin_iostockorder extends desktop_controller } - /** - * doSame - * @return mixed 返回值 - */ public function doSame() { $libBranchProduct = kernel::single('ome_branch_product'); diff --git a/app/console/controller/admin/stockdump.php b/app/console/controller/admin/stockdump.php index 92224922..ec32ad4c 100644 --- a/app/console/controller/admin/stockdump.php +++ b/app/console/controller/admin/stockdump.php @@ -14,15 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class console_ctl_admin_stockdump extends desktop_controller{ var $name = "库内转储"; var $workground = "console_center"; - /** - * index - * @return mixed 返回值 - */ public function index(){ $this->title = '库内转储'; @@ -77,17 +72,12 @@ class console_ctl_admin_stockdump extends desktop_controller{ /* * 新建调拨单 */ - public function add(){ $OBranch = app::get('ome')->model('branch'); - $where = ''; - $is_super = kernel::single('desktop_user')->is_super(); - if (!$is_super) { - $branch_id= $OBranch->getBranchByUser(true); - if($branch_id){ - $where= " AND wb.branch_id in(".implode(',', $branch_id).")"; - } + $branch_id= $OBranch->getBranchByUser(true); + if($branch_id){ + $where= " AND wb.branch_id in(".implode(',', $branch_id).")"; } #获取非自有WMS_id $wms_list = kernel::single('console_goodssync')->get_wms_list('selfwms','notequal'); @@ -104,10 +94,6 @@ class console_ctl_admin_stockdump extends desktop_controller{ /* * 库存入库单保存 */ - /** - * do_save - * @return mixed 返回值 - */ public function do_save() { $libBranchProduct = kernel::single('ome_branch_product'); @@ -190,11 +176,11 @@ class console_ctl_admin_stockdump extends desktop_controller{ } /** - * 取消转储单 - * @access public - * @param String $stockdump_id 转储单编号 - * @return - */ + * 取消转储单 + * @access public + * @param String $stockdump_id 转储单编号 + * @return + */ function do_cancel($stockdump_id){ $oStockdump = $this->app->model('stockdump'); if (empty($stockdump_id)){ @@ -212,10 +198,6 @@ class console_ctl_admin_stockdump extends desktop_controller{ die(json_encode($result)); } - /** - * do_save_operation - * @return mixed 返回值 - */ public function do_save_operation(){ $this->begin('index.php?app=console&ctl=admin_stockdump&act=index'); @@ -262,15 +244,12 @@ class console_ctl_admin_stockdump extends desktop_controller{ $where .= ' AND branch_bn in(\''.join('\',\'',$bn_array).'\')'; - $is_super = kernel::single('desktop_user')->is_super(); - if (!$is_super) { - $obranch_id= $branch_model->getBranchByUser(true); - if($obranch_id){ - foreach($obranch_id as $k=>&$v){ - if($v == $branch_id) unset($obranch_id[$k]); - } - $where .= " AND branch_id in(".implode(',', $obranch_id).")"; + $obranch_id= $branch_model->getBranchByUser(true); + if($obranch_id){ + foreach($obranch_id as $k=>&$v){ + if($v == $branch_id) unset($obranch_id[$k]); } + $where .= " AND branch_id in(".implode(',', $obranch_id).")"; } //过滤掉门店仓 @@ -290,7 +269,6 @@ class console_ctl_admin_stockdump extends desktop_controller{ } /*下载导入模版*/ - public function exportTemplate(){ $filename = "转储单".date('Y-m-d').".csv"; $encoded_filename = urlencode($filename); @@ -421,10 +399,6 @@ class console_ctl_admin_stockdump extends desktop_controller{ echo json_encode($product); } - /** - * 获取_products - * @return mixed 返回结果 - */ public function get_products(){ $name = $_GET['name']; $bn = $_GET['bn']; @@ -463,13 +437,13 @@ class console_ctl_admin_stockdump extends desktop_controller{ } /** - * 取消出入库单确定框 - * @access public - * @param Number $stock_id 入库单ID - * @param String $stock_bn 入库单编号 - * @param String $type 出入库,stockin入库;stockout出库 - * @return - */ + * 取消出入库单确定框 + * @access public + * @param Number $stock_id 入库单ID + * @param String $stock_bn 入库单编号 + * @param String $type 出入库,stockin入库;stockout出库 + * @return + */ function cancel($stock_id,$stock_bn){ $this->pagedata['stock_id'] = $stock_id; $this->pagedata['stock_bn'] = $stock_bn; @@ -481,14 +455,14 @@ class console_ctl_admin_stockdump extends desktop_controller{ $this->display('admin/stockdump/cancel_confirm.html'); } - /** - * 转储单查异查看 - * @access public - * @param Number $stock_id 入库单ID - * @param String $stock_bn 入库单编号 - * @param String $type 出入库,stockin入库;stockout出库 - * @return - */ + /** + * 转储单查异查看 + * @access public + * @param Number $stock_id 入库单ID + * @param String $stock_bn 入库单编号 + * @param String $type 出入库,stockin入库;stockout出库 + * @return + */ function difference($stockdump_id){ $branchObj = app::get('ome')->model('branch'); @@ -522,10 +496,6 @@ class console_ctl_admin_stockdump extends desktop_controller{ $this->singlepage('admin/stockdump/stockin_diff_item.html'); } - /** - * do_save_confirm_type - * @return mixed 返回值 - */ public function do_save_confirm_type(){ $this->begin('javascript:finderGroup["'.$_GET['finder_id'].'"].refresh();'); @@ -565,4 +535,4 @@ class console_ctl_admin_stockdump extends desktop_controller{ echo '"'.implode('","',$title2).'"'; } -} \ No newline at end of file +} diff --git a/app/console/model/delivery.php b/app/console/model/delivery.php index 06b940a2..01c88474 100644 --- a/app/console/model/delivery.php +++ b/app/console/model/delivery.php @@ -1,4 +1,5 @@ 'simple', 'ship_tel' => 'phone', 'ship_mobile' => 'phone', 'ship_addr' => 'simple', ); - /** - * table_name - * @param mixed $real real - * @return mixed 返回值 - */ - public function table_name($real = false){ + public function table_name($real = false){ if($real){ $table_name = 'sdb_ome_delivery'; }else{ @@ -42,10 +37,6 @@ class console_mdl_delivery extends dbeav_model{ return $table_name; } - /** - * 获取_schema - * @return mixed 返回结果 - */ public function get_schema(){ return app::get('ome')->model('delivery')->get_schema(); } @@ -65,26 +56,15 @@ class console_mdl_delivery extends dbeav_model{ return array_merge($childOptions,$parentOptions); } - /** - * _filter - * @param mixed $filter filter - * @param mixed $tableAlias tableAlias - * @param mixed $baseWhere baseWhere - * @return mixed 返回值 - */ public function _filter($filter,$tableAlias=null,$baseWhere=null) { $baseWhere = (array) $baseWhere; $tPre = ($tableAlias?$tableAlias:'`'.$this->table_name(true).'`').'.'; - + //setting $deliveryIds = array(); $where = ''; - - //filter - 加密字段处理 - $encryptWhere = kernel::single('ome_filter_encrypt')->encrypt($filter, $this->__encrypt_cols, $tPre, 'delivery'); - $baseWhere = array_merge($baseWhere, $encryptWhere); - + if(isset($filter['ship_tel_mobile'])){ $encryptVal = kernel::single('ome_security_factory')->encryptPublic($filter['ship_tel_mobile'],'phone'); $encryptVal = utils::addslashes_array($encryptVal); @@ -99,7 +79,7 @@ class console_mdl_delivery extends dbeav_model{ $where .= ' OR delivery_id IN ('.implode(',', $filter['extend_delivery_id']).')'; unset($filter['extend_delivery_id']); } - + if (isset($filter['member_uname'])){ $memberObj = app::get('ome')->model("members"); $rows = $memberObj->getList('member_id',array('uname|has'=>$filter['member_uname'])); @@ -110,7 +90,7 @@ class console_mdl_delivery extends dbeav_model{ $where .= ' AND member_id IN ('.implode(',', $memberId).')'; unset($filter['member_uname']); } - + if(isset($filter['outer_dlybn'])) { if(strpos($filter['outer_dlybn'], "\n") !== false){ $filter['outer_dlybn'] = array_unique(array_map('trim', array_filter(explode("\n", $filter['outer_dlybn'])))); @@ -121,7 +101,7 @@ class console_mdl_delivery extends dbeav_model{ $rows[] = 0; $where .= ' AND delivery_bn IN ("'.implode('","', $rows).'")'; } - + if (isset($filter['order_bn'])){ // 多订单号查询 if(strpos($filter['order_bn'], "\n") !== false){ @@ -136,156 +116,156 @@ class console_mdl_delivery extends dbeav_model{ $deliOrderObj = app::get('ome')->model("delivery_order"); $rows = $deliOrderObj->getList('delivery_id',array('order_id'=>$orderId)); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['order_bn']); } - + //按基础物料搜索 if (isset($filter['material_bn'])){ //多货号查询 if(strpos($filter['material_bn'], "\n") !== false){ $material_bns = array_unique(array_map('trim', array_filter(explode("\n", $filter['material_bn'])))); - + $filter['material_bn'] = $material_bns; } - + //search_delivery_items $itemsObj = app::get('ome')->model("delivery_items"); $rows = $itemsObj->getDeliveryIdByPbn($filter); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + //unset unset($filter['material_bn']); } - + //按货号搜索 if(isset($filter['product_bn'])){ //search_delivery_items $itemsObj = app::get('ome')->model("delivery_items"); $rows = $itemsObj->getDeliveryIdByFilter($filter); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + //unset unset($filter['product_bn']); } - + //按条形码搜索 if(isset($filter['product_barcode'])){ //search_delivery_items $itemsObj = app::get('ome')->model("delivery_items"); - + //获取条形码关联的货号 $codeSql = "SELECT a.code, b.bm_id,b.material_bn FROM sdb_material_codebase AS a LEFT JOIN sdb_material_basic_material AS b ON a.bm_id=b.bm_id "; $codeSql .= " WHERE a.code='". addslashes($filter['product_barcode']) ."'"; $materialInfo = $itemsObj->db->selectrow($codeSql); - + //用货号进行搜索 $filter['product_bn'] = $materialInfo['material_bn']; - + //unset(一定要注销掉,防止重复调用) unset($filter['product_barcode']); - + //list $rows = $itemsObj->getDeliveryIdByFilter($filter); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + //unset unset($filter['product_bn']); } - + if(isset($filter['logi_no_ext'])){ $logObj = app::get('ome')->model("delivery_log"); $rows = $logObj->getDeliveryIdByLogiNO($filter['logi_no_ext']); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['logi_no_ext']); } - + if(isset($filter['addonSQL'])){ $where .= ' AND '.$filter['addonSQL']; unset($filter['addonSQL']); } - + if(isset($filter['delivery_ident'])){ //delivery_id $tempDlyIds = array(0); - + $arr_delivery_ident = explode('_',$filter['delivery_ident']); $mdl_queue = app::get('ome')->model("print_queue"); if(count($arr_delivery_ident) == 2){ @@ -312,14 +292,14 @@ class console_mdl_delivery extends dbeav_model{ } } } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['delivery_ident']); } if($filter['todo']==1){ @@ -379,21 +359,21 @@ class console_mdl_delivery extends dbeav_model{ $delivery_id = $obj_delivery_bill->dump(array('logi_no'=>$filter['logi_no']),'delivery_id'); if(!empty($delivery_id['delivery_id'])){ $temp_dly_id = $delivery_id['delivery_id']; - + $tempDlyIds = array(0); $tempDlyIds[$temp_dly_id] = $temp_dly_id; - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['logi_no']); } } - + //客服备注 if(isset($filter['mark_text'])){ $mark_text = $filter['mark_text']; @@ -404,22 +384,22 @@ class console_mdl_delivery extends dbeav_model{ foreach($_rows as $_orders) { $temp_dly_id = $_orders['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['mark_text']); } } - + //买家留言 if(isset($filter['custom_mark'])){ $custom_mark = $filter['custom_mark']; @@ -430,28 +410,49 @@ class console_mdl_delivery extends dbeav_model{ foreach($_rows as $_orders) { $temp_dly_id = $_orders['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['custom_mark']); } } - - //同步状态筛查 + + //订单标记 + if($filter['order_label']){ + // 优化:使用EXISTS子查询提高性能,避免SQL注入 + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + LEFT JOIN sdb_ome_delivery o ON bl.bill_id = o.delivery_id + WHERE bl.bill_id = sdb_ome_delivery.delivery_id + AND bl.label_id = "'.addslashes($filter['order_label']).'" + AND bl.bill_type = "ome_delivery" + )'; + unset($filter['order_label']); + } + if (!empty($filter['order_label_code'])) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = sdb_ome_delivery.delivery_id + AND bl.label_code = "'.addslashes($filter['order_label_code']).'" + AND bl.bill_type = "ome_delivery" + )'; + unset($filter['order_label_code']); + } + #同步状态筛查 if (isset($filter['sync_filter'])) { $boolSync = kernel::single('console_delivery_bool_sync')->getBoolSync($filter['sync_filter']); $where .= ' AND sync IN ("'.implode('","', $boolSync).'")'; unset($filter['sync_filter']); } - + //delivery_ids if($deliveryIds){ $where .= " AND delivery_id IN ('". implode("','", $deliveryIds) ."')"; @@ -466,15 +467,15 @@ class console_mdl_delivery extends dbeav_model{ foreach ($tempData as $tempKey => $tempVal) { $temp_order_id = $tempVal['bill_id']; - + $orderId[$temp_order_id] = $temp_order_id; } - + $where .= ' AND delivery_id IN ("'. implode('","', $orderId) .'")'; }else{ $where .= ' AND delivery_id = "-1"'; } - + unset($filter['order_label'], $tempData); } if (isset($filter['delivery_bn'])){ @@ -522,12 +523,7 @@ class console_mdl_delivery extends dbeav_model{ return $result; } - /** - * insert - * @param mixed $data 数据 - * @return mixed 返回值 - */ - public function insert(&$data) + public function insert(&$data) { foreach ($this->__encrypt_cols as $field => $type) { if (isset($data[$field])) { @@ -568,13 +564,6 @@ class console_mdl_delivery extends dbeav_model{ return $data; } - /** - * modifier_ship_name - * @param mixed $ship_name ship_name - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_name($ship_name,$list,$row) { if ($this->is_export_data) { @@ -596,13 +585,6 @@ HTML; return $ship_name?$return:$ship_name; } - /** - * modifier_ship_tel - * @param mixed $tel tel - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_tel($tel,$list,$row) { if ($this->is_export_data) { @@ -624,13 +606,6 @@ HTML; return $tel?$return:$tel; } - /** - * modifier_ship_mobile - * @param mixed $mobile mobile - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_mobile($mobile,$list,$row) { if ($this->is_export_data) { @@ -652,13 +627,6 @@ HTML; return $mobile?$return:$mobile; } - /** - * modifier_ship_addr - * @param mixed $ship_addr ship_addr - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_addr($ship_addr,$list,$row) { if ($this->is_export_data) { @@ -680,13 +648,6 @@ HTML; return $ship_addr?$return:$ship_addr; } - /** - * modifier_member_id - * @param mixed $member_id ID - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_member_id($member_id,$list,$row) { static $members; diff --git a/app/console/view/admin/stockdump/stockdump_more_item.html b/app/console/view/admin/stockdump/stockdump_more_item.html deleted file mode 100644 index f3b7308b..00000000 --- a/app/console/view/admin/stockdump/stockdump_more_item.html +++ /dev/null @@ -1,61 +0,0 @@ - - -
-

转储详情:

-
- - - - - - - - - - - - -<{foreach from=$items item=item}> - - - - - - - - - -<{/foreach}> - - -
基础物料编码基础物料名称规格单位入库价格数量已入库数量
<{$item.bn}><{$item.product_name}><{$item.spec_info}><{$item.unit}><{$item.appro_price|cur}><{$item.num}><{$item.in_nums}>
-
- <{$pager}> -
- -<{capture name="footbar"}> -
- <{button label="关 闭" type="button" onclick="window.close();"}> -
-<{/capture}> -
-
\ No newline at end of file diff --git a/app/dealer/view/admin/order/order_button.html b/app/dealer/view/admin/order/order_button.html index ac043e59..bbcbb5e0 100644 --- a/app/dealer/view/admin/order/order_button.html +++ b/app/dealer/view/admin/order/order_button.html @@ -28,12 +28,13 @@ diff --git a/app/eccommon/dbschema/platform_regions.php b/app/eccommon/dbschema/platform_regions.php index 0ec346d5..59d11d92 100644 --- a/app/eccommon/dbschema/platform_regions.php +++ b/app/eccommon/dbschema/platform_regions.php @@ -157,4 +157,7 @@ $db['platform_regions'] = array( ), ), 'comment' => '平台地区表', + 'engine' => 'innodb', + 'version' => '$Rev: $', + 'charset' => 'utf8mb4', ); diff --git a/app/eccommon/dbschema/regions.php b/app/eccommon/dbschema/regions.php index 7c935a3c..ac803938 100644 --- a/app/eccommon/dbschema/regions.php +++ b/app/eccommon/dbschema/regions.php @@ -130,4 +130,7 @@ $db['regions']=array ( ), ), 'comment' => '电商商务通用应用区域表', + 'engine' => 'innodb', + 'version' => '$Rev: $', + 'charset' => 'utf8mb4', ); diff --git a/app/erpapi/lib/apiname.php b/app/erpapi/lib/apiname.php index 0bb87af5..831c38d0 100644 --- a/app/erpapi/lib/apiname.php +++ b/app/erpapi/lib/apiname.php @@ -256,6 +256,7 @@ define('SHOP_REFUND_NOTIFY_GET','store.tmc.refundcreated.get'); define('SHOP_REFUND_STATUS_GET','store.refund.status.get'); // 退款状态查询 define('SHOP_COMPENSATE_REFUND_GET','store.special.refunds.receive.get'); // 赔付单获取 define('SHOP_TRADE_REFUND_GET', 'store.trade.refund.get'); // 查询售后单详情 +define('SHOP_LOGISTICS_ORDER_REPORT','store.logistics.order.report'); // 淘宝加急发货回传平台订单状态接口 define('SHOP_LOGISTICS_SUBSCRIBE','store.trade.pub.appreciation'); // 增强版华强宝订阅(订单分发的信息:分给了的网点,业务员的信息) define('SHOP_LOGISTICS_BIND','erp.logistics.bind'); // ERP自己定义的 diff --git a/app/erpapi/lib/autotask/task/retryapi.php b/app/erpapi/lib/autotask/task/retryapi.php index b77130c1..e8cf2f31 100644 --- a/app/erpapi/lib/autotask/task/retryapi.php +++ b/app/erpapi/lib/autotask/task/retryapi.php @@ -90,6 +90,7 @@ class erpapi_autotask_task_retryapi{ break; case WMS_SALEORDER_CREATE: + case 'delivery_create': // 销售出库 $delivery = app::get('ome')->model('delivery')->dump(array('delivery_bn'=>$params['obj_bn']),'delivery_id,status,pause,process'); diff --git a/app/erpapi/lib/logistics/matrix/pdd/request/electron.php b/app/erpapi/lib/logistics/matrix/pdd/request/electron.php index 400daca7..6e4b34ad 100644 --- a/app/erpapi/lib/logistics/matrix/pdd/request/electron.php +++ b/app/erpapi/lib/logistics/matrix/pdd/request/electron.php @@ -60,6 +60,7 @@ class erpapi_logistics_matrix_pdd_request_electron extends erpapi_logistics_requ 'detail' => $sdf['shop']['address_detail'], 'district' => $sdf['shop']['area'], 'province' => $sdf['shop']['province'], + 'street' => $sdf['shop']['street'], 'mobile' => $sdf['shop']['mobile'], 'name' => $sdf['shop']['default_sender'], 'phone' => $sdf['shop']['tel'], @@ -119,8 +120,8 @@ class erpapi_logistics_matrix_pdd_request_electron extends erpapi_logistics_requ 'name' => $this->charFilter($pVal['item_name']) ); } - $TradeOrderInfoDto[] = array( - 'object_id' => $delivery['delivery_bn'], + $tmp = array( + 'object_id' => $delivery['delivery_bn'], 'order_platform' => $delivery['order_channels_type'] ? $delivery['order_channels_type'] : 'OTHER', 'tid_list' => empty($delivery['order_bn']) ? array($delivery['delivery_bn']) @@ -145,6 +146,13 @@ class erpapi_logistics_matrix_pdd_request_electron extends erpapi_logistics_requ 'order_bns' => implode(',', $delivery['order_bns']), ); + + // 四级地区(街道) + if ($delivery['ship_town']) { + $tmp['recipient']['street'] = $delivery['ship_town']; + } + + $TradeOrderInfoDto[] = $tmp; } $params = array( diff --git a/app/erpapi/lib/shop/matrix/360buy/response/order.php b/app/erpapi/lib/shop/matrix/360buy/response/order.php index dbda2273..5db18ca7 100644 --- a/app/erpapi/lib/shop/matrix/360buy/response/order.php +++ b/app/erpapi/lib/shop/matrix/360buy/response/order.php @@ -154,8 +154,15 @@ class erpapi_shop_matrix_360buy_response_order extends erpapi_shop_response_orde protected function _analysis() { $this->_ordersdf['is_delivery'] = 'Y';#默认可以发货 + + $platformSourceStatus = $this->_ordersdf['source_status']; + parent::_analysis(); + if ($platformSourceStatus == 'PAUSE') { + $this->_ordersdf['source_status'] = $this->_sourceStatus['PAUSE']; + } + if(!$this->_ordersdf['lastmodify']){ $this->_ordersdf['lastmodify'] = date('Y-m-d H:i:s',time()); } @@ -338,7 +345,7 @@ class erpapi_shop_matrix_360buy_response_order extends erpapi_shop_response_orde //@todo:官方文档:https://open.jd.com/v2/#/doc/scene?listId=2168 // type = 244 代表:244-新品国补立减 // type = 1080 代表:1080-政府消费券(可开票) - if(in_array($value['type'], [244, 1080])) { + if(in_array($value['type'], [244, 1080, 233])) { foreach ($value['orderCostAmounts'] as $orderCostAmount) { if($orderCostAmount['bearer'] == 5 && $orderCostAmount['bearAmount'] > 0) { @@ -769,9 +776,11 @@ class erpapi_shop_matrix_360buy_response_order extends erpapi_shop_response_orde protected function _canUpdate() { - - if ($this->_tgOrder['order_type'] == 'presale' && empty($this->_ordersdf['step_trade_status'])) { - $this->__apilog['result']['msg'] = '预售订单中间以普通订单下来的不接收'; + // 京东预售:仅付定金、平台 PAUSE 时不接收 + if ($this->_tgOrder['order_type'] == 'presale' + && $this->_tgOrder['pay_status'] == '3' + && $this->_ordersdf['source_status'] == $this->_sourceStatus['PAUSE']) { + $this->__apilog['result']['msg'] = '预售订单中间以普通订单下来的不接收,平台 PAUSE'; return false; } diff --git a/app/erpapi/lib/shop/matrix/jd/request/aftersale.php b/app/erpapi/lib/shop/matrix/jd/request/aftersale.php new file mode 100644 index 00000000..3a713e5b --- /dev/null +++ b/app/erpapi/lib/shop/matrix/jd/request/aftersale.php @@ -0,0 +1,93 @@ +get_name(); + if ($userName === null || $userName === '') { + $oper = kernel::single('ome_func')->getDesktopUser(); + $userName = $oper['op_name'] ? $oper['op_name'] : 'ERP'; + } + + $st = (string) $status; + if ($st === '5') { + $approval_state = 2; + $suggestion = $userName . '拒绝'; + if (!empty($aftersale['refuse_message'])) { + $suggestion .= ':' . $aftersale['refuse_message']; + } elseif (!empty($aftersale['memo']) && is_array($aftersale['memo']) && !empty($aftersale['memo']['refuse_message'])) { + $suggestion .= ':' . $aftersale['memo']['refuse_message']; + } + } else { + $approval_state = 1; + $suggestion = $userName . '同意'; + } + + // tid:订单编号 — 父类 erpapi_shop_request_aftersale::updateAfterSaleStatus 中赋值 $params['tid'] = $order['order_bn'] + return array( + 'approval_suggestion' => $suggestion, # 审核意见 + 'approval_state' => $approval_state, # 审核状态 1:审核通过 2:审核不通过 + 'refund_id' => $aftersale['return_bn'], # 售前退款数据唯一标示(售后退货场景为售后申请单号 return_bn,对齐矩阵推送 refund_id) + 'operator_state' => '5', # 操作状态:5新订单;9正在出库;10 出库成功;15正在发货;16发货成功 + ); + } + + /** + * 卖家确认收货(厂直 store.return.good.confirm:refund_id + tid) + * tid:优先售后单 platform_order_bn;为空则按 order_id 查 orders.platform_order_bn;仍为空则 order_bn 托底(换货子单用 relate_order_bn) + * + * @param array $sdf return_bn、platform_order_bn、order_id(由 returngoods_confirm 传入) + */ + public function returnGoodsConfirm($sdf) + { + $refundId = isset($sdf['return_bn']) ? $sdf['return_bn'] : ''; + $orderId = isset($sdf['order_id']) ? $sdf['order_id'] : null; + $tidFromReturn = isset($sdf['platform_order_bn']) ? trim((string) $sdf['platform_order_bn']) : ''; + + $tid = $tidFromReturn; + if ($tid === '' && $orderId) { + $orderRow = app::get('ome')->model('orders')->db_dump( + array('order_id' => $orderId), + 'platform_order_bn,order_bn,relate_order_bn,createway' + ); + if ($orderRow) { + $tid = isset($orderRow['platform_order_bn']) ? trim((string) $orderRow['platform_order_bn']) : ''; + if ($tid === '') { + $tid = ($orderRow['createway'] == 'after' && !empty($orderRow['relate_order_bn'])) + ? $orderRow['relate_order_bn'] + : $orderRow['order_bn']; + } + } + } + + if ($refundId === '' || $tid === '') { + return; + } + + $title = '售后确认收货[' . $refundId . ']'; + $data = array( + 'refund_id' => $refundId, + 'tid' => $tid, + ); + $this->__caller->call(SHOP_RETURN_GOOD_CONFIRM, $data, array(), $title, 10, $refundId); + } +} diff --git a/app/erpapi/lib/shop/matrix/jd/response/aftersalev2.php b/app/erpapi/lib/shop/matrix/jd/response/aftersalev2.php index 1fce6c73..b6df8dde 100644 --- a/app/erpapi/lib/shop/matrix/jd/response/aftersalev2.php +++ b/app/erpapi/lib/shop/matrix/jd/response/aftersalev2.php @@ -22,14 +22,52 @@ class erpapi_shop_matrix_jd_response_aftersalev2 extends erpapi_shop_response_aftersalev2 { + public function add($params) { + if ($params['refund_type'] == 'reship' && $params['refund_id']) { + $returnModel = app::get('ome')->model('return_product'); + $count = $returnModel->count(array( + 'shop_id' => $this->__channelObj->channel['shop_id'], + 'return_bn' => $params['refund_id'], + 'source' => 'matrix', + )); + + if ($count == 0) { + $returnRsp = $params; + $returnRsp['status'] = 'WAIT_BUYER_RETURN_GOODS'; + $returnRsp['refund_type'] = 'return'; + kernel::single('ome_return')->get_return_log($returnRsp, $this->__channelObj->channel['shop_id'], $msg); + } + } + + return parent::add($params); + } + protected function _formatAddParams($params) { $sdf = parent::_formatAddParams($params); - $sdf['refund_type'] = 'apply'; + // 原逻辑:所有售后单统一为退款申请(apply),会覆盖平台 refund_type=return,导致无法走退货售后 + // $sdf['refund_type'] = 'apply'; + $refundType = isset($sdf['refund_type']) ? (string) $sdf['refund_type'] : ''; + if ($refundType === '' || $refundType === 'refund') { + $sdf['refund_type'] = 'apply'; + } return $sdf; } protected function _getAddType($sdf) { - return 'refund';#只有售前退款单 + // return 'refund';#只有售前退款单 + + // 参考360buy + if(in_array($sdf['refund_type'],array('refund','apply'))) { #退款 + return 'refund'; + } elseif ($sdf['refund_type'] == 'return') { + return 'returnProduct'; + } elseif ($sdf['refund_type'] == 'reship') { + if ($sdf['status'] == 'confirm_failed'){ + return 'returnProduct'; + }else{ + return 'reship'; + } + } } protected function _formatAddItemList($sdf, $convert=array()) { diff --git a/app/erpapi/lib/shop/matrix/jd/response/order.php b/app/erpapi/lib/shop/matrix/jd/response/order.php index 53ccad96..a64c4b93 100644 --- a/app/erpapi/lib/shop/matrix/jd/response/order.php +++ b/app/erpapi/lib/shop/matrix/jd/response/order.php @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * @author ykm 2018/12/7 * @describe 京东供应商订单 @@ -71,7 +70,11 @@ class erpapi_shop_matrix_jd_response_order extends erpapi_shop_response_order } $arrField = explode('/', $field); $object['actually_amount'] = current($object['order_items'])[$arrField[0]][$arrField[1]]; + // 因为厂直是跟平台结算,所以商家结算(settlement_amount)要取采购价 + $object['settlement_amount'] = $object['purchase_price']; foreach ($object['order_items'] as &$item) { + // 因为厂直是跟平台结算,所以商家结算(settlement_amount)要取采购价 + $item['settlement_amount'] = $item['purchase_price']; if ($this->_ordersdf['timing_confirm']) { $item['estimate_con_time'] = (int)$this->_ordersdf['timing_confirm']; } diff --git a/app/erpapi/lib/shop/matrix/luban/response/order.php b/app/erpapi/lib/shop/matrix/luban/response/order.php index eb72fff2..16f65524 100644 --- a/app/erpapi/lib/shop/matrix/luban/response/order.php +++ b/app/erpapi/lib/shop/matrix/luban/response/order.php @@ -183,6 +183,9 @@ class erpapi_shop_matrix_luban_response_order extends erpapi_shop_response_order if(empty($this->_ordersdf['order_objects']) && !is_array($this->_ordersdf['order_objects'])){ return true; } + + // 抖音券包类商品可能不下发商家编码,先用平台ID兜底,避免失败订单无法人工匹配销售物料。 + $this->_fillEmptyBnWithPlatformIds(); //抖音订单扩展信息 $authoList = array(); @@ -547,6 +550,30 @@ class erpapi_shop_matrix_luban_response_order extends erpapi_shop_response_order $this->updateOrderPmtGoods(); } } + + /** + * 抖音部分券包类商品只下发 shop_goods_id/shop_product_id,不下发商家编码 bn。 + * + * 这种订单仍然会因为销售物料不存在进入失败订单,但如果 bn 为空,失败订单页面无法直接按编码人工匹配销售物料。 + * 因此仅在 luban 且 bn 为空时,用平台商品ID/SKU ID兜底,保留可人工识别和匹配的编码。 + * + * 注意:通用 formatItemsSdf() 对单 object 单 item 的老结构会把 item 提到 object 层,并用 item 字段覆盖 object 同名字段。 + * 所以单 SKU 场景最终 order_objects.bn 会跟随 item.bn,使用 shop_product_id 作为兜底值。 + */ + protected function _fillEmptyBnWithPlatformIds() + { + foreach ((array)$this->_ordersdf['order_objects'] as $objectKey => $object) { + if (!$object['bn'] && $object['shop_goods_id'] && $object['shop_goods_id'] != '0') { + $this->_ordersdf['order_objects'][$objectKey]['bn'] = $object['shop_goods_id']; + } + + foreach ((array)$object['order_items'] as $itemKey => $item) { + if (!$item['bn'] && $item['shop_product_id'] && $item['shop_product_id'] != '0') { + $this->_ordersdf['order_objects'][$objectKey]['order_items'][$itemKey]['bn'] = $item['shop_product_id']; + } + } + } + } /** * 订单更新 diff --git a/app/erpapi/lib/shop/matrix/taobao/request/logistics.php b/app/erpapi/lib/shop/matrix/taobao/request/logistics.php index 24e43164..5048b170 100644 --- a/app/erpapi/lib/shop/matrix/taobao/request/logistics.php +++ b/app/erpapi/lib/shop/matrix/taobao/request/logistics.php @@ -22,10 +22,26 @@ class erpapi_shop_matrix_taobao_request_logistics extends erpapi_shop_request_logistics { /** - * 更新ReturnLogistics - * @param mixed $reshipinfo reshipinfo - * @return mixed 返回值 + * 回告淘宝加急发货订单在 OMS 当前节点下的物流状态。 + * + * @param array $sdf + * @param bool $queue + * @return array */ + public function order_report($sdf, $queue = false) + { + $args = func_get_args(); + array_pop($args); + $_in_mq = $this->__caller->caller_into_mq('logistics_order_report', 'shop', $this->__channelObj->channel['shop_id'], $args, $queue); + if ($_in_mq) { + return $this->succ('成功放入队列'); + } + + $params = $this->buildUrgentOrderReportRequestParams($sdf); + + $title = sprintf('淘宝加急发货状态回告[%s:%s]', $sdf['tid'], $sdf['orderStatus']); + return $this->__caller->call(SHOP_LOGISTICS_ORDER_REPORT, $params, array (), $title, 10, $sdf['tid']); + } public function updateReturnLogistics($reshipinfo) { $orderModel = app::get('ome')->model('orders'); @@ -54,11 +70,6 @@ class erpapi_shop_matrix_taobao_request_logistics extends erpapi_shop_request_lo return $rs; } - /** - * 获取CorpServiceCode - * @param mixed $sdf sdf - * @return mixed 返回结果 - */ public function getCorpServiceCode($sdf) { $params = array( 'cp_code' => $sdf['cp_code'] @@ -68,11 +79,6 @@ class erpapi_shop_matrix_taobao_request_logistics extends erpapi_shop_request_lo return $result; } - /** - * timerule - * @param mixed $sdf sdf - * @return mixed 返回值 - */ public function timerule($sdf) { $params = [ @@ -87,4 +93,4 @@ class erpapi_shop_matrix_taobao_request_logistics extends erpapi_shop_request_lo $result = $this->__caller->call(TAOBAO_COMMON_TOP_SEND,$params,array(),$title, 10, $this->__channelObj->channel['shop_bn']); return $result; } -} \ No newline at end of file +} diff --git a/app/erpapi/lib/shop/matrix/tmall/request/logistics.php b/app/erpapi/lib/shop/matrix/tmall/request/logistics.php index 74fa46ef..4201a9a3 100644 --- a/app/erpapi/lib/shop/matrix/tmall/request/logistics.php +++ b/app/erpapi/lib/shop/matrix/tmall/request/logistics.php @@ -18,13 +18,30 @@ * @author ykm 2017/2/16 * @describe 物流相关 请求接口类 */ + class erpapi_shop_matrix_tmall_request_logistics extends erpapi_shop_request_logistics { /** - * 获取CorpServiceCode - * @param mixed $sdf sdf - * @return mixed 返回结果 + * 回告天猫加急发货订单在 OMS 当前节点下的物流状态。 + * + * @param array $sdf + * @param bool $queue + * @return array */ + public function order_report($sdf, $queue = false) + { + $args = func_get_args(); + array_pop($args); + $_in_mq = $this->__caller->caller_into_mq('logistics_order_report', 'shop', $this->__channelObj->channel['shop_id'], $args, $queue); + if ($_in_mq) { + return $this->succ('成功放入队列'); + } + + $params = $this->buildUrgentOrderReportRequestParams($sdf); + + $title = sprintf('天猫加急发货状态回告[%s:%s]', $sdf['tid'], $sdf['orderStatus']); + return $this->__caller->call(SHOP_LOGISTICS_ORDER_REPORT, $params, array (), $title, 10, $sdf['tid']); + } public function getCorpServiceCode($sdf) { $params = array( @@ -36,11 +53,6 @@ class erpapi_shop_matrix_tmall_request_logistics extends erpapi_shop_request_log return $result; } - /** - * timerule - * @param mixed $sdf sdf - * @return mixed 返回值 - */ public function timerule($sdf) { $params = [ @@ -55,4 +67,4 @@ class erpapi_shop_matrix_tmall_request_logistics extends erpapi_shop_request_log $result = $this->__caller->call(TAOBAO_COMMON_TOP_SEND,$params,array(),$title, 10, $this->__channelObj->channel['shop_bn']); return $result; } -} \ No newline at end of file +} diff --git a/app/erpapi/lib/shop/response/components/order/items.php b/app/erpapi/lib/shop/response/components/order/items.php index e7559c92..84e0dfbc 100644 --- a/app/erpapi/lib/shop/response/components/order/items.php +++ b/app/erpapi/lib/shop/response/components/order/items.php @@ -330,6 +330,8 @@ class erpapi_shop_response_components_order_items extends erpapi_shop_response_c } } + $object_addon = $this->_formatObjectAddon($object); + $this->_platform->_newOrder['order_objects'][] = array( 'obj_type' => $obj_type ? $obj_type : 'goods', 'obj_alias' => $object['obj_alias'] ? $object['obj_alias'] : $objTypeList[$obj_type], @@ -374,7 +376,7 @@ class erpapi_shop_response_components_order_items extends erpapi_shop_response_c 'main_oid' => $gift_mids, 'biz_delivery_type' => ($logisObjInfo['biz_delivery_type'] ? $logisObjInfo['biz_delivery_type'] : 0), //择配建议 'object_bool_type' => $objectBoolType, - 'addon' => is_array($object['addon']) ? json_encode($object['addon']) : $object['addon'], //扩展信息 + 'addon' => $object_addon, //扩展信息 'customization' => $object['customization'], //商品定制信息 'is_sales_material_setmapping' => $is_setmapping, // 是否SET商品映射 ); @@ -410,6 +412,81 @@ class erpapi_shop_response_components_order_items extends erpapi_shop_response_c } } + /** + * 格式化订单对象扩展信息。 + * + * 微信视频号失败订单恢复时需要重建 item,提前备份原始平台商品和 SKU 信息, + * 避免恢复后发货回写缺少 sku_id。 + * + * @param array $object 平台订单对象明细 + * @return string + */ + private function _formatObjectAddon($object) + { + $addon = $object['addon']; + if ($this->_platform->_newOrder['shop_type'] != 'wxshipin') { + return is_array($addon) ? json_encode($addon) : $addon; + } + + // 微信视频号失败订单可能因销售物料不存在而无法生成 item 层。 + // 先把原始平台 SKU 信息备份到 object addon,供失败订单恢复重建 item 时继承。 + $platformItems = $this->_getWxshipinPlatformItems($object); + if (!$platformItems) { + return is_array($addon) ? json_encode($addon) : $addon; + } + + if (is_array($addon)) { + $addonData = $addon; + } else { + $addonData = $addon ? json_decode($addon, true) : array(); + if (!is_array($addonData)) { + $addonData = array(); + } + } + $addonData['wxshipin_platform_items'] = $platformItems; + + return json_encode($addonData, JSON_UNESCAPED_UNICODE); + } + + private function _getWxshipinPlatformItems($object) + { + $items = array(); + // formatItemsSdf 会把单 item 订单合并到 object 层,并移除 order_items。 + // 因此这里同时兼容 object 层和原始 item 层的平台 SKU,避免失败订单恢复时丢失 sku_id。 + $shopProductId = ($object['shop_product_id'] && $object['shop_product_id'] != '0') ? $object['shop_product_id'] : ''; + foreach ((array)$object['order_items'] as $item) { + if (!$shopProductId && $item['shop_product_id'] && $item['shop_product_id'] != '0') { + $shopProductId = $item['shop_product_id']; + } + + $items[] = array( + 'bn' => $item['bn'], + 'shop_goods_id' => $item['shop_goods_id'] ? $item['shop_goods_id'] : $object['shop_goods_id'], + 'shop_product_id' => $item['shop_product_id'], + 'oid' => $object['oid'], + ); + } + if (!$items && $shopProductId) { + $items[] = array( + 'bn' => $object['bn'], + 'shop_goods_id' => $object['shop_goods_id'], + 'shop_product_id' => $shopProductId, + 'oid' => $object['oid'], + ); + } + + if (!$items && !$shopProductId) { + return array(); + } + + return array( + 'shop_goods_id' => $object['shop_goods_id'], + 'shop_product_id' => $shopProductId, + 'oid' => $object['oid'], + 'items' => $items, + ); + } + /** * 更新订单明细 * diff --git a/app/erpapi/lib/shop/response/delivergoods.php b/app/erpapi/lib/shop/response/delivergoods.php index e4b6aeb4..8edf6a64 100644 --- a/app/erpapi/lib/shop/response/delivergoods.php +++ b/app/erpapi/lib/shop/response/delivergoods.php @@ -22,6 +22,9 @@ */ class erpapi_shop_response_delivergoods extends erpapi_shop_response_abstract { + const URGENT_SERVICE_TAG = '加急发货'; + const URGENT_ORDER_FIELDS = 'order_id, order_bn, process_status, status, ship_status, order_bool_type, shop_id, shop_type, source, createway, sync, sync_fail_type, abnormal, pause, timing_confirm, pay_status, is_cod, order_type, logi_no,last_modified'; + /** * 接收参数 */ @@ -36,41 +39,203 @@ class erpapi_shop_response_delivergoods extends erpapi_shop_response_abstract */ public function urgent($params){ $tid = $params['tid']; + $serviceTags = $this->normalizeServiceTags($params['service_tags']); + $isUrgentShip = in_array(self::URGENT_SERVICE_TAG, $serviceTags, true); - $this->__apilog['title'] = sprintf('催发货[%s]', $tid); + $this->__apilog['title'] = sprintf('%s[%s]', $isUrgentShip ? '淘宝加急发货' : '催发货', $tid); $this->__apilog['original_bn'] = $tid; $this->__apilog['result']['data'] = array('tid' => $tid); if (!$tid) { - $this->__apilog['result']['msg'] = '缺少订单号'; + $this->__apilog['result'] = $this->buildFailResult('PARAM_ERROR', '缺少订单号', false, $tid); return false; } $shop_id = $this->__channelObj->channel['shop_id']; + $sellerId = trim((string)($params['seller_id'] ?: $params['sellerId'])); //检查订单 - $orderMdl = app::get('ome')->model('orders'); - $order = $this->getOrder('order_id, order_bn, process_status, status, ship_status, order_bool_type, shop_id', $shop_id, $tid); + $order = $isUrgentShip + ? $this->getLocalOrder(self::URGENT_ORDER_FIELDS, $shop_id, $tid) + : $this->getOrder(self::URGENT_ORDER_FIELDS, $shop_id, $tid); if (!$order) { - $this->__apilog['result']['msg'] = 'ERP不存在此单'; + $this->__apilog['result'] = $this->buildFailResult('ORDER_NOT_FOUND', 'ERP不存在此单', false, $tid); + return false; + } + + if ($isUrgentShip && $sellerId && !$this->isMatchedSellerId($shop_id, $sellerId)) { + $this->__apilog['result'] = $this->buildFailResult('INVALID_SELLER_ID', 'seller_id与店铺不匹配', false, $tid); return false; } if($order['status'] == 'dead'){ - $this->__apilog['result']['msg'] = '订单已作废'; + $this->__apilog['result'] = $this->buildFailResult('ORDER_CANCELLED', '订单已作废', false, $tid); return false; } if ($order['ship_status'] == '1') { - $this->__apilog['result']['msg'] = '订单已经发货'; + $this->__apilog['result'] = $this->buildFailResult('ORDER_ALREADY_SHIPPED', '订单已经发货', false, $tid); return false; } - + + $order['service_tags'] = $serviceTags; + $order['is_urgent_ship'] = $isUrgentShip ? 'true' : 'false'; $order['seller_name'] = $params['seller_name']; $order['logistics_time'] = $params['logistics_time']; + $order['notify_time'] = $params['notify_time']; + $order['estimated_delivery_time'] = $params['estimated_delivery_time']; return $order; } + + /** + * 统一规整矩阵透传的 service_tags。 + * + * 当前联调约定优先传一维数组;如果上游仍传字符串,则先尝试按 JSON 解码成数组后再使用。 + * + * @param mixed $serviceTags + * @return array + */ + protected function normalizeServiceTags($serviceTags) + { + if (is_string($serviceTags)) { + $serviceTags = trim($serviceTags); + if ($serviceTags === '') { + return []; + } + + $decodedServiceTags = json_decode($serviceTags, true); + if (json_last_error() === JSON_ERROR_NONE && is_array($decodedServiceTags)) { + $serviceTags = $decodedServiceTags; + } else { + return [$serviceTags]; + } + } + + if (!is_array($serviceTags)) { + return []; + } + + $normalized = []; + foreach ($serviceTags as $serviceTag) { + if (is_scalar($serviceTag)) { + $serviceTag = trim((string)$serviceTag); + if ($serviceTag !== '') { + $normalized[] = $serviceTag; + } + } + } + + return array_values(array_unique($normalized)); + } + + /** + * 查询本地或归档订单,供加急发货场景做订单校验。 + * + * @param string $field + * @param int $shopId + * @param string $orderBn + * @return array|false + */ + protected function getLocalOrder($field, $shopId, $orderBn) + { + $orderModel = app::get('ome')->model('orders'); + $orders = $orderModel->getList($field, array ('order_bn' => $orderBn, 'shop_id' => $shopId), 0, 1); + if ($orders) { + if ($orders[0]['order_type'] == 'brush') { + return false; + } + return $orders[0]; + } + + $archiveFields = $this->normalizeArchiveFields($field); + $archiveOrders = app::get('archive')->model('orders')->getList($archiveFields, array ('order_bn' => $orderBn, 'shop_id' => $shopId), 0, 1); + if (!$archiveOrders) { + return false; + } + + $order = $archiveOrders[0]; + if ($order['order_type'] == 'brush') { + return false; + } + + $defaults = array ( + 'order_bool_type' => 0, + 'sync' => 'fail', + 'sync_fail_type' => 'none', + 'abnormal' => 'false', + 'pause' => 'false', + 'timing_confirm' => 0, + 'pay_status' => (string)$order['pay_status'], + 'is_cod' => (string)$order['is_cod'], + 'logi_no' => '', + 'tran_type' => 'archive', + ); + + return array_merge($defaults, $order); + } + + /** + * 过滤归档订单可查询字段,避免按正式订单字段直接查归档表。 + * + * @param string $field + * @return string + */ + protected function normalizeArchiveFields($field) + { + $available = array ( + 'order_id', 'order_bn', 'process_status', 'status', 'ship_status', 'shop_id', 'shop_type', + 'source', 'createway', 'pay_status', 'is_cod', 'order_type' + ); + $fields = preg_split('/\s*,\s*/', $field); + $fields = array_values(array_intersect($fields, $available)); + if (!in_array('order_id', $fields)) { + $fields[] = 'order_id'; + } + return implode(',', $fields); + } + + /** + * 校验平台传入 seller_id 是否匹配当前店铺绑定的卖家身份。 + * + * @param int $shopId + * @param string $sellerId + * @return bool + */ + protected function isMatchedSellerId($shopId, $sellerId) + { + $shop = app::get('ome')->model('shop')->dump($shopId, 'addon'); + $addon = (array)$shop['addon']; + $candidateIds = array_filter(array ( + (string)$addon['tb_user_id'], + (string)$addon['user_id'], + (string)$addon['seller_id'], + )); + if (!$candidateIds) { + return true; + } + return in_array((string)$sellerId, $candidateIds, true); + } + + /** + * 统一构造催发货/加急发货失败响应。 + * + * @param string $errorCode + * @param string $msg + * @param bool $retry + * @param string $tid + * @return array + */ + protected function buildFailResult($errorCode, $msg, $retry = false, $tid = '') + { + return [ + 'rsp' => 'fail', + 'msg' => $msg, + 'error_code' => $errorCode, + 'retry' => $retry ? 'true' : 'false', + 'data' => ['tid' => $tid], + ]; + } /** * 获取数据 diff --git a/app/erpapi/lib/shop/response/order.php b/app/erpapi/lib/shop/response/order.php index ff9e05bc..d6e255fc 100755 --- a/app/erpapi/lib/shop/response/order.php +++ b/app/erpapi/lib/shop/response/order.php @@ -1662,6 +1662,12 @@ class erpapi_shop_response_order extends erpapi_shop_response_abstract if($oaid){ //consignee foreach ($this->_ordersdf['consignee'] as $key => $value) { + // 指定字段不参与 oaid 加密拼接 + //@todo:sdb_ome_member_address数据库表中ship_email字段只有150个字符长度,不能使用oaid进行加密拼接; + if (in_array($key, ['email', 'zip', 'ship_zip'])) { + continue; + } + if(strpos($value, '*') !== false) { $this->_ordersdf['consignee'][$key] .= '>>' . $oaid . $hashCode; }elseif($key == 'mobile' && $receiver_mobile_index){ diff --git a/app/erpapi/lib/shop/response/params/aftersalev2.php b/app/erpapi/lib/shop/response/params/aftersalev2.php index ca1c0fef..b5d24a44 100644 --- a/app/erpapi/lib/shop/response/params/aftersalev2.php +++ b/app/erpapi/lib/shop/response/params/aftersalev2.php @@ -117,7 +117,7 @@ class erpapi_shop_response_params_aftersalev2 extends erpapi_shop_response_param } //检查更新时间是否变化 - if($sdf['modified'] <= $refundApply['outer_lastmodify']) { + if($sdf['modified'] < $refundApply['outer_lastmodify']) { return array('rsp' => 'fail', 'msg' => '更新时间未变化,不更新'); } } diff --git a/app/erpapi/lib/shop/response/process/aftersalev2.php b/app/erpapi/lib/shop/response/process/aftersalev2.php index af2e9ce1..f7924794 100644 --- a/app/erpapi/lib/shop/response/process/aftersalev2.php +++ b/app/erpapi/lib/shop/response/process/aftersalev2.php @@ -156,6 +156,10 @@ class erpapi_shop_response_process_aftersalev2 { } private function _getRefundRefer($sdf) { + $refundApply = $sdf['refund_apply']; + if($refundApply && $refundApply['reship_id']) { + return '1'; + } //退款来源(normal:普通退款,aftersale:售后仅退款,不退货;) if($sdf['refund_refer'] == 'aftersale'){ $refund_refer = '1'; @@ -412,6 +416,9 @@ class erpapi_shop_response_process_aftersalev2 { //退款未退货 $this->_refundNoreturn($sdf,$refundApply); kernel::single('monitor_notice_refund_apply')->erpapi_refund($refundApply['apply_id']); + if ($orderInfo['pay_status'] == '5') { + kernel::single('ome_event_trigger_shop_order')->order_message_produce(array($orderInfo['order_id']),['cancel_order']); + } kernel::single('ome_refund_apply')->updateOrderObjectsPayStatusByItemIds($refundApply['apply_id']); // 增加service扩展点,允许外部service在退款成功后做自定义处理 diff --git a/app/erpapi/lib/shop/response/process/delivergoods.php b/app/erpapi/lib/shop/response/process/delivergoods.php index 4f3d36ec..89ef3e0e 100644 --- a/app/erpapi/lib/shop/response/process/delivergoods.php +++ b/app/erpapi/lib/shop/response/process/delivergoods.php @@ -16,19 +16,40 @@ */ /** * 订单催发货 - * + * * @author wangbiao * @version 0.1 */ class erpapi_shop_response_process_delivergoods extends erpapi_shop_response_abstract { - /** - * urgent - * @param mixed $order order - * @return mixed 返回值 - */ + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; + const URGENT_SERVICE_TAG = '加急发货'; + const URGENT_REPORT_TASK_NOTIFY = 'urgent_logistics_notify'; + const URGENT_REPORT_TASK_DELIVERY = 'urgent_logistics_dly'; + const URGENT_REPORT_TASK_CONSIGN = 'urgent_logistics_csg'; + /** + * 根据 service_tags 分流普通催发货与淘宝加急发货处理。 + * + * @param array $order + * @return array + */ public function urgent($order) + { + if ($this->isUrgentShip($order)) { + return $this->processUrgentShip($order); + } + + return $this->processLegacyRemindShip($order); + } + + /** + * 兼容老的催发货逻辑,仅更新催发货标记和返回平台所需状态。 + * + * @param array $order + * @return array + */ + protected function processLegacyRemindShip($order) { //更新订单为"催发货"状态 $orderMdl = app::get('ome')->model('orders'); @@ -99,15 +120,178 @@ class erpapi_shop_response_process_delivergoods extends erpapi_shop_response_abs } /** - * promise - * @param mixed $sdf sdf - * @return mixed 返回值 + * 处理淘宝加急发货通知:订单/发货单打标、加速审单,并投递状态回告任务。 + * + * @param array $order + * @return array */ - public function promise($sdf) { - if($sdf['event_type'] == 'latest_delivery_time') { - $orderExtendObj = app::get('ome')->model('order_extend'); - $extendinfo = [ - 'order_id' => $sdf['order']['order_id'], + protected function processUrgentShip($order) + { + try { + if (!$this->isUrgentShip($order)) { + return $this->fail('PARAM_ERROR', 'service_tags非法', false, $order['order_bn']); + } + + $labelLib = kernel::single('ome_bill_label'); + $deliveryMdl = app::get('ome')->model('delivery'); + $deliveryIds = $deliveryMdl->getDeliverIdByOrderId($order['order_id']); + $alreadyMarked = $labelLib->existLabel($order['order_id'], self::URGENT_LABEL_CODE); + + if (!$alreadyMarked) { + $err = ''; + $markResult = $labelLib->markBillLabel($order['order_id'], '', self::URGENT_LABEL_CODE, 'order', $err); + if (!$markResult) { + return $this->fail('SYSTEM_ERROR', $err ?: '订单加急标签写入失败', true, $order['order_bn']); + } + } + if ($deliveryIds) { + foreach ((array)$deliveryIds as $deliveryId) { + $err = ''; + $labelLib->markBillLabel($deliveryId, '', self::URGENT_LABEL_CODE, 'delivery', $err); + } + } + + if (!$alreadyMarked) { + $memo = '淘宝加急发货: 平台加急发货通知'; + if (!empty($order['notify_time'])) { + $memo .= ',通知时间:' . $order['notify_time']; + } + app::get('ome')->model('operation_log')->write_log('order_modify@ome', $order['order_id'], $memo); + } + + $this->accelerateTimingConfirm($order); + + $urgentLib = kernel::single('ome_order_urgent'); + $statusPayload = $urgentLib->buildUrgentOrderStatus($order['order_id']); + if (empty($statusPayload['orderStatus'])) { + return $this->fail('SYSTEM_ERROR', '订单状态计算失败', true, $order['order_bn']); + } + + $this->enqueueUrgentReport($order['order_id'], 'notify'); + + $responseParams = $urgentLib->buildUrgentNotifyResponseParams($order['order_id'], $order['order_bn']); + if (empty($responseParams['urgent_delivery_notify_response'])) { + $dtoJson = json_encode( + $urgentLib->formatUrgentOrderReportDto($statusPayload, $order['order_bn']), + JSON_UNESCAPED_UNICODE + ); + if ($dtoJson !== false) { + $responseParams = ['urgent_delivery_notify_response' => $dtoJson]; + } + } + + return [ + 'rsp' => 'succ', + 'msg' => $alreadyMarked ? '淘宝加急发货: 幂等成功' : '淘宝加急发货: 打标成功', + 'data' => $responseParams, + ]; + } catch (Exception $e) { + return $this->fail('SYSTEM_ERROR', $e->getMessage(), true, $order['order_bn']); + } + } + + /** + * 判断当前通知是否属于淘宝加急发货。 + * + * @param array $order + * @return bool + */ + protected function isUrgentShip($order) + { + if (!is_array($order['service_tags'])) { + $serviceTags = trim((string)$order['service_tags']); + return $serviceTags !== '' && $serviceTags === self::URGENT_SERVICE_TAG; + } + + return in_array(self::URGENT_SERVICE_TAG, $order['service_tags'], true); + } + + /** + * 统一构造加急发货处理失败响应。 + * + * @param string $errorCode + * @param string $msg + * @param bool $retry + * @param string $tid + * @return array + */ + protected function fail($errorCode, $msg, $retry = false, $tid = '') + { + return [ + 'rsp' => 'fail', + 'error_code' => $errorCode, + 'msg' => $msg, + 'retry' => $retry ? 'true' : 'false', + 'data' => ['tid' => $tid], + ]; + } + + /** + * 对满足自动审单条件的加急订单,直接将定时审单时间改写到当前调度时间。 + * + * @param array $order + * @return void + */ + protected function accelerateTimingConfirm($order) + { + $now = time()+30; + if ($order['pause'] !== 'false' || $order['abnormal'] !== 'false') { + return; + } + if (!in_array($order['process_status'], ['unconfirmed', 'confirmed', 'splitting'])) { + return; + } + if (!in_array($order['ship_status'], ['0', '2'])) { + return; + } + $isAuto = ($order['pay_status'] == '1' || $order['is_cod'] == 'true') + && $order['status'] == 'active' + && in_array($order['order_type'], kernel::single('ome_order_func')->get_normal_order_type()); + if (!$isAuto) { + return; + } + + app::get('ome')->model('orders')->update(['timing_confirm' => $now], ['order_id' => $order['order_id']]); + app::get('ome')->model('misc_task')->saveMiscTask([ + 'obj_id' => $order['order_id'], + 'obj_type' => 'timing_confirm_order', + 'exec_time' => $now, + 'addon' => json_encode(['urgent_delivery' => true]), + ]); + app::get('ome')->model('operation_log')->write_log('order_edit@ome', $order['order_id'], '淘宝加急发货: 提前定时审单时间至当前'); + } + + /** + * 根据场景补投加急发货状态回告任务。 + * + * @param int $orderId + * @param string $scene + * @return bool + */ + protected function enqueueUrgentReport($orderId, $scene) + { + if (!$orderId) { + return false; + } + $taskTypeMap = [ + 'notify' => self::URGENT_REPORT_TASK_NOTIFY, + 'delivery_status' => self::URGENT_REPORT_TASK_DELIVERY, + 'consign_sync' => self::URGENT_REPORT_TASK_CONSIGN, + ]; + return app::get('ome')->model('misc_task')->saveMiscTask([ + 'obj_id' => intval($orderId), + 'obj_type' => $taskTypeMap[$scene] ?: self::URGENT_REPORT_TASK_NOTIFY, + 'exec_time' => time(), + 'addon' => json_encode(['scene' => $scene], JSON_UNESCAPED_UNICODE), + ]); + } + + public function promise($sdf) + { + if ($sdf['event_type'] == 'latest_delivery_time') { + $orderExtendObj = app::get('ome')->model('order_extend'); + $extendinfo = [ + 'order_id' => $sdf['order']['order_id'], 'latest_delivery_time' => kernel::single('ome_func')->date2time($sdf['pick_date']) ]; $orderExtendObj->save($extendinfo); diff --git a/app/erpapi/lib/shop/whitelist.php b/app/erpapi/lib/shop/whitelist.php index c431e80f..5cec284a 100755 --- a/app/erpapi/lib/shop/whitelist.php +++ b/app/erpapi/lib/shop/whitelist.php @@ -295,6 +295,7 @@ class erpapi_shop_whitelist { SHOP_WLB_ORDER_JZPARTNER_QUERY, SHOP_WLB_ORDER_JZWITHINS_CONSIGN, SHOP_TMC_MESSAGE_PRODUCE, + SHOP_LOGISTICS_ORDER_REPORT, SHOP_LOGISTICS_DUMMY_SEND, SHOP_LOGISTICS_ADDRESS_SEARCH, SHOP_BILL_BOOK_BILL_GET, @@ -494,6 +495,7 @@ class erpapi_shop_whitelist { SHOP_LOGISTICS_OFFLINE_SEND, SHOP_UPDATE_ITEMS_QUANTITY_LIST_RPC, SHOP_REFUND_CHECK, + SHOP_RETURN_GOOD_CONFIRM, SHOP_OUT_BRANCH, JD_COMMON_TOP_SEND, SHOP_JDGXD_LOGISTICS_FULFILLMENT_INFO, diff --git a/app/erpapi/lib/system/response/msg.php b/app/erpapi/lib/system/response/msg.php index 4894b0b1..b5c0828d 100644 --- a/app/erpapi/lib/system/response/msg.php +++ b/app/erpapi/lib/system/response/msg.php @@ -33,7 +33,12 @@ class erpapi_system_response_msg extends erpapi_system_response_abstract return false; } - $content = json_decode($params['data'],true); + $content = is_array($params['data']) ? $params['data'] : json_decode($params['data'], true); + if (!is_array($content)) { + $this->__apilog['result']['msg'] = '消息内容格式错误'; + return false; + } + $content['node_id'] = $params['to_node_id']; $sdf = array( 'node_id' => $params['node_id'], diff --git a/app/erpapi/lib/system/response/process/msg.php b/app/erpapi/lib/system/response/process/msg.php index 1dcf9dc7..377bcec2 100644 --- a/app/erpapi/lib/system/response/process/msg.php +++ b/app/erpapi/lib/system/response/process/msg.php @@ -17,23 +17,24 @@ class erpapi_system_response_process_msg { - /** - * notify - * @param mixed $sdf sdf - * @return mixed 返回值 - */ + const SESSION_EXPIRE_WARNING_DAYS = 7; + public function notify($sdf) { if (!$sdf['node_id']) { - array('rsp' => 'fail', 'msg' => '节点不能为空'); + return array('rsp' => 'fail', 'msg' => '节点不能为空'); } $shopMdl = app::get('ome')->model('shop'); $shop = $shopMdl->dump(array('node_id' => $sdf['node_id']), 'shop_id,addon,name'); - + if (!$shop) { - array('rsp' => 'fail', 'msg' => '店铺未绑定'); + return array('rsp' => 'fail', 'msg' => '店铺未绑定'); + } + + if (isset($sdf['content']['access_token_available'])) { + return $this->processAccessTokenNotify($shopMdl, $shop, $sdf); } $rpcNotifyMdl = app::get('base')->model('rpcnotify'); @@ -53,4 +54,47 @@ class erpapi_system_response_process_msg return array('rsp' => 'succ', 'msg' => '消息已接收'); } + + protected function processAccessTokenNotify($shopMdl, $shop, $sdf) + { + $tokenAvailable = (string) $sdf['content']['access_token_available']; + if ($tokenAvailable === '-1') { + $warnMsg = '【' . $shop['name'] . '】 access_token 已失效,请及时处理,'.(isset($sdf['content']['info']) && !empty($sdf['content']['info']) ? $sdf['content']['info'] : '') ; + $this->sendSystemNotify($warnMsg); + + return array('rsp' => 'succ', 'msg' => '消息已接收'); + } + + if ($tokenAvailable !== '1') { + return array('rsp' => 'succ', 'msg' => '消息已接收'); + } + + $expireTime = trim((string) $sdf['content']['access_token_expire_in']); + if (!$expireTime) { + return array('rsp' => 'fail', 'msg' => 'access_token_expire_in不能为空'); + } + + $expireTimestamp = strtotime($expireTime); + if (!$expireTimestamp) { + return array('rsp' => 'fail', 'msg' => 'access_token_expire_in格式错误'); + } + + $addon = is_array($shop['addon']) ? $shop['addon'] : array(); + $addon['session_expire_time'] = $expireTimestamp; + $shopMdl->update(array('addon' => $addon), array('shop_id' => $shop['shop_id'])); + + if (($expireTimestamp - time()) < self::SESSION_EXPIRE_WARNING_DAYS * 86400) { + $warnMsg = '【' . $shop['name'] . '】 access_token 将于7天内过期,请及时处理,到期时间:'.$expireTime.(isset($sdf['content']['info']) && !empty($sdf['content']['info']) ? $sdf['content']['info'] : '') ; + $this->sendSystemNotify($warnMsg); + } + + return array('rsp' => 'succ', 'msg' => '消息已接收'); + } + + protected function sendSystemNotify($message) + { + kernel::single('monitor_event_notify')->addNotify('system_message', [ + 'errmsg' => $message, + ]); + } } diff --git a/app/erpapi/lib/wms/matrix/qimen/request/delivery.php b/app/erpapi/lib/wms/matrix/qimen/request/delivery.php index a0e0204f..a80ce7b1 100644 --- a/app/erpapi/lib/wms/matrix/qimen/request/delivery.php +++ b/app/erpapi/lib/wms/matrix/qimen/request/delivery.php @@ -24,6 +24,7 @@ */ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delivery { + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; private $_shop_type_mapping = array( 'taobao' => 'TB', 'paipai' => 'PP', @@ -51,7 +52,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive 'xhs' => 'XHS', 'weimobv' => 'WM', 'weimobr' => 'WM', - 'xiaomi' => 'XMYP', + 'xiaomi' => 'XMYP', 'dewu' => 'DW', 'wxshipin' => 'WXSPHXD', 'aikucun' => 'AKC', @@ -92,11 +93,11 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive if(kernel::single('ome_security_router',$sdf['shop_type'])->is_encrypt($sdf,'delivery')) { $this->is_platform_encrypt = true; } - + //oaid if(in_array($sdf['shop_type'], array('taobao','360buy', 'jd', 'wxshipin')) && $sdf['encrypt_source_data']['oaid']) { $sdf['oaid'] = $sdf['encrypt_source_data']['oaid']; - + // consignee foreach ($sdf['consignee'] as $dk => $dv) { if(is_string($dv) && $index = strpos($dv , '>>')) { @@ -108,7 +109,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive // alibaba解密用origin_caid_field,可参考ome_security_alibaba->get_encrypt_body if(in_array($sdf['shop_type'], array('alibaba')) && $sdf['encrypt_source_data']['origin_caid_field']) { $sdf['oaid'] = $sdf['encrypt_source_data']['origin_caid_field']; - + // consignee foreach ($sdf['consignee'] as $dk => $dv) { if(is_string($dv) && $index = strpos($dv , '>>')) { @@ -116,7 +117,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive } } } - + if( in_array($sdf['shop_type'], array('taobao')) ) { foreach ($sdf['consignee'] as $dk => $dv) { if(is_string($dv) && $index = strpos($dv , '>>')) { @@ -133,7 +134,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive if (in_array($sdf['shop_type'], array('xhs')) && $sdf['extend_field']['openAddressId']) { - + $sdf['oaid'] = $sdf['extend_field']['openAddressId']; } // 有些WMS还不支持oaid取号,所以也需要把密文推给他们 @@ -146,7 +147,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive protected function _format_delivery_create_params($sdf) { $appkey = $this->__channelObj->wms['addon']['wms_appkey']; - + $oaid = $sdf['oaid']; $params = parent::_format_delivery_create_params($sdf); $params['warehouse_code'] = $this->get_warehouse_code($this->__channelObj->wms['channel_id'],$sdf['branch_bn']); @@ -164,7 +165,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $params['shipper_address'] = $shop['addr']; $params['shipper_zip'] = $shop['zip']; $params['order_flag'] = ''; - + //泉峰的单独处理 if (base_shopnode::node_id('ome') == '1081190530') { //订单来源平台 @@ -176,23 +177,23 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive } else { $order_source = $this->_shop_type_mapping[$sdf['shop_type']]; $params['order_source'] = $order_source && $sdf['createway'] == 'matrix' ? $order_source : 'OTHER'; - + // 补发订单,如果关联的原订单是平台订单,则使用平台标识 if($sdf['order_type'] == 'bufa' && $sdf['relate_order_bn']){ // 获取关联的原订单信息 $relateOrderInfo = app::get('ome')->model('orders')->dump(array('order_bn'=>$sdf['relate_order_bn']), 'order_id,shop_type,createway'); if($relateOrderInfo && $relateOrderInfo['createway'] == 'matrix'){ $relate_order_source = $this->_shop_type_mapping[$relateOrderInfo['shop_type']]; - + // order_source $params['order_source'] = $relate_order_source ? $relate_order_source : $params['order_source']; } } - + //订单来源标识 if (($sdf['shop_type'] == 'taobao' && $sdf['shop_id'] && $sdf['createway'] == 'matrix') || ($sdf['order_source'] == 'platformexchange' && $order_source)) { //矩阵下发的淘宝订单 或 平台换货生成的新订单 - $params['order_source'] = $order_source; + $params['order_source'] = $order_source; //判断是不是天猫 $shopInfo = $shopObj->dump(array('shop_id'=>$sdf['shop_id'],'tbbusiness_type'=>'B')); if ($shopInfo) { @@ -241,7 +242,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive if($sdf['order_type'] == 'presale' && !in_array('PRESELL',$order_flag)){ $order_flag[] = 'PRESELL'; - } + } } // 天猫物流升级 if (kernel::single('ome_delivery_bool_type')->isCPUP($sdf['bool_type'])) { @@ -289,19 +290,19 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $extend_props['jdService'] = 'JDWJ_DELIVERY_TO_DOOR'; $order_flag[] = 'VISIT'; } - + //仓库自定义字段-活动号 if(isset($sdf['activity_no'])){ $extend_props['activity_no'] = $sdf['activity_no']; } - + //抖音自选物流发货 $labelCode = kernel::single('ome_bill_label')->getLabelFromOrder($sdf['delivery_id'], 'ome_delivery'); $labelCode = array_column($labelCode, 'label_code'); if (in_array(kernel::single('ome_bill_label')->isExpressMust(), (array)$labelCode)) { $order_flag[] = 'MODIFYTRANSPORT'; } - + // 国补订单(京东平台国补拍照信息:gov_photo_check) if(in_array($sdf['shop_type'], ['360buy', 'jd'])){ $guoBuLabelInfo = []; @@ -311,27 +312,33 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive if($orderInfo){ $guoBuLabelInfo = kernel::single('ome_bill_label')->getBillLabelInfo($orderInfo['order_id'], 'order', 'SOMS_GB'); } - + // 国补订单拍照信息 if($guoBuLabelInfo && $guoBuLabelInfo['label_value'] & 0x0400){ $extend_props['gov_photo_check'] = '国补拍照'; - + // flag $params['remark'] = '[国补拍照]'. $params['remark']; } } - + + if ($this->isUrgentDelivery($sdf)) { + $extend_props['urgent_delivery'] = true; + } + //是否是国补订单进行标识推送wms + $extend_props['isGuobuOrder'] = $sdf['is_guobu_order'] ?: 'false'; + $params['extendProps'] = json_encode($extend_props); $params['order_flag'] = implode(',', $order_flag); - + // 如果三级区不存在,直接使用二级市 $params['receiver_state'] = $this->_formate_receiver_province($params['receiver_state'],$params['receiver_district']); - + // oaid if($oaid) { // 是否密文标记 $params['is_platform_encrypt'] = $this->is_platform_encrypt; - + //[伊藤忠WMS]订单手工编辑收货人信息是明文时,不用传oaid if(in_array($appkey, array('31417025')) && $sdf['extend_status'] == 'consignee_modified' && !$this->is_platform_encrypt){ $params['receiver_oaid'] = ''; @@ -341,7 +348,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive }else{ $params['receiver_oaid'] = $oaid; } - + // tid if($sdf['extend_field']['oaidSourceCode']) { $params['tid'] = $sdf['extend_field']['oaidSourceCode']; @@ -397,16 +404,16 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $params = $this->_get_wms_cross_shop_waybill($params, $sdf); $params['seller_message'] = $sdf['memo']; - + //@todo:美诺WMS最多允许传255个字符(一个汉字为3个字符),超出部分需要截取,否则推送报错; if(strlen($params['seller_message']) > 255){ $params['seller_message'] = kernel::single('ome_func')->substrStringSafe($params['seller_message'], 255); } - + if(strlen($params['remark']) > 255){ $params['remark'] = kernel::single('ome_func')->substrStringSafe($params['remark'], 255); } - + $params['buyer_message'] = $sdf['custom_mark']; $receiver_name = $params['receiver_name']; @@ -414,7 +421,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $receiver_address = $params['receiver_address']; if ($receiver_address) $params['receiver_address'] = $receiver_address; - + //以product_id为键值组织货品明细(订单拆单后,回传奇门平台单号要唯一) $arrProductData = array(); if($sdf['order_objects']) @@ -424,14 +431,14 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive foreach ($objVal['order_items'] as $itemVal) { $product_id = $itemVal['product_id']; - + //根据订单类型,使用关联订单号 if(in_array($objVal['order_type'], array('bufa'))){ $relate_order_bn = ($objVal['relate_order_bn'] ? $objVal['relate_order_bn'] : $objVal['order_bn']); - + $arrProductData[$product_id]['order_bn'][$relate_order_bn] = $relate_order_bn; - + $sdf['order_bn'] = $relate_order_bn; // 补发单不推oaidOrderSourceCode @@ -445,7 +452,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive }else { $arrProductData[$product_id]['num'] = $itemVal['nums']; } - + $arrProductData[$product_id][$itemVal['item_id']]['oid'] = $itemVal['oid'] ? $itemVal['oid'] : uniqid(); $arrProductData[$product_id][$itemVal['item_id']]['shop_goods_id'] = $objVal['shop_goods_id']; } @@ -465,10 +472,10 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $detail_delivery_id = $tempItemVal['delivery_id']; $delivery_item_id = $tempItemVal['delivery_item_id']; $actually_amount = is_null($tempItemVal['actually_amount']) ? 0 : $tempItemVal['actually_amount']; - + // items $detailItems[$detail_delivery_id][$delivery_item_id] = $tempItemVal; - + // 按货号纬度累加:客户实付 if(!isset($detailItemBns[$product_bn])){ $detailItemBns[$product_bn] = [ @@ -477,13 +484,13 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive 'actually_amount' => 0, ]; } - + $detailItemBns[$product_bn]['number'] += $tempItemVal['number']; $detailItemBns[$product_bn]['actually_amount'] += $actually_amount; } - + $items = array('item'=>array()); $delivery_items = $sdf['delivery_items']; - + if ($delivery_items){ sort($delivery_items); foreach ($delivery_items as $k => $v) @@ -491,33 +498,33 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $product_bn = $v['bn']; $qimen_delivery_id = $v['qimen_delivery_id']; $delivery_item_id = $v['delivery_items_id']; - + // 客户实付(合并发货单,按货号纬度累加后的金额) $actually_amount = $detailItemBns[$product_bn]['actually_amount']; - + // foreign_sku $foreignsku = app::get('console')->model('foreign_sku')->dump(array('wms_id'=>$this->__channelObj->wms['channel_id'],'inner_sku'=>$v['bn'])); //订单拆单后,回传奇门平台单号要唯一 $productInfo = $arrProductData[$v['product_id']]; - + //取明细order_item_id //$items_detail = $shopObj->db->selectrow("SELECT order_item_id FROM sdb_ome_delivery_items_detail WHERE delivery_id=".$v['qimen_delivery_id']." AND delivery_item_id=".$v['delivery_items_id']); $items_detail = $detailItems[$qimen_delivery_id][$delivery_item_id]; - + //[兼容]合并发货单超过50个字符需要截取 if($appkey && in_array($appkey,array('31417025'))){ $trade_code = $sdf['order_bn']; }else{ $trade_code = current($productInfo['order_bn']); } - + $sub_trade_code = $productInfo[$items_detail['order_item_id']]['oid']; if($productInfo && ($v['number'] != $productInfo['num'])) { //$sub_trade_code .= '_'. $v['qimen_delivery_id']; } - + $_item = array( 'item_code' => $foreignsku['oms_sku'] ? $foreignsku['oms_sku'] : $v['bn'], 'item_name' => $v['product_name'], @@ -535,7 +542,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive 'ownerCode' => $sdf['owner_code'], 'item_actually_amount' => $actually_amount, // 客户实付 ); - + // 唯品会,判断是否有重点检查 if ($quality_check_itemcode && in_array($_item['item_code'], $quality_check_itemcode)) { $_item['extendProps'] = ['quality_check_itemcode'=>true]; @@ -543,14 +550,14 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $items['item'][] = $_item; } } - + //合并订单发货时,format格式化明细 //@todo:items明细中第一个订单号必须与receiver_address加密订单一致,否则第三方WMS无法解密; $orderBnList = explode('|', $sdf['order_bn']); if(count($orderBnList) > 1){ $items = $this->_formatMergeItems($sdf, $items); } - + //json $params['items'] = json_encode($items); @@ -574,10 +581,34 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $params['orig_order_code'] = $delivery['delivery_bn']; } $params['pay_time'] = $sdf['pay_time']; - + return $params; } - + + /** + * 判断当前发货单或关联订单是否已打上加急发货标签,用于透传 WMS。 + * + * @param array $sdf + * @return bool + */ + protected function isUrgentDelivery($sdf) + { + $labelLib = kernel::single('ome_bill_label'); + if (!empty($sdf['delivery_id']) && $labelLib->existLabel($sdf['delivery_id'], self::URGENT_LABEL_CODE, 'delivery')) { + return true; + } + if (!empty($sdf['order_id']) && $labelLib->existLabel($sdf['order_id'], self::URGENT_LABEL_CODE)) { + return true; + } + if (!empty($sdf['order_bn'])) { + $order = app::get('ome')->model('orders')->dump(['order_bn' => $sdf['order_bn']], 'order_id'); + if (!empty($order['order_id']) && $labelLib->existLabel($order['order_id'], self::URGENT_LABEL_CODE)) { + return true; + } + } + return false; + } + protected function _getNextObjType() { return ''; @@ -632,7 +663,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive } return $ret; } - + /** * 合并订单发货时,format格式化明细 * @todo:items明细中第一个订单号必须与receiver_address加密订单一致,否则第三方WMS无法解密; @@ -644,7 +675,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive public function _formatMergeItems($sdf, $items) { $first_order_bn = current(explode('|', $sdf['order_bn'])); - + $tempList = array(); $firstList = array(); foreach ($items['item'] as $itemKey => $itemVal) @@ -656,9 +687,9 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive $tempList[] = $itemVal; } } - + $items['item'] = array_merge($firstList, $tempList); - + return $items; } @@ -672,7 +703,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive { return WMS_PRESALES_PACKAGE_CONSIGN; } - + /** * 预售付尾款通知wms参数 * @@ -688,7 +719,7 @@ class erpapi_wms_matrix_qimen_request_delivery extends erpapi_wms_request_delive 'remark' => '', //备注 //'ownerCode' => $sdf['ownerCode'], //货主编码(此字段是矩阵取customerId字段的值) ); - + return $params; } diff --git a/app/erpapi/lib/wms/response/stockout.php b/app/erpapi/lib/wms/response/stockout.php index 7f077d52..3688de44 100644 --- a/app/erpapi/lib/wms/response/stockout.php +++ b/app/erpapi/lib/wms/response/stockout.php @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /** * 出库单 * @@ -114,7 +113,13 @@ class erpapi_wms_response_stockout extends erpapi_wms_response_abstract $val['batch'] = isset($val['batch']['batch'][0]) ? $val['batch']['batch'] : [$val['batch']['batch']]; foreach ($val['batch'] as $v) { if ($v['actualQty'] == 0) continue; - + + // 过滤掉batchCode批次号为空的记录 + //@todo:birkenStock客户反馈仓库那边有些商品不做批次管理,所以batchCode批次号为空; + if(empty($v['batchCode'])){ + continue; + } + $stockout_items[$val['product_bn']]['batch'][] = array( 'purchase_code' => $v['batchCode'], 'produce_code' => $v['produceCode'], diff --git a/app/erpapi/model/api/fail.php b/app/erpapi/model/api/fail.php index 5a1a2083..5bd9f13c 100644 --- a/app/erpapi/model/api/fail.php +++ b/app/erpapi/model/api/fail.php @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class erpapi_mdl_api_fail extends dbeav_model{ public $objTypeProperty = array( @@ -99,10 +98,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ ), ); - /** - * 获取ObjTypeText - * @return mixed 返回结果 - */ public function getObjTypeText() { $arrText = array(); foreach($this->objTypeProperty as $k => $val) { @@ -111,21 +106,11 @@ class erpapi_mdl_api_fail extends dbeav_model{ return $arrText; } - /** - * modifier_obj_type - * @param mixed $col col - * @return mixed 返回值 - */ public function modifier_obj_type($col) { return $this->objTypeProperty[$col] ? $this->objTypeProperty[$col]['text'] : $col; } - /** - * modifier_err_msg - * @param mixed $col col - * @return mixed 返回值 - */ public function modifier_err_msg($col){ $col = strip_tags($col); return sprintf("%s",$col, $col, $col); @@ -133,12 +118,12 @@ class erpapi_mdl_api_fail extends dbeav_model{ /** * 发布失败日志 - * + * * 已弃用 Thu May 5 11:04:32 2022 chenping@shopex.cn - * + * * @return void * @author - * */ + **/ public function publish_api_fail($method, $callback_params, $result) { @@ -200,10 +185,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ return true; } - /** - * 获取retryapiErrcode - * @return mixed 返回结果 - */ public function getretryapiErrcode(){ $errcode = kernel::single('erpapi_errcode')->errcode; @@ -222,15 +203,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ } //异步请求重试 重新组装数据 - /** - * 保存TriggerRequest - * @param mixed $objBn objBn - * @param mixed $objType objType - * @param mixed $api_method api_method - * @param mixed $errMsg errMsg - * @param mixed $sub_obj_bn sub_obj_bn - * @return mixed 返回操作结果 - */ public function saveTriggerRequest($objBn, $objType, $api_method='', $errMsg='', $sub_obj_bn = '') { $sdf = array( 'obj_bn' => $objBn, @@ -266,6 +238,7 @@ class erpapi_mdl_api_fail extends dbeav_model{ */ public function saveRunning($params) { $sdf = array( + 'method' => $params['method'], 'obj_bn' => $params['obj_bn'], 'obj_type' => $params['obj_type'], 'retry_params' => serialize(array( @@ -303,11 +276,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ } # 同步请求重试 不重新组装数据 - /** - * 保存SyncRequest - * @param mixed $params 参数 - * @return mixed 返回操作结果 - */ public function saveSyncRequest($params) { if($params['rsp'] == 'succ') { $this->delete(array('obj_bn'=>$params['obj_bn'], 'obj_type'=>$params['obj_type'])); @@ -343,14 +311,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ return false; } - /** - * dealCallback - * @param mixed $status status - * @param mixed $apiFailId ID - * @param mixed $msg msg - * @param mixed $msg_id ID - * @return mixed 返回值 - */ public function dealCallback($status,$apiFailId, $msg, $msg_id) { if(strpos($apiFailId, '-')) { list($id, $page) = explode('-', $apiFailId); @@ -402,13 +362,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ } } - /** - * 更新Fail - * @param mixed $id ID - * @param mixed $errMsg errMsg - * @param mixed $msgId ID - * @return mixed 返回值 - */ public function updateFail($id, $errMsg, $msgId) { $data = $this->getList('fail_times', array('id'=>$id), 0, 1); if(empty($data)) { @@ -425,11 +378,6 @@ class erpapi_mdl_api_fail extends dbeav_model{ } # 失败重试 - /** - * retry - * @param mixed $log log - * @return mixed 返回值 - */ public function retry($log) { $property = $this->objTypeProperty[$log['obj_type']]; diff --git a/app/finance/controller/monthend/verification.php b/app/finance/controller/monthend/verification.php index f1aaa921..a3f628ae 100644 --- a/app/finance/controller/monthend/verification.php +++ b/app/finance/controller/monthend/verification.php @@ -14,15 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class finance_ctl_monthend_verification extends desktop_controller{ - /** - * index - * @param mixed $monthly_id ID - * @return mixed 返回值 - */ public function index($monthly_id){ $base_filter = array(); @@ -45,10 +39,15 @@ class finance_ctl_monthend_verification extends desktop_controller{ $_GET['view'] = 0; } + $finder_id = isset($_GET['finder_id']) ? $_GET['finder_id'] : ''; + $finder_vid = isset($_GET['finder_vid']) ? $_GET['finder_vid'] : ''; + $return_view = isset($_GET['return_view']) ? $_GET['return_view'] : 0; + $return_page = isset($_GET['return_page']) ? $_GET['return_page'] : 1; + #增加销售应收单导出权限 $actions = array ( - '0' => array('label' => '返回', 'href' => 'index.php?app=finance&ctl=monthend&act=index&finder_id=' . $_GET['finder_id']), + '0' => array('label' => '返回', 'href' => 'index.php?app=finance&ctl=monthend&act=index&finder_id='.$finder_id.'&finder_vid='.$finder_vid.'&view='.$return_view.'&page='.$return_page), 'export' => array ( 'label' => '导出', 'class' => 'export', @@ -63,6 +62,12 @@ class finance_ctl_monthend_verification extends desktop_controller{ 'submit' => $this->url.'&act=ruleVerification&p[]='.$monthly_id.'&view='.$_GET['view'], 'target' => 'dialog::{width:600,height:300,title:\'规则核销\'}' ); + $actions['batch_verification'] = array( + 'label' => '批量核销', + 'href' => 'javascript:void(0);', + 'submit' => $this->url.'&act=batchVerificationDialog&p[]='.$monthly_id, + 'target' => 'dialog::{width:760,height:400,title:\'批量核销\'}', + ); $actions['import'] = array( 'label' => '导入差异类型', 'href' => 'index.php?app=finance&ctl=monthend_verification&act=displayImportV2&p[0]=finance_gap_type_import&finder_id={finder_id}&monthly_id='.$monthly_id, @@ -91,22 +96,21 @@ class finance_ctl_monthend_verification extends desktop_controller{ function _views(){ + $finder_id = isset($_GET['finder_id']) ? $_GET['finder_id'] : ''; + $finder_vid = isset($_GET['finder_vid']) ? $_GET['finder_vid'] : ''; + $return_view = isset($_GET['return_view']) ? $_GET['return_view'] : 0; + $return_page = isset($_GET['return_page']) ? $_GET['return_page'] : 1; + $return_params = '&finder_id='.$finder_id.'&finder_vid='.$finder_vid.'&return_view='.$return_view.'&return_page='.$return_page; $sub_menu = array( // 0 => array('label'=>app::get('base')->_('全部'),'filter'=>array('monthly_id'=>$this->report['monthly_id']),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=0'), - array('label'=>app::get('base')->_('未核销'),'filter'=>array('monthly_id'=>$this->report['monthly_id'],'verification_status'=>'1'),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=0'), + array('label'=>app::get('base')->_('未核销'),'filter'=>array('monthly_id'=>$this->report['monthly_id'],'verification_status'=>'1'),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=0'.$return_params), // array('label'=>app::get('base')->_('部分核销'),'filter'=>array('monthly_id'=>$this->report['monthly_id'],'status'=>1),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=1'), - array('label'=>app::get('base')->_('已核销'),'filter'=>array('monthly_id'=>$this->report['monthly_id'],'verification_status'=>'2'),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=1'), - array('label'=>app::get('base')->_('全部'),'filter'=>array('monthly_id'=>$this->report['monthly_id']),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=2'), + array('label'=>app::get('base')->_('已核销'),'filter'=>array('monthly_id'=>$this->report['monthly_id'],'verification_status'=>'2'),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=1'.$return_params), + array('label'=>app::get('base')->_('全部'),'filter'=>array('monthly_id'=>$this->report['monthly_id']),'addon'=>'_FILTER_POINT_','optional'=>false,'href'=>'index.php?app=finance&ctl=monthend_verification&act=index&p[0]='.$this->report['monthly_id'].'&view=2'.$return_params), ); return $sub_menu; } - /** - * detailVerification - * @param mixed $monthly_id ID - * @param mixed $order_bn order_bn - * @return mixed 返回值 - */ public function detailVerification($monthly_id,$order_bn) { $mdlBillBase = app::get('financebase')->model('bill_base'); @@ -190,10 +194,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ // 检查核销 - /** - * 检查Verificate - * @return mixed 返回验证结果 - */ public function checkVerificate(){ $res = kernel::single('finance_verification')->checkVerificate($_POST); $res['data'] = base64_encode(json_encode($res)); @@ -202,10 +202,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ } - /** - * confirmVerification - * @return mixed 返回值 - */ public function confirmVerification(){ $data = base64_decode($_POST['data']); $data = json_decode($data,1); @@ -215,34 +211,18 @@ class finance_ctl_monthend_verification extends desktop_controller{ //确认核销 - /** - * doVerificate - * @return mixed 返回值 - */ public function doVerificate(){ $this->begin(''); - - // 保存差异类型 - if($_POST['gap_type']) { - $mdlBill = app::get('finance')->model('bill'); - $mdlBill->update(array('gap_type' => $_POST['gap_type']), array('order_bn' => $_POST['order_bn'], 'monthly_id' => $_POST['monthly_id'])); - - $mdlAr = app::get('finance')->model('ar'); - $mdlAr->update(array('gap_type' => $_POST['gap_type']), array('order_bn' => $_POST['order_bn'], 'monthly_id' => $_POST['monthly_id'])); - - $mdlItem = app::get('finance')->model('monthly_report_items'); - $mdlItem->update(array('gap_type' => $_POST['gap_type']), array('order_bn' => $_POST['order_bn'], 'monthly_id' => $_POST['monthly_id'])); + + if ($_POST['gap_type']) { + $this->_saveOrderGapType($_POST['monthly_id'], $_POST['order_bn'], $_POST['gap_type']); } - + $res = kernel::single('finance_verification')->doManVerificate($_POST); $this->end(true, app::get('base')->_('核销成功')); } // 移除应收应退单 - /** - * doRemove - * @return mixed 返回值 - */ public function doRemove() { $ret = array('res'=>'fail','msg'=>'移除失败'); @@ -265,12 +245,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ echo json_encode($ret,1); } - /** - * dialog_memo - * @param mixed $monthly_id ID - * @param mixed $order_bn order_bn - * @return mixed 返回值 - */ public function dialog_memo($monthly_id, $order_bn) { $this->pagedata['monthly_id'] = $monthly_id; @@ -279,12 +253,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ $this->display('monthed/memo.html'); } - /** - * 保存_memo - * @param mixed $monthly_id ID - * @param mixed $order_bn order_bn - * @return mixed 返回操作结果 - */ public function save_memo($monthly_id, $order_bn) { $this->begin(); @@ -312,12 +280,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ $this->end(true); } - /** - * dialog_gap_type - * @param mixed $monthly_id ID - * @param mixed $order_bn order_bn - * @return mixed 返回值 - */ public function dialog_gap_type($monthly_id, $order_bn) { $this->pagedata['monthly_id'] = $monthly_id; @@ -336,12 +298,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ $this->display('monthed/gap_type.html'); } - /** - * 保存_gap_type - * @param mixed $monthly_id ID - * @param mixed $order_bn order_bn - * @return mixed 返回操作结果 - */ public function save_gap_type($monthly_id, $order_bn) { $this->begin(); @@ -364,10 +320,211 @@ class finance_ctl_monthend_verification extends desktop_controller{ } /** - * ruleVerification - * @param mixed $id ID - * @return mixed 返回值 + * 批量核销弹窗(带进度条) */ + public function batchVerificationDialog($monthly_id) + { + if (isset($_POST['isSelectedAll']) && $_POST['isSelectedAll'] == '_ALL_') { + die(app::get('finance')->_('暂不支持全选')); + } + + $ids = isset($_POST['id']) ? $_POST['id'] : null; + if (!is_array($ids)) { + if ($ids !== null && $ids !== '') { + $ids = array($ids); + } + } + if (empty($ids) || !is_array($ids)) { + die(app::get('finance')->_('请先选择要核销的单据')); + } + + $ids = array_values(array_unique(array_map('intval', $ids))); + $ids = array_filter($ids); + if (count($ids) === 0) { + die(app::get('finance')->_('请先选择要核销的单据')); + } + + $mdlItem = app::get('finance')->model('monthly_report_items'); + $list = $mdlItem->getList('id', array( + 'id' => $ids, + 'monthly_id' => $monthly_id, + 'verification_status' => '1', + ), 0, -1); + $GroupList = array_column($list, 'id'); + if (empty($GroupList)) { + die(app::get('finance')->_('请先选择未核销的单据')); + } + + $mr = app::get('finance')->model('monthly_report')->db_dump($monthly_id, 'shop_id'); + if (empty($mr['shop_id'])) { + die(app::get('finance')->_('账期数据不存在')); + } + + $oGap = app::get('financebase')->model('gap'); + $this->pagedata['gap_list'] = $oGap->getList('gap_name', array('status' => '1')); + $this->pagedata['billName'] = '待核销单据'; + $this->pagedata['request_url'] = $this->url.'&act=doBatchVerification&monthly_id='.$monthly_id.'&shop_id='.$mr['shop_id']; + $this->pagedata['maxProcessNum'] = 1; + $this->pagedata['close'] = false; + $this->pagedata['queueNum'] = 1; + $this->pagedata['custom_html'] = $this->fetch('monthed/batch_verification.html'); + $this->pagedata['count'] = count($GroupList); + $this->pagedata['arrId'] = json_encode($GroupList); + $this->display('admin/request_add.html', 'ome'); + } + + /** + * 批量核销分步执行(request_add 进度条调用) + */ + public function doBatchVerification() + { + $monthly_id = isset($_GET['monthly_id']) ? intval($_GET['monthly_id']) : 0; + $shop_id = isset($_GET['shop_id']) ? $_GET['shop_id'] : ''; + if (!$monthly_id || $shop_id === '') { + $this->_batchVerificationResponse(array( + 'total' => 0, + 'succ' => 0, + 'fail' => 0, + 'validation_error' => true, + 'fail_msg' => array(array('msg' => '参数无效')), + )); + } + + $ajaxParams = isset($_POST['ajaxParams']) ? trim($_POST['ajaxParams']) : ''; + $itemIds = $ajaxParams === '' + ? array() + : array_values(array_unique(array_filter(array_map('intval', explode(';', $ajaxParams))))); + + $retArr = array( + 'total' => count($itemIds), + 'succ' => 0, + 'fail' => 0, + 'fail_msg' => array(), + ); + + if (count($itemIds) === 0) { + $retArr['validation_error'] = true; + $retArr['fail_msg'][] = array('msg' => '缺少待处理数据'); + $this->_batchVerificationResponse($retArr); + } + + $gap_type = isset($_POST['gap_type']) ? trim($_POST['gap_type']) : ''; + + $is_verification = isset($_POST['is_verification']) ? intval($_POST['is_verification']) : 0; + $verification_memo = isset($_POST['verification_memo']) ? trim($_POST['verification_memo']) : ''; + if ($is_verification == 1 && $gap_type === '') { + $retArr['validation_error'] = true; + $retArr['fail_msg'][] = array('msg' => '强制核销时差异类型不能为空'); + $this->_batchVerificationResponse($retArr); + } + if ($is_verification == 1 && $verification_memo === '') { + $retArr['validation_error'] = true; + $retArr['fail_msg'][] = array('msg' => '填写强制核销备注'); + $this->_batchVerificationResponse($retArr); + } + + $mdlItem = app::get('finance')->model('monthly_report_items'); + foreach ($itemIds as $itemId) { + $row = $mdlItem->db_dump(array('id' => $itemId), 'order_bn,monthly_id,verification_status'); + if (empty($row)) { + $retArr['fail'] += 1; + $retArr['fail_msg'][] = array('msg' => '单据缺少'); + continue; + } + if ($row['verification_status'] == '2') { + $retArr['fail'] += 1; + $retArr['fail_msg'][] = array('obj_bn' => $row['order_bn'], 'msg' => '已核销'); + continue; + } + + $ids = $this->_getCurrentVerificateIds($row['monthly_id'], $row['order_bn']); + $params = array( + 'monthly_id' => $row['monthly_id'], + 'order_bn' => $row['order_bn'], + 'shop_id' => $shop_id, + 'bill_id' => $ids['bill_id'], + 'ar_id' => $ids['ar_id'], + 'gap_type' => $gap_type, + 'is_verification' => $is_verification, + 'verification_memo' => $verification_memo, + ); + + $this->_saveOrderGapType($row['monthly_id'], $row['order_bn'], $gap_type); + + $res = kernel::single('finance_verification')->doManVerificate($params); + if ($res['status'] == 'success') { + $retArr['succ'] += 1; + } else { + $retArr['fail'] += 1; + $msg = !empty($res['msg']) ? $res['msg'] : '核销失败'; + $retArr['fail_msg'][] = array('obj_bn' => $row['order_bn'], 'msg' => $msg); + } + } + + finance_monthly_report::updateMonthlyAmount(array('monthly_id' => $monthly_id)); + + $this->_batchVerificationResponse($retArr); + } + + /** + * 批量核销统一响应(request_add 约定:total/succ/fail/fail_msg) + */ + protected function _batchVerificationResponse($retArr) + { + echo json_encode($retArr); + exit; + } + + /** + * 获取本期待核销的实收实退、应收应退 id 列表 + */ + protected function _getCurrentVerificateIds($monthly_id, $order_bn) + { + $bill_ids = array(); + $ar_ids = array(); + + $bill_data = kernel::single('finance_bill')->getListByOrderBn($order_bn); + foreach ($bill_data as $v) { + if ($monthly_id == $v['monthly_id'] && $v['status'] == 0 && $v['charge_status'] == 1) { + $bill_ids[] = $v['bill_id']; + } + } + + $ar_data = kernel::single('finance_ar')->getListByOrderBn($order_bn); + foreach ($ar_data as $v) { + if ($monthly_id == $v['monthly_id'] && $v['status'] == 0 && $v['charge_status'] == 1) { + $ar_ids[] = $v['ar_id']; + } + } + + return array('bill_id' => $bill_ids, 'ar_id' => $ar_ids); + } + + /** + * 保存订单差异类型到 bill、ar、monthly_report_items + */ + protected function _saveOrderGapType($monthly_id, $order_bn, $gap_type) + { + if (!$gap_type) { + return; + } + + app::get('finance')->model('bill')->update( + array('gap_type' => $gap_type), + array('order_bn' => $order_bn, 'monthly_id' => $monthly_id) + ); + + app::get('finance')->model('ar')->update( + array('gap_type' => $gap_type), + array('order_bn' => $order_bn, 'monthly_id' => $monthly_id) + ); + + app::get('finance')->model('monthly_report_items')->update( + array('gap_type' => $gap_type), + array('order_bn' => $order_bn, 'monthly_id' => $monthly_id) + ); + } + public function ruleVerification($id) { $mr = app::get('finance')->model('monthly_report')->db_dump($id, 'shop_id'); $filter = array( @@ -384,10 +541,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ parent::dialog_batch(); } - /** - * doRuleVerification - * @return mixed 返回值 - */ public function doRuleVerification() { $itemIds = explode(',',$_POST['primary_id']); @@ -416,14 +569,14 @@ class finance_ctl_monthend_verification extends desktop_controller{ } } + $firstRow = app::get('finance')->model('monthly_report_items')->db_dump(['id'=>$itemIds[0]], 'monthly_id'); + if(!empty($firstRow['monthly_id'])) { + finance_monthly_report::updateMonthlyAmount(array('monthly_id'=>$firstRow['monthly_id'])); + } + echo json_encode($retArr),'ok.';exit; } - /** - * base_list - * @param mixed $id ID - * @return mixed 返回值 - */ public function base_list($id){ $row = app::get('finance')->model('monthly_report_items')->db_dump(['id'=>$id], 'order_bn'); $params = array( @@ -441,11 +594,6 @@ class finance_ctl_monthend_verification extends desktop_controller{ $this->finder('financebase_mdl_base', $params); } - /** - * sale_list - * @param mixed $id ID - * @return mixed 返回值 - */ public function sale_list($id){ $row = app::get('finance')->model('monthly_report_items')->db_dump(['id'=>$id], 'order_bn'); $orderObj = app::get('ome')->model('orders'); diff --git a/app/finance/dbschema/monthly_report.php b/app/finance/dbschema/monthly_report.php index 1b4fb9d7..d40b7e54 100644 --- a/app/finance/dbschema/monthly_report.php +++ b/app/finance/dbschema/monthly_report.php @@ -117,6 +117,24 @@ $db['monthly_report']=array ( 'default_in_list' => true, 'comment' => '平台补贴退(不包含支付优惠)', ), + 'verified_count' => array( + 'type' => 'number', + 'default' => 0, + 'label' => '已核销数量', + 'editable' => false, + 'in_list' => true, + 'default_in_list' => true, + 'order' => 105, + ), + 'unverified_count' => array( + 'type' => 'number', + 'default' => 0, + 'label' => '未核销数量', + 'editable' => false, + 'in_list' => true, + 'default_in_list' => true, + 'order' => 106, + ), 'begin_time' => array ( 'type' => 'time', @@ -205,4 +223,4 @@ $db['monthly_report']=array ( 'comment' => '月结账单', 'engine' => 'innodb', 'version' => '$Rev: $', -); \ No newline at end of file +); diff --git a/app/finance/lib/finder/monthly/report.php b/app/finance/lib/finder/monthly/report.php index 469f601d..684cb4b2 100644 --- a/app/finance/lib/finder/monthly/report.php +++ b/app/finance/lib/finder/monthly/report.php @@ -23,6 +23,9 @@ class finance_finder_monthly_report{ var $column_edit_order=5; function column_edit($row){ $confhref = ''; + $finder_id = $_GET['_finder']['finder_id']; + $return_view = isset($_GET['view']) ? $_GET['view'] : 0; + $return_page = isset($_GET['page']) ? $_GET['page'] : 1; @@ -36,7 +39,7 @@ class finance_finder_monthly_report{ { $confhref = '关账    '; } - $confhref .= '核销列表    '; + $confhref .= '核销列表    '; // $confhref .= '往期单据    ';//核销更改, 该功能不可用 // $confhref .= '重新核销';//核销更改, 该功能不可用 @@ -45,4 +48,4 @@ class finance_finder_monthly_report{ return $confhref; } -} \ No newline at end of file +} diff --git a/app/finance/lib/monthly/report.php b/app/finance/lib/monthly/report.php index f0b6c521..01b8a9a1 100644 --- a/app/finance/lib/monthly/report.php +++ b/app/finance/lib/monthly/report.php @@ -14,8 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - +/** +* @copyright shopex.cn +* @author Kris.wang 406048119@qq.com +* @version ocs +*/ class finance_monthly_report { public $monthly_report = array(); @@ -146,7 +149,7 @@ class finance_monthly_report /** * 根据时间获取账期ID - * + * * @param String $shop_id * @param String $time */ @@ -231,6 +234,22 @@ class finance_monthly_report } } + $monthly_count = array(); + $item_list = $mdlMonthlyReport->db->select('select count(*) as cnt,monthly_id,verification_status from sdb_finance_monthly_report_items where monthly_id in ('.implode(',', $monthly_list).') group by monthly_id,verification_status'); + if($item_list) + { + foreach ($item_list as $v) { + if($v['verification_status'] == 2) + { + $monthly_count[$v['monthly_id']]['verified_count'] = $v['cnt']; + } + else + { + $monthly_count[$v['monthly_id']]['unverified_count'] = $v['cnt']; + } + } + } + foreach ($monthly_list as $monthly_id) { $data = array(); @@ -242,9 +261,11 @@ class finance_monthly_report $data['platform_amount'] = isset($monthly_amount[$monthly_id]['platform_amount']) ? $monthly_amount[$monthly_id]['platform_amount'] : 0; $data['refund_actually_amount'] = isset($monthly_amount[$monthly_id]['refund_actually_amount']) ? $monthly_amount[$monthly_id]['refund_actually_amount'] : 0; $data['refund_platform_amount'] = isset($monthly_amount[$monthly_id]['refund_platform_amount']) ? $monthly_amount[$monthly_id]['refund_platform_amount'] : 0; + $data['verified_count'] = isset($monthly_count[$monthly_id]['verified_count']) ? $monthly_count[$monthly_id]['verified_count'] : 0; + $data['unverified_count'] = isset($monthly_count[$monthly_id]['unverified_count']) ? $monthly_count[$monthly_id]['unverified_count'] : 0; $mdlMonthlyReport->update($data,array('monthly_id'=>$monthly_id)); } } return $monthly_list; } -} \ No newline at end of file +} diff --git a/app/finance/lib/monthly/report/items.php b/app/finance/lib/monthly/report/items.php index bcf6432d..ccc2c0b1 100644 --- a/app/finance/lib/monthly/report/items.php +++ b/app/finance/lib/monthly/report/items.php @@ -111,6 +111,11 @@ class finance_monthly_report_items { } } + $itemRow = $oMRI->db_dump($itemId, 'monthly_id'); + if(!empty($itemRow['monthly_id'])) { + finance_monthly_report::updateMonthlyAmount(array('monthly_id'=>$itemRow['monthly_id'])); + } + return [$rs, $rsData]; } @@ -358,8 +363,9 @@ class finance_monthly_report_items { if($init_time['according'] == 'shi_shou') { $itemId = $oMonthlyReportItems->getItemId($arRow, false); if(empty($itemId) && $arRow['ar_type'] == 1) { - $order = app::get('ome')->model('orders')->db_dump(['order_bn'=>$arRow['order_bn']], 'source_status'); - if($order['source_status'] == 'TRADE_CLOSED') { + $order = app::get('ome')->model('orders')->db_dump(['order_bn'=>$arRow['order_bn']], 'source_status,end_time,shop_type'); + // ar_type=1:应退;source_status=TRADE_CLOSED:平台关闭;shop_type=luban:抖音;end_time为空:未确认收货。 + if($order && ($order['source_status'] == 'TRADE_CLOSED' || ($order['shop_type'] == 'luban' && empty($order['end_time'])))) { $itemId = $oMonthlyReportItems->getItemId($arRow); $arRows = $oAr->getList('ar_id',['order_bn'=>$arRow['order_bn'], 'monthly_item_id'=>0, 'ar_id|noequal'=>$arRow['ar_id']]); if($arRows) { diff --git a/app/finance/lib/verification.php b/app/finance/lib/verification.php index 72d9b920..8094da9a 100644 --- a/app/finance/lib/verification.php +++ b/app/finance/lib/verification.php @@ -356,6 +356,9 @@ class finance_verification } } + if(!empty($params['monthly_id'])) { + finance_monthly_report::updateMonthlyAmount(array('monthly_id'=>$params['monthly_id'])); + } return $res; } diff --git a/app/finance/view/monthed/batch_verification.html b/app/finance/view/monthed/batch_verification.html new file mode 100644 index 00000000..135ac915 --- /dev/null +++ b/app/finance/view/monthed/batch_verification.html @@ -0,0 +1,213 @@ +
+
+ + + + + + + + + + + + + + + +
差异类型: + + 强制核销时必填 +
是否强制核销: + + +    + +
核销备注: + +
+
+
+ diff --git a/app/finance/view/monthed/verificate_detail.html b/app/finance/view/monthed/verificate_detail.html index af2ea621..e861ad68 100644 --- a/app/finance/view/monthed/verificate_detail.html +++ b/app/finance/view/monthed/verificate_detail.html @@ -1,19 +1,3 @@ - - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{css app="ome" src="style.css"}> @@ -303,7 +287,6 @@ function do_submit(){ var is_verification = $$('input[name=is_verification]:checked').get('value'); var verification_memo = $$('textarea[name=verification_memo]').get('value'); - var gap_type = $$('select[name=gap_type]').get('value'); var ar_sel = new Array(); var bill_sel = new Array(); $$('input[name=ar_id[]]').each(function(item){ @@ -328,12 +311,6 @@ function do_submit(){ MessageBox.error("填写核销备注!"); return; } - - if(gap_type == '') - { - MessageBox.error("强制核销时必须选择差异类型!"); - return; - } } else { @@ -425,4 +402,4 @@ function change_current(key) } - \ No newline at end of file + diff --git a/app/invoice/lib/autotask/timer/makeoutinvoice.php b/app/invoice/lib/autotask/timer/makeoutinvoice.php index 7fa5f899..b132ac2b 100644 --- a/app/invoice/lib/autotask/timer/makeoutinvoice.php +++ b/app/invoice/lib/autotask/timer/makeoutinvoice.php @@ -204,10 +204,13 @@ class invoice_autotask_timer_makeoutinvoice */ public function invoiceBill() { + if (app::get('ome')->getConf('ome.order.autoinvoice') != 'on') { + return false; + } + $db = kernel::database(); $offset = 0; $limit = 500; - $autoinvoice = app::get('ome')->getConf('ome.order.autoinvoice'); //配置为空不进行处理 if (!app::get('invoice')->model('order_setting')->db_dump([])) { @@ -220,7 +223,17 @@ class invoice_autotask_timer_makeoutinvoice return false; } - $shop_id = array_column($selfShop,'shop_id'); + $channelMdl = app::get('invoice')->model('channel'); + $shop_id = []; + foreach ($selfShop as $shop) { + $channelInfo = $channelMdl->get_channel_info($shop['shop_id']); + if (!empty($channelInfo)) { + $shop_id[] = $shop['shop_id']; + } + } + if (!$shop_id) { + return false; + } do { //查询完结的单据 @@ -253,10 +266,8 @@ class invoice_autotask_timer_makeoutinvoice } //蓝票自动开票 - if ($autoinvoice == 'on') { - kernel::single('invoice_process')->billing(['id' => $val['id'], 'order_id' => $val['order_id'], 'msg' => '系统自动开票']); - /**@used-by sales_aftersale::generate_aftersale 50行--售后自动冲红 * */ - } + kernel::single('invoice_process')->billing(['id' => $val['id'], 'order_id' => $val['order_id'], 'msg' => '系统自动开票']); + /**@used-by sales_aftersale::generate_aftersale 50行--售后自动冲红 * */ } } diff --git a/app/material/lib/finder/material/basic.php b/app/material/lib/finder/material/basic.php new file mode 100644 index 00000000..e69de29b diff --git a/app/material/lib/sales/material/import.php b/app/material/lib/sales/material/import.php index 2a739b31..1784534b 100644 --- a/app/material/lib/sales/material/import.php +++ b/app/material/lib/sales/material/import.php @@ -304,9 +304,8 @@ class material_sales_material_import //组合、福袋组合 if (in_array($salesMaterial['sales_material_type'], ['2', '7'])) { + $is_check_rate = false; $tmp_rate = 0; - $allHaveValues = true; - $allNoValues = true; foreach ($salesMaterial['items'] as $key => $val) { if ($salesMaterial['sales_material_type'] == '7' && empty($val['*:组合价格贡献占比'])) { @@ -319,19 +318,15 @@ class material_sales_material_import } $tmp_rate += $val['*:组合价格贡献占比']; - $allHaveValues = false; + // 是否检测贡献占比 + $is_check_rate = true; } else { $salesMaterial['items'][$key]['*:组合价格贡献占比'] = 0; - $allNoValues = false; } } - if (!$allHaveValues && !$allNoValues) { - return [false, ['msg' => sprintf('%s组合价格贡献占比必须全部有值或者全部没有值', $salesMaterial['*:销售物料编码'])]]; - } - //检测贡献占比是否等于100 - if (!$allHaveValues) { + if($is_check_rate){ if ($tmp_rate > 100) { return [false, ['msg' => sprintf('%s组合价格贡献百分比:%s,已超100%s', $salesMaterial['*:销售物料编码'], $tmp_rate,'%')]]; } elseif ($tmp_rate < 100) { @@ -534,9 +529,8 @@ class material_sales_material_import //组合、福袋组合 if (in_array($salesMaterial['sales_material_type'], ['2', '7'])) { + $is_check_rate = false; $tmp_rate = 0; - $allHaveValues = true; - $allNoValues = true; foreach ($salesMaterial['items'] as $key => $val) { if ($salesMaterial['sales_material_type'] == '7' && empty($val['*:组合价格贡献占比'])) { return [false, ['msg' => sprintf('%s组合价格贡献占比不能为空', $val['*:基础物料编码/福袋组合编码'])]]; @@ -547,19 +541,15 @@ class material_sales_material_import } $tmp_rate += $val['*:组合价格贡献占比']; - $allHaveValues = false; + // 是否检测贡献占比 + $is_check_rate = true; } else { $salesMaterial['items'][$key]['*:组合价格贡献占比'] = 0; - $allNoValues = false; } } - if (!$allHaveValues && !$allNoValues) { - return [false, ['msg' => sprintf('%s组合价格贡献占比必须全部有值或者全部没有值', $salesMaterial['*:销售物料编码'])]]; - } - //检测贡献占比是否等于100 - if (!$allHaveValues) { + if($is_check_rate){ if ($tmp_rate > 100) { return [false, ['msg' => sprintf('%s组合价格贡献百分比:%s,已超100%s', $salesMaterial['*:销售物料编码'], $tmp_rate,'%')]]; } elseif ($tmp_rate < 100) { diff --git a/app/material/view/admin/material/sales/add.html b/app/material/view/admin/material/sales/add.html index 1d66b900..dfd386fe 100644 --- a/app/material/view/admin/material/sales/add.html +++ b/app/material/view/admin/material/sales/add.html @@ -1,19 +1,3 @@ - - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{css app="ome" src="style.css"}> @@ -121,7 +105,7 @@ 编码 名称 <{$price_label}> - 固定价 + 固定价 数量 组合价格贡献占比(1-100数值) 删除 @@ -272,8 +256,8 @@ 建议填写此单位 开电子发票必要参数 -
- +
+ <{button type="button" id="sales_material_btn" label="保 存"}>   <{button type="button" class="btn-secondary" id="return-btn" label="返 回" onclick="location.href=window.frameElement.src;"}>
@@ -346,7 +330,7 @@ var priceLabel = '<{$price_label|default:"零售价"}>'; //组合 var tpl='' +' {material_bn}{material_name}{' + (priceField || 'retail_price') + '}' - +' {fixed_price}' + +' {fixed_price}' +' ' +' ' +' <{img src="bundle/delecate.gif" app="desktop" key="state" class="pointer btn-delete-item"}>' @@ -711,7 +695,7 @@ var priceLabel = '<{$price_label|default:"零售价"}>'; } - $('material-save-btn').addEvent('click',function(e){ + $('sales_material_btn').addEvent('click',function(e){ var _this=this; var form=this.getParent('form'); diff --git a/app/material/view/admin/material/sales/detail.html b/app/material/view/admin/material/sales/detail.html index c28b3429..39dd94f9 100644 --- a/app/material/view/admin/material/sales/detail.html +++ b/app/material/view/admin/material/sales/detail.html @@ -1,19 +1,3 @@ - - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{css app="ome" src="style.css"}> @@ -146,7 +130,7 @@ 编码 名称 <{$price_label|default:"零售价"}> - 固定价 + 固定价 数量 组合价格贡献占比(1-100数值) 删除 @@ -537,7 +521,7 @@ var sm_id = "<{$material_info.sm_id}>"; if($('cantdel')){ var tpl='' +' {material_bn}{material_name}{display_price}' - +' {fixed_price}' + +' {fixed_price}' +' ' +' ' +' -<{img src="bundle/delecate.gif" style="display:none;" app="desktop" key="state" class="pointer btn-delete-item"}>' @@ -546,13 +530,13 @@ var sm_id = "<{$material_info.sm_id}>"; if (chose_type == 3) { var tpl = '' + ' {material_bn}{material_name}{display_price}' - +' {fixed_price}' + +' {fixed_price}' + ' ' + ''; }else{ var tpl = '' + ' {material_bn}{material_name}{display_price}' - +' {fixed_price}' + +' {fixed_price}' + ' ' + ' ' + ' <{img src="bundle/delecate.gif" app="desktop" key="state" class="pointer btn-delete-item"}>' diff --git a/app/material/view/admin/material/sales/edit.html b/app/material/view/admin/material/sales/edit.html index 98c9bd8a..c9b3ea80 100644 --- a/app/material/view/admin/material/sales/edit.html +++ b/app/material/view/admin/material/sales/edit.html @@ -1,19 +1,3 @@ - - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{css app="ome" src="style.css"}> @@ -160,7 +144,7 @@ 编码 名称 <{$price_label}> - 固定价 + 固定价 数量 组合价格贡献占比(1-100数值) 删除 @@ -406,9 +390,9 @@ 建议填写此单位 开电子发票必要参数 -
- - <{button type="button" class="btn-secondary" id="return-btn" label="返 回" onclick="location.href=window.frameElement.src;"}> +
+ <{button type="button" id="sales_material_btn" label="保 存"}>   + <{button type="button" class="btn-secondary" id="return-btn" label="取 消" onclick="javascript:void(window.close());"}>
@@ -619,7 +603,7 @@ var sm_id = "<{$material_info.sm_id}>"; if($('cantdel')){ var tpl='' +' {material_bn}{material_name}{' + (priceField || 'retail_price') + '}' - +' {fixed_price}' + +' {fixed_price}' +' ' +' ' +' -<{img src="bundle/delecate.gif" style="display:none;" app="desktop" key="state" class="pointer btn-delete-item"}>' @@ -634,7 +618,7 @@ var sm_id = "<{$material_info.sm_id}>"; }else{ var tpl='' +' {material_bn}{material_name}{' + (priceField || 'retail_price') + '}' - +' {fixed_price}' + +' {fixed_price}' +' ' +' ' +' <{img src="bundle/delecate.gif" app="desktop" key="state" class="pointer btn-delete-item"}>' @@ -1001,7 +985,7 @@ var sm_id = "<{$material_info.sm_id}>"; }); } - $('material-save-btn').addEvent('click',function(e){ + $('sales_material_btn').addEvent('click',function(e){ var _this=this; var form=this.getParent('form'); @@ -1043,9 +1027,8 @@ var sm_id = "<{$material_info.sm_id}>"; _this.disabled=false; }else{ _this.disabled=true; - if(opener.finderGroup['<{$env.get.finder_id}>']) opener.finderGroup['<{$env.get.finder_id}>'].refresh.delay(100,opener.finderGroup['<{$env.get.finder_id}>']).chain(function(){ - window.close() - }); + if(opener.finderGroup['<{$env.get.finder_id}>']) opener.finderGroup['<{$env.get.finder_id}>'].refresh.delay(100,opener.finderGroup['<{$env.get.finder_id}>']); + setTimeout('window.close()',200); } }catch(e){} } @@ -1062,9 +1045,8 @@ var sm_id = "<{$material_info.sm_id}>"; _this.disabled=false; }else{ _this.disabled=true; - if(opener.finderGroup['<{$env.get.finder_id}>']) opener.finderGroup['<{$env.get.finder_id}>'].refresh.delay(100,opener.finderGroup['<{$env.get.finder_id}>']).chain(function(){ - window.close() - }); + if(opener.finderGroup['<{$env.get.finder_id}>']) opener.finderGroup['<{$env.get.finder_id}>'].refresh.delay(100,opener.finderGroup['<{$env.get.finder_id}>']); + setTimeout('window.close()',200); } }catch(e){} } diff --git a/app/monitor/lib/event/template.php b/app/monitor/lib/event/template.php index 1c11a34f..f32d7a3e 100644 --- a/app/monitor/lib/event/template.php +++ b/app/monitor/lib/event/template.php @@ -36,7 +36,7 @@ class monitor_event_template // 'wms_reship_finish' => 'WMS退货失败报警', // 'wms_stockin_finish' => 'WMS入库失败报警', // 'wms_stockout_finish' => 'WMS出库失败报警', - // 'wms_stock_change' => 'WMS异动失败报警', + 'wms_stock_change' => 'WMS异动失败报警', // 'wms_stockprocess_confirm' => 'WMS加工单确认失败报警', // 'wms_transferorder_finish' => 'WMS移库失败报警', diff --git a/app/ome/controller/admin/delivery.php b/app/ome/controller/admin/delivery.php index be713b74..f3ce4df4 100644 --- a/app/ome/controller/admin/delivery.php +++ b/app/ome/controller/admin/delivery.php @@ -15,9 +15,31 @@ * limitations under the License. */ class ome_ctl_admin_delivery extends desktop_controller{ + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; var $name = "发货单"; var $workground = "console_center"; + function _views(){ + $mdl_delivery = $this->app->model('delivery'); + $baseFilter = array( + 'type' => 'normal', + 'pause' => 'false', + 'parent_id' => 0, + 'disabled' => 'false', + 'status' => array('ready','progress','succ') + ); + $sub_menu = array( + 0 => array('label' => app::get('base')->_('全部'), 'filter' => $baseFilter, 'optional' => false), + 1 => array('label' => app::get('base')->_('加急发货'), 'filter' => array_merge($baseFilter, array('delivery_label_code' => self::URGENT_LABEL_CODE)), 'optional' => false), + ); + foreach ($sub_menu as $k => $v) { + $sub_menu[$k]['filter'] = $v['filter']; + $sub_menu[$k]['addon'] = $mdl_delivery->count($v['filter']); + $sub_menu[$k]['href'] = 'index.php?app=ome&ctl='.$_GET['ctl'].'&act='.$_GET['act'].'&view='.$k; + } + return $sub_menu; + } + function index(){ $filter = array( 'type' => 'normal', @@ -50,6 +72,7 @@ class ome_ctl_admin_delivery extends desktop_controller{ 'use_buildin_export'=>false, 'use_buildin_import'=>false, 'use_buildin_filter'=>true, + 'use_view_tab'=>true, )); } diff --git a/app/ome/controller/admin/order.php b/app/ome/controller/admin/order.php index 11842d05..c16edf5b 100644 --- a/app/ome/controller/admin/order.php +++ b/app/ome/controller/admin/order.php @@ -16,6 +16,8 @@ */ class ome_ctl_admin_order extends desktop_controller{ + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; + var $name = "订单中心"; var $workground = "order_center"; var $order_type = 'all'; @@ -117,6 +119,7 @@ class ome_ctl_admin_order extends desktop_controller{ 7 => array('label'=>app::get('base')->_('已发货'),'filter'=>array('ship_status' =>'1','status' => 'active'),'optional'=>false), 8 => array('label'=>app::get('base')->_('取消'),'filter'=>array('process_status' => 'cancel'),'optional'=>false), 9 => array('label'=>app::get('base')->_('暂停'),'filter'=>array('pause' => 'true'),'optional'=>false), + 10 => array('label'=>app::get('base')->_('加急发货'),'filter'=>array('order_label_code' => self::URGENT_LABEL_CODE),'optional'=>false), ); $i=0; foreach($sub_menu as $k=>$v){ @@ -752,7 +755,7 @@ class ome_ctl_admin_order extends desktop_controller{ case 'buffer': $this->order_type = 'buffer'; $this->base_filter = $this->getBaseFilter('buffer'); - + $this->action = array( array('label' => '订单分派', 'submit' => 'index.php?app=ome&ctl=admin_order&act=dispatchDailog&flt=buffer', 'target' => 'dialog::{width:600,height:300,title:\'订单分派\'}'), ); @@ -773,9 +776,9 @@ class ome_ctl_admin_order extends desktop_controller{ if($organization_permissions){ $this->base_filter['org_id'] = $organization_permissions; } - + $this->base_filter['archive'] ='0'; - + //跨境申报 //$this->base_filter['process_status|noequal'] = 'is_declare'; @@ -839,7 +842,7 @@ class ome_ctl_admin_order extends desktop_controller{ break; } } - + //订单退回 $isgoback = kernel::single('desktop_user')->has_permission('order_goback'); if($isgoback){ @@ -918,7 +921,7 @@ class ome_ctl_admin_order extends desktop_controller{ array('label'=>'重新路由', 'submit' => 'index.php?app=ome&ctl=admin_order_lack&act=routerAgain', 'target' => 'dialog::{width:600,height:250,title:\'重新路由\'}'), array('label' => '设置定时审单', 'submit' => 'index.php?app=ome&ctl=admin_order_auto&act=timingConfirm', 'target' => 'dialog::{width:400,height:150,title:\'设置定时审单\'}'), ); - + foreach ($this->action as $k => $v_action) { if (isset($v_action['group'])) { //批量编辑权限控制 @@ -936,7 +939,7 @@ class ome_ctl_admin_order extends desktop_controller{ ); } } - + // 超级管理员 if(kernel::single('desktop_user')->is_super()){ if(isset($this->base_filter['op_id'])) @@ -945,19 +948,19 @@ class ome_ctl_admin_order extends desktop_controller{ if(isset($this->base_filter['group_id'])) unset($this->base_filter['group_id']); } - + $export = false; $user = kernel::single('desktop_user'); if($user->has_permission('order_export')){ $export = true; } - + //archive $this->base_filter['archive'] = 0; - + //是否允许审核 $this->base_filter['is_not_combine'] = 0; - + $this->finder('ome_mdl_orders',array( 'title'=>$this->title, 'actions'=>$this->action, @@ -1071,10 +1074,6 @@ class ome_ctl_admin_order extends desktop_controller{ } } - /** - * 设置DlyCorp - * @return mixed 返回操作结果 - */ public function setDlyCorp(){ $ids = $_POST['order_id']; if(empty($ids)){ @@ -1093,10 +1092,6 @@ class ome_ctl_admin_order extends desktop_controller{ $this->display('admin/order/set_dly.html'); } - /** - * batchExamineSingle - * @return mixed 返回值 - */ public function batchExamineSingle() { $params = $this->_parseAjaxParams($_POST['ajaxParams']); $dlyType = strtoupper($_POST['dlyType']); @@ -1145,10 +1140,6 @@ class ome_ctl_admin_order extends desktop_controller{ echo json_encode(array('flag'=>true, 'type'=>'combine', 'order'=>$order)); } - /** - * batchClaim - * @return mixed 返回值 - */ public function batchClaim() { $this->begin('index.php?app=ome&ctl=admin_order&act=confirm&flt=ourgroup&view=1'); $orderIds = $admin = array(); @@ -1202,10 +1193,6 @@ class ome_ctl_admin_order extends desktop_controller{ return; } - /** - * claim - * @return mixed 返回值 - */ public function claim() { $this->begin('index.php?app=ome&ctl=admin_order&act=confirm&flt=ourgroup&view=1'); $order = $admin = array(); @@ -1596,14 +1583,14 @@ class ome_ctl_admin_order extends desktop_controller{ "; exit; } - + //定制订单类型,未推送给莫凡,不允许手工审核订单 if($order['order_type'] == 'custom' && $order['is_delivery'] == 'N'){ header("content-type:text/html; charset=utf-8"); echo ""; exit; } - + $orderExtend = app::get('ome')->model('order_extend')->db_dump(['order_id'=>$order_id]); $orderExtend['extend_field'] && $orderExtend['extend_field'] = json_decode($orderExtend['extend_field'], 1); @@ -1622,7 +1609,7 @@ class ome_ctl_admin_order extends desktop_controller{ echo ""; exit; } - + } else { if ($order['op_id'] == '' && !$is_supp) { $oo['order_id'] = $order_id; @@ -1664,12 +1651,12 @@ class ome_ctl_admin_order extends desktop_controller{ $orderSplitLib = kernel::single('ome_order_split'); $split_seting = $orderSplitLib->get_delivery_seting(); $split_model = $split_seting ? 2 : 0;//自由拆单方式split_model=2 - + $this->pagedata['split_model'] = $split_model; //获取当前订单的上下条订单 $this->pagedata['filter'] = urlencode($ini_filter); - + // 是否支持手工合单(On:开启,Off:关闭) $is_manual_merge = app::get('ome')->getConf('ome.combine.manual.merge'); if($is_manual_merge){ @@ -1677,11 +1664,11 @@ class ome_ctl_admin_order extends desktop_controller{ }else{ $order['is_manual_merge'] = ''; } - + //获取相关订单,并输入内容 $combineObj = kernel::single('omeauto_auto_combine'); $combineOrders = $combineObj->fetchCombineOrder($order); - + // order $order = $oOrder->dump($order_id); // 处理加密 @@ -1708,11 +1695,11 @@ class ome_ctl_admin_order extends desktop_controller{ //地址html转化 $order['consignee']['addr'] = str_replace(array("\r\n","\r","\n","'","\""), '', htmlspecialchars($order['consignee']['addr'])); - + //shipping_name字段处理:根据corp.php的corp_default方法显示正确名称 if (isset($order['shipping']['shipping_name'])) { $corpModel = app::get('ome')->model('dly_corp'); - + // 尝试从不同配送模式中查找配送方式名称 $shippingNameMap = $corpModel->corp_default('instatnt'); // 先查找同城配送 if(isset($shippingNameMap[$order['shipping']['shipping_name']])){ @@ -1724,7 +1711,7 @@ class ome_ctl_admin_order extends desktop_controller{ } } } - + $orderIdx = $order['order_combine_idx']; $orderHash = $order['order_combine_hash']; @@ -1753,7 +1740,7 @@ class ome_ctl_admin_order extends desktop_controller{ $recommendLogiStr = implode(',', $tempData); $this->pagedata['recommendLogiStr'] = $recommendLogiStr; } - + $flag_edit = 'true'; foreach ($combineOrders as $k=>$combineOrder) { @@ -1765,11 +1752,11 @@ class ome_ctl_admin_order extends desktop_controller{ $combineOrders[$k]['mark_text'] = strip_tags(htmlspecialchars($combineOrder['mark_text'])); $combineOrders[$k]['custom_mark'] = strip_tags(htmlspecialchars($combineOrder['custom_mark'])); - + //shipping_name字段处理:根据corp.php的corp_default方法显示正确名称 if (isset($combineOrder['shipping']['shipping_name'])) { $corpModel = app::get('ome')->model('dly_corp'); - + // 尝试从不同配送模式中查找配送方式名称 $shippingNameMap = $corpModel->corp_default('instatnt'); // 先查找同城配送 if(isset($shippingNameMap[$combineOrder['shipping']['shipping_name']])){ @@ -1934,12 +1921,12 @@ class ome_ctl_admin_order extends desktop_controller{ } // 仅保留同时存在于所有订单 has_store_branch 的门店仓 $o2oBranchIds = array_values(array_intersect($o2oBranchIds, $hasStoreBranchIds)); - + if (!empty($o2oBranchIds)) { // 使用门店仓覆盖区域检测工具类,过滤出可用的门店仓 $ship_area = $order['consignee']['area']; $availableO2OBranchIds = kernel::single('ome_store_branch_coverage')->getAvailableBranches($o2oBranchIds, $ship_area); - + if (!empty($availableO2OBranchIds)) { $storeBranches = $branchObj->getList('*', array( 'branch_id' => $availableO2OBranchIds, @@ -1959,7 +1946,7 @@ class ome_ctl_admin_order extends desktop_controller{ } } } - + if ($branch_id[$orderHash]){ $selected_branch_id = $branch_id[$orderHash]; @@ -2081,9 +2068,9 @@ class ome_ctl_admin_order extends desktop_controller{ $order['is_jy'] = true; } } - + //预估发货快递白名单 - + if (isset($orderExtend['white_delivery_cps']) && is_string($orderExtend['white_delivery_cps'])) { $logiCodes = json_decode($orderExtend['white_delivery_cps'], true); if (is_array($logiCodes) && !empty($logiCodes)) { @@ -2134,7 +2121,7 @@ class ome_ctl_admin_order extends desktop_controller{ if($split_model){ $orderItemMdl = app::get('ome')->model('order_items'); $orderItemList = $orderItemMdl->getList('*', array('order_id'=>$order['order_id'])); - + //是否存在福袋基础物料 $is_luckybag_flag = false; foreach ($orderItemList as $itemKey => $itemVal) @@ -2143,13 +2130,13 @@ class ome_ctl_admin_order extends desktop_controller{ if($itemVal['delete'] == 'true'){ continue; } - + //item_type if($itemVal['item_type'] == 'lkb'){ $is_luckybag_flag = true; } } - + //货到付款禁止拆单 if($order['shipping']['is_cod'] == 'true' || ($order['shop_type'] == 'taobao' && $order['order_source'] == 'maochao') || $is_luckybag_flag){ $this->pagedata['split_model'] = 0; @@ -2202,12 +2189,6 @@ class ome_ctl_admin_order extends desktop_controller{ } } - /** - * 获取DefaultBranch - * @param mixed $orderIds ID - * @param mixed $addr addr - * @return mixed 返回结果 - */ public function getDefaultBranch($orderIds,$addr=''){ $combineObj = kernel::single('omeauto_auto_combine'); $branchPlugObj = new omeauto_auto_plugin_branch(); @@ -2239,10 +2220,6 @@ class ome_ctl_admin_order extends desktop_controller{ return $branch_id; } - /** - * ajaxGetDefaultBranch - * @return mixed 返回值 - */ public function ajaxGetDefaultBranch(){ $orderIds = json_decode($_POST['orders']); @@ -2339,7 +2316,7 @@ class ome_ctl_admin_order extends desktop_controller{ $storeCode = ''; $order_bool_type = ''; $branch_id = []; - + foreach ($itemObjects as $key => $item) { $orders = $item->getOrders(); foreach ($orders as $order => $orderVal) { @@ -2373,7 +2350,7 @@ class ome_ctl_admin_order extends desktop_controller{ } } $branch_id[$key] = kernel::single('omeauto_branch_choose')->getSelectBid($tid, $item); - + foreach ($item->getBranchIdCorpId() as $bid => $cid) { $branchIdCropId[$bid] = $cid; } @@ -2480,7 +2457,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * 确认及通生成发货单 - * + * * @param void * @return void */ @@ -2896,7 +2873,7 @@ class ome_ctl_admin_order extends desktop_controller{ if(is_array($filter)&&count($filter)>0){ $orderObj = $this->app->model("orders"); $logObj = $this->app->model('operation_log'); - + $logObj->batch_write_log('order_dispatch@ome',$filter,'订单退回到暂存区',time()); $orderObj->filter_use_like = true; $orderObj->update($data,$filter); @@ -3448,7 +3425,7 @@ class ome_ctl_admin_order extends desktop_controller{ $edit_order['order_id'] = $order_id; $edit_order['pause'] = 'true'; $oOrder->save($edit_order); - + //pause $order['pause'] = 'true'; }elseif($order['process_status'] == 'is_retrial'){ @@ -3474,7 +3451,7 @@ class ome_ctl_admin_order extends desktop_controller{ if ($order['process_status'] == 'cancel'){ exit('订单已取消,无法再编辑订单'); } - + //[拆单]部分拆分订单,获取发货单及订单已拆分数量 $orderSplitLib = kernel::single('ome_order_split'); $split_seting = $orderSplitLib->get_delivery_seting(); @@ -3630,7 +3607,7 @@ class ome_ctl_admin_order extends desktop_controller{ $obj_config[$obj]['objs'] = $idata; } } - + $conf_list = array(); if ($obj_config) foreach ($obj_config as $name => $conf){ @@ -3717,10 +3694,10 @@ class ome_ctl_admin_order extends desktop_controller{ }else{ $result = true; $msg = '成功'; - + // orderIds $orderIds = [$order_id]; - + // 订单发货完成后,service扩展触发其他服务 foreach(kernel::servicelist('ome.service.order.finish.after') as $service) { if(method_exists($service, 'after_order_finish')) { @@ -3728,7 +3705,7 @@ class ome_ctl_admin_order extends desktop_controller{ } } } - + $this->end($result, app::get('base')->_("余单撤消".$msg)); } } @@ -3938,10 +3915,10 @@ class ome_ctl_admin_order extends desktop_controller{ /** * 编辑地址 - * + * * @return void * @author - * */ + **/ public function view_edit_consignee($order_id) { $orderMdl = app::get('ome')->model('orders'); @@ -3992,14 +3969,14 @@ class ome_ctl_admin_order extends desktop_controller{ exit; } } - + $psRow = app::get('ome')->model('order_platformsplit')->db_dump(['order_id'=>$order_id], 'id'); if($psRow) { header("content-type:text/html; charset=utf-8"); echo ""; exit; } - + if($_POST['cost_shipping'] == 0){} //检测编辑前后,配送费用是否发生了改变 @@ -4032,7 +4009,7 @@ class ome_ctl_admin_order extends desktop_controller{ $allow_edit = $allow_edit_service->is_allow_edit($order_edit_info, $error); } } - + if (!$allow_edit){ $this->begin(''); if (empty($error)) @@ -4040,11 +4017,11 @@ class ome_ctl_admin_order extends desktop_controller{ $this->end(false, $error); } } - + //操作 if ($_POST['do_action'] != 0){ $this->begin(''); - + $basicMaterialExtObj = app::get('material')->model('basic_material_ext'); $oOrderItm = $this->app->model("order_items"); $oOrderObj = $this->app->model("order_objects"); @@ -4174,7 +4151,7 @@ class ome_ctl_admin_order extends desktop_controller{ $objMath = kernel::single('eccommon_math'); $pro_total = $order['cost_item']; - + $discount = strval($post['discount']); $pmt_order_price = $post['pmt_order']; @@ -4277,7 +4254,7 @@ class ome_ctl_admin_order extends desktop_controller{ $new_order['order_combine_hash'] = $combieHashIdxInfo['combine_hash']; $new_order['order_combine_idx'] = $combieHashIdxInfo['combine_idx']; } - + // 原订单更新位置 kernel::single('console_map_order')->getLocation($order_id); @@ -4294,13 +4271,13 @@ class ome_ctl_admin_order extends desktop_controller{ $tmp = array(); $tmp = $o['items']; unset($o['items']); - + // 更新pay_status状态值 //@todo:解决手工批量删除赠品,又手工编辑订单进行恢复,导致pay_status='5'退款状态,无法审核订单; if($o['delete'] == 'false' && $o['price'] == '0'){ $o['pay_status'] = '0'; } - + $oOrderObj->save($o); foreach ($tmp as $oo){ @@ -4327,7 +4304,7 @@ class ome_ctl_admin_order extends desktop_controller{ $chk_bm_ids[] = $product_id; $product_info = $basicMaterialExtObj->dump(array('bm_id'=>$product_id), 'specifications'); - + $oOrderItm->save($aoo); } } @@ -4383,7 +4360,7 @@ class ome_ctl_admin_order extends desktop_controller{ } } } - + //订单编辑API if ($is_order_change == true){ if ($service_order = kernel::servicelist('service.order')){ @@ -4434,7 +4411,7 @@ class ome_ctl_admin_order extends desktop_controller{ kernel::single('ome_order_order')->order_pay_confirm($order['shop_id'],$order_id,$post['total_amount']); } - + //[翱象]地址变更后,重新获取配送建议 if($is_address_change && in_array($order['shop_type'], array('taobao', 'tmall'))){ $orderTypeLib = kernel::single('ome_order_bool_type'); @@ -4462,14 +4439,14 @@ class ome_ctl_admin_order extends desktop_controller{ $oOperation_log->write_log('order_modify@ome', $order_id, $log_msg); } } - + // [大家电订单]商品被修改、收货人地址被修改,订单需要重新预约时间 if($is_address_change){ kernel::single('ome_order_reservation')->againReservation($order_id, 'address_change'); }elseif($is_goods_modify){ kernel::single('ome_order_reservation')->againReservation($order_id, 'goods_change'); } - + // 增加service调用,便于扩展finish_edit后的处理逻辑 foreach (kernel::servicelist('ome.service.order.finishedit.after') as $service) { if (method_exists($service, 'afterFinishEdit')) { @@ -4483,7 +4460,7 @@ class ome_ctl_admin_order extends desktop_controller{ $this->begin(''); $oOrder = $this->app->model("orders"); - + $order_id = $_POST['order_id']; $order = $oOrder->dump($order_id); @@ -4618,7 +4595,7 @@ class ome_ctl_admin_order extends desktop_controller{ $filter = array( 'code|head'=>$_GET['barcode'] ); - + $code_list = []; $bm_ids = $basicMaterialBarcode->getBmidListByFilter($filter, $code_list); $filter['bm_id'] = $bm_ids; @@ -4767,8 +4744,13 @@ class ome_ctl_admin_order extends desktop_controller{ $this->pagedata['price_monitor'] = $price_monitor; } - //差额[现订单金额-原订单金额] - $diff_money = round(floatval($newtotal - $total), 3); + //差额[现订单金额-原订单金额],按2位小数比较,避免前端重算精度导致无实质修改时出现虚假差额 + $newtotal_2 = bcmul($newtotal, 1, 2); + $total_2 = bcmul($total, 1, 2); + $diff_money = bcsub($newtotal_2, $total_2, 2); + if (bccomp($diff_money, '0', 2) === 0) { + $newtotal = $total; + } $this->pagedata['diff_money'] = $diff_money; $this->pagedata['is_cod'] = $is_cod; @@ -4855,14 +4837,14 @@ class ome_ctl_admin_order extends desktop_controller{ $this->begin("index.php?app=ome&ctl=admin_order&act=addNormalOrder"); define('FRST_TRIGGER_OBJECT_TYPE','订单:手工新建订单'); define('FRST_TRIGGER_ACTION_TYPE','ome_ctl_admin_order:doAddNormalOrder'); - + $oObj = $this->app->model("orders"); $logObj = app::get('ome')->model('operation_log'); - + $salesMLib = kernel::single('material_sales_material'); $lib_ome_order = kernel::single('ome_order'); $fudaiLib = kernel::single('material_fukubukuro_dispatch'); - + $tostr = array(); $post = $_POST; $post['consignee']['r_time'] = '任意日期 任意时间段'; @@ -4898,7 +4880,7 @@ class ome_ctl_admin_order extends desktop_controller{ }else { $this->end(false, '请填写配送地址信息'); } - + //补发订单 if(in_array($post['order']['order_type'], array('bufa'))){ //不需要验证收货人信息,允许复制原订单上加密的收货人信息 @@ -4968,17 +4950,17 @@ class ome_ctl_admin_order extends desktop_controller{ }else{ $this->end(false, '请选择来源店铺!'); } - + //shop_bn $shopObj = app::get("ome")->model('shop'); $shopInfo = $shopObj->dump(array('shop_id'=>$iorder['shop_id']), 'shop_bn'); $shop_bn = $shopInfo['shop_bn']; - + $lucky_falg = false; foreach ($num as $k => $i){ //销售物料购买数量 $obj_number = $i; - + $salesMInfo = $salesMLib->getSalesMById($iorder['shop_id'],$k); if($salesMInfo){ if($salesMInfo['sales_material_type'] == 5){ //多选一 @@ -4988,7 +4970,7 @@ class ome_ctl_admin_order extends desktop_controller{ $luckybagParams = $salesMInfo; $luckybagParams['sale_material_nums'] = $obj_number; $luckybagParams['shop_bn'] = $shop_bn; - + $fdResult = $fudaiLib->process($luckybagParams); if($fdResult['rsp'] == 'succ'){ $basicMInfos = $fdResult['data']; @@ -4996,16 +4978,16 @@ class ome_ctl_admin_order extends desktop_controller{ //标记福袋分配错误信息 $this->end(false, '销售物料编码:'. $salesMInfo['sales_material_bn'] .'获取福袋组合失败:'. $fdResult['error_msg'] .'!'); } - + $lucky_falg = true; - + //unset unset($luckybagParams, $fdResult); }else{ //获取绑定的基础物料 $basicMInfos = $salesMLib->getBasicMBySalesMId($salesMInfo['sm_id']); } - + //如果是促销类销售物料 if($salesMInfo['sales_material_type'] == 2){ //促销 $obj_type = $item_type = 'pkg'; @@ -5025,10 +5007,10 @@ class ome_ctl_admin_order extends desktop_controller{ //福袋组合 $obj_type = 'lkb'; $item_type = 'lkb'; - + //福袋销售物料内的基础物料已经分配好正确的购买数量 $lkb_obj_quantity = 1; - + //格式化order_items $return_arr_info = $lib_ome_order->format_order_items_data($item_type, $lkb_obj_quantity, $basicMInfos); }else{ @@ -5063,7 +5045,7 @@ class ome_ctl_admin_order extends desktop_controller{ $tostr[]=array("name"=>$salesMInfo['sales_material_name'],"num"=>$obj_number); } } - + if(empty($iorder['order_objects'])) { $this->end(false, '选择的商品不是该店铺的!'); } @@ -5095,10 +5077,10 @@ class ome_ctl_admin_order extends desktop_controller{ $iorder['currency'] = 'CNY'; $iorder['pmt_order'] = $post['pmt_order']; $iorder['discount'] = $post['discount']; - + //关联订单号 $iorder['relate_order_bn'] = trim($post['relate_order_bn']) ? trim($post['relate_order_bn']) : trim($post['order_bn']); - + $iorder['total_amount'] = $mathLib->number_plus(array($item_cost,$post['cost_shipping'],$post['discount'])); $iorder['total_amount'] = $mathLib->number_minus(array($iorder['total_amount'],$post['pmt_order'])); @@ -5199,13 +5181,13 @@ class ome_ctl_admin_order extends desktop_controller{ $logObj->write_log('order_modify@ome', $iorder['order_id'], $log_msg); } } - + //福袋日志记录 if($lucky_falg){ $luckyBagLib = kernel::single('ome_order_luckybag'); $luckyBagLib->saveLuckyBagUseLogs($iorder); } - + //[SAP创建]调用service进行SAP创建 foreach(kernel::servicelist('ome.service.order.create.after') as $object) { @@ -5213,14 +5195,10 @@ class ome_ctl_admin_order extends desktop_controller{ $object->after_create($iorder); } } - + $this->end(true, '创建成功','index.php?app=ome&ctl=admin_order&act=createOrderResult&order_bn='.$iorder['order_bn']); } - /** - * 创建OrderResult - * @return mixed 返回值 - */ public function createOrderResult() { $this->pagedata['order_bn'] = $_GET['order_bn']; @@ -5473,7 +5451,7 @@ class ome_ctl_admin_order extends desktop_controller{ $o2oStore = $o2oStoreObj->getList('store_id', array('branch_id' => $branch_id, 'is_o2o' => '1'), 0, 1); $isO2OStore = !empty($o2oStore); } - + if($exrecommend_available && in_array($channel_type,array('selfwms'))){ $_order_ids = json_decode($_POST['order_info'],true); if(!empty($_order_ids)){ @@ -5528,20 +5506,20 @@ class ome_ctl_admin_order extends desktop_controller{ //过滤掉不适用此店铺的快递公司 $corpList = array(); - + // 小时达平台运力时,只保留指定的物流公司 $xiaoshiPlatformShipping = null; if($order_id && $xiaoshiInfo['is_xiaoshi_da'] && $xiaoshiInfo['is_platform_delivery'] && $orderRow['shipping']){ $xiaoshiPlatformShipping = $orderRow['shipping']; } - + foreach($rows as $k=>$v) { // 小时达平台运力时,只保留指定的物流公司 if($xiaoshiPlatformShipping && $v['type'] != $xiaoshiPlatformShipping){ continue; } - + if($v['tmpl_type']=='electron' && $channelType[$v['channel_id']]=='wlb' && $v['shop_id']!=$shop_id) { continue; } @@ -5680,11 +5658,11 @@ class ome_ctl_admin_order extends desktop_controller{ } } /** - * 获取订单编辑方式 - * @access public - * @param number $order_id 订单ID - * @return json - */ + * 获取订单编辑方式 + * @access public + * @param number $order_id 订单ID + * @return json + */ function update_type($order_id){ $return = array('rsp'=>'fail','msg'=>'','data'=>''); $rs = kernel::single('ome_order')->update_iframe($order_id,$is_request=false); @@ -5704,11 +5682,11 @@ class ome_ctl_admin_order extends desktop_controller{ /** - * 订单编辑页面 - * @access public - * @param number $order_id 订单ID - * @return json - */ + * 订单编辑页面 + * @access public + * @param number $order_id 订单ID + * @return json + */ function update_iframe($order_id){ $oOrder = $this->app->model('orders'); $order = $oOrder->getRow($order_id); @@ -5765,12 +5743,12 @@ class ome_ctl_admin_order extends desktop_controller{ /** - * 订单编辑接口 - * @access public - * @param number $order_id 订单ID - * @param String $finder_id FINDER_id - * @return json - */ + * 订单编辑接口 + * @access public + * @param number $order_id 订单ID + * @param String $finder_id FINDER_id + * @return json + */ function update_iframe_api($order_id,$finder_id=''){ $sh_base_url = kernel::base_url(1); $notify_url = $sh_base_url.'/index.php?app=ome&ctl=admin_order&act=update_iframe&p[0]='.$order_id.'&finder_id='.$finder_id; @@ -5781,12 +5759,12 @@ class ome_ctl_admin_order extends desktop_controller{ /** - * 更新订单同步状态 - * @access public - * @param number $order_id 订单ID - * @param String $sync_status 编辑同步状态 - * @return json - */ + * 更新订单同步状态 + * @access public + * @param number $order_id 订单ID + * @param String $sync_status 编辑同步状态 + * @return json + */ function set_sync_status($order_id,$sync_status=''){ $rs = array('rsp'=>'fail','msg'=>''); if (in_array($sync_status,array('fail','success'))){ @@ -5799,12 +5777,12 @@ class ome_ctl_admin_order extends desktop_controller{ } /** - * 关闭订单编辑页面后所做操作 - * @access public - * @param number $order_id 订单ID - * @param String $is_operator 是否记录操作日志 - * @return bool - */ + * 关闭订单编辑页面后所做操作 + * @access public + * @param number $order_id 订单ID + * @param String $is_operator 是否记录操作日志 + * @return bool + */ function update_iframe_after($order_id,$is_operator='1'){ $rs = array('rsp'=>'fail','msg'=>''); if (empty($order_id)) die(json_encode($rs)); @@ -5823,11 +5801,11 @@ class ome_ctl_admin_order extends desktop_controller{ die(json_encode($rs)); } - /** - * 获取店铺订单信息 - * - * @return void - * */ + /** + * 获取店铺订单信息 + * + * @return void + **/ function getShopOrder(){ $Oshop = $this->app->model('shop'); $shop = $Oshop->getList('name,shop_id,node_type,node_id,business_type as order_type'); @@ -5958,10 +5936,6 @@ class ome_ctl_admin_order extends desktop_controller{ $this->display('admin/order/order_pausenotify.html'); } - /** - * downloadPrintSite - * @return mixed 返回值 - */ public function downloadPrintSite() { $product_type = isset($_GET['product_type']) ? trim($_GET['product_type']) : 'tp'; $url = 'http://update.tg.taoex.com/tg.php'; @@ -5980,10 +5954,6 @@ class ome_ctl_admin_order extends desktop_controller{ } - /** - * errorReportPrintSite - * @return mixed 返回值 - */ public function errorReportPrintSite() { $product_type = isset($_GET['product_type']) ? trim($_GET['product_type']) : 'tp'; $base_host = kernel::single('base_request')->get_host(); @@ -6188,10 +6158,10 @@ class ome_ctl_admin_order extends desktop_controller{ /** * [拆单]计算物流费 - * + * * @return void * @author chenping - * */ + **/ public function calFreightCost($shipping_area,$logi_id,$weight) { if (false !== strpos($shipping_area,'mainland')) list($area_prefix,$area_chs,$area_id) = explode(':',$shipping_area); @@ -6314,7 +6284,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * 销售物料列表弹窗数据获取方法 - * + * * @param Void * @return String */ @@ -6385,7 +6355,7 @@ class ome_ctl_admin_order extends desktop_controller{ $filter = array( 'code|head'=>$basic_material_barcode ); - + $code_list = []; $bm_ids = $basicMaterialBarcode->getBmidListByFilter($filter, $code_list); $_tmp = $salesBasicMaterialObj->getList('*',array('bm_id|in'=>$bm_ids),0,-1); @@ -6457,7 +6427,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * 销售物料列表弹窗选中物料信息查询方法 - * + * * @param Int $bm_id * @return String */ @@ -6522,7 +6492,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * Ajax获取o2o门店店铺 - * + * * @return Json */ public function ajax_o2o_store_list() @@ -6663,7 +6633,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * Ajax获取订单对应仓库信息 - * + * * @return Json */ public function ajax_o2o_order_by_branch() @@ -6701,7 +6671,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * Ajax最大程度的获取o2o门店店铺 - * + * * @return Json */ public function ajax_region_by_o2o_store() @@ -6845,7 +6815,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * Ajax获取门店关联的地区 - * + * * @return Json */ public function ajax_store_regions() @@ -6864,7 +6834,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * [JS调用]门店区域下拉列表 - * + * * @return Json */ function selO2oRegion() @@ -6893,19 +6863,19 @@ class ome_ctl_admin_order extends desktop_controller{ $salesMStockLib = kernel::single('material_sales_material_stock'); $salesBasicMaterialObj = app::get('material')->model('sales_basic_material'); $basicMaterialObj = app::get('material')->model('basic_material'); - + $fudaiLib = kernel::single('material_fukubukuro_dispatch'); - + $sm_id = $_POST['sm_id']; $shop_id = $_POST['shop_id']; //目前多选一用 $sales_material_bn= $_GET['sales_material_bn']; $sales_material_name= $_GET['sales_material_name']; - + //shop_bn $shopObj = app::get("ome")->model('shop'); $shopInfo = $shopObj->dump(array('shop_id'=>$shop_id), 'shop_bn'); $shop_bn = $shopInfo['shop_bn']; - + if (is_array($sm_id)){ if ($sm_id[0] == "_ALL_"){ $filter = ''; @@ -6925,7 +6895,7 @@ class ome_ctl_admin_order extends desktop_controller{ 'sales_material_name'=>$sales_material_name ); } - + //sales_material $filter['use_like'] = 1; $data = $salesMaterialObj->getList('sm_id,sales_material_name,sales_material_bn,sales_material_type',$filter,0,-1); @@ -6936,7 +6906,7 @@ class ome_ctl_admin_order extends desktop_controller{ //$store = $salesMStockLib->getSalesMStockById($item['sm_id']); $store = 100; $salesMLib = kernel::single('material_sales_material'); - + if($item['sales_material_type'] == 5){ //多选一 $basicMInfos = $salesMLib->get_order_pickone_bminfo($item['sm_id'],"1",$shop_id); $basic_info_arr_pickone = array(); @@ -6955,7 +6925,7 @@ class ome_ctl_admin_order extends desktop_controller{ //福袋组合 $item['sale_material_nums'] = 1; $item['shop_bn'] = $shop_bn; - + $fdResult = $fudaiLib->process($item); if($fdResult['rsp'] == 'succ' && $fdResult['data']){ $basic_info_arr = array(); @@ -6971,10 +6941,10 @@ class ome_ctl_admin_order extends desktop_controller{ 'luckybag_id' => $basicMInfo['combine_id'], //福袋组合ID ); } - + $item['items'] = $basic_info_arr; } - + }else{ $promoItems = $salesBasicMaterialObj->getList('*',array('sm_id'=>$item['sm_id']),0,-1); if($promoItems){ @@ -6998,7 +6968,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * Ajax通过门店编号自动选择门店 - * + * * @return Json */ public function ajax_autoload_select_store() @@ -7175,10 +7145,10 @@ class ome_ctl_admin_order extends desktop_controller{ } /** * 加密字段显示明文 - * + * * @return void * @author - * */ + **/ public function showSensitiveData($order_id, $fieldType='') { $order = app::get('ome')->model('orders')->db_dump(array('order_id'=>$order_id), '*'); @@ -7197,7 +7167,7 @@ class ome_ctl_admin_order extends desktop_controller{ $order['uname'] = $member['uname']; } - + // 报备外呼主叫号码组 //@todo:700虚拟号拨打前必须上报主叫号码组,号码组之外的号码拨打不通 if(in_array($_GET['source'], ['reservation']) && in_array($order['shop_type'], ['taobao','360buy'])){ @@ -7207,24 +7177,19 @@ class ome_ctl_admin_order extends desktop_controller{ if($result['rsp'] == 'succ'){ //操作人 $opinfo = kernel::single('ome_func')->get_system(); - + //log app::get('ome')->model('operation_log')->write_log('order_confirm@ome', $order_id, '报备外呼主叫号码组,成功!', time(), $opinfo); } } } - + // 页面加密处理 $order['encrypt_body'] = kernel::single('ome_security_router',$order['shop_type'])->get_encrypt_body($order, 'order', $fieldType); - + $this->splash('success',null,null,'redirect',$order); } - /** - * showSensitiveInvoice - * @param mixed $order_id ID - * @return mixed 返回值 - */ public function showSensitiveInvoice($order_id) { $order = app::get('ome')->model('orders')->db_dump(array('order_id'=>$order_id,'order_type'=>'_ALL_'), 'order_id,ship_name,ship_tel,ship_mobile,ship_addr,shop_id,shop_type,order_bn,member_id'); @@ -7239,10 +7204,6 @@ class ome_ctl_admin_order extends desktop_controller{ } //批量编辑订单 - /** - * BatchUpdateOrder - * @return mixed 返回值 - */ public function BatchUpdateOrder() { $ordersModel = app::get('ome')->model('orders'); @@ -7299,15 +7260,11 @@ class ome_ctl_admin_order extends desktop_controller{ parent::dialog_batch(); } - /** - * doBatchUpdateOrder - * @return mixed 返回值 - */ public function doBatchUpdateOrder() { $ordersModel = app::get('ome')->model('orders'); $orderItemModel = app::get('ome')->model('order_items'); - + $replace = (array)$_POST['replace']; //删除 $replace = array_filter($replace); @@ -7370,7 +7327,7 @@ class ome_ctl_admin_order extends desktop_controller{ //提交事务 kernel::database()->commit(); - + //成功 $retArr['isucc']++; } @@ -7379,11 +7336,6 @@ class ome_ctl_admin_order extends desktop_controller{ exit; } - /** - * dispatchDailog - * @param mixed $order_id ID - * @return mixed 返回值 - */ public function dispatchDailog($order_id = NULL) { @ini_set('memory_limit','256M'); @@ -7416,11 +7368,7 @@ class ome_ctl_admin_order extends desktop_controller{ parent::selectToPageRequest($orderObj, $pageData); } - /** - * ajaxDispatch - * @return mixed 返回值 - */ - public function ajaxDispatch() + public function ajaxDispatch() { $order_id = explode(';', $_POST['ajaxParams']); @@ -7430,12 +7378,12 @@ class ome_ctl_admin_order extends desktop_controller{ 'fail' => 0, 'fail_msg' => array(), ); - if (!$_POST['new_group_id']) { + if (!$_POST['new_group_id']) { $retArr['fail'] = $retArr['total']; $retArr['fail_msg'][] = ['msg'=>'请选择分组']; echo json_encode($retArr);exit; } - + $orderMdl = app::get('ome')->model('orders'); $orders = $orderMdl->getList('order_id,order_bn', ['order_id'=>$order_id]); @@ -7509,10 +7457,6 @@ class ome_ctl_admin_order extends desktop_controller{ parent::dialog_batch(); } - /** - * doBatchEditLabel - * @return mixed 返回值 - */ public function doBatchEditLabel() { $ordLabelObj = app::get('ome')->model('bill_label'); @@ -7689,7 +7633,7 @@ class ome_ctl_admin_order extends desktop_controller{ /** * 审核订单时提示建议信息 - * + * * @return void */ public function reconfirmOrder() @@ -7738,7 +7682,7 @@ class ome_ctl_admin_order extends desktop_controller{ $this->display('admin/order/order_check_msg.html'); } - + /** * Ajax获取订单收货人解密数据 * @@ -7749,37 +7693,37 @@ class ome_ctl_admin_order extends desktop_controller{ public function ajaxShowSensitiveData($order_id) { $search = array(' ','"','"',"\r\n","\r","\n",','); - + // order $orderInfo = app::get('ome')->model('orders')->db_dump(array('order_id'=>$order_id), '*'); - + // 补发订单类型,使用原平台订单信息进行解密 if(in_array($orderInfo['order_type'], array('bufa')) && $orderInfo['relate_order_bn']){ $orderInfo = app::get('ome')->model('orders')->db_dump(array('order_bn'=>$orderInfo['relate_order_bn']), '*'); } - + // 归档订单 if (empty($orderInfo)) { $orderInfo = app::get('archive')->model('orders')->db_dump($order_id,'*'); } - + if ($orderInfo['member_id']) { $member = app::get('ome')->model('members')->db_dump($orderInfo['member_id'],'uname'); $orderInfo['uname'] = $member['uname']; } - + // 获取订单解密信息 //$orderInfo = app::get('ome')->model('orders')->dump(array('order_id'=>$order_id), '*'); //kernel::single('ome_order')->getEncryptOriginData($orderInfo); - + // area $temp = explode(':', $orderInfo['ship_area']); $area = $temp[1]; $area = str_replace('/', '-', $area); - + // 解密收货人信息 $encryptData = kernel::single('ome_security_router', $orderInfo['shop_type'])->decrypt($orderInfo, 'order'); - + // telephone $telephone = ''; if($encryptData['ship_mobile']){ @@ -7787,7 +7731,7 @@ class ome_ctl_admin_order extends desktop_controller{ }elseif($encryptData['ship_tel']){ $telephone = str_replace($search, '', $encryptData['ship_tel']); } - + // 收货人明文信息 $shipInfo = [ 'ship_name' => str_replace($search, '', $encryptData['ship_name']), @@ -7795,7 +7739,7 @@ class ome_ctl_admin_order extends desktop_controller{ 'area' => $area, 'ship_addr' => str_replace($search, '', $encryptData['ship_addr']), ]; - + $result = [ 'rsp' => 'succ', 'error_msg' => '', @@ -7803,11 +7747,43 @@ class ome_ctl_admin_order extends desktop_controller{ 'order_bn' => $orderInfo['order_bn'], 'ship_info' => implode(',', $shipInfo), //订单明细手工复制收货人解密信息 ]; - + // merge $result = array_merge($result, $shipInfo); - + echo json_encode($result); exit; } + + /** + * 手工建单 - 相似订单选择弹窗 + */ + function finderOrders() + { + $op_id = kernel::single('desktop_user')->get_id(); + $this->title = '订单选择'; + $base_filter = array(); + + $organization_permissions = kernel::single('desktop_user')->get_organization_permission(); + if ($organization_permissions) { + $base_filter['org_id'] = $organization_permissions; + } + + $params = array( + 'title' => $this->title, + 'use_buildin_new_dialog' => false, + 'use_buildin_set_tag' => false, + 'use_buildin_recycle' => false, + 'use_buildin_export' => false, + 'use_buildin_import' => false, + 'use_buildin_filter' => true, + 'use_view_tab' => false, + 'finder_aliasname' => 'order_finder_select' . $op_id, + 'finder_cols' => 'order_bn,shop_id,total_amount,process_status,is_cod,pay_status,ship_status,payment,shipping,createtime,paytime', + 'orderBy' => 'order_id', + 'orderType' => 'desc', + 'base_filter' => $base_filter, + ); + $this->finder('ome_mdl_orders', $params); + } } diff --git a/app/ome/controller/admin/order/fail.php b/app/ome/controller/admin/order/fail.php index 99219eaf..1746ce74 100644 --- a/app/ome/controller/admin/order/fail.php +++ b/app/ome/controller/admin/order/fail.php @@ -116,7 +116,7 @@ class ome_ctl_admin_order_fail extends desktop_controller } //修正订单项 - if (kernel::single("ome_order_fail")->modifyOrderItems($order_id, $oldPbn, $pbn)) { + if (kernel::single('ome_order_fail')->modifyOrderItems($order_id, $oldPbn, $pbn)) { $this->splash('success', $url, '订单处理成功'); } else { $this->splash('error', $url, '存在异常商品,订单修正失败!'); @@ -140,15 +140,25 @@ class ome_ctl_admin_order_fail extends desktop_controller } //type + $failLib = kernel::single('ome_order_fail'); if ($type == 'bn') { - $orderData = kernel::single('ome_order_fail')->getFailOrderByBn($oldPbn); + $orderData = $failLib->getFailOrderByBn($oldPbn); + $totalCount = $failLib->countFailOrderByBn($oldPbn, false); + $batchableCount = $failLib->countFailOrderByBn($oldPbn, true); } else { - $orderData = kernel::single('ome_order_fail')->getFailOrderByName($oldPbn); + $orderData = $failLib->getFailOrderByName($oldPbn); + $totalCount = $failLib->countFailOrderByName($oldPbn, false); + $batchableCount = $failLib->countFailOrderByName($oldPbn, true); } // check if(empty($orderData)){ - echo ""; + if ($totalCount > 0) { + $msg = sprintf('存在 %d 条匹配的失败订单,但流程状态不是【未确认】,无法批量修复!', $totalCount); + } else { + $msg = '没有找到匹配的失败订单!'; + } + echo ""; exit; } @@ -180,6 +190,13 @@ class ome_ctl_admin_order_fail extends desktop_controller } } $GroupList = array_column($orderData, 'order_id'); + $excludedCount = $totalCount - $batchableCount; + if ($excludedCount > 0) { + $this->pagedata['batch_exclude_notice'] = sprintf( + '另有 %d 条同条件失败订单因流程状态不是【未确认】已排除,不在本次批量范围内。', + $excludedCount + ); + } $this->pagedata['oldPbn'] = base64_encode(json_encode($oldPbn)); $this->pagedata['pbn'] = base64_encode(json_encode($pbn)); $this->pagedata['modifyType'] = $type; diff --git a/app/ome/controller/admin/order/lack.php b/app/ome/controller/admin/order/lack.php index cda72486..a8c1fd5e 100644 --- a/app/ome/controller/admin/order/lack.php +++ b/app/ome/controller/admin/order/lack.php @@ -404,7 +404,7 @@ class ome_ctl_admin_order_lack extends desktop_controller { protected function _getOlistFilter() { $params = array( - 'assigned' => 'assigned', + //'assigned' => 'assigned', 'abnormal' => 'false', 'is_fail' => 'false', 'status' => 'active', @@ -417,7 +417,7 @@ class ome_ctl_admin_order_lack extends desktop_controller { // } if(!kernel::single('desktop_user')->is_super()){ $op_id = kernel::single('desktop_user')->get_id(); - $params['op_id'] = $op_id; + $params['op_id'] = array($op_id, 0); } /*$flag = omeauto_auto_const::__STORE_CODE; $params['order_confirm_filter'] = sprintf("(sdb_ome_orders.auto_status & %s = %s)", $flag, $flag); */ diff --git a/app/ome/controller/admin/receipts/print.php b/app/ome/controller/admin/receipts/print.php index e2c8abf3..dbc067c6 100644 --- a/app/ome/controller/admin/receipts/print.php +++ b/app/ome/controller/admin/receipts/print.php @@ -20,6 +20,7 @@ */ class ome_ctl_admin_receipts_print extends desktop_controller { + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; var $name = "发货中心"; var $workground = "delivery_center"; @@ -97,9 +98,14 @@ class ome_ctl_admin_receipts_print extends desktop_controller { 'filter' => $tmp_filter, 'optional' => false ); + $sub_menu[$c++] = array( + 'label' => app::get('base')->_('加急发货'), + 'filter' => array_merge($tmp_filter, array('delivery_label_code' => self::URGENT_LABEL_CODE)), + 'optional' => false + ); #第三方发货时,显示已发货、未发货 if($_GET['ctl'] == 'admin_receipts_outer') { - $c = 3;#物流公司view在未发货之后 + $c = $c + 2; $outer_filter = $tmp_filter; #让已发货、未发货显示在全部之后 $outer = $this->shipStatus(); diff --git a/app/ome/controller/admin/return/rchange.php b/app/ome/controller/admin/return/rchange.php index 0271e887..f70e7cbd 100644 --- a/app/ome/controller/admin/return/rchange.php +++ b/app/ome/controller/admin/return/rchange.php @@ -2813,31 +2813,29 @@ class ome_ctl_admin_return_rchange extends desktop_controller }elseif(in_array($reship_detail['shop_type'] ,array( 'luban','meituan4medicine'))){ $lubanReutrnInfo = app::get('ome')->model('return_product_luban')->db_dump(array('return_id'=>$reship_detail['return_id'])); if(!empty($lubanReutrnInfo)){ - if ($_FILES['refuse_proof']['size']<=0) { - $this->end(false, '请上传凭证图片!'); + $memo = array( + 'reject_reason_code' => $_POST['seller_refuse_reason_id'], + 'remark' => $_POST['refuse_message'], + 'parse' => 'second', + ); + + if ($_FILES['refuse_proof']['size'] > 0) { + if ($_FILES ['refuse_proof'] ['size'] > 512000) { + $this->end(false, '上传文件不能超过500K!'); + } + + $type = array ('gif','jpg','png'); + $pathinfo = pathinfo($_FILES ['refuse_proof'] ['name']); + if (!in_array($pathinfo['extension'], $type)) { + $this->end(false, "您只能上传以下类型文件".implode('、', $type)."!"); + } + + $storager = kernel::single ( 'base_storager' ); + $id = $storager->save_upload ( $_FILES ['refuse_proof'], "file", "", $msg ); //返回file_id; + $refuse_memo['image'] = $storager->getUrl ( $id, "file" ); + $memo['refuse_proof'] = $refuse_memo['image']; } - - if ($_FILES ['refuse_proof'] ['size'] > 512000) { - $this->end(false, '上传文件不能超过500K!'); - } - - $type = array ('gif','jpg','png'); - $pathinfo = pathinfo($_FILES ['refuse_proof'] ['name']); - if (!in_array($pathinfo['extension'], $type)) { - $this->end(false, "您只能上传以下类型文件".implode('、', $type)."!"); - } - - $storager = kernel::single ( 'base_storager' ); - $id = $storager->save_upload ( $_FILES ['refuse_proof'], "file", "", $msg ); //返回file_id; - $refuse_memo['image'] = $storager->getUrl ( $id, "file" ); - $imagebinary = $refuse_memo['image']; - - //memo - $memo['refuse_proof'] = $imagebinary; - $memo['reject_reason_code'] = $_POST['seller_refuse_reason_id']; - $memo['remark'] = $_POST['refuse_message']; - $memo['parse'] = 'second'; - + //request $result = kernel::single('ome_service_aftersale')->update_status($reship_detail['return_id'],'5','sync',$memo); if ($result['rsp'] != 'succ' && !$_POST['forced_cancel']) { diff --git a/app/ome/dbschema/orders.php b/app/ome/dbschema/orders.php index 8fa759a9..757f7a57 100644 --- a/app/ome/dbschema/orders.php +++ b/app/ome/dbschema/orders.php @@ -1281,6 +1281,13 @@ $db['orders'] = array( 3 => 'is_not_combine', ), ), + 'idx_shopid_orderid_createtime' => [ + 'columns' => [ + 'shop_id', + 'order_id', + 'createtime', + ], + ], ), 'comment' => '订单表,用于存储全渠道订单', 'engine' => 'innodb', diff --git a/app/ome/dbschema/sales.php b/app/ome/dbschema/sales.php index 5109dfe8..9a7d0453 100644 --- a/app/ome/dbschema/sales.php +++ b/app/ome/dbschema/sales.php @@ -364,6 +364,8 @@ $db['sales'] = array( 'type' => 'money', 'default' => '0', 'label' => '结算金额',//客户实付 + 平台支付总额 + 'in_list' => true, + 'default_in_list' => true, ), 'actually_amount' => array( 'type' => 'money', diff --git a/app/ome/lib/aftersale/request/jd.php b/app/ome/lib/aftersale/request/jd.php new file mode 100644 index 00000000..8c055199 --- /dev/null +++ b/app/ome/lib/aftersale/request/jd.php @@ -0,0 +1,25 @@ + 'succ', 'msg' => '', 'data' => ''); + $return_id = $data['return_id']; + $status = $data['status']; + + if ($status == '3' || $status == '5') { + $rsp = kernel::single('ome_service_aftersale')->update_status($return_id, $status, 'sync'); + if ($rsp && $rsp['rsp'] == 'fail') { + $rs['rsp'] = 'fail'; + $rs['msg'] = $rsp['msg']; + } + } + + return $rs; + } +} diff --git a/app/ome/lib/auth/config.php b/app/ome/lib/auth/config.php index a75e550b..3c6c4fad 100644 --- a/app/ome/lib/auth/config.php +++ b/app/ome/lib/auth/config.php @@ -139,6 +139,17 @@ class ome_auth_config 'node_id' => '节点', ), ), + 'b2b' => + array( + 'label' => 'B2B', + 'desc' => 'B2B平台对接', + 'params' => + array( + 'b2b_url' => 'API地址', + 'b2b_response_secret' => 'RESPONSE SECRET', + 'node_id' => '节点', + ), + ), ); foreach (ome_shop_type::get_shop_type() as $key => $value) { diff --git a/app/ome/lib/bill/label.php b/app/ome/lib/bill/label.php index 4f1760ff..4c8bc7c8 100644 --- a/app/ome/lib/bill/label.php +++ b/app/ome/lib/bill/label.php @@ -71,6 +71,7 @@ class ome_bill_label 'SOMS_QN_DISTR' => ['label_name' => '清仓', 'label_color' => '#ff6f61'], 'SOMS_CHANGE_CANCEL' => ['label_name' => '换货取消', 'label_color' => '#cca4e3'], 'SOMS_UPDATE_ITEM' => ['label_name' => '改SKU', 'label_color' => 'PaleVioletRed'],//#DB7093 + 'SOMS_MATERIAL_REPLACE' => ['label_name' => '物料替换', 'label_color' => 'MediumSlateBlue', 'label_thumb' => '替换'], 'SOMS_COMBINE_ORDER' => ['label_name' => '合单', 'label_color' => 'Salmon', 'label_to_delivery' => true],//#FA8072 'SOMS_GXD' => ['label_name' => '工小达', 'label_color' => 'MediumTurquoise','label_to_delivery' => true], 'SOMS_GB' => ['label_name' => '国补', 'label_color' => 'Coral', 'label_thumb'=>'国补'], @@ -86,10 +87,11 @@ class ome_bill_label 'SOMS_GIFT_RELATED_ORDER' => ['label_name' => '赠品子单', 'label_color' => '#cca4e3', 'label_thumb'=>'赠品子单'], 'SOMS_YPDS' => ['label_name' => '百亿补贴', 'label_color' => '#FF6B6B', 'label_thumb'=>'百补'], 'SOMS_SUPERLINK' => ['label_name' => '超链', 'label_color' => '#FF6B6B', 'label_thumb'=>'超链'], - + 'SOMS_TMYP' => ['label_name' => '天猫优品国补', 'label_color' => 'Coral', 'label_thumb'=>'天猫优品国补'], 'SOMS_LARGE_APPLIANCE' => ['label_name'=>'大家电', 'label_color'=>'#c25975', 'label_to_delivery'=>true], 'SOMS_PICKUP' => ['label_name' => '物流提货', 'label_color' => 'Teal'], + 'SOMS_URGENT_SHIP' => ['label_name' => '加急发货', 'label_color' => 'OrangeRed', 'label_to_delivery' => true, 'label_thumb' => '加急'], ]; // 小标 public $labelValuePreset = [ @@ -307,7 +309,7 @@ class ome_bill_label 'label_value' => $label_value?:0, 'extend_info' => $extend_info, 'create_time' => time(), - 'label_desc' => $labelInfo['label_desc'], + 'label_desc' => $labelInfo['label_desc'], ); $billLabelMdl = app::get('ome')->model('bill_label'); $isCheck = $billLabelMdl->db_dump(['bill_type' => $bill_type, 'bill_id' => $bill_id, 'label_id' => $labelInfo['label_id']], 'id,label_value'); @@ -338,7 +340,7 @@ class ome_bill_label 'source' => 'system', 'create_time' => time(), 'last_modified' => time(), - 'label_desc' => $info['label_desc'], + 'label_desc' => $info['label_desc'], ]; $labelMdl = app::get('omeauto')->model('order_labels'); @@ -525,7 +527,7 @@ class ome_bill_label } } } - + /** * 获取指定标签编码关联的标记信息 * @@ -539,31 +541,31 @@ class ome_bill_label { $labelMdl = app::get('omeauto')->model('order_labels'); $billLabelMdl = app::get('ome')->model('bill_label'); - + //check if(empty($bill_id) || empty($bill_type) || empty($label_code)){ $error_msg = '无效的传参,请检查'; return array(); } - + $lableInfo = $labelMdl->db_dump(array('label_code'=>$label_code), '*'); if(empty($lableInfo)){ $error_msg = '标签编码:'. $label_code .'不存在'; return array(); } - + $billLableInfo = $billLabelMdl->db_dump(array('bill_type'=>$bill_type, 'bill_id'=>$bill_id, 'label_id'=>$lableInfo['label_id']), '*'); if(empty($billLableInfo)){ $error_msg = '标签编码:'. $label_code .'没有单据打标记信息'; return array(); } - + //merge $billLableInfo = array_merge($billLableInfo, $lableInfo); - + return $billLableInfo; } - + public function isExpressMust() { return 'SOMS_EXPRESS_MUST'; @@ -573,11 +575,11 @@ class ome_bill_label //京东变成可发货 $ordLabelObj = app::get('ome')->model('bill_label'); - + $bills = $ordLabelObj->dump(array('label_code'=>'SOMS_JDZD','bill_type'=>'order','bill_id'=>$order_id),'bill_id'); $extendMdl = app::get('ome')->model('order_extend'); - + if($bills){ $extends = $extendMdl->dump(array('order_id'=>$order_id),'extend_field'); $extend_field = json_decode($extends['extend_field'],true); @@ -604,20 +606,20 @@ class ome_bill_label //京东变成可发货 $ordLabelObj = app::get('ome')->model('bill_label'); - + $bills = $ordLabelObj->dump(array('label_code'=>'SOMS_CLOUDBRANCH','bill_type'=>'order','bill_id'=>$order_id),'bill_id'); $extendMdl = app::get('ome')->model('order_extend'); - + if($bills){ return true; - + } return false; } - + //工小达标识 public function isSomsGxd() { @@ -643,7 +645,7 @@ class ome_bill_label } $billLabelMdl = app::get('ome')->model('bill_label'); - + // 检查是否有小时达标签 $xiaoshiLabel = $billLabelMdl->dump([ 'label_code' => 'SOMS_XSDBC', @@ -663,7 +665,7 @@ class ome_bill_label } $label_value = intval($xiaoshiLabel['label_value']); - + // 根据二进制值判断配送方式 $is_third_party = (bool)($label_value & 0x0001); // 第三方运力 $is_self_delivery = (bool)($label_value & 0x0002); // 商家自配运力 @@ -674,7 +676,7 @@ class ome_bill_label if ($is_third_party) $delivery_methods[] = '第三方运力'; if ($is_self_delivery) $delivery_methods[] = '商家自配运力'; if ($is_platform_delivery) $delivery_methods[] = '平台运力'; - + $delivery_method = implode('、', $delivery_methods); return [ @@ -685,4 +687,28 @@ class ome_bill_label 'is_platform_delivery' => $is_platform_delivery ]; } + /** + * 判断指定单据上是否已存在目标标签,兼容订单与发货单。 + * @param $bill_id + * @param $label_code + * @param string $bill_type + * @return bool + */ + public function existLabel($bill_id, $label_code, $bill_type = 'order') + { + $labelInfo = $this->getBillLabelInfo($bill_id, $bill_type, $label_code); + return !empty($labelInfo); + } + + /** + * 获取标签信息 + * @param $order_id + * @param $label_code + * @return false|mixed|null + */ + public function getLabelInfo($order_id, $label_code) + { + $labelInfo = $this->getBillLabelInfo($order_id, 'order', $label_code); + return $labelInfo; + } } diff --git a/app/ome/lib/event/trigger/shop/data/delivery/common.php b/app/ome/lib/event/trigger/shop/data/delivery/common.php index 0f4ff3b0..1edb5b1c 100644 --- a/app/ome/lib/event/trigger/shop/data/delivery/common.php +++ b/app/ome/lib/event/trigger/shop/data/delivery/common.php @@ -1406,9 +1406,12 @@ class ome_event_trigger_shop_data_delivery_common //获取删除的平台商品 $deleteOidList = array(); + $objectByObjId = array(); $objectList = $orderObjMdl->getList('obj_id,obj_type,bn,oid,divide_order_fee,pay_status,`delete`,main_oid', array('order_id'=>$order_id)); foreach ($objectList as $key => $val) { + $objectByObjId[$val['obj_id']] = $val; + $oid = $val['oid']; //check @@ -1476,6 +1479,14 @@ class ome_event_trigger_shop_data_delivery_common //删除已经退款的oid子订单 if($deleteOidList[$oid]){ + //换货/改SKU:同oid下可能存在已退款旧子单与有效新子单,以发货明细关联的obj_id为准 + $orderObjId = $itemVal['order_obj_id']; + if ($orderObjId && isset($objectByObjId[$orderObjId])) { + $linkedObj = $objectByObjId[$orderObjId]; + if ($linkedObj['delete'] == 'false' && !in_array($linkedObj['pay_status'], array('4', '5'))) { + continue; + } + } unset($this->__sdf['delivery_items'][$itemKey]); } } diff --git a/app/ome/lib/event/trigger/shop/order.php b/app/ome/lib/event/trigger/shop/order.php index 5ceac16b..4190c538 100644 --- a/app/ome/lib/event/trigger/shop/order.php +++ b/app/ome/lib/event/trigger/shop/order.php @@ -25,6 +25,8 @@ */ class ome_event_trigger_shop_order { + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; + /** * 淘宝全链路 * @@ -85,6 +87,86 @@ class ome_event_trigger_shop_order kernel::single('erpapi_router_request')->set('shop',$shop_id)->order_message_produce($sdf,false); } } + //淘宝加急发货状态上传 + $this->urgent_logistics_report($orderIds); + } + + /** + * 遍历加急订单并向淘宝/天猫补发当前物流状态回告。 + * + * @param array|int $orderIds + * @param string|array $scene + * @return void + */ + public function urgent_logistics_report($orderIds, $scene = '') + { + $orderIds = (array)$orderIds; + if (is_array($scene)) { + if (!empty($scene['order_ids']) && is_array($scene['order_ids'])) { + $orderIds = $scene['order_ids']; + } + $scene = $scene['scene']; + } + if (!$orderIds) { + return; + } + + $orderModel = app::get('ome')->model('orders'); + $labelLib = kernel::single('ome_bill_label'); + $urgentLib = kernel::single('ome_order_urgent'); + $orderList = $orderModel->getList('order_id,order_bn,shop_id,shop_type,source,createway', ['order_id' => $orderIds]); + + foreach ((array)$orderList as $order) { + if ($order['source'] != 'matrix' || $order['createway'] != 'matrix') { + continue; + } + if (!in_array($order['shop_type'], ['taobao', 'tmall'])) { + continue; + } + if (!$labelLib->existLabel($order['order_id'], self::URGENT_LABEL_CODE)) { + continue; + } + + $statusPayload = $urgentLib->buildUrgentOrderStatus($order['order_id']); + if (empty($statusPayload['orderStatus'])) { + continue; + } + if (in_array($statusPayload['orderStatus'], ['SHIPPED', 'CANCELLED']) && $this->isUrgentTerminalReported($order['order_id'], $statusPayload['orderStatus'])) { + continue; + } + + $sdf = [ + 'tid' => $order['order_bn'], + 'orderStatus' => $statusPayload['orderStatus'], + 'scene' => $scene, + 'status_update_time' => $statusPayload['status_update_time'] ?: '', + 'order_details' => $statusPayload['order_details'] ?: [], + 'tracking_number' => $statusPayload['tracking_number'] ?: '', + 'exception_reason' => $statusPayload['exception_reason'] ?: '', + 'is_split' => (bool)($statusPayload['is_split'] ?? false), + 'order_id' => $order['order_id'], + ]; + + $result = kernel::single('erpapi_router_request')->set('shop', $order['shop_id'])->logistics_order_report($sdf, false); + if (($result['rsp'] == 'succ' || $result['rsp'] == 'success') && in_array($statusPayload['orderStatus'], ['SHIPPED', 'CANCELLED'])) { + app::get('ome')->model('operation_log')->write_log('order_modify@ome', $order['order_id'], '淘宝加急发货状态回告终态:' . $statusPayload['orderStatus']); + } + } + } + + /** + * 通过操作日志判断终态回告是否已经成功落库,避免重复回告。 + * + * @param int $orderId + * @param string $status + * @return bool + */ + protected function isUrgentTerminalReported($orderId, $status) + { + $pattern = '淘宝加急发货状态回告终态:' . $status; + $sql = "SELECT log_id FROM sdb_ome_operation_log WHERE obj_id=" . intval($orderId) . " AND obj_type='order_modify@ome' AND memo LIKE '%" . addslashes($pattern) . "%' LIMIT 1"; + $rows = kernel::database()->select($sql); + return !empty($rows); } public function received($orderId) { diff --git a/app/ome/lib/finder/orders.php b/app/ome/lib/finder/orders.php index 2b5e2b3e..445e5de9 100644 --- a/app/ome/lib/finder/orders.php +++ b/app/ome/lib/finder/orders.php @@ -33,10 +33,20 @@ class ome_finder_orders var $detail_freeze = '订单冻结流水'; function __construct(){ - if($_GET['act'] == 'index' || $_GET['act'] == 'confirm' || $_GET['act'] == 'pending' || $_GET['act'] == 'processed'){ + if(($_GET['ctl'] == 'admin_order' + && ($_GET['act'] == 'confirm' || $_GET['act'] == 'index' || $_GET['flt'] == 'buffer' || $_GET['flt'] == 'assigned')) + || $_GET['ctl']=='admin_order_lack'){ //nothing }else{ - unset($this->column_confirm); + unset($this->column_confirm); + } + + //剔除复审操作按扭 + if($_GET['ctl'] == 'admin_order' && $_GET['act'] == 'retrial'){ + //nothing + }else{ + unset($this->column_abnormal_status); + unset($this->column_mark_text); } } @@ -1634,7 +1644,57 @@ EOF; } return date('Y-m-d H:i:s', $timeConfirm); } - + + var $column_abnormal_status = '复审操作'; + var $column_abnormal_status_width = '110'; + var $column_abnormal_status_order = '10'; + function column_abnormal_status($row) + { + $find_id = $_GET['_finder']['finder_id']; + $order_id = $row['order_id']; + + //不是复审订单,直接返回 + if($row[$this->col_prefix.'process_status'] != 'is_retrial'){ + return ''; + } + + $sql = "SELECT id, retrial_type, status FROM ".DB_PREFIX."ome_order_retrial WHERE order_id='".$order_id."' AND status in('0', '2') ORDER BY dateline DESC"; + $result = kernel::database()->select($sql); + + $str = '编辑'; + if($result[0]['status'] == '2' && $result[0]['retrial_type'] == 'normal') + { + return $str.' | 恢复原订单'; + } + elseif($result[0]['status'] == '2') + { + return $str.'(价格复审)'; + } + else + { + return '未审核'; + } + } + + var $column_mark_text = '复审备注'; + var $column_mark_text_width = '130'; + var $column_mark_text_order = '15'; + function column_mark_text($row) + { + $order_id = $row['order_id']; + + //不是复审订单,直接返回 + if($row[$this->col_prefix.'process_status'] != 'is_retrial'){ + return ''; + } + + $sql = "SELECT id, remarks, lastdate FROM ".DB_PREFIX."ome_order_retrial WHERE order_id='".$order_id."' AND status in('0', '2') ORDER BY dateline DESC"; + $result = kernel::database()->select($sql); + + $html = strip_tags(htmlspecialchars($result[0]['remarks'])); + return "
".$html."
"; + } + var $column_order_combined_confirm = '已合并审单'; var $column_order_combined_confirm_width = "60"; function column_order_combined_confirm($row) { diff --git a/app/ome/lib/order/fail.php b/app/ome/lib/order/fail.php index e5e92346..921aa7d3 100644 --- a/app/ome/lib/order/fail.php +++ b/app/ome/lib/order/fail.php @@ -124,7 +124,11 @@ class ome_order_fail if($pbn){ $salesMLib = kernel::single('material_sales_material'); - foreach($pbn as $obj_id=>$bn){ + foreach($pbn as $obj_id=>$bn) + { + // trim + $bn = trim($bn); + //获取对应的obj层数据 $objInfo = $Oorder_objects->getList('*',array('obj_id'=>$obj_id), 0 , 1); //销售物料没对上,进行修复 @@ -172,10 +176,11 @@ class ome_order_fail $price = bcdiv($amount, $basicMInfo['number']*$quantity, 2); $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $basicMInfo['number']*$quantity; + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00, @@ -201,10 +206,11 @@ class ome_order_fail //组织item数据 foreach($basicMInfos as $k => $basicMInfo){ $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $basicMInfo['number']; + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => (float)$objInfo[0]['cost'] ? $objInfo[0]['cost'] : $basicMInfo['cost'], @@ -234,10 +240,11 @@ class ome_order_fail $luckybag_id = ($basicMInfo['combine_id'] ? $basicMInfo['combine_id'] : 0); //items + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00, @@ -275,10 +282,11 @@ class ome_order_fail $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $objInfo[0]['sendnum']*$basicMInfo['number']; //普通销售物料item层数据以object为主,原本就是1:1的两层结构,item合并object,item层数据真实 + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], $objInfo[0]['shop_product_id']); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => $objInfo[0]['shop_product_id'] ? $objInfo[0]['shop_product_id'] : 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => (float)$objInfo[0]['cost'] ? $objInfo[0]['cost'] : $basicMInfo['cost'], @@ -583,10 +591,11 @@ class ome_order_fail foreach($basicMInfos as $k => $basicMInfo){ //$basicMInfo['retail_price'] ? $basicMInfo['retail_price'] : 0.00 $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $basicMInfo['number']*$quantity; + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00, @@ -610,10 +619,11 @@ class ome_order_fail //组织item数据 foreach($basicMInfos as $k => $basicMInfo){ $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $basicMInfo['number']; + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => (float)$objInfo[0]['cost'] ? $objInfo[0]['cost'] : $basicMInfo['cost'], @@ -643,10 +653,11 @@ class ome_order_fail $luckybag_id = ($basicMInfo['combine_id'] ? $basicMInfo['combine_id'] : 0); //items + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], 0); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => $basicMInfo['cost'] ? $basicMInfo['cost'] : 0.00, @@ -683,10 +694,11 @@ class ome_order_fail $sendnum = $orderInfo[0]['ship_status'] == '0' ? 0 : $objInfo[0]['sendnum']*$basicMInfo['number']; //普通销售物料item层数据以object为主,原本就是1:1的两层结构,item合并object,item层数据真实 + $shop_product_id = $this->_getWxshipinShopProductId($orderInfo[0], $objInfo[0], $objInfo[0]['shop_product_id']); $order_items[] = array( 'shop_goods_id' => $objInfo[0]['shop_goods_id'] ? $objInfo[0]['shop_goods_id'] : 0, 'product_id' => $basicMInfo['bm_id'] ? $basicMInfo['bm_id'] : 0, - 'shop_product_id' => $objInfo[0]['shop_product_id'] ? $objInfo[0]['shop_product_id'] : 0, + 'shop_product_id' => $shop_product_id, 'bn' => $basicMInfo['material_bn'], 'name' => $basicMInfo['material_name'], 'cost' => (float)$objInfo[0]['cost'] ? $objInfo[0]['cost'] : $basicMInfo['cost'], @@ -914,6 +926,48 @@ class ome_order_fail $orderObj->write_log_detail($log_id,$orders); } + /** + * 获取微信视频号失败订单恢复时使用的平台 SKU ID。 + * + * 非微信视频号订单保持原默认值;微信视频号订单优先使用已有 SKU, + * 没有时从 order_objects.addon 里备份的原始平台明细继承。 + * + * @param array $orderInfo 订单主信息 + * @param array $objectInfo 订单对象信息 + * @param mixed $defaultShopProductId 默认平台 SKU ID + * @return mixed + */ + private function _getWxshipinShopProductId($orderInfo, $objectInfo, $defaultShopProductId = 0) + { + if ($orderInfo['shop_type'] != 'wxshipin') { + return $defaultShopProductId ? $defaultShopProductId : 0; + } + if ($defaultShopProductId && $defaultShopProductId != '0') { + return $defaultShopProductId; + } + + // 微信视频号发货回写依赖平台 SKU ID。失败订单恢复时 item 是重建的, + // 这里从订单转换阶段备份的原始平台明细中继承,避免恢复后 sku_id 变成 0。 + $addon = $objectInfo['addon']; + $addonData = is_array($addon) ? $addon : ($addon ? json_decode($addon, true) : array()); + if (!is_array($addonData) || empty($addonData['wxshipin_platform_items'])) { + return 0; + } + + $platformItems = $addonData['wxshipin_platform_items']; + if ($platformItems['shop_product_id'] && $platformItems['shop_product_id'] != '0') { + return $platformItems['shop_product_id']; + } + + foreach ((array)$platformItems['items'] as $item) { + if ($item['shop_product_id'] && $item['shop_product_id'] != '0') { + return $item['shop_product_id']; + } + } + + return 0; + } + public function getFailOrderByBn($smBns=array()) { $orderObj = app::get('ome')->model('orders'); @@ -925,6 +979,7 @@ class ome_order_fail $sql = "SELECT I.order_id FROM sdb_ome_order_objects as I LEFT JOIN sdb_ome_orders AS O ON I.order_id=O.order_id "; $sql .= " WHERE O.org_id>0 AND O.is_fail='true' AND O.edit_status='true' AND O.archive='1' "; + $sql .= " AND O.process_status='unconfirmed' "; $sql .= " AND I.goods_id=0 AND I.bn IN('". implode("','", $smBns). "') GROUP BY order_id LIMIT 0,1000"; $orderList = $orderObj->db->select($sql); @@ -942,12 +997,67 @@ class ome_order_fail $sql = "SELECT I.order_id FROM sdb_ome_order_objects as I LEFT JOIN sdb_ome_orders AS O ON I.order_id=O.order_id "; $sql .= " WHERE O.org_id>0 AND O.is_fail='true' AND O.edit_status='true' AND O.archive='1' "; + $sql .= " AND O.process_status='unconfirmed' "; $sql .= " AND I.goods_id=0 AND I.shop_goods_id IN('". implode("','", $shopGoodsIds). "') GROUP BY order_id LIMIT 0,1000"; $orderList = $orderObj->db->select($sql); return $orderList; } + + /** + * 统计可批量修复的失败订单数量 + * + * @param array $smBns + * @param bool $requireUnconfirmed true=与批量修复条件一致(未确认) + * @return int + */ + public function countFailOrderByBn($smBns = array(), $requireUnconfirmed = true) + { + $orderObj = app::get('ome')->model('orders'); + + if (empty($smBns)) { + return 0; + } + + $sql = "SELECT COUNT(DISTINCT O.order_id) AS cnt FROM sdb_ome_order_objects as I LEFT JOIN sdb_ome_orders AS O ON I.order_id=O.order_id "; + $sql .= " WHERE O.org_id>0 AND O.is_fail='true' AND O.edit_status='true' AND O.archive='1' "; + if ($requireUnconfirmed) { + $sql .= " AND O.process_status='unconfirmed' "; + } + $sql .= " AND I.goods_id=0 AND I.bn IN('". implode("','", $smBns). "')"; + + $row = $orderObj->db->selectrow($sql); + + return intval($row['cnt']); + } + + /** + * 统计可批量修复的失败订单数量(按平台商品ID) + * + * @param array $shopGoodsIds + * @param bool $requireUnconfirmed true=与批量修复条件一致(未确认) + * @return int + */ + public function countFailOrderByName($shopGoodsIds = array(), $requireUnconfirmed = true) + { + $orderObj = app::get('ome')->model('orders'); + + if (empty($shopGoodsIds)) { + return 0; + } + + $sql = "SELECT COUNT(DISTINCT O.order_id) AS cnt FROM sdb_ome_order_objects as I LEFT JOIN sdb_ome_orders AS O ON I.order_id=O.order_id "; + $sql .= " WHERE O.org_id>0 AND O.is_fail='true' AND O.edit_status='true' AND O.archive='1' "; + if ($requireUnconfirmed) { + $sql .= " AND O.process_status='unconfirmed' "; + } + $sql .= " AND I.goods_id=0 AND I.shop_goods_id IN('". implode("','", $shopGoodsIds). "')"; + + $row = $orderObj->db->selectrow($sql); + + return intval($row['cnt']); + } /** * 修复[淘宝平台]原始属性值 diff --git a/app/ome/lib/order/urgent.php b/app/ome/lib/order/urgent.php new file mode 100644 index 00000000..bb1d3296 --- /dev/null +++ b/app/ome/lib/order/urgent.php @@ -0,0 +1,672 @@ +model('orders')->dump($orderId, 'pay_status,order_id,order_bn,process_status,status,ship_status,sync,sync_fail_type,abnormal,pause,logi_no,source,createway,shop_id,shop_type,last_modified,createtime'); + if (!$order) { + return []; + } + + // 获取订单关联发货单列表,并使用最早创建的主发货单作为订单级状态时间参考 + $deliveryRows = app::get('ome')->model('delivery')->getDeliversByOrderId($orderId); + $delivery = $this->getPrimaryUrgentDelivery($deliveryRows); + + $details = $this->buildUrgentOrderDetails($orderId, $deliveryRows, $order); + $mainStatusData = $this->buildUrgentMainStatus($order, $details, $delivery); + + return [ + 'orderStatus' => $mainStatusData['orderStatus'], + 'status_update_time' => $mainStatusData['status_update_time'], + 'tracking_number' => $mainStatusData['tracking_number'], + 'exception_reason' => $mainStatusData['exception_reason'], + 'order_details' => $details, + 'is_split' => $this->isSplitOrder($order), + ]; + } + + /** + * 构建加急发货回告 DTO。 + * + * @param int|string $orderId + * @param string $orderBn + * @return array + */ + public function buildUrgentOrderReportDto($orderId, $orderBn = '') + { + $statusPayload = $this->buildUrgentOrderStatus($orderId); + if (empty($statusPayload['orderStatus'])) { + return []; + } + + if (!$orderBn) { + $order = app::get('ome')->model('orders')->dump($orderId, 'order_bn'); + $orderBn = $order['order_bn'] ?: ''; + } + + return $this->formatUrgentOrderReportDto($statusPayload, $orderBn); + } + + /** + * 构建矩阵出站参数 erp_synergy_callback_req_dto。 + * + * @param int|string $orderId + * @param string $orderBn + * @return array + */ + public function buildUrgentOrderReportParams($orderId, $orderBn = '') + { + return $this->wrapUrgentOrderDtoPayload( + $this->buildUrgentOrderReportDto($orderId, $orderBn), + 'erp_synergy_callback_req_dto' + ); + } + + /** + * 构建加急发货入站响应参数 urgent_delivery_notify_response。 + * + * @param int|string $orderId + * @param string $orderBn + * @return array + */ + public function buildUrgentNotifyResponseParams($orderId, $orderBn = '') + { + return $this->wrapUrgentOrderDtoPayload( + $this->buildUrgentOrderReportDto($orderId, $orderBn), + 'urgent_delivery_notify_response' + ); + } + + /** + * 将 DTO 内容包装为指定字段名的 JSON 字符串参数。 + * + * @param array $payload + * @param string $fieldName + * @return array + */ + protected function wrapUrgentOrderDtoPayload($payload, $fieldName) + { + if (!$payload) { + return []; + } + + $dtoJson = $this->encodeUrgentOrderDtoJson($payload); + if ($dtoJson === '') { + return []; + } + + return [ + $fieldName => $dtoJson, + ]; + } + + /** + * 编码加急回告 DTO,入站响应与主动回告共用。 + * + * @param array $payload + * @return string + */ + public function encodeUrgentOrderDtoJson($payload) + { + $dtoJson = json_encode($payload, JSON_UNESCAPED_UNICODE); + if ($dtoJson !== false) { + return $dtoJson; + } + + array_walk_recursive($payload, function (&$value) { + if (is_string($value)) { + $value = iconv('UTF-8', 'UTF-8//IGNORE', $value); + } + }); + + $dtoJson = json_encode($payload, JSON_UNESCAPED_UNICODE); + return $dtoJson === false ? '' : $dtoJson; + } + + /** + * 将状态聚合结果格式化为 erp_synergy_callback_req_dto 内容。 + * + * @param array $statusPayload + * @param string $orderBn + * @return array + */ + public function formatUrgentOrderReportDto($statusPayload, $orderBn) + { + $payload = [ + 'trade_order_code' => (string)$orderBn, + 'order_status' => (string)$statusPayload['orderStatus'], + 'status_update_time' => $statusPayload['status_update_time'] ?: date('Y-m-d H:i:s'), + 'tracking_number' => '', + 'exception_reason' => '', + 'extend_fields' => '{}', + 'order_details' => array_values((array)($statusPayload['order_details'] ?: [])), + 'is_split' => (bool)($statusPayload['is_split'] ?? false), + ]; + + if (!empty($statusPayload['tracking_number'])) { + $payload['tracking_number'] = (string)$statusPayload['tracking_number']; + } + if (!empty($statusPayload['exception_reason'])) { + $payload['exception_reason'] = (string)$statusPayload['exception_reason']; + } + + return $payload; + } + + /** + * 判断订单是否拆单,逻辑与发货同步 _is_split_order 保持一致。 + * + * @param array $order + * @return bool + */ + public function isSplitOrder($order) + { + if ($order['ship_status'] == '2' + || $order['process_status'] == 'remain_cancel' + || $order['process_status'] == 'splitting') { + return true; + } + + return count($this->getOrderDeliveryIds($order['order_id'])) > 1; + } + + /** + * 获取订单有效主发货单列表。 + * + * @param int|string $orderId + * @return array + */ + protected function getOrderDeliveryIds($orderId) + { + $sql = "SELECT d.delivery_id,d.status,d.delivery_time + FROM sdb_ome_delivery_order AS dord + LEFT JOIN sdb_ome_delivery AS d + ON(dord.delivery_id=d.delivery_id) + WHERE dord.order_id='" . intval($orderId) . "' + AND d.parent_id='0' + AND d.disabled='false' + AND d.status IN('succ','progress','ready')"; + $rows = kernel::database()->select($sql); + + $deliveryIds = []; + foreach ((array)$rows as $row) { + $deliveryIds[$row['delivery_id']] = $row; + } + + return $deliveryIds; + } + + /** + * 解析加急状态的更新时间 + * + * 按优先级从发货单和订单中取最合适的时间戳,格式化为 Y-m-d H:i:s 返回。 + * 优先级:发货时间 > 发货单修改时间 > 订单修改时间 > 订单创建时间 + * + * @param array $order 订单信息 + * @param array $delivery 发货单信息 + * @return string 格式化后的时间字符串 + */ + protected function resolveUrgentStatusUpdateTime($order, $delivery) + { + // 按优先级取时间戳 + $timestamp = 0; + if (!empty($delivery['delivery_time'])) { + $timestamp = $delivery['delivery_time']; + } elseif (!empty($delivery['last_modified'])) { + $timestamp = $delivery['last_modified']; + } elseif (!empty($order['last_modified'])) { + $timestamp = $order['last_modified']; + } elseif (!empty($order['createtime'])) { + $timestamp = $order['createtime']; + } + + // 无有效时间戳时返回当前时间 + if (!$timestamp) { + return date('Y-m-d H:i:s'); + } + // 数字型时间戳转格式化字符串 + if (is_numeric($timestamp)) { + return date('Y-m-d H:i:s', intval($timestamp)); + } + + return (string)$timestamp; + } + + /** + * 构建加急订单的商品明细列表 + * + * 优先使用 order_items 表(含 SKU 信息)拼装明细; + * 若 order_items 无有效数据则降级使用 order_objects 表。 + * + * @param int|string $orderId 订单ID + * @return array 订单明细数组,每项包含 sub_trade_order_code、item_id、sku_id、quantity + */ + protected function buildUrgentOrderDetails($orderId, $deliveryRows = [], $order = []) + { + $details = []; + $deliveryRows = (array)$deliveryRows; + // 查询订单货品和订单商品行 + $objectRows = app::get('ome')->model('order_objects')->getList('obj_id,oid,shop_goods_id,quantity', ['order_id' => $orderId, 'delete' => 'false']); + $orderItemRows = app::get('ome')->model('order_items')->getList('item_id,obj_id,shop_goods_id,shop_product_id,nums,item_type', ['order_id' => $orderId, 'delete' => 'false']); + $deliveryDetailRows = app::get('ome')->model('delivery_items_detail')->getList( + 'delivery_id,order_obj_id,order_item_id,oid,number', + ['order_id' => $orderId] + ); + + // 构建 obj_id => object 映射,便于关联查找 + $objectMap = []; + foreach ((array)$objectRows as $objectRow) { + $objectMap[$objectRow['obj_id']] = $objectRow; + } + + // 统计每个 obj_id 下的 order_items 数量,用于判断 obj 级映射是否会歧义。 + $objectItemCountMap = []; + foreach ((array)$orderItemRows as $itemRow) { + if (empty($itemRow['obj_id'])) { + continue; + } + if (!isset($objectItemCountMap[$itemRow['obj_id']])) { + $objectItemCountMap[$itemRow['obj_id']] = 0; + } + $objectItemCountMap[$itemRow['obj_id']]++; + } + + // 构建发货单映射与订单货品 -> 发货单映射,便于按真实发货单状态生成明细状态 + $deliveryMap = []; + foreach ($deliveryRows as $deliveryRow) { + $deliveryMap[$deliveryRow['delivery_id']] = $deliveryRow; + } + + $detailDeliveryMap = []; + foreach ((array)$deliveryDetailRows as $deliveryDetailRow) { + if (!empty($deliveryDetailRow['order_item_id'])) { + $detailDeliveryMap['item_' . $deliveryDetailRow['order_item_id']] = $deliveryMap[$deliveryDetailRow['delivery_id']]; + } + if (!empty($deliveryDetailRow['order_obj_id'])) { + $detailDeliveryMap['obj_' . $deliveryDetailRow['order_obj_id']] = $deliveryMap[$deliveryDetailRow['delivery_id']]; + } + if (!empty($deliveryDetailRow['oid'])) { + $detailDeliveryMap['oid_' . $deliveryDetailRow['oid']] = $deliveryMap[$deliveryDetailRow['delivery_id']]; + } + } + + // 优先从 order_items 构建明细(包含 SKU 维度信息) + foreach ((array)$orderItemRows as $itemRow) { + $objectRow = $objectMap[$itemRow['obj_id']] ?: []; + if (!$objectRow) { + continue; + } + // 过滤非商品类型且无商品编码的行 + if ($itemRow['item_type'] !== 'product' && !$itemRow['shop_product_id'] && !$itemRow['shop_goods_id']) { + continue; + } + + if (empty($objectRow['oid'])){ + continue; + } + + $deliveryRow = []; + if (!empty($detailDeliveryMap['item_' . $itemRow['item_id']])) { + $deliveryRow = $detailDeliveryMap['item_' . $itemRow['item_id']]; + } elseif (!empty($objectRow['oid']) && !empty($detailDeliveryMap['oid_' . $objectRow['oid']])) { + $deliveryRow = $detailDeliveryMap['oid_' . $objectRow['oid']]; + } elseif (($objectItemCountMap[$itemRow['obj_id']] ?: 0) === 1 && !empty($detailDeliveryMap['obj_' . $itemRow['obj_id']])) { + // 仅当该 obj_id 下只有一个明细时,才允许退化到 obj 级发货单映射,避免把别的明细发货单借给当前明细。 + $deliveryRow = $detailDeliveryMap['obj_' . $itemRow['obj_id']]; + } + $detailStatus = $this->buildUrgentDetailStatus($deliveryRow, $order); + $trackingNumber = $this->resolveDetailTrackingNumber($deliveryRow, $detailStatus['order_status']); + + $details[] = [ + 'sub_trade_order_code' => (string)$objectRow['oid'], + 'item_id' => (string)($itemRow['shop_goods_id'] ?: $objectRow['shop_goods_id']), + 'sku_id' => (string)$itemRow['shop_product_id'], + 'quantity' => intval($itemRow['nums']), + 'sub_trade_order_status' => $detailStatus['order_status'], + 'status_update_time' => $detailStatus['status_update_time'], + 'tracking_number' => $trackingNumber, + ]; + } + + if ($details) { + return $details; + } + + // 降级方案:直接使用 order_objects 构建明细(无 SKU 信息) + foreach ((array)$objectRows as $objectRow) { + $deliveryRow = []; + if (!empty($objectRow['oid']) && !empty($detailDeliveryMap['oid_' . $objectRow['oid']])) { + $deliveryRow = $detailDeliveryMap['oid_' . $objectRow['oid']]; + } elseif (!empty($detailDeliveryMap['obj_' . $objectRow['obj_id']])) { + $deliveryRow = $detailDeliveryMap['obj_' . $objectRow['obj_id']]; + } + $detailStatus = $this->buildUrgentDetailStatus($deliveryRow, $order); + $trackingNumber = $this->resolveDetailTrackingNumber($deliveryRow, $detailStatus['order_status']); + $details[] = [ + 'sub_trade_order_code' => (string)$objectRow['oid'], + 'item_id' => (string)$objectRow['shop_goods_id'], + 'sku_id' => '', + 'quantity' => intval($objectRow['quantity']), + 'sub_trade_order_status' => $detailStatus['order_status'], + 'status_update_time' => $detailStatus['status_update_time'], + 'tracking_number' => $trackingNumber, + ]; + } + + return $details; + } + + /** + * 选取订单关联的主发货单,优先取最早创建的有效发货单。 + * + * @param array $deliveryRows + * @return array + */ + protected function getPrimaryUrgentDelivery($deliveryRows) + { + $primaryDelivery = []; + foreach ((array)$deliveryRows as $deliveryRow) { + if (!$primaryDelivery) { + $primaryDelivery = $deliveryRow; + continue; + } + + $primaryCreateTime = intval($primaryDelivery['create_time']); + $currentCreateTime = intval($deliveryRow['create_time']); + if ($currentCreateTime && (!$primaryCreateTime || $currentCreateTime < $primaryCreateTime)) { + $primaryDelivery = $deliveryRow; + } + } + + return $primaryDelivery; + } + + /** + * 按发货单和发货回写日志构建订单明细状态。 + * + * 规则: + * - 订单取消 → CANCELLED + * - 无发货单 → ORDER_CREATED + * - 明细状态只认当前明细自身映射到的发货单,不借用同订单其它明细的发货单 + * - 有发货单且未发货完成 → WAREHOUSE_PROCESSING + * - 有发货单且已发货完成时,再用 shipment_log 区分: + * - shipment_log 失败 → WAREHOUSE_CONSIGN_FAIL + * - shipment_log 成功 → SHIPPED + * - 无明确回写结果 → WAREHOUSE_PROCESSING + * + * @param array $delivery + * @param array $order + * @return array + */ + protected function buildUrgentDetailStatus($delivery, $order) + { + $detailStatus = 'ORDER_CREATED'; + $detailTime = $this->resolveUrgentDetailStatusUpdateTime($delivery, $order); + + if ($order['status'] == 'dead' || $order['process_status'] == 'cancel' || $order['pay_status'] == '5') { + $detailStatus = 'CANCELLED'; + } elseif ($delivery) { + if ($delivery['status'] != 'succ' && $delivery['process'] != 'true') { + $detailStatus = 'WAREHOUSE_PROCESSING'; + } else { + $shipmentLog = $this->getLatestShipmentLog($order['order_bn'], $delivery['logi_no']); + if ($shipmentLog['status'] == 'fail') { + $detailStatus = 'WAREHOUSE_CONSIGN_FAIL'; + $detailTime = $this->formatUrgentTimestamp($shipmentLog['updateTime']) ?: $detailTime; + } elseif ($shipmentLog['status'] == 'succ') { + $detailStatus = 'SHIPPED'; + $detailTime = $this->formatUrgentTimestamp($shipmentLog['updateTime']) ?: $detailTime; + } else { + $detailStatus = 'WAREHOUSE_PROCESSING'; + } + } + } + + return [ + 'order_status' => $detailStatus, + 'status_update_time' => $detailTime, + ]; + } + + /** + * 解析订单明细状态更新时间。 + * + * 若存在发货单则取发货单创建时间,否则取订单创建时间。 + * + * @param array $delivery + * @param array $order + * @return string + */ + protected function resolveUrgentDetailStatusUpdateTime($delivery, $order) + { + $timestamp = $delivery['create_time'] ?: $order['createtime']; + return $this->formatUrgentTimestamp($timestamp); + } + + /** + * 按子交易单号聚合明细,同一子单取优先级最高的状态。 + * + * @param array $details + * @return array + */ + protected function aggregateDetailsBySubTradeOrder($details) + { + $priorityMap = [ + 'WAREHOUSE_CONSIGN_FAIL' => 5, + 'SHIPPED' => 4, + 'CANCELLED' => 3, + 'WAREHOUSE_PROCESSING' => 2, + 'ORDER_CREATED' => 1, + ]; + + $grouped = []; + foreach ((array)$details as $detail) { + $oid = (string)$detail['sub_trade_order_code']; + if ($oid === '') { + continue; + } + if (!isset($grouped[$oid])) { + $grouped[$oid] = $detail; + continue; + } + + $currentPriority = $priorityMap[$grouped[$oid]['sub_trade_order_status']] ?? 0; + $newPriority = $priorityMap[$detail['sub_trade_order_status']] ?? 0; + if ($newPriority > $currentPriority) { + $grouped[$oid] = $detail; + } + } + + return array_values($grouped); + } + + /** + * 解析子单运单号:SHIPPED 时取映射发货单 delivery.logi_no,主推与入站响应共用。 + * + * @param array $deliveryRow + * @param string $detailStatus + * @return string + */ + protected function resolveDetailTrackingNumber($deliveryRow, $detailStatus) + { + if ($detailStatus !== 'SHIPPED' || empty($deliveryRow['logi_no'])) { + return ''; + } + + return (string)$deliveryRow['logi_no']; + } + + /** + * 从已发货子单中选取主单运单号:优先最早 status_update_time,时间相同按子单号升序。 + * 主单 tracking_number 与 order_details[].tracking_number 均来自 delivery.logi_no。 + * + * @param array $subOrders + * @return string + */ + protected function resolveMainTrackingFromShippedSubOrders($subOrders) + { + $shippedSubs = []; + foreach ((array)$subOrders as $subOrder) { + if ($subOrder['sub_trade_order_status'] !== 'SHIPPED') { + continue; + } + if (empty($subOrder['tracking_number'])) { + continue; + } + $shippedSubs[] = $subOrder; + } + + if (!$shippedSubs) { + return ''; + } + + usort($shippedSubs, function ($left, $right) { + $timeCompare = strcmp((string)$left['status_update_time'], (string)$right['status_update_time']); + if ($timeCompare !== 0) { + return $timeCompare; + } + + return strcmp((string)$left['sub_trade_order_code'], (string)$right['sub_trade_order_code']); + }); + + return (string)$shippedSubs[0]['tracking_number']; + } + + /** + * 根据子单状态聚合主结构状态与时间。 + * + * 规则: + * - 任一子单 WAREHOUSE_CONSIGN_FAIL → 主单异常态,不返回运单号 + * - 否则按优先级 SHIPPED > CANCELLED > WAREHOUSE_PROCESSING > ORDER_CREATED + * - 主单 SHIPPED 时,运单号取已发货子单对应发货单 logi_no;多个 SHIPPED 时取最早时间,时间相同按子单号升序 + * - 主结构 status_update_time 取命中状态对应子单时间 + * + * @param array $order + * @param array $details + * @param array $delivery + * @return array + */ + protected function buildUrgentMainStatus($order, $details, $delivery = []) + { + $defaultStatus = 'ORDER_CREATED'; + $defaultTime = $this->resolveUrgentStatusUpdateTime($order, $delivery); + + if (!$details) { + return [ + 'orderStatus' => $defaultStatus, + 'status_update_time' => $defaultTime, + 'tracking_number' => '', + 'exception_reason' => '', + ]; + } + + $subOrders = $this->aggregateDetailsBySubTradeOrder($details); + + $failSubOrder = null; + foreach ($subOrders as $subOrder) { + if ($subOrder['sub_trade_order_status'] !== 'WAREHOUSE_CONSIGN_FAIL') { + continue; + } + if (!$failSubOrder || strcmp((string)$subOrder['status_update_time'], (string)$failSubOrder['status_update_time']) < 0) { + $failSubOrder = $subOrder; + } + } + if ($failSubOrder) { + return [ + 'orderStatus' => 'WAREHOUSE_CONSIGN_FAIL', + 'status_update_time' => $failSubOrder['status_update_time'], + 'tracking_number' => '', + 'exception_reason' => '发货状态回写平台失败', + ]; + } + + $priorityMap = [ + 'SHIPPED' => 4, + 'CANCELLED' => 3, + 'WAREHOUSE_PROCESSING' => 2, + 'ORDER_CREATED' => 1, + ]; + + $bestDetail = [ + 'sub_trade_order_status' => $defaultStatus, + 'status_update_time' => $defaultTime, + ]; + + foreach ($subOrders as $subOrder) { + $detailStatus = $subOrder['sub_trade_order_status']; + $detailPriority = $priorityMap[$detailStatus] ?? 0; + $bestPriority = $priorityMap[$bestDetail['sub_trade_order_status']] ?? 0; + if ($detailPriority > $bestPriority) { + $bestDetail = $subOrder; + } + } + + $trackingNo = ''; + if ($bestDetail['sub_trade_order_status'] === 'SHIPPED') { + $trackingNo = $this->resolveMainTrackingFromShippedSubOrders($subOrders); + } + + return [ + 'orderStatus' => $bestDetail['sub_trade_order_status'], + 'status_update_time' => $bestDetail['status_update_time'], + 'tracking_number' => $trackingNo, + 'exception_reason' => '', + ]; + } + + /** + * 读取当前订单+运单号对应的最新发货回写日志。 + * + * @param string $orderBn + * @param string $logiNo + * @return array + */ + protected function getLatestShipmentLog($orderBn, $logiNo) + { + if (!$orderBn || !$logiNo) { + return []; + } + + $rows = app::get('ome')->model('shipment_log')->getList( + 'status,updateTime,deliveryCode', + ['orderBn' => $orderBn, 'deliveryCode' => $logiNo], + 0, + 1, + 'updateTime DESC, log_id DESC' + ); + + return $rows ? $rows[0] : []; + } + + /** + * 统一格式化时间戳。 + * + * @param mixed $timestamp + * @return string + */ + protected function formatUrgentTimestamp($timestamp) + { + if (!$timestamp) { + return date('Y-m-d H:i:s'); + } + if (is_numeric($timestamp)) { + return date('Y-m-d H:i:s', intval($timestamp)); + } + + return (string)$timestamp; + } +} diff --git a/app/ome/lib/receipt/reship.php b/app/ome/lib/receipt/reship.php index 46bf8e67..918be2b6 100644 --- a/app/ome/lib/receipt/reship.php +++ b/app/ome/lib/receipt/reship.php @@ -86,14 +86,22 @@ class ome_receipt_reship if (!empty($reship_item)) { $product_ids = array_column($reship_item, 'product_id'); $basicMaterialObj = app::get('material')->model('basic_material'); - $basic_materials = $basicMaterialObj->getList('bm_id,type', array('bm_id' => $product_ids)); + $basic_materials = $basicMaterialObj->getList('bm_id,type,is_ctrl_store', array('bm_id' => $product_ids)); + $basicMaterialList = array_column($basic_materials, null, 'bm_id'); + $basic_materials = array_column($basic_materials, 'type', 'bm_id'); $filtered_reship_item = array(); foreach ($reship_item as $item) { $bm_id = $item['product_id']; + + // 过滤掉基础物料属性为:虚拟类型 + 不管控库存(type=5 && is_ctrl_store=2) if (isset($basic_materials[$bm_id]) && $basic_materials[$bm_id] == 5) { - continue; + // 只过滤不管控库存的虚拟类型基础物料 + if(isset($basicMaterialList[$bm_id]) && $basicMaterialList[$bm_id]['is_ctrl_store'] == 2){ + continue; + } } + $filtered_reship_item[] = $item; } $reship_item = $filtered_reship_item; @@ -101,6 +109,7 @@ class ome_receipt_reship if (empty($reship_item)) { return array(); } + // 外部订单 $dextMdl = app::get('console')->model('delivery_extension'); $delivery_ext = $dextMdl->dump(array('delivery_bn' => $delivery['delivery_bn']), 'original_delivery_bn'); diff --git a/app/ome/lib/sales/price.php b/app/ome/lib/sales/price.php index dd402e94..de08cb4e 100644 --- a/app/ome/lib/sales/price.php +++ b/app/ome/lib/sales/price.php @@ -59,12 +59,6 @@ class ome_sales_price{ return $order; } - /** - * calculate - * @param mixed $order_original_data 数据 - * @param mixed $sales_data 数据 - * @return mixed 返回值 - */ public function calculate($order_original_data,&$sales_data){ if(!$this->_check($order_original_data, $sales_data)){ @@ -121,6 +115,8 @@ class ome_sales_price{ $all_sale_price += $sale_item['price']*$sale_item['nums']; $all_pmt_price += $sale_item['pmt_price']; } + + $all_pmt_price = sprintf('%.2f', $all_pmt_price); $all_sale_price = sprintf('%.2f', $all_sale_price); $old_discount = sprintf('%.2f', $sales_data['discount']); @@ -223,13 +219,6 @@ class ome_sales_price{ $sales_data['actually_amount'] += $sales_data['service_price']; } - /** - * 获取ItemProductSalePrice - * @param mixed $saleData 数据 - * @param mixed $arrOrder arrOrder - * @param mixed $productGoods productGoods - * @return mixed 返回结果 - */ public function getItemProductSalePrice($saleData, $arrOrder, $productGoods) { $itemSalePrice = array(); foreach ($saleData as $orderId => $val) { diff --git a/app/ome/lib/service/aftersale.php b/app/ome/lib/service/aftersale.php index 97e8042d..492c248e 100644 --- a/app/ome/lib/service/aftersale.php +++ b/app/ome/lib/service/aftersale.php @@ -106,7 +106,7 @@ class ome_service_aftersale{ if ($returninfo['source'] == 'matrix' && in_array($returninfo['shop_type'],array('bbc','ecos.b2c','ecos.b2b2c.stdsrc','360buy','meituan4medicine'))){ $returninfo['memo'] = $memo; - }elseif($returninfo['source'] == 'matrix' && in_array($returninfo['shop_type'], array('luban'))){ + }elseif($returninfo['source'] == 'matrix' && in_array($returninfo['shop_type'], array('luban','jd'))){ //使用售后申请单上的内容 $returninfo['memo'] = $memo; } @@ -379,7 +379,7 @@ class ome_service_aftersale{ */ public function returngoods_confirm($return_id){ $returnModel = app::get('ome')->model('return_product'); - $returninfo = $returnModel->db_dump(array('return_id'=>$return_id,'source'=>'matrix'),'return_bn,return_id,shop_id,kinds'); + $returninfo = $returnModel->db_dump(array('return_id'=>$return_id,'source'=>'matrix'),'return_bn,return_id,shop_id,kinds,platform_order_bn,order_id'); if($returninfo){ $rs = kernel::single('erpapi_router_request')->set('shop', $returninfo['shop_id'])->aftersale_returnGoodsSign($returninfo); $rs = kernel::single('erpapi_router_request')->set('shop', $returninfo['shop_id'])->aftersale_returnGoodsConfirm($returninfo); diff --git a/app/ome/model/delivery.php b/app/ome/model/delivery.php index bbaf82ad..feb1e82d 100644 --- a/app/ome/model/delivery.php +++ b/app/ome/model/delivery.php @@ -2,6 +2,7 @@ class ome_mdl_delivery extends dbeav_model { + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; //public $filter_use_like = true; public $has_many = array( 'delivery_items' => 'delivery_items', @@ -38,16 +39,24 @@ class ome_mdl_delivery extends dbeav_model parent::__construct($app); } + /** + * 扩展发货单 Finder 过滤条件,支持加急标签相关筛选与自定义 SQL 条件。 + * + * @param array $filter + * @param string|null $tableAlias + * @param array|null $baseWhere + * @return string + */ public function _filter($filter, $tableAlias = null, $baseWhere = null) { $tPre = ($tableAlias ? $tableAlias : '`' . $this->table_name(true) . '`') . '.'; $tmpBaseWhere = kernel::single('ome_filter_encrypt')->encrypt($filter, $this->__encrypt_cols, $tPre, 'delivery'); $baseWhere = $baseWhere ? array_merge((array)$baseWhere, (array)$tmpBaseWhere) : (array)$tmpBaseWhere; - + //setting $deliveryIds = array(); $where = ''; - + //filter if (isset($filter['extend_delivery_id'])) { //delivery_id @@ -56,17 +65,17 @@ class ome_mdl_delivery extends dbeav_model { $tempDlyIds[$extend_delivery_id] = $extend_delivery_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['extend_delivery_id']); } - + if (isset($filter['member_uname'])) { $memberObj = $this->app->model("members"); $rows = $memberObj->getList('member_id', array('uname|has' => $filter['member_uname'])); @@ -94,23 +103,23 @@ class ome_mdl_delivery extends dbeav_model $deliOrderObj = $this->app->model("delivery_order"); $rows = $deliOrderObj->getList('delivery_id', array('order_id' => $orderId)); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['order_bn']); } @@ -118,30 +127,30 @@ class ome_mdl_delivery extends dbeav_model if (isset($filter['material_bn'])){ if(strpos($filter['material_bn'], "\n") !== false){ $material_bns = array_unique(array_map('trim', array_filter(explode("\n", $filter['material_bn'])))); - + $filter['material_bn'] = $material_bns; } //search_delivery_items $itemsObj = app::get('ome')->model("delivery_items"); $rows = $itemsObj->getDeliveryIdByPbn($filter); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['material_bn']); } @@ -156,23 +165,23 @@ class ome_mdl_delivery extends dbeav_model //search_delivery_items $itemsObj = $this->app->model("delivery_items"); $rows = $itemsObj->getDeliveryIdByPbarcode($filter); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + //unset unset($filter['product_barcode']); } @@ -180,35 +189,61 @@ class ome_mdl_delivery extends dbeav_model if (isset($filter['logi_no_ext'])) { $logObj = $this->app->model("delivery_log"); $rows = $logObj->getDeliveryIdByLogiNO($filter['logi_no_ext']); - + //delivery_id $tempDlyIds = array(0); foreach($rows as $row) { $temp_dly_id = $row['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['logi_no_ext']); } - + if (isset($filter['addonSQL'])) { $where .= ' AND ' . $filter['addonSQL']; unset($filter['addonSQL']); } - + if (!empty($filter['delivery_label_code'])) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.addslashes($filter['delivery_label_code']).'" + )'; + unset($filter['delivery_label_code']); + } + if (isset($filter['urgent_delivery'])) { + if ($filter['urgent_delivery'] === 'true' || $filter['urgent_delivery'] === true || $filter['urgent_delivery'] == 1) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.self::URGENT_LABEL_CODE.'" + )'; + } else { + $where .= ' AND NOT EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.self::URGENT_LABEL_CODE.'" + )'; + } + unset($filter['urgent_delivery']); + } if (isset($filter['delivery_ident'])) { //delivery_id $tempDlyIds = array(0); - + $arr_delivery_ident = explode('_', $filter['delivery_ident']); $mdl_queue = app::get('ome')->model("print_queue"); if (count($arr_delivery_ident) == 2) { @@ -236,37 +271,37 @@ class ome_mdl_delivery extends dbeav_model } } } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['delivery_ident']); } - + if (isset($filter['ship_tel_mobile'])) { $where .= ' AND (ship_tel=\'' . $filter['ship_tel_mobile'] . '\' or ship_mobile=\'' . $filter['ship_tel_mobile'] . '\')'; unset($filter['ship_tel_mobile']); } - + if ($filter['todo'] == 1) { $where .= " AND ({$tPre}stock_status='false' or {$tPre}expre_status='false' or {$tPre}deliv_status='false')"; unset($filter['todo']); } - + if ($filter['todo'] == 2) { $where .= " AND ({$tPre}stock_status='false' or {$tPre}expre_status='false')"; unset($filter['todo']); } - + if ($filter['todo'] == 3) { $where .= " AND ({$tPre}expre_status='false' or {$tPre}deliv_status='false')"; unset($filter['todo']); } - + if ($filter['todo'] == 4) { $where .= " AND {$tPre}expre_status='false'"; unset($filter['todo']); @@ -323,17 +358,17 @@ class ome_mdl_delivery extends dbeav_model foreach ($_rows as $_orders) { $temp_dly_id = $_orders['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['mark_text']); } } @@ -348,17 +383,17 @@ class ome_mdl_delivery extends dbeav_model foreach ($_rows as $_orders) { $temp_dly_id = $_orders['delivery_id']; - + $tempDlyIds[$temp_dly_id] = $temp_dly_id; } - + //intersection if(empty($deliveryIds)){ $deliveryIds = $tempDlyIds; }else{ $deliveryIds = array_intersect($deliveryIds, $tempDlyIds); } - + unset($filter['custom_mark']); } } @@ -367,7 +402,7 @@ class ome_mdl_delivery extends dbeav_model if($deliveryIds){ $where .= " AND delivery_id IN (". implode(',', $deliveryIds) .")"; } - + return parent::_filter($filter, $tableAlias, $baseWhere) . $where; } @@ -622,10 +657,10 @@ class ome_mdl_delivery extends dbeav_model }else{ $ids = array($parent_id); } - + return $ids; } - + foreach ($rows as $item) { $data[] = $item['delivery_id']; } @@ -864,40 +899,40 @@ class ome_mdl_delivery extends dbeav_model if($dly['delivery_time']){ $delivery_time = $delivery_time ? min($delivery_time, $dly['delivery_time']) : $dly['delivery_time']; } - + //承诺最晚送达时间(取最早时间) if($dly['promised_sign_time']){ $promised_sign_time = $promised_sign_time ? min($promised_sign_time, $dly['promised_sign_time']) : $dly['promised_sign_time']; } - + //计划发货时间(取最早时间) if($dly['promised_collect_time']){ $promised_collect_time = $promised_collect_time ? min($promised_collect_time, $dly['promised_collect_time']) : $dly['promised_collect_time']; } - + //计划发货时间(取最早时间) if($dly['promise_outbound_time']){ $promise_outbound_time = $promise_outbound_time ? min($promise_outbound_time, $dly['promise_outbound_time']) : $dly['promise_outbound_time']; } - + //计划发货时间(取最早时间) if($dly['plan_sign_time']){ $plan_sign_time = $plan_sign_time ? min($plan_sign_time, $dly['plan_sign_time']) : $dly['plan_sign_time']; } - + //物流服务标签(取合集) if($dly['promise_service']){ $promiseServiceList = array_merge($promiseServiceList, explode(',', $dly['promise_service'])); $promiseServiceList = array_unique($promiseServiceList); } - + //物流升级服务 if($dly['cpup_service']){ $cpup_service = array_merge($cpup_service, explode(',', $dly['cpup_service'])); $cpup_service = array_unique($cpup_service); } } - + } #获取发货单累计重量 @@ -968,12 +1003,12 @@ class ome_mdl_delivery extends dbeav_model if ($r_time) { $new_dly['ship_time'] = $r_time; } - + //未发货之前,不能赋值,否则客户导出时有异议 // if ($delivery_time){ // $new_dly['delivery_time'] = $delivery_time; // } - + if ($promised_collect_time){ $new_dly['promised_collect_time'] = $promised_collect_time; } @@ -985,22 +1020,22 @@ class ome_mdl_delivery extends dbeav_model if ($order_createtime) { $new_dly['order_createtime'] = $order_createtime; } - + //承诺最晚出库时间 if($promise_outbound_time){ $new_dly['promise_outbound_time'] = $promise_outbound_time; } - + //承诺计划送达时间 if($plan_sign_time){ $new_dly['plan_sign_time'] = $plan_sign_time; } - + //物流服务标签 if($promiseServiceList){ $new_dly['promise_service'] = implode(',', $promiseServiceList); } - + //save if ($this->save($new_dly)) { //创建大发货单 @@ -1327,12 +1362,12 @@ class ome_mdl_delivery extends dbeav_model } else { $ids[] = $dly_ids; } - + $memo_log = ''; if ($memo) { $memo_log .= ',备注:' . $memo; } - + $data['memo'] = $memo; $data['status'] = 'back'; $data['logi_no'] = null; @@ -1377,7 +1412,7 @@ class ome_mdl_delivery extends dbeav_model } $opObj->write_log('delivery_back@ome', $item, '发货单撤销成功' . $memo_log); - + // 发货单取消成功通知 $this->sendDeliveryCancelSuccessNotify($deliveryInfo, $memo); @@ -2015,7 +2050,7 @@ class ome_mdl_delivery extends dbeav_model } return ($arr1['product_id'] < $arr2['product_id']) ? -1 : 1; } - + /** * 新建发货单 * @@ -2045,7 +2080,7 @@ class ome_mdl_delivery extends dbeav_model $deliveryEventStartTime = microtime(true); kernel::single('ome_event_trigger_shop_delivery')->delivery_add($data['delivery_id']); $deliveryEventTime = microtime(true) - $deliveryEventStartTime; - + // 记录发货单事件触发性能数据 ome_api_log::add_message('event', 'delivery_add', $deliveryEventTime, array( 'delivery_id' => $data['delivery_id'] @@ -2075,7 +2110,7 @@ class ome_mdl_delivery extends dbeav_model $objIdArr = array_column($order_items, 'obj_id'); $objectsList = $orderObjMdl->getList('obj_id,goods_id', ['order_id'=>$order_id, 'obj_id'=>$objIdArr]); $objectsList = array_column($objectsList, null, 'obj_id'); - + foreach ($delivery['delivery_items'] as $di => $dv) { $sm_id = 0; foreach ($order_items as $ov) { @@ -2127,7 +2162,7 @@ class ome_mdl_delivery extends dbeav_model }elseif($order['platform_order_bn']){ $data['platform_order_bn'] = $order['platform_order_bn']; } - + $logi_name = ""; if ($is_diff_order) { //补差价订单直接生成已发货的发货单 不涉及库存 @@ -2141,11 +2176,11 @@ class ome_mdl_delivery extends dbeav_model if ($delivery['type']) { $data['type'] = $delivery['type']; } - + //计算预计物流费用 // 记录运费和重量计算开始时间 $freightStartTime = microtime(true); - + $weight = 0; if (isset($delivery['weight'])) { $weight = $delivery['weight']; @@ -2168,7 +2203,7 @@ class ome_mdl_delivery extends dbeav_model $price = $this->getDeliveryFreight($area_id, $delivery['logi_id'], $weight); $dly_corp = $oDly_corp->dump($delivery['logi_id']); $logi_name = $dly_corp['name']; - + // 计算保价费用 $protect = $dly_corp['protect']; if ($protect == 'true') { @@ -2177,10 +2212,10 @@ class ome_mdl_delivery extends dbeav_model $cost_protect = max($protect_price, $dly_corp['minprice']); } } - + // 计算运费和重量计算总耗时 $freightTime = microtime(true) - $freightStartTime; - + // 记录运费和重量计算性能数据 ome_api_log::add_message('freight', 'freight_calculation', $freightTime, array( 'delivery_id' => $data['delivery_id'] ?? '', @@ -2189,7 +2224,7 @@ class ome_mdl_delivery extends dbeav_model 'weight' => $weight, 'freight_price' => $price )); - + //[同城配]配送方式 if($dly_corp['corp_model'] == 'instatnt'){ //同城配送 @@ -2198,7 +2233,7 @@ class ome_mdl_delivery extends dbeav_model //商家配送 $data['delivery'] = 'seller'; } - + //order has logi_info:aikucun if ($delivery['delivery_waybillCode']) { $data['logi_no'] = $delivery['delivery_waybillCode']; @@ -2217,15 +2252,15 @@ class ome_mdl_delivery extends dbeav_model $data['member_id'] = $delivery['member_id'] ? $delivery['member_id'] : $order['member_id']; $data['shop_id'] = $order['shop_id']; $data['shop_type'] = $order['shop_type']; - + $data['delivery_items'] = $delivery['delivery_items']; $data['consignee'] = $ship_info; - + //权限相关 $data['org_id'] = $order['org_id']; //运营组织 $data['betc_id'] = $order['betc_id']; //贸易公司ID $data['cos_id'] = $order['cos_id']; //组织架构ID - + //支持四、五级地区 $temp_area = explode('/', $area_chs); $data['consignee']['province'] = $temp_area[0]; @@ -2244,7 +2279,7 @@ class ome_mdl_delivery extends dbeav_model if ($order['order_type'] == 'jisuxianhuo') { $data['bool_type'] = $data['bool_type'] | ome_delivery_bool_type::__JISU_CODE; } - + if ($order['order_type'] == 'platform') { $data['original_delivery_bn'] = $delivery_bn; $data['bool_type'] = ($data['bool_type'] ? $data['bool_type'] : 0) | ome_delivery_bool_type::__PLATFORM_CODE; @@ -2254,13 +2289,13 @@ class ome_mdl_delivery extends dbeav_model $data['bool_type'] = ($data['bool_type'] ? $data['bool_type'] : 0) | ome_delivery_bool_type::__SHSM_CODE; } } - + // format $bns = array(); $totalNum = 0; foreach ($data['delivery_items'] as $dlyItemKey => $v) { $product_id = $v['product_id']; - + $totalNum += $v['number']; $bns[$v['product_id']] = $v['bn']; } @@ -2279,17 +2314,17 @@ class ome_mdl_delivery extends dbeav_model if (kernel::single('ome_order_bool_type')->isCPUP($order['order_bool_type'])) { $data['bool_type'] = $data['bool_type'] | ome_delivery_bool_type::__CPUP_CODE; - + //未发货之前,不能赋值,否则客户导出时有异议 //$data['delivery_time'] = $orderExtend['latest_delivery_time']; - + $data['cpup_service'] = $orderExtend['cpup_service']; $data['promise_service'] = $orderExtend['promise_service']; $data['promised_collect_time'] = $orderExtend['promised_collect_time']; $data['promised_sign_time'] = $orderExtend['promised_sign_time']; $data['cpup_addon'] = serialize($orderExtend); } - + //[翱象]相关信息 if(in_array($order['shop_type'], array('taobao', 'tmall')) && $order['order_bool_type'] && $orderExtend){ //是否翱象订单 @@ -2298,25 +2333,25 @@ class ome_mdl_delivery extends dbeav_model if($isAoxiang){ //翱象发货单标识 $data['bool_type'] = $data['bool_type'] | ome_delivery_bool_type::__AOXIANG_CODE; - + //物流升级服务 $data['cpup_service'] = $orderExtend['cpup_service']; - + //最晚发货时间 //$data['delivery_time'] = $orderExtend['latest_delivery_time']; - + //承诺最晚送达时间 $data['promised_sign_time'] = $orderExtend['promised_sign_time']; - + //承诺最晚揽收时间 $data['promised_collect_time'] = $orderExtend['promised_collect_time']; - + //承诺最晚出库时间 $data['promise_outbound_time'] = $orderExtend['latest_delivery_time']; - + //承诺计划送达时间 $data['plan_sign_time'] = $orderExtend['plan_sign_time']; - + //物流服务标签(多个订单合并取消合集) $data['promise_service'] = $orderExtend['promise_service']; } @@ -2327,12 +2362,12 @@ class ome_mdl_delivery extends dbeav_model //分销订单 $data['platform_order_bn'] = $order['platform_order_bn']; } - + //save $saveStartTime = microtime(true); $result = $this->save($data); $saveTime = microtime(true) - $saveStartTime; - + // 记录发货单保存性能数据 ome_api_log::add_message('database', 'delivery_save', $saveTime, array( 'delivery_id' => $data['delivery_id'] ?? '', @@ -2346,10 +2381,10 @@ class ome_mdl_delivery extends dbeav_model if ($delivery['type'] != 'reject') { $err_msg = ''; - + // product_id $productIds = array_column($delivery['delivery_items'], 'product_id'); - + // 获取指定不需要管控库存的基础物料 $notCtrlStoreBmList = kernel::single('material_basic_material')->getNotCtrlStoreProducts($productIds); if($notCtrlStoreBmList){ @@ -2357,7 +2392,7 @@ class ome_mdl_delivery extends dbeav_model foreach ($delivery['delivery_items'] as $dlyItemKey => $dlyItemVal) { $product_id = $dlyItemVal['product_id']; - + // 是否管控库存 if(isset($notCtrlStoreBmList[$product_id]) && $notCtrlStoreBmList[$product_id]){ $delivery['delivery_items'][$dlyItemKey]['is_product_ctrl_store'] = false; @@ -2366,7 +2401,7 @@ class ome_mdl_delivery extends dbeav_model } } } - + //库存管控 $storeManageLib = kernel::single('ome_store_manage'); $storeManageLib->loadBranch(array('branch_id' => $delivery['branch_id'])); @@ -2375,19 +2410,19 @@ class ome_mdl_delivery extends dbeav_model $params['params'] = array_merge($delivery, array('order_id' => $order_id, 'shop_id' => $order['shop_id'], 'delivery_id' => $data['delivery_id'], 'order_type' => $order['order_type'])); $params['node_type'] = 'addDly'; $shop = app::get('ome')->model('shop')->db_dump(['shop_id'=>$order['shop_id']], 'delivery_mode'); - + // 记录库存冻结开始时间 $inventoryFreezeStartTime = microtime(true); - + if($shop['delivery_mode'] == 'jingxiao') { $processResult = true; //经销发货单不产生冻结 } else { $processResult = $storeManageLib->processBranchStore($params, $err_msg); } - + // 计算库存冻结耗时 $inventoryFreezeTime = microtime(true) - $inventoryFreezeStartTime; - + // 记录库存冻结操作 ome_api_log::add_message('inventory', 'inventory_freeze', $inventoryFreezeTime, array( 'delivery_id' => $data['delivery_id'], @@ -2402,7 +2437,7 @@ class ome_mdl_delivery extends dbeav_model // 记录拆单处理开始时间 $splitProcessStartTime = microtime(true); - + if (!kernel::single('ome_order_object_splitnum')->addDeliverySplitNum($order_items)) { $this->db->rollBack(); return array('rsp' => 'fail', 'msg' => '明细已经生成发货单'); @@ -2414,10 +2449,10 @@ class ome_mdl_delivery extends dbeav_model //有优惠明细记录,实付进行重算 $order_items = $this->_regroupDeliveryItemDetailData($order_id,$order_items); - + // 计算拆单处理耗时 $splitProcessTime = microtime(true) - $splitProcessStartTime; - + // 记录优惠明细重算性能数据 ome_api_log::add_message('discount', 'discount_recalculation', $splitProcessTime, array( 'delivery_id' => $data['delivery_id'] ?? '', @@ -2441,10 +2476,17 @@ class ome_mdl_delivery extends dbeav_model //更新订单相应状态 $this->updateOrderLogi($data['delivery_id'], $data); + //订单标签插入到发货单上 + if (in_array(strtolower($order['shop_type']),['vop','luban','taobao'])) { + kernel::single('ome_bill_label')->transferLabel('omeorders_to_omedelivery', [ + 'order_id' => $order_id, + 'ome_delivery_id' => $data['delivery_id'], + ]); + } // 记录标签处理开始时间 $labelProcessStartTime = microtime(true); - + // jitx 检测订单是否有标签 if (in_array(strtolower($order['shop_type']),['vop','luban'])) { kernel::single('ome_bill_label')->transferLabel('omeorders_to_omedelivery', [ @@ -2452,22 +2494,22 @@ class ome_mdl_delivery extends dbeav_model 'ome_delivery_id' => $data['delivery_id'], ]); } - + // 标签扩展信息(Json格式) $bill_extend_info = ''; if($extendInfo){ $bill_extend_info = is_array($extendInfo) ? json_encode($extendInfo, JSON_UNESCAPED_UNICODE) : $extendInfo; } - + //标签写入发货单 kernel::single('ome_bill_label')->orderToDeliveryLabel($order_id, $data['delivery_id'], 'ome_delivery', $bill_extend_info); - + //打上标 kernel::single('ome_bill_label_delivery')->ToDeliveryPresaleLabel($order, $data['delivery_id']); - + // 计算标签处理耗时 $labelProcessTime = microtime(true) - $labelProcessStartTime; - + // 记录标签处理性能数据 ome_api_log::add_message('label', 'label_process', $labelProcessTime, array( 'delivery_id' => $data['delivery_id'] ?? '', @@ -2579,7 +2621,7 @@ class ome_mdl_delivery extends dbeav_model // 客户实付 $actually_amount = (isset($orderItemList[$item_id]['actually_amount']) ? $orderItemList[$item_id]['actually_amount'] : 0); - + //PKG捆绑商品 if($item['item_type'] == 'pkg'){ //平台支付明细 @@ -2713,7 +2755,7 @@ class ome_mdl_delivery extends dbeav_model // 客户实付 $order_items[$key]['actually_amount'] = $actually_amount; - + //SKU商品优惠 $diff_promotion_amount = $total_promotion_amount - $dly_total_promotion_amount; $diff_promotion_amount = ($diff_promotion_amount <= 0 ? $total_promotion_amount : $diff_promotion_amount); @@ -2883,7 +2925,11 @@ class ome_mdl_delivery extends dbeav_model } /** - * 淘宝全链路 已验货 + * 发货单验货后触发淘宝全链路消息,并补投加急发货状态回告任务。 + * + * @param int $delivery_id + * @param array $statusArr + * @return void */ public function sendMessageProduce($delivery_id, $statusArr) { @@ -2897,6 +2943,16 @@ class ome_mdl_delivery extends dbeav_model } kernel::single('ome_event_trigger_shop_order')->order_message_produce($orderIds, $statusArr); + if ($orderIds) { + foreach (array_values(array_unique(array_map('intval', $orderIds))) as $orderId) { + app::get('ome')->model('misc_task')->saveMiscTask([ + 'obj_id' => $orderId, + 'obj_type' => 'urgent_logistics_dly', + 'exec_time' => time(), + 'addon' => json_encode(['scene' => 'delivery_status'], JSON_UNESCAPED_UNICODE), + ]); + } + } } /** * 发送CRM赠品日志 @@ -3409,7 +3465,16 @@ class ome_mdl_delivery extends dbeav_model // return $data; // } - //从载方法 以解决 发货中未录入快递单号不能过滤的bug + /** + * 重载带物流单号的列表查询,并在启用时让加急发货单优先排序。 + * + * @param string $cols + * @param array $filter + * @param int $offset + * @param int $limit + * @param string|array|null $orderType + * @return array + */ public function getlist_logi_no($cols = '*', $filter = array(), $offset = 0, $limit = -1, $orderType = null) { if (!$cols) { @@ -3421,7 +3486,7 @@ class ome_mdl_delivery extends dbeav_model if ($this->use_meta) { $meta_info = $this->prepare_select($cols); } - $orderType = $orderType ? $orderType : $this->defaultOrder; + $orderType = $orderType ? $orderType : $this->getUrgentPriorityOrder($this->defaultOrder, $filter); if ($filter['logi_no'] == 'NULL') { unset($filter['logi_no']); @@ -3609,7 +3674,11 @@ class ome_mdl_delivery extends dbeav_model } /** - * 重载 save 方法,发现有打印状态的更新及 logi_no 的更新,就回传至对应订单 + * 重载 save 方法:同步订单物流信息,并把订单加急标签继承到发货单。 + * + * @param array $data + * @param bool|null $mustUpdate + * @return bool */ public function save(&$data, $mustUpdate = null) { @@ -3619,11 +3688,93 @@ class ome_mdl_delivery extends dbeav_model if ($data['delivery_id'] > 0) { $this->updateOrderLogi($data['delivery_id'], $data); + $this->inheritUrgentLabelFromOrders($data['delivery_id']); } return $result; } + /** + * 在加急优先配置开启时,构造发货单列表的加急优先排序 SQL。 + * + * @param string|array $orderType + * @param array $filter + * @return string|array + */ + protected function getUrgentPriorityOrder($orderType, $filter = []) + { + if (!$this->isUrgentPriorityEnabledByFilter($filter)) { + return $orderType; + } + $orderSql = is_array($orderType) ? implode( ' ', $orderType) : $orderType; + $prefix = "CASE WHEN EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = ".$this->table_name(true).".delivery_id + AND bl.bill_type = 'delivery' + AND bl.label_code = '".self::URGENT_LABEL_CODE."' + ) THEN 0 ELSE 1 END ASC"; + return $prefix . ($orderSql ? ',' . $orderSql : ''); + } + + /** + * 判断当前查询上下文是否开启加急单优先排序。 + * + * @param array $filter + * @return bool + */ + protected function isUrgentPriorityEnabledByFilter($filter = []) + { + $shopId = null; + $branchId = null; + if (!empty($filter['shop_id']) && !is_array($filter['shop_id'])) { + $shopId = $filter['shop_id']; + } + if (!empty($filter['branch_id']) && !is_array($filter['branch_id'])) { + $branchId = $filter['branch_id']; + } elseif (!empty($filter['ext_branch_id']) && is_array($filter['ext_branch_id']) && count($filter['ext_branch_id']) == 1) { + $branchId = current($filter['ext_branch_id']); + } + + $shopConf = $shopId ? app::get('ome')->getConf('ome.urgent_delivery.prioritize_wave.shop.' . $shopId) : null; + if ($shopConf !== null && $shopConf !== '') { + return $shopConf !== 'off'; + } + $branchConf = $branchId ? app::get('ome')->getConf('ome.urgent_delivery.prioritize_wave.branch.' . $branchId) : null; + if ($branchConf !== null && $branchConf !== '') { + return $branchConf !== 'off'; + } + $globalConf = app::get('ome')->getConf('ome.urgent_delivery.prioritize_wave'); + return $globalConf === null || $globalConf === '' || $globalConf === 'on'; + } + + /** + * 在发货单保存后,把关联订单上的加急标签补写到发货单标签表。 + * + * @param int $deliveryId + * @return bool + */ + public function inheritUrgentLabelFromOrders($deliveryId) + { + if (!$deliveryId) { + return false; + } + $labelLib = kernel::single('ome_bill_label'); + if ($labelLib->existLabel($deliveryId, self::URGENT_LABEL_CODE, 'delivery')) { + return true; + } + $orderRows = app::get('ome')->model('delivery_order')->getList('order_id', ['delivery_id' => $deliveryId]); + if (!$orderRows) { + return false; + } + foreach ($orderRows as $row) { + if ($labelLib->existLabel($row['order_id'], self::URGENT_LABEL_CODE)) { + $err = ''; + return $labelLib->markBillLabel($deliveryId, '', self::URGENT_LABEL_CODE, 'delivery', $err); + } + } + return false; + } + /** * 更新发货单对应的订单发货物流信息 * @@ -4451,6 +4602,7 @@ class ome_mdl_delivery extends dbeav_model public function extra_cols() { return array( + 'column_delivery_label' => array('label' => '发货单标记', 'width' => '220', 'func_suffix' => 'delivery_label'), 'column_custom_mark' => array('label' => '买家留言', 'width' => '180', 'func_suffix' => 'custom_mark'), 'column_mark_text' => array('label' => '客服备注', 'width' => '180', 'func_suffix' => 'mark_text'), 'column_tax_no' => array('label' => '发票号', 'width' => '180', 'func_suffix' => 'tax_no'), @@ -4490,6 +4642,31 @@ class ome_mdl_delivery extends dbeav_model return kernel::single('ome_extracolumn_delivery_ident')->process($rows); } + /** + * 渲染发货单列表的标签列,包含加急发货标签展示。 + * + * @param array $rows + * @return array + */ + public function extra_delivery_label($rows) + { + $deliveryIds = array_column((array)$rows, 'delivery_id'); + if (!$deliveryIds) { + return array(); + } + $labelRows = app::get('ome')->model('bill_label')->getBIllLabelList($deliveryIds, 'delivery'); + $result = array(); + foreach ((array)$labelRows as $label) { + $result[$label['bill_id']] .= sprintf( + "%s", + $label['label_name'], + $label['label_color'], + $label['label_name'] + ); + } + return $result; + } + public function getDlyId($logi_nos = false) { $all_logi_no = array(); @@ -4586,7 +4763,7 @@ class ome_mdl_delivery extends dbeav_model return $delivery_nums['nums']; } - + /** * 获取订单下所有发货单 * @param $order_id diff --git a/app/ome/model/delivery/order.php b/app/ome/model/delivery/order.php index c8c486ef..7faf4296 100644 --- a/app/ome/model/delivery/order.php +++ b/app/ome/model/delivery/order.php @@ -17,6 +17,15 @@ class ome_mdl_delivery_order extends dbeav_model{ + public function save(&$data, $mustUpdate = null) + { + $result = parent::save($data, $mustUpdate); + if ($result && !empty($data['delivery_id'])) { + app::get('ome')->model('delivery')->inheritUrgentLabelFromOrders($data['delivery_id']); + } + return $result; + } + function insertParentOrderByItems($parent_id, $items){ if (!is_array($items)) return false; @@ -70,4 +79,4 @@ class ome_mdl_delivery_order extends dbeav_model{ return $this->db->select($sql); } } -?> \ No newline at end of file +?> diff --git a/app/ome/model/misc/task.php b/app/ome/model/misc/task.php index bd5d7e03..29e7a0f2 100644 --- a/app/ome/model/misc/task.php +++ b/app/ome/model/misc/task.php @@ -53,6 +53,21 @@ class ome_mdl_misc_task extends dbeav_model 'class' => 'ome_order_refund', 'method' => 'reundCancelOrder', ), + 'urgent_logistics_notify' => array( + 'text' => '淘宝加急发货状态回告', + 'class' => 'ome_event_trigger_shop_order', + 'method' => 'urgent_logistics_report', + ), + 'urgent_logistics_dly' => array( + 'text' => '淘宝加急发货状态回告', + 'class' => 'ome_event_trigger_shop_order', + 'method' => 'urgent_logistics_report', + ), + 'urgent_logistics_csg' => array( + 'text' => '淘宝加急发货状态回告', + 'class' => 'ome_event_trigger_shop_order', + 'method' => 'urgent_logistics_report', + ), ); /** diff --git a/app/ome/model/order/items.php b/app/ome/model/order/items.php index 2118a859..9b608506 100644 --- a/app/ome/model/order/items.php +++ b/app/ome/model/order/items.php @@ -627,6 +627,37 @@ class ome_mdl_order_items extends dbeav_model $new_order_item[$i] = array_merge($new_order_item[$i], $order_item[$i]); } + + // 微信视频号发货回写依赖平台商品ID和SKU ID。批量替换商品时保留旧平台明细字段, + // 避免新商品的 shop_goods_id/shop_product_id 变为 0 导致回写失败。 + if ($order['shop_type'] == 'wxshipin' && $obj_type != 'gift') { + $old_order_items = array_values((array)$objectInfo['order_items']); + $can_inherit_platform_fields = $objectInfo['shop_goods_id'] && $objectInfo['shop_goods_id'] != '0' && count($old_order_items) == count($new_order_item); + + // 先完整校验旧明细平台字段和数量结构,避免只继承一部分 item。 + if ($can_inherit_platform_fields) { + foreach ($new_order_item as $i => $new_item) { + $old_item = $old_order_items[$i]; + if (!$old_item['shop_goods_id'] || $old_item['shop_goods_id'] == '0' + || !$old_item['shop_product_id'] || $old_item['shop_product_id'] == '0') { + $can_inherit_platform_fields = false; + break; + } + } + } + + // 所有 item 都校验通过后,再统一继承 object 和 item 的平台字段。 + if ($can_inherit_platform_fields) { + $new_order_object['shop_goods_id'] = $objectInfo['shop_goods_id']; + // 旧/新 item 数量一致时,按明细生成顺序继承平台商品ID和SKU ID。 + foreach ($new_order_item as $i => &$new_item) { + $old_item = $old_order_items[$i]; + $new_item['shop_goods_id'] = $old_item['shop_goods_id']; + $new_item['shop_product_id'] = $old_item['shop_product_id']; + } + unset($new_item); + } + } //删除被替换的订单明细 $delete_order_items = array(); @@ -768,6 +799,10 @@ class ome_mdl_order_items extends dbeav_model //修改明细打标 $boolExtendStatus = ome_order_bool_extendstatus::__GOODS_PRICE; app::get('ome')->model('order_extend')->updateBoolExtendStatus($order_id, $boolExtendStatus); + + // 批量编辑物料替换打标 + $labelErr = ''; + kernel::single('ome_bill_label')->markBillLabel($order_id, '', 'SOMS_MATERIAL_REPLACE', 'order', $labelErr, 0); return true; } diff --git a/app/ome/model/order/retrial.php b/app/ome/model/order/retrial.php index b2af0242..8e6777d0 100644 --- a/app/ome/model/order/retrial.php +++ b/app/ome/model/order/retrial.php @@ -170,10 +170,15 @@ class ome_mdl_order_retrial extends dbeav_model { $where = ' WHERE '.$where; } - - $sql = "SELECT count(*) as num FROM ". DB_PREFIX ."ome_order_retrial as a + + $needJoin = (strpos($where, 'b.') !== false); + if ($needJoin) { + $sql = "SELECT count(*) as num FROM ". DB_PREFIX ."ome_order_retrial as a LEFT JOIN ". DB_PREFIX ."ome_orders as b ON a.order_id=b.order_id ". $where; + } else { + $sql = "SELECT count(*) as num FROM ". DB_PREFIX ."ome_order_retrial as a ". $where; + } $row = $this->db->select($sql); return $row[0]['num']; diff --git a/app/ome/model/orders.php b/app/ome/model/orders.php index 1d6fbdc9..609789aa 100644 --- a/app/ome/model/orders.php +++ b/app/ome/model/orders.php @@ -81,9 +81,9 @@ class ome_mdl_orders extends dbeav_model{ /** * 须加密字段 - * + * * @var string - * */ + **/ private $__encrypt_cols = array( 'ship_name' => 'simple', 'ship_tel' => 'phone', @@ -487,6 +487,16 @@ class ome_mdl_orders extends dbeav_model{ $where .= ' AND order_id IN ('. $sql .')'; } + if (!empty($filter['order_label_code'])) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = sdb_ome_orders.order_id + AND bl.label_code = "'.addslashes($filter['order_label_code']).'" + AND bl.bill_type = "order" + )'; + unset($filter['order_label_code']); + } + // 最晚发货时间 if($filter['latest_delivery_time']){ @@ -548,12 +558,12 @@ class ome_mdl_orders extends dbeav_model{ } /** - * 快速查询订单主表信息 - * @access public - * @param mixed $filter 过滤条件,也可以直接是订单主键ID,如:$order_id - * @param String $cols 字段名 - * @return Array 订单信息 - */ + * 快速查询订单主表信息 + * @access public + * @param mixed $filter 过滤条件,也可以直接是订单主键ID,如:$order_id + * @param String $cols 字段名 + * @return Array 订单信息 + */ function getRow($filter,$cols='*'){ if (empty($filter)) return array(); @@ -579,11 +589,11 @@ class ome_mdl_orders extends dbeav_model{ } /** - * 获取订单商品明细 - * @access public - * @param Number $order_id 订单ID - * @return Array 订单商品明细 - */ + * 获取订单商品明细 + * @access public + * @param Number $order_id 订单ID + * @return Array 订单商品明细 + */ function order_objects($order_id){ if (empty($order_id)) return array(); @@ -640,13 +650,6 @@ class ome_mdl_orders extends dbeav_model{ } } - /** - * modifier_shop_id - * @param mixed $shop_id ID - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_shop_id($shop_id,$list,$row){ static $shopList; @@ -661,13 +664,6 @@ class ome_mdl_orders extends dbeav_model{ return $shopList[$shop_id]; } - /** - * modifier_org_id - * @param mixed $org_id ID - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_org_id($org_id,$list,$row){ static $orgList; @@ -1518,7 +1514,7 @@ class ome_mdl_orders extends dbeav_model{ /** * 确认组 - * + * * @param Integer $row 组ID * @return void */ @@ -1541,7 +1537,7 @@ class ome_mdl_orders extends dbeav_model{ /** * 获取用户名 - * + * * @param Integer $gid * @return String; */ @@ -1566,7 +1562,7 @@ class ome_mdl_orders extends dbeav_model{ /** * 获取组名 - * + * * @param Integer $gid * @return String; */ @@ -1592,7 +1588,7 @@ class ome_mdl_orders extends dbeav_model{ /** * 确认人 - * + * * @param Integer $row 确认人ID * @return void */ @@ -1769,9 +1765,9 @@ class ome_mdl_orders extends dbeav_model{ /** * 获得总数量 - * + * * @param string $where - * + * * @return array() */ function get_all($where){ @@ -1805,9 +1801,9 @@ class ome_mdl_orders extends dbeav_model{ /** * 获得确认组订单数量 - * + * * @param string $where - * + * * @return array */ function get_group($where){ @@ -1847,10 +1843,10 @@ class ome_mdl_orders extends dbeav_model{ /** * 获得已分派但未确认时间超过设定时间的订单数量 - * + * * @param string $where * @param string $type - * + * * @return number */ function get_operator($where){ @@ -1954,10 +1950,10 @@ class ome_mdl_orders extends dbeav_model{ /** * 更新订单状态 - * + * * @param bigint $order_id * @param string $status - * + * * @return boolean */ function set_status($order_id, $status){ @@ -2595,7 +2591,6 @@ class ome_mdl_orders extends dbeav_model{ /* * 快速查找订单信息 */ - public function getOrders($name=null) { $sql = " SELECT order_id,order_bn FROM `sdb_ome_orders` @@ -2663,8 +2658,8 @@ class ome_mdl_orders extends dbeav_model{ return false; } - //brush特殊订单、补发订单,不需要后续功能 - if(in_array($sdf['shop_type'], array('brsh', 'bufa'))){ + // brush特殊订单、补发订单,不需要后续功能 + if(in_array($sdf['order_type'], array('brsh', 'bufa'))){ return true; } @@ -2754,15 +2749,15 @@ class ome_mdl_orders extends dbeav_model{ } /** - * 取消订单 - * @access public - * @param Number $order_id 订单ID - * @param String $memo 取消备注 - * @param Bool $is_request 是否询问请求 - * @param string $mode 请求类型:sync同步 async异步 - * @param Bool $must_log 订单收订叫回失败记录日志 - * @return Array - */ + * 取消订单 + * @access public + * @param Number $order_id 订单ID + * @param String $memo 取消备注 + * @param Bool $is_request 是否询问请求 + * @param string $mode 请求类型:sync同步 async异步 + * @param Bool $must_log 订单收订叫回失败记录日志 + * @return Array + */ function cancel($order_id,$memo,$is_request=true,$mode='sync', $must_log = false){ $operLogMdl = $this->app->model('operation_log'); @@ -3038,11 +3033,11 @@ class ome_mdl_orders extends dbeav_model{ /** * 统计导出数据 - * + * * @param Array $filter 过滤条件 * @return void * @author - * */ + **/ public function fcount_csv($filter) { $count = $this->count($filter); @@ -3292,7 +3287,7 @@ class ome_mdl_orders extends dbeav_model{ /** * [第三步]最终,导入数据保存 - * + * * @return void */ function finish_import_csv(){ @@ -3605,7 +3600,7 @@ class ome_mdl_orders extends dbeav_model{ /** * [第一步]整理导入的数据 - * + * * @param $row * @param $title * @param $tmpl @@ -3770,7 +3765,7 @@ class ome_mdl_orders extends dbeav_model{ /** * [第二步]检查导入的订单商品明细 - * + * * @param $data * @param $mark * @param $tmpl @@ -4051,12 +4046,7 @@ class ome_mdl_orders extends dbeav_model{ //不能进行订单编辑的状态判断 - /** - * not_allow_edit - * @param mixed $order_id ID - * @return mixed 返回值 - */ - public function not_allow_edit($order_id){ + public function not_allow_edit($order_id){ $order = $this->dump($order_id); //已取消的订单不允许编辑 if($order['process_status'] == 'cancel'){ @@ -4133,11 +4123,11 @@ class ome_mdl_orders extends dbeav_model{ } - /** - * 统计订单商品重量 - * @param order_id - * @return void - */ + /** + * 统计订单商品重量 + * @param order_id + * @return void + */ function getOrderWeight($order_id,$type='',$additional=''){ $orderObj = $this->app->model('orders'); $basicMaterialExtObj = app::get('material')->model('basic_material_ext'); @@ -4198,9 +4188,9 @@ class ome_mdl_orders extends dbeav_model{ } /** - * 异常订单过滤条件 - * - */ + * 异常订单过滤条件 + * + */ function _abnormalFilter($filter,$tableAlias=null,$baseWhere=null){ $table_name = $this->table_name(true); @@ -4794,13 +4784,6 @@ class ome_mdl_orders extends dbeav_model{ return trim(str_replace(array("\t","\r","\n"),array("","",""),$str)); } - /** - * modifier_ship_name - * @param mixed $ship_name ship_name - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_name($ship_name,$list,$row) { if ($this->is_export_data) { @@ -4829,13 +4812,6 @@ HTML; return $ship_name?$return:$ship_name; } - /** - * modifier_ship_tel - * @param mixed $tel tel - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_tel($tel,$list,$row) { if ($this->is_export_data) { @@ -4863,13 +4839,6 @@ HTML; return $tel?$return:$tel; } - /** - * modifier_ship_mobile - * @param mixed $mobile mobile - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_mobile($mobile,$list,$row) { if ($this->is_export_data) { @@ -4898,13 +4867,6 @@ HTML; return $mobile?$return:$mobile; } - /** - * modifier_ship_addr - * @param mixed $ship_addr ship_addr - * @param mixed $list list - * @param mixed $row row - * @return mixed 返回值 - */ public function modifier_ship_addr($ship_addr,$list,$row) { if ($this->is_export_data) { @@ -4935,7 +4897,7 @@ HTML; /** * 增加旺旺联系方式 - * + * * @param integre $row 用户ID * @return String */ @@ -5007,11 +4969,6 @@ HTML; return $order_list[$row['order_id']]['uname']; } - /** - * insert - * @param mixed $data 数据 - * @return mixed 返回值 - */ public function insert(&$data) { foreach ($this->__encrypt_cols as $field => $type) { @@ -5075,11 +5032,6 @@ HTML; } } - /** - * 获取Area - * @param mixed $where where - * @return mixed 返回结果 - */ public function getArea($where) { $sql = 'SELECT order_id from sdb_ome_orders WHERE '.$where; return array_column($this->db->select($sql),'order_id'); @@ -5221,11 +5173,6 @@ HTML; return $data; } - /** - * 获取CustomExportTitle - * @param mixed $main_title main_title - * @return mixed 返回结果 - */ public function getCustomExportTitle($main_title) { $main_title = array_keys($main_title); @@ -5234,10 +5181,6 @@ HTML; return mb_convert_encoding(implode(',', $title), 'GBK', 'UTF-8'); } - /** - * orderItemsExportTitle - * @return mixed 返回值 - */ public function orderItemsExportTitle() { $items_title = array( diff --git a/app/ome/view/admin/order/fail/batchsave.html b/app/ome/view/admin/order/fail/batchsave.html index cad49714..a4d843b7 100644 --- a/app/ome/view/admin/order/fail/batchsave.html +++ b/app/ome/view/admin/order/fail/batchsave.html @@ -1,3 +1,6 @@ - \ No newline at end of file + +<{if $batch_exclude_notice}> +

<{$batch_exclude_notice}>

+<{/if}> \ No newline at end of file diff --git a/app/ome/view/admin/order/order_edit.html b/app/ome/view/admin/order/order_edit.html index f5e4514d..c93778cc 100644 --- a/app/ome/view/admin/order/order_edit.html +++ b/app/ome/view/admin/order/order_edit.html @@ -1,18 +1,3 @@ - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{script src="coms/autocompleter.js" app='desktop' }> @@ -299,6 +284,7 @@ validatorMap.set('telephone', ['<{t}>固定电话不正确<{/t}>', function(elem return v == null || v == '' || /^(\(0\d{2,3}\)|0\d{2,3}-)?[2-9]\d{5,7}(\(\d{2,5}\)|-\d{2,5})?$/.test(v); }]); +var orderEditAmountInited = false; total(); function total(){ @@ -325,6 +311,7 @@ function total(){ } ome_edit_total_amount(total,sale_amount); + orderEditAmountInited = true; } function ome_edit_total_amount(total,sale_amount) @@ -451,19 +438,16 @@ function ome_edit_total_amount(total,sale_amount) } }); - // 如果有oid限制,仅同步订单优惠金额 - if (hasOidLimit) { + // 用户编辑后同步订单优惠金额;初次加载保持数据库原值,避免产生虚假差额 + if (hasOidLimit && orderEditAmountInited) { pmt_order = totalPartMjzDiscount.toFixed(2); - // 更新输入框的值 $('pmt_order').set('value', pmt_order); } - - //计算当前总金额(订单总金额 = sale_amount实际销售总金额 + cost_tax税金 + cost_protect保价费用 + cost_payment支付手续费 + service_price服务订单费用 - ) + + // 计算订单总金额,结果保留2位小数(与数据库一致) total_amount = parseFloat(sale_amount) + parseFloat(cost_tax) + parseFloat(cost_protect) + parseFloat(cost_payment) + service_price; - - //total_amount + pmt_order订单优惠金额 + discount订单折扣 + cost_freight配送费用 - total_pmt_goods商品优惠金额 total_amount = total_amount - parseFloat(pmt_order) + parseFloat(discount) + parseFloat(cost_freight); - total_amount = total_amount.toFixed(3); + total_amount = (Math.round(total_amount * 100) / 100).toFixed(2); $('cost_amount_show').set('text', '¥'+parseFloat(cost_item).toFixed(3)); $('total_amount_show').set('text', '¥'+total_amount); diff --git a/app/ome/view/admin/order/order_edit_split.html b/app/ome/view/admin/order/order_edit_split.html index 5b28df52..38695d4f 100644 --- a/app/ome/view/admin/order/order_edit_split.html +++ b/app/ome/view/admin/order/order_edit_split.html @@ -1,19 +1,3 @@ - - <{capture name="header"}> <{css app="ome" src="ome.css"}> <{script src="coms/autocompleter.js" app='desktop' }> @@ -308,6 +292,7 @@ validatorMap.set('telephone', ['<{t}>固定电话不正确<{/t}>', function(elem return v == null || v == '' || /^(\(0\d{2,3}\)|0\d{2,3}-)?[2-9]\d{5,7}(\(\d{2,5}\)|-\d{2,5})?$/.test(v); }]); +var orderEditAmountInited = false; total(); function total(){ @@ -334,6 +319,7 @@ function total(){ } ome_edit_total_amount(total,sale_amount); + orderEditAmountInited = true; } @@ -461,19 +447,16 @@ function ome_edit_total_amount(total,sale_amount) } }); - // 如果有oid限制,仅同步订单优惠金额 - if (hasOidLimit) { + // 用户编辑后同步订单优惠金额;初次加载保持数据库原值,避免产生虚假差额 + if (hasOidLimit && orderEditAmountInited) { pmt_order = totalPartMjzDiscount.toFixed(2); - // 更新输入框的值 $('pmt_order').set('value', pmt_order); } - //计算当前总金额(订单总金额 = sale_amount实际销售总金额 + cost_tax税金 + cost_protect保价费用 + cost_payment支付手续费 + service_price服务订单费用) + // 计算订单总金额,结果保留2位小数(与数据库一致) total_amount = parseFloat(sale_amount) + parseFloat(cost_tax) + parseFloat(cost_protect) + parseFloat(cost_payment) + service_price; - - //total_amount + pmt_order订单优惠金额 + discount订单折扣 + cost_freight配送费用 - total_pmt_goods商品优惠金额 total_amount = total_amount - parseFloat(pmt_order) + parseFloat(discount) + parseFloat(cost_freight); - total_amount = total_amount.toFixed(3); + total_amount = (Math.round(total_amount * 100) / 100).toFixed(2); $('cost_amount_show').set('text', '¥'+parseFloat(cost_item).toFixed(3)); $('total_amount_show').set('text', '¥'+total_amount); diff --git a/app/ome/view/admin/return_product/rchange/do_cancel.html b/app/ome/view/admin/return_product/rchange/do_cancel.html index 3b2b122b..998ea4d2 100644 --- a/app/ome/view/admin/return_product/rchange/do_cancel.html +++ b/app/ome/view/admin/return_product/rchange/do_cancel.html @@ -1,19 +1,3 @@ - - @@ -26,7 +10,7 @@ <{if $reship.shop_type == 'taobao' || $reship.shop_type == 'tmall' || $reship.shop_type == 'luban'}> - + diff --git a/app/omeauto/lib/auto/group/item.php b/app/omeauto/lib/auto/group/item.php index 7574e04c..0c24b2bf 100644 --- a/app/omeauto/lib/auto/group/item.php +++ b/app/omeauto/lib/auto/group/item.php @@ -1,19 +1,4 @@ db->exec("UPDATE sdb_ome_delivery SET logi_no='" . $waybillCode . "' WHERE delivery_id=" . $newdly_id); } + ome_delivery_notice::create($newdly_id); } else { //发货单通知单推送仓库 foreach ($ids as $newdly_id) { @@ -1104,7 +1090,7 @@ class omeauto_auto_group_item )); } $wmsStart = microtime(true); - ome_delivery_notice::create($newdly_id); + $wmsTime = microtime(true) - $wmsStart; // 记录WMS通知性能数据 @@ -1114,6 +1100,7 @@ class omeauto_auto_group_item if ($waybillCode) { $deliveryObj->db->exec("UPDATE sdb_ome_delivery SET logi_no='" . $waybillCode . "' WHERE delivery_id=" . $newdly_id); } + ome_delivery_notice::create($newdly_id); } } // todo maxiaochen 得物品牌直发 请求接单接口,如果检测到有取消的发货单,则先调用发货仓修改接口 diff --git a/app/omevirtualwms/controller/admin/wms.php b/app/omevirtualwms/controller/admin/wms.php index 54d7596d..e59fc79e 100644 --- a/app/omevirtualwms/controller/admin/wms.php +++ b/app/omevirtualwms/controller/admin/wms.php @@ -1,19 +1,4 @@ append_missing_items($aftersale_items, array( + 'reshipitemData' => $reshipitemData, + 'branch_id' => $branch_id, + 'iostockInfos' => $iostockInfos, + )); + } + } + } + unset($reshipitemData); //获取退货关联的订单明细 @@ -468,12 +462,6 @@ class sales_aftersale_type_change return $data; } - /** - * 获取OrderObj - * @param mixed $order_id ID - * @param mixed $is_archive is_archive - * @return mixed 返回结果 - */ public function getOrderObj($order_id,$is_archive){ if ($is_archive) { @@ -495,11 +483,6 @@ class sales_aftersale_type_change return $objs; } - /** - * 获取SaleAmount - * @param mixed $order_id ID - * @return mixed 返回结果 - */ public function getSaleAmount($order_id){ $db = kernel::database(); $items = $db->select("SELECT sales_material_bn,bn,sales_amount,nums FROM sdb_ome_sales_items AS I LEFT JOIN sdb_ome_sales as S ON I.sale_id=S.sale_id WHERE S.order_id=".$order_id." AND I.product_id>0"); diff --git a/app/siso/lib/receipt/sales/abstract.php b/app/siso/lib/receipt/sales/abstract.php index 94571f9d..7db12efa 100644 --- a/app/siso/lib/receipt/sales/abstract.php +++ b/app/siso/lib/receipt/sales/abstract.php @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - class siso_receipt_sales_abstract { /** @@ -55,6 +54,18 @@ class siso_receipt_sales_abstract continue; //部分拆分OR部分发货时,跳过生成销售单 } } + + // 事务内二次检查,防止并发重复生成销售单 + $order_id = intval($sale['order_id']); + $salesObj->db->select( + "SELECT order_id FROM sdb_ome_orders WHERE order_id={$order_id} FOR UPDATE" + ); + $exists = $salesObj->db->select( + "SELECT sale_id FROM sdb_ome_sales WHERE order_id={$order_id}" + ); + if ($exists) { + continue; + } if(!$this->check_required($sale,$msg)){ //事务回滚 @@ -497,4 +508,4 @@ class siso_receipt_sales_abstract */ } -} \ No newline at end of file +} diff --git a/app/wms/model/delivery.php b/app/wms/model/delivery.php index d9e75b2d..7f8c3be1 100644 --- a/app/wms/model/delivery.php +++ b/app/wms/model/delivery.php @@ -15,6 +15,7 @@ * limitations under the License. */ class wms_mdl_delivery extends dbeav_model{ + const URGENT_LABEL_CODE = 'SOMS_URGENT_SHIP'; public $filter_use_like = true; var $has_many = array( 'delivery_items' => 'delivery_items', @@ -53,6 +54,7 @@ class wms_mdl_delivery extends dbeav_model{ public function _filter($filter,$tableAlias=null,$baseWhere=null){ $baseWhere = (array) $baseWhere; $tPre = ($tableAlias?$tableAlias:'`'.$this->table_name(true).'`').'.'; + $where = ''; /////////////////////////// // 加密处理逻辑 2017/5/5 by cp // /////////////////////////// @@ -200,6 +202,33 @@ class wms_mdl_delivery extends dbeav_model{ $where .= ' AND '.$filter['addonSQL']; unset($filter['addonSQL']); } + if (!empty($filter['delivery_label_code'])) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.addslashes($filter['delivery_label_code']).'" + )'; + unset($filter['delivery_label_code']); + } + if (isset($filter['urgent_delivery'])) { + if ($filter['urgent_delivery'] === 'true' || $filter['urgent_delivery'] === true || $filter['urgent_delivery'] == 1) { + $where .= ' AND EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.self::URGENT_LABEL_CODE.'" + )'; + } else { + $where .= ' AND NOT EXISTS ( + SELECT 1 FROM sdb_ome_bill_label bl + WHERE bl.bill_id = '.$tPre.'delivery_id + AND bl.bill_type = "delivery" + AND bl.label_code = "'.self::URGENT_LABEL_CODE.'" + )'; + } + unset($filter['urgent_delivery']); + } if (isset($filter['shop_id_in'])) { $where .= ' AND ' . $tPre . 'shop_id in("'.implode('","', $filter['shop_id_in']).'")'; unset($filter['shop_id_in']); @@ -1433,6 +1462,7 @@ class wms_mdl_delivery extends dbeav_model{ */ function extra_cols(){ return array( + 'column_delivery_label' => array('label'=>'发货单标记','width'=>'220','func_suffix'=>'delivery_label'), 'column_custom_mark' => array('label'=>'买家留言','width'=>'180','func_suffix'=>'custom_mark'), 'column_mark_text' => array('label'=>'客服备注','width'=>'180','func_suffix'=>'mark_text'), 'column_tax_no' => array('label'=>'发票号','width'=>'180','func_suffix'=>'tax_no'), @@ -1468,6 +1498,24 @@ class wms_mdl_delivery extends dbeav_model{ return kernel::single('wms_extracolumn_delivery_ident')->process($rows); } + function extra_delivery_label($rows){ + $deliveryIds = array_column((array)$rows, 'delivery_id'); + if (!$deliveryIds) { + return array(); + } + $labelRows = app::get('ome')->model('bill_label')->getBIllLabelList($deliveryIds, 'delivery'); + $result = array(); + foreach ((array)$labelRows as $label) { + $result[$label['bill_id']] .= sprintf( + "%s", + $label['label_name'], + $label['label_color'], + $label['label_name'] + ); + } + return $result; + } + //定义导出明细内容的相关字段 public function get_exp_detail_schema(){ $schema = array ( diff --git a/assets/static/logo-5ckfAmJf.png b/assets/static/logo-5ckfAmJf.png index aca2cd3522221742f0e4c172a9cfdad8c8b05f25..b572a180d0d099a4070dd4c108bf357346badb6d 100644 GIT binary patch delta 11 ScmX>(iRsiNrVXB*j9dU82?R+1 delta 9 QcmX>#iRt7drVXB*02YJ - 8.3.4.20260508 + 8.4.0.20260707 ONEX OMS taog
* 上传凭证:上传凭证: <{input type="sfile" name="refuse_proof" f_type="public" }>