diff --git a/service/calculate/meter.go b/service/calculate/meter.go new file mode 100644 index 0000000..b30cb72 --- /dev/null +++ b/service/calculate/meter.go @@ -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 diff --git a/service/calculate/summary.go b/service/calculate/summary.go index 26d5620..13ba004 100644 --- a/service/calculate/summary.go +++ b/service/calculate/summary.go @@ -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 +} \ No newline at end of file diff --git a/service/calculate/tenement.go b/service/calculate/tenement.go index 1749140..9bc9b74 100644 --- a/service/calculate/tenement.go +++ b/service/calculate/tenement.go @@ -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 +} diff --git a/service/calculate/wattCost.go b/service/calculate/wattCost.go index fe14ba6..113eaab 100644 --- a/service/calculate/wattCost.go +++ b/service/calculate/wattCost.go @@ -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) }