electricity_bill_calc_service/service/calculate/utils.go

142 lines
5.2 KiB
Go

package calculate
import (
"electricity_bill_calc/model"
"electricity_bill_calc/model/calculate"
"errors"
"fmt"
"github.com/shopspring/decimal"
)
// 计算两个读书之间的有功(总)电量
func ComputeOverall(startReading model.MeterReading, endReading model.MeterReading, summary calculate.Summary) (model.ConsumptionUnit, error) {
start := startReading.Overall.InexactFloat64() * startReading.Ratio.InexactFloat64()
end := endReading.Overall.InexactFloat64() * endReading.Ratio.InexactFloat64()
if start > end {
return model.ConsumptionUnit{}, errors.New(fmt.Sprintf("表计 {%s} 有功(总)开始读数 {%x} 大于结束读数 {%x}", startReading.Meter, start, end))
}
amount := end - start
var summaryAmount float64
if summary.Overall.Amount == decimal.Zero {
summaryAmount = decimal.NewFromFloat(1.0).InexactFloat64()
} else {
summaryAmount = summary.Overall.Amount.InexactFloat64()
}
return model.ConsumptionUnit{
Amount: decimal.NewFromFloat(amount),
Fee: decimal.NewFromFloat(amount * summary.Overall.Price.InexactFloat64()),
Price: decimal.NewFromFloat(summary.Overall.Price.InexactFloat64()),
Proportion: decimal.NewFromFloat(amount / summaryAmount),
}, nil
}
//计算两个读书之间的尖峰电量
func ComputeCritical(startReading model.MeterReading, endReading model.MeterReading, summary calculate.Summary) (model.ConsumptionUnit, error) {
start := startReading.Critical.InexactFloat64() * startReading.Ratio.InexactFloat64()
end := endReading.Critical.InexactFloat64() * endReading.Ratio.InexactFloat64()
if start > end {
return model.ConsumptionUnit{}, errors.New(fmt.Sprintf("尖峰开始读数 {%x} 大于结束读数 {%x}", start, end))
}
amount := end - start
var summaryAmount float64
if summary.Critical.Amount.Equal(decimal.Zero) {
summaryAmount = decimal.NewFromFloat(1.0).InexactFloat64()
} else {
summaryAmount = summary.Critical.Amount.InexactFloat64()
}
return model.ConsumptionUnit{
Amount: decimal.NewFromFloat(amount),
Fee: decimal.NewFromFloat(amount * summary.Critical.Amount.InexactFloat64()),
Price: decimal.NewFromFloat(summary.Critical.Price.InexactFloat64()),
Proportion: decimal.NewFromFloat(amount / summaryAmount),
}, nil
}
// 计算两个读数之间的峰电量
func ComputePeak(startReading model.MeterReading, endReading model.MeterReading, summary calculate.Summary) (model.ConsumptionUnit, error) {
start := startReading.Peak.InexactFloat64() * startReading.Ratio.InexactFloat64()
end := startReading.Peak.InexactFloat64() * endReading.Ratio.InexactFloat64()
if start > end {
return model.ConsumptionUnit{}, errors.New(fmt.Sprintf("峰开始读数 {%x} 大于结束读数 {%x}", start, end))
}
amount := end - start
var summaryAmount float64
if summary.Peak.Amount.Equal(decimal.Zero) {
summaryAmount = decimal.NewFromFloat(1.0).InexactFloat64()
} else {
summaryAmount = summary.Peak.Amount.InexactFloat64()
}
return model.ConsumptionUnit{
Amount: decimal.NewFromFloat(amount),
Fee: decimal.NewFromFloat(amount * summary.Peak.Price.InexactFloat64()),
Price: decimal.NewFromFloat(summary.Peak.Price.InexactFloat64()),
Proportion: decimal.NewFromFloat(amount / summaryAmount),
}, nil
}
//计算两个读数之间的平电量
func ComputeFlat(startReading model.MeterReading, endReading model.MeterReading, summary calculate.Summary) (model.ConsumptionUnit, error) {
start := startReading.Flat.InexactFloat64() * startReading.Ratio.InexactFloat64()
end := endReading.Flat.InexactFloat64() * endReading.Ratio.InexactFloat64()
if start > end {
return model.ConsumptionUnit{}, errors.New(fmt.Sprintf("平开始读数 {%x} 大于结束读数 {%x}", start, end))
}
amount := end - start
var summaryAmount float64
if summary.Flat.Amount.Equal(decimal.Zero) {
summaryAmount = decimal.NewFromFloat(1.0).InexactFloat64()
} else {
summaryAmount = summary.Flat.Amount.InexactFloat64()
}
return model.ConsumptionUnit{
Amount: decimal.NewFromFloat(amount),
Fee: decimal.NewFromFloat(amount * summary.Flat.Price.InexactFloat64()),
Price: decimal.NewFromFloat(summary.Flat.Price.InexactFloat64()),
Proportion: decimal.NewFromFloat(amount / summaryAmount),
}, nil
}
//计算两个读数之间的谷电量
func ComputeValley(startReading model.MeterReading, endReading model.MeterReading, summary calculate.Summary) (model.ConsumptionUnit, error) {
start := startReading.Valley.InexactFloat64() * startReading.Ratio.InexactFloat64()
end := endReading.Valley.InexactFloat64() * endReading.Ratio.InexactFloat64()
if start > end {
return model.ConsumptionUnit{}, errors.New(fmt.Sprintf("谷开始读数 {%x} 大于结束读数 {%x}", start, end))
}
amount := end - start
var summaryAmount float64
if summary.Valley.Amount.Equal(decimal.Zero) {
summaryAmount = decimal.NewFromFloat(1.0).InexactFloat64()
} else {
summaryAmount = summary.Valley.Amount.InexactFloat64()
}
return model.ConsumptionUnit{
Amount: decimal.NewFromFloat(amount),
Fee: decimal.NewFromFloat(amount * summary.Valley.Price.InexactFloat64()),
Price: decimal.NewFromFloat(summary.Valley.Price.InexactFloat64()),
Proportion: decimal.NewFromFloat(amount / summaryAmount),
}, nil
}