1. 【新增】售后单售后原因类型支持搜索

2. 【新增】手工创建订单折扣可输入正数

3. 【优化】盘点申请单确认

4. 【修复】采购退货单模拟出库失败问题

5. 【新增】订单金额客户实付与结算金额

6. 【优化】仓库发货统计报表物料名称显示

7. 【优化】自有仓储虚拟发货逻辑

8. 【修复】基础物料分类管理问题
This commit is contained in:
chenping
2026-04-01 11:59:17 +08:00
parent 9341122827
commit 61783b7d01
754 changed files with 46179 additions and 5700 deletions

View File

@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class wms_ctl_admin_check extends desktop_controller{
var $name = "货物校验";
var $workground = "wms_delivery";
@@ -156,7 +155,17 @@ class wms_ctl_admin_check extends desktop_controller{
$deliveryBill = $dlyBillMdl->db_dump(['logi_no' => $logi_no]);
$delivery_id = $deliveryBill ? $deliveryBill['delivery_id'] : 0;
$bill_id = $deliveryBill ? $deliveryBill['b_id'] : 0;
// [提货物流] delivery_model='pickup' 运单号后取,扫描的是发货单号
if (empty($deliveryBill)) {
$pickupDly = $deliveryObj->dump(array('delivery_bn' => $logi_no, 'delivery_model' => 'pickup'), 'delivery_id');
if ($pickupDly) {
$delivery_id = $pickupDly['delivery_id'];
$deliveryBill = $dlyBillMdl->db_dump(array('delivery_id' => $delivery_id, 'type' => 1));
$bill_id = $deliveryBill ? $deliveryBill['b_id'] : 0;
}
}
//[同城配]商家配送支持配送员手机号搜索
if(empty($deliveryBill) && strlen($logi_no) == 11){
$deliveryInfo = $deliveryObj->dump(array('deliveryman_mobile'=>$logi_no, 'process_status'=>array(0,1)), '*');
@@ -213,7 +222,7 @@ class wms_ctl_admin_check extends desktop_controller{
$this->pagedata['markandtext'] = $markandtext;
# 货品名显示方式(stock:后台,front:前台)
# 基础物料名称显示方式(stock:后台,front:前台)
$product_name_show_type = app::get('wms')->getConf('wms.delivery.check_show_type');
$product_name_show_type = empty($product_name_show_type) ? 'stock' : $product_name_show_type;
@@ -494,8 +503,8 @@ class wms_ctl_admin_check extends desktop_controller{
'delivery_id' => $dly_id,
);
//[同城配]商家配送
if($dly['delivery_model'] == 'seller'){
//[同城配]商家配送 / [提货物流]
if($dly['delivery_model'] == 'seller' || $dly['delivery_model'] == 'pickup'){
$filter = array(
'delivery_id' => $dly_id,
);
@@ -626,10 +635,15 @@ class wms_ctl_admin_check extends desktop_controller{
$filter = array(
'delivery_id'=>$delivery,
);
$deliverys = $deliveryObj->getList('delivery_id,delivery_bn',$filter);
$deliverys = $deliveryObj->getList('delivery_id,delivery_bn,delivery_model',$filter);
$succ = 0;
$fail = 0;
foreach($deliverys as $value){
if (isset($value['delivery_model']) && $value['delivery_model'] === 'pickup'){
$fail++;
$failInfo[] = $value['delivery_bn'] . '(提货单不支持分组校验)';
continue;
}
$logi_no = $dlyBillObj->getPrimaryLogiNoById($value['delivery_id']);
$checkInfo = $dlyCheckLib->checkAllow($logi_no, $msg, 'group', true);
if ($checkInfo){

View File

@@ -20,10 +20,6 @@ class wms_ctl_admin_consign extends desktop_controller{
var $name = "发货处理";
var $workground = "wms_delivery";
/**
* _views
* @return mixed 返回值
*/
public function _views()
{
@@ -72,7 +68,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 逐单发货的入口展示页
*/
function index(){
@@ -110,7 +106,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 批量发货的入口展示页
*/
function batch(){
@@ -124,7 +120,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 分组发货的入口展示页
*/
function group_consign(){
@@ -199,7 +195,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 发货前的发货单相关信息检查
*/
function batchCheck(&$rs = false){
@@ -213,7 +209,7 @@ class wms_ctl_admin_consign extends desktop_controller{
$dlyCheckLib = kernel::single('wms_delivery_check');
//逐个发货:发货判断,批量发货不做此过滤
// 先做系统业务校验consignAllow通过后再针对 pickup 且无 logi_no 时调官方提货
if ($_GET['delivery_type'] == 'single'){
$return_error = $dlyCheckLib->consignAllow('', $logi_nos, $weight);
if ($return_error){
@@ -221,8 +217,16 @@ class wms_ctl_admin_consign extends desktop_controller{
echo json_encode($tmp);
die;
}
$pickup_err=null;
$pickup_err = $this->_batchCheckPickupOfficial($logi_nos);
if ($pickup_err !== null) {
$tmp = array('status'=>'error','msg'=>$pickup_err);
echo json_encode($tmp);
die;
}
}else{
$logi_no_arr = array_unique(explode(',', $logi_nos));
$tmp = array();
$delivery_list = array();
if ($logi_no_arr){
@@ -240,14 +244,76 @@ class wms_ctl_admin_consign extends desktop_controller{
}
}
if ($tmp){
if (!empty($tmp)){
echo json_encode($tmp); die;
}
$rs = true;#发货判断完成的标示,这个对校验完成即发货有用
if ($_GET['delivery_type'] == 'single') {
$dlyObj = app::get('wms')->model('delivery');
$deliveryBillLib = kernel::single('wms_delivery_bill');
$delivery_id = $deliveryBillLib->getDeliveryIdByPrimaryLogi($logi_nos);
if (empty($delivery_id)) {
$delivery_id = $deliveryBillLib->getDeliveryIdBySecondaryLogi($logi_nos);
}
if (empty($delivery_id)) {
$pickupDly = $dlyObj->dump(array('delivery_bn' => $logi_nos, 'delivery_model' => 'pickup'), 'delivery_id');
if (!empty($pickupDly)) {
$delivery_id = $pickupDly['delivery_id'];
}
}
$is_pickup = false;
if ($delivery_id) {
$dly = $dlyObj->dump(array('delivery_id' => $delivery_id), 'delivery_model');
$is_pickup = (isset($dly['delivery_model']) && $dly['delivery_model'] === 'pickup');
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode(array('status' => 'ok', 'is_pickup' => $is_pickup));
return;
}
echo "";
}
/**
* pickup 单:仅当 logi_no 为空时调官方提货,已有 logi_no 则不请求;失败返回错误文案(兼容 PHP5.2,不用闭包)
* @param string $scan_val 扫描值(对应界面「输入快递单号」/ POST delivery_id可为发货单号
* @return string|null 失败时返回错误信息,否则 null
*/
private function _batchCheckPickupOfficial($scan_val)
{
$deliveryBillLib = kernel::single('wms_delivery_bill');
$dlyObj = app::get('wms')->model('delivery');
$dlyBillObj = app::get('wms')->model('delivery_bill');
$delivery_id = $deliveryBillLib->getDeliveryIdByPrimaryLogi($scan_val);
if ($delivery_id === null) {
$delivery_id = $deliveryBillLib->getDeliveryIdBySecondaryLogi($scan_val);
}
if ($delivery_id === null) {
$pickupDly = $dlyObj->dump(array('delivery_bn' => $scan_val, 'delivery_model' => 'pickup'), 'delivery_id');
if ($pickupDly) {
$delivery_id = $pickupDly['delivery_id'];
}
}
if (empty($delivery_id)) {
return null;
}
$dly = $dlyObj->dump(array('delivery_id' => $delivery_id), 'delivery_id,delivery_model');
if (empty($dly) || !isset($dly['delivery_model']) || $dly['delivery_model'] !== 'pickup') {
return null;
}
$bill = $dlyBillObj->db_dump(array('delivery_id' => $delivery_id, 'type' => 1), 'logi_no');
// 已有 logi_no 则不请求官方提货,避免重复调用
if (!empty($bill['logi_no'])) {
return null;
}
$ret = kernel::single('wms_logistics')->officialPickup($delivery_id);
if (is_array($ret) && isset($ret['rsp']) && $ret['rsp'] === 'fail') {
return isset($ret['msg']) ? $ret['msg'] : '官方提货失败';
}
return null;
}
function batch_log_detail(){
$log_id = $_GET['log_id'];
$filter = array('log_id'=>$log_id);
@@ -263,7 +329,7 @@ class wms_ctl_admin_consign extends desktop_controller{
$this->display('admin/delivery/batch_log_detail.html');
}
/**
/**
* 批量发货确认
* 显示批量发货订单中有退款申请或已退款的订单,让管理员确认是否发货或不发货
* @param json $data
@@ -276,7 +342,7 @@ class wms_ctl_admin_consign extends desktop_controller{
/**
* 发货处理
*
*
*/
function consign($is_from_check = false){
if($is_from_check){
@@ -312,7 +378,15 @@ class wms_ctl_admin_consign extends desktop_controller{
$logi_no = $dlyBillInfo['logi_no'];
}
}
// [提货物流] delivery_model='pickup' 运单号后取,扫描的是发货单号
if (empty($delivery_id)) {
$pickupDly = $dlyObj->dump(array('delivery_bn' => $logi_no, 'delivery_model' => 'pickup'), 'delivery_id');
if ($pickupDly) {
$delivery_id = $pickupDly['delivery_id'];
}
}
if(!is_null($delivery_id)){
$primary = true;
$dly = $dlyObj->dump(array('delivery_id' => $delivery_id),'*',array('delivery_items'=>array('*')));
@@ -327,6 +401,14 @@ class wms_ctl_admin_consign extends desktop_controller{
$logi_number = $dly['logi_number'];
$delivery_logi_number =$dly['delivery_logi_number'];
// 确认出库成功后用于触发的快递单打印(仅 delivery_model=pickup 时返回,前端将拉取 toPrintExpre 同源数据并直接触发菜鸟打印)
$consignExtra = (isset($dly['delivery_model']) && $dly['delivery_model'] === 'pickup')
? array(
'print_delivery_id' => $dly['delivery_id'],
'print_logi_id' => $dly['logi_id'],
)
: array();
//检查前端订单是否退款,原有逻辑是否需要?
//danny_freeze_stock_log
@@ -363,7 +445,7 @@ class wms_ctl_admin_consign extends desktop_controller{
if(($logi_number==$delivery_logi_number)&&$dly['status'] != 3){
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
@@ -375,13 +457,13 @@ class wms_ctl_admin_consign extends desktop_controller{
if($logi_number==($delivery_logi_number+1)){
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
}
}else{
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}
}
}else{
@@ -389,7 +471,7 @@ class wms_ctl_admin_consign extends desktop_controller{
if($logi_number == 1){
if(($logi_number==$delivery_logi_number)&&$dly['status'] != 3){
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
@@ -410,7 +492,7 @@ class wms_ctl_admin_consign extends desktop_controller{
$dlyObj->update($data,$filter);
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
@@ -441,17 +523,17 @@ class wms_ctl_admin_consign extends desktop_controller{
if($logi_number==($delivery_logi_number+1)){
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
}
}
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
//加入如果$logi_number==$delivery_logi_number 但是发货状态没有改变的判断
}elseif(($delivery_logi_number == $logi_number) && $dly['status'] != 3){
if ($dlyProcessLib->consignDelivery($dly['delivery_id'])){
$this->end(true, '发货处理完成');
$this->_endConsignSuccess($consignExtra);
}else {
$msg['delivery_bn'] = $dly['delivery_bn'];
$this->end(false, '发货未完成', '', array('msg'=>$msg));
@@ -464,7 +546,39 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
* 生成确认出库成功后的快递单打印页链接(与 admin_receipts_print toPrintExpre 参数一致)
* @param int|string $delivery_id wms 发货单 id
* @param int|string $logi_id 物流公司 id
* @return string
*/
protected function _getConsignPrintExpreUrl($delivery_id, $logi_id) {
return 'index.php?app=wms&ctl=admin_receipts_print&act=toPrintExpre&status=3&logi_id=' . urlencode((string)$logi_id) . '&delivery_id=' . urlencode((string)$delivery_id);
}
/**
* consign 成功返回封装:
* - pickup 场景:返回纯 JSON避免 desktop 的 splash/doCommand 触发 redirect 打断自动打印流程
* - 其他场景:保持原有 end() 行为
*
* @param array $consignExtra
*/
protected function _endConsignSuccess($consignExtra = array())
{
if (is_array($consignExtra) && isset($consignExtra['print_delivery_id']) && $consignExtra['print_delivery_id']) {
// 先提交事务(与 end() 一致),再返回纯 JSON避免 desktop 的 splash/redirect 打断自动打印
$this->endonly(true);
header('Content-Type: application/json; charset=utf-8');
$out = array_merge(array('success' => '成功:发货处理完成'), $consignExtra);
$out['redirect'] = 'index.php?app=wms&ctl=admin_consign&act=index';
echo json_encode($out);
exit;
}
// 非 pickup保持原有 end(),框架会处理 splash/redirect
$this->end(true, '发货处理完成', null, $consignExtra);
}
/**
*
* 分组发货执行方法
*/
function ajaxDoGroupConsign(){
@@ -517,7 +631,11 @@ class wms_ctl_admin_consign extends desktop_controller{
$fail = 0;
$failInfo = array();
foreach($deliverys as $value){
if (isset($value['delivery_model']) && $value['delivery_model'] === 'pickup'){
$fail++;
$failInfo[] = $value['delivery_bn'] . '(提货单不支持分组发货)';
continue;
}
$weight = $value['net_weight']>0 ? $value['net_weight'] : $group_weight;
$weight = $weight ? $weight : $minWeight;
@@ -615,7 +733,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 补打物流单入口页
*/
public function fill_delivery(){
@@ -623,7 +741,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 补打物流单的详细页
*/
public function fill_delivery_confirm(){
@@ -736,10 +854,10 @@ class wms_ctl_admin_consign extends desktop_controller{
// die;
}
/**
*
* 删除子快递单
*/
/**
*
* 删除子快递单
*/
function del_deliveryBill(){
$b_id = $_POST['b_id'];
$delivery_id = $_POST['delivery_id'];
@@ -903,8 +1021,8 @@ class wms_ctl_admin_consign extends desktop_controller{
}
}
/**
*
/**
*
* 快递单状态翻译显示
*/
function statusinfo($status,$style=1){
@@ -929,9 +1047,9 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 保存批量发货至记录队列表中
*/
*/
function doBatchConsign(){
$goto_url = 'index.php?app=wms&ctl=admin_consign&act=batch';
$ids = $_POST['delivery_id'];
@@ -971,8 +1089,8 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
* 获取发货记录历史
*/
*获取发货记录历史
*/
function batchConsignLog(){
$blObj = app::get('wms')->model('batch_log');
$batchLogLib = kernel::single('wms_batch_log');
@@ -993,7 +1111,7 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
*
*
* 更新处理中发货记录值
*/
function updateBatchConsignLog(){
@@ -1019,8 +1137,8 @@ class wms_ctl_admin_consign extends desktop_controller{
/**
* 商品重量报警判断
*/
* 商品重量报警判断
*/
function weightWarn(){
$type = $_GET['type'];
$logi_no = $_POST['logi_no'];
@@ -1056,8 +1174,8 @@ class wms_ctl_admin_consign extends desktop_controller{
}
/**
* 发货重量报警页面提醒
*/
* 发货重量报警页面提醒
*/
function showWeightWarn(){
$logi_no = $_GET['logi_no'];
@@ -1122,7 +1240,7 @@ class wms_ctl_admin_consign extends desktop_controller{
/**
* 极速发货
*
*
* @param void
* @return void
*/
@@ -1183,6 +1301,14 @@ class wms_ctl_admin_consign extends desktop_controller{
$basicMaterialExtObj = app::get('material')->model('basic_material_ext');
$deliveryBill = $dlyBillMdl->db_dump(['logi_no' => $logi_no]);
// [提货物流] delivery_model='pickup' 运单号后取,扫描的是发货单号(delivery_bn),按 delivery_bn 查主单
if (empty($deliveryBill)) {
$pickupDly = $dlyMdl->dump(array('delivery_bn' => $logi_no, 'delivery_model' => 'pickup'), 'delivery_id');
if ($pickupDly) {
$deliveryBill = $dlyBillMdl->db_dump(array('delivery_id' => $pickupDly['delivery_id'], 'type' => 1));
}
}
//[同城配]商家配送支持配送员手机号搜索
if(empty($deliveryBill) && strlen($logi_no) == 11){
@@ -1299,7 +1425,7 @@ class wms_ctl_admin_consign extends desktop_controller{
//检查运单号是否属于同一个处理的发货单
$deliveryBillLib = kernel::single('wms_delivery_bill');
$db_logi_no = $deliveryBillLib->getPrimaryLogiNoById($dly_id);
if ($db_logi_no != $logi_no){
if ($db_logi_no != $logi_no && $dly['delivery_model'] != 'pickup'){
$tmp = array('result'=>false,'msg'=>'扫描的快递单号与系统中的快递单号不对应');
echo json_encode($tmp);die;
}

View File

@@ -22,12 +22,6 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
var $dlyCorp_tab = 'show';
/**
* _views
* @param mixed $base_filter base_filter
* @param mixed $source source
* @return mixed 返回值
*/
public function _views($base_filter = [], $source = '') {
if($this->dlyCorp_tab == 'hidden'){
return array();
@@ -59,7 +53,11 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
foreach ($sub_menu as $k => $v) {
//$v['filter']['branch_id'] = $outerBranch;
//非管理员取管辖仓与自建仓的交集
$v['filter']['ext_branch_id'] = $v['filter']['ext_branch_id'] ? array_intersect($v['filter']['ext_branch_id'], $outerBranch) : $outerBranch;
$v['filter']['ext_branch_id'] = $v['filter']['ext_branch_id'] ? $v['filter']['ext_branch_id'] : $outerBranch;
if (!is_array($v['filter']['ext_branch_id'])) {
$v['filter']['ext_branch_id'] = array($v['filter']['ext_branch_id']);
}
$v['filter']['ext_branch_id'] = array_intersect($v['filter']['ext_branch_id'], $outerBranch);
$sub_menu[$k]['filter'] = $v['filter'] ? $v['filter'] : null;
$sub_menu[$k]['addon'] = $mdl_order->count($v['filter']);
$query['view'] = $i++;
@@ -71,9 +69,9 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
/**
* 第三方发货单列表
*
*
* @author chenping<chenping@shopex.cn>
* */
**/
public function index()
{
if (isset($_POST['delivery_bn']) && $_POST['delivery_bn']) {
@@ -109,7 +107,9 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
$branch_ids = $oBranch->getBranchByUser(true);
if ($branch_ids) {
$filter['ext_branch_id'] = $_POST['branch_id'] ? $_POST['branch_id'] : $branch_ids;
if (!is_array($filter['ext_branch_id'])) {
$filter['ext_branch_id'] = array($filter['ext_branch_id']);
}
$filter['ext_branch_id'] = array_intersect($filter['ext_branch_id'], $outerBranch);
} else {
$filter['ext_branch_id'] = 'false';
@@ -192,10 +192,6 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
}
#自定义发货模板导出
/**
* exportTemplate
* @return mixed 返回值
*/
public function exportTemplate(){
if(!empty($_POST['delivery_id'])){
$filter['delivery_id'] = $_POST['delivery_id'];
@@ -222,4 +218,4 @@ class wms_ctl_admin_receipts_outer extends wms_ctl_admin_receipts_print {
echo "\n";
}
}
}
}

View File

@@ -165,9 +165,10 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
$this->dlyCorp_tab = 'hidden';
}
//同城配送&&商家配送
//同城配送&&商家配送&&官方物流提货
$is_instatnt = false;
$is_seller = false;
$is_pickup = false;
$logi_id = intval($_GET['logi_id']);
if($logi_id){
@@ -176,6 +177,8 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
$is_instatnt = true;
}elseif($dlyCorpInfo['corp_model'] == 'seller'){
$is_seller = true;
}elseif($dlyCorpInfo['corp_model'] == 'pickup'){
$is_pickup = true;
}
}
@@ -411,13 +414,23 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
unset($params['actions']['orderbycreatetime']);
}elseif($is_seller){
//同城配送
//商家配送
$params['actions']['deliveryman'] = array(
'label' => '批量填写商家配送',
'submit' => 'index.php?app=wms&ctl=admin_receipts_print&act=batchDeliveryman' . $attach,
'target' => 'dialog::{title:\'批量填写商家配送信息\',width:500,height:300}',
);
unset($params['actions']['orderbycreatetime']);
}elseif($is_pickup){
//官方物流提货
/* $params['actions']['stock'] = array(
'label' => '官方物流提货',
'submit' => 'index.php?app=wms&ctl=admin_receipts_print&act=toPrintStock' . $attach,
'target' => "_blank",
);*/
unset($params['actions']['orderbycreatetime']);
}else{
//批量更换物流按钮
@@ -1734,6 +1747,11 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
$dly[$k]['_memo_'][1] = "发货单商品信息打印(打印模板: $current_otmpl_name ";
break;
}
// 官方物流提货:自动补上快递单打印状态
if ($delivery['delivery_model'] == 'pickup' && $type != 'express') {
$dly[$k]['print_status'] = $dly[$k]['print_status'] | 4;
}
}
$opObj = app::get('ome')->model('operation_log');
foreach ($dly as $k => $v) {
@@ -1824,6 +1842,8 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
exit;
}
$PrintStockLib = kernel::single('wms_delivery_print_stock');
$format_data = $PrintStockLib->format($print_data, $sku,$_err);
$this->pagedata = $format_data;
@@ -2818,6 +2838,221 @@ class wms_ctl_admin_receipts_print extends desktop_controller {
$objExpress->setParams($params)->getTmpl();
}
/**
* 发货流程页:无需打开打印页面,直接获取快递单打印数据(与 toPrintExpre 同源逻辑)
*
* 返回结构用于 app/logisticsmanager/statics/js/printer.js 的 CaiNiaoPrinter
* - data: 由 wms.service.template 组织出的数组(含 json_packet 等字段)
* - template / custom_template_url / custom_data: 与 template_cainiao_web.html 一致
*/
public function ajaxGetPrintExpreData()
{
@ini_set('memory_limit','1024M');
$req = kernel::single('base_component_request');
$delivery_id = $req->get_post('delivery_id');
if ($delivery_id === null || $delivery_id === '') {
$delivery_id = $req->get_get('delivery_id');
}
$delivery_id = trim((string)$delivery_id);
if ($delivery_id === '') {
echo json_encode(array('status' => 'error', 'msg' => '参数错误delivery_id'));
return;
}
// 支持数字为 delivery_id非数字时按 pickup 的发货单号(delivery_bn)解析
if (!ctype_digit($delivery_id)) {
$dlyObj = app::get('wms')->model('delivery');
$pickupDly = $dlyObj->dump(array('delivery_bn' => $delivery_id, 'delivery_model' => 'pickup'), 'delivery_id');
if (empty($pickupDly)) {
echo json_encode(array('status' => 'error', 'msg' => '未找到提货单或非提货单'));
return;
}
$delivery_id = $pickupDly['delivery_id'];
}
$delivery_id = intval($delivery_id);
if ($delivery_id <= 0) {
echo json_encode(array('status' => 'error', 'msg' => '参数错误delivery_id'));
return;
}
$_err = 'false';
$sku = $req->get_get('sku');
$sku = $sku ? $sku : '';
$afterPrint = true;
$now_print_type = 'ship';
$msg = array();
$PrintLib = kernel::single('wms_delivery_print');
$filter_condition = array('filter' => array('delivery_id' => array($delivery_id)));
$print_data = $PrintLib->getPrintDatas($filter_condition, $now_print_type, $sku, $afterPrint, $msg);
if (!$print_data) {
$errMsg = isset($msg['error_msg']) ? $msg['error_msg'] : '获取打印数据失败';
echo json_encode(array('status' => 'error', 'msg' => $errMsg));
return;
}
if (isset($msg['warn_msg']) && $msg['warn_msg']) {
echo json_encode(array('status' => 'error', 'msg' => $msg['warn_msg']));
return;
}
$deliveryObj = app::get('wms')->model('delivery');
$dlyBillObj = app::get('wms')->model('delivery_bill');
$channelObj = app::get("logisticsmanager")->model("channel");
$ids = $print_data['ids'];
// 防止并发打印重复获取运单号(单笔也保持一致行为)
$_inner_key = sprintf("print_ids_%s", md5(implode(',', (array)$ids)));
$aData = cachecore::fetch($_inner_key);
if ($aData === false) {
cachecore::store($_inner_key, 'printed', 5);
} else {
echo json_encode(array('status' => 'error', 'msg' => '该发货单正在准备打印数据,请稍后重试'));
return;
}
// 复用 toPrintExpre 的关键组织逻辑:组装 $expressDelivery、处理电子面单、产出 $mydata
$expressDelivery = array();
$logiId = null;
$existTB = false;
$existPDD = false;
$existDY = false;
foreach ((array)$print_data['deliverys'] as $val) {
empty($logiId) && $logiId = $val['logi_id'];
$orderSource = current($val['orders']);
if ($val['shop_type'] == 'taobao' && $orderSource['source'] == 'matrix') {
$existTB = true;
}
if ($val['shop_type'] == 'pinduoduo' && $orderSource['source'] == 'matrix') {
$existPDD = true;
}
if ($val['shop_type'] == 'luban' && $orderSource['source'] == 'matrix') {
$existDY = true;
}
foreach ($val as $dk => $dv) {
if (!is_array($dv)) {
$expressDelivery[$val['delivery_id']][$dk] = $dv;
}
}
}
$corp = app::get('ome')->model('dly_corp')->dump($logiId);
if (!$corp) {
echo json_encode(array('status' => 'error', 'msg' => '获取物流公司信息失败'));
return;
}
// 同城配校验(保持与 toPrintExpre 一致)
if (in_array($corp['corp_model'], array('instatnt', 'seller'))) {
$billList = $dlyBillObj->getList('*', array('delivery_id' => array($delivery_id)));
foreach ($billList as $billVal) {
if (empty($billVal['logi_no'])) {
echo json_encode(array('status' => 'error', 'msg' => '同城配请先填写物流信息或配送员信息'));
return;
}
}
}
app::get('ome')->model('dly_corp_channel')->getChannel($corp, $expressDelivery);
if (!$corp['channel_id'] && $corp['tmpl_type'] == 'electron') {
echo json_encode(array('status' => 'error', 'msg' => '对应多个电子面单来源,无法打印'));
return;
}
// 电子面单处理:与 toPrintExpre 一致的模板/控件校验 + dealElectron
if ($corp['tmpl_type'] == 'electron') {
$channelInfo = $channelObj->db_dump(array('channel_id' => $corp['channel_id']), 'channel_type,logistics_code');
$expressTmpl = app::get("logisticsmanager")->model('express_template')->dump($corp['prt_tmpl_id'], 'template_type,control_type');
if ($channelInfo['channel_type'] == 'hqepay' && $channelInfo['logistics_code'] == 'SF' && $expressTmpl['control_type'] == 'lodop') {
$existTB = $existPDD = $existDY = false;
}
if ($existTB === true && !in_array($expressTmpl['template_type'], array('cainiao_standard', 'cainiao_user'))) {
echo json_encode(array('status' => 'error', 'msg' => '淘宝订单请使用菜鸟控件、菜鸟模板'));
return;
}
if ($existPDD === true && !in_array($expressTmpl['template_type'], array('pdd_standard', 'pdd_user'))) {
echo json_encode(array('status' => 'error', 'msg' => '拼多多订单请使用拼多多控件、拼多多模板'));
return;
}
if ($existDY === true && !in_array($expressTmpl['template_type'], array('douyin_standard', 'douyin_user'))) {
echo json_encode(array('status' => 'error', 'msg' => '抖音订单请使用抖音控件、抖音模板'));
return;
}
$eleRet = kernel::single('wms_delivery_electron')->dealElectron($expressDelivery, $corp['channel_id'], $afterPrint, $this);
if (isset($eleRet['id_bn']) && count($eleRet['id_bn'])) {
// 单笔接口,直接返回首条错误
$first = current($eleRet['id_bn']);
$errMsg = isset($first['msg']) ? $first['msg'] : '电子面单处理失败';
echo json_encode(array('status' => 'error', 'msg' => $errMsg));
return;
}
}
foreach ((array)$print_data['deliverys'] as $dk => $dv) {
if (isset($expressDelivery[$dk]['logi_no']) && $expressDelivery[$dk]['logi_no']) {
$print_data['deliverys'][$dk]['logi_no'] = $expressDelivery[$dk]['logi_no'];
}
}
$PrintShipLib = kernel::single('wms_delivery_print_ship');
$format_data = $PrintShipLib->format($print_data, $sku, $_err);
$express_company_no = strtoupper($corp['type']);
$objExpress = ome_print_tmpl_express::instance($express_company_no, $this);
if (!$objExpress->getExpressTpl($corp)) {
$msg = $objExpress->msg ? $objExpress->msg : '获取打印模板失败';
echo json_encode(array('status' => 'error', 'msg' => $msg));
return;
}
$printTpl = $objExpress->printTpl;
$mydata = array();
if (isset($format_data['delivery']) && $format_data['delivery']) {
foreach ($format_data['delivery'] as $val) {
$val['printTpl']['template_type'] = $printTpl['template_type'];
$val['printTpl']['control_type'] = $printTpl['control_type'];
$data = array();
foreach (kernel::servicelist('wms.service.template') as $object => $instance) {
$tmp = array();
if (method_exists($instance, 'getElementContent')) {
$tmp = $instance->getElementContent($val);
}
$data = array_merge($data, $tmp);
}
$mydata[] = $data;
}
}
// 发货流程页只触发打 1 份面单,避免队列里出现多单
if (count($mydata) > 1) {
$mydata = array_slice($mydata, 0, 1);
}
// JSON 输出给前端直接调用 printer.js
$custom_data = array();
if (isset($printTpl['template_select']) && $printTpl['template_select']) {
$decoded = json_decode($printTpl['template_select'], true);
if (is_array($decoded)) {
$custom_data = $decoded;
}
}
$printer_type = (isset($printTpl['control_type']) && $printTpl['control_type'] !== '') ? $printTpl['control_type'] : 'cainiao';
echo json_encode(array(
'status' => 'success',
'printer_type' => $printer_type,
'options' => array(
'data' => $mydata,
'template' => isset($printTpl['template_data']) ? str_replace('url:', '', $printTpl['template_data']) : '',
'custom_template_url' => isset($printTpl['custom_area_url']) ? $printTpl['custom_area_url'] : '',
'custom_data' => $custom_data,
),
'express_company_no' => $express_company_no,
'err' => $_err,
));
return;
}
function covertNullToString(&$items) {
foreach ($items as $k => &$v) {
if ($v === null) {