electricity_bill_calc_service/service/report.go

245 lines
6.1 KiB
Go

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
}
func (_ReportService) UpdateMaintenanceFee(feeId string, updates map[string]interface{}) (err error) {
_, err = global.DBConn.Table(new(model.WillDilutedFee)).ID(feeId).Update(updates)
return
}