fix(#10): 修复创建报表错误

This commit is contained in:
2023-08-14 10:05:09 +08:00
parent 559c2d439d
commit 845bd75348
7 changed files with 199 additions and 171 deletions

View File

@@ -3,7 +3,6 @@ package calculate
import (
"electricity_bill_calc/model"
"electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository"
"errors"
"fmt"
"github.com/shopspring/decimal"
@@ -189,147 +188,169 @@ func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summa
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
}
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
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)
}
// 计算并更新公摊分摊信息
for _, p := range pooleds {
poolingAmount := p.PooledAmount
proportion := p.PooledAmount.Div(p.ParentAmount)
fee := poolingAmount.Mul(summary.Overall.Price)
consumptions := 0.00
total := 0.00
var pooled []*calculate.Pooling
// 更新父级表计的公摊分摊信息
key := Key{
Code: p.ParentCode,
for _, p := range pooleds {
consumptions += p.Electricity.InexactFloat64()
total += p.ParentElectricity.InexactFloat64()
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
}

View File

@@ -1,43 +1,41 @@
package calculate
import (
"context"
"electricity_bill_calc/global"
"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()
// 保存核算概况结果到数据库
err := repository.CalculateRepository.SaveReportSummary(tx, 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
}

View File

@@ -94,7 +94,7 @@ func determineTenementConsumptions(tenement model.Tenement,
moveOutAt := tenement.MovedOutAt
if moveOutAt == nil {
shiftedTime := ShiftToAsiaShanghai(time.Time{})
moveOutAt = &types.DateTime{Time: shiftedTime}// 使用 types.DateTime 的零值表示时间的最大值
moveOutAt = &types.DateTime{Time: shiftedTime} // 使用 types.DateTime 的零值表示时间的最大值
}
endReading, err := determineTenementMeterEndReading(meter.MeterId, periodEnd, ShiftToAsiaShanghai(moveOutAt.Time), meter, currentTermReadings)
if err != nil {
@@ -296,7 +296,7 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
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)
@@ -401,28 +401,29 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
}
var CriticalProportion decimal.Decimal
if summary.Critical.Amount == decimal.Zero {
fmt.Println(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())
@@ -465,5 +466,6 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
tc = append(tc, tenementCharge)
}
}
fmt.Println(tc)
return tc
}

View File

@@ -94,9 +94,6 @@ func MainCalculateProcess(rid string) error {
return err
}
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
// 根据核算报表中设置的摊薄内容,逐个表计进行计算
err = CalculateBasicPooling(report, &summary, &meters)
if err != nil {
@@ -125,7 +122,7 @@ func MainCalculateProcess(rid string) error {
return err
}
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
tenementCharges = TenementChargeCalculate(tenementReports, summary, meters)
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
// 从此处开始向数据库保存全部计算结果。
ctx, cancel := global.TimeoutContext()
@@ -133,35 +130,35 @@ 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)
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)
_ = tx.Commit(ctx)
return nil
}