package tod
|
|
|
|
import (
|
|
"errors"
|
|
"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"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"time"
|
|
"xorm.io/core"
|
|
)
|
|
|
|
// TOD 缓存数据对象定义
|
|
type TodLandData struct {
|
|
Projnr string // 项目号
|
|
Edifile string // EDI 文件名
|
|
Bl_CoDict map[string]service.BL_CustOrder // 解析的客户订单对象
|
|
Covtablst []db.Pln_custorder_ver // 客户订单版本头
|
|
}
|
|
|
|
// 加载TOD文件并将文件中的客户订单数据解析到客户订单字典,key值是OemOrderNr
|
|
func (blt *TodLandData) ReadTodData(tod_file string) (err error) {
|
|
var (
|
|
tod TOD
|
|
seq SEQ
|
|
sg service.BL_SupplyGroup
|
|
lin LIN
|
|
bl_sgpt service.BL_SgPart
|
|
bl_co service.BL_CustOrder
|
|
edifile string
|
|
ok bool
|
|
)
|
|
|
|
// 读取并解析TOD文件
|
|
tod = TOD{}
|
|
if err = ParseTodEdi(tod_file, &tod); err != nil {
|
|
log.Printf("Failed to load tod file: %s due to: %v", tod_file, err)
|
|
return
|
|
}
|
|
|
|
// 获取TOD文件名
|
|
_, edifile = filepath.Split(tod_file)
|
|
|
|
// 初始化客户订单字典
|
|
blt.Bl_CoDict = make(map[string]service.BL_CustOrder)
|
|
|
|
// 遍历TOD文件将数据填充到订单字典中
|
|
for _, seq = range tod.SeqList {
|
|
if bl_co, ok = blt.Bl_CoDict[seq.Gir.CustOrderNr]; !ok {
|
|
// 客户订单不存在,初始化一个新的客户订单
|
|
bl_co = service.BL_CustOrder{}
|
|
bl_co.Oemordernr = seq.Gir.CustOrderNr
|
|
bl_co.Projnr = blt.Projnr
|
|
bl_co.Partfamilyid = seq.Gir.PartFamily
|
|
bl_co.SeqType = seq.SeqType
|
|
bl_co.Ordertime = tod.Dtm.MsgTime
|
|
bl_co.Swet = seq.Dtm.MsgTime
|
|
bl_co.Edifile = edifile
|
|
bl_co.Bl_sgdict = make(map[string]service.BL_SupplyGroup)
|
|
bl_co.Bl_ordattrdict = make(map[int]service.BL_OrdAttribute)
|
|
bl_co.Bl_verrdict = make(map[string]service.BL_VerifyError)
|
|
}
|
|
|
|
// 获取供应组下所有的零件信息
|
|
sg = service.BL_SupplyGroup{}
|
|
sg.Bl_sgpartDict = make(map[string]service.BL_SgPart)
|
|
sg.Partfamilyid = seq.Gir.PartFamily
|
|
sg.Supplygroupid = seq.Gir.SupplyGroup
|
|
for _, lin = range seq.LinList {
|
|
bl_sgpt = service.BL_SgPart{}
|
|
bl_sgpt.Partid = lin.PartNr + "-" + lin.Pia.Ai // 零件号
|
|
bl_sgpt.Ai = lin.Pia.Ai // 零件版本号
|
|
bl_sgpt.Qty = lin.Qty.Qty // 零件数量
|
|
bl_sgpt.Supplygroupid = sg.Supplygroupid
|
|
bl_sgpt.Originalsgid = sg.Supplygroupid
|
|
bl_sgpt.AtcodDict = make(map[int]service.BL_Attribute)
|
|
sg.Bl_sgpartDict[bl_sgpt.Partid] = bl_sgpt
|
|
}
|
|
bl_co.Bl_sgdict[sg.Supplygroupid] = sg
|
|
blt.Bl_CoDict[bl_co.Oemordernr] = bl_co
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 将TOD解析数据保存到数据库:客户订单版本和零件清单
|
|
func (blt *TodLandData) SaveTodData(mdata *service.TodProject) (err error) {
|
|
var (
|
|
cotab db.Pln_custorder
|
|
bl_co service.BL_CustOrder
|
|
exist bool
|
|
session *xorm.Session
|
|
)
|
|
|
|
for _, bl_co = range blt.Bl_CoDict {
|
|
//开启事务
|
|
session = db.G_DbEngine.NewSession()
|
|
|
|
if err = session.Begin(); err != nil {
|
|
session.Close()
|
|
return
|
|
}
|
|
|
|
// 查找OEM订单是否存在,不存在则创建
|
|
cotab = db.Pln_custorder{Oemordernr: bl_co.Oemordernr, Partfamilyid: bl_co.Partfamilyid, Projnr: blt.Projnr}
|
|
if exist, cotab, err = cotab.GetByOemOrderNrBySession(session); err != nil {
|
|
err = errors.New(fmt.Sprintf("Failed to get cust order for oemorder: %s due to: %v", bl_co.Oemordernr, err))
|
|
session.Rollback()
|
|
session.Close()
|
|
return
|
|
}
|
|
|
|
// 如果客户订单存在
|
|
if exist {
|
|
// 获取客户订单头信息并更新它的处理状态
|
|
cotab.Handlestatus = "RC"
|
|
cotab.Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss")
|
|
if _, err = session.ID(core.PK{db.G_FINR, cotab.Custordernr}).Cols("handlestatus", "lastmodif").Update(cotab); err != nil {
|
|
err = errors.New(fmt.Sprintf("Failed to update cust order: %s due to: %v", cotab.Custordernr, err))
|
|
session.Rollback()
|
|
session.Close()
|
|
return
|
|
}
|
|
bl_co.Custordernr = cotab.Custordernr
|
|
bl_co.Custordertab = cotab
|
|
} else {
|
|
if err = bl_co.CreateCOHead(session, mdata.Projecttab.Custorder_snr); err != nil {
|
|
err = errors.New(fmt.Sprintf("Failed to create cust order for oemorder: %s due to: %v", bl_co.Oemordernr, err))
|
|
session.Rollback()
|
|
session.Close()
|
|
return
|
|
}
|
|
}
|
|
|
|
// 保存客户订单版本信息
|
|
if err = bl_co.SaveCOHeadVersion(session); err != nil {
|
|
err = errors.New(fmt.Sprintf("Failed to save cust order: %s history version due to: %v", bl_co.Custordernr, err))
|
|
session.Rollback()
|
|
session.Close()
|
|
return
|
|
}
|
|
|
|
session.Commit()
|
|
session.Close()
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 测试TOD解析缓存并创建客户订单头
|
|
func ReadTodFileToLand() (err error) {
|
|
var (
|
|
projtab db.Me_project
|
|
projtablst []db.Me_project
|
|
todland TodLandData
|
|
todProj service.TodProject
|
|
rd []os.FileInfo
|
|
fi os.FileInfo
|
|
edi_file string
|
|
matched bool
|
|
)
|
|
|
|
projtab = db.Me_project{}
|
|
if projtablst, err = projtab.GetAllActive(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目失败,原因是: %v", err))
|
|
return
|
|
}
|
|
|
|
for i, _ := range projtablst {
|
|
todProj = service.TodProject{}
|
|
todProj.Projecttab = projtablst[i]
|
|
todProj.Projectid = projtablst[i].Projectid
|
|
fmt.Println("Ready to load data for project:", projtablst[i].Projectid)
|
|
if err = todProj.GetAttributeList(common.ATCOD_TYPE_PART); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的属性失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
if err = todProj.GetPartFamilyList(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的零件族失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
if err = todProj.GetSupplyGroupList(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的供应组失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
if err = todProj.GetPartList(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的零件清单失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
if err = todProj.GetCarModelList(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的Carmodel失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
if err = todProj.GetPartRuleList(); err != nil {
|
|
err = errors.New(fmt.Sprintf("加载项目:%s的共用件规则失败,原因是: %v", projtablst[i].Projectid, err))
|
|
return
|
|
}
|
|
fmt.Println("完成项目主数据加载!")
|
|
|
|
fmt.Println(projtablst[i].Projectid, " ==> Try to load file from folder:", projtablst[i].Tod_folder)
|
|
if rd, err = ioutil.ReadDir(projtablst[i].Tod_folder + "/inbox"); err != nil {
|
|
err = errors.New(fmt.Sprintf("读取TOD的Inbox文件夹失败,原因是: %v", err))
|
|
return
|
|
}
|
|
for _, fi = range rd {
|
|
if fi.IsDir() {
|
|
continue
|
|
}
|
|
edi_file = projtablst[i].Tod_folder + "/inbox" + "/" + fi.Name()
|
|
fmt.Println("Try to load tod file:", edi_file)
|
|
// 判断文件的合规性
|
|
if matched, err = regexp.MatchString(todProj.Projecttab.Tod_filename_regexp, fi.Name()); err != nil {
|
|
err = errors.New(fmt.Sprintf("TOD文件名: %s : 匹配规范错误: %v !", fi.Name(), err))
|
|
os.Rename(edi_file, todProj.Projecttab.Tod_folder+"/errbox"+"/"+fi.Name())
|
|
continue
|
|
}
|
|
if !matched {
|
|
err = errors.New(fmt.Sprintf("TOD文件名: %s 不符合规范: %s !", fi.Name(), todProj.Projecttab.Tod_filename_regexp))
|
|
os.Rename(edi_file, todProj.Projecttab.Tod_folder+"/errbox"+"/"+fi.Name())
|
|
continue
|
|
}
|
|
|
|
fmt.Println("Ready to read tod data......")
|
|
todland = TodLandData{}
|
|
todland.Projnr = projtablst[i].Projectid
|
|
todland.Edifile = edi_file
|
|
if err = todland.ReadTodData(edi_file); err != nil {
|
|
err = errors.New(fmt.Sprintf("TOD文件: %s : 解析错误: %v !", fi.Name(), err))
|
|
os.Rename(edi_file, todProj.Projecttab.Tod_folder+"/errbox"+"/"+fi.Name())
|
|
continue
|
|
}
|
|
|
|
if err = todland.SaveTodData(&todProj); err != nil {
|
|
err = errors.New(fmt.Sprintf("TOD文件: %s : 保存错误: %v !", fi.Name(), err))
|
|
os.Rename(edi_file, todProj.Projecttab.Tod_folder+"/errbox"+"/"+fi.Name())
|
|
continue
|
|
}
|
|
|
|
// 将TOD文件移到已处理文件夹 outbox
|
|
os.Rename(edi_file, todProj.Projecttab.Tod_folder+"/outbox"+"/"+fi.Name())
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|