package calloff import ( "fmt" "github.com/go-xorm/xorm" "io/ioutil" "leit.com/leit_seat_aps/common" "leit.com/leit_seat_aps/db" "leit.com/leit_seat_aps/service" "os" "regexp" "testing" "time" ) // 测试Calloff文件解析和保存 func TestParseCalloffNew(t *testing.T) { var ( connstring string err error projtab db.Me_project projtablst []db.Me_project cfland CalloffLandData cfProj service.CalloffProject rd []os.FileInfo fi os.FileInfo edi_file string matched bool ) // 连接数据库 connstring = fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable", `localhost`, "lapp", "123fis", "SJA_APS", 1433) if err = db.InitMssqlDb(connstring); err != nil { t.Errorf("Failed to connect db due to: %v", err) return } defer db.G_DbEngine.Close() projtab = db.Me_project{} if projtablst, err = projtab.GetAllActive(); err != nil { t.Errorf("Failed to get project list!") return } for i, _ := range projtablst { cfProj = service.CalloffProject{} cfProj.Projecttab = projtablst[i] cfProj.Projectid = projtablst[i].Projectid fmt.Println("Ready to load data for project:", projtablst[i].Projectid) // 读取文件夹内的文件并解析 if rd, err = ioutil.ReadDir(cfProj.Projecttab.Calloff_folder + "/inbox"); err != nil { return } for _, fi = range rd { if fi.IsDir() { continue } edi_file = cfProj.Projecttab.Calloff_folder + "/inbox" + "/" + fi.Name() // 判断文件的合规性 if matched, err = regexp.MatchString(cfProj.Projecttab.Calloff_filename_regexp, fi.Name()); err != nil { t.Errorf("Failed to match EDI file name: %s due to: %v", fi.Name(), err) return } if !matched { t.Errorf("The specified EDI file: %s doesn't match the required name specification!", fi.Name()) os.Rename(edi_file, cfProj.Projecttab.Calloff_folder+"/errbox"+"/"+fi.Name()) return } // 解析CALLOFF文件到字典 fmt.Println("Ready to read tod data......") cfland = CalloffLandData{} cfland.Projnr = projtablst[i].Projectid cfland.Edifile = edi_file if err = cfland.ReadCalloffData(edi_file); err != nil { t.Errorf("Failed to parse Calloff file due to: %v", err) os.Rename(edi_file, cfProj.Projecttab.Calloff_folder+"/errbox"+"/"+fi.Name()) return } // 保存CALLOFF字典到临时缓存表 if err = cfland.SaveCalloffData(); err != nil { //t.Errorf("Failed to save Calloff parse result due to: %v", err) os.Rename(edi_file, cfProj.Projecttab.Calloff_folder+"/errbox"+"/"+fi.Name()) continue } // 将文件移到outbox os.Rename(edi_file, cfProj.Projecttab.Calloff_folder+"/outbox"+"/"+fi.Name()) } } } // 测试读取Calloff信息并生成发运包装 func TestParseCalloffOrder(t *testing.T) { var ( connstring string err error i, j, k, prevCS, m, n int projtab db.Me_project projtablst []db.Me_project cfProj service.CalloffProject cflandtab db.Pln_calloffdata_landing cflandtablst []db.Pln_calloffdata_landing cflandtablst2 []db.Pln_calloffdata_landing cftab db.Pln_calloffdata_landing cftablst []db.Pln_calloffdata_landing bl_co service.BL_CustOrder bl_prevco service.BL_CustOrder wotab db.Pln_workorder sgtab db.Me_supplygroup exist, ok, audit,relstat,stop bool prevOemord string sgdict map[string]string bl_pakordlst []service.BL_PackOrder bl_pakord service.BL_PackOrder cferror db.Pln_calloff_errorlst errorlst []db.Pln_calloff_errorlst session *xorm.Session ) // 连接数据库 connstring = fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable", `localhost`, "lapp", "123fis", "SJA_APS", 1433) if err = db.InitMssqlDb(connstring); err != nil { t.Errorf("Failed to connect db due to: %v", err) return } defer db.G_DbEngine.Close() projtab = db.Me_project{} if projtablst, err = projtab.GetAllActive(); err != nil { t.Errorf("Failed to get project list!") return } for i, _ = range projtablst { cfProj = service.CalloffProject{} cfProj.Projecttab = projtablst[i] cfProj.Projectid = projtablst[i].Projectid fmt.Println("Ready to load data for project:", projtablst[i].Projectid) // 加载项目主数据 if err = cfProj.LoadMasterData(); err != nil { t.Errorf("Failed to load project master data due to: %v!", err) return } // 循环读取未处理的Calloff消息,按零件族和CheckSequence排序 cflandtab = db.Pln_calloffdata_landing{Projnr: cfProj.Projectid} if cflandtablst, err = cflandtab.GetUnparsedLandingData(); err != nil { t.Errorf("Failed to get unparsed calloff landding data due to: %v!", err) return } // 遍历未处理的Calloff消息 for j = 0; j < len(cflandtablst); j++ { // 读取项目各零件族解析的最大CheckSequence号 if err = cfProj.LoadPartFamilyMaxParsedCheckSequence(); err != nil { t.Errorf("Failed to load project max check sequence data for each partfamily due to: %v!", err) return } errorlst = []db.Pln_calloff_errorlst{} // 验证Calloff有效性 // 1. 基于零件族判断CheckSequence是否连续 if projtablst[i].Calloff_verify_checksequence > 0 { if prevCS, ok = cfProj.Pfcsdict[cflandtablst[j].Partfamilyid]; !ok { t.Errorf("Calloff landing data's partfamily %s is not existing in the global dict!", cflandtablst[j].Partfamilyid) return } // 检查checksequence是否连续,如果不连续查询两者之间是否有报错的解析记录,如果没有报错,如果有继续不处理 if prevCS > 0 && prevCS+1 != cflandtablst[j].Checksequence { if exist, err = cflandtablst[j].AnyErrorRecordBetweenCheckSequence( cfProj.Projectid,cflandtablst[j].Partfamilyid,prevCS,cflandtablst[j].Checksequence ); err != nil{ t.Errorf("Failed to query calloff record!") return } if exist { continue }else{ cferror = db.Pln_calloff_errorlst{} cferror.Finr = db.G_FINR cferror.Calloffnr = cflandtablst[j].Calloffnr cferror.Errortype = common.CALLOFF_CHECK_SEQUENCE cferror.Consumeplant = cflandtablst[j].Consumeplant cferror.Partfamilyid = cflandtablst[j].Partfamilyid cferror.Oemordernr = cflandtablst[j].Oemordernr cferror.Errorstatus = "O" cferror.Errorinfo = "CheckSequence不连续:" + common.ValueToString(prevCS, "") + ";" + common.ValueToString(cflandtablst[j].Checksequence, "") cferror.Lastmodif = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") cferror.Credatuz = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") errorlst = append(errorlst, cferror) // CheckSequence 不连续,报错 fmt.Println("CheckSequence不连续:", prevCS, "==>", cflandtablst[j].Checksequence) } } } // 2. 判断客户订单是否存在 bl_co = service.BL_CustOrder{Projnr: cflandtablst[j].Projnr, Oemordernr: cflandtablst[j].Oemordernr, Partfamilyid: cflandtablst[j].Partfamilyid} if exist, err = bl_co.GetCalloffOemorder(); err != nil { t.Errorf("Failed to get custorder for oemorder %s due to: %v ", cflandtablst[j].Oemordernr, err) return } if !exist { cferror = db.Pln_calloff_errorlst{} cferror.Finr = db.G_FINR cferror.Calloffnr = cflandtablst[j].Calloffnr cferror.Errortype = common.CALLOFF_ORDER_NOTEXIST cferror.Consumeplant = cflandtablst[j].Consumeplant cferror.Partfamilyid = cflandtablst[j].Partfamilyid cferror.Oemordernr = cflandtablst[j].Oemordernr cferror.Errorstatus = "O" cferror.Errorinfo = "Calloff的客户订单不存在:Partfamilyid:" + cflandtablst[j].Partfamilyid + ";Oemordernr:" + cflandtablst[j].Oemordernr cferror.Lastmodif = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") cferror.Credatuz = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") errorlst = append(errorlst, cferror) t.Errorf("Calloff的客户订单%s - %s不存在 :", cflandtablst[j].Oemordernr, cflandtablst[j].Partfamilyid) } // 获取前面一个CheckSequence及其对应的客户订单号 prevCS, _ = cfProj.Pfcsdict[cflandtablst[j].Partfamilyid] prevOemord = "" fmt.Println(cflandtablst[j].Checksequence,"的前序:",prevCS) if prevCS > 0 { cflandtab = db.Pln_calloffdata_landing{Projnr: cfProj.Projectid, Checksequence: prevCS, Partfamilyid: cflandtablst[j].Partfamilyid} if cflandtablst2, err = cflandtab.GetByProjectCheckSequencePartfamily(); len(cflandtablst2) > 0 { prevOemord = cflandtablst2[0].Oemordernr fmt.Println("前序客户订单:",prevOemord) // 获取前序客户订单对应的calloff记录 cftab = db.Pln_calloffdata_landing{Projnr: cfProj.Projectid, Oemordernr: prevOemord} // 获取前序calloff的所有记录 if cftablst, err = cftab.GetByProjectOemorder(); err != nil{ t.Errorf("查询项目%s 客户订单%s 的calloff记录失败: %v!", cftab.Projnr, cftab.Oemordernr, err) return } // 获取前序客户订单 bl_prevco = service.BL_CustOrder{Projnr: cfProj.Projectid, Oemordernr: cflandtablst2[0].Oemordernr, Partfamilyid: cflandtablst2[0].Partfamilyid} if exist, err = bl_prevco.GetCalloffOemorder(); err != nil { t.Errorf("Failed to get custorder for oemorder %s due to: %v ", cflandtablst2[0].Oemordernr, err) return } // 校验客户订单的零件族是否齐全 sgdict = make(map[string]string) if sgdict, err = bl_prevco.GetOemorderModelSpecPfdict(); err!= nil{ t.Errorf("查询项目%s 客户订单%s 的车型规格字典记录失败: %v!", bl_prevco.Custordertab.Projnr, bl_prevco.Custordertab.Custordernr, err) return } if len(sgdict) != len(cftablst){ // 整车副缺零件族 fmt.Println("客户订单",prevOemord,"的calloff不齐全无法校验!") continue } // 校验是否解析有错误 if len(cftablst) > 0 { fmt.Println("遍历前序订单的calloff记录") // 校验前车付的calloff是否有错 stop = false for k = 0; k < len(cftablst); k++ { fmt.Println(k,"-->",cftablst[k]) if cftablst[k].Parsed == 0 || cftablst[k].Handlestatus != common.CO_PARSE_STATUS_OK { stop = true break } } if stop{ fmt.Println("前序未完成处理,跳过!") continue } } } } // 3. 判断客户订单状态是否满足 if projtablst[i].Calloff_verify_orderstatus > 0 && bl_co.Custordertab.Status < common.CO_STATUS_PLANNED { cferror = db.Pln_calloff_errorlst{} cferror.Finr = db.G_FINR cferror.Calloffnr = cflandtablst[j].Calloffnr cferror.Errortype = common.CALLOFF_ORDER_NOTSTATUS cferror.Consumeplant = cflandtablst[j].Consumeplant cferror.Partfamilyid = cflandtablst[j].Partfamilyid cferror.Oemordernr = cflandtablst[j].Oemordernr cferror.Errorstatus = "O" cferror.Errorinfo = "calloff的客户订单状态不满足:Partfamilyid:" + cflandtablst[j].Partfamilyid + ";Oemordernr:" + cflandtablst[j].Oemordernr cferror.Lastmodif = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") cferror.Credatuz = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") errorlst = append(errorlst, cferror) } // 4. 判断客户订单规格是否已审核 if projtablst[i].Calloff_verify_orderspec > 0 { if audit, err = bl_co.IsCarmodelSpecAudited(); err !=nil { t.Errorf("Failed to inert error list due to : %v", err) return } else{ if !audit { cferror = db.Pln_calloff_errorlst{} cferror.Finr = db.G_FINR cferror.Calloffnr = cflandtablst[j].Calloffnr cferror.Errortype = common.CALLOFF_ORDER_NOTSPEC cferror.Consumeplant = cflandtablst[j].Consumeplant cferror.Partfamilyid = cflandtablst[j].Partfamilyid cferror.Oemordernr = cflandtablst[j].Oemordernr cferror.Errorstatus = "O" cferror.Errorinfo = "calloff的客户订单的规格型号未审核:" + cflandtablst[j].Partfamilyid + ";Oemordernr:" + cflandtablst[j].Oemordernr cferror.Lastmodif = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") cferror.Credatuz = common.TimeFormat(time.Now(), "yyyyMMddHHmmss") errorlst = append(errorlst, cferror) } } } // 如果有错,则停下不解析 if len(errorlst) > 0 { session = db.G_DbEngine.NewSession() defer session.Close() if err = session.Begin(); err != nil { return } //保存错误 if err = cferror.InsertList(session, errorlst); err != nil { t.Errorf("Failed to inert error list due to : %v", err) return } cflandtablst[j].Parsed = common.EDI_PARSE_YES cflandtablst[j].Handlestatus = common.CO_PARSE_STATUS_ERROR cflandtablst[j].Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss") if err = cflandtablst[j].UpdateFields(session, "parsed,handlestatus, lastmodif"); err != nil { t.Errorf("Failed to update calloffdata_landing due to : %v", err) session.Rollback() return } session.Commit() continue } // Hardcode: 对于G38项目的PF2的CALLOFF需要等同一客户订单的PF1的CALL进来后才解析 if cflandtablst[j].Projnr == "G38" && cflandtablst[j].Partfamilyid == "SITKD2" { // 获取同项目OEMORDER的Calloff判断解析状态 if exist, err = cflandtab.ExistUnParsedCfByProjectOemorderPf(cfProj.Projectid,cflandtablst[j].Oemordernr,"SITKD1"); err != nil{ t.Errorf("获取项目%s 客户订单%s 零件族%s 的calloff记录失败 : %v", cfProj.Projectid,cflandtablst[j].Oemordernr,cflandtablst[j].Partfamilyid, err) return } if exist{ continue } } // 遍历客户订单的生产订单列表,将生产订单加入包装 fmt.Println("======================== 遍历客户订单:",bl_co.Custordernr, common.ValueToInt(bl_co.Custordertab.Oemseq, 0)) for k = 0; k < len(bl_co.Custordertab.Wotablst); k++ { wotab = bl_co.Custordertab.Wotablst[k] if wotab.Shippable == 0 || wotab.Packstatus == common.WO_STATUS_PACKED { continue } fmt.Println(" === 遍历其生产订单:",wotab.Workordernr, "==>",wotab.Supplygroupid) // 获取供应组 if sgtab,ok = cfProj.Sgdict[wotab.Supplygroupid]; !ok { t.Errorf("生产订单 %s 的供应组:%s 不存在!", wotab.Workordernr, wotab.Supplygroupid) session.Rollback() return } // 头枕走特殊逻辑 if sgtab.Sgtype == common.SG_TYPE_CHILD { } // 初始化 bl_pakord = service.BL_PackOrder{} session = db.G_DbEngine.NewSession() defer session.Close() if err = session.Begin(); err != nil { return } // 基于checksequence和工单的供应组ID查找包装单 if exist, bl_pakord, err = cfProj.GetPackOrderByCheckSequenceSupplyGroup(session, cflandtablst[j].Checksequence, wotab.Supplygroupid); err != nil{ t.Errorf("无法获取checksequence %d 的包装订单,原因是:%v", cflandtablst[j].Checksequence, err) session.Rollback() return } if exist{ fmt.Println("基于CheckSeq获取到包装单:",bl_pakord.PackorderId) } // 基于OEMSEQ和工单的供应组ID查找包装单 if !exist { if exist, bl_pakord, err = cfProj.GetPackOrderByOemseqSupplyGroup(session, wotab); err != nil{ t.Errorf("无法获取工单 %s 的包装订单,原因是:%v", wotab.Workordernr, err) session.Rollback() return } } // 不存在则新建包装单 if !exist { if bl_pakordlst, err = cfProj.CreatePackOrderByCheckSeqWO(session, cflandtablst[j], wotab); err != nil { fmt.Println("创建开口包装单失败,原因:", err) session.Rollback() continue } // 获取当前OEMSEQ 或 checksequence的包装单 ok = false for m = 0; m < len(bl_pakordlst); m++ { for n = 0; n < len(bl_pakordlst[m].Pkotab.Itemlst); n++ { if (bl_pakordlst[m].Pkotab.Itemlst[n].Supplygroupid == wotab.Supplygroupid) && ( bl_pakordlst[m].Pkotab.Itemlst[n].Oemseq == common.ValueToInt(wotab.Oemseq, 0) || bl_pakordlst[m].Pkotab.Itemlst[n].Seq == cflandtablst[j].Checksequence ) { ok = true bl_pakord = bl_pakordlst[m] break } } if ok { break } } if !ok { fmt.Println("无法为当前工单找到包装单!") continue } } // 将工单加入到当前包装单 if ok, err = cfProj.AddWOToPackOrder(wotab, cflandtablst[j].Checksequence, &bl_pakord, session); err != nil{ t.Errorf("添加工单 %s 到包装单 %s 出错,原因是 %v", wotab.Workordernr,bl_pakord.PackorderId, err) session.Rollback() return } /**bl_pakord.RefreshFillStatus() fmt.Println("OEMSEQ count = ",bl_pakord.OemseqCount," CheckSeq count = ",bl_pakord.SeqCount) for n = 0; n < len(bl_pakord.Pkotab.Itemlst); n++ { fmt.Println(n,"-",bl_pakord.Pkotab.Itemlst[n].Oemseq,"--",bl_pakord.Pkotab.Itemlst[n].Seq) }**/ if ok { fmt.Println("成功添加工单",wotab.Workordernr,"到包装单",bl_pakord.PackorderId) // 关闭当前包装 if relstat, err = cfProj.ReleasePackOrder(session, bl_pakord); err != nil{ t.Errorf("下达包装单 %s 出错,原因是 %v", bl_pakord.PackorderId, err) session.Rollback() return } if relstat{ fmt.Println("成功下达包装单",bl_pakord.PackorderId) } } session.Commit() } session = db.G_DbEngine.NewSession() defer session.Close() if err = session.Begin(); err != nil { return } // 更新客户订单Call off相关信息 bl_co.Custordertab.Calloffnr = cflandtablst[j].Calloffnr bl_co.Custordertab.Calloffswet = cflandtablst[j].Swet bl_co.Custordertab.Checksequence = cflandtablst[j].Checksequence bl_co.Custordertab.Consumecompany = cflandtablst[j].Consumecompany bl_co.Custordertab.Consumeplant = cflandtablst[j].Consumeplant bl_co.Custordertab.Consigneecompany = cflandtablst[j].Consigneecompany bl_co.Custordertab.Consigneeplant = cflandtablst[j].Consigneeplant bl_co.Custordertab.Vehicleidset = cflandtablst[j].Vehicleidset bl_co.Custordertab.Vehicleid = cflandtablst[j].Vehicleid bl_co.Custordertab.Unloadingplace = cflandtablst[j].Unloadingplace bl_co.Custordertab.Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss") if err = bl_co.Custordertab.UpdateFields(session, "calloffnr, calloffswet, checksequence, consumecompany, consumeplant, consigneecompany, consigneeplant, vehicleidset, vehicleid, unloadingplace, lastmodif"); err != nil { t.Errorf("Failed to update custordertab due to %v", err) session.Rollback() return } // calloff 客户订单成功,将landdata置位 cflandtablst[j].Handlestatus = common.CO_PARSE_STATUS_OK cflandtablst[j].Parsed = common.EDI_PARSE_YES cflandtablst[j].Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss") if err = cflandtablst[j].UpdateFields(session, "parsed,handlestatus, lastmodif"); err != nil { t.Errorf("Failed to update parse status due to %v", err) session.Rollback() return } session.Commit() } } } // 将26下达的包装单加载到发运车中,系统根据实际加载情况 func TestGenerateDeliveryCar(t *testing.T) { var ( connstring string err error i, j, idx int projtab db.Me_project projtablst []db.Me_project pkotab db.Jit_packorder pkotablst []db.Jit_packorder cfProj service.CalloffProject bl_sco service.BL_ShipcarOrder bl_scolst []service.BL_ShipcarOrder fillable, canfix, canrelease bool shiptplid string session *xorm.Session ) // 连接数据库 connstring = fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable", `localhost`, "lapp", "123fis", "SJA_APS", 1433) if err = db.InitMssqlDb(connstring); err != nil { t.Errorf("Failed to connect db due to: %v", err) return } defer db.G_DbEngine.Close() projtab = db.Me_project{} if projtablst, err = projtab.GetAllActive(); err != nil { t.Errorf("Failed to get project list!") return } for i, _ = range projtablst { cfProj = service.CalloffProject{} cfProj.Projecttab = projtablst[i] cfProj.Projectid = projtablst[i].Projectid fmt.Println("Ready to load data for project:", projtablst[i].Projectid) // 读取项目的包装类型主数据 if err = cfProj.LoadPackageType(); err != nil { t.Errorf("Failed to load project package type data due to: %v!", err) return } // 读取项目的发运车模板主数据 if err = cfProj.LoadShipCarTemplate(); err != nil { t.Errorf("Failed to load project ship car data due to: %v!", err) return } // 循环读取状态>=26已下达且未装车的包装单 pkotab = db.Jit_packorder{} if pkotablst, err = pkotab.GetUnloadedPackOrders(cfProj.Projectid); err != nil { t.Errorf("Failed to load project unloaded pack orders due to: %v!", err) return } // 遍历包装单 for j = 0; j < len(pkotablst); j++ { // 判断状态 if pkotablst[j].Status < common.PKO_STATUS_PLANNED || pkotablst[j].Loadstatus == common.PKO_STATUS_LOADED { continue } // 获取开口发运车订单并添加到发运车中 if bl_scolst, err = cfProj.GetOpenShipCarOrder(); err != nil { t.Errorf("Failed to get open car orders due to: %v!", err) return } session = db.G_DbEngine.NewSession() defer session.Close() if err = session.Begin(); err != nil { return } // 匹配所有可用模板计算各包装项最大装载量并与已填充量比较,确认是否可以继续填充 => 有可用发运车 if len(bl_scolst) > 0 { fillable, idx = cfProj.CheckOpenCarOrdersForPackOrder(bl_scolst, pkotablst[j]) } bl_sco = service.BL_ShipcarOrder{} // 如果有适配的开口发运车 if len(bl_scolst) > 0 && fillable { bl_sco.Shiporderid = bl_scolst[idx].Shiporderid if err = bl_sco.AddPackOrder(session, pkotablst[j]); err != nil { t.Errorf("Failed to add packorder %s into shipcar order %s due to: %v!", pkotablst[j].Packorderid, bl_scolst[idx].Shiporderid, err) session.Rollback() session.Close() return } } else { // 如果没有开口发运车,则创建发运车并添加 if bl_sco, err = cfProj.CreateShipCarOrder(session); err != nil { t.Errorf("Failed to create shipcar order due to: %v!", err) session.Rollback() session.Close() return } if err = bl_sco.AddPackOrder(session, pkotablst[j]); err != nil { t.Errorf("Failed to add packorder %s into shipcar order %s due to: %v!", pkotablst[j].Packorderid, bl_sco.Shiporderid, err) session.Rollback() session.Close() return } } // 获取发运车最新的数据 if err = bl_sco.GetOrderDataBySession(session); err != nil { t.Errorf("Failed to get ship order %s data!", bl_sco.Shiporderid) session.Rollback() session.Close() return } // 检查发运车是否可以指定模板,状态从10 -> 20 if bl_sco.Spordtab.Status < common.SPO_STATUS_PLANNED { cfProj.InitShipOrderWorkoload(&bl_sco) cfProj.RecalShipItemWorkloadMaxQty(&bl_sco) if canfix, shiptplid, err = cfProj.IsShipcarOrderFixTemplate(&bl_sco); err != nil { t.Errorf("Failed to check shiporder fixable due to %v!", err) session.Rollback() session.Close() return } if canfix { // 释放发运车并更新匹配的模板 if err = cfProj.FixShipCarOrderTemplate(session, &bl_sco, shiptplid); err != nil { t.Errorf("Failed to release ship car order!") session.Rollback() session.Close() return } } } // 检查发运车是否达到上限可关闭,状态从20 -> 26 if canrelease, err = cfProj.IsShipcarOrderReleasable(&bl_sco); err != nil { t.Errorf("Failed to check shiporder releasable due to %v!", err) session.Rollback() session.Close() return } if canrelease { // 释放发运车并更新匹配的模板 if err = cfProj.ReleaseShipCarOrder(session, &bl_sco); err != nil { t.Errorf("Failed to release ship car order!") session.Rollback() session.Close() return } } session.Commit() session.Close() } } }