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) {

View File

@@ -36,7 +36,17 @@ class wms_delivery_check{
$delivery_id = $deliveryBill ? $deliveryBill['delivery_id'] : 0;
$delivery = $dlyModel->getList('branch_id,delivery_id,status,deli_cfg,process_status,delivery_bn,print_status,logi_number',array('delivery_id'=>$delivery_id),0,1);
// [提货物流] delivery_model='pickup' 运单号后取,扫描的是发货单号
if (empty($delivery)) {
$pickupDly = $dlyModel->getList('branch_id,delivery_id,status,deli_cfg,process_status,delivery_bn,print_status,logi_number', array('delivery_bn' => $logi_no, 'delivery_model' => 'pickup'), 0, 1);
if ($pickupDly) {
$delivery = $pickupDly;
$delivery_id = $pickupDly[0]['delivery_id'];
$deliveryBill = $dlyBillMdl->db_dump(array('delivery_id' => $delivery_id, 'type' => 1));
}
}
//[同城配]商家配送支持配送员手机号搜索
if(empty($delivery) && strlen($logi_no) == 11){
$delivery = $dlyModel->getList('*', array('deliveryman_mobile'=>$logi_no, 'process_status'=>array(0,1)), 0, 1);
@@ -310,7 +320,17 @@ class wms_delivery_check{
}
}
}
// [提货物流] delivery_model='pickup' 运单号后取,扫描的是发货单号
if (empty($dly)) {
$pickupDly = $dlyObj->dump(array('delivery_bn' => $logi_no, 'delivery_model' => 'pickup'), 'delivery_id');
if ($pickupDly) {
$primary = true;
$delivery_id = $pickupDly['delivery_id'];
$dly = $dlyObj->dump(array('delivery_id' => $delivery_id), '*', array('delivery_items' => array('*')));
}
}
//[同城配]商家配送支持配送员手机号搜索
if(empty($dly) && strlen($logi_no) == 11){
$dly = $dlyObj->dump(array('deliveryman_mobile'=>$logi_no, 'process_status'=>array(2,3)), '*', array('delivery_items'=>array('*')));

View File

@@ -245,6 +245,7 @@ class wms_delivery_process{
*/
function consignDelivery($dly_id, $type='') {
$deliveryObj = app::get('wms')->model('delivery');
$opinfo = array();
$delivery_time = time();
$filter['delivery_id'] = $dly_id;
@@ -256,7 +257,7 @@ class wms_delivery_process{
if(!is_numeric($affect_row) || $affect_row <= 0){
return false;
}else{
$deliveryInfo = $deliveryObj->dump($dly_id,'delivery_bn,outer_delivery_bn,branch_id,weight,delivery_cost_actual');
$deliveryInfo = $deliveryObj->dump($dly_id, '*');
//如果发货成功,处理保质期批次的变化:冻结释放,实际数量扣减,单据转正
$storageLifeReceiptLib = kernel::single('material_receipt_storagelife');
@@ -304,6 +305,9 @@ class wms_delivery_process{
$deliveryBillItemMdl = app::get('wms')->model('delivery_bill_items');
$bill_list = $billObj->getList('*',array('delivery_id'=>$dly_id, 'status'=>'1'));
// 获取主单运单号
$primary_bill = $billObj->dump(array('delivery_id'=>$dly_id, 'type'=>'1', 'status'=>'1'), '*');
$other_list_0 = array(); $packages = [];
foreach ($bill_list as $bill) {
@@ -322,6 +326,16 @@ class wms_delivery_process{
);
}
// logi_id
if ($deliveryInfo['logi_id']) {
$data['logistics'] = $deliveryInfo['logi_id'];
}
// logi_no
if (isset($primary_bill['logi_no']) && $primary_bill['logi_no']) {
$data['logi_no'] = $primary_bill['logi_no'];
}
$data['other_list_0'] = json_encode($other_list_0);
$data['packages'] = json_encode($packages);
@@ -361,6 +375,12 @@ class wms_delivery_process{
}
$res = kernel::single('wms_event_trigger_delivery')->consign($wms_id, $data, true);
if ($res === false || (is_array($res) && $res['rsp'] == 'fail')) {
$msg = is_array($res) && $res['msg'] ? '通知OMS发货失败' . $res['msg'] : '通知OMS发货失败';
$opObj->write_log('delivery_process@wms', $dly_id, $msg,'',$opinfo);
return false;
}
return true;
}

View File

@@ -87,6 +87,7 @@ class wms_event_trigger_logistics_data_electron_wxshipin extends wms_event_trigg
}
$dlyCorp = app::get('ome')->model('dly_corp')->dump(array('corp_id' => $delivery['logi_id']));
app::get('ome')->model('dly_corp_channel')->getChannel($dlyCorp, array($delivery));
$prt_tmpl_id = $dlyCorp['prt_tmpl_id'];

View File

@@ -164,6 +164,7 @@ class wms_event_trigger_logistics_data_electron_xhs extends wms_event_trigger_lo
}
$dlyCorp = app::get('ome')->model('dly_corp')->dump(array('corp_id' => $delivery['logi_id']));
app::get('ome')->model('dly_corp_channel')->getChannel($dlyCorp, array($delivery));
$sdf = parent::getDirectSdf($arrDelivery, $arrBill, $shop);
$sdf['primary_bn'] = $delivery['delivery_bn'];

View File

@@ -17,7 +17,7 @@
class wms_finder_delivery{
var $detail_basic = "发货单详情";
var $detail_item = "货品详情";
var $detail_item = "基础物料详情";
var $detail_delivery = "物流单列表";
var $detail_serial = "唯一码详情";
var $detail_storagelife = "保质期批次详情";
@@ -170,7 +170,7 @@ class wms_finder_delivery{
$content = $row[$this->col_prefix . 'bnsContent'];
$cnts = unserialize($content);
$cnt = sprintf("共有 %d 种商品,总共数量为 %d 件, 具体 SKU 为: %s", $skuNum, $itemNum, @implode(', ', $cnts));
$cnt = sprintf("共有 %d 种基础物料,总共数量为 %d 件, 具体 SKU 为: %s", $skuNum, $itemNum, @implode(', ', $cnts));
@reset($cnts);
$content = $cnts[@key($cnts)];
@@ -181,7 +181,7 @@ class wms_finder_delivery{
}
var $column_product_name = "货品名称";
var $column_product_name = "基础物料名称";
var $column_product_name_width = "160";
function column_product_name($row,$list) {
@@ -196,7 +196,7 @@ class wms_finder_delivery{
foreach ($product_id as $pid) {
$names[] = $productName[$pid];
}
$cnt = sprintf("共有 %d 种商品,总共数量为 %d 件, 具体 名称 为: %s", $skuNum, $itemNum, @implode(', ', $names));
$cnt = sprintf("共有 %d 种基础物料,总共数量为 %d 件, 具体 名称 为: %s", $skuNum, $itemNum, @implode(', ', $names));
@reset($names);
$content = $names[@key($names)];

View File

@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class wms_finder_extend_filter_branch_product{
function get_extend_colums(){
$db['branch_product']=array (
@@ -22,7 +21,7 @@ class wms_finder_extend_filter_branch_product{
'bn'=> array (
'type' => 'varchar(40)',
'editable' => false,
'label' => '货号',
'label' => '基础物料编码',
'width' => 110,
'filtertype' => 'normal',
'filterdefault' => true,
@@ -59,4 +58,4 @@ class wms_finder_extend_filter_branch_product{
}
}
?>
?>

204
app/wms/lib/logistics.php Normal file
View File

@@ -0,0 +1,204 @@
<?php
/**
* WMS 物流相关封装
* 统一通过 erpapi shop request 调用各平台物流接口
*/
class wms_logistics
{
/**
* 官方提货(提货物流)
* 入参为 wms delivery_id通过 outer_delivery_bn 对应 ome_delivery.delivery_bn 取 ome 发货单,
* 用 ome_event_trigger_shop_data_delivery_alibaba->get_sdf 取 sdf再调 erpapi 对应平台 officialPickup
* @param int|array $delivery_id wms 发货单主键;或数组且含 key delivery_id
* @return array 统一返回 ['rsp' => 'succ'|'fail', 'msg' => '', 'data' => ...],便于后续根据成功/失败处理
*/
public function officialPickup($delivery_id)
{
$fail = function ($msg, $data = null) {
return ['rsp' => 'fail', 'msg' => $msg, 'data' => $data];
};
$ok = function ($result) {
if (is_array($result) && isset($result['rsp'])) {
return $result;
}
return ['rsp' => 'succ', 'msg' => '', 'data' => $result];
};
$wms_delivery_id = is_array($delivery_id) ? (isset($delivery_id['delivery_id']) ? (int)$delivery_id['delivery_id'] : 0) : (int)$delivery_id;
if ($wms_delivery_id <= 0) {
return $fail('无效的发货单ID');
}
$wmsDeliveryMdl = app::get('wms')->model('delivery');
$wmsDelivery = $wmsDeliveryMdl->dump($wms_delivery_id, 'delivery_id,outer_delivery_bn,shop_id');
if (empty($wmsDelivery) || empty($wmsDelivery['outer_delivery_bn']) || empty($wmsDelivery['shop_id'])) {
return $fail('未找到WMS发货单或缺少 outer_delivery_bn/shop_id');
}
$omeDeliveryMdl = app::get('ome')->model('delivery');
$omeDelivery = $omeDeliveryMdl->dump(['delivery_bn' => $wmsDelivery['outer_delivery_bn']]);
if (empty($omeDelivery) || empty($omeDelivery['delivery_id'])) {
return $fail('未找到对应的OMS发货单');
}
$ome_delivery_id = $omeDelivery['delivery_id'];
$deliveryList = $omeDeliveryMdl->getList('*', ['delivery_id' => $ome_delivery_id]);
if (empty($deliveryList)) {
return $fail('OMS发货单列表为空');
}
$deliveryOrderMdl = app::get('ome')->model('delivery_order');
$deliveryOrderList = $deliveryOrderMdl->getList('delivery_id,order_id', ['delivery_id' => $ome_delivery_id]);
$order_ids = [];
$delivery_orders = [];
$orderList = [];
foreach ($deliveryOrderList as $row) {
$order_ids[] = $row['order_id'];
$delivery_orders[$row['delivery_id']] = &$orderList[$row['order_id']];
}
$orderModel = app::get('ome')->model('orders');
$orders = $orderModel->getList('*', ['order_id' => $order_ids]);
foreach ($orders as $o) {
$orderList[$o['order_id']] = $o;
}
$delivery = $deliveryList[0];
$order = isset($delivery_orders[$ome_delivery_id]) ? $delivery_orders[$ome_delivery_id] : null;
$sdf = $this->_buildOfficialPickupSdf($ome_delivery_id, $delivery, $order);
if (empty($sdf)) {
return $fail('获取平台发货数据(sdf)为空');
}
$result = kernel::single('erpapi_router_request')->set('shop', $wmsDelivery['shop_id'])->logistics_officialPickup($sdf);
$ret = $ok($result);
// 仅成功时:从平台返回结果中提取运单号,回写 OMS / WMS原 erpapi_shop_matrix_alibaba_request_delivery confirm_callback 逻辑)
if ($ret['rsp'] === 'succ' || $ret['rsp'] === 'success') {
$this->_officialPickupSyncLogiNo($ret, $sdf['delivery_bn'], $wmsDelivery['delivery_id']);
}
return $ret;
}
/**
* 在本类内直接组装 officialPickup 所需 sdf与 erpapi alibaba request logistics 入参一致,避免 router 取数不全
* 结构orderinfo.order_bn、delivery_items(oid/nums/number/weight)、memo、delivery_time、delivery_bn
* @param int $ome_delivery_id OMS 发货单 id
* @param array $delivery OMS 发货单行(含 delivery_bn, delivery_time, memo 等)
* @param array|null $order OMS 订单行(含 order_bn/platform_order_bn
* @return array 空表示组装失败,否则为 alibaba officialPickup 所需 sdf
*/
protected function _buildOfficialPickupSdf($ome_delivery_id, $delivery, $order)
{
if (empty($delivery) || empty($order)) {
return [];
}
$order_bn = isset($order['platform_order_bn']) && $order['platform_order_bn'] !== ''
? $order['platform_order_bn']
: (isset($order['order_bn']) ? $order['order_bn'] : '');
if ($order_bn === '') {
return [];
}
$detailMdl = app::get('ome')->model('delivery_items_detail');
$details = $detailMdl->getList('*', ['delivery_id' => $ome_delivery_id]);
if (empty($details)) {
return [];
}
$objIds = array_unique(array_column($details, 'order_obj_id'));
$objMdl = app::get('ome')->model('order_objects');
$objRows = $objMdl->getList('obj_id,oid', ['obj_id' => $objIds]);
$objId2Oid = [];
foreach ($objRows as $r) {
$objId2Oid[$r['obj_id']] = isset($r['oid']) ? trim((string)$r['oid']) : '';
}
$delivery_items = [];
foreach ($details as $d) {
$oid = isset($objId2Oid[$d['order_obj_id']]) ? $objId2Oid[$d['order_obj_id']] : '';
if ($oid === '') {
continue;
}
$num = isset($d['number']) ? (int)$d['number'] : 0;
if ($num < 1) {
continue;
}
$delivery_items[] = [
'oid' => $oid,
'nums' => $num,
'number' => $num,
'weight' => isset($d['weight']) ? (float)$d['weight'] : 0,
];
}
if (empty($delivery_items)) {
return [];
}
return [
'orderinfo' => ['order_bn' => $order_bn],
'delivery_items'=> $delivery_items,
'memo' => isset($delivery['memo']) ? $delivery['memo'] : '',
'delivery_time' => isset($delivery['delivery_time']) ? $delivery['delivery_time'] : time(),
'delivery_bn' => isset($delivery['delivery_bn']) ? $delivery['delivery_bn'] : '',
];
}
/**
* 从 officialPickup 返回的 result 中解析出 result.pickUpInfo与 yunqi saveOfficialPickupResult 一致data 可能为 JSON 字符串,且含 msg 内嵌 JSON
* @param array $result ['rsp'=>'succ','data'=>'...'] 其中 data 可能为 '{"msg":"{\"result\":{\"pickUpInfo\":{...}}}","success":true}'
* @return array|null pickUpInfo 或 null
*/
protected function _parseOfficialPickupResult($result)
{
$data = isset($result['data']) ? $result['data'] : $result;
if (is_string($data)) {
$data = json_decode($data, true);
if (is_array($data) && isset($data['msg']) && is_string($data['msg'])) {
$inner = json_decode($data['msg'], true);
if (is_array($inner)) {
$data = array_merge($data, $inner);
}
}
}
if (!is_array($data)) {
$data = array();
}
if (!empty($data['result']['pickUpInfo'])) {
return $data['result']['pickUpInfo'];
}
if (!empty($result['result']['pickUpInfo'])) {
return $result['result']['pickUpInfo'];
}
return null;
}
/**
* 官方提货成功:从接口返回中解析 pickUpInfo.mailNo回写 OMS 与 WMS 运单号
* @param array $result officialPickup 返回的 ['rsp'=>'succ','data'=>...]
* @param string $delivery_bn OMS 发货单号delivery_bn
* @param int $wms_delivery_id WMS 发货单主键
*/
protected function _officialPickupSyncLogiNo($result, $delivery_bn, $wms_delivery_id)
{
$pickUpInfo = $this->_parseOfficialPickupResult($result);
if (empty($pickUpInfo) || empty($pickUpInfo['mailNo'])) {
return;
}
$mailNo = trim($pickUpInfo['mailNo']);
// OMS: 通过 addLogiNo 统一链路更新 ome_delivery.logi_no
kernel::single('ome_event_receive_delivery')->update([
'delivery_bn' => $delivery_bn,
'logi_no' => $mailNo,
'action' => 'addLogiNo',
'status' => 'update',
]);
// WMS: 同步更新 wms_delivery_bill.logi_notype=1 主单)
app::get('wms')->model('delivery_bill')->update(
['logi_no' => $mailNo],
['delivery_id' => $wms_delivery_id, 'type' => 1]
);
}
}

View File

@@ -88,6 +88,13 @@ class wms_operation_log{
'fukubukuro_combine_add' => array('name'=>'福袋组合添加', 'type'=>'fukubukuro_combine@material'),
'fukubukuro_combine_edit' => array('name'=>'福袋组合编辑', 'type'=>'fukubukuro_combine@material'),
'fukubukuro_combine_modify' => array('name'=>'编辑关联销售物料', 'type'=>'fukubukuro_combine@material'),
// 赠品审批实例
'order_workflow_case' => array('name'=>'赠品审批', 'type'=>'workflow_case@ticket'),
// SET商品
'set_materialprice_create' => array('name'=>'创建加价购', 'type'=>'basic_material_price@miele'),
'set_materialprice_edit' => array('name'=>'编辑加价购', 'type'=>'basic_material_price@miele'),
);
return array('wms'=>$operations);

View File

@@ -118,7 +118,7 @@ class wms_mdl_branch_product extends ome_mdl_branch_product{
'*:仓库' => 'branch_name',
'*:货号' => 'bn',
'*:条形码' => 'barcode',
'*:货品名称' => 'name',
'*:基础物料名称' => 'name',
'*:库存' => 'store',
'*:冻结库存' => 'store_freeze',
'*:在途库存'=>'arrive_store'

View File

@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class wms_mdl_delivery extends dbeav_model{
public $filter_use_like = true;
var $has_many = array(
@@ -57,11 +56,56 @@ class wms_mdl_delivery extends dbeav_model{
///////////////////////////
// 加密处理逻辑 2017/5/5 by cp //
///////////////////////////
//filter - 加密字段处理
$encryptWhere = kernel::single('ome_filter_encrypt')->encrypt($filter, $this->__encrypt_cols, $tPre, 'delivery');
$baseWhere = array_merge($baseWhere, $encryptWhere);
$where = '';
foreach ($filter as $key => $value) {
$pos = strpos($key,'|');
$field = false !== $pos ? substr($key,0,$pos): $key;
$encrypt_type = $this->__encrypt_cols[$field];
if ($encrypt_type) {
$searchtype = false !== $pos ? substr($key,$pos+1): 'nequal';
// 京东加密
$encryptVal360 = kernel::single('erpapi_rpc_hufu')->encrypt($value).kernel::single('ome_security_hash')->get_code();
// 拼多多加密
$encryptValPdd = kernel::single('erpapi_rpc_fangzhou')->encrypt($value).kernel::single('ome_security_hash')->get_code();
if ($searchtype!='nequal' && in_array($encrypt_type,array('search','nick','receiver_name'))) {
$encryptVal = kernel::single('ome_security_factory')->search($value,$encrypt_type);
$encryptVal360 = kernel::single('ome_security_factory')->search($encryptVal360,$encrypt_type);
$encryptValPdd = kernel::single('ome_security_factory')->search($encryptValPdd,$encrypt_type);
} else {
$encryptVal = kernel::single('ome_security_factory')->encryptPublic($value,$encrypt_type);
$encryptVal360 = kernel::single('ome_security_factory')->encryptPublic($encryptVal360,$encrypt_type);
$encryptValPdd = kernel::single('ome_security_factory')->encryptPublic($encryptValPdd,$encrypt_type);
}
$originalVal = utils::addslashes_array($value);
$encryptVal = utils::addslashes_array($encryptVal);
switch ($searchtype) {
case 'has':
$baseWhere[] = "({$tPre}{$field} LIKE '%".$originalVal."%' || {$tPre}{$field} LIKE '%".$encryptVal."%')";
break;
case 'head':
$baseWhere[] = "({$tPre}{$field} LIKE '".$originalVal."%' || {$tPre}{$field} LIKE '%".$encryptVal."%')";
break;
case 'foot':
$baseWhere[] = "({$tPre}{$field} LIKE '%".$originalVal."' || {$tPre}{$field} LIKE '%".$encryptVal."%')";
break;
default:
$baseWhere[] = "{$tPre}{$field} IN('".$originalVal."','".$encryptVal."','".$encryptVal360."','".$encryptValPdd."')";
break;
}
unset($filter[$key]);
}
}
if(isset($filter['ship_tel_mobile'])){
$encryptVal = kernel::single('ome_security_factory')->encryptPublic($filter['ship_tel_mobile'],'phone');
$encryptVal = utils::addslashes_array($encryptVal);
@@ -581,7 +625,7 @@ class wms_mdl_delivery extends dbeav_model{
}
/**
* 获取打印货品
* 获取打印基础物料
*
* @param Array $deliverys 发货单集合
* @return void
@@ -601,7 +645,7 @@ class wms_mdl_delivery extends dbeav_model{
}
}
// 货品货位有关系
// 基础物料货位有关系
$bppModel = app::get('ome')->model('branch_product_pos');
$bppList = $bppModel->getList('product_id,pos_id,branch_id',array('product_id'=>$product_ids));
@@ -1128,7 +1172,7 @@ class wms_mdl_delivery extends dbeav_model{
$_rows = $this->db->select($_sql);
$_store_position = null;
if(!empty($_rows[0])){
#一个货品有多个货位时,中间要隔开
#一个基础物料有多个货位时,中间要隔开
foreach($_rows as $v){
$_store_position .= $v['store_position'].'|';
}
@@ -1139,7 +1183,7 @@ class wms_mdl_delivery extends dbeav_model{
$product_info = $basicMaterialLib->getBasicMaterialExt($row['product_id']);
#处理货品多规格值
#处理基础物料多规格值
$spec_value = '';
if(is_array($product_info['spec_desc']['spec_value']) && !empty($product_info['spec_desc']['spec_value'])){
$spec_value = implode('|',$product_info['spec_desc']['spec_value']);
@@ -1339,7 +1383,7 @@ class wms_mdl_delivery extends dbeav_model{
return $type;
}
//逐单发货时根据发货单id获取货号、货品名称、数量、重量
//逐单发货时根据发货单id获取基础物料编码、基础物料名称、数量、重量
function getProcutInfo($delivery_id){
$sql = 'select
items.bn,items.product_id,items.product_name,items.number,delivery.net_weight,delivery.delivery_id
@@ -1430,7 +1474,7 @@ class wms_mdl_delivery extends dbeav_model{
'columns' => array (
'bn' => array(
'type' => 'varchar(30)',
'label' => '商品货号',
'label' => '基础物料编码',
'width' => 85,
'editable' => false,
),
@@ -1599,7 +1643,7 @@ class wms_mdl_delivery extends dbeav_model{
$_rows = $this->db->select($_sql);
$_store_position = null;
if(!empty($_rows[0])){
#一个货品有多个货位时,中间要隔开
#一个基础物料有多个货位时,中间要隔开
foreach($_rows as $v){
$_store_position .= $v['store_position'].'|';
}

View File

@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class wms_mdl_inventory extends dbeav_model{
var $export_name = '盘点表';
@@ -41,7 +40,7 @@ class wms_mdl_inventory extends dbeav_model{
}
/*
* 获取货品
* 获取基础物料
*/
function getBranchProduct($branch_id, $barcode)
{
@@ -179,7 +178,7 @@ class wms_mdl_inventory extends dbeav_model{
return $arr;
}
/*
* 获取货品信息
* 获取基础物料信息
*/
function getProduct($data=null, $lim=0, $limit=1, $type='search'){
@@ -855,7 +854,7 @@ class wms_mdl_inventory extends dbeav_model{
return $titleRs;
}else{
if( $row[0] ){
# 盘点货品处理
# 盘点基础物料处理
if( array_key_exists( '*:商品名称',$title ) )
{
$product = $basicMaterialObj->dump(array('material_bn'=>trim($row[1])), 'bm_id');
@@ -1020,7 +1019,7 @@ class wms_mdl_inventory extends dbeav_model{
}
/*
* 根据条码获取货品
* 根据条码获取基础物料
*/
function getProductbybarcode($branch_id, $barcode)
{
@@ -1045,7 +1044,7 @@ class wms_mdl_inventory extends dbeav_model{
}
/*
* 根据货号获取货品
* 根据基础物料编码获取基础物料
*/
function getProductbybn($branch_id, $bn)
{
@@ -1110,4 +1109,4 @@ class wms_mdl_inventory extends dbeav_model{
}
}
?>
?>

View File

@@ -93,6 +93,8 @@
var weightSet ='<{$weightSet}>';
var weightWarn='<{$weightWarn}>';
var logi_no_position = '<{$logi_no_position}>';
var BASE_URL = '<{$env.BASE_URL}>';
var currentDeliveryIsPickup = false;
switch(logi_no_position){
case 'up':
@@ -215,10 +217,13 @@ function delivery_verify(e){
}
}catch(e){}
return MessageBox.error(json.msg);
}else{
if (json != ''){
json = json.filter(function(n){
}
if (typeof json === 'object' && json.status === 'ok'){
currentDeliveryIsPickup = (json.is_pickup === true);
json = '';
}
if (json != ''){
json = json.filter(function(n){
if (n.order_exists_refund != ''){
is_confirm_delivery = true;
refund_orders = n.order_exists_refund;
@@ -372,23 +377,44 @@ function delivery_verify(e){
}});
}else{
submitSend(e);
if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').submit(); }
}
}
}else{
submitSend(e);
if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').submit(); }
}
}
}
}
}
}).send();
}
function submitSend(e){
$('ome_single_delivery').fireEvent('submit',{stop:$empty});
var form = $('ome_single_delivery');
if (form.retrieve('submiting')) return;
var target = form.retrieve('target') || {};
// 先触发打印(不等待),再提交 consign打印异常也不影响 consign 提交
var printVal = $('delivery_id').value || '';
if (printVal) {
try { autoCainiaoPrint(printVal); } catch (err) {}
}
if (target.onRequest) target.onRequest();
form.store('submiting', true);
new Request({
url: form.get('action'),
method: (form.get('method') || 'post').toLowerCase(),
data: form,
onComplete: function(resp) {
if (form && form.uid) form.eliminate('submiting');
if (target.onComplete) target.onComplete(resp);
},
onFailure: function() {
if (form && form.uid) form.eliminate('submiting');
$('sendProduct').set('disabled', '');
$('sendProduct').getElements('span')[1].set('text','确认出库');
$('error').show().set('html', '请求失败,请重试');
}
}).send();
}
//根据物流单号,获取货号、货品名称
function showProductItems(){
@@ -429,8 +455,125 @@ $('ome_single_delivery').store('target',{
}
}else{
$('sendProduct').set('disabled', 'true');
if (json.redirect) {
if (typeof MessageBox !== 'undefined') {
new MessageBox(json.success || '发货处理完成', { type: 'success', autohide: 1500 });
}
var url = json.redirect;
var q = (window.location.search || '').replace(/^\?/, '');
if (q) url += (url.indexOf('?') >= 0 ? '&' : '?') + q;
setTimeout(function(){ window.location.href = url; }, 800);
}
}
}
});
</script>
// 仅 pickup 时拦截 submit走自定义 Request + 打印 + redirect非 pickup 保持原样 fireEvent('submit') 由框架处理
$('ome_single_delivery').addEvent('submit', function(e) {
if (currentDeliveryIsPickup) {
e.stop();
if (e.preventDefault) e.preventDefault();
submitSend(e);
return false;
}
});
var _printerJsLoaded = false;
function _loadPrinterJs(cb) {
if (_printerJsLoaded && typeof(initPrinter) == 'function') return cb();
if (typeof(Ex_Loader) == 'function') {
Ex_Loader('security', BASE_URL + '/app/logisticsmanager/statics/js/printer.js?v=20210412', function(){
_printerJsLoaded = true;
cb();
});
return;
}
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = BASE_URL + '/app/logisticsmanager/statics/js/printer.js?v=20210412';
s.onload = function(){ _printerJsLoaded = true; cb(); };
document.getElementsByTagName('head')[0].appendChild(s);
}
function autoCainiaoPrint(deliveryId) {
_loadPrinterJs(function(){
new Request({
url:'index.php?app=wms&ctl=admin_receipts_print&act=ajaxGetPrintExpreData',
method:'POST',
data:{delivery_id:deliveryId},
onSuccess:function(resp){
resp = (resp || '').trim();
var ret = resp ? JSON.decode(resp) : {};
if (!ret || ret.status != 'success') {
if (ret && ret.msg && (ret.msg.indexOf('未找到提货单') >= 0 || ret.msg.indexOf('非提货单') >= 0)) return;
var msg = ret && ret.msg ? ret.msg : '获取打印数据失败';
$('error').show().set('html',msg);
return;
}
var options = ret.options || {};
var printerType = (ret.printer_type && ret.printer_type !== '') ? ret.printer_type : 'cainiao';
if (printerType === 'cainiao' && options.data && options.data.length) {
var hasJsonPacket = options.data.every(function(item){ return item && typeof item.json_packet === 'string' && item.json_packet.length > 0; });
if (!hasJsonPacket) {
$('error').show().set('html', '无电子面单数据,无法触发菜鸟打印。请确认该单已获取电子面单或稍后在打印页补打。');
return;
}
}
options.onError = function(data){
var msg = (typeof data == 'object' && data.errmsg) ? data.errmsg : '与菜鸟打印组件通信失败,请确认已安装并打开菜鸟组件';
$('error').show().set('html',msg);
};
var decrypted = false;
var printersReady = false;
var printerName = '';
var printed = false;
var printTriggered = false;
options.onOpen = function(){
try { printerObj.getPrinters(); } catch(e){}
};
options.onGetPrinters = function(data){
if(!data.printers || data.printers.length == 0) {
$('error').show().set('html', data.msg ? data.msg : '没有可用打印机');
return;
}
printerName = data.defaultPrinter ? data.defaultPrinter : data.printers[0].name;
printersReady = true;
tryStartPrint();
};
options.onDecryptComplete = function(p){
if (p && p.rsp == 'fail') {
$('error').show().set('html', p.errmsg ? p.errmsg : '数据解密失败');
return;
}
decrypted = true;
tryStartPrint();
};
options.onPrintFailure = function(data){
var msg = data && data.msg ? data.msg : '打印失败';
$('error').show().set('html', msg);
printed = false;
};
options.onPrintSuccess = function(){
printed = true;
};
var printerObj = initPrinter(printerType, options);
printerObj.decryptAsync(5);
function tryStartPrint(){
if (printTriggered) return;
if (!decrypted || !printersReady) return;
if (!printerName) return;
if (printerObj.destatus != 'succ') return;
printTriggered = true;
printed = true;
printerObj.print.delay(10, printerObj, [{name:printerName}]);
}
}
}).send();
});
}
</script>

View File

@@ -77,7 +77,7 @@
<div class="form-field">
<span class="form-field-label">发货校验商品数量设置:</span>
<input class="form-input" placeholder="请输入发货校验商品数量设置" type="text" name="set[wms.delivery.check]" value="<{$setData.wms_delivery_check}>" vtype="required&&unsignedint" />
<span class="form-remark">同一货品数量大于设置数量时可以通过录入数量来批量检验</span>
<span class="form-remark">同一基础物料数量大于设置数量时可以通过录入数量来批量检验</span>
</div>
<div class="form-field">
<span class="form-field-label">逐单发货是否称重:</span>
@@ -118,14 +118,14 @@
</div>
<div class="form-field weightwarn_on">
<span class="form-field-label">逐单发货称重报警设置:</span>
包裹称重重量比系统中货品净重多出<input class="form-input" style="width: 5%" type="text" name="set[wms.delivery.max_weightwarn]" value="<{$setData.wms_delivery_max_weightwarn|default:0}>" vtype="required&&unsignedint" />
包裹称重重量比系统中基础物料净重多出<input class="form-input" style="width: 5%" type="text" name="set[wms.delivery.max_weightwarn]" value="<{$setData.wms_delivery_max_weightwarn|default:0}>" vtype="required&&unsignedint" />
<span id='warnunit1' style="width:20px;"><{if $setData.wms_delivery_maxpercent=='1'}>%<{else}>g<{/if}></span>
<input type="hidden" id="maxpercent" name="set[wms.delivery.maxpercent]" value="<{$setData.wms_delivery_maxpercent|default:0}>">&nbsp;&nbsp;以上,进行报警
<input type="checkbox" class='weightpercent' value="1" <{if $setData.wms_delivery_maxpercent=='1'}>checked<{/if}>>按百分比计算
</div>
<div class="form-field weightwarn_on1">
<span class="form-field-label"></span>
包裹称重重量比系统中货品净重少了<input class="form-input" style="width: 5%" type="text" name="set[wms.delivery.min_weightwarn]" value="<{$setData.wms_delivery_min_weightwarn|default:0}>" vtype="required&&unsignedint" />
包裹称重重量比系统中基础物料净重少了<input class="form-input" style="width: 5%" type="text" name="set[wms.delivery.min_weightwarn]" value="<{$setData.wms_delivery_min_weightwarn|default:0}>" vtype="required&&unsignedint" />
<span id='warnunit2' ><{if $setData.wms_delivery_minpercent=='1'}>%<{else}>g<{/if}></span>
<input type="hidden" id="minpercent" name="set[wms.delivery.minpercent]" value="<{$setData.wms_delivery_minpercent|default:0}>">&nbsp;&nbsp;以上,进行报警
<input type="checkbox" class='weightpercent1' value="2" <{if $setData.wms_delivery_minpercent=='1'}>checked<{/if}>>按百分比计算
@@ -263,4 +263,4 @@ window.addEvent('domready',function(){
}
}
});
</script>
</script>

View File

@@ -26,9 +26,9 @@
<tr>
<th style='text-align:left;padding-left:5px;'>采购单号</th>
<th style='text-align:left;padding-left:5px;'>拣货单号</th>
<th style='text-align:left;padding-left:5px;'>货号</th>
<th style='text-align:left;padding-left:5px;'>基础物料编码</th>
<th style='text-align:left;padding-left:5px;'>条形码</th>
<th style='text-align:left;padding-left:5px;'>货品名称</th>
<th style='text-align:left;padding-left:5px;'>基础物料名称</th>
<th style='text-align:left;padding-left:5px;'>尺寸</th>
<th style='text-align:left;padding-left:5px;'>申请数量</th>
<th style='text-align:left;padding-left:5px;'>实际数量</th>