Compare commits
42 Commits
b59e24333e
...
0f91b8a332
Author | SHA1 | Date | |
---|---|---|---|
0f91b8a332 | |||
59a604bab0 | |||
eaf45331f1 | |||
2844db1a86 | |||
7d3fafeb04 | |||
032d38181a | |||
292a50029f | |||
de176ce61d | |||
8a383515d3 | |||
37bd0da1f2 | |||
bfa7ac1508 | |||
3f36153968 | |||
845bd75348 | |||
559c2d439d | |||
d6829fce27 | |||
d1e8c63ec9 | |||
e229f3976d | |||
683907b363 | |||
c1b84d1fbb | |||
2021d67d03 | |||
b988ffcb75 | |||
361b302407 | |||
d8f470e660 | |||
c472eb4196 | |||
98866a8de5 | |||
c89a5f20ad | |||
01e944cb5a | |||
c2d43bd98e | |||
a543b33276 | |||
6289257ac1 | |||
5d997c14ee | |||
b50eabbca6 | |||
a34aa6ad07 | |||
3d918eea85 | |||
7f46f2f36b | |||
ed10996a06 | |||
2aa3729e03 | |||
7d59121c2f | |||
b2efb972dc | |||
5f750dd0e0 | |||
dd6becc994 | |||
00cf35ec2a |
@ -12,12 +12,11 @@ import (
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var meterLog = logger.Named("Handler", "Meter")
|
||||
@ -54,7 +53,8 @@ func searchMetersWithinPark(c *fiber.Ctx) error {
|
||||
}
|
||||
keyword := c.Query("keyword")
|
||||
page := c.QueryInt("page", 1)
|
||||
meters, total, err := repository.MeterRepository.MetersIn(parkId, uint(page), &keyword)
|
||||
mtype := c.QueryInt("type", 3)
|
||||
meters, total, err := repository.MeterRepository.MetersIn(parkId, uint(page), &keyword, mtype)
|
||||
if err != nil {
|
||||
meterLog.Error("无法查询指定园区下的表计信息,无法获取表计列表", zap.Error(err))
|
||||
return result.Error(http.StatusInternalServerError, err.Error())
|
||||
@ -100,6 +100,7 @@ func createNewMeterManually(c *fiber.Ctx) error {
|
||||
meterLog.Error("无法手动添加一条0.4kV表计记录,无法解析表计创建表单", zap.Error(err))
|
||||
return result.NotAccept(err.Error())
|
||||
}
|
||||
|
||||
if err := service.MeterService.CreateMeterRecord(parkId, &creationForm); err != nil {
|
||||
meterLog.Error("无法手动添加一条0.4kV表计记录,无法创建表计记录", zap.Error(err))
|
||||
return result.NotAccept(err.Error())
|
||||
@ -201,7 +202,12 @@ func replaceMeter(c *fiber.Ctx) error {
|
||||
meterLog.Error("无法更换系统中的表计,无法解析表计更换表单", zap.Error(err))
|
||||
return result.NotAccept(err.Error())
|
||||
}
|
||||
return nil
|
||||
err := service.MeterService.ReplaceMeter(parkId, meterId, &replacementForm.OldReading, replacementForm.NewMeter.Code, replacementForm.NewMeter.Ratio, &replacementForm.NewMeter.Reading)
|
||||
if err != nil {
|
||||
meterLog.Error("更换表计出错1111", zap.Error(err))
|
||||
return result.Error(500, err.Error())
|
||||
}
|
||||
return result.Success("更换成功")
|
||||
}
|
||||
|
||||
// 列出指定公摊表计下的所有关联表计
|
||||
@ -349,6 +355,7 @@ func listUnboundTenementMeters(c *fiber.Ctx) error {
|
||||
func queryMeterReadings(c *fiber.Ctx) error {
|
||||
result := response.NewResult(c)
|
||||
parkId := c.Params("pid")
|
||||
mtype := c.QueryInt("type", 3)
|
||||
if pass, err := checkParkBelongs(parkId, meterLog, c, &result); !pass {
|
||||
return err
|
||||
}
|
||||
@ -373,7 +380,7 @@ func queryMeterReadings(c *fiber.Ctx) error {
|
||||
endDate = &parsedDate
|
||||
}
|
||||
}
|
||||
readings, total, err := service.MeterService.SearchMeterReadings(parkId, building, startDate, endDate, uint(page), keyword)
|
||||
readings, total, err := service.MeterService.SearchMeterReadings(parkId, building, startDate, endDate, uint(page), keyword, uint(mtype))
|
||||
if err != nil {
|
||||
meterLog.Error("查询指定园区中的表计读数,无法获取表计读数列表", zap.Error(err))
|
||||
return result.Error(http.StatusInternalServerError, err.Error())
|
||||
|
@ -187,7 +187,7 @@ func deleteSpecificPark(c *fiber.Ctx) error {
|
||||
parkLog.Error("无法删除园区。", zap.String("park id", parkId), zap.String("user id", session.Uid), zap.Error(err))
|
||||
return result.Error(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return result.Deleted("已删除指定的园区")
|
||||
return result.Success("已删除指定的园区")
|
||||
}
|
||||
|
||||
// 列出指定园区中已经登记的建筑
|
||||
|
@ -11,6 +11,9 @@ import (
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/samber/lo"
|
||||
@ -244,8 +247,28 @@ func getReportSummary(c *fiber.Ctx) error {
|
||||
reportLog.Error("未找到核算报表的总览信息")
|
||||
return result.NotFound("未找到核算报表的总览信息。")
|
||||
}
|
||||
var summaryResponse vo.ParkSummaryResponse
|
||||
copier.Copy(&summaryResponse, report)
|
||||
summaryResponse := vo.ParkSummaryResponse{
|
||||
ReportId: report.ReportId,
|
||||
OverallDisplay: vo.ConsumptionDisplay{
|
||||
AmountStr: strconv.FormatFloat(report.Overall.Amount.InexactFloat64(), 'f', -1, 64),
|
||||
FeeStr: strconv.FormatFloat(report.Overall.Fee.InexactFloat64(), 'f', -1, 64),
|
||||
PriceStr: strconv.FormatFloat(report.Overall.Price.InexactFloat64(), 'f', -1, 64),
|
||||
ProportionStr: strconv.FormatFloat(report.Overall.Proportion.InexactFloat64(), 'f', -1, 64),
|
||||
},
|
||||
Area: report.OverallArea,
|
||||
BasicFee: report.BasicFee,
|
||||
PooledBasicFeeByAmount: report.BasicPooledPriceConsumption.Decimal,
|
||||
PooledBasicFeeByArea: report.BasicPooledPriceArea.Decimal,
|
||||
AdjustFee: report.AdjustFee,
|
||||
PooledAdjustFeeByAmount: report.AdjustPooledPriceConsumption.Decimal,
|
||||
PooledAdjustFeeByArea: report.AdjustPooledPriceArea.Decimal,
|
||||
Consumption: report.ConsumptionFee.Decimal,
|
||||
//Loss: report.Loss.Decimal,
|
||||
Loss: report.AuthorizeLoss.Amount,
|
||||
//LossRate: report.LossFee.Decimal,
|
||||
LossRate: report.AuthorizeLoss.Proportion,
|
||||
}
|
||||
//copier.Copy(&summaryResponse, report)
|
||||
return result.Success(
|
||||
"已经获取到核算报表的总览信息。",
|
||||
fiber.Map{"summary": summaryResponse},
|
||||
@ -264,15 +287,45 @@ func listPublicMetersInReport(c *fiber.Ctx) error {
|
||||
reportLog.Error("无法获取核算报表中的公共表计信息", zap.Error(err))
|
||||
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公共表计信息。")
|
||||
}
|
||||
meterResponse := lo.Map(meters, func(meter *model.ReportDetailedPublicConsumption, _ int) *vo.ReportPublicQueryResponse {
|
||||
m := &vo.ReportPublicQueryResponse{}
|
||||
m.FromReportDetailPublicConsumption(meter)
|
||||
return m
|
||||
})
|
||||
|
||||
var meterResponses []vo.Public
|
||||
for _, meter := range meters {
|
||||
meterResponse := vo.Public{
|
||||
Address: meter.Address,
|
||||
AdjustLoss: model.ConsumptionUnit{
|
||||
Amount: meter.LossAdjust.Amount,
|
||||
Fee: meter.LossAdjust.Fee,
|
||||
Price: meter.LossAdjust.Price,
|
||||
Proportion: meter.LossAdjust.Proportion,
|
||||
},
|
||||
Area: meter.Area.Decimal.String(),
|
||||
AttachedAt: meter.AttachedAt,
|
||||
Building: meter.Building,
|
||||
BuildingName: meter.BuildingName,
|
||||
Code: meter.ParkMeterID,
|
||||
DetachedAt: meter.DetachedAt,
|
||||
DisplayRatio: strconv.FormatFloat(meter.DisplayRatio, 'f', -1, 64),
|
||||
Enabled: meter.Enabled,
|
||||
OnFloor: meter.OnFloor,
|
||||
Overall: model.ConsumptionUnit{
|
||||
Amount: meter.Overall.Amount,
|
||||
Fee: meter.Overall.Fee,
|
||||
Price: meter.Overall.Price,
|
||||
Proportion: meter.Overall.Proportion,
|
||||
},
|
||||
ParkID: meter.ParkID,
|
||||
Ratio: meter.Ratio.String(),
|
||||
Seq: meter.Seq,
|
||||
Type: float64(meter.MeterType),
|
||||
}
|
||||
|
||||
meterResponses = append(meterResponses, meterResponse)
|
||||
}
|
||||
|
||||
return result.Success(
|
||||
"已经获取到指定核算报表中的分页公共表计的核算信息。",
|
||||
response.NewPagedResponse(page, total).ToMap(),
|
||||
fiber.Map{"public": meterResponse},
|
||||
fiber.Map{"public": meterResponses},
|
||||
)
|
||||
}
|
||||
|
||||
@ -394,7 +447,7 @@ func reportComprehensiveSearch(c *fiber.Ctx) error {
|
||||
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||
return result.Unauthorized("无法获取当前用户的会话信息。")
|
||||
}
|
||||
park := tools.EmptyToNil(c.Query("park_id"))
|
||||
park := tools.EmptyToNil(c.Query("park"))
|
||||
if session.Type == model.USER_TYPE_ENT && park != nil && len(*park) > 0 {
|
||||
if pass, err := checkParkBelongs(*park, reportLog, c, &result); !pass {
|
||||
return err
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
|
||||
var tenementLog = logger.Named("Handler", "Tenement")
|
||||
|
||||
func InitializeTenementHandler(router *fiber.App) {
|
||||
func InitializeTenementHandler(router *fiber.App) {
|
||||
router.Get("/tenement/choice", security.EnterpriseAuthorize, listTenementForChoice)
|
||||
router.Get("/tenement/:pid", security.EnterpriseAuthorize, listTenement)
|
||||
router.Put("/tenement/:pid/:tid", security.EnterpriseAuthorize, updateTenement)
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"electricity_bill_calc/tools"
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/jinzhu/copier"
|
||||
@ -136,7 +137,8 @@ func deleteTopUp(c *fiber.Ctx) error {
|
||||
topUpLog.Error("删除一条指定的商户充值记录,删除失败", zap.Error(err))
|
||||
return result.NotAccept("商户充值记录删除不成功")
|
||||
}
|
||||
return result.Deleted(
|
||||
fmt.Println("已经删除一条指定的商户充值记录")
|
||||
return result.Success(
|
||||
"已经删除一条指定的商户充值记录",
|
||||
)
|
||||
}
|
||||
|
@ -24,23 +24,23 @@ type Pooling struct {
|
||||
}
|
||||
|
||||
type Meter struct {
|
||||
Code string
|
||||
Detail model.MeterDetail
|
||||
CoveredArea decimal.Decimal
|
||||
LastTermReading *Reading
|
||||
CurrentTermReading *Reading
|
||||
Overall model.ConsumptionUnit
|
||||
Critical model.ConsumptionUnit
|
||||
Peak model.ConsumptionUnit
|
||||
Flat model.ConsumptionUnit
|
||||
Valley model.ConsumptionUnit
|
||||
AdjustLoss model.ConsumptionUnit
|
||||
PooledBasic model.ConsumptionUnit
|
||||
PooledAdjust model.ConsumptionUnit
|
||||
PooledLoss model.ConsumptionUnit
|
||||
PooledPublic model.ConsumptionUnit
|
||||
SharedPoolingProportion decimal.Decimal
|
||||
Poolings []*Pooling
|
||||
Code string `json:"code"`
|
||||
Detail model.MeterDetail `json:"detail"`
|
||||
CoveredArea decimal.Decimal `json:"covered_area"`
|
||||
LastTermReading *Reading `json:"last_term_reading"`
|
||||
CurrentTermReading *Reading `json:"current_term_reading"`
|
||||
Overall model.ConsumptionUnit `json:"overall"`
|
||||
Critical model.ConsumptionUnit `json:"critical"`
|
||||
Peak model.ConsumptionUnit `json:"peak"`
|
||||
Flat model.ConsumptionUnit `json:"flat"`
|
||||
Valley model.ConsumptionUnit `json:"valley"`
|
||||
AdjustLoss model.ConsumptionUnit `json:"adjust_loss"`
|
||||
PooledBasic model.ConsumptionUnit `json:"pooled_basic"`
|
||||
PooledAdjust model.ConsumptionUnit `json:"pooled_adjust"`
|
||||
PooledLoss model.ConsumptionUnit `json:"pooled_loss"`
|
||||
PooledPublic model.ConsumptionUnit `json:"pooled_public"`
|
||||
SharedPoolingProportion decimal.Decimal `json:"shared_pooling_proportion"`
|
||||
Poolings []*Pooling `json:"poolings"`
|
||||
}
|
||||
|
||||
type PrimaryTenementStatistics struct {
|
||||
@ -49,20 +49,20 @@ type PrimaryTenementStatistics struct {
|
||||
}
|
||||
|
||||
type TenementCharge struct {
|
||||
Tenement string
|
||||
Overall model.ConsumptionUnit
|
||||
Critical model.ConsumptionUnit
|
||||
Peak model.ConsumptionUnit
|
||||
Flat model.ConsumptionUnit
|
||||
Valley model.ConsumptionUnit
|
||||
BasicFee decimal.Decimal
|
||||
AdjustFee decimal.Decimal
|
||||
LossPooled decimal.Decimal
|
||||
PublicPooled decimal.Decimal
|
||||
FinalCharges decimal.Decimal
|
||||
Loss decimal.Decimal
|
||||
Submeters []*Meter
|
||||
Poolings []*Meter
|
||||
Tenement string `json:"tenement"`
|
||||
Overall model.ConsumptionUnit `json:"overall"`
|
||||
Critical model.ConsumptionUnit `json:"critical"`
|
||||
Peak model.ConsumptionUnit `json:"peak"`
|
||||
Flat model.ConsumptionUnit `json:"flat"`
|
||||
Valley model.ConsumptionUnit `json:"valley"`
|
||||
BasicFee decimal.Decimal `json:"basic_fee"`
|
||||
AdjustFee decimal.Decimal `json:"adjust_fee"`
|
||||
LossPooled decimal.Decimal `json:"loss_pooled"`
|
||||
PublicPooled decimal.Decimal `json:"public_pooled"`
|
||||
FinalCharges decimal.Decimal `json:"final_charges"`
|
||||
Loss model.ConsumptionUnit `json:"loss"`
|
||||
Submeters []*Meter `json:"submeters"`
|
||||
Poolings []*Meter `json:"poolings"`
|
||||
}
|
||||
|
||||
type Summary struct {
|
||||
|
@ -32,7 +32,7 @@ type Park struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
LastModifiedAt time.Time `json:"lastModifiedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt"`
|
||||
NormAuthorizedLossRate float64 `json:"norm_authorized_loss_rate"`
|
||||
NormAuthorizedLossRate float64 `json:"normAuthorizedLoss"db:"norm_authorized_loss_rate"`
|
||||
}
|
||||
|
||||
type ParkPeriodStatistics struct {
|
||||
|
@ -122,6 +122,7 @@ type ReportTenement struct {
|
||||
Invoice []string `json:"invoice" db:"invoice"`
|
||||
Meters []NestedMeter `json:"meters" db:"meters"`
|
||||
Pooled []NestedMeter `json:"pooled" db:"pooled"`
|
||||
Loss ConsumptionUnit `json:"loss"` //TODO: 2023.08.11 测试时发现少一个字段(已补全)
|
||||
}
|
||||
|
||||
type ReportTask struct {
|
||||
|
@ -7,7 +7,7 @@ type Tenement struct {
|
||||
Park string `json:"parkId" db:"park_id"`
|
||||
FullName string `json:"fullName" db:"full_name"`
|
||||
ShortName *string `json:"shortName" db:"short_name"`
|
||||
Abbr string `json:"-"`
|
||||
Abbr string `json:"abbr"`
|
||||
Address string `json:"address"`
|
||||
ContactName string `json:"contactName" db:"contact_name"`
|
||||
ContactPhone string `json:"contactPhone" db:"contact_phone"`
|
||||
|
@ -1,6 +1,7 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"electricity_bill_calc/global"
|
||||
"electricity_bill_calc/logger"
|
||||
"electricity_bill_calc/model"
|
||||
@ -12,8 +13,6 @@ import (
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/shopspring/decimal"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
@ -32,18 +31,26 @@ var CalculateRepository = _CalculateRepository{
|
||||
ds: goqu.Dialect("postgres"),
|
||||
}
|
||||
|
||||
//更新当前报表的核算状态
|
||||
// 更新当前报表的核算状态
|
||||
func (cr _CalculateRepository) UpdateReportCalculateStatus(rid string, status string,
|
||||
message string) (bool, error) {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
var atio int
|
||||
var err error
|
||||
|
||||
currentTime := time.Now()
|
||||
if status == "success" {
|
||||
atio = 1 //创建报表成功
|
||||
} else {
|
||||
atio = 2 // 数据不足
|
||||
}
|
||||
|
||||
updateResultSql, updateResultArgs, _ := cr.ds.
|
||||
Update(goqu.T("report_task")).
|
||||
Set(goqu.Record{
|
||||
"status": status,
|
||||
"status": int16(atio),
|
||||
"last_modified_at": currentTime,
|
||||
"message": message,
|
||||
}).Where(goqu.I("id").Eq(rid)).
|
||||
@ -124,7 +131,7 @@ func (cr _CalculateRepository) GetAllPoolingMeterRelations(pid string, revokedAf
|
||||
|
||||
var meterRelation []model.MeterRelation
|
||||
|
||||
err := pgxscan.Select(ctx, global.DB, meterRelation, relationsSql, relationsArgs...)
|
||||
err := pgxscan.Select(ctx, global.DB, &meterRelation, relationsSql, relationsArgs...)
|
||||
if err != nil {
|
||||
cr.log.Error("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的出错", zap.Error(err))
|
||||
return nil, err
|
||||
@ -142,21 +149,24 @@ func (cr _CalculateRepository) GetAllTenementMeterRelations(pid string, associat
|
||||
From(goqu.T("tenement_meter")).
|
||||
Where(goqu.I("park_id").Eq(pid)).
|
||||
Where(goqu.And(
|
||||
goqu.I("associated_at").IsNull(),
|
||||
goqu.I("associated_at").IsNotNull(),
|
||||
goqu.I("associated_at").Lte(associatedBefore),
|
||||
)).
|
||||
Where(goqu.And(
|
||||
goqu.I("associated_at").IsNull(),
|
||||
goqu.I("associated_at").Gte(disassociatedAfter),
|
||||
goqu.Or(
|
||||
goqu.I("disassociated_at").IsNull(),
|
||||
goqu.I("disassociated_at").Gte(disassociatedAfter),
|
||||
),
|
||||
)).ToSQL()
|
||||
|
||||
var tenementMeter []model.TenementMeter
|
||||
|
||||
err := pgxscan.Select(ctx, global.DB, tenementMeter, relationsQuerySql, relationsQueryArgs...)
|
||||
err := pgxscan.Select(ctx, global.DB, &tenementMeter, relationsQuerySql, relationsQueryArgs...)
|
||||
if err != nil {
|
||||
cr.log.Error("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
fmt.Println("==", tenementMeter)
|
||||
return tenementMeter, nil
|
||||
|
||||
}
|
||||
@ -178,13 +188,13 @@ func (cr _CalculateRepository) GetMeterReadings(rid string, meterType int16) ([]
|
||||
goqu.I("r.id").Eq(rid),
|
||||
goqu.I("mr.meter_type").Eq(meterType),
|
||||
// TODO:2023.08.02 此方法出错优先查看是否这里出问题
|
||||
goqu.I("mr.read_at::date <@ r.period"),
|
||||
goqu.L("?::date <@ ?", goqu.I("mr.read_at"), goqu.I("r.period")),
|
||||
).
|
||||
Order(goqu.I("mr.read_at").Asc()).Select(goqu.I("mr.*")).ToSQL()
|
||||
|
||||
var readings []model.MeterReading
|
||||
|
||||
err := pgxscan.Select(ctx, global.DB, readings, readingsQuerySql, readingsQueryArgs...)
|
||||
err := pgxscan.Select(ctx, global.DB, &readings, readingsQuerySql, readingsQueryArgs...)
|
||||
if err != nil {
|
||||
cr.log.Error("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据出错", zap.Error(err))
|
||||
return nil, err
|
||||
@ -199,7 +209,8 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
readingsSql, readingsArgs, _ := cr.ds.From(goqu.T("meter_reading").As("mr")).
|
||||
readingsSql, readingsArgs, _ := cr.ds.
|
||||
From(goqu.T("meter_reading").As("mr")).
|
||||
Select(
|
||||
goqu.MAX("mr.read_at").As("read_at"),
|
||||
goqu.I("mr.park_id"),
|
||||
@ -219,7 +230,7 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
|
||||
Where(
|
||||
goqu.I("r.id").Eq(rid),
|
||||
goqu.I("mr.meter_type").Eq(meterType),
|
||||
goqu.I(" mr.read_at::date <= lower(r.period)"),
|
||||
goqu.L(" read_at <= lower(r.period)"),
|
||||
).
|
||||
GroupBy(
|
||||
goqu.I("mr.park_id"),
|
||||
@ -235,11 +246,12 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
|
||||
).ToSQL()
|
||||
|
||||
var readings []model.MeterReading
|
||||
err := pgxscan.Select(ctx, global.DB, readings, readingsSql, readingsArgs...)
|
||||
err := pgxscan.Select(ctx, global.DB, &readings, readingsSql, readingsArgs...)
|
||||
if err != nil {
|
||||
cr.log.Error("获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数出错", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readings, nil
|
||||
}
|
||||
|
||||
@ -266,11 +278,11 @@ func (cr _CalculateRepository) GetAllTenements(rid string) ([]model.Tenement, er
|
||||
).
|
||||
Where(
|
||||
goqu.I("r.id").Eq(rid),
|
||||
goqu.I("t.moved_in_at <= upper(r.period)"),
|
||||
goqu.L("t.moved_in_at <= upper(r.period)"),
|
||||
).ToSQL()
|
||||
|
||||
fmt.Println(tenementQuerySql)
|
||||
var tenements []model.Tenement
|
||||
err := pgxscan.Select(ctx, global.DB, tenements, tenementQuerySql, tenementQueryArgs...)
|
||||
err := pgxscan.Select(ctx, global.DB, &tenements, tenementQuerySql, tenementQueryArgs...)
|
||||
if err != nil {
|
||||
cr.log.Error("取得指定报表所涉及的所有商户信息出错", zap.Error(err))
|
||||
return nil, err
|
||||
@ -309,52 +321,59 @@ func (cr _CalculateRepository) ClearReportContent(tx pgx.Tx, rid string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, rid string, meters []calculate.Meter) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, ctx context.Context, rid string, meters []calculate.Meter) error {
|
||||
if len(meters) == 0 {
|
||||
// 如果没有公共表计则直接返回
|
||||
return nil
|
||||
}
|
||||
// 准备插入表达式
|
||||
insertExpr := cr.ds.Insert("report_public_consumption").
|
||||
Cols(
|
||||
"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley",
|
||||
"loss_adjust", "consumption_total", "loss_adjust_total", "final_total",
|
||||
).Prepared(true)
|
||||
// 添加值到插入表达式中
|
||||
|
||||
for _, meter := range meters {
|
||||
insertExpr = insertExpr.Vals([]interface{}{
|
||||
// 准备插入表达式
|
||||
insertExpr := cr.ds.Insert("report_public_consumption").
|
||||
Cols(
|
||||
"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley",
|
||||
"loss_adjust", "consumption_total", "loss_adjust_total", "final_total",
|
||||
)
|
||||
// 添加值到插入表达式中
|
||||
overall, _ := json.Marshal(meter.Overall)
|
||||
criyical, _ := json.Marshal(meter.Critical)
|
||||
peak, _ := json.Marshal(meter.Peak)
|
||||
flat, _ := json.Marshal(meter.Flat)
|
||||
valley, _ := json.Marshal(meter.Valley)
|
||||
adjustLoss, _ := json.Marshal(meter.AdjustLoss)
|
||||
insertExpr = insertExpr.Vals(goqu.Vals{
|
||||
rid,
|
||||
meter.Code,
|
||||
meter.Overall.Fee,
|
||||
meter.Critical.Fee,
|
||||
meter.Peak.Fee,
|
||||
meter.Flat.Fee,
|
||||
meter.Valley.Fee,
|
||||
meter.AdjustLoss.Fee,
|
||||
overall,
|
||||
criyical,
|
||||
peak,
|
||||
flat,
|
||||
valley,
|
||||
adjustLoss,
|
||||
meter.Overall.Fee,
|
||||
meter.AdjustLoss.Fee,
|
||||
meter.Overall.Fee.Add(meter.AdjustLoss.Fee),
|
||||
})
|
||||
}
|
||||
|
||||
// 执行插入语句
|
||||
inserSql, insertArgs, err := insertExpr.Prepared(true).ToSQL()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(ctx, inserSql, insertArgs); err != nil {
|
||||
return fmt.Errorf("保存报表核算概要失败: %w", err)
|
||||
// 执行插入语句
|
||||
inserSql, insertArgs, _ := insertExpr.ToSQL()
|
||||
_, err := tx.Exec(ctx, inserSql, insertArgs...)
|
||||
if err != nil {
|
||||
_ = tx.Rollback(ctx)
|
||||
return fmt.Errorf("保存报表核算概要失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Summary) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, ctx context.Context, summary calculate.Summary) error {
|
||||
// 构建插入表达式
|
||||
insertsql, insertArgs, _ := cr.ds.Insert("report_summary").
|
||||
Overall, _ := json.Marshal(summary.Overall)
|
||||
Critical, _ := json.Marshal(summary.Critical)
|
||||
Peak, _ := json.Marshal(summary.Peak)
|
||||
Flat, _ := json.Marshal(summary.Flat)
|
||||
Valley, _ := json.Marshal(summary.Valley)
|
||||
AuthoizeLoss, _ := json.Marshal(summary.AuthoizeLoss)
|
||||
insertsql, insertArgs, err := cr.ds.Insert(goqu.T("report_summary")).
|
||||
Cols(
|
||||
"report_id", "overall", "critical", "peak", "flat", "valley",
|
||||
"loss", "loss_fee", "basic_fee", "basic_pooled_price_consumption", "basic_pooled_price_area",
|
||||
@ -363,16 +382,18 @@ func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Su
|
||||
"consumption_fee", "authorize_loss", "overall_area", "total_consumption",
|
||||
).
|
||||
Vals(goqu.Vals{
|
||||
summary.ReportId, summary.Overall, summary.Critical, summary.Peak, summary.Flat,
|
||||
summary.Valley, summary.Loss, summary.LossFee, summary.BasicFee,
|
||||
summary.ReportId, Overall, Critical, Peak, Flat,
|
||||
Valley, summary.Loss, summary.LossFee, summary.BasicFee,
|
||||
summary.BasicPooledPriceConsumption, summary.BasicPooledPriceArea,
|
||||
summary.AdjustFee, summary.AdjustPooledPriceConsumption, summary.AdjustPooledPriceArea,
|
||||
summary.LossDilutedPrice, summary.LossProportion, summary.FinalDilutedOverall,
|
||||
summary.ConsumptionFee, summary.AuthoizeLoss, summary.OverallArea, summary.TotalConsumption,
|
||||
}).Prepared(true).ToSQL()
|
||||
|
||||
summary.ConsumptionFee, AuthoizeLoss, summary.OverallArea, summary.TotalConsumption,
|
||||
}).ToSQL()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
// 执行插入语句
|
||||
|
||||
if _, err := tx.Exec(ctx, insertsql, insertArgs...); err != nil {
|
||||
cr.log.Error("保存报表核算概要失败。")
|
||||
return err
|
||||
@ -441,10 +462,15 @@ func (cr _CalculateRepository) SaveReportPoolings(tx pgx.Tx,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
overall, _ := json.Marshal(meter.Overall)
|
||||
criyical, _ := json.Marshal(meter.Critical)
|
||||
peak, _ := json.Marshal(meter.Peak)
|
||||
flat, _ := json.Marshal(meter.Flat)
|
||||
valley, _ := json.Marshal(meter.Valley)
|
||||
|
||||
insertQuery := goqu.Insert("report_pooled_consumption").
|
||||
Cols("report_id", "pooled_meter_id", "overall", "critical", "peak", "flat", "valley", "pooled_area", "diluted").
|
||||
Vals(goqu.Vals{rid, meter.Code, meter.Overall, meter.Critical, meter.Peak, meter.Flat, meter.Valley, meter.CoveredArea, submetersJSON})
|
||||
Vals(goqu.Vals{rid, meter.Code, overall, criyical, peak, flat, valley, meter.CoveredArea, submetersJSON})
|
||||
|
||||
insertQueries = append(insertQueries, *insertQuery)
|
||||
}
|
||||
@ -471,40 +497,55 @@ func (cr _CalculateRepository) SaveReportTenement(tx pgx.Tx, report model.Report
|
||||
cr.log.Info("保存商户报表。")
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
insertQuery := cr.ds.Insert("report_tenement").Prepared(true)
|
||||
values := []goqu.Record{}
|
||||
insertQuery := cr.ds.
|
||||
Insert("report_tenement")
|
||||
var rows []goqu.Record
|
||||
for _, tenement := range tenements {
|
||||
charge := findTenementCharge(tenementCharges, tenement.Id)
|
||||
values = append(values, goqu.Record{
|
||||
tenementCharge := findTenementCharge(tenementCharges, tenement.Id)
|
||||
|
||||
tenementDetail, _ := json.Marshal(tenement)
|
||||
overallJSON, _ := json.Marshal(tenementCharge.Overall)
|
||||
criticalJSON, _ := json.Marshal(tenementCharge.Critical)
|
||||
peakJSON, _ := json.Marshal(tenementCharge.Peak)
|
||||
flatJSON, _ := json.Marshal(tenementCharge.Flat)
|
||||
valleyJSON, _ := json.Marshal(tenementCharge.Valley)
|
||||
lossJSON, _ := json.Marshal(tenementCharge.Loss)
|
||||
submetersJSON, _ := json.Marshal(convertToNestedMeters(tenementCharge.Submeters))
|
||||
poolingsJSON, _ := json.Marshal(convertToNestedMeters(tenementCharge.Poolings))
|
||||
|
||||
row := goqu.Record{
|
||||
"report_id": report.Id,
|
||||
"tenement_id": tenement.Id,
|
||||
"tenement_detail": toJSONString(tenement),
|
||||
"tenement_detail": tenementDetail,
|
||||
"calc_period": report.Period,
|
||||
"overall": toJSONString(charge.Overall),
|
||||
"critical": toJSONString(charge.Critical),
|
||||
"peak": toJSONString(charge.Peak),
|
||||
"flat": toJSONString(charge.Flat),
|
||||
"valley": toJSONString(charge.Valley),
|
||||
"loss": toJSONString(charge.Loss),
|
||||
"basic_fee_pooled": charge.BasicFee,
|
||||
"adjust_fee_pooled": charge.AdjustFee,
|
||||
"loss_fee_pooled": charge.LossPooled,
|
||||
"final_pooled": charge.PublicPooled,
|
||||
"final_charge": charge.FinalCharges,
|
||||
"meters": toJSONString(convertToNestedMeters(charge.Submeters)),
|
||||
"pooled": toJSONString(convertToNestedMeters(charge.Poolings)),
|
||||
})
|
||||
"overall": overallJSON,
|
||||
"critical": criticalJSON,
|
||||
"peak": peakJSON,
|
||||
"flat": flatJSON,
|
||||
"valley": valleyJSON,
|
||||
"loss": lossJSON,
|
||||
"basic_fee_pooled": tenementCharge.BasicFee,
|
||||
"adjust_fee_pooled": tenementCharge.AdjustFee,
|
||||
"loss_fee_pooled": tenementCharge.LossPooled,
|
||||
"final_pooled": tenementCharge.PublicPooled,
|
||||
"final_charge": tenementCharge.FinalCharges,
|
||||
"meters": submetersJSON,
|
||||
"pooled": poolingsJSON,
|
||||
}
|
||||
|
||||
rows = append(rows, row)
|
||||
}
|
||||
|
||||
sql, params, err := insertQuery.Rows(values).Prepared(true).ToSQL()
|
||||
if err != nil {
|
||||
log.Println("sql出现问题................................")
|
||||
return err
|
||||
}
|
||||
tx.Exec(ctx, sql, params...)
|
||||
sql, params, err := insertQuery.Rows(rows).Prepared(true).ToSQL()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = tx.Exec(ctx, sql, params...)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -533,8 +574,3 @@ func convertToNestedMeters(meters []*calculate.Meter) []NestedMeter {
|
||||
}
|
||||
return nestedMeters
|
||||
}
|
||||
|
||||
// toJSONString 将对象转换为 JSON 字符串
|
||||
func toJSONString(obj interface{}) string {
|
||||
return `"` + strings.ReplaceAll(fmt.Sprintf("%#v", obj), `"`, `\"`) + `"`
|
||||
}
|
||||
|
@ -12,13 +12,13 @@ import (
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
"fmt"
|
||||
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
_ "github.com/doug-martin/goqu/v9/dialect/postgres"
|
||||
"github.com/georgysavva/scany/v2/pgxscan"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/shopspring/decimal"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
)
|
||||
|
||||
type _MeterRepository struct {
|
||||
@ -121,11 +121,10 @@ func (mr _MeterRepository) AllUsedMetersInReport(rid string) ([]*model.MeterDeta
|
||||
}
|
||||
|
||||
// 分页列出指定园区下的表计信息
|
||||
func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*model.MeterDetail, int64, error) {
|
||||
func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string, mtype int) ([]*model.MeterDetail, int64, error) {
|
||||
mr.log.Info("分页列出指定园区下的表计信息", zap.String("park id", pid), zap.Uint("page", page), zap.String("keyword", tools.DefaultTo(keyword, "")))
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
meterQuery := mr.ds.
|
||||
From(goqu.T("meter_04kv").As("m")).
|
||||
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("m.building").Eq(goqu.I("b.id")))).
|
||||
@ -143,7 +142,10 @@ func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*
|
||||
goqu.I("m.park_id").Eq(pid),
|
||||
goqu.I("m.detached_at").IsNull(),
|
||||
)
|
||||
|
||||
if mtype != 3 {
|
||||
meterQuery = meterQuery.Where(goqu.I("m.meter_type").Eq(uint(mtype)))
|
||||
countQuery = countQuery.Where(goqu.I("m.meter_type").Eq(uint(mtype)))
|
||||
}
|
||||
if keyword != nil && len(*keyword) > 0 {
|
||||
pattern := fmt.Sprintf("%%%s%%", *keyword)
|
||||
meterQuery = meterQuery.Where(
|
||||
@ -174,11 +176,11 @@ func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*
|
||||
mr.log.Error("查询表计信息失败", zap.Error(err))
|
||||
return make([]*model.MeterDetail, 0), 0, err
|
||||
}
|
||||
|
||||
if err := pgxscan.Get(ctx, global.DB, &total, countSql, countArgs...); err != nil {
|
||||
mr.log.Error("查询表计数量失败", zap.Error(err))
|
||||
return make([]*model.MeterDetail, 0), 0, err
|
||||
}
|
||||
|
||||
return meters, total, nil
|
||||
}
|
||||
|
||||
@ -209,12 +211,12 @@ func (mr _MeterRepository) ListMetersByIDs(pid string, ids []string) ([]*model.M
|
||||
mr.log.Error("查询表计信息失败", zap.Error(err))
|
||||
return make([]*model.MeterDetail, 0), err
|
||||
}
|
||||
|
||||
return meters, nil
|
||||
}
|
||||
|
||||
// 获取指定表计的详细信息
|
||||
func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetail, error) {
|
||||
log.Println("获取指定标记的详细信息,1111111111111111")
|
||||
mr.log.Info("获取指定表计的详细信息", zap.String("park id", pid), zap.String("meter code", code))
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
@ -231,7 +233,7 @@ func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetai
|
||||
goqu.I("m.code").Eq(code),
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
|
||||
log.Println("111111111111111111111111", meterSql)
|
||||
if err := pgxscan.Get(ctx, global.DB, &meter, meterSql, meterArgs...); err != nil {
|
||||
mr.log.Error("查询表计信息失败", zap.Error(err))
|
||||
return nil, err
|
||||
@ -242,8 +244,10 @@ func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetai
|
||||
|
||||
// 创建一条新的表计信息
|
||||
func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid string, meter vo.MeterCreationForm) (bool, error) {
|
||||
log.Println("创建一条新的表记55555555555555555555")
|
||||
mr.log.Info("创建一条新的表计信息", zap.String("park id", pid), zap.String("meter code", meter.Code))
|
||||
timeNow := types.Now()
|
||||
//timeNow := types.Now()
|
||||
|
||||
meterSql, meterArgs, _ := mr.ds.
|
||||
Insert(goqu.T("meter_04kv")).
|
||||
Cols(
|
||||
@ -251,8 +255,9 @@ func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid strin
|
||||
"attached_at", "created_at", "last_modified_at",
|
||||
).
|
||||
Vals(
|
||||
goqu.Vals{pid, meter.Code, meter.Address, meter.Ratio, meter.Seq, meter.MeterType, meter.Building, meter.OnFloor, meter.Area, meter.Enabled,
|
||||
timeNow, timeNow, timeNow,
|
||||
goqu.Vals{pid, meter.Code, meter.Address, meter.Ratio, meter.Seq, meter.MeterType, meter.Building, meter.OnFloor,
|
||||
meter.Area, meter.Enabled,
|
||||
meter.Reading.ReadAt, meter.Reading.ReadAt, meter.Reading.ReadAt,
|
||||
},
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
@ -262,6 +267,7 @@ func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid strin
|
||||
mr.log.Error("创建表计信息失败", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
log.Println("555555555555", meterSql)
|
||||
return ok.RowsAffected() > 0, nil
|
||||
}
|
||||
|
||||
@ -304,6 +310,7 @@ func (mr _MeterRepository) CreateOrUpdateMeter(tx pgx.Tx, ctx context.Context, p
|
||||
|
||||
// 记录一条表计的抄表信息
|
||||
func (mr _MeterRepository) RecordReading(tx pgx.Tx, ctx context.Context, pid, code string, meterType int16, ratio decimal.Decimal, reading *vo.MeterReadingForm) (bool, error) {
|
||||
log.Println("记录一条表记的抄表信息22222222222222222222")
|
||||
mr.log.Info("记录一条表计的抄表信息", zap.String("park id", pid), zap.String("meter code", code))
|
||||
readAt := tools.DefaultTo(reading.ReadAt, types.Now())
|
||||
readingSql, readingArgs, _ := mr.ds.
|
||||
@ -315,6 +322,7 @@ func (mr _MeterRepository) RecordReading(tx pgx.Tx, ctx context.Context, pid, co
|
||||
goqu.Vals{pid, code, readAt, meterType, ratio, reading.Overall, reading.Critical, reading.Peak, reading.Flat, reading.Valley},
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
log.Println("22222222222222222222", readingSql)
|
||||
|
||||
ok, err := tx.Exec(ctx, readingSql, readingArgs...)
|
||||
if err != nil {
|
||||
@ -390,6 +398,7 @@ func (mr _MeterRepository) ListMeterCodes(pid string) ([]string, error) {
|
||||
|
||||
// 解除指定园区中指定表计的使用
|
||||
func (mr _MeterRepository) DetachMeter(tx pgx.Tx, ctx context.Context, pid, code string) (bool, error) {
|
||||
log.Println("解除指定园区的指定表记使用33333333333333333333")
|
||||
mr.log.Info("解除指定园区中指定表计的使用", zap.String("park id", pid), zap.String("meter code", code))
|
||||
timeNow := types.Now()
|
||||
meterSql, meterArgs, _ := mr.ds.
|
||||
@ -405,7 +414,7 @@ func (mr _MeterRepository) DetachMeter(tx pgx.Tx, ctx context.Context, pid, code
|
||||
goqu.I("code").Eq(code),
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
|
||||
log.Println("3333333333333333", meterSql)
|
||||
ok, err := tx.Exec(ctx, meterSql, meterArgs...)
|
||||
if err != nil {
|
||||
mr.log.Error("解除表计使用失败", zap.Error(err))
|
||||
@ -467,6 +476,7 @@ func (mr _MeterRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, master
|
||||
|
||||
// 解除两个表计之间的关联
|
||||
func (mr _MeterRepository) UnbindMeter(tx pgx.Tx, ctx context.Context, pid, masterMeter, slaveMeter string) (bool, error) {
|
||||
log.Println("解除两个标记之间的关系》》》》》》》》》》》》》》》》》》》》》》》4444444444")
|
||||
mr.log.Info("解除两个表计之间的关联", zap.String("master meter code", masterMeter), zap.String("slave meter code", slaveMeter))
|
||||
relationSql, relationArgs, _ := mr.ds.
|
||||
Update(goqu.T("meter_relations")).
|
||||
@ -482,14 +492,14 @@ func (mr _MeterRepository) UnbindMeter(tx pgx.Tx, ctx context.Context, pid, mast
|
||||
goqu.I("revoked_at").IsNull(),
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
|
||||
log.Println("4444444444444444", relationSql)
|
||||
ok, err := tx.Exec(ctx, relationSql, relationArgs...)
|
||||
if err != nil {
|
||||
mr.log.Error("解除表计关系失败", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
return ok.RowsAffected() > 0, nil
|
||||
return ok.RowsAffected() >= 0, nil
|
||||
}
|
||||
|
||||
// 列出指定公摊表计的所有关联表计关系
|
||||
@ -553,7 +563,7 @@ func (mr _MeterRepository) ListMeterRelations(pid, code string) ([]*model.MeterR
|
||||
|
||||
var relations []*model.MeterRelation
|
||||
relationsSql, relationsArgs, _ := mr.ds.
|
||||
From(goqu.T("meter_relations")).
|
||||
From(goqu.T("meter_relations").As("r")).
|
||||
Select("*").
|
||||
Where(
|
||||
goqu.I("r.park_id").Eq(pid),
|
||||
@ -777,25 +787,31 @@ func (mr _MeterRepository) ListUnboundTenementMeters(uid string, pid *string, ke
|
||||
}
|
||||
|
||||
// 查询指定园区中的符合条件的抄表记录
|
||||
func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page uint, start, end *types.Date, buidling *string) ([]*model.MeterReading, int64, error) {
|
||||
func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page uint, start, end *types.Date, buidling *string, mtype uint) ([]*model.MeterReading, int64, error) {
|
||||
mr.log.Info("查询指定园区中的符合条件的抄表记录", zap.String("park id", pid), zap.String("keyword", tools.DefaultTo(keyword, "")), zap.Uint("page", page), logger.DateFieldp("start", start), logger.DateFieldp("end", end), zap.String("building", tools.DefaultTo(buidling, "")))
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
readingQuery := mr.ds.
|
||||
From(goqu.T("meter_reading").As("r")).
|
||||
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")), goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
|
||||
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")),
|
||||
goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
|
||||
Select("r.*").
|
||||
Where(
|
||||
goqu.I("r.park_id").Eq(pid),
|
||||
)
|
||||
countQuery := mr.ds.
|
||||
From(goqu.T("meter_reading").As("r")).
|
||||
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")), goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
|
||||
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")),
|
||||
goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
|
||||
Select(goqu.COUNT("*")).
|
||||
Where(
|
||||
goqu.I("r.park_id").Eq(pid),
|
||||
)
|
||||
if mtype != 3 {
|
||||
readingQuery = readingQuery.Where(goqu.I("m.meter_type").Eq(mtype))
|
||||
countQuery = countQuery.Where(goqu.I("m.meter_type").Eq(mtype))
|
||||
}
|
||||
|
||||
if keyword != nil && len(*keyword) > 0 {
|
||||
pattern := fmt.Sprintf("%%%s%%", *keyword)
|
||||
@ -859,7 +875,6 @@ func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page u
|
||||
mr.log.Error("查询抄表记录数量失败", zap.Error(err))
|
||||
return make([]*model.MeterReading, 0), 0, err
|
||||
}
|
||||
|
||||
return readings, total, nil
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ func (pr _ParkRepository) ListAllParks(uid string) ([]*model.Park, error) {
|
||||
"id", "user_id", "name", "area", "tenement_quantity", "capacity", "category",
|
||||
"meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate",
|
||||
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at",
|
||||
"deleted_at",
|
||||
"deleted_at","norm_authorized_loss_rate",
|
||||
).
|
||||
Where(
|
||||
goqu.I("user_id").Eq(uid),
|
||||
|
@ -9,7 +9,11 @@ import (
|
||||
"electricity_bill_calc/tools/serial"
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
_ "github.com/doug-martin/goqu/v9/dialect/postgres"
|
||||
@ -124,8 +128,8 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
|
||||
createSql, createArgs, _ := rr.ds.
|
||||
Insert(goqu.T("report")).
|
||||
Cols(
|
||||
"id", "park_id", "period", "category", "meter_o4kv_type", "price_policy",
|
||||
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at",
|
||||
"id", "park_id", "period", "category", "meter_04kv_type", "price_policy",
|
||||
"basis_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at",
|
||||
"last_modified_at",
|
||||
).
|
||||
Vals(goqu.Vals{
|
||||
@ -134,38 +138,45 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
|
||||
createTime,
|
||||
}).
|
||||
Prepared(true).ToSQL()
|
||||
summarySql, summaryArgs, _ := rr.ds.
|
||||
critical := model.ConsumptionUnit{
|
||||
Amount: form.Critical,
|
||||
Fee: form.CriticalFee,
|
||||
}
|
||||
criticalData, _ := json.Marshal(critical)
|
||||
overall := model.ConsumptionUnit{
|
||||
Amount: form.Overall,
|
||||
Fee: form.OverallFee,
|
||||
}
|
||||
overallData, _ := json.Marshal(overall)
|
||||
peak := model.ConsumptionUnit{
|
||||
Amount: form.Peak,
|
||||
Fee: form.PeakFee,
|
||||
}
|
||||
peakData, _ := json.Marshal(peak)
|
||||
flat := model.ConsumptionUnit{
|
||||
Amount: form.Flat,
|
||||
Fee: form.FlatFee,
|
||||
}
|
||||
flatData, _ := json.Marshal(flat)
|
||||
valley := model.ConsumptionUnit{
|
||||
Amount: form.Valley,
|
||||
Fee: form.ValleyFee,
|
||||
}
|
||||
valleyData, _ := json.Marshal(valley)
|
||||
summarySql, summaryArgs, err5 := rr.ds.
|
||||
Insert(goqu.T("report_summary")).
|
||||
Cols(
|
||||
"report_id", "overall", "critical", "peak", "flat", "valley", "basic_fee",
|
||||
"adjust_fee",
|
||||
).
|
||||
Vals(goqu.Vals{
|
||||
reportId,
|
||||
model.ConsumptionUnit{
|
||||
Amount: form.Overall,
|
||||
Fee: form.OverallFee,
|
||||
},
|
||||
model.ConsumptionUnit{
|
||||
Amount: form.Critical,
|
||||
Fee: form.CriticalFee,
|
||||
},
|
||||
model.ConsumptionUnit{
|
||||
Amount: form.Peak,
|
||||
Fee: form.PeakFee,
|
||||
},
|
||||
model.ConsumptionUnit{
|
||||
Amount: form.Flat,
|
||||
Fee: form.FlatFee,
|
||||
},
|
||||
model.ConsumptionUnit{
|
||||
Amount: form.Valley,
|
||||
Fee: form.ValleyFee,
|
||||
},
|
||||
form.BasicFee,
|
||||
form.AdjustFee,
|
||||
}).
|
||||
Prepared(true).ToSQL()
|
||||
//Cols("report_id", "overall", "critical", "peak", "flat", "valley", "basic_fee", "adjust_fee").
|
||||
Rows(goqu.Record{
|
||||
"report_id": reportId,
|
||||
"overall": string(overallData),
|
||||
"critical": string(criticalData),
|
||||
"peak": string(peakData),
|
||||
"flat": string(flatData),
|
||||
"valley": string(valleyData),
|
||||
"basic_fee": form.BasicFee,
|
||||
"adjust_fee": form.AdjustFee,
|
||||
}).Prepared(true).ToSQL()
|
||||
log.Println("errrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr:", err5)
|
||||
taskSql, taskArgs, _ := rr.ds.
|
||||
Insert(goqu.T("report_task")).
|
||||
Cols("id", "status", "last_modified_at").
|
||||
@ -189,11 +200,14 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
|
||||
tx.Rollback(ctx)
|
||||
return false, "", err
|
||||
}
|
||||
log.Println("?????????", summarySql, summaryArgs)
|
||||
log.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", resSummary.RowsAffected())
|
||||
if resSummary.RowsAffected() == 0 {
|
||||
rr.log.Error("保存核算报表汇总时出现错误", zap.Error(err))
|
||||
tx.Rollback(ctx)
|
||||
return false, "", exceptions.NewUnsuccessCreateError("创建核算报表汇总时出现错误")
|
||||
}
|
||||
|
||||
resTask, err := tx.Exec(ctx, taskSql, taskArgs...)
|
||||
if err != nil {
|
||||
rr.log.Error("创建核算报表任务时出现错误", zap.Error(err))
|
||||
@ -295,7 +309,6 @@ func (rr _ReportRepository) RetrieveReportSummary(rid string) (*model.ReportSumm
|
||||
Select("*").
|
||||
Where(goqu.I("report_id").Eq(rid)).
|
||||
Prepared(true).ToSQL()
|
||||
|
||||
var summary model.ReportSummary
|
||||
if err := pgxscan.Get(ctx, global.DB, &summary, querySql, queryParams...); err != nil {
|
||||
rr.log.Error("获取指定报表的总览信息时出现错误", zap.Error(err))
|
||||
@ -332,23 +345,31 @@ func (rr _ReportRepository) GetReportTaskStatus(uid string) ([]*model.ReportTask
|
||||
}
|
||||
|
||||
// 检索指定核算报表中园区公共表计的核算记录
|
||||
func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyword *string) ([]*model.ReportDetailedPublicConsumption, int64, error) {
|
||||
func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyword *string) ([]*vo.ReportPublishResponse, int64, error) {
|
||||
rr.log.Info("检索指定核算报表中园区公共表计的核算记录", zap.String("Report", rid))
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
reportQuery := rr.ds.
|
||||
From(goqu.T("report_public_consumption").As("r")).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.park_meter_id")))).
|
||||
Join(goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(
|
||||
goqu.I("m.code").Eq(goqu.I("r.park_meter_id")),
|
||||
goqu.I("m.park_id").Eq(goqu.I("ri.park_id")),
|
||||
)).
|
||||
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))).
|
||||
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
|
||||
Select(
|
||||
goqu.I("r.*"), goqu.I("b.name").As("building_name"), goqu.I("p.public_pooled"),
|
||||
goqu.I("r.*"), goqu.I("m.*"), goqu.I("b.name").As("building_name"),
|
||||
).
|
||||
Where(goqu.I("r.report_id").Eq(rid))
|
||||
countQuery := rr.ds.
|
||||
From(goqu.T("report_public_consumption").As("r")).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.park_meter_id")))).
|
||||
Join(goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(
|
||||
goqu.I("m.code").Eq(goqu.I("r.park_meter_id")),
|
||||
goqu.I("m.park_id").Eq(goqu.I("ri.park_id")),
|
||||
)).
|
||||
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))).
|
||||
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
|
||||
Select(goqu.COUNT(goqu.I("r.*"))).
|
||||
@ -372,7 +393,7 @@ func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyw
|
||||
Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize)
|
||||
|
||||
var (
|
||||
consumptions []*model.ReportDetailedPublicConsumption = make([]*model.ReportDetailedPublicConsumption, 0)
|
||||
consumptions = make([]*vo.ReportPublishResponse, 0)
|
||||
count int64
|
||||
)
|
||||
querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL()
|
||||
@ -390,19 +411,23 @@ func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyw
|
||||
|
||||
// 检索指定核算报表中公摊表计的核算记录
|
||||
func (rr _ReportRepository) ListPooledMetersInReport(rid string, page uint, keyword *string) ([]*model.ReportDetailedPooledConsumption, int64, error) {
|
||||
|
||||
rr.log.Info("检索指定核算报表中公摊表计的核算记录", zap.String("Report", rid))
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
reportQuery := rr.ds.
|
||||
From(goqu.T("report_pooled_consumption").As("r")).
|
||||
Join(
|
||||
goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))).
|
||||
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))).
|
||||
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("ri.park_id")))).
|
||||
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
|
||||
Select(
|
||||
goqu.I("r.*"), goqu.I("m.*"), goqu.I("b.name").As("building_name"), goqu.I("p.public_pooled"),
|
||||
).
|
||||
Where(goqu.I("r.report_id").Eq(rid))
|
||||
reportQuery = reportQuery.Where(goqu.I("m.park_id").Eq(goqu.I("p.id")))
|
||||
countQuery := rr.ds.
|
||||
From(goqu.T("report_pooled_consumption").As("r")).
|
||||
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))).
|
||||
@ -479,6 +504,10 @@ func (rr _ReportRepository) ListPooledMeterDetailInReport(rid, mid string) ([]*m
|
||||
rr.log.Error("列出指定核算报表中指定公共表计下参与公共表计费用分摊的表计详细时出现错误", zap.Error(err))
|
||||
return make([]*model.ReportDetailNestedMeterConsumption, 0), err
|
||||
}
|
||||
|
||||
if len(meterDetails) <= 0 {
|
||||
return make([]*model.ReportDetailNestedMeterConsumption, 0), errors.New("暂无分摊关系")
|
||||
}
|
||||
assembled := lo.Map(meter.Diluted, func(m model.NestedMeter, _ int) *model.ReportDetailNestedMeterConsumption {
|
||||
meterDetail, _ := lo.Find(meterDetails, func(elem *model.MeterDetail) bool {
|
||||
return elem.Code == m.MeterId
|
||||
@ -534,15 +563,17 @@ func (rr _ReportRepository) ListTenementInReport(rid string, page uint, keyword
|
||||
Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize)
|
||||
|
||||
var (
|
||||
tenements []*model.ReportTenement = make([]*model.ReportTenement, 0)
|
||||
tenements = make([]*model.ReportTenement, 0)
|
||||
count int64
|
||||
)
|
||||
querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL()
|
||||
countSql, countArgs, _ := countQuery.Prepared(true).ToSQL()
|
||||
fmt.Println(querySql, rid)
|
||||
if err := pgxscan.Select(ctx, global.DB, &tenements, querySql, queryArgs...); err != nil {
|
||||
rr.log.Error("查询指定核算报表下的商户简要计费信息时出现错误", zap.Error(err))
|
||||
return tenements, 0, err
|
||||
}
|
||||
|
||||
if err := pgxscan.Get(ctx, global.DB, &count, countSql, countArgs...); err != nil {
|
||||
rr.log.Error("查询指定核算报表下的商户简要计费信息总数量时出现错误", zap.Error(err))
|
||||
return tenements, 0, err
|
||||
@ -618,7 +649,7 @@ func (rr _ReportRepository) ComprehensiveReportSearch(uid, pid *string, page uin
|
||||
countQuery = countQuery.Where(goqu.I("ud.id").Eq(*uid))
|
||||
}
|
||||
|
||||
if pid != nil && len(*pid) > 0 {
|
||||
if pid != nil && *pid != "" {
|
||||
reportQuery = reportQuery.Where(goqu.I("p.id").Eq(*pid))
|
||||
countQuery = countQuery.Where(goqu.I("p.id").Eq(*pid))
|
||||
}
|
||||
@ -626,7 +657,8 @@ func (rr _ReportRepository) ComprehensiveReportSearch(uid, pid *string, page uin
|
||||
queryDateRange := types.NewDateRange(start, end)
|
||||
reportQuery = reportQuery.Where(goqu.L("r.period <@ ?", queryDateRange))
|
||||
countQuery = countQuery.Where(goqu.L("r.period <@ ?", queryDateRange))
|
||||
|
||||
reportQuery = reportQuery.Where(goqu.I("r.published").Eq(true))
|
||||
countQuery = countQuery.Where(goqu.I("r.published").Eq(true))
|
||||
if keyword != nil && len(*keyword) > 0 {
|
||||
pattern := fmt.Sprintf("%%%s%%", *keyword)
|
||||
reportQuery = reportQuery.Where(goqu.Or(
|
||||
|
@ -226,7 +226,7 @@ func (tr _TenementRepository) AddTenement(tx pgx.Tx, ctx context.Context, pid st
|
||||
Bank: tools.DefaultOrEmptyStr(tenement.Bank, ""),
|
||||
Account: tools.DefaultOrEmptyStr(tenement.Account, ""),
|
||||
},
|
||||
currentTime,
|
||||
tenement.MoveIn,
|
||||
currentTime,
|
||||
currentTime,
|
||||
}...,
|
||||
@ -238,7 +238,7 @@ func (tr _TenementRepository) AddTenement(tx pgx.Tx, ctx context.Context, pid st
|
||||
}
|
||||
|
||||
// 向园区中指定商户下绑定一个新的表计
|
||||
func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid, meter string) error {
|
||||
func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid, meter string, form *vo.MeterReadingForm) error {
|
||||
tr.log.Info("向园区中指定商户下绑定一个新的表计", zap.String("Park", pid), zap.String("Tenement", tid), zap.String("Meter", meter))
|
||||
|
||||
createSql, createArgs, _ := tr.ds.
|
||||
@ -251,7 +251,7 @@ func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid
|
||||
pid,
|
||||
tid,
|
||||
meter,
|
||||
types.Now(),
|
||||
form.ReadAt,
|
||||
},
|
||||
).
|
||||
Prepared(true).ToSQL()
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"electricity_bill_calc/tools"
|
||||
"electricity_bill_calc/types"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
@ -238,8 +239,11 @@ func (ur _UserRepository) FindUser(keyword *string, userType int16, state *bool,
|
||||
}
|
||||
|
||||
if state != nil {
|
||||
userQuery = userQuery.Where(goqu.Ex{"u.enabled": state})
|
||||
countQuery = countQuery.Where(goqu.Ex{"u.enabled": state})
|
||||
//userQuery = userQuery.Where(goqu.C("u.enabled").Eq(*state))
|
||||
userQuery = userQuery.Where(goqu.Ex{"u.enabled": *state})
|
||||
countQuery = countQuery.Where(goqu.Ex{"u.enabled": *state})
|
||||
//countQuery = countQuery.Where(goqu.C("u.enabled").Eq(*state))
|
||||
|
||||
}
|
||||
|
||||
userQuery.Order(goqu.I("u.created_at").Desc())
|
||||
@ -249,8 +253,9 @@ func (ur _UserRepository) FindUser(keyword *string, userType int16, state *bool,
|
||||
|
||||
userSql, userParams, _ := userQuery.Prepared(true).ToSQL()
|
||||
countSql, countParams, _ := countQuery.Prepared(true).ToSQL()
|
||||
log.Println(">>>>>>>>>>>", userSql)
|
||||
if err := pgxscan.Select(ctx, global.DB, &userWithDetails, userSql, userParams...); err != nil {
|
||||
ur.log.Error("从数据库查询用户列表失败。", zap.Error(err))
|
||||
ur.log.Error("从数据库查询用户列表失败。》》》》》》》》》》》》》》", zap.Error(err))
|
||||
return make([]*model.UserWithDetail, 0), 0, err
|
||||
}
|
||||
if err := pgxscan.Get(ctx, global.DB, &userCount, countSql, countParams...); err != nil {
|
||||
|
@ -3,10 +3,10 @@ package calculate
|
||||
import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/model/calculate"
|
||||
"electricity_bill_calc/repository"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shopspring/decimal"
|
||||
"log"
|
||||
)
|
||||
|
||||
func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []calculate.Meter, publics []calculate.Meter) (MeterMap, error) {
|
||||
@ -14,20 +14,27 @@ func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []c
|
||||
// Collect tenement meters
|
||||
for _, t := range tenements {
|
||||
for _, m := range t.Meters {
|
||||
log.Println("m000000000000000000000000000", m.Code)
|
||||
|
||||
key := Key{TenementID: t.Tenement.Id, Code: m.Code}
|
||||
meters[key] = m
|
||||
}
|
||||
}
|
||||
// Collect poolings
|
||||
for _, m := range poolings {
|
||||
log.Println("m111111111111111111111111", m.Code)
|
||||
key := Key{TenementID: "", Code: m.Code}
|
||||
meters[key] = m
|
||||
}
|
||||
|
||||
// Collect publics
|
||||
for _, m := range publics {
|
||||
log.Println("m222222222222222222222222222", m.Code)
|
||||
|
||||
key := Key{TenementID: "", Code: m.Code}
|
||||
meters[key] = m
|
||||
}
|
||||
log.Println("m33333333333333333333333333333333333333", meters[Key{Code: "yq00001"}])
|
||||
return meters, nil
|
||||
}
|
||||
|
||||
@ -144,9 +151,9 @@ func CalculateLossPooling(report model.ReportIndex, summary calculate.Summary, m
|
||||
|
||||
/// 计算所有商户类型表计的全周期电量。
|
||||
|
||||
func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal, error) {
|
||||
func CalculateTenementConsumptions(meters *MeterMap) (map[string]decimal.Decimal, error) {
|
||||
consumptions := make(map[string]decimal.Decimal)
|
||||
for _, meter := range meters {
|
||||
for _, meter := range *meters {
|
||||
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
|
||||
amount, ok := consumptions[meter.Code]
|
||||
if !ok {
|
||||
@ -156,7 +163,7 @@ func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal,
|
||||
consumptions[meter.Code] = amount
|
||||
}
|
||||
}
|
||||
for _, meter := range meters {
|
||||
for _, meter := range *meters {
|
||||
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
|
||||
amount, ok := consumptions[meter.Code]
|
||||
if !ok {
|
||||
@ -176,273 +183,174 @@ func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal,
|
||||
return consumptions, nil
|
||||
}
|
||||
|
||||
/*
|
||||
/// 计算商户表计的公摊分摊
|
||||
|
||||
func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error {
|
||||
for _, meter := range meters {
|
||||
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
|
||||
switch report.PublicPooled {
|
||||
case model.POOLING_MODE_AREA:
|
||||
for _, relation := range meterRelations {
|
||||
if relation.SlaveMeter == meter.Code {
|
||||
key := Key{
|
||||
Code: relation.MasterMeter,
|
||||
}
|
||||
parentMeter, ok := meters[key]
|
||||
if !ok {
|
||||
return errors.New("父级表记未找到")
|
||||
}
|
||||
|
||||
poolingAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea).
|
||||
Mul(meter.SharedPoolingProportion).
|
||||
Mul(parentMeter.Overall.Amount).Mul(summary.Overall.Price)
|
||||
|
||||
pooling := calculate.Pooling{
|
||||
Code: parentMeter.Code,
|
||||
Detail: model.ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: poolingAmount.Mul(summary.Overall.Price),
|
||||
Price: summary.Overall.Price,
|
||||
//后续debug此处需要判断,
|
||||
Proportion: poolingAmount.Div(parentMeter.Overall.Amount),
|
||||
},
|
||||
}
|
||||
|
||||
pooling := calculate.Pooling{
|
||||
Code: parentMeter.Code,
|
||||
Detail: model.ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: poolingAmount.Mul(summary.Overall.Price),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: poolingAmount.Div(parentMeter.Overall.Amount),
|
||||
},
|
||||
}
|
||||
meter.PooledPublic = &ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
|
||||
}
|
||||
|
||||
meter.Poolings = append(meter.Poolings, pooling)
|
||||
}
|
||||
}
|
||||
|
||||
case Consumption:
|
||||
for _, relation := range meterRelations {
|
||||
if relation.SlaveMeter == meter.Code {
|
||||
parentMeter, ok := meters[relation.MasterMeter]
|
||||
if !ok {
|
||||
return errors.New("parent meter not found")
|
||||
}
|
||||
|
||||
if parentMeter.Overall.Amount.Cmp(new(big.Rat)) == 0 {
|
||||
poolingAmount := new(big.Rat)
|
||||
parentAmount := new(big.Rat)
|
||||
|
||||
pooling := &Pooling{
|
||||
Code: parentMeter.Code,
|
||||
Detail: &ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: new(big.Rat),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: new(big.Rat),
|
||||
},
|
||||
}
|
||||
|
||||
meter.PooledPublic = &ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: new(big.Rat),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: new(big.Rat),
|
||||
}
|
||||
|
||||
meter.Poolings = append(meter.Poolings, pooling)
|
||||
} else {
|
||||
poolingAmount := new(big.Rat).Mul(meter.Overall.Amount, new(big.Rat).Quo(parentMeter.Overall.Amount, parentMeter.Overall.Amount))
|
||||
parentAmount := parentMeter.Overall.Amount
|
||||
|
||||
pooling := &Pooling{
|
||||
Code: parentMeter.Code,
|
||||
Detail: &ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
|
||||
},
|
||||
}
|
||||
|
||||
meter.PooledPublic = &ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
|
||||
}
|
||||
|
||||
meter.Poolings = append(meter.Poolings, pooling)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// handle other pooling modes...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
// 计算商户表计的公摊分摊
|
||||
func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error {
|
||||
|
||||
switch report.PublicPooled {
|
||||
case model.POOLING_MODE_AREA:
|
||||
for _, meter := range meters {
|
||||
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
|
||||
var pooleds []struct {
|
||||
PooledAmount decimal.Decimal
|
||||
ParentAmount decimal.Decimal
|
||||
ParentCode string
|
||||
}
|
||||
pooleds := make([]struct {
|
||||
Electricity decimal.Decimal
|
||||
ParentElectricity decimal.Decimal
|
||||
Code string
|
||||
}, 0)
|
||||
|
||||
for _, relation := range meterRelations {
|
||||
if relation.SlaveMeter == meter.Code {
|
||||
key := Key{
|
||||
Code: relation.MasterMeter,
|
||||
Code: relation.MasterMeter,
|
||||
TenementID: "",
|
||||
}
|
||||
parentMeter, ok := meters[key]
|
||||
if !ok {
|
||||
// 处理未找到父级表计的情况
|
||||
continue
|
||||
}
|
||||
// 计算分摊电量和父级表电量
|
||||
|
||||
pooledAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea).Mul(parentMeter.Overall.Amount).Mul(meter.SharedPoolingProportion)
|
||||
area := parentMeter.CoveredArea
|
||||
coveredArea := area
|
||||
overall := parentMeter.Overall
|
||||
proportion := meter.SharedPoolingProportion
|
||||
|
||||
electricity := area.InexactFloat64() / coveredArea.InexactFloat64() * overall.Amount.InexactFloat64() * proportion.InexactFloat64()
|
||||
pooleds = append(pooleds, struct {
|
||||
PooledAmount decimal.Decimal
|
||||
ParentAmount decimal.Decimal
|
||||
ParentCode string
|
||||
Electricity decimal.Decimal
|
||||
ParentElectricity decimal.Decimal
|
||||
Code string
|
||||
}{
|
||||
PooledAmount: pooledAmount,
|
||||
ParentAmount: parentMeter.Overall.Amount,
|
||||
ParentCode: parentMeter.Code,
|
||||
Electricity: decimal.NewFromFloat(electricity),
|
||||
ParentElectricity: overall.Amount,
|
||||
Code: parentMeter.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 计算总分摊电量和总父级电量
|
||||
var consumptions, total decimal.Decimal
|
||||
for _, p := range pooleds {
|
||||
consumptions = consumptions.Add(p.PooledAmount)
|
||||
total = total.Add(p.ParentAmount)
|
||||
}
|
||||
consumptions := 0.00
|
||||
total := 0.00
|
||||
var pooled []*calculate.Pooling
|
||||
|
||||
// 计算并更新公摊分摊信息
|
||||
for _, p := range pooleds {
|
||||
poolingAmount := p.PooledAmount
|
||||
proportion := p.PooledAmount.Div(p.ParentAmount)
|
||||
fee := poolingAmount.Mul(summary.Overall.Price)
|
||||
consumptions += p.Electricity.InexactFloat64()
|
||||
total += p.ParentElectricity.InexactFloat64()
|
||||
|
||||
// 更新父级表计的公摊分摊信息
|
||||
key := Key{
|
||||
Code: p.ParentCode,
|
||||
unit := model.ConsumptionUnit{
|
||||
Amount: p.Electricity,
|
||||
Fee: decimal.NewFromFloat(p.Electricity.InexactFloat64() * summary.Overall.Price.InexactFloat64()),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: decimal.Zero,
|
||||
}
|
||||
parentMeter := meters[key]
|
||||
parentMeter.PooledPublic.Amount = consumptions
|
||||
parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price)
|
||||
parentMeter.PooledPublic.Proportion = consumptions.Div(total)
|
||||
meters[Key{Code: p.ParentCode}] = parentMeter
|
||||
// 创建并更新分摊信息
|
||||
|
||||
if p.ParentElectricity != decimal.Zero {
|
||||
unit.Proportion = decimal.NewFromFloat(p.Electricity.InexactFloat64() / p.ParentElectricity.InexactFloat64())
|
||||
}
|
||||
|
||||
pooling := calculate.Pooling{
|
||||
Code: p.ParentCode,
|
||||
Detail: model.ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: fee,
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: proportion,
|
||||
},
|
||||
Code: p.Code,
|
||||
Detail: unit,
|
||||
}
|
||||
meter.Poolings = append(meter.Poolings, &pooling)
|
||||
|
||||
pooled = append(pooled, &pooling)
|
||||
}
|
||||
|
||||
meter.PooledPublic = model.ConsumptionUnit{
|
||||
Amount: decimal.NewFromFloat(consumptions),
|
||||
Fee: decimal.NewFromFloat(consumptions * summary.Overall.Price.InexactFloat64()),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: decimal.NewFromFloat(consumptions / total),
|
||||
}
|
||||
|
||||
meter.Poolings = pooled
|
||||
}
|
||||
}
|
||||
|
||||
case model.POOLING_MODE_CONSUMPTION:
|
||||
case model.PRICING_POLICY_CONSUMPTION:
|
||||
for _, meter := range meters {
|
||||
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
|
||||
var pooled []struct {
|
||||
PooledAmount decimal.Decimal
|
||||
ParentAmount decimal.Decimal
|
||||
ParentCode string
|
||||
}
|
||||
pooled := make([]struct {
|
||||
Electricity decimal.Decimal
|
||||
ParentElectricity decimal.Decimal
|
||||
Code string
|
||||
}, 0)
|
||||
|
||||
for _, relation := range meterRelations {
|
||||
if relation.SlaveMeter == meter.Code {
|
||||
parentMeter, ok := meters[Key{Code: relation.MasterMeter}]
|
||||
key := Key{
|
||||
Code: relation.MasterMeter,
|
||||
TenementID: "",
|
||||
}
|
||||
parentMeter, ok := meters[key]
|
||||
if !ok {
|
||||
// 处理未找到父级表计的情况
|
||||
continue
|
||||
}
|
||||
// 计算分摊电量和父级电量
|
||||
var pooledAmount decimal.Decimal
|
||||
if parentMeter.Overall.Amount.IsZero() {
|
||||
relations, err := repository.MeterRepository.ListPooledMeterRelations(report.Park, meter.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//此处rust版本有误,更新后的解决办法
|
||||
pooledAmount = meter.Overall.Amount.Div(decimal.NewFromInt(int64(len(relations)))).Mul(parentMeter.Overall.Amount)
|
||||
|
||||
overall := parentMeter.Overall
|
||||
|
||||
if overall.Amount == decimal.Zero {
|
||||
pooled = append(pooled, struct {
|
||||
Electricity decimal.Decimal
|
||||
ParentElectricity decimal.Decimal
|
||||
Code string
|
||||
}{
|
||||
Electricity: decimal.Zero,
|
||||
ParentElectricity: decimal.Zero,
|
||||
Code: parentMeter.Code,
|
||||
})
|
||||
} else { //TODO: 2023.08.11 计算处理流程修改到此处,以下问题未作修改还存在问题
|
||||
electricity := meter.Overall.Amount.InexactFloat64() / overall.Amount.InexactFloat64() * overall.Amount.InexactFloat64()
|
||||
pooled = append(pooled, struct {
|
||||
Electricity decimal.Decimal
|
||||
ParentElectricity decimal.Decimal
|
||||
Code string
|
||||
}{
|
||||
Electricity: decimal.NewFromFloat(electricity),
|
||||
ParentElectricity: overall.Amount,
|
||||
Code: parentMeter.Code,
|
||||
})
|
||||
}
|
||||
pooled = append(pooled, struct {
|
||||
PooledAmount decimal.Decimal
|
||||
ParentAmount decimal.Decimal
|
||||
ParentCode string
|
||||
}{
|
||||
PooledAmount: pooledAmount,
|
||||
ParentAmount: parentMeter.Overall.Amount,
|
||||
ParentCode: parentMeter.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 计算总分摊电量和总父级表记电量
|
||||
var consumptions, total decimal.Decimal
|
||||
consumptions := decimal.Zero.InexactFloat64()
|
||||
total := decimal.Zero.InexactFloat64()
|
||||
var poolings []*calculate.Pooling
|
||||
|
||||
for _, p := range pooled {
|
||||
consumptions = consumptions.Add(p.PooledAmount)
|
||||
total = total.Add(p.ParentAmount)
|
||||
}
|
||||
consumptions += p.Electricity.InexactFloat64()
|
||||
total += p.ParentElectricity.InexactFloat64()
|
||||
|
||||
// 计算并更新公摊分摊信息
|
||||
for _, p := range pooled {
|
||||
poolingAmount := p.PooledAmount
|
||||
proportion := p.PooledAmount.Div(p.ParentAmount)
|
||||
fee := poolingAmount.Mul(summary.Overall.Price)
|
||||
unit := model.ConsumptionUnit{
|
||||
Amount: p.Electricity,
|
||||
Fee: decimal.NewFromFloat(p.Electricity.InexactFloat64() * summary.Overall.Price.InexactFloat64()),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: decimal.Zero,
|
||||
}
|
||||
|
||||
// 更新父级表计的公摊分摊信息
|
||||
parentMeter := meters[Key{Code: p.ParentCode}]
|
||||
parentMeter.PooledPublic.Amount = consumptions
|
||||
parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price)
|
||||
parentMeter.PooledPublic.Proportion = consumptions.Div(total)
|
||||
meters[Key{Code: p.ParentCode}] = parentMeter
|
||||
if p.ParentElectricity != decimal.Zero {
|
||||
unit.Proportion = decimal.NewFromFloat(p.Electricity.InexactFloat64() / p.ParentElectricity.InexactFloat64())
|
||||
}
|
||||
|
||||
// 创建并更新分摊信息
|
||||
pooling := calculate.Pooling{
|
||||
Code: p.ParentCode,
|
||||
Detail: model.ConsumptionUnit{
|
||||
Amount: poolingAmount,
|
||||
Fee: fee,
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: proportion,
|
||||
},
|
||||
Code: p.Code,
|
||||
Detail: unit,
|
||||
}
|
||||
meter.Poolings = append(meter.Poolings, &pooling)
|
||||
|
||||
poolings = append(poolings, &pooling)
|
||||
}
|
||||
|
||||
meter.PooledPublic = model.ConsumptionUnit{
|
||||
Amount: decimal.NewFromFloat(consumptions),
|
||||
Fee: decimal.NewFromFloat(consumptions * summary.Overall.Price.InexactFloat64()),
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: decimal.Zero,
|
||||
}
|
||||
|
||||
if total != decimal.Zero.InexactFloat64() {
|
||||
meter.SharedPoolingProportion = decimal.NewFromFloat(consumptions / total)
|
||||
}
|
||||
|
||||
meter.Poolings = poolings
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// 处理其他分摊模式
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/model/calculate"
|
||||
"electricity_bill_calc/repository"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -22,6 +23,11 @@ func MetersParkCalculate(report model.ReportIndex, periodStart time.Time,
|
||||
|
||||
parkMeterReadings = append(parkMeterReadings, lastTermParkMeterReadings...)
|
||||
|
||||
if len(parkMeterReadings) <= 0 {
|
||||
fmt.Println(parkMeterReadings)
|
||||
return []calculate.Meter{}, nil
|
||||
}
|
||||
|
||||
var parkMetersReports []calculate.Meter
|
||||
for _, meter := range meterDetail {
|
||||
if meter.MeterType == model.METER_INSTALLATION_PARK {
|
||||
|
@ -1,51 +1,44 @@
|
||||
package calculate
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/global"
|
||||
"context"
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/model/calculate"
|
||||
"electricity_bill_calc/repository"
|
||||
"fmt"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// 向数据库保存核算概况结果
|
||||
func SaveSummary(tx pgx.Tx, summary calculate.Summary) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
func SaveSummary(tx pgx.Tx, ctx context.Context, summary calculate.Summary) error {
|
||||
|
||||
// 保存核算概况结果到数据库
|
||||
err := repository.CalculateRepository.SaveReportSummary(tx, summary)
|
||||
err := repository.CalculateRepository.SaveReportSummary(tx,ctx, summary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.Commit(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// type MeterMap map[string]map[string]calculate.Meter
|
||||
// 向数据库保存公共表计的计算结果
|
||||
func SavePublics(tx pgx.Tx, report model.ReportIndex, meters MeterMap) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
|
||||
func SavePublics(tx pgx.Tx, ctx context.Context, report model.ReportIndex, meters MeterMap) error {
|
||||
var filteredMeters []calculate.Meter
|
||||
|
||||
for _, m := range meters {
|
||||
if m.Detail.MeterType == model.METER_INSTALLATION_PARK {
|
||||
filteredMeters = append(filteredMeters, m)
|
||||
}
|
||||
}
|
||||
err := repository.CalculateRepository.SaveReportPublics(tx, report.Id, filteredMeters)
|
||||
fmt.Println(tx)
|
||||
err := repository.CalculateRepository.SaveReportPublics(tx, ctx, report.Id, filteredMeters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.Commit(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relations []model.MeterRelation) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
var poolingMeters []calculate.Meter
|
||||
var tenementMeters []calculate.Meter
|
||||
// 根据条件筛选 Meter 并保存到对应的数组中
|
||||
@ -60,13 +53,9 @@ func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relation
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.Commit(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.PrimaryTenementStatistics, tc []calculate.TenementCharge) error {
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
defer cancel()
|
||||
var ts []model.Tenement
|
||||
for _, r := range tenement {
|
||||
ts = append(ts, r.Tenement)
|
||||
@ -75,7 +64,5 @@ func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.Pri
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.Commit(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -4,12 +4,13 @@ import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/model/calculate"
|
||||
"electricity_bill_calc/repository"
|
||||
"electricity_bill_calc/types"
|
||||
"github.com/shopspring/decimal"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//核算园区中的全部公摊表计的电量用量
|
||||
// 核算园区中的全部公摊表计的电量用量
|
||||
func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
|
||||
periodEnd time.Time, meterDetails []*model.MeterDetail,
|
||||
summary calculate.Summary) ([]calculate.Meter, error) {
|
||||
@ -24,6 +25,9 @@ func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
|
||||
}
|
||||
|
||||
poolingMeterReadings = append(poolingMeterReadings, lastTermPoolingMeterReadings...)
|
||||
if len(poolingMeterReadings) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var poolingMetersReports []calculate.Meter
|
||||
for _, meter := range meterDetails {
|
||||
@ -36,10 +40,14 @@ func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
|
||||
return poolingMetersReports, nil
|
||||
}
|
||||
|
||||
// 确定指定非商户表计在指定时间段内的全部电量
|
||||
// 确定指定非商户表计在指定时间段内的全部电量
|
||||
func determinePublicMeterConsumptions(meterId string, periodStart time.Time,
|
||||
periodEnd time.Time, readings []model.MeterReading,
|
||||
meterDetail model.MeterDetail, summary calculate.Summary) (calculate.Meter, error) {
|
||||
if meterDetail.DetachedAt == nil {
|
||||
zeroTime := time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
meterDetail.DetachedAt = &types.DateTime{Time: zeroTime}
|
||||
}
|
||||
startReading, err := DeterminePublicMeterStartReading(meterId, periodStart, meterDetail.DetachedAt.Time, readings)
|
||||
if err != nil {
|
||||
return calculate.Meter{}, err
|
||||
|
@ -36,13 +36,15 @@ func DeterminePublicMeterStartReading(meterId string, periodStart time.Time,
|
||||
for _, reading := range meterReadings {
|
||||
readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC())
|
||||
for _, startTime := range startTimes {
|
||||
if reading.Meter == meterId && readingAt.After(startTime) || readingAt.Equal(startTime) {
|
||||
if reading.Meter == meterId && readingAt.Truncate(24*time.Hour).Equal(startTime.Truncate(24*time.Hour)) || readingAt.After(startTime) {
|
||||
startReading = append(startReading, reading)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(startReading)
|
||||
|
||||
if len(startReading) <= 0 {
|
||||
return nil, errors.New(fmt.Sprintf("无法确定表计 %s 的计量的起始读数", meterId))
|
||||
}
|
||||
@ -71,20 +73,20 @@ func DeterminePublicMeterEndReading(meterId string, periodEnd time.Time,
|
||||
minReading = reading.ReadAt
|
||||
}
|
||||
}
|
||||
startTimes := []time.Time{
|
||||
endTimes := []time.Time{
|
||||
minReading.Time,
|
||||
periodEnding.Time,
|
||||
ShiftToAsiaShanghai(detachedAt),
|
||||
}
|
||||
if len(startTimes) < 0 {
|
||||
if len(endTimes) < 0 {
|
||||
return nil, errors.New(fmt.Sprintf("无法确定表计 {%s} 的计量的终止时间", meterId))
|
||||
}
|
||||
|
||||
var startReading []model.MeterReading
|
||||
for _, reading := range meterReadings {
|
||||
readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC())
|
||||
for _, startTime := range startTimes {
|
||||
if reading.Meter == meterId && readingAt.After(startTime) || readingAt.Equal(startTime) {
|
||||
for _, endTime := range endTimes {
|
||||
if reading.Meter == meterId && readingAt.Truncate(24*time.Hour).Equal(endTime.Truncate(24*time.Hour)) || readingAt.Before(endTime) {
|
||||
startReading = append(startReading, reading)
|
||||
break
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics, summary calculate.Summary) decimal.Decimal {
|
||||
var areaMaters []calculate.Meter
|
||||
for _, t := range tenements {
|
||||
fmt.Println(t.Meters)
|
||||
areaMaters = append(areaMaters, t.Meters...)
|
||||
}
|
||||
|
||||
@ -42,7 +43,7 @@ func removeDuplicates(meters []calculate.Meter) []calculate.Meter {
|
||||
}
|
||||
|
||||
// 计算线损以及调整线损
|
||||
func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
|
||||
func LossCalculate(report *model.ReportIndex, Public []calculate.Meter,
|
||||
publicTotal *decimal.Decimal, summary *calculate.Summary) error {
|
||||
summary.Loss = summary.Overall.Amount.Sub(summary.TotalConsumption)
|
||||
|
||||
@ -56,7 +57,7 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
|
||||
summary.LossProportion = summary.Loss.Div(summaryAmount)
|
||||
|
||||
var authorizedLossRate decimal.Decimal
|
||||
//TODO: 2023.08.04 在此发现reportIndex结构体与数据库中的report表字段不对应缺少两个相应字段,在此添加的,如在其他地方有错误优先查找这里
|
||||
// TODO: 2023.08.04 在此发现reportIndex结构体与数据库中的report表字段不对应缺少两个相应字段,在此添加的,如在其他地方有错误优先查找这里
|
||||
if summary.LossProportion.InexactFloat64() > report.AuthorizedLossRate {
|
||||
authorizedLossRate = summary.LossProportion
|
||||
} else {
|
||||
@ -72,11 +73,15 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
|
||||
|
||||
differentialLoss := summary.LossDilutedPrice.Sub(summary.AuthoizeLoss.Amount)
|
||||
|
||||
fmt.Println(publicTotal.InexactFloat64())
|
||||
if publicTotal.InexactFloat64() <= decimal.Zero.InexactFloat64() {
|
||||
return errors.New("园区公共表计的电量总和为非正值,或者园区未设置公共表计,无法计算核定线损")
|
||||
}
|
||||
|
||||
for _, meter := range *Public {
|
||||
if Public == nil {
|
||||
return nil
|
||||
}
|
||||
for _, meter := range Public {
|
||||
amountProportion := meter.Overall.Amount.InexactFloat64() / publicTotal.InexactFloat64()
|
||||
adjustAmount := differentialLoss.InexactFloat64() * decimal.NewFromFloat(-1.0).InexactFloat64()
|
||||
meter.AdjustLoss = model.ConsumptionUnit{
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/model/calculate"
|
||||
"electricity_bill_calc/repository"
|
||||
"electricity_bill_calc/types"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shopspring/decimal"
|
||||
@ -42,7 +43,6 @@ func TenementMetersCalculate(report *model.ReportIndex,
|
||||
}
|
||||
|
||||
var tenementReports []calculate.PrimaryTenementStatistics
|
||||
|
||||
for _, tenement := range tenements {
|
||||
var meters []model.TenementMeter
|
||||
|
||||
@ -79,13 +79,24 @@ func determineTenementConsumptions(tenement model.Tenement,
|
||||
meterDetails []*model.MeterDetail, summary calculate.Summary) (calculate.PrimaryTenementStatistics, error) {
|
||||
var meters []calculate.Meter
|
||||
for _, meter := range relatedMeters {
|
||||
startReading, err := determineTenementMeterStartReading(meter.MeterId, periodStart, ShiftToAsiaShanghai(tenement.MovedInAt.Time), meter, currentTermReadings, lastPeriodReadings)
|
||||
|
||||
movedInAt := tenement.MovedInAt
|
||||
if movedInAt == nil {
|
||||
shiftedTime := ShiftToAsiaShanghai(time.Time{})
|
||||
movedInAt = &types.DateTime{Time: shiftedTime}
|
||||
}
|
||||
startReading, err := determineTenementMeterStartReading(meter.MeterId, periodStart, ShiftToAsiaShanghai(movedInAt.Time), meter, currentTermReadings, lastPeriodReadings)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return calculate.PrimaryTenementStatistics{}, err
|
||||
}
|
||||
|
||||
endReading, err := determineTenementMeterEndReading(meter.MeterId, periodEnd, ShiftToAsiaShanghai(tenement.MovedOutAt.Time), meter, currentTermReadings)
|
||||
moveOutAt := tenement.MovedOutAt
|
||||
if moveOutAt == nil {
|
||||
shiftedTime := ShiftToAsiaShanghai(time.Time{})
|
||||
moveOutAt = &types.DateTime{Time: shiftedTime} // 使用 types.DateTime 的零值表示时间的最大值
|
||||
}
|
||||
endReading, err := determineTenementMeterEndReading(meter.MeterId, periodEnd, ShiftToAsiaShanghai(moveOutAt.Time), meter, currentTermReadings)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return calculate.PrimaryTenementStatistics{}, err
|
||||
@ -142,7 +153,7 @@ func determineTenementConsumptions(tenement model.Tenement,
|
||||
}
|
||||
|
||||
currentTermReadingPtr := ¤tTermReading
|
||||
meter := calculate.Meter{
|
||||
m := calculate.Meter{
|
||||
Code: meter.MeterId,
|
||||
Detail: detail,
|
||||
CoveredArea: decimal.NewFromFloat(detail.Area.Decimal.InexactFloat64()),
|
||||
@ -165,7 +176,7 @@ func determineTenementConsumptions(tenement model.Tenement,
|
||||
Poolings: nil,
|
||||
}
|
||||
|
||||
meters = append(meters, meter)
|
||||
meters = append(meters, m)
|
||||
}
|
||||
|
||||
return calculate.PrimaryTenementStatistics{
|
||||
@ -272,6 +283,7 @@ func ShiftToAsiaShanghai(t time.Time) time.Time {
|
||||
func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
|
||||
summary calculate.Summary, meters MeterMap) []calculate.TenementCharge {
|
||||
result := make(map[string][]string)
|
||||
var tc []calculate.TenementCharge
|
||||
for _, t := range tenements {
|
||||
meterCodes := make([]string, 0)
|
||||
for _, m := range t.Meters {
|
||||
@ -281,11 +293,10 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
|
||||
result[t.Tenement.Id] = meterCodes
|
||||
}
|
||||
var Key Key
|
||||
var tc []calculate.TenementCharge
|
||||
for tCode, meterCodes := range result {
|
||||
relatedMeters := make([]calculate.Meter, 0)
|
||||
for _, code := range meterCodes {
|
||||
Key.Code = code + "_" + tCode
|
||||
Key.Code = code
|
||||
meter, ok := meters[Key]
|
||||
if ok {
|
||||
relatedMeters = append(relatedMeters, meter)
|
||||
@ -390,55 +401,77 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
|
||||
}
|
||||
|
||||
var CriticalProportion decimal.Decimal
|
||||
if summary.Critical.Amount == decimal.Zero {
|
||||
if summary.Critical.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
|
||||
CriticalProportion = decimal.Zero
|
||||
} else {
|
||||
CriticalProportion = decimal.NewFromFloat(critical.Amount.InexactFloat64() / summary.Critical.Amount.InexactFloat64())
|
||||
}
|
||||
|
||||
var PeakProportion decimal.Decimal
|
||||
if summary.Peak.Amount == decimal.Zero {
|
||||
if summary.Peak.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
|
||||
PeakProportion = decimal.Zero
|
||||
} else {
|
||||
PeakProportion = decimal.NewFromFloat(peak.Amount.InexactFloat64() / summary.Peak.Amount.InexactFloat64())
|
||||
}
|
||||
|
||||
var FlatProportion decimal.Decimal
|
||||
if summary.Flat.Amount == decimal.Zero {
|
||||
if summary.Flat.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
|
||||
FlatProportion = decimal.Zero
|
||||
} else {
|
||||
FlatProportion = decimal.NewFromFloat(flat.Amount.InexactFloat64() / summary.Flat.Amount.InexactFloat64())
|
||||
}
|
||||
|
||||
var ValleyProportion decimal.Decimal
|
||||
if summary.Valley.Amount == decimal.Zero {
|
||||
if summary.Valley.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
|
||||
ValleyProportion = decimal.Zero
|
||||
} else {
|
||||
ValleyProportion = decimal.NewFromFloat(valley.Amount.InexactFloat64() / summary.Valley.Amount.InexactFloat64())
|
||||
}
|
||||
|
||||
var lossProportion decimal.Decimal
|
||||
if summary.AuthoizeLoss.Amount == decimal.Zero {
|
||||
lossProportion = decimal.Zero
|
||||
} else {
|
||||
lossProportion = decimal.NewFromFloat(lossAmount.InexactFloat64() / summary.AuthoizeLoss.Amount.InexactFloat64())
|
||||
}
|
||||
tenementCharge := calculate.TenementCharge{
|
||||
Tenement: tCode,
|
||||
Overall: model.ConsumptionUnit{
|
||||
Amount: overall.Amount,
|
||||
Fee: overall.Fee,
|
||||
Price: summary.Overall.Price,
|
||||
Proportion: OverallProportion,
|
||||
},
|
||||
Critical: model.ConsumptionUnit{
|
||||
Amount: critical.Amount,
|
||||
Fee: critical.Fee,
|
||||
Price: summary.Critical.Price,
|
||||
Proportion: CriticalProportion,
|
||||
},
|
||||
Peak: model.ConsumptionUnit{
|
||||
Price: summary.Overall.Price,
|
||||
Amount: peak.Amount,
|
||||
Fee: peak.Fee,
|
||||
Price: summary.Peak.Price,
|
||||
Proportion: PeakProportion,
|
||||
},
|
||||
Flat: model.ConsumptionUnit{
|
||||
Price: summary.Overall.Price,
|
||||
Amount: flat.Amount,
|
||||
Fee: flat.Fee,
|
||||
Price: summary.Flat.Price,
|
||||
Proportion: FlatProportion,
|
||||
},
|
||||
Valley: model.ConsumptionUnit{
|
||||
Price: summary.Overall.Price,
|
||||
Amount: valley.Amount,
|
||||
Fee: valley.Fee,
|
||||
Price: summary.Valley.Price,
|
||||
Proportion: ValleyProportion,
|
||||
},
|
||||
Loss: model.ConsumptionUnit{
|
||||
Amount: lossAmount,
|
||||
Fee: lossPooled,
|
||||
Price: summary.AuthoizeLoss.Price,
|
||||
Proportion: lossProportion,
|
||||
},
|
||||
BasicFee: basicPooled,
|
||||
AdjustFee: adjustPooled,
|
||||
LossPooled: lossPooled,
|
||||
@ -450,9 +483,9 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
|
||||
Submeters: nil,
|
||||
Poolings: nil,
|
||||
}
|
||||
|
||||
tc = append(tc, tenementCharge)
|
||||
}
|
||||
}
|
||||
//fmt.Println(len(tc))
|
||||
return tc
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ func MainCalculateProcess(rid string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(report, reportSummary)
|
||||
summary := calculate.FromReportSummary(reportSummary, report)
|
||||
|
||||
periodStart := report.Period.SafeLower()
|
||||
@ -66,8 +67,8 @@ func MainCalculateProcess(rid string) error {
|
||||
// 计算所有表计的总电量
|
||||
parkTotal := TotalConsumptionCalculate(tenementReports, summary)
|
||||
|
||||
// 计算线损以及调整线损
|
||||
err = LossCalculate(report, &parkMetersReports, &parkTotal, &summary)
|
||||
//计算线损以及调整线损
|
||||
err = LossCalculate(report, parkMetersReports, &parkTotal, &summary)
|
||||
if err != nil {
|
||||
fmt.Println("9", err)
|
||||
return err
|
||||
@ -79,15 +80,13 @@ func MainCalculateProcess(rid string) error {
|
||||
fmt.Println("10", err)
|
||||
return err
|
||||
}
|
||||
// 计算基本电费分摊、调整电费分摊、电费摊薄单价。
|
||||
err = CalculatePrices(&summary)
|
||||
if err != nil {
|
||||
fmt.Println("11", err)
|
||||
return err
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// 计算基本电费分摊、调整电费分摊、电费摊薄单价。
|
||||
err = CalculatePrices(&summary)
|
||||
fmt.Println("计算数据读取完成=======================================================================================================================================================================================")
|
||||
// 收集目前所有已经处理的表计,统一对其进行摊薄计算。
|
||||
meters, err := CollectMeters(tenementReports, poolingMetersReports, parkMetersReports)
|
||||
if err != nil {
|
||||
@ -95,9 +94,6 @@ func MainCalculateProcess(rid string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
|
||||
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
|
||||
|
||||
// 根据核算报表中设置的摊薄内容,逐个表计进行计算
|
||||
err = CalculateBasicPooling(report, &summary, &meters)
|
||||
if err != nil {
|
||||
@ -115,7 +111,7 @@ func MainCalculateProcess(rid string) error {
|
||||
return err
|
||||
}
|
||||
// 计算所有商户类型表计的全周期电量,并根据全周期电量计算共用过同一表计的商户的二次分摊比例。
|
||||
_, err = CalculateTenementConsumptions(meters)
|
||||
_, err = CalculateTenementConsumptions(&meters)
|
||||
if err != nil {
|
||||
fmt.Println("16", err)
|
||||
return err
|
||||
@ -126,7 +122,7 @@ func MainCalculateProcess(rid string) error {
|
||||
return err
|
||||
}
|
||||
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
|
||||
tenementCharges = TenementChargeCalculate(tenementReports, summary, meters)
|
||||
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
|
||||
|
||||
// 从此处开始向数据库保存全部计算结果。
|
||||
ctx, cancel := global.TimeoutContext()
|
||||
@ -134,35 +130,36 @@ func MainCalculateProcess(rid string) error {
|
||||
tx, _ := global.DB.Begin(ctx)
|
||||
err = repository.CalculateRepository.ClearReportContent(tx, report.Id)
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
_ = tx.Rollback(ctx)
|
||||
fmt.Println("18", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = SaveSummary(tx, summary)
|
||||
err = SaveSummary(tx, ctx, summary)
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
_ = tx.Rollback(ctx)
|
||||
fmt.Println("19", err)
|
||||
return err
|
||||
}
|
||||
err = SavePublics(tx, *report, meters)
|
||||
err = SavePublics(tx, ctx, *report, meters)
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
_ = tx.Rollback(ctx)
|
||||
fmt.Println("20", err)
|
||||
return err
|
||||
}
|
||||
err = SavePoolings(tx, *report, meters, meterRelations)
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
_ = tx.Rollback(ctx)
|
||||
fmt.Println("21", err)
|
||||
return err
|
||||
}
|
||||
err = SaveTenements(tx, *report, tenementReports, tenementCharges)
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
_ = tx.Rollback(ctx)
|
||||
fmt.Println("22", err)
|
||||
return err
|
||||
}
|
||||
tx.Commit(ctx)
|
||||
fmt.Println("商户分摊关系保存成功")
|
||||
_ = tx.Commit(ctx)
|
||||
return nil
|
||||
}
|
||||
|
151
service/meter.go
151
service/meter.go
@ -49,7 +49,7 @@ func (ms _MeterService) CreateMeterRecord(pid string, form *vo.MeterCreationForm
|
||||
return err
|
||||
}
|
||||
|
||||
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, form.Code, form.MeterType, form.Ratio, &form.MeterReadingForm)
|
||||
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, form.Code, form.MeterType, form.Ratio, &form.Reading)
|
||||
if err != nil {
|
||||
ms.log.Error("无法记录表计读数。", zap.Error(err))
|
||||
tx.Rollback(ctx)
|
||||
@ -222,7 +222,7 @@ func (ms _MeterService) BatchImportMeters(pid string, file *multipart.FileHeader
|
||||
Building: element.Building,
|
||||
OnFloor: element.OnFloor,
|
||||
Area: element.Area,
|
||||
MeterReadingForm: vo.MeterReadingForm{
|
||||
Reading: vo.MeterReadingForm{
|
||||
ReadAt: &element.ReadAt,
|
||||
Overall: element.Overall,
|
||||
Critical: element.Critical.Decimal,
|
||||
@ -257,7 +257,7 @@ func (ms _MeterService) BatchImportMeters(pid string, file *multipart.FileHeader
|
||||
}
|
||||
// 步骤5:将全部抄表信息保存进入数据库
|
||||
for _, record := range meterCreationForms {
|
||||
_, err := repository.MeterRepository.RecordReading(tx, ctx, pid, record.Code, record.MeterType, record.Ratio, &record.MeterReadingForm)
|
||||
_, err := repository.MeterRepository.RecordReading(tx, ctx, pid, record.Code, record.MeterType, record.Ratio, &record.Reading)
|
||||
if err != nil {
|
||||
ms.log.Error("无法在数据插入阶段保存抄表信息。", zap.String("meter code", record.Code), zap.Error(err))
|
||||
tx.Rollback(ctx)
|
||||
@ -363,16 +363,16 @@ func (ms _MeterService) ReplaceMeter(
|
||||
|
||||
// 步骤6:将旧表计的部分信息赋予新表计
|
||||
newMeterCreationForm := vo.MeterCreationForm{
|
||||
Code: newMeterCode,
|
||||
Address: oldMeter.Address,
|
||||
MeterType: oldMeter.MeterType,
|
||||
Ratio: newMeterRatio,
|
||||
Seq: oldMeter.Seq,
|
||||
Enabled: oldMeter.Enabled,
|
||||
Building: oldMeter.Building,
|
||||
OnFloor: oldMeter.OnFloor,
|
||||
Area: oldMeter.Area,
|
||||
MeterReadingForm: *newMeterReading,
|
||||
Code: newMeterCode,
|
||||
Address: oldMeter.Address,
|
||||
MeterType: oldMeter.MeterType,
|
||||
Ratio: newMeterRatio,
|
||||
Seq: oldMeter.Seq,
|
||||
Enabled: oldMeter.Enabled,
|
||||
Building: oldMeter.Building,
|
||||
OnFloor: oldMeter.OnFloor,
|
||||
Area: oldMeter.Area,
|
||||
Reading: *newMeterReading,
|
||||
}
|
||||
|
||||
// 步骤7:将新表计写入系统
|
||||
@ -389,7 +389,7 @@ func (ms _MeterService) ReplaceMeter(
|
||||
}
|
||||
|
||||
// 步骤8:将新表计的读数写入系统
|
||||
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, newMeterCode, newMeterCreationForm.MeterType, newMeterCreationForm.Ratio, &newMeterCreationForm.MeterReadingForm)
|
||||
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, newMeterCode, newMeterCreationForm.MeterType, newMeterCreationForm.Ratio, &newMeterCreationForm.Reading)
|
||||
switch {
|
||||
case err != nil:
|
||||
ms.log.Error("无法将新表计的读数写入系统。", zap.Error(err))
|
||||
@ -444,6 +444,118 @@ func (ms _MeterService) ReplaceMeter(
|
||||
return nil
|
||||
}
|
||||
|
||||
//func replaceMeter(
|
||||
// pid string,
|
||||
// oldMeterCode string,
|
||||
// oldMeterReading *MeterReadingForm,
|
||||
// newMeterCode string,
|
||||
// newMeterRatio *big.Float,
|
||||
// newMeterReading *MeterReadingForm,
|
||||
//) (bool, error) {
|
||||
// ctx := context.Background()
|
||||
// tx, err := PostgresPool{}.begin(ctx)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤1:获取旧表计的信息
|
||||
// oldMeter, err := repositories{}.meter_fetch_meter_detail(pid, oldMeterCode)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
// if oldMeter == nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, fmt.Errorf("要替换的旧表计不存在")
|
||||
// }
|
||||
//
|
||||
// // 步骤2:将旧表计的读数写入读数表
|
||||
// err = repositories{}.meter_record_reading(tx, pid, oldMeterCode, oldMeter.MeterType, oldMeter.Ratio, oldMeterReading)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤3: 将旧表计从系统中移除
|
||||
// err = repositories{}.meter_detach_meter(tx, pid, oldMeterCode)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤4: 获取旧表计的关联信息
|
||||
// var oldMeterAssociations []*MeterRelation
|
||||
// if oldMeter.MeterType == Pooling {
|
||||
// oldMeterAssociations, err = repositories{}.meter_list_pooled_meter_relations(pid, oldMeterCode)
|
||||
// } else {
|
||||
// oldMeterAssociations, err = repositories{}.meter_list_meter_relations(pid, oldMeterCode)
|
||||
// }
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤5: 将旧表计的关联信息全部置为解除
|
||||
// for _, relation := range oldMeterAssociations {
|
||||
// err = repositories{}.meter_unbind_meter(tx, pid, relation.MasterMeter, relation.SlaveMeter)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 步骤6: 将旧表计的部分信息赋予新表计
|
||||
// newMeterCreationForm := &MeterCreationForm{
|
||||
// Code: newMeterCode,
|
||||
// Address: oldMeter.Address,
|
||||
// MeterType: oldMeter.MeterType,
|
||||
// Ratio: newMeterRatio,
|
||||
// Seq: oldMeter.Seq,
|
||||
// // Assign other fields
|
||||
// Reading: newMeterReading,
|
||||
// }
|
||||
//
|
||||
// // 步骤7: 将新表计写入系统
|
||||
// err = repositories{}.meter_create_meter(tx, pid, newMeterCreationForm)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤8: 将新表计的读数写入读数表
|
||||
// err = repositories{}.meter_record_reading(tx, pid, newMeterCode, oldMeter.MeterType, newMeterRatio, newMeterReading)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 步骤9: 将旧表计的关联信息复制一份并赋予新表计
|
||||
// if oldMeter.MeterType == Pooling {
|
||||
// for _, relation := range oldMeterAssociations {
|
||||
// err = repositories{}.meter_bind_meter(tx, pid, newMeterCode, relation.SlaveMeter)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// for _, relation := range oldMeterAssociations {
|
||||
// err = repositories{}.meter_bind_meter(tx, pid, relation.MasterMeter, newMeterCode)
|
||||
// if err != nil {
|
||||
// tx.rollback(ctx)
|
||||
// return false, err
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// err = tx.commit(ctx)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// return true, nil
|
||||
//}
|
||||
|
||||
// 列出园区中指定公摊表计下的所有关联表计
|
||||
func (ms _MeterService) ListPooledMeterRelations(pid, masterMeter string) ([]*model.MeterDetail, error) {
|
||||
ms.log.Info("列出园区中指定公摊表计下的所有关联表计", zap.String("park id", pid), zap.String("meter code", masterMeter))
|
||||
@ -587,7 +699,7 @@ func (ms _MeterService) UnbindMeter(pid, masterMeter string, slaveMeters []strin
|
||||
}
|
||||
|
||||
// 查询符合条件的表计读数记录
|
||||
func (ms _MeterService) SearchMeterReadings(pid string, building *string, start, end *types.Date, page uint, keyword *string) ([]*model.DetailedMeterReading, int64, error) {
|
||||
func (ms _MeterService) SearchMeterReadings(pid string, building *string, start, end *types.Date, page uint, keyword *string, mtype uint) ([]*model.DetailedMeterReading, int64, error) {
|
||||
ms.log.Info(
|
||||
"查询符合条件的表计读数记录",
|
||||
zap.String("park id", pid),
|
||||
@ -597,7 +709,7 @@ func (ms _MeterService) SearchMeterReadings(pid string, building *string, start,
|
||||
zap.Uint("page", page),
|
||||
zap.Stringp("keyword", keyword),
|
||||
)
|
||||
readings, total, err := repository.MeterRepository.ListMeterReadings(pid, keyword, page, start, end, building)
|
||||
readings, total, err := repository.MeterRepository.ListMeterReadings(pid, keyword, page, start, end, building, mtype)
|
||||
if err != nil {
|
||||
ms.log.Error("无法查询符合条件的表计读数记录。", zap.Error(err))
|
||||
return make([]*model.DetailedMeterReading, 0), 0, err
|
||||
@ -777,3 +889,10 @@ func (ms _MeterService) BatchImportReadings(pid string, file *multipart.FileHead
|
||||
}
|
||||
return make([]excel.ExcelAnalysisError, 0), nil
|
||||
}
|
||||
|
||||
//// 更换系统中的表计
|
||||
//func (ms _MeterService) ReplaceMeter(pid string, oldMeterCode string, oldMeterReading vo.MeterReadingForm,
|
||||
// newMeterCode string, newMeterRatio decimal.Decimal, newMeterDisplayRatio decimal.Decimal,
|
||||
// newMeterReading vo.NewMeterForReplacingForm) {
|
||||
//
|
||||
//}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"electricity_bill_calc/types"
|
||||
"electricity_bill_calc/vo"
|
||||
"github.com/pkg/errors"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
@ -209,30 +210,35 @@ func (rs _ReportService) ReportCalcuateDispatch(rid string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//创建一个新的核算报表,并同时完成核算报表的计算
|
||||
// 创建一个新的核算报表,并同时完成核算报表的计算
|
||||
func (rs _ReportService) CreateNewReport(createFrom *vo.ReportCreationForm) (bool, error) {
|
||||
state, report, err := repository.ReportRepository.CreateReport(createFrom)
|
||||
if err != nil {
|
||||
rs.log.Error("创建核算报表错误", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
|
||||
if !state {
|
||||
status, err := repository.CalculateRepository.UpdateReportCalculateStatus(report, "InsufficientData", "创建报表时发生错误,需手动再次计算")
|
||||
status, err := repository.CalculateRepository.UpdateReportCalculateStatus(report, "InsufficientData",
|
||||
"创建报表时发生错误,需手动再次计算")
|
||||
if err != nil {
|
||||
rs.log.Error("创建报表时发生错误,需手动再次计算", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
err = rs.CalculateReport(report)
|
||||
if err != nil {
|
||||
rs.log.Error("计算时出错", zap.Error(err))
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
//更新一个核算报表中的数据,并同时完成计算
|
||||
// 更新一个核算报表中的数据,并同时完成计算
|
||||
func (rs _ReportService) UpdateRepoet(rid string, updateForm *vo.ReportModifyForm) (bool, error) {
|
||||
state, err := repository.ReportRepository.UpdateReportSummary(rid, updateForm)
|
||||
if err != nil {
|
||||
@ -258,10 +264,10 @@ var CALCULATE_TASK_PARALLEL_CONTROL = func() *sync.Mutex {
|
||||
|
||||
// 执行一个核算报表的计算任务
|
||||
func (rs _ReportService) CalculateReport(rid string) error {
|
||||
semaphore := CALCULATE_TASK_PARALLEL_CONTROL
|
||||
|
||||
semaphore.Lock()
|
||||
defer semaphore.Unlock()
|
||||
//semaphore := CALCULATE_TASK_PARALLEL_CONTROL
|
||||
//
|
||||
//semaphore.Lock()
|
||||
//defer semaphore.Unlock()
|
||||
|
||||
errs := calculate.MainCalculateProcess(rid)
|
||||
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"electricity_bill_calc/repository"
|
||||
"electricity_bill_calc/vo"
|
||||
"fmt"
|
||||
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@ -82,7 +81,7 @@ func (ts _TenementService) BindMeter(pid, tid, meterCode string, reading *vo.Met
|
||||
tx.Rollback(ctx)
|
||||
return fmt.Errorf("未能获取表计详细信息,%w", err)
|
||||
}
|
||||
err = repository.TenementRepository.BindMeter(tx, ctx, pid, tid, meterCode)
|
||||
err = repository.TenementRepository.BindMeter(tx, ctx, pid, tid, meterCode, reading)
|
||||
if err != nil {
|
||||
ts.log.Error("向商户绑定一个新表计失败,未能绑定表计", zap.Error(err))
|
||||
tx.Rollback(ctx)
|
||||
@ -201,7 +200,7 @@ func (ts _TenementService) MoveOutTenement(pid, tid string, reading []*vo.MeterR
|
||||
tx.Rollback(ctx)
|
||||
return fmt.Errorf("找不到指定表计[%s]的抄表信息,%w", meterCode, err)
|
||||
}
|
||||
if reading.Validate() {
|
||||
if !reading.Validate() {
|
||||
ts.log.Error("迁出指定商户失败,表计读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", zap.String("Meter", meterCode))
|
||||
tx.Rollback(ctx)
|
||||
return fmt.Errorf("表计[%s]读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", meterCode)
|
||||
|
75
vo/meter.go
75
vo/meter.go
@ -1,22 +1,24 @@
|
||||
package vo
|
||||
|
||||
import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/types"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type MeterCreationForm struct {
|
||||
Code string `json:"code"`
|
||||
Address *string `json:"address"`
|
||||
Ratio decimal.Decimal `json:"ratio"`
|
||||
Seq int64 `json:"seq"`
|
||||
MeterType int16 `json:"type"`
|
||||
Building *string `json:"building"`
|
||||
OnFloor *string `json:"onFloor"`
|
||||
Area decimal.NullDecimal `json:"area"`
|
||||
Enabled bool `json:"enabled"`
|
||||
MeterReadingForm `json:"-"`
|
||||
Code string `json:"code"`
|
||||
Address *string `json:"address"`
|
||||
Ratio decimal.Decimal `json:"ratio"`
|
||||
Seq int64 `json:"seq"`
|
||||
MeterType int16 `json:"type"`
|
||||
Building *string `json:"building"`
|
||||
OnFloor *string `json:"onFloor"`
|
||||
Area decimal.NullDecimal `json:"area"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Reading MeterReadingForm `json:"reading"`
|
||||
}
|
||||
|
||||
type MeterModificationForm struct {
|
||||
@ -59,7 +61,7 @@ type SimplifiedMeterDetailResponse struct {
|
||||
Area decimal.Decimal `json:"area"`
|
||||
Enabled bool `json:"enabled"`
|
||||
MeterType int16 `json:"type"`
|
||||
AttachedAt types.DateTime `json:"attachedAt"`
|
||||
AttachedAt *types.DateTime `json:"attachedAt"`
|
||||
DetachedAt *types.DateTime `json:"detachedAt"`
|
||||
}
|
||||
type ReadableMeterQueryResponse struct {
|
||||
@ -67,3 +69,54 @@ type ReadableMeterQueryResponse struct {
|
||||
Address *string `json:"address"`
|
||||
Park string `json:"park"`
|
||||
}
|
||||
|
||||
type ReportPublishResponse struct {
|
||||
//ID string
|
||||
ReportID string `json:"report_id" db:"report_id"` // 报告ID
|
||||
ParkMeterID string `json:"park_meter_id" db:"park_meter_id"` // 停车计费ID
|
||||
Overall model.ConsumptionUnit `json:"overall" db:"overall"` // 总体信息
|
||||
Critical model.ConsumptionUnit `json:"critical" db:"critical"` // 关键信息
|
||||
Peak model.ConsumptionUnit `json:"peak" db:"peak"` // 高峰信息
|
||||
Flat model.ConsumptionUnit `json:"flat" db:"flat"` // 平峰信息
|
||||
Valley model.ConsumptionUnit `json:"valley" db:"valley"` // 谷峰信息
|
||||
LossAdjust model.ConsumptionUnit `json:"loss_adjust" db:"loss_adjust"` // 损耗调整信息
|
||||
ConsumptionTotal float64 `json:"consumption_total" db:"consumption_total"` // 总消费量
|
||||
LossAdjustTotal float64 `json:"loss_adjust_total" db:"loss_adjust_total"` // 总损耗调整
|
||||
FinalTotal float64 `json:"final_total" db:"final_total"` // 最终总量
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"` // 创建时间
|
||||
LastModifiedAt time.Time `json:"last_modified_at" db:"last_modified_at"` // 最后修改时间
|
||||
Code string `json:"code" db:"code"` // 代码
|
||||
ParkID string `json:"park_id" db:"park_id"` // 停车场ID
|
||||
Address *string `json:"address" db:"address"` // 地址
|
||||
Ratio decimal.Decimal `json:"ratio" db:"ratio"` // 比率
|
||||
Seq int64 `json:"seq" db:"seq"` // 序列号
|
||||
Enabled bool `json:"enabled" db:"enabled"` // 是否启用
|
||||
MeterType int16 `json:"meter_type" db:"meter_type"` // 计量类型
|
||||
Building *string `json:"building" db:"building"` // 建筑物
|
||||
OnFloor *string `json:"on_floor" db:"on_floor"` // 楼层
|
||||
Area decimal.NullDecimal `json:"area" db:"area"` // 面积
|
||||
AttachedAt *types.DateTime `json:"attached_at" db:"attached_at"` // 附加时间
|
||||
DetachedAt *types.DateTime `json:"detached_at" db:"detached_at"` // 分离时间
|
||||
DisplayRatio float64 `json:"display_ratio" db:"display_ratio"` // 显示比例
|
||||
BuildingName *string `json:"building_name" db:"building_name"` // 建筑物名称
|
||||
PublicPooled int16 `json:"public_pooled" db:"public_pooled"` // 公共汇总
|
||||
}
|
||||
|
||||
type Public struct {
|
||||
Address *string `json:"address"` // 户址
|
||||
AdjustLoss model.ConsumptionUnit `json:"adjustLoss"` // 调整线损数据,仅运维可见,仅使用其中`amount`内容
|
||||
Area string `json:"area"` // 所辖面积
|
||||
AttachedAt *types.DateTime `json:"attachedAt"` // 接入系统时间,挂表
|
||||
Building *string `json:"building"` // 所在建筑ID
|
||||
BuildingName *string `json:"buildingName"` // 所在建筑名称
|
||||
Code string `json:"code"` // 表计表号
|
||||
DetachedAt *types.DateTime `json:"detachedAt"` // 从系统移除时间,拆表
|
||||
DisplayRatio string `json:"displayRatio"` // 表计表显倍率,仅用于展示。
|
||||
Enabled bool `json:"enabled"` // 是否可用
|
||||
OnFloor *string `json:"onFloor"` // 所在楼层
|
||||
Overall model.ConsumptionUnit `json:"overall"` // 总电量部分
|
||||
ParkID string `json:"parkId"` // 所属园区ID
|
||||
Ratio string `json:"ratio"` // 表计计算倍率,参与表计读数计算。
|
||||
Seq int64 `json:"seq"` // 抄表序号
|
||||
Type float64 `json:"type"` // 表计类型,0:商户电表,1:园区电表,2:公摊电表
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/types"
|
||||
"fmt"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
@ -19,7 +18,8 @@ type MeterReadingForm struct {
|
||||
|
||||
func (r MeterReadingForm) Validate() bool {
|
||||
flat := r.Overall.Sub(r.Critical).Sub(r.Peak).Sub(r.Valley)
|
||||
return flat.GreaterThanOrEqual(decimal.Zero)
|
||||
b := flat.GreaterThanOrEqual(decimal.Zero)
|
||||
return b
|
||||
}
|
||||
|
||||
type MeterReadingFormWithCode struct {
|
||||
|
@ -18,6 +18,7 @@ type TenementCreationForm struct {
|
||||
InvoicePhone *string `json:"invoicePhone"`
|
||||
Bank *string `json:"bank"`
|
||||
Account *string `json:"bankAccount"`
|
||||
MoveIn *string `json:"moveIn"`
|
||||
}
|
||||
|
||||
type TenementQueryResponse struct {
|
||||
|
@ -22,4 +22,5 @@ type TopUpDetailQueryResponse struct {
|
||||
Amount decimal.Decimal `json:"amount"`
|
||||
PaymentType int16 `json:"paymentType"`
|
||||
SyncStatus int16 `json:"syncStatus" copier:"SyncStatus"`
|
||||
CancelledAt *types.DateTime `json:"cancelledAt"` // TODO: 2023.08.11 在查询充值记录的时候发现缺少该字段(已添加)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user