package service import ( "electricity_bill_calc/exceptions" "electricity_bill_calc/global" "electricity_bill_calc/model" "electricity_bill_calc/tools" "time" "github.com/fufuok/utils" "github.com/google/uuid" "github.com/samber/lo" "xorm.io/builder" ) type _ReportService struct{} var ReportService _ReportService func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewestReport, error) { parks := make([]model.ParkNewestReport, 0) err := global.DBConn. Alias("p"). Join("LEFT", []string{"report", "r"}, "r.park_id=p.id"). Where(builder.Eq{"p.user_id": uid, "p.enabled": true}). Find(&parks) if err != nil { return make([]model.ParkNewestReport, 0), err } reducedParks := lo.Reduce( parks, func(acc map[string]model.ParkNewestReport, elem model.ParkNewestReport, index int) map[string]model.ParkNewestReport { if v, ok := acc[elem.Park.Id]; ok { if elem.Report != nil { if v.Report == nil || (elem.Report.Period.After(v.Report.Period)) { acc[elem.Park.Id] = elem } } } else { acc[elem.Park.Id] = elem } return acc }, make(map[string]model.ParkNewestReport, 0), ) return lo.Values(reducedParks), nil } func (_ReportService) IsNewPeriodValid(uid string, period time.Time) (bool, error) { reports := make([]model.Report, 0) err := global.DBConn. Table("report").Alias("r"). Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). Where(builder.Eq{"p.user_id": uid}). Find(&reports) if err != nil { return false, nil } // 检查给定的期数在目前的记录中是否已经存在 exists := lo.Reduce( reports, func(acc bool, elem model.Report, index int) bool { if elem.Period.Equal(period) { return acc || true } else { return acc || false } }, false, ) if exists { return false, nil } // 检查给定的期数与目前已发布的最大期数的关系 maxPublished := lo.Reduce( reports, func(acc *time.Time, elem model.Report, index int) *time.Time { if elem.Published { if acc == nil || (acc != nil && elem.Period.After(*acc)) { return &elem.Period } } return acc }, nil, ) // 检查给定的期数与目前未发布的最大期数的关系 maxUnpublished := lo.Reduce( reports, func(acc *time.Time, elem model.Report, index int) *time.Time { if acc == nil || (acc != nil && elem.Period.After(*acc)) { return &elem.Period } return acc }, nil, ) if maxUnpublished == nil { return true, nil } if maxPublished != nil && maxUnpublished.Equal(*maxPublished) { // 此时不存在未发布的报表 return tools.IsNextMonth(*maxPublished, period), nil } else { // 存在未发布的报表 return false, nil } } func (_ReportService) InitializeNewReport(parkId string, period time.Time) (err error) { newReport := model.Report{ Id: uuid.New().String(), ParkId: parkId, StepState: model.NewSteps(), Published: false, Withdraw: model.REPORT_NOT_WITHDRAW, } newReportSummary := model.ReportSummary{ ReportId: newReport.Id, } tx := global.DBConn.NewSession() if err = tx.Begin(); err != nil { return } defer tx.Close() _, err = tx.Insert(newReport, newReportSummary) if err != nil { tx.Rollback() return } err = tx.Commit() if err != nil { tx.Rollback() return } return nil } func (_ReportService) RetreiveReportIndex(rid string) (*model.Report, error) { reports := make([]model.Report, 0) err := global.DBConn.Where(builder.Eq{"id": rid}).Find(&reports) if err != nil { return nil, err } if len(reports) > 0 { return &reports[0], nil } else { return nil, nil } } func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, error) { var summary = new(model.ReportSummary) _, err := global.DBConn.ID(rid).NoAutoCondition().Get(summary) if err != nil { return nil, err } return summary, nil } func (_ReportService) UpdateReportSummary(summary *model.ReportSummary) error { _, err := global.DBConn.ID(summary.ReportId).Cols("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee").Update(summary) return err } func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error { var report = new(model.Report) has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(report) if err != nil { return err } if !has { return exceptions.NewNotFoundError("未找到指定报表") } var summary = new(model.ReportSummary) has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary) if err != nil { return err } if !has { return exceptions.NewNotFoundError("未找到指定报表的园区概况") } tx := global.DBConn.NewSession() if err = tx.Begin(); err != nil { return err } defer tx.Close() summary.CalculatePrices() _, err = tx.ID(summary.ReportId).Cols("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price").Update(summary) if err != nil { tx.Rollback() return err } report.StepState.Summary = true _, err = tx.ID(report.Id).Cols("step_state").Update(report) if err != nil { tx.Rollback() return err } err = tx.Commit() if err != nil { tx.Rollback() return err } return nil } func (_ReportService) FetchWillDulutedMaintenanceFees(reportId string) ([]model.WillDilutedFee, error) { fees := make([]model.WillDilutedFee, 0) err := global.DBConn.Where(builder.Eq{"report_id": reportId}).Asc("created_at").Find(&fees) if err != nil { return make([]model.WillDilutedFee, 0), nil } return fees, nil } func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error { fee.Id = utils.UUIDString() _, err := global.DBConn.Insert(fee) return err } func (_ReportService) BatchSaveMaintenanceFee(fees []model.WillDilutedFee) error { tx := global.DBConn.NewSession() if err := tx.Begin(); err != nil { return err } defer tx.Close() _, err := tx.Insert(fees) if err != nil { return err } err = tx.Commit() if err != nil { tx.Rollback() return err } return nil }