SJA APS后端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
9.0 KiB

  1. package seq
  2. import (
  3. "fmt"
  4. "github.com/go-xorm/xorm"
  5. "io/ioutil"
  6. "leit.com/leit_seat_aps/common"
  7. "leit.com/leit_seat_aps/db"
  8. "leit.com/leit_seat_aps/service"
  9. "os"
  10. "regexp"
  11. "testing"
  12. "time"
  13. )
  14. // 测试SEQ文件解析和保存
  15. func TestParseSeqNew(t *testing.T) {
  16. var (
  17. connstring string
  18. err error
  19. projtab db.Me_project
  20. projtablst []db.Me_project
  21. seqland SeqLandData
  22. seqProj service.SeqProject
  23. rd []os.FileInfo
  24. fi os.FileInfo
  25. edi_file string
  26. matched bool
  27. )
  28. // 连接数据库
  29. connstring = fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable",
  30. `localhost`, "lapp", "123fis", "SJA_APS", 1433)
  31. if err = db.InitMssqlDb(connstring); err != nil {
  32. t.Errorf("Failed to connect db due to: %v", err)
  33. return
  34. }
  35. defer db.G_DbEngine.Close()
  36. projtab = db.Me_project{}
  37. if projtablst, err = projtab.GetAllActive(); err != nil {
  38. t.Errorf("Failed to get project list!")
  39. return
  40. }
  41. for i, _ := range projtablst {
  42. seqProj = service.SeqProject{}
  43. seqProj.Projecttab = projtablst[i]
  44. seqProj.Projectid = projtablst[i].Projectid
  45. fmt.Println("Ready to load data for project:", projtablst[i].Projectid)
  46. // 读取文件夹内的文件并解析
  47. if rd, err = ioutil.ReadDir(seqProj.Projecttab.Seq_folder + "/inbox"); err != nil {
  48. return
  49. }
  50. for _, fi = range rd {
  51. if fi.IsDir() {
  52. continue
  53. }
  54. edi_file = seqProj.Projecttab.Seq_folder + "/inbox" + "/" + fi.Name()
  55. // 判断文件的合规性
  56. if matched, err = regexp.MatchString(seqProj.Projecttab.Seq_filename_regexp, fi.Name()); err != nil {
  57. t.Errorf("Failed to match EDI file name: %s due to: %v", fi.Name(), err)
  58. return
  59. }
  60. if !matched {
  61. t.Errorf("The specified EDI file: %s doesn't match the required name specification!", fi.Name())
  62. os.Rename(edi_file, seqProj.Projecttab.Seq_folder+"/errbox"+"/"+fi.Name())
  63. return
  64. }
  65. // 解析SEQ文件到字典
  66. fmt.Println("Ready to read tod data......")
  67. seqland = SeqLandData{}
  68. seqland.Projnr = projtablst[i].Projectid
  69. seqland.Edifile = edi_file
  70. if err = seqland.ReadSeqData(edi_file); err != nil {
  71. t.Errorf("Failed to parse SEQ file due to: %v", err)
  72. os.Rename(edi_file, seqProj.Projecttab.Seq_folder+"/errbox"+"/"+fi.Name())
  73. return
  74. }
  75. // 保存SEQ字典到SEQ的临时缓存表
  76. if err = seqland.SaveSeqData(); err != nil {
  77. t.Errorf("Failed to save SEQ parse result due to: %v", err)
  78. return
  79. }
  80. // 将文件移到outbox
  81. os.Rename(edi_file, seqProj.Projecttab.Seq_folder+"/outbox"+"/"+fi.Name())
  82. }
  83. }
  84. }
  85. // 解析并读取SEQ
  86. func TestParseSeqOrder(t *testing.T) {
  87. var (
  88. connstring string
  89. err error
  90. i, j,prevseq int
  91. projtab db.Me_project
  92. projtablst []db.Me_project
  93. seqProj service.SeqProject
  94. seqlandtab db.Pln_seqdata_landing
  95. seqlandtablst []db.Pln_seqdata_landing
  96. cotab db.Pln_custorder
  97. bl_co service.BL_CustOrder
  98. bl_ordmsg service.BL_Ordmsg
  99. ok, exist bool
  100. session *xorm.Session
  101. )
  102. // 连接数据库
  103. connstring = fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;port=%d;encrypt=disable",
  104. `localhost`, "lapp", "123fis", "SJA_APS", 1433)
  105. if err = db.InitMssqlDb(connstring); err != nil {
  106. t.Errorf("Failed to connect db due to: %v", err)
  107. return
  108. }
  109. defer db.G_DbEngine.Close()
  110. projtab = db.Me_project{}
  111. if projtablst, err = projtab.GetAllActive(); err != nil {
  112. t.Errorf("Failed to get project list!")
  113. return
  114. }
  115. for i, _ = range projtablst {
  116. seqProj = service.SeqProject{}
  117. seqProj.Projecttab = projtablst[i]
  118. seqProj.Projectid = projtablst[i].Projectid
  119. fmt.Println("Ready to load data for project:", projtablst[i].Projectid)
  120. // 加载项目的二级物料主数据
  121. if err = seqProj.LoadMaterialData(); err != nil {
  122. t.Errorf("Failed to Load material data due to: %v", err)
  123. return
  124. }
  125. // 加载BOM主数据
  126. if err = seqProj.LoadBomData(); err != nil {
  127. t.Errorf("Failed to load bom data due to: %v", err)
  128. return
  129. }
  130. // 读取SEQ解析用主数据
  131. seqlandtab = db.Pln_seqdata_landing{Projnr: seqProj.Projectid}
  132. if seqlandtablst, err = seqlandtab.GetUnparsedLandingData(); err != nil {
  133. t.Errorf("Failed to GetUnparsedLandingData due to: %v", err)
  134. return
  135. }
  136. // 读取SEQ的LandingData
  137. for j, _ = range seqlandtablst {
  138. // 初始化客户订单对象并获取客户订单头,如果不存在则返回
  139. cotab = db.Pln_custorder{Projnr: seqlandtablst[j].Projnr, Oemordernr: seqlandtablst[j].Oemordernr, Partfamilyid: seqlandtablst[j].Partfamilyid}
  140. if exist, cotab, err = cotab.GetByOemOrderNr(); err != nil {
  141. t.Errorf("Failed to get custorder for oemorder %s due to: %v", seqlandtablst[j].Oemordernr, err)
  142. return
  143. }
  144. if exist {
  145. bl_co = service.BL_CustOrder{}
  146. bl_co.Custordertab = cotab
  147. bl_co.Custordernr = cotab.Custordernr
  148. bl_co.Partfamilyid = cotab.Partfamilyid
  149. bl_co.Projnr = cotab.Projnr
  150. bl_co.SeqType = seqlandtablst[j].Seqmode
  151. bl_co.Oemordernr = seqlandtablst[j].Oemordernr
  152. } else {
  153. fmt.Println(fmt.Sprintf("客户订单%s不存在!",seqlandtablst[j].Oemordernr))
  154. continue
  155. }
  156. // 获取客户订单完整数据(客户订单头、解析的零件和属性、生产订单列表)
  157. if err = bl_co.GetFullData(); err != nil {
  158. t.Errorf("Failed to get full data for custorder %s due to: %v", bl_co.Custordernr, err)
  159. return
  160. }
  161. // 验证客户订单状态是否满足更新条件
  162. if bl_co.Custordertab.Handlestatus != common.CO_PARSE_STATUS_OK {
  163. continue
  164. }
  165. // 判断订单状态,如果是>=26,则跳出循环
  166. if bl_co.Custordertab.Status >= common.CO_STATUS_RELEASED {
  167. // 客户订单状态不允许更新,设置解析状态为9
  168. seqlandtablst[j].Parsed = common.EDI_PARSE_ERROR
  169. seqlandtablst[j].Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss")
  170. fields := []string{"parsed", "lastmodif"}
  171. if err = seqlandtablst[j].UpdateFieldsWithoutSession(fields); err != nil {
  172. return
  173. }
  174. continue
  175. }
  176. // 校验客户订单的OEMSEQ是否连续(基于零件族获取最大的已计划的客户订单的SEQ)
  177. if bl_co.Custordertab.Orderinfo != "TCAR" && seqlandtablst[j].Oemseq < 9999999999 && seqProj.Projecttab.Seq_verify_sequence > 0 && seqProj.IsPartFamilyNeedToContinue(bl_co.Custordertab.Partfamilyid) {
  178. // 读取项目各零件族最大的OEMSEQ号
  179. if err = seqProj.GetPartFamilyMaxOemseq(); err != nil {
  180. t.Errorf("加载项目零件族最大OEMSEQ号失败: %v", err)
  181. return
  182. }
  183. if prevseq, ok = seqProj.Pfseqdict[bl_co.Custordertab.Partfamilyid]; !ok {
  184. t.Errorf("获取零件族%s 最大OEMSEQ失败: %v", bl_co.Custordertab.Partfamilyid, err)
  185. return
  186. }
  187. if prevseq > 0 && ( prevseq +1 != common.ValueToInt(seqlandtablst[j].Oemseq, 0)) {
  188. fmt.Println(fmt.Sprintf("当前零件族%s的最大OEMSEQ%d,与SEQ订单%s的排序%d不连续!",bl_co.Custordertab.Partfamilyid,
  189. prevseq,seqlandtablst[j].Oemordernr,common.ValueToInt(seqlandtablst[j].Oemseq,0) ))
  190. continue
  191. }
  192. }
  193. // 更新客户订单的SEQ信息和状态(设置Preschedseq)
  194. session = db.G_DbEngine.NewSession()
  195. defer session.Close()
  196. if err = session.Begin(); err != nil {
  197. return
  198. }
  199. // 基于SEQ保存客户订单版本信息(用于追溯)
  200. if err = bl_co.SaveSeqCOV(seqlandtablst[j]); err != nil {
  201. t.Errorf("Failed to insert SEQ cov data for custorder %s due to: %v", bl_co.Custordernr, err)
  202. session.Rollback()
  203. session.Close()
  204. return
  205. }
  206. // 将SEQ信息更新到对应的客户订单和生产订单
  207. if err = bl_co.UpdateSEQData(seqlandtablst[j]); err != nil {
  208. t.Errorf("Failed to update SEQ data for custorder %s due to: %v", bl_co.Custordernr, err)
  209. session.Rollback()
  210. session.Close()
  211. return
  212. }
  213. // 创建OEM订单消息用于Carmodel的解析
  214. bl_ordmsg = service.BL_Ordmsg{MsgType: common.MSG_TYPE_CARMODEL, MsgEvent: common.MSG_EVENT_NEW, MsgObjid: bl_co.Oemordernr, MsgcPara1: bl_co.Projnr}
  215. if err = bl_ordmsg.CreateForOemorderToParseCarmodel(session); err != nil {
  216. t.Errorf("为客户订单 %s 创建车型解析消息失败: %v", bl_co.Custordernr, err)
  217. session.Rollback()
  218. session.Close()
  219. return
  220. }
  221. // 创建客户订单计算二级需求的消息
  222. bl_ordmsg = service.BL_Ordmsg{MsgType: common.MSG_TYPE_DEMAND, MsgEvent: common.MSG_EVENT_NEW, MsgObjid: bl_co.Custordernr, MsgcPara1: bl_co.Projnr}
  223. if err = bl_ordmsg.Create(session); err != nil {
  224. t.Errorf("为客户订单 %s 创建二级需求消息失败: %v", bl_co.Custordernr, err)
  225. session.Rollback()
  226. session.Close()
  227. return
  228. }
  229. // 更新解析记录的状态为已解析
  230. seqlandtablst[j].Parsed = common.EDI_PARSE_YES
  231. seqlandtablst[j].Lastmodif = common.Date(time.Now().Unix(), "YYYYMMDDHHmmss")
  232. fields := []string{"parsed", "lastmodif"}
  233. if err = seqlandtablst[j].UpdateFields(session, fields); err != nil {
  234. t.Errorf("Failed to close seqlandtab for custorder %s due to: %v", bl_co.Custordernr, err)
  235. session.Rollback()
  236. session.Close()
  237. return
  238. }
  239. session.Commit()
  240. session.Close()
  241. }
  242. }
  243. }