package api import ( "box-cost/db/model" "box-cost/db/repo" "box-cost/log" "errors" "fmt" "strconv" "time" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) // 单据管理 func Bill(r *GinRouter) { // 创建单据 r.POSTJWT("/bill/purchase/create", CreateBill) // 获取单据详情 r.GETJWT("/bill/purchase/detail/:id", GetBill) // 获取单据列表 r.GETJWT("/bill/purchase/list", GetBills) // 获取单据列表 r.GETJWT("/bill/purchase/download", DownLoadBills) // 更新单据 r.POSTJWT("/bill/purchase/update", UpdateBill) // 删除单据 r.POSTJWT("/bill/purchase/delete/:id", DelBill) // 审核单据 r.POSTJWT("/bill/purchase/review/:id", PurchaseReview) // 对账单据 r.POSTJWT("/bill/record", BillRecord) } type BillRecordReq struct { BillType string `json:"billType"` Id primitive.ObjectID `json:"id"` Record *bool `json:"record"` } // 对账单据 func BillRecord(c *gin.Context, apictx *ApiSession) (interface{}, error) { var req BillRecordReq err := c.ShouldBindJSON(&req) if err != nil { return nil, errors.New("参数错误!") } if req.Id.IsZero() { return nil, errors.New("id错误!") } collection := "" if req.BillType == "purchase" { collection = repo.CollectionBillPurchase } else if req.BillType == "produce" { collection = repo.CollectionBillProduce } else if req.BillType == "product" { collection = repo.CollectionBillProduct } else { return nil, errors.New("订单类型错误!") } update := bson.M{"isRecord": req.Record} userId, _ := primitive.ObjectIDFromHex(apictx.User.ID) user, _ := getUserById(apictx, userId) // return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), collection, req.Id.Hex(), &update) return repo.RepoUpdateSetDoc1(apictx.CreateRepoCtx(), collection, req.Id.Hex(), &update, &repo.RecordLogReq{ Path: c.Request.URL.Path, UserInfo: user, TargetId: req.Id.Hex(), Type: "recorded", }) } // 审核单据 func PurchaseReview(c *gin.Context, apictx *ApiSession) (interface{}, error) { _id := c.Param("id") id, err := primitive.ObjectIDFromHex(_id) if err != nil { return nil, errors.New("id错误") } userId, err := primitive.ObjectIDFromHex(apictx.User.Parent) if err != nil { return nil, errors.New("用户异常") } user, err := getUserById(apictx, userId) if err != nil { return nil, errors.New("查找用户失败") } if !isManager(user.Roles) { return nil, errors.New("该用户没有权限") } // 查询单据获取已有的签字 bill := model.PurchaseBill{} found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": id, "reviewed": 1}, }, &bill) signs := make([]primitive.ObjectID, 0) if found && len(bill.SignUsers) > 0 { // 如果自己已存在该集合中了 for _, signUser := range bill.SignUsers { if signUser == userId { return nil, errors.New("该单据您已签字审核过了") } } signs = bill.SignUsers } // 更改状态为已审核 并签字 signs = append(signs, userId) purchase := model.PurchaseBill{ Reviewed: 1, UpdateTime: time.Now(), SignUsers: signs, } // return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, _id, &purchase) return repo.RepoUpdateSetDoc1(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, _id, &purchase, &repo.RecordLogReq{ Path: c.Request.URL.Path, UserInfo: user, TargetId: _id, Type: "reviewed", }) } type MatBillReq struct { Bill *model.PurchaseBill CompIndex *int MatIndex *int //MatKey string //components.0.mats.0.billId } // 创建单据 func CreateBill(c *gin.Context, apictx *ApiSession) (interface{}, error) { req := &model.PurchaseBill{} err := c.ShouldBindJSON(req) if err != nil { fmt.Println(err) return nil, errors.New("参数错误") } ctx := apictx.CreateRepoCtx() bill := req if bill.PackId.Hex() == "" { return nil, errors.New("包装产品id为空") } if bill.PlanId.Hex() == "" { return nil, errors.New("生产计划id为空") } if bill.Type == "" { return nil, errors.New("类型为空") } bill.SerialNumber, err = generateSerial(c, apictx, bill.Type) if err != nil { return nil, err } bill.Status = "created" if bill.Reviewed == 0 { bill.Reviewed = -1 } bill.CreateTime = time.Now() bill.UpdateTime = time.Now() _isSend := false bill.IsSend = &_isSend notAck := false bill.IsAck = ¬Ack // 制单人数据 userId, _ := primitive.ObjectIDFromHex(apictx.User.Parent) fmt.Println("userId:", apictx.User.Parent) userInfo := &model.UserSmaple{} if !userId.IsZero() { user, err := getUserById(apictx, userId) userInfo = user if err == nil { bill.UserName = user.Name bill.UserId = userId } } return repo.RepoAddDoc1(ctx, repo.CollectionBillPurchase, &bill, &repo.RecordLogReq{ Path: c.Request.URL.Path, UserInfo: userInfo, TargetId: "", Type: "created", }) } // 获取单据信息 func GetBill(c *gin.Context, apictx *ApiSession) (interface{}, error) { billId := c.Param("id") id, err := primitive.ObjectIDFromHex(billId) if err != nil { return nil, errors.New("非法id") } var bill model.PurchaseBill option := &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": id}, } found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), option, &bill) if !found || err != nil { log.Info(err) return nil, errors.New("数据未找到") } return bill, nil } // 获取单据列表 func GetBills(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) option := &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: makeBillQuery(query), Page: page, Size: size, Sort: bson.M{"createTime": -1}, } return repo.RepoPageSearch(apictx.CreateRepoCtx(), option) } func DownLoadBills(c *gin.Context, apictx *ApiSession) (interface{}, error) { billId := c.Query("id") isPdf := c.Query("isPdf") if len(billId) < 1 { return nil, fmt.Errorf("id不能为空") } id, err := primitive.ObjectIDFromHex(billId) if err != nil { return nil, errors.New("非法id") } var bill model.PurchaseBill option := &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": id}, } found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), option, &bill) if !found || err != nil { log.Info(err) return nil, errors.New("数据未找到") } f := excelize.NewFile() index := f.NewSheet("Sheet1") f.SetActiveSheet(index) f.SetDefaultFont("宋体") var billExcel *PurchaseBillExcel if len(bill.Paper) > 0 { billExcel = NewPurchaseBill(f) } if billExcel == nil { return nil, errors.New("数据未找到") } // 获取已审核的签名数据 if bill.Reviewed == 1 { if len(bill.SignUsers) > 0 { signs := []*model.Signature{} repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionSignature, Query: repo.Map{"_id": bson.M{"$in": bill.SignUsers}}, Sort: bson.M{"sort": 1}, // 升序 }, &signs) billExcel.Signatures = signs } } billExcel.Content = &bill billExcel.IsPdf = isPdf companyName := getCompanyName(apictx) billExcel.Title = fmt.Sprintf("%s原材料采购单", companyName) //设置对应的数据 billExcel.Draws() // 下载为pdf if isPdf == "true" { buf, _ := f.WriteToBuffer() res, err := excelToPdf(buf, apictx.Svc.Conf.PdfApiAddr) if err != nil { fmt.Println(err) return nil, errors.New("转化pdf失败") } defer res.Body.Close() c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+"bill.pdf") c.Header("Content-Transfer-Encoding", "binary") err = res.Write(c.Writer) if err != nil { return nil, err } return nil, nil } // 下载为execl c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+"bill.xlsx") c.Header("Content-Transfer-Encoding", "binary") err = f.Write(c.Writer) if err != nil { return nil, err } return nil, nil } // 更新单据 func UpdateBill(c *gin.Context, apictx *ApiSession) (interface{}, error) { var bill model.PurchaseBill err := c.ShouldBindJSON(&bill) if err != nil { fmt.Println(err) return nil, errors.New("参数错误") } if bill.Id.Hex() == "" { return nil, errors.New("id的为空") } // 如果更改类型 if len(bill.Type) > 0 { billType, err := searchBillTypeById(apictx, repo.CollectionBillPurchase, bill.Id) if err != nil { return nil, err } if billType != bill.Type { bill.SerialNumber, err = generateSerial(c, apictx, bill.Type) if err != nil { return nil, err } } } userId, _ := primitive.ObjectIDFromHex(apictx.User.ID) user, _ := getUserById(apictx, userId) logType := "update" // 更改状态 ok, err := isCompareStatus(apictx, repo.CollectionBillPurchase, bill.Id, bill.Status) if err != nil { return nil, err } if bill.Status == "complete" { if !ok { bill.CompleteTime = time.Now() logType = "complete" } } if bill.Status == "deprecated" { if !ok { logType = "deprecated" } } if bill.Remark == "" { bill.Remark = " " } if bill.SupplierRemark == "" { bill.SupplierRemark = " " } // 修改单据信息需要同步plan中stage项 if len(bill.Paper) > 0 { // 获取当前订单供应商id // 对比供应商是否变化,变化了就同步计划中的供应商 currPurchase := &model.PurchaseBill{} repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": bill.Id}, Project: []string{"supplierId"}, }, currPurchase) var supplierInfo *model.Supplier if currPurchase.SupplierId != bill.SupplierId { // 查询更改后的supplierInfo supplierInfo = &model.Supplier{} repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionSupplier, Query: repo.Map{"_id": bill.SupplierId}, }, supplierInfo) } units := []string{"元/吨", "元/平方米"} idStatges := make(map[string]*UpdateBilltoStageReq) for _, paper := range bill.Paper { if len(paper.Id) == 0 { continue } width, _ := strconv.Atoi(paper.Width) Height, _ := strconv.Atoi(paper.Height) idStatges[paper.Id] = &UpdateBilltoStageReq{ BillType: "purchase", SupplierInfo: supplierInfo, Norm: paper.Norm, Width: width, Height: Height, Price2: paper.Price2, OrderCount: paper.OrderCount, OrderPrice: paper.OrderPrice, Remark: paper.Remark, ConfirmCount: paper.ConfirmCount, DeliveryTime: paper.DeliveryTime, IsChangePrice2: isInclude(paper.Price2Unit, units), } } _, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx) if err != nil { return nil, errors.New("该单据改动同步到产品失败") } fmt.Println("单据同步到产品,planId:", bill.PlanId) } bill.UpdateTime = time.Now() // return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, bill.Id.Hex(), &bill) return repo.RepoUpdateSetDoc1(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, bill.Id.Hex(), &bill, &repo.RecordLogReq{ Path: c.Request.URL.Path, UserInfo: user, TargetId: bill.Id.Hex(), Type: logType, }) } func isInclude(str1 string, arr []string) bool { for _, a := range arr { if str1 == a { return true } } return false } // 删除单据 func DelBill(c *gin.Context, apictx *ApiSession) (interface{}, error) { billId := c.Param("id") if billId == "" { return nil, errors.New("id为空") } return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionBillPurchase, billId) }