作者 13655977079
提交者 yangfu

refactor: 物料管理优化

1 delete FROM "dictionarys" where dictionary_id in (3812266576427090944); 1 delete FROM "dictionarys" where dictionary_id in (3812266576427090944);
2 2
3 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972873532463383552, 'ACM-001', '天联共创-生产制造-物料属性', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "外购"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "自制"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "委外"}]'); 3 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972873532463383552, 'ACM-001', '天联共创-生产制造-物料属性', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "外购"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "自制"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "委外"}]');
4 -INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972875981165167616, 'ACM-002', '天联共创-生产制造-物料类别', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "原材料"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "半成品"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "成品"}]');  
5 -INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972882719129994240, 'ACM-003', '天联共创-生产制造-单位', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "千克"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "个"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "包"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "箱"}, {"sort": 5, "isShow": 1, "itemCode": "5", "itemLabel": "", "itemValue": "片"}, {"sort": 6, "isShow": 1, "itemCode": "6", "itemLabel": "", "itemValue": "套"}, {"sort": 7, "isShow": 1, "itemCode": "7", "itemLabel": "", "itemValue": "份"}, {"sort": 8, "isShow": 1, "itemCode": "8", "itemLabel": "", "itemValue": "台"}, {"sort": 9, "isShow": 1, "itemCode": "9", "itemLabel": "", "itemValue": "米"}, {"sort": 10, "isShow": 1, "itemCode": "10", "itemLabel": "", "itemValue": "升"}, {"sort": 11, "isShow": 1, "itemCode": "11", "itemLabel": "", "itemValue": "辆"}, {"sort": 12, "isShow": 1, "itemCode": "12", "itemLabel": "", "itemValue": "秒"}, {"sort": 13, "isShow": 1, "itemCode": "13", "itemLabel": "", "itemValue": "栋"}]'); 4 +INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972875981165167616, 'ACM-002', '天联共创-生产制造-物料管理-物料类别', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "原材料"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "半成品"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "成品"}]');
  5 +INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3972882719129994240, 'ACM-003', '天联共创-生产制造-单位', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "千克"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "个"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "包"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "箱"}, {"sort": 5, "isShow": 1, "itemCode": "5", "itemLabel": "", "itemValue": "片"}, {"sort": 6, "isShow": 1, "itemCode": "6", "itemLabel": "", "itemValue": "套"}, {"sort": 7, "isShow": 1, "itemCode": "7", "itemLabel": "", "itemValue": "份"}, {"sort": 8, "isShow": 1, "itemCode": "8", "itemLabel": "", "itemValue": "台"}, {"sort": 9, "isShow": 1, "itemCode": "9", "itemLabel": "", "itemValue": "米"}, {"sort": 10, "isShow": 1, "itemCode": "10", "itemLabel": "", "itemValue": "升"}, {"sort": 11, "isShow": 1, "itemCode": "11", "itemLabel": "", "itemValue": "辆"}, {"sort": 12, "isShow": 1, "itemCode": "12", "itemLabel": "", "itemValue": "秒"}, {"sort": 13, "isShow": 1, "itemCode": "13", "itemLabel": "", "itemValue": "栋"}, {"sort": 14, "isShow": 1, "itemCode": "14", "itemLabel": "", "itemValue": "袋"}, {"sort": 15, "isShow": 1, "itemCode": "15", "itemLabel": "", "itemValue": "kg"}, {"sort": 16, "isShow": 1, "itemCode": "16", "itemLabel": "", "itemValue": "串"}, {"sort": 17, "isShow": 1, "itemCode": "17", "itemLabel": "", "itemValue": "件"}]');
6 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3978995238135399424, 'ACM-004', '天联共创-生产制造-单位换算-物料类别', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "南瓜饼串"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "包装袋(空)"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "包装袋(件数)"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "装箱(件数)"}]'); 6 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3978995238135399424, 'ACM-004', '天联共创-生产制造-单位换算-物料类别', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "南瓜饼串"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "包装袋(空)"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "包装袋(件数)"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "装箱(件数)"}]');
7 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3812266576427090944, 'XTZD-003', '生产制造-单位', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "个"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "袋"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "kg"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "串"}, {"sort": 5, "isShow": 1, "itemCode": "5", "itemLabel": "", "itemValue": "箱"}, {"sort": 6, "isShow": 1, "itemCode": "6", "itemLabel": "", "itemValue": "件"}]'); 7 INSERT INTO "public"."dictionarys"("dictionary_id", "dict_code", "dict_name", "describe", "dict_items") VALUES (3812266576427090944, 'XTZD-003', '生产制造-单位', '', '[{"sort": 1, "isShow": 1, "itemCode": "1", "itemLabel": "", "itemValue": "个"}, {"sort": 2, "isShow": 1, "itemCode": "2", "itemLabel": "", "itemValue": "袋"}, {"sort": 3, "isShow": 1, "itemCode": "3", "itemLabel": "", "itemValue": "kg"}, {"sort": 4, "isShow": 1, "itemCode": "4", "itemLabel": "", "itemValue": "串"}, {"sort": 5, "isShow": 1, "itemCode": "5", "itemLabel": "", "itemValue": "箱"}, {"sort": 6, "isShow": 1, "itemCode": "6", "itemLabel": "", "itemValue": "件"}]');
@@ -63,6 +63,9 @@ func (crontabService *CrontabService) initTask() { @@ -63,6 +63,9 @@ func (crontabService *CrontabService) initTask() {
63 63
64 syncMaterialGroup := task.NewTask("定时同步物料分组", "0 0 0/2 * * *", SyncMaterialGroup) 64 syncMaterialGroup := task.NewTask("定时同步物料分组", "0 0 0/2 * * *", SyncMaterialGroup)
65 task.AddTask("syncMaterialGroup", syncMaterialGroup) 65 task.AddTask("syncMaterialGroup", syncMaterialGroup)
  66 +
  67 + syncMaterial := task.NewTask("定时同步物料", "0 0 0/2 * * *", SyncMaterial)
  68 + task.AddTask("syncMaterial", syncMaterial)
66 } 69 }
67 70
68 func (crontabService *CrontabService) StartCrontabTask() { 71 func (crontabService *CrontabService) StartCrontabTask() {
@@ -8,6 +8,7 @@ import ( @@ -8,6 +8,7 @@ import (
8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/syncdata" 8 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/syncdata"
9 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log" 9 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
10 "runtime/debug" 10 "runtime/debug"
  11 + "time"
11 ) 12 )
12 13
13 // SyncMaterial 定时同步物料 14 // SyncMaterial 定时同步物料
@@ -30,10 +31,13 @@ func SyncMaterial(ctx context.Context) error { @@ -30,10 +31,13 @@ func SyncMaterial(ctx context.Context) error {
30 } 31 }
31 transactionContext.RollbackTransaction() 32 transactionContext.RollbackTransaction()
32 }() 33 }()
33 - 34 + var pullType string = ""
  35 + if val := ctx.Value("pullType"); val != nil {
  36 + pullType = val.(string)
  37 + }
34 log.Logger.Debug("【定时同步物料】 启动") 38 log.Logger.Debug("【定时同步物料】 启动")
35 pullK3CloudService := syncdata.PullDataK3CloudService{} 39 pullK3CloudService := syncdata.PullDataK3CloudService{}
36 - if err := pullK3CloudService.SyncDataMaterialGroup(transactionContext.(*pg.TransactionContext)); err != nil { 40 + if err := pullK3CloudService.SyncDataMaterial(transactionContext.(*pg.TransactionContext), pullType, time.Time{}); err != nil {
37 log.Logger.Error(err.Error(), map[string]interface{}{"task": "定时同步物料"}) 41 log.Logger.Error(err.Error(), map[string]interface{}{"task": "定时同步物料"})
38 return nil 42 return nil
39 } 43 }
@@ -14,7 +14,7 @@ type UpdateProductMaterialGroupCommand struct { @@ -14,7 +14,7 @@ type UpdateProductMaterialGroupCommand struct {
14 // 物料分组名称 14 // 物料分组名称
15 MaterialGroupName string `cname:"物料分组名称" json:"materialGroupName" valid:"Required"` 15 MaterialGroupName string `cname:"物料分组名称" json:"materialGroupName" valid:"Required"`
16 // 物料分组编码 16 // 物料分组编码
17 - MaterialGroupNumber string `cname:"物料分组编码" json:"materialGroupNumber" valid:"Required"` 17 + MaterialGroupNumber string `cname:"物料分组编码" json:"materialGroupNumber"`
18 } 18 }
19 19
20 func (updateProductMaterialGroupCommand *UpdateProductMaterialGroupCommand) Valid(validation *validation.Validation) { 20 func (updateProductMaterialGroupCommand *UpdateProductMaterialGroupCommand) Valid(validation *validation.Validation) {
@@ -210,6 +210,101 @@ func (srv *PullDataK3CloudService) PullMaterial(timeFilter time.Time) error { @@ -210,6 +210,101 @@ func (srv *PullDataK3CloudService) PullMaterial(timeFilter time.Time) error {
210 return nil 210 return nil
211 } 211 }
212 212
  213 +func (srv *PullDataK3CloudService) pullMaterial(timeFilter time.Time) ([]models.MaterialK3cloud, error) {
  214 + //拉取数据
  215 + var filterString []string
  216 + if !timeFilter.IsZero() {
  217 + str := timeFilter.Format("2006-01-02T15:04:05")
  218 + filterString = append(filterString, "FModifyDate>='"+str+"'")
  219 + }
  220 + client, err := newK3cloudClient()
  221 + if err != nil {
  222 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  223 + }
  224 + fieldKeys := []string{
  225 + "FMATERIALID", "FSpecification", "FName", "FNumber",
  226 + "FDocumentStatus", "FForbidStatus", "FErpClsID",
  227 + "FBaseUnitId", "FBaseUnitId.FName", "FCreateDate", "FModifyDate",
  228 + "FForbidDate", "FApproveDate", "FMaterialGroup", "FMaterialGroup.FName",
  229 + "FRefStatus", "FMaterialGroup.FNumber", "FUseOrgId", "FUseOrgId.FName", "FCategoryID",
  230 + }
  231 + var (
  232 + startRow int
  233 + allResult []map[string]string
  234 + queryErr error
  235 + )
  236 + for {
  237 + result, err := client.ExecuteBillQuery(k3cloud.RequestExecuteBillQuery{
  238 + FormId: "BD_MATERIAL",
  239 + Data: k3cloud.ExecuteBillQueryData{
  240 + FormId: "BD_MATERIAL",
  241 + FieldKeys: strings.Join(fieldKeys, ","), //查询的字段
  242 + StartRow: startRow,
  243 + Limit: 1000,
  244 + FilterString: strings.Join(filterString, " and "),
  245 + },
  246 + })
  247 + if err != nil {
  248 + queryErr = err
  249 + break
  250 + }
  251 + mp := result.ToMapString()
  252 + if len(mp) == 0 {
  253 + break
  254 + }
  255 + allResult = append(allResult, mp...)
  256 + startRow += 1000
  257 + }
  258 + if queryErr != nil {
  259 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  260 + }
  261 + var (
  262 + materialModels []models.MaterialK3cloud
  263 + materialTemp models.MaterialK3cloud
  264 + )
  265 + nowTime := time.Now()
  266 + for _, item := range allResult {
  267 + materialId, err := strconv.Atoi(item["FMATERIALID"])
  268 + if err != nil {
  269 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  270 + }
  271 + fErpClsID, _ := strconv.Atoi(item["FErpClsID"])
  272 + fBaseUnitId, _ := strconv.Atoi(item["FBaseUnitId"])
  273 + materialGroup, _ := strconv.Atoi(item["MaterialGroup"])
  274 + fUseOrgId, _ := strconv.Atoi(item["FUseOrgId"])
  275 + refStatus, _ := strconv.Atoi(item["RefStatus"])
  276 + fCreateDate, _ := time.Parse("2006-01-02T15:04:05.999", item["FCreateDate"])
  277 + fModifyDate, _ := time.Parse("2006-01-02T15:04:05.999", item["FModifyDate"])
  278 + fForbidDate, _ := time.Parse("2006-01-02T15:04:05.999", item["FForbidDate"])
  279 + fApproveDate, _ := time.Parse("2006-01-02T15:04:05.999", item["FApproveDate"])
  280 + materialTemp = models.MaterialK3cloud{
  281 + MaterialId: materialId,
  282 + Name: item["FName"],
  283 + Number: item["FNumber"],
  284 + Specification: item["FSpecification"],
  285 + ForbidStatus: item["FForbidStatus"],
  286 + ErpClsId: fErpClsID,
  287 + BaseUnitId: fBaseUnitId,
  288 + BaseUnitName: item["FBaseUnitId.FName"],
  289 + CreateDate: fCreateDate,
  290 + ModifyDate: fModifyDate,
  291 + ForbidDate: fForbidDate,
  292 + ApproveDate: fApproveDate,
  293 + MaterialGroup: materialGroup,
  294 + MaterialGroupNumber: item["FMaterialGroup.FNumber"],
  295 + MaterialGroupName: item["FMaterialGroup.FName"],
  296 + RefStatus: refStatus,
  297 + UseOrgId: fUseOrgId,
  298 + UseOrgName: item["FUseOrgId.FName"],
  299 + JoinProductId: 0,
  300 + DataVersion: nowTime.Unix(),
  301 + FCategoryID: item["FCategoryID"],
  302 + }
  303 + materialModels = append(materialModels, materialTemp)
  304 + }
  305 + return materialModels, nil
  306 +}
  307 +
213 //PullMaterialGroup 拉取物料分组 308 //PullMaterialGroup 拉取物料分组
214 func (srv *PullDataK3CloudService) PullMaterialGroup() error { 309 func (srv *PullDataK3CloudService) PullMaterialGroup() error {
215 client, err := newK3cloudClient() 310 client, err := newK3cloudClient()
@@ -463,6 +558,33 @@ func (srv *PullDataK3CloudService) PullPrdMo(timeFilter time.Time) error { @@ -463,6 +558,33 @@ func (srv *PullDataK3CloudService) PullPrdMo(timeFilter time.Time) error {
463 return nil 558 return nil
464 } 559 }
465 560
  561 +// PullMaterialCategory 拉取物料分类
  562 +func (srv *PullDataK3CloudService) PullMaterialCategory() (map[string]string, error) {
  563 + client, err := newK3cloudClient()
  564 + if err != nil {
  565 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  566 + }
  567 + fieldKeys := []string{
  568 + "FName", "FNUMBER", "FMasterId",
  569 + }
  570 + result, err := client.ExecuteBillQuery(k3cloud.RequestExecuteBillQuery{
  571 + FormId: "BD_MATERIALCATEGORY",
  572 + Data: k3cloud.ExecuteBillQueryData{
  573 + FormId: "BD_MATERIALCATEGORY",
  574 + FieldKeys: strings.Join(fieldKeys, ","), //查询的字段
  575 + //TopRowCount: 4,
  576 +
  577 + FilterString: "",
  578 + },
  579 + })
  580 + categorys := result.ToMapString()
  581 + var categorysById = make(map[string]string)
  582 + for _, v := range categorys {
  583 + categorysById[v["FMasterId"]] = v["FName"]
  584 + }
  585 + return categorysById, nil
  586 +}
  587 +
466 // 同步产品 588 // 同步产品
467 func (srv *PullDataK3CloudService) SyncDataProduct(ptr *pgTransaction.TransactionContext, fromTime time.Time) error { 589 func (srv *PullDataK3CloudService) SyncDataProduct(ptr *pgTransaction.TransactionContext, fromTime time.Time) error {
468 prdMoDao, err := dao.NewMaterialK3cloudDao(ptr) 590 prdMoDao, err := dao.NewMaterialK3cloudDao(ptr)
@@ -683,23 +805,15 @@ func (srv *PullDataK3CloudService) SyncDataMaterialGroup(ptr *pgTransaction.Tran @@ -683,23 +805,15 @@ func (srv *PullDataK3CloudService) SyncDataMaterialGroup(ptr *pgTransaction.Tran
683 } 805 }
684 806
685 // SyncDataMaterial 同步物料数据 807 // SyncDataMaterial 同步物料数据
686 -func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.TransactionContext, fromTime time.Time) error {  
687 - /*  
688 - 1.获取更新时间  
689 - 2.获取prd_mo_k3cloud从更新时间开始的有变化的数据  
690 - 3.查询是否有重复的批次号  
691 - 4.有进行更新,其他的插入  
692 - */ 808 +// pullType 拉取数据方式 full:全量 其他:增量
  809 +func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.TransactionContext, pullType string, fromTime time.Time) error {
693 var ( 810 var (
694 - lastTime = utils.GetZeroTime(time.Now()).Add(-time.Hour * 24) //前一天有修改的记录  
695 - org *domain.Org  
696 - limit = 500  
697 - offset = 0  
698 - pageIndex = 0  
699 - err error 811 + lastTime = utils.GetZeroTime(time.Now()).Add(-time.Hour * 24) //前一天有修改的记录
  812 + org *domain.Org
  813 + err error
700 ) 814 )
701 - if !fromTime.IsZero() {  
702 - lastTime = fromTime 815 + if pullType == "full" {
  816 + lastTime = time.Time{}
703 } 817 }
704 818
705 var userService = domainService.NewUserService() 819 var userService = domainService.NewUserService()
@@ -710,9 +824,9 @@ func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.Transacti @@ -710,9 +824,9 @@ func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.Transacti
710 824
711 var ( 825 var (
712 cid = constant.MANUFACTURE_DEFAULT_COMPANYID 826 cid = constant.MANUFACTURE_DEFAULT_COMPANYID
  827 + oid = constant.MANUFACTURE_DEFAULT_ORGID
713 productMaterialRepository, _, _ = factory.FastProductMaterial(ptr, 0) 828 productMaterialRepository, _, _ = factory.FastProductMaterial(ptr, 0)
714 productMaterialGroupRepository, _, _ = factory.FastProductMaterialGroup(ptr, 0) 829 productMaterialGroupRepository, _, _ = factory.FastProductMaterialGroup(ptr, 0)
715 - prdMoK3cloudDao, _ = dao.NewPrdMoK3cloudDao(ptr)  
716 materialGroups domain.ProductMaterialGroups 830 materialGroups domain.ProductMaterialGroups
717 ) 831 )
718 832
@@ -721,38 +835,63 @@ func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.Transacti @@ -721,38 +835,63 @@ func (srv *PullDataK3CloudService) SyncDataMaterial(ptr *pgTransaction.Transacti
721 return err 835 return err
722 } 836 }
723 mapMaterialGroup := materialGroups.ToMapByGroupNumber() 837 mapMaterialGroup := materialGroups.ToMapByGroupNumber()
724 - for {  
725 - offset += pageIndex * limit  
726 - pageIndex += 1  
727 838
728 - records, _, err := prdMoK3cloudDao.GetLatestMaterialData(lastTime, offset, limit)  
729 - if err != nil {  
730 - return err 839 + records, err := srv.pullMaterial(lastTime)
  840 + if err != nil {
  841 + return err
  842 + }
  843 +
  844 + mapMaterialCategory, err := srv.PullMaterialCategory()
  845 + if err != nil {
  846 + return err
  847 + }
  848 + log.Logger.Debug(fmt.Sprintf("【同步物料数据】查询数据条数:%v", len(records)))
  849 + for index, item := range records {
  850 + var (
  851 + material *domain.ProductMaterial
  852 + materialGroup *domain.ProductMaterialGroup
  853 + ok bool
  854 + attribute string //物料属性
  855 + category string //物料类别
  856 + )
  857 + if materialGroup, ok = mapMaterialGroup[item.MaterialGroupNumber]; !ok {
  858 + continue
  859 + }
  860 + material, err = productMaterialRepository.FindOne(map[string]interface{}{"companyId": cid, "materialNumber": item.Number})
  861 + if err == nil && material != nil {
  862 + continue
  863 + }
  864 + if err != domain.ErrorNotFound {
  865 + continue
  866 + }
  867 + if v, ok := mapMaterialCategory[item.FCategoryID]; ok {
  868 + category = v
731 } 869 }
  870 + attribute = domain.MaterialAttributeDescription(item.ErpClsId)
732 871
733 - for _, v := range records {  
734 - var (  
735 - material *domain.ProductMaterial  
736 - materialGroup *domain.ProductMaterialGroup  
737 - ok bool  
738 - )  
739 - if materialGroup, ok = mapMaterialGroup[v.MaterialNumber]; !ok {  
740 - continue  
741 - }  
742 - material, err = productMaterialRepository.FindOne(map[string]interface{}{"companyId": cid, "materialNumber": v.MaterialNumber})  
743 - if err == nil && material != nil {  
744 - continue  
745 - }  
746 - if err == domain.ErrorNotFound {  
747 - material = &domain.ProductMaterial{  
748 - ProductMaterialGroupId: materialGroup.ProductMaterialGroupId,  
749 - Ext: domain.NewExt(org.OrgName),  
750 - }  
751 - } 872 + material = &domain.ProductMaterial{
  873 + CompanyId: cid,
  874 + OrgId: oid,
  875 + ProductMaterialGroupId: materialGroup.ProductMaterialGroupId,
  876 + MaterialName: item.Name,
  877 + MaterialNumber: item.Number,
  878 + MaterialAttribute: &domain.MaterialAttribute{Attribute: attribute},
  879 + MaterialCategory: &domain.MaterialCategory{Category: category},
  880 + ProductMaterialExt: &domain.MaterialExt{
  881 + Specification: item.Specification,
  882 + Unit: item.BaseUnitName,
  883 + ExpiredDay: 0,
  884 + Remark: "",
  885 + Source: "k3cloud",
  886 + },
  887 + CreatedAt: time.Now(),
  888 + UpdatedAt: time.Now(),
  889 + Ext: domain.NewExt(org.OrgName),
752 } 890 }
753 - if len(records) == 0 || len(records) < limit {  
754 - break 891 + if material, err = productMaterialRepository.Save(material); err != nil {
  892 + return err
755 } 893 }
  894 + log.Logger.Debug(fmt.Sprintf("同步 序号:%v 物料数据 id:%v number:%v name:%v", index, material.ProductMaterialId, material.MaterialNumber, material.MaterialName))
756 } 895 }
757 return nil 896 return nil
758 } 897 }
@@ -32,4 +32,6 @@ type MaterialExt struct { @@ -32,4 +32,6 @@ type MaterialExt struct {
32 ExpiredDay int `json:"expiredDay"` 32 ExpiredDay int `json:"expiredDay"`
33 // 备注 33 // 备注
34 Remark string `json:"remark"` 34 Remark string `json:"remark"`
  35 + // 来源 k3cloud
  36 + Source string `json:"source"`
35 } 37 }
@@ -67,3 +67,27 @@ func (productMaterials ProductMaterials) ToMapByNumber() map[string]*ProductMate @@ -67,3 +67,27 @@ func (productMaterials ProductMaterials) ToMapByNumber() map[string]*ProductMate
67 } 67 }
68 return mapProductMaterial 68 return mapProductMaterial
69 } 69 }
  70 +
  71 +// 10:资产,9:配置,2:自制,11:费用,12:模型,5:虚拟,7:一次性,13:产品系列 12:模型,3:委外,4:特征,6:服务,1:外购
  72 +var mapMaterialCategory = map[int]string{
  73 + 1: "外购",
  74 + 2: "自制",
  75 + 3: "委外",
  76 + 4: "特征",
  77 + 5: "虚拟",
  78 + 6: "服务",
  79 + 7: "一次性",
  80 + 8: "",
  81 + 9: "配置",
  82 + 10: "资产",
  83 + 11: "费用",
  84 + 12: "模型",
  85 + 13: "产品系列",
  86 +}
  87 +
  88 +func MaterialAttributeDescription(code int) string {
  89 + if v, ok := mapMaterialCategory[code]; ok {
  90 + return v
  91 + }
  92 + return ""
  93 +}
@@ -172,9 +172,9 @@ func (d *PrdMoK3cloudDao) GetLatestData(fromTime time.Time) ([]*models.PrdMoK3cl @@ -172,9 +172,9 @@ func (d *PrdMoK3cloudDao) GetLatestData(fromTime time.Time) ([]*models.PrdMoK3cl
172 } 172 }
173 173
174 // GetLatestMaterialData 增量获取物料数据 174 // GetLatestMaterialData 增量获取物料数据
175 -func (d *PrdMoK3cloudDao) GetLatestMaterialData(fromTime time.Time, offset, limit int) ([]*models.ProductMaterial, int, error) {  
176 - m := new(models.ProductMaterial)  
177 - result := make([]*models.ProductMaterial, 0) 175 +func (d *PrdMoK3cloudDao) GetLatestMaterialData(fromTime time.Time, offset, limit int) ([]*models.MaterialK3cloud, int, error) {
  176 + m := new(models.MaterialK3cloud)
  177 + result := make([]*models.MaterialK3cloud, 0)
178 query := d.transactionContext.PgTx.Model(m) 178 query := d.transactionContext.PgTx.Model(m)
179 if !fromTime.IsZero() { 179 if !fromTime.IsZero() {
180 query.Where("modify_date>=?", fromTime) 180 query.Where("modify_date>=?", fromTime)
@@ -53,8 +53,7 @@ func (ptr *PGMaterialService) AddMaterial(opt *domain.OperateInfo, item *domain. @@ -53,8 +53,7 @@ func (ptr *PGMaterialService) AddMaterial(opt *domain.OperateInfo, item *domain.
53 UpdatedAt: time.Now(), 53 UpdatedAt: time.Now(),
54 Ext: domain.NewExt(org.OrgName).WithOperator(user), 54 Ext: domain.NewExt(org.OrgName).WithOperator(user),
55 } 55 }
56 - aaa, err := productMaterialRepository.Save(newProductMaterial)  
57 - return aaa, err 56 + return productMaterialRepository.Save(newProductMaterial)
58 } 57 }
59 58
60 // 物料分组 59 // 物料分组
@@ -25,6 +25,7 @@ type MaterialK3cloud struct { @@ -25,6 +25,7 @@ type MaterialK3cloud struct {
25 UseOrgName string `comment:"使用组织" pg:"use_org_name"` 25 UseOrgName string `comment:"使用组织" pg:"use_org_name"`
26 JoinProductId int64 `comment:"关联的product表id" pg:"join_product_id"` 26 JoinProductId int64 `comment:"关联的product表id" pg:"join_product_id"`
27 DataVersion int64 `comment:"数据版本" pg:"data_version"` 27 DataVersion int64 `comment:"数据版本" pg:"data_version"`
  28 + FCategoryID string `pg:"-"`
28 } 29 }
29 30
30 //批量处理sql脚本样例 31 //批量处理sql脚本样例
@@ -137,7 +137,7 @@ func (repository *ProductMaterialRepository) FindOne(queryOptions map[string]int @@ -137,7 +137,7 @@ func (repository *ProductMaterialRepository) FindOne(queryOptions map[string]int
137 query.SetWhereByQueryOption("product_material.material_number = ?", "materialNumber") 137 query.SetWhereByQueryOption("product_material.material_number = ?", "materialNumber")
138 if err := query.First(); err != nil { 138 if err := query.First(); err != nil {
139 if err.Error() == "pg: no rows in result set" { 139 if err.Error() == "pg: no rows in result set" {
140 - return nil, fmt.Errorf("没有此资源") 140 + return nil, domain.ErrorNotFound
141 } else { 141 } else {
142 return nil, err 142 return nil, err
143 } 143 }
@@ -2,6 +2,7 @@ package k3cloud @@ -2,6 +2,7 @@ package k3cloud
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
  5 + "fmt"
5 "io" 6 "io"
6 "time" 7 "time"
7 8
@@ -87,3 +88,20 @@ func (c *Client) ExecuteBillQuery(param RequestExecuteBillQuery) (*BillQueryResu @@ -87,3 +88,20 @@ func (c *Client) ExecuteBillQuery(param RequestExecuteBillQuery) (*BillQueryResu
87 queryResult := newBillQueryResult(dataByte, param.Data.FieldKeys) 88 queryResult := newBillQueryResult(dataByte, param.Data.FieldKeys)
88 return queryResult, queryResult.Error() 89 return queryResult, queryResult.Error()
89 } 90 }
  91 +
  92 +// ExecuteMetaDataQuery 元数据查询
  93 +func (c *Client) ExecuteMetaDataQuery(param RequestMetaDataQuery) ([]byte, error) {
  94 + api := "/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.QueryBusinessInfo.common.kdsvc"
  95 + resp, err := c.PostRequest(api, param)
  96 + if err != nil {
  97 + return nil, err
  98 + }
  99 + defer resp.Body.Close()
  100 + var dataByte []byte
  101 + dataByte, err = io.ReadAll(resp.Body)
  102 + if err != nil {
  103 + return nil, err
  104 + }
  105 + fmt.Println("data ", string(dataByte))
  106 + return dataByte, nil
  107 +}
1 package k3cloud 1 package k3cloud
2 2
3 import ( 3 import (
  4 + "fmt"
4 "strings" 5 "strings"
5 "testing" 6 "testing"
  7 + "time"
6 ) 8 )
7 9
8 var ( 10 var (
@@ -40,7 +42,7 @@ func TestExecuteBillQuery(t *testing.T) { @@ -40,7 +42,7 @@ func TestExecuteBillQuery(t *testing.T) {
40 "FDocumentStatus", "FForbidStatus", "FErpClsID", 42 "FDocumentStatus", "FForbidStatus", "FErpClsID",
41 "FBaseUnitId", "FBaseUnitId.FName", "FCreateDate", "FModifyDate", 43 "FBaseUnitId", "FBaseUnitId.FName", "FCreateDate", "FModifyDate",
42 "FForbidDate", "FApproveDate", "FMaterialGroup", "FMaterialGroup.FName", 44 "FForbidDate", "FApproveDate", "FMaterialGroup", "FMaterialGroup.FName",
43 - "FRefStatus", "FMaterialGroup.FNumber", "FUseOrgId", "FUseOrgId.FName", 45 + "FRefStatus", "FMaterialGroup.FNumber", "FUseOrgId", "FUseOrgId.FName", "FCategoryID",
44 } 46 }
45 result, err := client.ExecuteBillQuery(RequestExecuteBillQuery{ 47 result, err := client.ExecuteBillQuery(RequestExecuteBillQuery{
46 FormId: "BD_MATERIAL", 48 FormId: "BD_MATERIAL",
@@ -85,3 +87,52 @@ func TestExecuteBillQuery2(t *testing.T) { @@ -85,3 +87,52 @@ func TestExecuteBillQuery2(t *testing.T) {
85 return 87 return
86 } 88 }
87 } 89 }
  90 +
  91 +func TestMetaDataQuery(t *testing.T) {
  92 + client, err := NewClient(hostUrl, acctID, username, password)
  93 + if err != nil {
  94 + t.Error(err)
  95 + return
  96 + }
  97 + inputs := []struct {
  98 + formId string
  99 + desc string
  100 + }{
  101 + {"BD_MATERIALCATEGORY", "货类别没"},
  102 + {"BD_MATERIALCATEGORY", "货类别没"},
  103 + }
  104 + for _, v := range inputs {
  105 + result, err := client.ExecuteMetaDataQuery(RequestMetaDataQuery{Data{FormId: v.formId}, v.formId})
  106 + if err != nil {
  107 + fmt.Println(err.Error())
  108 + }
  109 + t.Log(v.formId, v.desc, string(result))
  110 + }
  111 + time.Sleep(time.Second)
  112 +}
  113 +
  114 +func TestExecuteMATERIALCATEGORYQuery(t *testing.T) {
  115 + client, err := NewClient(hostUrl, acctID, username, password)
  116 + if err != nil {
  117 + t.Error(err)
  118 + return
  119 + }
  120 + fieldKeys := []string{
  121 + "FName", "FNUMBER", "FMasterId",
  122 + }
  123 + result, err := client.ExecuteBillQuery(RequestExecuteBillQuery{
  124 + FormId: "PRD_MO",
  125 + Data: ExecuteBillQueryData{
  126 + FormId: "BD_MATERIALCATEGORY",
  127 + FieldKeys: strings.Join(fieldKeys, ","), //查询的字段
  128 + //TopRowCount: 4,
  129 +
  130 + FilterString: "",
  131 + },
  132 + })
  133 + t.Logf("result buf===> %s \n", string(result.Buf))
  134 + if err != nil {
  135 + t.Error(err)
  136 + return
  137 + }
  138 +}
@@ -51,3 +51,13 @@ type ( @@ -51,3 +51,13 @@ type (
51 Data ExecuteBillQueryData `json:"data"` 51 Data ExecuteBillQueryData `json:"data"`
52 } 52 }
53 ) 53 )
  54 +
  55 +type (
  56 + RequestMetaDataQuery struct {
  57 + Data Data `json:"data"`
  58 + FormId string `json:"FormId"` //必录,查询表单元数据唯一标识
  59 + }
  60 + Data struct {
  61 + FormId string `json:"FormId"` //必录,查询表单元数据唯一标识
  62 + }
  63 +)
@@ -146,6 +146,14 @@ func (controller *StatisticsController) TaskHandler() func(ctx *context.Context) @@ -146,6 +146,14 @@ func (controller *StatisticsController) TaskHandler() func(ctx *context.Context)
146 } 146 }
147 case "11": 147 case "11":
148 crontab.SyncMaterialGroup(nil) 148 crontab.SyncMaterialGroup(nil)
  149 + case "12":
  150 + bc := c.Background()
  151 + bc = c.WithValue(bc, "pullType", "full")
  152 + err := crontab.SyncMaterial(bc)
  153 + if err != nil {
  154 + Response(ctx, nil, err)
  155 + return
  156 + }
149 } 157 }
150 Response(ctx, nil, nil) 158 Response(ctx, nil, nil)
151 } 159 }