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 }