package settle_account_bill import ( "dashoo.cn/micro_libary/request" "database/sql" "errors" "fmt" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" "lims_adapter/dao/account" "lims_adapter/model" accountModel "lims_adapter/model/account" "strconv" "strings" ) // Service 会议室服务 type Service struct { Dao *account.SettleAccountBillDao Tenant string } // NewSrv 服务初始化 func NewService(tenant string) Service { return Service{Dao: account.NewSettleAccountBillDao(tenant), Tenant: tenant} } // List 会议室列表 func (s Service) List(req model.ListReq, user request.UserInfo) ([]accountModel.BillInfo, int, error) { entityModel := s.Dao.M where := "1=1" if req.Entity != nil { entity := new(accountModel.SettleAccountBillReq) err := gconv.Struct(req.Entity, entity) if err != nil { return nil, 0, err } if entity.MainUserId != 0 { where += fmt.Sprintf(" AND settle_account_bill.MainUserId='%v'", entity.MainUserId) } if entity.Status != "" { where += fmt.Sprintf(" AND settle_account_bill.Status='%v'", entity.Status) } if entity.SettleDate != "" { timelist := strings.Split(entity.SettleDate,",") if len(timelist) == 2 { where += fmt.Sprintf(" AND settle_account_bill.SettleDate>='%v' AND settle_account_bill.SettleDate<='%v'", timelist[0],timelist[1]) } } if entity.SettleUser != "" { where += fmt.Sprintf(" AND settle_account_bill.SettleUser LIKE '%%%v%%'", entity.SettleUser) } if entity.MainUser != "" { where += fmt.Sprintf(" AND settle_account_bill.MainUser LIKE '%%%v%%'", entity.MainUser) } if entity.StartDate != "" && entity.EndDate != "" { where += fmt.Sprintf(" AND settle_account_bill.StartDate>='%v' AND settle_account_bill.EndDate<='%v'", entity.StartDate, entity.EndDate) } if entity.IsSelf != "1" { // 1 查看全部;其他 查看自己 where += fmt.Sprintf(" AND settle_account_bill.MainUserId='%v'", user.Id) } } entityModel = entityModel.Where(where) total, err := entityModel.Count() if err != nil { return nil, 0, err } if total == 0 { return nil, 0, nil } res, err := entityModel.InnerJoin("settle_account_main", "settle_account_bill.Id=settle_account_main.BillId").Group("settle_account_bill.Id").Page(req.Current, req.Size).Order("settle_account_bill.Id DESC").Fields("settle_account_bill.*, SUM(settle_account_main.TotalPrice) TotalAmount").FindAll() if err != nil { return nil, 0, err } if res.IsEmpty() { return nil, 0, nil } list := make([]accountModel.BillInfo, 0) err = res.Structs(&list) if err != nil { return nil, 0, err } return list, total, nil } // 结算 func (s Service) Settle(req accountModel.AccountBillSettleReq, user request.UserInfo) error { if req.BillId == 0 { return errors.New("参数缺失") } tx, err := s.Dao.DB.Begin() if err != nil { return err } _, err = tx.Update("settle_account_bill", fmt.Sprintf("Status='2',SettleUserId='%v',SettleUser='%v',SettleDate='%v'", user.Id, user.RealName, gtime.Now()), fmt.Sprintf("Id='%v'", req.BillId)) if err != nil { tx.Rollback() return err } _, err = tx.Update("settle_account_main", fmt.Sprintf("AccountStatus='1',SettleUserId='%v',SettleUser='%v',SettleDate='%v'", user.Id, user.RealName, gtime.Now()), fmt.Sprintf("BillId='%v'", req.BillId)) if err != nil { tx.Rollback() return err } _, err = tx.Update("base_account", fmt.Sprintf("Surplus=Surplus-%v", req.Amount), fmt.Sprintf("Id='%v'", req.AccountId)) if err != nil { tx.Rollback() return err } return tx.Commit() } // 确认 func (s Service) Confirm(req accountModel.AccountBillConfirmReq, user request.UserInfo) error { if req.BillId == 0 { return errors.New("参数缺失") } total,_ := s.Dao.DB.Model("settle_account_main").Where(fmt.Sprintf("BillId='%v' And SettleStatus='0'",req.BillId)).Count() if total>0 { return errors.New("实验明细有未确认项") } _, err := s.Dao.Update(fmt.Sprintf("Status='1',VerificationUserId='%v',VerificationUser='%v',VerificationDate='%v'", user.Id, user.RealName, gtime.Now()), fmt.Sprintf("Id='%v'", req.BillId)) return err } // 自动生成账单 func (s Service) GenerateBill() error { var rules []Param var rule1 Param var rule2 Param var rule3 Param var mains []accountModel.SettleAccountMain //var details []accountModel.SettleAccountDetail var accounts []accountModel.BaseAccount var auto AutoConfirmRecord mainMap := make(map[int][]accountModel.SettleAccountMain, 0) //detailMap := make(map[int][]accountModel.SettleAccountDetail, 0) accountMap := make(map[int]accountModel.BaseAccount, 0) now := gtime.Now() all, err := s.Dao.DB.Model("base_param").Where("Name='已出账单生成日期' OR Name='账单明细自动确认天数' OR Name='付款截止日期参数'").FindAll() if err != nil { return err } err = all.Structs(&rules) if err != nil { if err == sql.ErrNoRows { return errors.New("参数未配置") } return err } for _, item := range rules { if item.Name == "已出账单生成日期" { rule1 = item continue } if item.Name == "账单明细自动确认天数" { rule2 = item continue } if item.Name == "付款截止日期参数" { rule3 = item continue } } if rule1.Id == 0 || rule2.Id == 0 || rule3.Id == 0 { return errors.New("参数未配置") } all, err = s.Dao.DB.Model("base_account").FindAll() if err != nil { return err } err = all.Structs(&accounts) if err != nil { return err } for _, item := range accounts { if accountMap[item.MainUserId].Id == 0 { accountMap[item.MainUserId] = item } else if accountMap[item.MainUserId].MainUserId == item.MainUserId && (accountMap[item.MainUserId].Advance > item.Advance || (accountMap[item.MainUserId].Advance == item.Advance && accountMap[item.MainUserId].Id > item.Id)) { accountMap[item.MainUserId] = item } } pDay, _ := strconv.Atoi(rule1.Value) diffDay, _ := strconv.Atoi(rule2.Value) endDay, _ := strconv.Atoi(rule3.Value) if now.Day() != pDay { return nil } endDate := now.AddDate(0, 0, -1).Format("Y-m-d 23:59:59") startDate := now.AddDate(0, -1, 0).Format("Y-m-d 00:00:00") // appointment.Status:1 待审核;2 已通过;3 已拒绝;4 已取消;5 已过期;6 超时取消 all, err = s.Dao.DB.Model("settle_account_main").InnerJoin("appointment", "appointment.Id=settle_account_main.AppointId").Fields("settle_account_main.*").Where(fmt.Sprintf("settle_account_main.Status='0' AND ((appointment.Status=2 AND appointment.SignOutTime>='%v' AND appointment.SignOutTime<='%v') OR (appointment.Status=4 OR appointment.Status=6))", startDate, endDate)).FindAll() if err != nil { return err } err = all.Structs(&mains) if err != nil || len(mains) == 0 { if err == sql.ErrNoRows { return nil } return err } //all, err = s.Dao.DB.Model("settle_account_detail").Where(fmt.Sprintf("CreateOn>='%v' AND CreateOn<='%v'", startDate, endDate)).FindAll() //if err != nil { // return err //} //err = all.Structs(&details) //if err != nil { // return err //} for _, item := range mains { // 统计结算明细主表 if mainMap[item.MainUserId] == nil { mainMap[item.MainUserId] = make([]accountModel.SettleAccountMain, 0) } mainMap[item.MainUserId] = append(mainMap[item.MainUserId], item) } //for _, item := range details { // 统计结算明细子表 // if detailMap[item.Pid] == nil { // detailMap[item.Pid] = make([]accountModel.SettleAccountDetail, 0) // } // detailMap[item.Pid] = append(detailMap[item.Pid], item) //} tx, err := s.Dao.DB.Begin() if err != nil { return err } auto.BillIds = "-1" auto.AutoSettleDate = now.AddDate(0, 0, diffDay) for key, value := range mainMap { var bill accountModel.SettleAccountBill bill.PaymentDueDate = now.AddDate(0, 0, endDay) bill.StartDate = gtime.NewFromStr(startDate) bill.EndDate = gtime.NewFromStr(endDate) bill.MainUserId = key bill.MainUser = value[0].MainUser bill.AccountId = accountMap[bill.MainUserId].Id bill.Status = "0" ids := "-1" for _, item := range value { ids += fmt.Sprintf(",%v", item.Id) bill.TotalCount += item.TotalPrice } r, err := tx.Save("settle_account_bill", bill) if err != nil { tx.Rollback() return err } id, _ := r.LastInsertId() auto.BillIds += fmt.Sprintf(",%v", id) _, err = tx.Update("settle_account_main", fmt.Sprintf("BillId='%v',Status='1'", id), fmt.Sprintf("Id IN (%v)", ids)) if err != nil { tx.Rollback() return err } _, err = tx.Update("settle_account_detail", fmt.Sprintf("BillId='%v'", id), fmt.Sprintf("pid IN (%v)", ids)) if err != nil { tx.Rollback() return err } } _, err = tx.Save("auto_confirm_record", auto) // 自动确认辅助表 if err != nil { tx.Rollback() return err } return tx.Commit() } // 自动确认 func (s Service) AutoConfirm() error { now := gtime.Now() endDate := now.Format("Y-m-d 23:59:59") startDate := now.Format("Y-m-d 00:00:00") var autos []AutoConfirmRecord all, err := s.Dao.DB.Model("auto_confirm_record").Where(fmt.Sprintf("AutoSettleDate>='%v' AND AutoSettleDate<='%v'", startDate, endDate)).FindAll() if err != nil { return err } err = all.Structs(&autos) if err != nil { if err == sql.ErrNoRows { return nil } return err } if len(autos) == 0 { return nil } tx, err := s.Dao.DB.Begin() if err != nil { return err } ids := "-1" for _, item := range autos { ids += fmt.Sprintf(",%v", item.Id) _, err = tx.Update("settle_account_main", fmt.Sprintf("VerificationUserId=0,VerificationUser='系统自动确认',VerificationDate='%v',SettleStatus='1'", now.Format("Y-m-d H:i:s")), fmt.Sprintf("BillId IN (%v) AND (VerificationUser IS NULL OR VerificationUser='')", item.BillIds)) if err != nil { tx.Rollback() return err } } _, err = tx.Delete("auto_confirm_record", fmt.Sprintf("Id IN (%v)", ids)) if err != nil { tx.Rollback() return err } return tx.Commit() } type Param struct { Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` Sys string `protobuf:"bytes,5,opt,name=sys,proto3" json:"sys"` SortCode int32 `protobuf:"varint,6,opt,name=sort_code,json=sortCode,proto3" json:"sort_code"` Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"` CreateOn string `protobuf:"bytes,8,opt,name=create_on,json=createOn,proto3" json:"create_on,omitempty"` CreateUserId int32 `protobuf:"varint,9,opt,name=create_user_id,json=createUserId,proto3" json:"create_user_id,omitempty"` CreateBy string `protobuf:"bytes,10,opt,name=create_by,json=createBy,proto3" json:"create_by,omitempty"` ModifiedOn string `protobuf:"bytes,11,opt,name=modified_on,json=modifiedOn,proto3" json:"modified_on,omitempty"` ModifiedUserId int32 `protobuf:"varint,12,opt,name=modified_user_id,json=modifiedUserId,proto3" json:"modified_user_id,omitempty"` ModifiedBy string `protobuf:"bytes,13,opt,name=modified_by,json=modifiedBy,proto3" json:"modified_by,omitempty"` } // auto_confirm_record type AutoConfirmRecord struct { Id int `orm:"Id,primary" json:"id"` // 主键 BillIds string `orm:"BillIds" json:"bill_ids"` // 账单Ids AutoSettleDate *gtime.Time `orm:"AutoSettleDate" json:"auto_settle_date"` // 自动确认时间 }