electricity_bill_calc_service/service/report.go

163 lines
3.9 KiB
Go

package service
import (
"electricity_bill_calc/global"
"electricity_bill_calc/model"
"electricity_bill_calc/utils"
"time"
"github.com/google/uuid"
"github.com/shopspring/decimal"
"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 := utils.Reduce(
parks,
make(map[string]model.ParkNewestReport, 0),
func(acc map[string]model.ParkNewestReport, elem model.ParkNewestReport) 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
},
)
return utils.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 := utils.Reduce(
reports,
false,
func(acc bool, elem model.Report) bool {
if elem.Period.Equal(period) {
return acc || true
} else {
return acc || false
}
},
)
if exists {
return false, nil
}
// 检查给定的期数与目前已发布的最大期数的关系
maxPublished := utils.Reduce(
reports,
nil,
func(acc *time.Time, elem model.Report) *time.Time {
if elem.Published {
if acc == nil || (acc != nil && elem.Period.After(*acc)) {
return &elem.Period
}
}
return acc
},
)
// 检查给定的期数与目前未发布的最大期数的关系
maxUnpublished := utils.Reduce(
reports,
nil,
func(acc *time.Time, elem model.Report) *time.Time {
if acc == nil || (acc != nil && elem.Period.After(*acc)) {
return &elem.Period
}
return acc
},
)
if maxUnpublished == nil {
return true, nil
}
if maxPublished != nil && maxUnpublished.Equal(*maxPublished) {
// 此时不存在未发布的报表
return utils.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) RetreiveParkSummary(rid string) (*model.ReportSummary, error) {
var summary = new(model.ReportSummary)
_, err := global.DBConn.ID(rid).Get(summary)
if err != nil {
return nil, err
}
return summary, nil
}
func (_ReportService) CheckSummaryOverall(summary model.ReportSummary) bool {
var sum = decimal.Sum(summary.Critical, summary.Peak, summary.Valley)
return sum.LessThan(summary.Overall)
}