package service import ( "encoding/json" "fmt" "kpt.xdmy/apiserver/config" "strconv" "strings" "time" log "github.com/sirupsen/logrus" "kpt.xdmy/apiserver/model" "kpt.xdmy/apiserver/model/http" ) const ( //ContractToAspUrl = config.Conf.Http.Routing + "/SRM/MM018/PurchaseInfo" ContractToAspDestID = "EQMAN" ContractToAspBussTp = "MM018" ContractLimit = 10 ) var ( sapContractReq = &http.SapContractReq{ Dest: &http.Dest{ DestID: ContractToAspDestID, BussTp: ContractToAspBussTp, //Url: ContractToAspUrl, }, DATA: &http.ContractDataToASP{}, } loc, _ = time.LoadLocation("Local") ) type ContractInfo struct { PastureBigContract *model.PastureBigcontract // 牧场和合同关联表 Contract []*model.Contract // 合同子表 Provider *model.Provider // 供应商 Pasture *model.Pasture // 牧场 } // GetBigContractData 获取主合同信息 func GetBigContractData() []*model.BigContract { bigContractData := make([]*model.BigContract, 0) if err := s.d.DB.Where("isToSap = ?", 0).Where("SHStatus = ?", 7).Find(&bigContractData).Debug().Error; err != nil { log.Errorf("AutoContractToASP Error:%v", err) } for _, item := range bigContractData { if item.SHStatus == 7 && item.SHtype == 3 && item.CGChargedate.UnixNano() > time.Now().AddDate(0, 0, -1).UnixNano() { contractCodeSlice := strings.Split(item.ContractCode, "-") contractCode := contractCodeSlice[0] s.d.DB.Exec(`update contract set isToSap = 0 where enable = 1 and bigid in(select id from bigContract where like ? )`, "%"+contractCode+"%") } } return bigContractData } func GetPastureBigContract(contractCode string) ([]*model.PastureBigcontract, error) { pastureBigContract := make([]*model.PastureBigcontract, 0) SQL := fmt.Sprintf("select t.* from( "+ " select pastureId as pasture_id ,enable FROM bigcontract WHERE contractCode LIKE '%s' and SHStatus = 7 GROUP BY pastureId "+ " union all "+ " SELECT pasture_id, enable FROM pasture_bigcontract WHERE bigcontract_id IN (SELECT id FROM bigcontract WHERE contractCode LIKE '%s' AND enable = 1 and SHStatus = 7 ) )t"+ " join pasture p on p.id = t.pasture_id "+ " group by pasture_id", "%"+contractCode+"%", "%"+contractCode+"%") if err := s.d.DB.Raw(SQL).Find(&pastureBigContract).Error; err != nil { return nil, err } return pastureBigContract, nil } // GetContractInfo 获取合同相关信息 func GetContractInfo(bigContract *model.BigContract, pastureBigContract *model.PastureBigcontract) *ContractInfo { //wg := sync.WaitGroup{} //wg.Add(3) contractInfo := &ContractInfo{} // 获取牧场数据合同数据 //go func() { pasture := &model.Pasture{ ID: pastureBigContract.PastureId, } if err := s.d.DB.First(pasture).Error; err != nil { log.Errorf("AutoContractToASP Pasture Err:%v,bigContractData:%v", err, bigContract) } contractInfo.Pasture = pasture // wg.Done() //}() // 获取合同子表数据 //go func() { contract := make([]*model.Contract, 0) if err := s.d.DB.Debug().Where("bigId = ?", bigContract.ID).Where("isToSap = ? ", 0).Find(&contract).Error; err != nil { log.Errorf("AutoContractToASP contract Err:%v,bigContractData:%v", err, bigContract) } contractInfo.Contract = contract // wg.Done() //}() // 获取供应商数据 //go func() { provider := &model.Provider{ ID: bigContract.ProviderID, } if err := s.d.DB.First(provider).Error; err != nil { log.Errorf("AutoContractToASP Provider Err:%v,bigContractData:%v", err, bigContract) } contractInfo.Provider = provider // wg.Done() //}() //wg.Wait() return contractInfo } // http://192.168.61.117/SAPQ0/SRM/MM018/PurchaseInfo // AutoContractToASP 合同信息自动同步到ASP func AutoContractToASP() { sapContractReq.Url = config.Conf.Http.Routing + "/SRM/MM018/PurchaseInfo" bigContractData := GetBigContractData() ContractCodeMap := make(map[string][]*model.PastureBigcontract, 0) errDataList := make(map[string][]*model.ContractSapErr, 0) contractInfoList := make([]*ContractInfo, 0) for _, bigContract := range bigContractData { contractCode := bigContract.ContractCode if bigContract.SHStatus != 7 { continue } var count int64 s.d.DB.Debug().Table(new(model.BigContract).TableName()).Where("id = ? ", bigContract.ID).Where("isToSap = ?", 0).Count(&count) if count == 0 { continue } if strings.Contains(bigContract.ContractCode, "-") { contractCodeSlice := strings.Split(bigContract.ContractCode, "-") contractCode = contractCodeSlice[0] } var err error pastureBigContractSlice := make([]*model.PastureBigcontract, 0) if _, ok := ContractCodeMap[contractCode]; !ok { pastureBigContractSlice, err = GetPastureBigContract(contractCode) if err != nil { log.Errorf("AutoContractToASP pastureBigContractSlice Err:%v", err) continue } ContractCodeMap[contractCode] = append(ContractCodeMap[contractCode], pastureBigContractSlice...) //if err := s.d.DB.Debug().Table(new(model.BigContract).TableName()).Where("contractCode like ? ", "%"+contractCode+"%").Update("isToSap", 1).Error; err != nil { // log.Errorf("AutoContractToASP SQLUpdate Error:%v", err) //} } if err := s.d.DB.Debug().Table(new(model.BigContract).TableName()).Where("id = ? ", bigContract.ID).Update("isToSap", 1).Error; err != nil { log.Errorf("AutoContractToASP SQLUpdate Error:%v", err) } if _, ok := ContractCodeMap[contractCode]; ok { for _, pastureBigContract := range ContractCodeMap[contractCode] { // 获取合同相关数据集合 contractInfo := GetContractInfo(bigContract, pastureBigContract) if len(contractInfo.Contract) == 0 || pastureBigContract.PastureId == 18 { continue } // 发送数据至SAP errData := PushContractDataToSAP(bigContract, contractInfo, contractCode) for _, data := range errData { errDataList[contractCode] = append(errDataList[contractCode], data...) } contractInfoList = append(contractInfoList, contractInfo) //go func(bigContract *model.BigContract, contractInfo *ContractInfo) { //}(bigContract, contractInfo) //ContractCodeMap[contractCode] = append(ContractCodeMap[contractCode], pastureBigContract) } } } now := time.Now() for _, contractSapErr := range errDataList { for _, c := range contractSapErr { c.CreateTime = now s.d.DB.Create(&c) } } for _, contractInfo := range contractInfoList { for _, c := range contractInfo.Contract { if c.IsToSap == 0 { if err := s.d.DB.Table("contract").Where("id = ?", c.ID).Update("isToSap", 1).Error; err != nil { log.Errorf("AutoContractToASP SQLUpdate Error:%v", err) } } } } log.Info("AutoContractToASP Success") } // PushContractDataToSAP 同步数据给SAP func PushContractDataToSAP(bigContract *model.BigContract, contractInfo *ContractInfo, contractCode string) map[string][]*model.ContractSapErr { errMap := make(map[string][]*model.ContractSapErr, 0) for _, contract := range contractInfo.Contract { if contract.IsToSap == 1 { continue } LOEKZ := "" if contract.Enable == 0 { LOEKZ = "X" } startTime, _ := time.ParseInLocation(time.RFC3339, bigContract.StartTime, loc) stopTime, _ := time.ParseInLocation(time.RFC3339, bigContract.StopTime, loc) astr := strconv.FormatFloat(contract.Price, 'f', -1, 64) b := strings.Index(astr, ".") per := "" if len(astr[b+1:]) > 2 && b > 0 { num, _ := strconv.ParseFloat(astr[b+1:], 64) if num > 0 { contract.Price = contract.Price * 1000 per = "1000" } } var isZeroStock int if bigContract.IsZeroStock == 1 { isZeroStock = 2 } else { isZeroStock = 0 } //LOEKZ = "X" contractDataToASP := &http.ContractDataToASP{ MATNR: contract.PartCode, LIFNR: contractInfo.Provider.SapCode, EKORG: contractInfo.Pasture.ParchaseOrganization, WERKS: contractInfo.Pasture.FactoryCode, WAERS: "CNY", PEINH: per, NETPR: fmt.Sprintf("%.2f", contract.Price), MWSKZ: "J0", EKGRP: contractInfo.Pasture.PurchasingGroup, DATAB: startTime.Format("20060102"), DATBI: stopTime.Format("20060102"), LOEKZ: LOEKZ, ESOKZ: fmt.Sprintf("%d", isZeroStock), MEINS: contract.Unit, Code: bigContract.ContractCode, } sapContractReq.DATA = contractDataToASP rp := &http.SapContractResp{} rbyte, _ := json.Marshal(sapContractReq) fmt.Println(string(rbyte)) if err := s.SyncSap(sapContractReq, rp, sapContractReq); err != nil { log.Errorf("AutoContractToASP SyncSap Err:%v contract:%v", err, contract) continue } log.Info(rp) if rp.Dest.Status != "S" { log.Errorf("AutoContractToASP SyncSap Error:%v,contract:%v", rp, contract) contract.PastureID = contractInfo.Pasture.ID errMap[contractCode] = append(errMap[contractCode], &model.ContractSapErr{ ContractID: contract.ID, PastureID: contractInfo.Pasture.ID, PastureName: contractInfo.Pasture.Name, PartID: contract.PartID, PartName: contract.PartName, PartCode: contract.PartCode, Specification: contract.Specification, Price: contract.Price, BrandID: contract.BrandID, Brand: contract.Brand, InventoryType: contract.InventoryType, PlanAmount: contract.PlanAmount, Remark: contract.Remark, Enable: contract.Enable, Unit: contract.Unit, IsZeroStock: contract.IsZeroStock, ChangeID: contract.ChangeID, SapText: rp.MessText, ContractCode: contractCode, }) } } return errMap } func RemoveRepeatedElement1(arr []string) (newArr []string) { newArr = make([]string, 0) for i := 0; i < len(arr); i++ { repeat := false for j := i + 1; j < len(arr); j++ { if arr[i] == arr[j] { repeat = true break } } if !repeat { newArr = append(newArr, arr[i]) } } return }