electricity_bill_calc_service/service/calculate/summary.go

90 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package calculate
import (
"electricity_bill_calc/model"
"electricity_bill_calc/model/calculate"
"errors"
"fmt"
"github.com/shopspring/decimal"
)
// 计算已经启用的商铺面积和
func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics,
summary calculate.Summary) decimal.Decimal {
var areaMaters []calculate.Meter
for _, t := range tenements {
areaMaters = append(areaMaters, t.Meters...)
}
areaMaters = removeDuplicates(areaMaters)
var areaTotal float64
for _, m := range areaMaters {
areaTotal += m.Detail.Area.Decimal.InexactFloat64()
}
areaTotal += summary.OverallArea.InexactFloat64()
return decimal.NewFromFloat(areaTotal)
}
func removeDuplicates(meters []calculate.Meter) []calculate.Meter {
result := make([]calculate.Meter, 0, len(meters))
seen := make(map[string]bool)
for _, meter := range meters {
if !seen[meter.Code] {
seen[meter.Code] = true
result = append(result, meter)
}
}
return result
}
//计算线损以及调整线损
func LossCalculate(report *model.ReportIndex, Public []calculate.Meter,
publicTotal decimal.Decimal, summary calculate.Summary) error {
summary.Loss = summary.Overall.Amount.Sub(summary.TotalConsumption)
var summaryAmount decimal.Decimal
if summary.Overall.Amount == decimal.Zero {
summaryAmount = decimal.NewFromFloat(1.0)
} else {
summaryAmount = summary.Overall.Amount
}
summary.LossProportion = summary.Loss.Div(summaryAmount)
var authorizedLossRate decimal.Decimal
if summary.LossProportion.InexactFloat64() > report.AuthorizedLossRate {
authorizedLossRate = summary.LossProportion
} else {
return errors.New(fmt.Sprintf("经过核算园区的线损率为:{%.8f} 核定线损率为:{%.8f}", summary.LossProportion.InexactFloat64(),authorizedLossRate.InexactFloat64()))
}
summary.AuthoizeLoss = model.ConsumptionUnit{
Amount: decimal.NewFromFloat(summary.Overall.Amount.InexactFloat64() * authorizedLossRate.InexactFloat64()),
Fee: decimal.NewFromFloat((summary.Overall.Amount.InexactFloat64() * authorizedLossRate.InexactFloat64()) * summary.Overall.Price.InexactFloat64()),
Price: summary.Overall.Price,
Proportion: authorizedLossRate,
}
differentialLoss := summary.LossDilutedPrice.Sub(summary.AuthoizeLoss.Amount)
if publicTotal.InexactFloat64() <= decimal.Zero.InexactFloat64() {
return errors.New("园区公共表计的电量总和为非正值,或者园区未设置公共表计,无法计算核定线损")
}
for _, meter := range Public {
amountProportion := meter.Overall.Amount.InexactFloat64() / publicTotal.InexactFloat64()
adjustAmount := differentialLoss.InexactFloat64() * decimal.NewFromFloat(-1.0).InexactFloat64()
meter.AdjustLoss = model.ConsumptionUnit{
Amount: decimal.NewFromFloat(adjustAmount),
Fee: decimal.NewFromFloat(adjustAmount * summary.LossDilutedPrice.InexactFloat64()),
Price: summary.LossDilutedPrice,
Proportion: decimal.NewFromFloat(amountProportion),
}
}
return nil
}