Merge pull request 'ZiHangQinBranch' (#2) from ZiHangQin/electricity_bill_calc_service:ZiHangQinBranch into 0.2

Reviewed-on: free-lancers/electricity_bill_calc_service#2
This commit is contained in:
Khadgar 2023-08-04 15:01:24 +08:00
commit 79d55505a7
4 changed files with 236 additions and 4 deletions

View File

@ -0,0 +1,10 @@
package calculate
import "electricity_bill_calc/model/calculate"
// / 合并所有的表计
type Key struct {
Code string
TenementID string
}
type MeterMap map[Key]calculate.Meter

View File

@ -90,7 +90,8 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
}
// 计算已经启用的商铺面积和
func EnabledAreaCalculate(tenements *[]calculate.PrimaryTenementStatistics, summary *calculate.Summary) error {
func EnabledAreaCalculate(tenements *[]calculate.PrimaryTenementStatistics,
summary *calculate.Summary) error {
var areaMeters []calculate.Meter
for _, t := range *tenements {
areaMeters = append(areaMeters, t.Meters...)
@ -111,3 +112,23 @@ func EnabledAreaCalculate(tenements *[]calculate.PrimaryTenementStatistics, summ
}
return nil
}
// 计算基本电费分摊、调整电费分摊以及电费摊薄单价。
func PricesCalculate(summary *calculate.Summary) error {
if summary.TotalConsumption.IsZero() {
return nil
}
summary.BasicPooledPriceConsumption = summary.BasicFee.Div(summary.TotalConsumption)
if summary.OverallArea.IsZero() {
summary.BasicPooledPriceArea = decimal.Zero
} else {
summary.BasicPooledPriceArea = summary.BasicFee.Div(summary.OverallArea)
}
summary.AdjustPooledPriceConsumption = summary.AdjustFee.Div(summary.TotalConsumption)
if summary.OverallArea.IsZero() {
summary.AdjustPooledPriceArea = decimal.Zero
} else {
summary.AdjustPooledPriceArea = summary.AdjustFee.Div(summary.OverallArea)
}
return nil
}

View File

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"github.com/shopspring/decimal"
"sort"
"strings"
"time"
"unsafe"
@ -266,3 +267,192 @@ func ShiftToAsiaShanghai(t time.Time) time.Time {
location, _ := time.LoadLocation("Asia/Shanghai")
return t.In(location)
}
// 计算各个商户的合计信息,并归总与商户关联的表计记录
func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
summary calculate.Summary, meters MeterMap) []calculate.TenementCharge {
result := make(map[string][]string)
for _, t := range tenements {
meterCodes := make([]string, 0)
for _, m := range t.Meters {
meterCodes = append(meterCodes, m.Code)
}
sort.Strings(meterCodes)
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
meter, ok := meters[Key]
if ok {
relatedMeters = append(relatedMeters, meter)
}
}
// 计算商户的合计电费信息
var overall model.ConsumptionUnit
var critical model.ConsumptionUnit
var peak model.ConsumptionUnit
var flat model.ConsumptionUnit
var valley model.ConsumptionUnit
var basicPooled decimal.Decimal
var adjustPooled decimal.Decimal
var lossAmount decimal.Decimal
var lossPooled decimal.Decimal
var publicPooled decimal.Decimal
for _, meter := range relatedMeters {
overall.Amount.Add(meter.Overall.Amount)
overall.Fee.Add(meter.Overall.Fee)
critical.Amount.Add(meter.Critical.Amount)
critical.Fee.Add(meter.Critical.Fee)
peak.Amount.Add(meter.Peak.Amount)
peak.Fee.Add(meter.Peak.Fee)
flat.Amount.Add(meter.Flat.Amount)
flat.Fee.Add(meter.Flat.Fee)
valley.Amount.Add(meter.Valley.Amount)
valley.Fee.Add(meter.Valley.Fee)
basicPooled.Add(meter.PooledBasic.Fee)
adjustPooled.Add(meter.PooledAdjust.Fee)
lossAmount.Add(meter.PooledLoss.Amount)
lossPooled.Add(meter.PooledLoss.Fee)
publicPooled.Add(meter.PooledPublic.Fee)
// 反写商户表计的统计数据
meter.Overall.Proportion = func() decimal.Decimal {
if overall.Amount.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.Overall.Amount.Div(overall.Amount)
}()
meter.Critical.Proportion = func() decimal.Decimal {
if critical.Amount.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.Critical.Amount.Div(critical.Amount)
}()
meter.Peak.Proportion = func() decimal.Decimal {
if peak.Amount.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.Peak.Amount.Div(peak.Amount)
}()
meter.Flat.Proportion = func() decimal.Decimal {
if flat.Amount.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.Flat.Amount.Div(flat.Amount)
}()
meter.Valley.Proportion = func() decimal.Decimal {
if valley.Amount.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.Valley.Amount.Div(valley.Amount)
}()
meter.PooledBasic.Proportion = func() decimal.Decimal {
if basicPooled.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.PooledBasic.Fee.Div(basicPooled)
}()
meter.PooledAdjust.Proportion = func() decimal.Decimal {
if adjustPooled.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.PooledAdjust.Fee.Div(adjustPooled)
}()
meter.PooledLoss.Proportion = func() decimal.Decimal {
if lossPooled.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.PooledLoss.Fee.Div(lossPooled)
}()
meter.PooledPublic.Proportion = func() decimal.Decimal {
if publicPooled.Equal(decimal.Zero) {
return decimal.Zero
}
return meter.PooledPublic.Fee.Div(publicPooled)
}()
var OverallProportion decimal.Decimal
if summary.Overall.Amount == decimal.Zero {
OverallProportion = decimal.Zero
} else {
OverallProportion = decimal.NewFromFloat(overall.Amount.InexactFloat64() / summary.Overall.Amount.InexactFloat64())
}
var CriticalProportion decimal.Decimal
if summary.Critical.Amount == decimal.Zero {
CriticalProportion = decimal.Zero
} else {
CriticalProportion = decimal.NewFromFloat(critical.Amount.InexactFloat64() / summary.Critical.Amount.InexactFloat64())
}
var PeakProportion decimal.Decimal
if summary.Peak.Amount == decimal.Zero {
PeakProportion = decimal.Zero
} else {
PeakProportion = decimal.NewFromFloat(peak.Amount.InexactFloat64() / summary.Peak.Amount.InexactFloat64())
}
var FlatProportion decimal.Decimal
if summary.Flat.Amount == decimal.Zero {
FlatProportion = decimal.Zero
} else {
FlatProportion = decimal.NewFromFloat(flat.Amount.InexactFloat64() / summary.Flat.Amount.InexactFloat64())
}
var ValleyProportion decimal.Decimal
if summary.Valley.Amount == decimal.Zero {
ValleyProportion = decimal.Zero
} else {
ValleyProportion = decimal.NewFromFloat(valley.Amount.InexactFloat64() / summary.Valley.Amount.InexactFloat64())
}
tenementCharge := calculate.TenementCharge{
Tenement: tCode,
Overall: model.ConsumptionUnit{
Price: summary.Overall.Price,
Proportion: OverallProportion,
},
Critical: model.ConsumptionUnit{
Price: summary.Critical.Price,
Proportion: CriticalProportion,
},
Peak: model.ConsumptionUnit{
Price: summary.Overall.Price,
Proportion: PeakProportion,
},
Flat: model.ConsumptionUnit{
Price: summary.Overall.Price,
Proportion: FlatProportion,
},
Valley: model.ConsumptionUnit{
Price: summary.Overall.Price,
Proportion: ValleyProportion,
},
BasicFee: basicPooled,
AdjustFee: adjustPooled,
LossPooled: lossPooled,
PublicPooled: publicPooled,
FinalCharges: decimal.NewFromFloat(
overall.Fee.InexactFloat64() + basicPooled.InexactFloat64() +
adjustPooled.InexactFloat64() + lossPooled.InexactFloat64() +
publicPooled.InexactFloat64()),
Submeters: nil,
Poolings: nil,
}
tc = append(tc, tenementCharge)
}
}
return tc
}

View File

@ -74,11 +74,22 @@ func MainCalculateProcess(rid string) {
// 计算所有已经启用的商铺面积总和,仅计算所有未迁出的商户的所有表计对应的商铺面积。
err = EnabledAreaCalculate(&tenementReports, &summary)
if err != nil{
fmt.Println("10",err)
if err != nil {
fmt.Println("10", err)
return
}
err = PricesCalculate(&summary)
if err != nil {
fmt.Println("11", err)
return
}
fmt.Println(meterRelations, poolingMetersReports, parkMetersReports, parkTotal)
//为获取值初始化一个空的,合并分支时可忽略
var meters MeterMap
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
fmt.Println(meterRelations, poolingMetersReports, tenementCharges)
}