Jianw
2025-05-13 3b39fe3810c3ee2ec9ec97236c1769c5c85e062c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
--[[
    编码: WMS-40-22
    名称: 作业-成品出库-启动
    作者:HAN  
    日期:2025-1-29
 
    版本: V6.0
    
    说明:该脚本和项目关联度较高,会根据项目不同而不同
    函数: OperationStart
 
    输入条件:
        1)  globa_attr 全局属性
            {
                factory:"0000"
                start_area:"AL1-01"
                op_id:"{5F0C57D6-85BB-4578-AF13-89C0BB7A3BC9}"
                op_type:"1"
                cntr_code:"TP20000001"
                start_site_layer:"0"
                op_code:"OP230926-00672"
                start_site:"1001"
                start_loc:"LL1-1001"
                start_wh:"W001"
            }
        2) dataJson -- 后台匹配到的 作业定义属性
            {
                start_wh:"W001"
                start_area:"AL1-01"
                enable:1
                name:"成品出库"
                type:1
                code:"OP012"
                end_wh:"W001"
                end_area:""
                factory:"0000"
                priority:1
                work_mode:0
            }
        3) dataobj  -- Operation 对象
 
    功能:
        1)根据入库规则计算出入库位置
        2)创建2个任务
            1 -- NDC 从线体出口搬运到 指定货位
            2 -- 线体把货品搬运到 1,3,4,5 楼的线体出库口,搬运到1楼出库口
 
--]]
 
wms_op = require( "wms_operation" )
wms_wh = require( "wms_wh" )
 
function OperationStart ( strLuaDEID ) 
    local nRet, strRetInfo
 
    lua.Debug( strLuaDEID, debug.getinfo(1), "成品出库作业启动", 1 )
 
    -- 通过全局参数 获取触发【作业】启动事件时服务端设置的一些输入参数
    -- start_loc,op_code,start_area, cntr_code 详细见mobox-WMS 编程指南
    local global_attrs
    nRet, global_attrs = m3.GetSysGloablAttr( strLuaDEID )
    if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), global_attrs ) end
 
    -- 获取当前的【作业定义】 信息
    -- 根据【作业定义】中定义的终点仓库、库区、货位信息确定入库的目标货位
    local op_def
    nRet, op_def = m3.GetSysDataJson( strLuaDEID )
    if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), op_def ) end
 
    local end_wh_code = ''
    local end_area_code = ''        -- 出库分拣区
 
    -- 获取作业对象, 从作业对象中获取{扩展数据}, 从{扩展数据}获取线体设备编码
    local operation = {}
    nRet, operation = m3.GetSysCurEditDataObj( strLuaDEID, "Operation" )
    if (nRet ~= 0) then lua.Error( strLuaDEID, debug.getinfo(1), "获取作业对象属性失败!"..operation ) end
 
    if ( op_def.type ~= wms_base.Get_nConst(strLuaDEID, "作业类型-出库") ) then
        -- 注意这里不用Error说明还是需要主线程继续匹配另外的 作业定义
        -- 如果采用Error主线程程序会被终止
        lua.Warning( strLuaDEID, debug.getinfo(1), "作业定义中的类型不是出库类型!" ) 
        return
    end
 
    -- 判断作业里是否有明确容器,如果已经明确了容器说明出库的货品已经确定
    -- 在新兴项目中容器是必须要有,因为成品出库是通过发货单、分拣单来生成的
    if( operation.cntr_code == '' ) then lua.Error( strLuaDEID, debug.getinfo(1), "作业中必须要有容器编号!" ) end
 
    -- 确定出库口区域和分拣口
    -- 获取出库的分拣口,先从作业里获取,如果没有从作业定义里获取,还是没有从仓库的“分拣”功能区获取
    local strErr
    if ( operation.end_area_code ~= '') then
        end_wh_code = lua.Get_StrAttrValue( operation.end_wh_code )
        end_area_code = lua.Get_StrAttrValue( operation.end_area_code )
    else
        end_wh_code = op_def.end_wh 
        end_area_code = op_def.end_area
    end 
    if ( end_wh_code == nil or end_wh_code == '' ) then  lua.Error( strLuaDEID, debug.getinfo(1), "作业定义或作业信息不完整,必须要有出库仓库编码!" ) end 
    if ( end_area_code == '' or end_area_code == nil ) then 
        -- 通过作业和作业定义都无法货位分拣区、分拣位
        -- 通过 end_wh_code 的分拣功能区来确定
 
        local sorting_arae_loc_list = wms_base.Get_Warehouse_FuncArea( strLuaDEID, end_wh_code, "功能区类型-分拣" )
        local nCountFA = #sorting_arae_loc_list
 
        if ( nCountFA == 0 ) then  lua.Error( strLuaDEID, debug.getinfo(1), "仓库:"..end_wh_code .."必须要定义一个'分拣'类型的功能区!" ) end
        -- 在新兴的项目中库区的出库接驳区位只能是一个,如果有多个这里就要加均衡
        if ( nCountFA ~= 1 ) then  lua.Error( strLuaDEID, debug.getinfo(1), "仓库:"..end_wh_code .."只能定义一个'分拣'类型的功能区、位" ) end
        if ( sorting_arae_loc_list[1].type ~= wms_base.Get_nConst(strLuaDEID, "基础类型-库区") ) then 
            lua.Error( strLuaDEID, debug.getinfo(1), "仓库:"..end_wh_code.."只能定义库区类型的'分拣'区" ) 
        end
        end_area_code = sorting_arae_loc_list[1].code
    end
 
    -- 获取 起点货位 所在仓库,库区的 接驳区或接驳位
    local start_wh_code = operation.start_wh_code
    local start_area_code = operation.start_area_code
    -- 获取接驳位
    local dock_loc = ''     -- 接驳位
 
    lua.Debug( strLuaDEID, debug.getinfo(1), "start_wh_code", start_wh_code )
    lua.Debug( strLuaDEID, debug.getinfo(1), "operation", operation )
    
    local dock_arae_loc_list = wms_base.Get_Warehouse_FuncArea( strLuaDEID, start_wh_code, "功能区类型-出库接驳" )
    -- 在新兴的项目中库区的出库接驳区位只能是一个,如果有多个这里就要加均衡
    if ( #dock_arae_loc_list ~= 1 ) then 
        strErr =  "仓库:"..start_wh_code
        if ( start_area_code ~= '') then strErr = strErr.." 库区:"..start_area_code end
        strErr = strErr.."只能定义一个'出库接驳'类型的功能区、位"
        lua.Error( strLuaDEID, debug.getinfo(1), strErr )
    end
    -- 如果定义的功能区位不是货位类型报错
    if ( dock_arae_loc_list[1].type ~= 1) then
        strErr =  "仓库:"..start_wh_code
        if ( start_area_code ~= '') then strErr = strErr.." 库区:"..start_area_code end
        strErr = strErr.."只能定义货位类型的'出库接驳'位"
        lua.Error( strLuaDEID, debug.getinfo(1), strErr )        
    end
    lua.Debug( strLuaDEID, debug.getinfo(1), "dock_arae_loc_list", dock_arae_loc_list )
    dock_loc = dock_arae_loc_list[1].code
 
    -- AGV搬运任务需要 货位的 AGV站点 属性,因此需要根据货位去获取一下站点信息
    local loc_from, loc_to
    nRet, loc_from = wms_wh.Location_GetInfo( strLuaDEID, operation.start_loc_code )
    if (nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1),"wms_wh.Location_GetInfo 失败!"..loc_from) end
    nRet, loc_to = wms_wh.Location_GetInfo( strLuaDEID, dock_loc )
    if (nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1),"wms_wh.Location_GetInfo 失败!"..loc_to) end
 
    -- 创建 AGV 搬运任务
    local task = m3.AllocObject(strLuaDEID,"Task")
    task.sort_no = 1
    task.op_code = operation.code                               -- 作业编码
    task.op_name = operation.op_def_name
    task.factory = operation.factory                            -- 工厂
    task.type = wms_base.Get_nConst(strLuaDEID, "任务类型-AGV出库搬运")   -- 任务类型
    task.cntr_code = operation.cntr_code
    -- 起点
    task.start_wh_code = operation.start_wh_code
    task.start_area_code  = operation.start_area_code
    task.start_loc_code  = operation.start_loc_code
    task.start_site = loc_from.agv_site
    -- 终点
    task.end_wh_code  = loc_to.wh_code
    task.end_area_code  = loc_to.area_code
    task.end_loc_code  = loc_to.code
    task.end_site   = loc_to.agv_site
    task.schedule_type = wms_base.Get_nConst(strLuaDEID, "调度类型-NDC") -- 设置调度类型
    
    lua.Debug( strLuaDEID, debug.getinfo(1), "task1", task )
 
    nRet, task = m3.CreateDataObj(strLuaDEID, task)
    if (nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1),"创建AGV任务失败!"..task) end
    -- 任务创建完成后,需要给任务的两个货位加锁
    -- 把开始货位加出库锁,重点货位加入库锁
    nRet, strRetInfo = wms_task.LockLocation( strLuaDEID, task, "锁类型-出库锁", "锁类型-入库锁" )
    if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1),"wms_task.LockLocation失败!"..strRetInfo ) end
end