package service
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/go-xorm/xorm"
|
|
"leit.com/leit_seat_aps/common"
|
|
"leit.com/leit_seat_aps/db"
|
|
)
|
|
|
|
/**
|
|
基于已派工生产订单计算拣料单
|
|
基本逻辑:
|
|
1. 加载产线对应的拣料单模板
|
|
2. 循环加载派工生产订单,按产线和schedKey排序
|
|
3. 遍历生产订单零件列表
|
|
4. 遍历零件属性和生产订单对应产线的拣料单属性进行适配,满足则将该零件和数量添加到该拣料单中
|
|
5. 拣料单满,关闭拣料单并新建一个空拣料单
|
|
**/
|
|
|
|
type PickingEngine struct {
|
|
PlanMode string
|
|
PickOrderSN string // 拣料单流水号SN
|
|
PickingTmpDict map[string]BL_PickingTemplate // 拣料单模板
|
|
WorklineDict map[string]BL_Workline // 产线
|
|
Projectdict map[string]BL_Project // 所有的项目主数据
|
|
}
|
|
|
|
// 加载产线数据
|
|
func (pe *PickingEngine) LoadWorkLines() (err error) {
|
|
var (
|
|
wltab db.Workline
|
|
wltablst []db.Workline
|
|
bl_wl BL_Workline
|
|
i int
|
|
)
|
|
|
|
wltab = db.Workline{}
|
|
if wltablst, err = wltab.GetByPlanMode(pe.PlanMode); err != nil {
|
|
return
|
|
}
|
|
|
|
pe.WorklineDict = make(map[string]BL_Workline)
|
|
for i = 0; i < len(wltablst); i++ {
|
|
wltablst[i].Clipped()
|
|
bl_wl = BL_Workline{}
|
|
bl_wl.PickTmpDict = make(map[string]BL_PickingTemplate)
|
|
bl_wl.WorklineId = wltablst[i].Worklineid
|
|
bl_wl.SortMode = wltablst[i].Taskqueuesortway
|
|
if wltablst[i].Multiqueuemixsort == 1 {
|
|
bl_wl.MixSort = true
|
|
bl_wl.MixSortMode = wltablst[i].Taskqueuemixsortway
|
|
bl_wl.MixSortRule = wltablst[i].Mixsortlogic
|
|
} else {
|
|
bl_wl.MixSort = false
|
|
}
|
|
bl_wl.ReleaseMode = wltablst[i].Taskreleaseway
|
|
bl_wl.ReleaseValue = wltablst[i].Releaseparameter
|
|
bl_wl.Worklinetab = wltablst[i]
|
|
pe.WorklineDict[bl_wl.WorklineId] = bl_wl
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 加载拣料单模板
|
|
func (pe *PickingEngine) LoadPickingTemplates() (err error) {
|
|
var (
|
|
pktmptab db.Pln_picktemplate
|
|
pktmptablst []db.Pln_picktemplate
|
|
bl_pktmp BL_PickingTemplate
|
|
bl_wl BL_Workline
|
|
i, j, k int
|
|
ok bool
|
|
)
|
|
|
|
// 加载拣料单模板
|
|
pktmptab = db.Pln_picktemplate{}
|
|
if pktmptablst, err = pktmptab.GetAllActive(); err != nil {
|
|
return
|
|
}
|
|
fmt.Println(pktmptablst)
|
|
for i = 0; i < len(pktmptablst); i++ {
|
|
bl_pktmp = BL_PickingTemplate{}
|
|
bl_pktmp.TemplateId = pktmptablst[i].Picktemplateid
|
|
bl_pktmp.WorklineId = pktmptablst[i].Worklineid
|
|
bl_pktmp.PrinterId = pktmptablst[i].Printerid
|
|
bl_pktmp.Picktemplatetab = pktmptablst[i]
|
|
bl_pktmp.AssignAttrDict = make(map[int]db.Pln_picktemplate_attrlst)
|
|
bl_pktmp.AssignPartDict = make(map[string]db.Pln_picktemplate_itemlst)
|
|
|
|
for j = 0; j < len(pktmptablst[i].Attrlst); j++ {
|
|
bl_pktmp.AssignAttrDict[pktmptablst[i].Attrlst[j].Attrcode] = pktmptablst[i].Attrlst[j]
|
|
}
|
|
|
|
for k = 0; k < len(pktmptablst[i].Itemlst); k++ {
|
|
bl_pktmp.AssignPartDict[pktmptablst[i].Itemlst[k].Partid] = pktmptablst[i].Itemlst[k]
|
|
}
|
|
|
|
pe.PickingTmpDict[bl_pktmp.TemplateId] = bl_pktmp
|
|
|
|
// 更新产线关联的拣料单模板
|
|
if bl_wl, ok = pe.WorklineDict[bl_pktmp.WorklineId]; ok {
|
|
bl_wl.PickTmpDict[bl_pktmp.TemplateId] = bl_pktmp
|
|
pe.WorklineDict[bl_wl.WorklineId] = bl_wl
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// PK_LoadMasterData: 加载拣料单服务的主数据
|
|
func (pe *PickingEngine) LoadMasterData() (err error) {
|
|
var (
|
|
projtab db.Me_project
|
|
projlsttab []db.Me_project
|
|
bl_proj BL_Project
|
|
i int
|
|
)
|
|
|
|
// 初始化
|
|
pe.PickingTmpDict = make(map[string]BL_PickingTemplate)
|
|
pe.WorklineDict = make(map[string]BL_Workline)
|
|
pe.Projectdict = make(map[string]BL_Project)
|
|
|
|
// 加载产线
|
|
pe.PlanMode = common.LINE_PLAN_IN_SEQ
|
|
if err = pe.LoadWorkLines(); err != nil {
|
|
return
|
|
}
|
|
fmt.Println("完成产线主数据加载!")
|
|
// 加载拣料单模板
|
|
if err = pe.LoadPickingTemplates(); err != nil {
|
|
return
|
|
}
|
|
fmt.Println("完成拣料单模板主数据加载!")
|
|
// 加载所有激活的项目主数据
|
|
projtab = db.Me_project{}
|
|
if projlsttab, err = projtab.GetAllActive(); err != nil {
|
|
return
|
|
}
|
|
for i = 0; i < len(projlsttab); i++ {
|
|
bl_proj = BL_Project{}
|
|
bl_proj.Projectid = projlsttab[i].Projectid
|
|
bl_proj.Projecttab = projlsttab[i]
|
|
if err = bl_proj.GetPartList(); err != nil {
|
|
return
|
|
}
|
|
if err = bl_proj.GetAttributeList(common.ATCOD_TYPE_PART); err != nil {
|
|
return
|
|
}
|
|
if err = bl_proj.GetPartFamilyList(); err != nil {
|
|
return
|
|
}
|
|
if err = bl_proj.GetSupplyGroupList(); err != nil {
|
|
return
|
|
}
|
|
pe.Projectdict[bl_proj.Projectid] = bl_proj
|
|
}
|
|
fmt.Println("完成项目主数据加载!")
|
|
return
|
|
}
|
|
|
|
// 基于拣料单模板查找开口的拣料单(未下达的),如果存在多个,则返回最早新建的
|
|
func (pe *PickingEngine) GetOpenPickOrderByTemplate(session *xorm.Session, bl_pko *BL_PickingOrder, wonr string, attrcode int, partid string) (exist bool, pickorderid string, err error) {
|
|
var (
|
|
i int
|
|
pkordtab db.Pln_pickorder
|
|
pkordtablst []db.Pln_pickorder
|
|
bl_pktmp BL_PickingTemplate
|
|
ok bool
|
|
)
|
|
|
|
exist = false
|
|
// 获取最新创建已计划未下达的包装单
|
|
pkordtab = db.Pln_pickorder{}
|
|
if exist, pkordtablst, err = pkordtab.GetOpenOrdersForTemplateBySession(session, bl_pko.TemplateId); err != nil {
|
|
return
|
|
}
|
|
// 遍历开口拣料单适配
|
|
for i = 0; i < len(pkordtablst); i++ {
|
|
bl_pko.OrderNr = pkordtablst[i].Pickorderid
|
|
bl_pko.PlanQty = pkordtablst[i].Planqty
|
|
bl_pko.Pickordertab = pkordtablst[i]
|
|
// 查找拣料单模板是否存在
|
|
if bl_pktmp, ok = pe.PickingTmpDict[bl_pko.TemplateId]; !ok {
|
|
err = errors.New("The specified picking template: " + bl_pko.TemplateId + " is not existing in the global mdata!")
|
|
return
|
|
}
|
|
// 获取当前拣料单的已填充信息
|
|
bl_pko.RefreshPickingStatus(&bl_pktmp)
|
|
if exist, err = bl_pko.IsFillable(wonr, attrcode, partid, &bl_pktmp); err != nil {
|
|
return
|
|
}
|
|
if exist {
|
|
pickorderid = pkordtablst[i].Pickorderid
|
|
break
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|