142 lines
5.2 KiB
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
|
|
}
|