Compare commits

...

42 Commits

Author SHA1 Message Date
0f91b8a332 doc(calculate): 优化代码格式,删除部分无用打印语句 2023-08-15 15:20:59 +08:00
59a604bab0 fix(park): 修复创建报表中核定线损未显示问题 2023-08-15 15:13:10 +08:00
eaf45331f1 fix(calculate_tenement):修复计算相关赋值问题 2023-08-15 14:46:04 +08:00
2844db1a86 fix(#27): 修复用户电量电费详细为空 2023-08-15 14:13:25 +08:00
7d3fafeb04 fix(#27): 未完全修复成功 2023-08-15 11:05:41 +08:00
032d38181a fix(#26): 修复获取公摊表计下的摊薄表计失败[如果没有公摊关系,则无提示,无显示信息] 2023-08-14 17:26:58 +08:00
292a50029f Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-14 16:34:16 +08:00
de176ce61d fix(#23): 修复获取园区公共电费概况有问题 2023-08-14 16:34:12 +08:00
8a383515d3 fix(#22):修复部分字段读数问题 2023-08-14 14:42:15 +08:00
37bd0da1f2 Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-14 13:49:48 +08:00
bfa7ac1508 fix(#24):修复获取到指定核算报表中的分页公摊表计的核算信息问题 2023-08-14 13:48:58 +08:00
3f36153968 fix(#22):修复无法获取报表的总览信息错误 2023-08-14 13:24:25 +08:00
845bd75348 fix(#10): 修复创建报表错误 2023-08-14 10:05:09 +08:00
559c2d439d Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-11 15:31:37 +08:00
d6829fce27 fix(#10):修复空指针 2023-08-11 15:31:24 +08:00
d1e8c63ec9 fix(park): 修复删除园区返回信息错误 2023-08-11 15:19:06 +08:00
e229f3976d fix(#20): 修复在删除充值记录的时候出现问题 2023-08-11 14:52:15 +08:00
683907b363 fix(#10): 计算相关读取数据部分debug完成 2023-08-11 13:13:45 +08:00
c1b84d1fbb Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-11 11:00:32 +08:00
2021d67d03 fix(#10):修复空指针 2023-08-11 10:59:53 +08:00
b988ffcb75 fix(pooled): 增加缺少字段loss 2023-08-11 10:57:45 +08:00
361b302407 Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-11 10:37:40 +08:00
d8f470e660 fix(#10): 修复部分计算错误,遗留问题在pooled中的deteminePublicMeterConsumpyions里时间为空错误 2023-08-11 10:37:17 +08:00
c472eb4196 fix(#17):修复有绑定表计的商户迁出时无法迁出的错误 2023-08-11 09:02:57 +08:00
98866a8de5 fix(#16):修复商户入驻时间为指定日期,并非当前日期 2023-08-10 16:33:41 +08:00
c89a5f20ad fix(doc): 注释优化 2023-08-10 16:13:12 +08:00
01e944cb5a fix(meter): 修改结构体MeterCreationForm中的字段名称,和此结构体的调用处 2023-08-10 16:12:13 +08:00
c2d43bd98e fix(#15): 修复: 更换表计的时候,在代码中接收了参数未作任何处理 2023-08-10 15:27:59 +08:00
a543b33276 Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-10 15:03:49 +08:00
6289257ac1 fix(#13):修复历史电费核算时未选择园区时显示园区中的数据,选中某一园区时显示不同园区的数据 2023-08-10 14:54:12 +08:00
5d997c14ee Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-10 10:49:47 +08:00
b50eabbca6 fix(meter): 修复:更换电表时的修改逻辑 2023-08-10 10:49:40 +08:00
a34aa6ad07 fix(#12):修复抄表记录与表记管理处无论选择任何表记类型只会显示全部错误 2023-08-10 09:54:57 +08:00
3d918eea85 fix(tenement): 解决向园区中指定商户下绑定一个新的表计时时间异常问题 2023-08-10 09:32:38 +08:00
7f46f2f36b fix(calculate): 修复创建报表时的状态错误 2023-08-09 16:24:16 +08:00
ed10996a06 Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.2 2023-08-09 15:44:10 +08:00
2aa3729e03 fix(#12):修复抄表记录与表记管理处无论选择任何表记类型只会显示全部错误 2023-08-09 15:42:37 +08:00
7d59121c2f fix(report): 调试,历史电费核算部分 2023-08-09 15:35:02 +08:00
b2efb972dc fix(report): 调试,历史电费核算部分 2023-08-09 15:28:17 +08:00
5f750dd0e0 Merge branch '0.2' of https://git.archgrid.xyz/free-lancers/electricity_bill_calc_service into 0.7 2023-08-09 10:51:57 +08:00
dd6becc994 fix(#10):修复创建报表错误,但查出列出园区bug 2023-08-09 10:48:33 +08:00
00cf35ec2a fix(#10):修复创建报表错误,但查出列出园区bug 2023-08-08 17:41:16 +08:00
30 changed files with 802 additions and 526 deletions

View File

@ -12,12 +12,11 @@ import (
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"fmt" "fmt"
"net/http"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/samber/lo" "github.com/samber/lo"
"go.uber.org/zap" "go.uber.org/zap"
"net/http"
) )
var meterLog = logger.Named("Handler", "Meter") var meterLog = logger.Named("Handler", "Meter")
@ -54,7 +53,8 @@ func searchMetersWithinPark(c *fiber.Ctx) error {
} }
keyword := c.Query("keyword") keyword := c.Query("keyword")
page := c.QueryInt("page", 1) page := c.QueryInt("page", 1)
meters, total, err := repository.MeterRepository.MetersIn(parkId, uint(page), &keyword) mtype := c.QueryInt("type", 3)
meters, total, err := repository.MeterRepository.MetersIn(parkId, uint(page), &keyword, mtype)
if err != nil { if err != nil {
meterLog.Error("无法查询指定园区下的表计信息,无法获取表计列表", zap.Error(err)) meterLog.Error("无法查询指定园区下的表计信息,无法获取表计列表", zap.Error(err))
return result.Error(http.StatusInternalServerError, err.Error()) return result.Error(http.StatusInternalServerError, err.Error())
@ -100,6 +100,7 @@ func createNewMeterManually(c *fiber.Ctx) error {
meterLog.Error("无法手动添加一条0.4kV表计记录,无法解析表计创建表单", zap.Error(err)) meterLog.Error("无法手动添加一条0.4kV表计记录,无法解析表计创建表单", zap.Error(err))
return result.NotAccept(err.Error()) return result.NotAccept(err.Error())
} }
if err := service.MeterService.CreateMeterRecord(parkId, &creationForm); err != nil { if err := service.MeterService.CreateMeterRecord(parkId, &creationForm); err != nil {
meterLog.Error("无法手动添加一条0.4kV表计记录,无法创建表计记录", zap.Error(err)) meterLog.Error("无法手动添加一条0.4kV表计记录,无法创建表计记录", zap.Error(err))
return result.NotAccept(err.Error()) return result.NotAccept(err.Error())
@ -201,7 +202,12 @@ func replaceMeter(c *fiber.Ctx) error {
meterLog.Error("无法更换系统中的表计,无法解析表计更换表单", zap.Error(err)) meterLog.Error("无法更换系统中的表计,无法解析表计更换表单", zap.Error(err))
return result.NotAccept(err.Error()) return result.NotAccept(err.Error())
} }
return nil err := service.MeterService.ReplaceMeter(parkId, meterId, &replacementForm.OldReading, replacementForm.NewMeter.Code, replacementForm.NewMeter.Ratio, &replacementForm.NewMeter.Reading)
if err != nil {
meterLog.Error("更换表计出错1111", zap.Error(err))
return result.Error(500, err.Error())
}
return result.Success("更换成功")
} }
// 列出指定公摊表计下的所有关联表计 // 列出指定公摊表计下的所有关联表计
@ -349,6 +355,7 @@ func listUnboundTenementMeters(c *fiber.Ctx) error {
func queryMeterReadings(c *fiber.Ctx) error { func queryMeterReadings(c *fiber.Ctx) error {
result := response.NewResult(c) result := response.NewResult(c)
parkId := c.Params("pid") parkId := c.Params("pid")
mtype := c.QueryInt("type", 3)
if pass, err := checkParkBelongs(parkId, meterLog, c, &result); !pass { if pass, err := checkParkBelongs(parkId, meterLog, c, &result); !pass {
return err return err
} }
@ -373,7 +380,7 @@ func queryMeterReadings(c *fiber.Ctx) error {
endDate = &parsedDate endDate = &parsedDate
} }
} }
readings, total, err := service.MeterService.SearchMeterReadings(parkId, building, startDate, endDate, uint(page), keyword) readings, total, err := service.MeterService.SearchMeterReadings(parkId, building, startDate, endDate, uint(page), keyword, uint(mtype))
if err != nil { if err != nil {
meterLog.Error("查询指定园区中的表计读数,无法获取表计读数列表", zap.Error(err)) meterLog.Error("查询指定园区中的表计读数,无法获取表计读数列表", zap.Error(err))
return result.Error(http.StatusInternalServerError, err.Error()) return result.Error(http.StatusInternalServerError, err.Error())

View File

@ -187,7 +187,7 @@ func deleteSpecificPark(c *fiber.Ctx) error {
parkLog.Error("无法删除园区。", zap.String("park id", parkId), zap.String("user id", session.Uid), zap.Error(err)) parkLog.Error("无法删除园区。", zap.String("park id", parkId), zap.String("user id", session.Uid), zap.Error(err))
return result.Error(http.StatusInternalServerError, err.Error()) return result.Error(http.StatusInternalServerError, err.Error())
} }
return result.Deleted("已删除指定的园区") return result.Success("已删除指定的园区")
} }
// 列出指定园区中已经登记的建筑 // 列出指定园区中已经登记的建筑

View File

@ -11,6 +11,9 @@ import (
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"log"
"strconv"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/samber/lo" "github.com/samber/lo"
@ -244,8 +247,28 @@ func getReportSummary(c *fiber.Ctx) error {
reportLog.Error("未找到核算报表的总览信息") reportLog.Error("未找到核算报表的总览信息")
return result.NotFound("未找到核算报表的总览信息。") return result.NotFound("未找到核算报表的总览信息。")
} }
var summaryResponse vo.ParkSummaryResponse summaryResponse := vo.ParkSummaryResponse{
copier.Copy(&summaryResponse, report) ReportId: report.ReportId,
OverallDisplay: vo.ConsumptionDisplay{
AmountStr: strconv.FormatFloat(report.Overall.Amount.InexactFloat64(), 'f', -1, 64),
FeeStr: strconv.FormatFloat(report.Overall.Fee.InexactFloat64(), 'f', -1, 64),
PriceStr: strconv.FormatFloat(report.Overall.Price.InexactFloat64(), 'f', -1, 64),
ProportionStr: strconv.FormatFloat(report.Overall.Proportion.InexactFloat64(), 'f', -1, 64),
},
Area: report.OverallArea,
BasicFee: report.BasicFee,
PooledBasicFeeByAmount: report.BasicPooledPriceConsumption.Decimal,
PooledBasicFeeByArea: report.BasicPooledPriceArea.Decimal,
AdjustFee: report.AdjustFee,
PooledAdjustFeeByAmount: report.AdjustPooledPriceConsumption.Decimal,
PooledAdjustFeeByArea: report.AdjustPooledPriceArea.Decimal,
Consumption: report.ConsumptionFee.Decimal,
//Loss: report.Loss.Decimal,
Loss: report.AuthorizeLoss.Amount,
//LossRate: report.LossFee.Decimal,
LossRate: report.AuthorizeLoss.Proportion,
}
//copier.Copy(&summaryResponse, report)
return result.Success( return result.Success(
"已经获取到核算报表的总览信息。", "已经获取到核算报表的总览信息。",
fiber.Map{"summary": summaryResponse}, fiber.Map{"summary": summaryResponse},
@ -264,15 +287,45 @@ func listPublicMetersInReport(c *fiber.Ctx) error {
reportLog.Error("无法获取核算报表中的公共表计信息", zap.Error(err)) reportLog.Error("无法获取核算报表中的公共表计信息", zap.Error(err))
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公共表计信息。") return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公共表计信息。")
} }
meterResponse := lo.Map(meters, func(meter *model.ReportDetailedPublicConsumption, _ int) *vo.ReportPublicQueryResponse {
m := &vo.ReportPublicQueryResponse{} var meterResponses []vo.Public
m.FromReportDetailPublicConsumption(meter) for _, meter := range meters {
return m meterResponse := vo.Public{
}) Address: meter.Address,
AdjustLoss: model.ConsumptionUnit{
Amount: meter.LossAdjust.Amount,
Fee: meter.LossAdjust.Fee,
Price: meter.LossAdjust.Price,
Proportion: meter.LossAdjust.Proportion,
},
Area: meter.Area.Decimal.String(),
AttachedAt: meter.AttachedAt,
Building: meter.Building,
BuildingName: meter.BuildingName,
Code: meter.ParkMeterID,
DetachedAt: meter.DetachedAt,
DisplayRatio: strconv.FormatFloat(meter.DisplayRatio, 'f', -1, 64),
Enabled: meter.Enabled,
OnFloor: meter.OnFloor,
Overall: model.ConsumptionUnit{
Amount: meter.Overall.Amount,
Fee: meter.Overall.Fee,
Price: meter.Overall.Price,
Proportion: meter.Overall.Proportion,
},
ParkID: meter.ParkID,
Ratio: meter.Ratio.String(),
Seq: meter.Seq,
Type: float64(meter.MeterType),
}
meterResponses = append(meterResponses, meterResponse)
}
return result.Success( return result.Success(
"已经获取到指定核算报表中的分页公共表计的核算信息。", "已经获取到指定核算报表中的分页公共表计的核算信息。",
response.NewPagedResponse(page, total).ToMap(), response.NewPagedResponse(page, total).ToMap(),
fiber.Map{"public": meterResponse}, fiber.Map{"public": meterResponses},
) )
} }
@ -394,7 +447,7 @@ func reportComprehensiveSearch(c *fiber.Ctx) error {
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err)) reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
return result.Unauthorized("无法获取当前用户的会话信息。") return result.Unauthorized("无法获取当前用户的会话信息。")
} }
park := tools.EmptyToNil(c.Query("park_id")) park := tools.EmptyToNil(c.Query("park"))
if session.Type == model.USER_TYPE_ENT && park != nil && len(*park) > 0 { if session.Type == model.USER_TYPE_ENT && park != nil && len(*park) > 0 {
if pass, err := checkParkBelongs(*park, reportLog, c, &result); !pass { if pass, err := checkParkBelongs(*park, reportLog, c, &result); !pass {
return err return err

View File

@ -19,7 +19,7 @@ import (
var tenementLog = logger.Named("Handler", "Tenement") var tenementLog = logger.Named("Handler", "Tenement")
func InitializeTenementHandler(router *fiber.App) { func InitializeTenementHandler(router *fiber.App) {
router.Get("/tenement/choice", security.EnterpriseAuthorize, listTenementForChoice) router.Get("/tenement/choice", security.EnterpriseAuthorize, listTenementForChoice)
router.Get("/tenement/:pid", security.EnterpriseAuthorize, listTenement) router.Get("/tenement/:pid", security.EnterpriseAuthorize, listTenement)
router.Put("/tenement/:pid/:tid", security.EnterpriseAuthorize, updateTenement) router.Put("/tenement/:pid/:tid", security.EnterpriseAuthorize, updateTenement)

View File

@ -8,6 +8,7 @@ import (
"electricity_bill_calc/tools" "electricity_bill_calc/tools"
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"fmt"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
@ -136,7 +137,8 @@ func deleteTopUp(c *fiber.Ctx) error {
topUpLog.Error("删除一条指定的商户充值记录,删除失败", zap.Error(err)) topUpLog.Error("删除一条指定的商户充值记录,删除失败", zap.Error(err))
return result.NotAccept("商户充值记录删除不成功") return result.NotAccept("商户充值记录删除不成功")
} }
return result.Deleted( fmt.Println("已经删除一条指定的商户充值记录")
return result.Success(
"已经删除一条指定的商户充值记录", "已经删除一条指定的商户充值记录",
) )
} }

View File

@ -24,23 +24,23 @@ type Pooling struct {
} }
type Meter struct { type Meter struct {
Code string Code string `json:"code"`
Detail model.MeterDetail Detail model.MeterDetail `json:"detail"`
CoveredArea decimal.Decimal CoveredArea decimal.Decimal `json:"covered_area"`
LastTermReading *Reading LastTermReading *Reading `json:"last_term_reading"`
CurrentTermReading *Reading CurrentTermReading *Reading `json:"current_term_reading"`
Overall model.ConsumptionUnit Overall model.ConsumptionUnit `json:"overall"`
Critical model.ConsumptionUnit Critical model.ConsumptionUnit `json:"critical"`
Peak model.ConsumptionUnit Peak model.ConsumptionUnit `json:"peak"`
Flat model.ConsumptionUnit Flat model.ConsumptionUnit `json:"flat"`
Valley model.ConsumptionUnit Valley model.ConsumptionUnit `json:"valley"`
AdjustLoss model.ConsumptionUnit AdjustLoss model.ConsumptionUnit `json:"adjust_loss"`
PooledBasic model.ConsumptionUnit PooledBasic model.ConsumptionUnit `json:"pooled_basic"`
PooledAdjust model.ConsumptionUnit PooledAdjust model.ConsumptionUnit `json:"pooled_adjust"`
PooledLoss model.ConsumptionUnit PooledLoss model.ConsumptionUnit `json:"pooled_loss"`
PooledPublic model.ConsumptionUnit PooledPublic model.ConsumptionUnit `json:"pooled_public"`
SharedPoolingProportion decimal.Decimal SharedPoolingProportion decimal.Decimal `json:"shared_pooling_proportion"`
Poolings []*Pooling Poolings []*Pooling `json:"poolings"`
} }
type PrimaryTenementStatistics struct { type PrimaryTenementStatistics struct {
@ -49,20 +49,20 @@ type PrimaryTenementStatistics struct {
} }
type TenementCharge struct { type TenementCharge struct {
Tenement string Tenement string `json:"tenement"`
Overall model.ConsumptionUnit Overall model.ConsumptionUnit `json:"overall"`
Critical model.ConsumptionUnit Critical model.ConsumptionUnit `json:"critical"`
Peak model.ConsumptionUnit Peak model.ConsumptionUnit `json:"peak"`
Flat model.ConsumptionUnit Flat model.ConsumptionUnit `json:"flat"`
Valley model.ConsumptionUnit Valley model.ConsumptionUnit `json:"valley"`
BasicFee decimal.Decimal BasicFee decimal.Decimal `json:"basic_fee"`
AdjustFee decimal.Decimal AdjustFee decimal.Decimal `json:"adjust_fee"`
LossPooled decimal.Decimal LossPooled decimal.Decimal `json:"loss_pooled"`
PublicPooled decimal.Decimal PublicPooled decimal.Decimal `json:"public_pooled"`
FinalCharges decimal.Decimal FinalCharges decimal.Decimal `json:"final_charges"`
Loss decimal.Decimal Loss model.ConsumptionUnit `json:"loss"`
Submeters []*Meter Submeters []*Meter `json:"submeters"`
Poolings []*Meter Poolings []*Meter `json:"poolings"`
} }
type Summary struct { type Summary struct {

View File

@ -32,7 +32,7 @@ type Park struct {
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
LastModifiedAt time.Time `json:"lastModifiedAt"` LastModifiedAt time.Time `json:"lastModifiedAt"`
DeletedAt *time.Time `json:"deletedAt"` DeletedAt *time.Time `json:"deletedAt"`
NormAuthorizedLossRate float64 `json:"norm_authorized_loss_rate"` NormAuthorizedLossRate float64 `json:"normAuthorizedLoss"db:"norm_authorized_loss_rate"`
} }
type ParkPeriodStatistics struct { type ParkPeriodStatistics struct {

View File

@ -122,6 +122,7 @@ type ReportTenement struct {
Invoice []string `json:"invoice" db:"invoice"` Invoice []string `json:"invoice" db:"invoice"`
Meters []NestedMeter `json:"meters" db:"meters"` Meters []NestedMeter `json:"meters" db:"meters"`
Pooled []NestedMeter `json:"pooled" db:"pooled"` Pooled []NestedMeter `json:"pooled" db:"pooled"`
Loss ConsumptionUnit `json:"loss"` //TODO: 2023.08.11 测试时发现少一个字段(已补全)
} }
type ReportTask struct { type ReportTask struct {

View File

@ -7,7 +7,7 @@ type Tenement struct {
Park string `json:"parkId" db:"park_id"` Park string `json:"parkId" db:"park_id"`
FullName string `json:"fullName" db:"full_name"` FullName string `json:"fullName" db:"full_name"`
ShortName *string `json:"shortName" db:"short_name"` ShortName *string `json:"shortName" db:"short_name"`
Abbr string `json:"-"` Abbr string `json:"abbr"`
Address string `json:"address"` Address string `json:"address"`
ContactName string `json:"contactName" db:"contact_name"` ContactName string `json:"contactName" db:"contact_name"`
ContactPhone string `json:"contactPhone" db:"contact_phone"` ContactPhone string `json:"contactPhone" db:"contact_phone"`

View File

@ -1,6 +1,7 @@
package repository package repository
import ( import (
"context"
"electricity_bill_calc/global" "electricity_bill_calc/global"
"electricity_bill_calc/logger" "electricity_bill_calc/logger"
"electricity_bill_calc/model" "electricity_bill_calc/model"
@ -12,8 +13,6 @@ import (
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"log"
"strings"
"time" "time"
"github.com/doug-martin/goqu/v9" "github.com/doug-martin/goqu/v9"
@ -32,18 +31,26 @@ var CalculateRepository = _CalculateRepository{
ds: goqu.Dialect("postgres"), ds: goqu.Dialect("postgres"),
} }
//更新当前报表的核算状态 // 更新当前报表的核算状态
func (cr _CalculateRepository) UpdateReportCalculateStatus(rid string, status string, func (cr _CalculateRepository) UpdateReportCalculateStatus(rid string, status string,
message string) (bool, error) { message string) (bool, error) {
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
var atio int
var err error
currentTime := time.Now() currentTime := time.Now()
if status == "success" {
atio = 1 //创建报表成功
} else {
atio = 2 // 数据不足
}
updateResultSql, updateResultArgs, _ := cr.ds. updateResultSql, updateResultArgs, _ := cr.ds.
Update(goqu.T("report_task")). Update(goqu.T("report_task")).
Set(goqu.Record{ Set(goqu.Record{
"status": status, "status": int16(atio),
"last_modified_at": currentTime, "last_modified_at": currentTime,
"message": message, "message": message,
}).Where(goqu.I("id").Eq(rid)). }).Where(goqu.I("id").Eq(rid)).
@ -124,7 +131,7 @@ func (cr _CalculateRepository) GetAllPoolingMeterRelations(pid string, revokedAf
var meterRelation []model.MeterRelation var meterRelation []model.MeterRelation
err := pgxscan.Select(ctx, global.DB, meterRelation, relationsSql, relationsArgs...) err := pgxscan.Select(ctx, global.DB, &meterRelation, relationsSql, relationsArgs...)
if err != nil { if err != nil {
cr.log.Error("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的出错", zap.Error(err)) cr.log.Error("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的出错", zap.Error(err))
return nil, err return nil, err
@ -142,21 +149,24 @@ func (cr _CalculateRepository) GetAllTenementMeterRelations(pid string, associat
From(goqu.T("tenement_meter")). From(goqu.T("tenement_meter")).
Where(goqu.I("park_id").Eq(pid)). Where(goqu.I("park_id").Eq(pid)).
Where(goqu.And( Where(goqu.And(
goqu.I("associated_at").IsNull(), goqu.I("associated_at").IsNotNull(),
goqu.I("associated_at").Lte(associatedBefore), goqu.I("associated_at").Lte(associatedBefore),
)). )).
Where(goqu.And( Where(goqu.And(
goqu.I("associated_at").IsNull(), goqu.Or(
goqu.I("associated_at").Gte(disassociatedAfter), goqu.I("disassociated_at").IsNull(),
goqu.I("disassociated_at").Gte(disassociatedAfter),
),
)).ToSQL() )).ToSQL()
var tenementMeter []model.TenementMeter var tenementMeter []model.TenementMeter
err := pgxscan.Select(ctx, global.DB, tenementMeter, relationsQuerySql, relationsQueryArgs...) err := pgxscan.Select(ctx, global.DB, &tenementMeter, relationsQuerySql, relationsQueryArgs...)
if err != nil { if err != nil {
cr.log.Error("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.Error(err)) cr.log.Error("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.Error(err))
return nil, err return nil, err
} }
fmt.Println("==", tenementMeter)
return tenementMeter, nil return tenementMeter, nil
} }
@ -178,13 +188,13 @@ func (cr _CalculateRepository) GetMeterReadings(rid string, meterType int16) ([]
goqu.I("r.id").Eq(rid), goqu.I("r.id").Eq(rid),
goqu.I("mr.meter_type").Eq(meterType), goqu.I("mr.meter_type").Eq(meterType),
// TODO2023.08.02 此方法出错优先查看是否这里出问题 // TODO2023.08.02 此方法出错优先查看是否这里出问题
goqu.I("mr.read_at::date <@ r.period"), goqu.L("?::date <@ ?", goqu.I("mr.read_at"), goqu.I("r.period")),
). ).
Order(goqu.I("mr.read_at").Asc()).Select(goqu.I("mr.*")).ToSQL() Order(goqu.I("mr.read_at").Asc()).Select(goqu.I("mr.*")).ToSQL()
var readings []model.MeterReading var readings []model.MeterReading
err := pgxscan.Select(ctx, global.DB, readings, readingsQuerySql, readingsQueryArgs...) err := pgxscan.Select(ctx, global.DB, &readings, readingsQuerySql, readingsQueryArgs...)
if err != nil { if err != nil {
cr.log.Error("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据出错", zap.Error(err)) cr.log.Error("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据出错", zap.Error(err))
return nil, err return nil, err
@ -199,7 +209,8 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
readingsSql, readingsArgs, _ := cr.ds.From(goqu.T("meter_reading").As("mr")). readingsSql, readingsArgs, _ := cr.ds.
From(goqu.T("meter_reading").As("mr")).
Select( Select(
goqu.MAX("mr.read_at").As("read_at"), goqu.MAX("mr.read_at").As("read_at"),
goqu.I("mr.park_id"), goqu.I("mr.park_id"),
@ -219,7 +230,7 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
Where( Where(
goqu.I("r.id").Eq(rid), goqu.I("r.id").Eq(rid),
goqu.I("mr.meter_type").Eq(meterType), goqu.I("mr.meter_type").Eq(meterType),
goqu.I(" mr.read_at::date <= lower(r.period)"), goqu.L(" read_at <= lower(r.period)"),
). ).
GroupBy( GroupBy(
goqu.I("mr.park_id"), goqu.I("mr.park_id"),
@ -235,11 +246,12 @@ func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16
).ToSQL() ).ToSQL()
var readings []model.MeterReading var readings []model.MeterReading
err := pgxscan.Select(ctx, global.DB, readings, readingsSql, readingsArgs...) err := pgxscan.Select(ctx, global.DB, &readings, readingsSql, readingsArgs...)
if err != nil { if err != nil {
cr.log.Error("获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数出错", zap.Error(err)) cr.log.Error("获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数出错", zap.Error(err))
return nil, err return nil, err
} }
return readings, nil return readings, nil
} }
@ -266,11 +278,11 @@ func (cr _CalculateRepository) GetAllTenements(rid string) ([]model.Tenement, er
). ).
Where( Where(
goqu.I("r.id").Eq(rid), goqu.I("r.id").Eq(rid),
goqu.I("t.moved_in_at <= upper(r.period)"), goqu.L("t.moved_in_at <= upper(r.period)"),
).ToSQL() ).ToSQL()
fmt.Println(tenementQuerySql)
var tenements []model.Tenement var tenements []model.Tenement
err := pgxscan.Select(ctx, global.DB, tenements, tenementQuerySql, tenementQueryArgs...) err := pgxscan.Select(ctx, global.DB, &tenements, tenementQuerySql, tenementQueryArgs...)
if err != nil { if err != nil {
cr.log.Error("取得指定报表所涉及的所有商户信息出错", zap.Error(err)) cr.log.Error("取得指定报表所涉及的所有商户信息出错", zap.Error(err))
return nil, err return nil, err
@ -309,52 +321,59 @@ func (cr _CalculateRepository) ClearReportContent(tx pgx.Tx, rid string) error {
return nil return nil
} }
func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, rid string, meters []calculate.Meter) error { func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, ctx context.Context, rid string, meters []calculate.Meter) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
if len(meters) == 0 { if len(meters) == 0 {
// 如果没有公共表计则直接返回 // 如果没有公共表计则直接返回
return nil return nil
} }
// 准备插入表达式
insertExpr := cr.ds.Insert("report_public_consumption").
Cols(
"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley",
"loss_adjust", "consumption_total", "loss_adjust_total", "final_total",
).Prepared(true)
// 添加值到插入表达式中
for _, meter := range meters { for _, meter := range meters {
insertExpr = insertExpr.Vals([]interface{}{ // 准备插入表达式
insertExpr := cr.ds.Insert("report_public_consumption").
Cols(
"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley",
"loss_adjust", "consumption_total", "loss_adjust_total", "final_total",
)
// 添加值到插入表达式中
overall, _ := json.Marshal(meter.Overall)
criyical, _ := json.Marshal(meter.Critical)
peak, _ := json.Marshal(meter.Peak)
flat, _ := json.Marshal(meter.Flat)
valley, _ := json.Marshal(meter.Valley)
adjustLoss, _ := json.Marshal(meter.AdjustLoss)
insertExpr = insertExpr.Vals(goqu.Vals{
rid, rid,
meter.Code, meter.Code,
meter.Overall.Fee, overall,
meter.Critical.Fee, criyical,
meter.Peak.Fee, peak,
meter.Flat.Fee, flat,
meter.Valley.Fee, valley,
meter.AdjustLoss.Fee, adjustLoss,
meter.Overall.Fee, meter.Overall.Fee,
meter.AdjustLoss.Fee, meter.AdjustLoss.Fee,
meter.Overall.Fee.Add(meter.AdjustLoss.Fee), meter.Overall.Fee.Add(meter.AdjustLoss.Fee),
}) })
} // 执行插入语句
inserSql, insertArgs, _ := insertExpr.ToSQL()
// 执行插入语句 _, err := tx.Exec(ctx, inserSql, insertArgs...)
inserSql, insertArgs, err := insertExpr.Prepared(true).ToSQL() if err != nil {
if err != nil { _ = tx.Rollback(ctx)
return err return fmt.Errorf("保存报表核算概要失败: %w", err)
} }
if _, err := tx.Exec(ctx, inserSql, insertArgs); err != nil {
return fmt.Errorf("保存报表核算概要失败: %w", err)
} }
return nil return nil
} }
func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Summary) error { func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, ctx context.Context, summary calculate.Summary) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
// 构建插入表达式 // 构建插入表达式
insertsql, insertArgs, _ := cr.ds.Insert("report_summary"). Overall, _ := json.Marshal(summary.Overall)
Critical, _ := json.Marshal(summary.Critical)
Peak, _ := json.Marshal(summary.Peak)
Flat, _ := json.Marshal(summary.Flat)
Valley, _ := json.Marshal(summary.Valley)
AuthoizeLoss, _ := json.Marshal(summary.AuthoizeLoss)
insertsql, insertArgs, err := cr.ds.Insert(goqu.T("report_summary")).
Cols( Cols(
"report_id", "overall", "critical", "peak", "flat", "valley", "report_id", "overall", "critical", "peak", "flat", "valley",
"loss", "loss_fee", "basic_fee", "basic_pooled_price_consumption", "basic_pooled_price_area", "loss", "loss_fee", "basic_fee", "basic_pooled_price_consumption", "basic_pooled_price_area",
@ -363,16 +382,18 @@ func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Su
"consumption_fee", "authorize_loss", "overall_area", "total_consumption", "consumption_fee", "authorize_loss", "overall_area", "total_consumption",
). ).
Vals(goqu.Vals{ Vals(goqu.Vals{
summary.ReportId, summary.Overall, summary.Critical, summary.Peak, summary.Flat, summary.ReportId, Overall, Critical, Peak, Flat,
summary.Valley, summary.Loss, summary.LossFee, summary.BasicFee, Valley, summary.Loss, summary.LossFee, summary.BasicFee,
summary.BasicPooledPriceConsumption, summary.BasicPooledPriceArea, summary.BasicPooledPriceConsumption, summary.BasicPooledPriceArea,
summary.AdjustFee, summary.AdjustPooledPriceConsumption, summary.AdjustPooledPriceArea, summary.AdjustFee, summary.AdjustPooledPriceConsumption, summary.AdjustPooledPriceArea,
summary.LossDilutedPrice, summary.LossProportion, summary.FinalDilutedOverall, summary.LossDilutedPrice, summary.LossProportion, summary.FinalDilutedOverall,
summary.ConsumptionFee, summary.AuthoizeLoss, summary.OverallArea, summary.TotalConsumption, summary.ConsumptionFee, AuthoizeLoss, summary.OverallArea, summary.TotalConsumption,
}).Prepared(true).ToSQL() }).ToSQL()
if err != nil {
fmt.Println(err)
return err
}
// 执行插入语句 // 执行插入语句
if _, err := tx.Exec(ctx, insertsql, insertArgs...); err != nil { if _, err := tx.Exec(ctx, insertsql, insertArgs...); err != nil {
cr.log.Error("保存报表核算概要失败。") cr.log.Error("保存报表核算概要失败。")
return err return err
@ -441,10 +462,15 @@ func (cr _CalculateRepository) SaveReportPoolings(tx pgx.Tx,
if err != nil { if err != nil {
return err return err
} }
overall, _ := json.Marshal(meter.Overall)
criyical, _ := json.Marshal(meter.Critical)
peak, _ := json.Marshal(meter.Peak)
flat, _ := json.Marshal(meter.Flat)
valley, _ := json.Marshal(meter.Valley)
insertQuery := goqu.Insert("report_pooled_consumption"). insertQuery := goqu.Insert("report_pooled_consumption").
Cols("report_id", "pooled_meter_id", "overall", "critical", "peak", "flat", "valley", "pooled_area", "diluted"). Cols("report_id", "pooled_meter_id", "overall", "critical", "peak", "flat", "valley", "pooled_area", "diluted").
Vals(goqu.Vals{rid, meter.Code, meter.Overall, meter.Critical, meter.Peak, meter.Flat, meter.Valley, meter.CoveredArea, submetersJSON}) Vals(goqu.Vals{rid, meter.Code, overall, criyical, peak, flat, valley, meter.CoveredArea, submetersJSON})
insertQueries = append(insertQueries, *insertQuery) insertQueries = append(insertQueries, *insertQuery)
} }
@ -471,40 +497,55 @@ func (cr _CalculateRepository) SaveReportTenement(tx pgx.Tx, report model.Report
cr.log.Info("保存商户报表。") cr.log.Info("保存商户报表。")
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
insertQuery := cr.ds.Insert("report_tenement").Prepared(true) insertQuery := cr.ds.
values := []goqu.Record{} Insert("report_tenement")
var rows []goqu.Record
for _, tenement := range tenements { for _, tenement := range tenements {
charge := findTenementCharge(tenementCharges, tenement.Id) tenementCharge := findTenementCharge(tenementCharges, tenement.Id)
values = append(values, goqu.Record{
tenementDetail, _ := json.Marshal(tenement)
overallJSON, _ := json.Marshal(tenementCharge.Overall)
criticalJSON, _ := json.Marshal(tenementCharge.Critical)
peakJSON, _ := json.Marshal(tenementCharge.Peak)
flatJSON, _ := json.Marshal(tenementCharge.Flat)
valleyJSON, _ := json.Marshal(tenementCharge.Valley)
lossJSON, _ := json.Marshal(tenementCharge.Loss)
submetersJSON, _ := json.Marshal(convertToNestedMeters(tenementCharge.Submeters))
poolingsJSON, _ := json.Marshal(convertToNestedMeters(tenementCharge.Poolings))
row := goqu.Record{
"report_id": report.Id, "report_id": report.Id,
"tenement_id": tenement.Id, "tenement_id": tenement.Id,
"tenement_detail": toJSONString(tenement), "tenement_detail": tenementDetail,
"calc_period": report.Period, "calc_period": report.Period,
"overall": toJSONString(charge.Overall), "overall": overallJSON,
"critical": toJSONString(charge.Critical), "critical": criticalJSON,
"peak": toJSONString(charge.Peak), "peak": peakJSON,
"flat": toJSONString(charge.Flat), "flat": flatJSON,
"valley": toJSONString(charge.Valley), "valley": valleyJSON,
"loss": toJSONString(charge.Loss), "loss": lossJSON,
"basic_fee_pooled": charge.BasicFee, "basic_fee_pooled": tenementCharge.BasicFee,
"adjust_fee_pooled": charge.AdjustFee, "adjust_fee_pooled": tenementCharge.AdjustFee,
"loss_fee_pooled": charge.LossPooled, "loss_fee_pooled": tenementCharge.LossPooled,
"final_pooled": charge.PublicPooled, "final_pooled": tenementCharge.PublicPooled,
"final_charge": charge.FinalCharges, "final_charge": tenementCharge.FinalCharges,
"meters": toJSONString(convertToNestedMeters(charge.Submeters)), "meters": submetersJSON,
"pooled": toJSONString(convertToNestedMeters(charge.Poolings)), "pooled": poolingsJSON,
}) }
rows = append(rows, row)
} }
sql, params, err := insertQuery.Rows(values).Prepared(true).ToSQL() sql, params, err := insertQuery.Rows(rows).Prepared(true).ToSQL()
if err != nil {
log.Println("sql出现问题................................")
return err
}
tx.Exec(ctx, sql, params...)
if err != nil { if err != nil {
fmt.Println(err)
}
_, err = tx.Exec(ctx, sql, params...)
if err != nil {
fmt.Println(err.Error())
return err return err
} }
return nil return nil
} }
@ -533,8 +574,3 @@ func convertToNestedMeters(meters []*calculate.Meter) []NestedMeter {
} }
return nestedMeters return nestedMeters
} }
// toJSONString 将对象转换为 JSON 字符串
func toJSONString(obj interface{}) string {
return `"` + strings.ReplaceAll(fmt.Sprintf("%#v", obj), `"`, `\"`) + `"`
}

View File

@ -12,13 +12,13 @@ import (
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"fmt" "fmt"
"github.com/doug-martin/goqu/v9" "github.com/doug-martin/goqu/v9"
_ "github.com/doug-martin/goqu/v9/dialect/postgres" _ "github.com/doug-martin/goqu/v9/dialect/postgres"
"github.com/georgysavva/scany/v2/pgxscan" "github.com/georgysavva/scany/v2/pgxscan"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"go.uber.org/zap" "go.uber.org/zap"
"log"
) )
type _MeterRepository struct { type _MeterRepository struct {
@ -121,11 +121,10 @@ func (mr _MeterRepository) AllUsedMetersInReport(rid string) ([]*model.MeterDeta
} }
// 分页列出指定园区下的表计信息 // 分页列出指定园区下的表计信息
func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*model.MeterDetail, int64, error) { func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string, mtype int) ([]*model.MeterDetail, int64, error) {
mr.log.Info("分页列出指定园区下的表计信息", zap.String("park id", pid), zap.Uint("page", page), zap.String("keyword", tools.DefaultTo(keyword, ""))) mr.log.Info("分页列出指定园区下的表计信息", zap.String("park id", pid), zap.Uint("page", page), zap.String("keyword", tools.DefaultTo(keyword, "")))
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
meterQuery := mr.ds. meterQuery := mr.ds.
From(goqu.T("meter_04kv").As("m")). From(goqu.T("meter_04kv").As("m")).
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("m.building").Eq(goqu.I("b.id")))). LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("m.building").Eq(goqu.I("b.id")))).
@ -143,7 +142,10 @@ func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*
goqu.I("m.park_id").Eq(pid), goqu.I("m.park_id").Eq(pid),
goqu.I("m.detached_at").IsNull(), goqu.I("m.detached_at").IsNull(),
) )
if mtype != 3 {
meterQuery = meterQuery.Where(goqu.I("m.meter_type").Eq(uint(mtype)))
countQuery = countQuery.Where(goqu.I("m.meter_type").Eq(uint(mtype)))
}
if keyword != nil && len(*keyword) > 0 { if keyword != nil && len(*keyword) > 0 {
pattern := fmt.Sprintf("%%%s%%", *keyword) pattern := fmt.Sprintf("%%%s%%", *keyword)
meterQuery = meterQuery.Where( meterQuery = meterQuery.Where(
@ -174,11 +176,11 @@ func (mr _MeterRepository) MetersIn(pid string, page uint, keyword *string) ([]*
mr.log.Error("查询表计信息失败", zap.Error(err)) mr.log.Error("查询表计信息失败", zap.Error(err))
return make([]*model.MeterDetail, 0), 0, err return make([]*model.MeterDetail, 0), 0, err
} }
if err := pgxscan.Get(ctx, global.DB, &total, countSql, countArgs...); err != nil { if err := pgxscan.Get(ctx, global.DB, &total, countSql, countArgs...); err != nil {
mr.log.Error("查询表计数量失败", zap.Error(err)) mr.log.Error("查询表计数量失败", zap.Error(err))
return make([]*model.MeterDetail, 0), 0, err return make([]*model.MeterDetail, 0), 0, err
} }
return meters, total, nil return meters, total, nil
} }
@ -209,12 +211,12 @@ func (mr _MeterRepository) ListMetersByIDs(pid string, ids []string) ([]*model.M
mr.log.Error("查询表计信息失败", zap.Error(err)) mr.log.Error("查询表计信息失败", zap.Error(err))
return make([]*model.MeterDetail, 0), err return make([]*model.MeterDetail, 0), err
} }
return meters, nil return meters, nil
} }
// 获取指定表计的详细信息 // 获取指定表计的详细信息
func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetail, error) { func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetail, error) {
log.Println("获取指定标记的详细信息1111111111111111")
mr.log.Info("获取指定表计的详细信息", zap.String("park id", pid), zap.String("meter code", code)) mr.log.Info("获取指定表计的详细信息", zap.String("park id", pid), zap.String("meter code", code))
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
@ -231,7 +233,7 @@ func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetai
goqu.I("m.code").Eq(code), goqu.I("m.code").Eq(code),
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()
log.Println("111111111111111111111111", meterSql)
if err := pgxscan.Get(ctx, global.DB, &meter, meterSql, meterArgs...); err != nil { if err := pgxscan.Get(ctx, global.DB, &meter, meterSql, meterArgs...); err != nil {
mr.log.Error("查询表计信息失败", zap.Error(err)) mr.log.Error("查询表计信息失败", zap.Error(err))
return nil, err return nil, err
@ -242,8 +244,10 @@ func (mr _MeterRepository) FetchMeterDetail(pid, code string) (*model.MeterDetai
// 创建一条新的表计信息 // 创建一条新的表计信息
func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid string, meter vo.MeterCreationForm) (bool, error) { func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid string, meter vo.MeterCreationForm) (bool, error) {
log.Println("创建一条新的表记55555555555555555555")
mr.log.Info("创建一条新的表计信息", zap.String("park id", pid), zap.String("meter code", meter.Code)) mr.log.Info("创建一条新的表计信息", zap.String("park id", pid), zap.String("meter code", meter.Code))
timeNow := types.Now() //timeNow := types.Now()
meterSql, meterArgs, _ := mr.ds. meterSql, meterArgs, _ := mr.ds.
Insert(goqu.T("meter_04kv")). Insert(goqu.T("meter_04kv")).
Cols( Cols(
@ -251,8 +255,9 @@ func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid strin
"attached_at", "created_at", "last_modified_at", "attached_at", "created_at", "last_modified_at",
). ).
Vals( Vals(
goqu.Vals{pid, meter.Code, meter.Address, meter.Ratio, meter.Seq, meter.MeterType, meter.Building, meter.OnFloor, meter.Area, meter.Enabled, goqu.Vals{pid, meter.Code, meter.Address, meter.Ratio, meter.Seq, meter.MeterType, meter.Building, meter.OnFloor,
timeNow, timeNow, timeNow, meter.Area, meter.Enabled,
meter.Reading.ReadAt, meter.Reading.ReadAt, meter.Reading.ReadAt,
}, },
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()
@ -262,6 +267,7 @@ func (mr _MeterRepository) CreateMeter(tx pgx.Tx, ctx context.Context, pid strin
mr.log.Error("创建表计信息失败", zap.Error(err)) mr.log.Error("创建表计信息失败", zap.Error(err))
return false, err return false, err
} }
log.Println("555555555555", meterSql)
return ok.RowsAffected() > 0, nil return ok.RowsAffected() > 0, nil
} }
@ -304,6 +310,7 @@ func (mr _MeterRepository) CreateOrUpdateMeter(tx pgx.Tx, ctx context.Context, p
// 记录一条表计的抄表信息 // 记录一条表计的抄表信息
func (mr _MeterRepository) RecordReading(tx pgx.Tx, ctx context.Context, pid, code string, meterType int16, ratio decimal.Decimal, reading *vo.MeterReadingForm) (bool, error) { func (mr _MeterRepository) RecordReading(tx pgx.Tx, ctx context.Context, pid, code string, meterType int16, ratio decimal.Decimal, reading *vo.MeterReadingForm) (bool, error) {
log.Println("记录一条表记的抄表信息22222222222222222222")
mr.log.Info("记录一条表计的抄表信息", zap.String("park id", pid), zap.String("meter code", code)) mr.log.Info("记录一条表计的抄表信息", zap.String("park id", pid), zap.String("meter code", code))
readAt := tools.DefaultTo(reading.ReadAt, types.Now()) readAt := tools.DefaultTo(reading.ReadAt, types.Now())
readingSql, readingArgs, _ := mr.ds. readingSql, readingArgs, _ := mr.ds.
@ -315,6 +322,7 @@ func (mr _MeterRepository) RecordReading(tx pgx.Tx, ctx context.Context, pid, co
goqu.Vals{pid, code, readAt, meterType, ratio, reading.Overall, reading.Critical, reading.Peak, reading.Flat, reading.Valley}, goqu.Vals{pid, code, readAt, meterType, ratio, reading.Overall, reading.Critical, reading.Peak, reading.Flat, reading.Valley},
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()
log.Println("22222222222222222222", readingSql)
ok, err := tx.Exec(ctx, readingSql, readingArgs...) ok, err := tx.Exec(ctx, readingSql, readingArgs...)
if err != nil { if err != nil {
@ -390,6 +398,7 @@ func (mr _MeterRepository) ListMeterCodes(pid string) ([]string, error) {
// 解除指定园区中指定表计的使用 // 解除指定园区中指定表计的使用
func (mr _MeterRepository) DetachMeter(tx pgx.Tx, ctx context.Context, pid, code string) (bool, error) { func (mr _MeterRepository) DetachMeter(tx pgx.Tx, ctx context.Context, pid, code string) (bool, error) {
log.Println("解除指定园区的指定表记使用33333333333333333333")
mr.log.Info("解除指定园区中指定表计的使用", zap.String("park id", pid), zap.String("meter code", code)) mr.log.Info("解除指定园区中指定表计的使用", zap.String("park id", pid), zap.String("meter code", code))
timeNow := types.Now() timeNow := types.Now()
meterSql, meterArgs, _ := mr.ds. meterSql, meterArgs, _ := mr.ds.
@ -405,7 +414,7 @@ func (mr _MeterRepository) DetachMeter(tx pgx.Tx, ctx context.Context, pid, code
goqu.I("code").Eq(code), goqu.I("code").Eq(code),
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()
log.Println("3333333333333333", meterSql)
ok, err := tx.Exec(ctx, meterSql, meterArgs...) ok, err := tx.Exec(ctx, meterSql, meterArgs...)
if err != nil { if err != nil {
mr.log.Error("解除表计使用失败", zap.Error(err)) mr.log.Error("解除表计使用失败", zap.Error(err))
@ -467,6 +476,7 @@ func (mr _MeterRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, master
// 解除两个表计之间的关联 // 解除两个表计之间的关联
func (mr _MeterRepository) UnbindMeter(tx pgx.Tx, ctx context.Context, pid, masterMeter, slaveMeter string) (bool, error) { func (mr _MeterRepository) UnbindMeter(tx pgx.Tx, ctx context.Context, pid, masterMeter, slaveMeter string) (bool, error) {
log.Println("解除两个标记之间的关系》》》》》》》》》》》》》》》》》》》》》》》4444444444")
mr.log.Info("解除两个表计之间的关联", zap.String("master meter code", masterMeter), zap.String("slave meter code", slaveMeter)) mr.log.Info("解除两个表计之间的关联", zap.String("master meter code", masterMeter), zap.String("slave meter code", slaveMeter))
relationSql, relationArgs, _ := mr.ds. relationSql, relationArgs, _ := mr.ds.
Update(goqu.T("meter_relations")). Update(goqu.T("meter_relations")).
@ -482,14 +492,14 @@ func (mr _MeterRepository) UnbindMeter(tx pgx.Tx, ctx context.Context, pid, mast
goqu.I("revoked_at").IsNull(), goqu.I("revoked_at").IsNull(),
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()
log.Println("4444444444444444", relationSql)
ok, err := tx.Exec(ctx, relationSql, relationArgs...) ok, err := tx.Exec(ctx, relationSql, relationArgs...)
if err != nil { if err != nil {
mr.log.Error("解除表计关系失败", zap.Error(err)) mr.log.Error("解除表计关系失败", zap.Error(err))
return false, err return false, err
} }
return ok.RowsAffected() > 0, nil return ok.RowsAffected() >= 0, nil
} }
// 列出指定公摊表计的所有关联表计关系 // 列出指定公摊表计的所有关联表计关系
@ -553,7 +563,7 @@ func (mr _MeterRepository) ListMeterRelations(pid, code string) ([]*model.MeterR
var relations []*model.MeterRelation var relations []*model.MeterRelation
relationsSql, relationsArgs, _ := mr.ds. relationsSql, relationsArgs, _ := mr.ds.
From(goqu.T("meter_relations")). From(goqu.T("meter_relations").As("r")).
Select("*"). Select("*").
Where( Where(
goqu.I("r.park_id").Eq(pid), goqu.I("r.park_id").Eq(pid),
@ -777,25 +787,31 @@ func (mr _MeterRepository) ListUnboundTenementMeters(uid string, pid *string, ke
} }
// 查询指定园区中的符合条件的抄表记录 // 查询指定园区中的符合条件的抄表记录
func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page uint, start, end *types.Date, buidling *string) ([]*model.MeterReading, int64, error) { func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page uint, start, end *types.Date, buidling *string, mtype uint) ([]*model.MeterReading, int64, error) {
mr.log.Info("查询指定园区中的符合条件的抄表记录", zap.String("park id", pid), zap.String("keyword", tools.DefaultTo(keyword, "")), zap.Uint("page", page), logger.DateFieldp("start", start), logger.DateFieldp("end", end), zap.String("building", tools.DefaultTo(buidling, ""))) mr.log.Info("查询指定园区中的符合条件的抄表记录", zap.String("park id", pid), zap.String("keyword", tools.DefaultTo(keyword, "")), zap.Uint("page", page), logger.DateFieldp("start", start), logger.DateFieldp("end", end), zap.String("building", tools.DefaultTo(buidling, "")))
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
readingQuery := mr.ds. readingQuery := mr.ds.
From(goqu.T("meter_reading").As("r")). From(goqu.T("meter_reading").As("r")).
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")), goqu.I("m.park_id").Eq(goqu.I("r.park_id")))). LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")),
goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
Select("r.*"). Select("r.*").
Where( Where(
goqu.I("r.park_id").Eq(pid), goqu.I("r.park_id").Eq(pid),
) )
countQuery := mr.ds. countQuery := mr.ds.
From(goqu.T("meter_reading").As("r")). From(goqu.T("meter_reading").As("r")).
LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")), goqu.I("m.park_id").Eq(goqu.I("r.park_id")))). LeftJoin(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("r.meter_id").Eq(goqu.I("m.code")),
goqu.I("m.park_id").Eq(goqu.I("r.park_id")))).
Select(goqu.COUNT("*")). Select(goqu.COUNT("*")).
Where( Where(
goqu.I("r.park_id").Eq(pid), goqu.I("r.park_id").Eq(pid),
) )
if mtype != 3 {
readingQuery = readingQuery.Where(goqu.I("m.meter_type").Eq(mtype))
countQuery = countQuery.Where(goqu.I("m.meter_type").Eq(mtype))
}
if keyword != nil && len(*keyword) > 0 { if keyword != nil && len(*keyword) > 0 {
pattern := fmt.Sprintf("%%%s%%", *keyword) pattern := fmt.Sprintf("%%%s%%", *keyword)
@ -859,7 +875,6 @@ func (mr _MeterRepository) ListMeterReadings(pid string, keyword *string, page u
mr.log.Error("查询抄表记录数量失败", zap.Error(err)) mr.log.Error("查询抄表记录数量失败", zap.Error(err))
return make([]*model.MeterReading, 0), 0, err return make([]*model.MeterReading, 0), 0, err
} }
return readings, total, nil return readings, total, nil
} }

View File

@ -38,7 +38,7 @@ func (pr _ParkRepository) ListAllParks(uid string) ([]*model.Park, error) {
"id", "user_id", "name", "area", "tenement_quantity", "capacity", "category", "id", "user_id", "name", "area", "tenement_quantity", "capacity", "category",
"meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate", "meter_04kv_type", "region", "address", "contact", "phone", "enabled", "price_policy", "tax_rate",
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at", "basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "last_modified_at",
"deleted_at", "deleted_at","norm_authorized_loss_rate",
). ).
Where( Where(
goqu.I("user_id").Eq(uid), goqu.I("user_id").Eq(uid),

View File

@ -9,7 +9,11 @@ import (
"electricity_bill_calc/tools/serial" "electricity_bill_calc/tools/serial"
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"encoding/json"
"errors"
"fmt" "fmt"
"log"
"github.com/doug-martin/goqu/v9" "github.com/doug-martin/goqu/v9"
_ "github.com/doug-martin/goqu/v9/dialect/postgres" _ "github.com/doug-martin/goqu/v9/dialect/postgres"
@ -124,8 +128,8 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
createSql, createArgs, _ := rr.ds. createSql, createArgs, _ := rr.ds.
Insert(goqu.T("report")). Insert(goqu.T("report")).
Cols( Cols(
"id", "park_id", "period", "category", "meter_o4kv_type", "price_policy", "id", "park_id", "period", "category", "meter_04kv_type", "price_policy",
"basic_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at", "basis_pooled", "adjust_pooled", "loss_pooled", "public_pooled", "created_at",
"last_modified_at", "last_modified_at",
). ).
Vals(goqu.Vals{ Vals(goqu.Vals{
@ -134,38 +138,45 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
createTime, createTime,
}). }).
Prepared(true).ToSQL() Prepared(true).ToSQL()
summarySql, summaryArgs, _ := rr.ds. critical := model.ConsumptionUnit{
Amount: form.Critical,
Fee: form.CriticalFee,
}
criticalData, _ := json.Marshal(critical)
overall := model.ConsumptionUnit{
Amount: form.Overall,
Fee: form.OverallFee,
}
overallData, _ := json.Marshal(overall)
peak := model.ConsumptionUnit{
Amount: form.Peak,
Fee: form.PeakFee,
}
peakData, _ := json.Marshal(peak)
flat := model.ConsumptionUnit{
Amount: form.Flat,
Fee: form.FlatFee,
}
flatData, _ := json.Marshal(flat)
valley := model.ConsumptionUnit{
Amount: form.Valley,
Fee: form.ValleyFee,
}
valleyData, _ := json.Marshal(valley)
summarySql, summaryArgs, err5 := rr.ds.
Insert(goqu.T("report_summary")). Insert(goqu.T("report_summary")).
Cols( //Cols("report_id", "overall", "critical", "peak", "flat", "valley", "basic_fee", "adjust_fee").
"report_id", "overall", "critical", "peak", "flat", "valley", "basic_fee", Rows(goqu.Record{
"adjust_fee", "report_id": reportId,
). "overall": string(overallData),
Vals(goqu.Vals{ "critical": string(criticalData),
reportId, "peak": string(peakData),
model.ConsumptionUnit{ "flat": string(flatData),
Amount: form.Overall, "valley": string(valleyData),
Fee: form.OverallFee, "basic_fee": form.BasicFee,
}, "adjust_fee": form.AdjustFee,
model.ConsumptionUnit{ }).Prepared(true).ToSQL()
Amount: form.Critical, log.Println("errrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr:", err5)
Fee: form.CriticalFee,
},
model.ConsumptionUnit{
Amount: form.Peak,
Fee: form.PeakFee,
},
model.ConsumptionUnit{
Amount: form.Flat,
Fee: form.FlatFee,
},
model.ConsumptionUnit{
Amount: form.Valley,
Fee: form.ValleyFee,
},
form.BasicFee,
form.AdjustFee,
}).
Prepared(true).ToSQL()
taskSql, taskArgs, _ := rr.ds. taskSql, taskArgs, _ := rr.ds.
Insert(goqu.T("report_task")). Insert(goqu.T("report_task")).
Cols("id", "status", "last_modified_at"). Cols("id", "status", "last_modified_at").
@ -189,11 +200,14 @@ func (rr _ReportRepository) CreateReport(form *vo.ReportCreationForm) (bool, str
tx.Rollback(ctx) tx.Rollback(ctx)
return false, "", err return false, "", err
} }
log.Println("?????????", summarySql, summaryArgs)
log.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", resSummary.RowsAffected())
if resSummary.RowsAffected() == 0 { if resSummary.RowsAffected() == 0 {
rr.log.Error("保存核算报表汇总时出现错误", zap.Error(err)) rr.log.Error("保存核算报表汇总时出现错误", zap.Error(err))
tx.Rollback(ctx) tx.Rollback(ctx)
return false, "", exceptions.NewUnsuccessCreateError("创建核算报表汇总时出现错误") return false, "", exceptions.NewUnsuccessCreateError("创建核算报表汇总时出现错误")
} }
resTask, err := tx.Exec(ctx, taskSql, taskArgs...) resTask, err := tx.Exec(ctx, taskSql, taskArgs...)
if err != nil { if err != nil {
rr.log.Error("创建核算报表任务时出现错误", zap.Error(err)) rr.log.Error("创建核算报表任务时出现错误", zap.Error(err))
@ -295,7 +309,6 @@ func (rr _ReportRepository) RetrieveReportSummary(rid string) (*model.ReportSumm
Select("*"). Select("*").
Where(goqu.I("report_id").Eq(rid)). Where(goqu.I("report_id").Eq(rid)).
Prepared(true).ToSQL() Prepared(true).ToSQL()
var summary model.ReportSummary var summary model.ReportSummary
if err := pgxscan.Get(ctx, global.DB, &summary, querySql, queryParams...); err != nil { if err := pgxscan.Get(ctx, global.DB, &summary, querySql, queryParams...); err != nil {
rr.log.Error("获取指定报表的总览信息时出现错误", zap.Error(err)) rr.log.Error("获取指定报表的总览信息时出现错误", zap.Error(err))
@ -332,23 +345,31 @@ func (rr _ReportRepository) GetReportTaskStatus(uid string) ([]*model.ReportTask
} }
// 检索指定核算报表中园区公共表计的核算记录 // 检索指定核算报表中园区公共表计的核算记录
func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyword *string) ([]*model.ReportDetailedPublicConsumption, int64, error) { func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyword *string) ([]*vo.ReportPublishResponse, int64, error) {
rr.log.Info("检索指定核算报表中园区公共表计的核算记录", zap.String("Report", rid)) rr.log.Info("检索指定核算报表中园区公共表计的核算记录", zap.String("Report", rid))
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
reportQuery := rr.ds. reportQuery := rr.ds.
From(goqu.T("report_public_consumption").As("r")). From(goqu.T("report_public_consumption").As("r")).
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.park_meter_id")))). Join(goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
Join(goqu.T("meter_04kv").As("m"), goqu.On(
goqu.I("m.code").Eq(goqu.I("r.park_meter_id")),
goqu.I("m.park_id").Eq(goqu.I("ri.park_id")),
)).
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))). Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))).
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))). LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
Select( Select(
goqu.I("r.*"), goqu.I("b.name").As("building_name"), goqu.I("p.public_pooled"), goqu.I("r.*"), goqu.I("m.*"), goqu.I("b.name").As("building_name"),
). ).
Where(goqu.I("r.report_id").Eq(rid)) Where(goqu.I("r.report_id").Eq(rid))
countQuery := rr.ds. countQuery := rr.ds.
From(goqu.T("report_public_consumption").As("r")). From(goqu.T("report_public_consumption").As("r")).
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.park_meter_id")))). Join(goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
Join(goqu.T("meter_04kv").As("m"), goqu.On(
goqu.I("m.code").Eq(goqu.I("r.park_meter_id")),
goqu.I("m.park_id").Eq(goqu.I("ri.park_id")),
)).
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))). Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))).
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))). LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
Select(goqu.COUNT(goqu.I("r.*"))). Select(goqu.COUNT(goqu.I("r.*"))).
@ -372,7 +393,7 @@ func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyw
Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize) Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize)
var ( var (
consumptions []*model.ReportDetailedPublicConsumption = make([]*model.ReportDetailedPublicConsumption, 0) consumptions = make([]*vo.ReportPublishResponse, 0)
count int64 count int64
) )
querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL() querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL()
@ -390,19 +411,23 @@ func (rr _ReportRepository) ListPublicMetersInReport(rid string, page uint, keyw
// 检索指定核算报表中公摊表计的核算记录 // 检索指定核算报表中公摊表计的核算记录
func (rr _ReportRepository) ListPooledMetersInReport(rid string, page uint, keyword *string) ([]*model.ReportDetailedPooledConsumption, int64, error) { func (rr _ReportRepository) ListPooledMetersInReport(rid string, page uint, keyword *string) ([]*model.ReportDetailedPooledConsumption, int64, error) {
rr.log.Info("检索指定核算报表中公摊表计的核算记录", zap.String("Report", rid)) rr.log.Info("检索指定核算报表中公摊表计的核算记录", zap.String("Report", rid))
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
defer cancel() defer cancel()
reportQuery := rr.ds. reportQuery := rr.ds.
From(goqu.T("report_pooled_consumption").As("r")). From(goqu.T("report_pooled_consumption").As("r")).
Join(
goqu.T("report").As("ri"), goqu.On(goqu.I("ri.id").Eq(goqu.I("r.report_id")))).
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))). Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))).
Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("m.park_id")))). Join(goqu.T("park").As("p"), goqu.On(goqu.I("p.id").Eq(goqu.I("ri.park_id")))).
LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))). LeftJoin(goqu.T("park_building").As("b"), goqu.On(goqu.I("b.id").Eq(goqu.I("m.building")))).
Select( Select(
goqu.I("r.*"), goqu.I("m.*"), goqu.I("b.name").As("building_name"), goqu.I("p.public_pooled"), goqu.I("r.*"), goqu.I("m.*"), goqu.I("b.name").As("building_name"), goqu.I("p.public_pooled"),
). ).
Where(goqu.I("r.report_id").Eq(rid)) Where(goqu.I("r.report_id").Eq(rid))
reportQuery = reportQuery.Where(goqu.I("m.park_id").Eq(goqu.I("p.id")))
countQuery := rr.ds. countQuery := rr.ds.
From(goqu.T("report_pooled_consumption").As("r")). From(goqu.T("report_pooled_consumption").As("r")).
Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))). Join(goqu.T("meter_04kv").As("m"), goqu.On(goqu.I("m.code").Eq(goqu.I("r.pooled_meter_id")))).
@ -479,6 +504,10 @@ func (rr _ReportRepository) ListPooledMeterDetailInReport(rid, mid string) ([]*m
rr.log.Error("列出指定核算报表中指定公共表计下参与公共表计费用分摊的表计详细时出现错误", zap.Error(err)) rr.log.Error("列出指定核算报表中指定公共表计下参与公共表计费用分摊的表计详细时出现错误", zap.Error(err))
return make([]*model.ReportDetailNestedMeterConsumption, 0), err return make([]*model.ReportDetailNestedMeterConsumption, 0), err
} }
if len(meterDetails) <= 0 {
return make([]*model.ReportDetailNestedMeterConsumption, 0), errors.New("暂无分摊关系")
}
assembled := lo.Map(meter.Diluted, func(m model.NestedMeter, _ int) *model.ReportDetailNestedMeterConsumption { assembled := lo.Map(meter.Diluted, func(m model.NestedMeter, _ int) *model.ReportDetailNestedMeterConsumption {
meterDetail, _ := lo.Find(meterDetails, func(elem *model.MeterDetail) bool { meterDetail, _ := lo.Find(meterDetails, func(elem *model.MeterDetail) bool {
return elem.Code == m.MeterId return elem.Code == m.MeterId
@ -534,15 +563,17 @@ func (rr _ReportRepository) ListTenementInReport(rid string, page uint, keyword
Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize) Offset(startRow).Limit(config.ServiceSettings.ItemsPageSize)
var ( var (
tenements []*model.ReportTenement = make([]*model.ReportTenement, 0) tenements = make([]*model.ReportTenement, 0)
count int64 count int64
) )
querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL() querySql, queryArgs, _ := reportQuery.Prepared(true).ToSQL()
countSql, countArgs, _ := countQuery.Prepared(true).ToSQL() countSql, countArgs, _ := countQuery.Prepared(true).ToSQL()
fmt.Println(querySql, rid)
if err := pgxscan.Select(ctx, global.DB, &tenements, querySql, queryArgs...); err != nil { if err := pgxscan.Select(ctx, global.DB, &tenements, querySql, queryArgs...); err != nil {
rr.log.Error("查询指定核算报表下的商户简要计费信息时出现错误", zap.Error(err)) rr.log.Error("查询指定核算报表下的商户简要计费信息时出现错误", zap.Error(err))
return tenements, 0, err return tenements, 0, err
} }
if err := pgxscan.Get(ctx, global.DB, &count, countSql, countArgs...); err != nil { if err := pgxscan.Get(ctx, global.DB, &count, countSql, countArgs...); err != nil {
rr.log.Error("查询指定核算报表下的商户简要计费信息总数量时出现错误", zap.Error(err)) rr.log.Error("查询指定核算报表下的商户简要计费信息总数量时出现错误", zap.Error(err))
return tenements, 0, err return tenements, 0, err
@ -618,7 +649,7 @@ func (rr _ReportRepository) ComprehensiveReportSearch(uid, pid *string, page uin
countQuery = countQuery.Where(goqu.I("ud.id").Eq(*uid)) countQuery = countQuery.Where(goqu.I("ud.id").Eq(*uid))
} }
if pid != nil && len(*pid) > 0 { if pid != nil && *pid != "" {
reportQuery = reportQuery.Where(goqu.I("p.id").Eq(*pid)) reportQuery = reportQuery.Where(goqu.I("p.id").Eq(*pid))
countQuery = countQuery.Where(goqu.I("p.id").Eq(*pid)) countQuery = countQuery.Where(goqu.I("p.id").Eq(*pid))
} }
@ -626,7 +657,8 @@ func (rr _ReportRepository) ComprehensiveReportSearch(uid, pid *string, page uin
queryDateRange := types.NewDateRange(start, end) queryDateRange := types.NewDateRange(start, end)
reportQuery = reportQuery.Where(goqu.L("r.period <@ ?", queryDateRange)) reportQuery = reportQuery.Where(goqu.L("r.period <@ ?", queryDateRange))
countQuery = countQuery.Where(goqu.L("r.period <@ ?", queryDateRange)) countQuery = countQuery.Where(goqu.L("r.period <@ ?", queryDateRange))
reportQuery = reportQuery.Where(goqu.I("r.published").Eq(true))
countQuery = countQuery.Where(goqu.I("r.published").Eq(true))
if keyword != nil && len(*keyword) > 0 { if keyword != nil && len(*keyword) > 0 {
pattern := fmt.Sprintf("%%%s%%", *keyword) pattern := fmt.Sprintf("%%%s%%", *keyword)
reportQuery = reportQuery.Where(goqu.Or( reportQuery = reportQuery.Where(goqu.Or(

View File

@ -226,7 +226,7 @@ func (tr _TenementRepository) AddTenement(tx pgx.Tx, ctx context.Context, pid st
Bank: tools.DefaultOrEmptyStr(tenement.Bank, ""), Bank: tools.DefaultOrEmptyStr(tenement.Bank, ""),
Account: tools.DefaultOrEmptyStr(tenement.Account, ""), Account: tools.DefaultOrEmptyStr(tenement.Account, ""),
}, },
currentTime, tenement.MoveIn,
currentTime, currentTime,
currentTime, currentTime,
}..., }...,
@ -238,7 +238,7 @@ func (tr _TenementRepository) AddTenement(tx pgx.Tx, ctx context.Context, pid st
} }
// 向园区中指定商户下绑定一个新的表计 // 向园区中指定商户下绑定一个新的表计
func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid, meter string) error { func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid, meter string, form *vo.MeterReadingForm) error {
tr.log.Info("向园区中指定商户下绑定一个新的表计", zap.String("Park", pid), zap.String("Tenement", tid), zap.String("Meter", meter)) tr.log.Info("向园区中指定商户下绑定一个新的表计", zap.String("Park", pid), zap.String("Tenement", tid), zap.String("Meter", meter))
createSql, createArgs, _ := tr.ds. createSql, createArgs, _ := tr.ds.
@ -251,7 +251,7 @@ func (tr _TenementRepository) BindMeter(tx pgx.Tx, ctx context.Context, pid, tid
pid, pid,
tid, tid,
meter, meter,
types.Now(), form.ReadAt,
}, },
). ).
Prepared(true).ToSQL() Prepared(true).ToSQL()

View File

@ -9,6 +9,7 @@ import (
"electricity_bill_calc/tools" "electricity_bill_calc/tools"
"electricity_bill_calc/types" "electricity_bill_calc/types"
"fmt" "fmt"
"log"
"time" "time"
"github.com/doug-martin/goqu/v9" "github.com/doug-martin/goqu/v9"
@ -238,8 +239,11 @@ func (ur _UserRepository) FindUser(keyword *string, userType int16, state *bool,
} }
if state != nil { if state != nil {
userQuery = userQuery.Where(goqu.Ex{"u.enabled": state}) //userQuery = userQuery.Where(goqu.C("u.enabled").Eq(*state))
countQuery = countQuery.Where(goqu.Ex{"u.enabled": state}) userQuery = userQuery.Where(goqu.Ex{"u.enabled": *state})
countQuery = countQuery.Where(goqu.Ex{"u.enabled": *state})
//countQuery = countQuery.Where(goqu.C("u.enabled").Eq(*state))
} }
userQuery.Order(goqu.I("u.created_at").Desc()) userQuery.Order(goqu.I("u.created_at").Desc())
@ -249,8 +253,9 @@ func (ur _UserRepository) FindUser(keyword *string, userType int16, state *bool,
userSql, userParams, _ := userQuery.Prepared(true).ToSQL() userSql, userParams, _ := userQuery.Prepared(true).ToSQL()
countSql, countParams, _ := countQuery.Prepared(true).ToSQL() countSql, countParams, _ := countQuery.Prepared(true).ToSQL()
log.Println(">>>>>>>>>>>", userSql)
if err := pgxscan.Select(ctx, global.DB, &userWithDetails, userSql, userParams...); err != nil { if err := pgxscan.Select(ctx, global.DB, &userWithDetails, userSql, userParams...); err != nil {
ur.log.Error("从数据库查询用户列表失败。", zap.Error(err)) ur.log.Error("从数据库查询用户列表失败。》》》》》》》》》》》》》》", zap.Error(err))
return make([]*model.UserWithDetail, 0), 0, err return make([]*model.UserWithDetail, 0), 0, err
} }
if err := pgxscan.Get(ctx, global.DB, &userCount, countSql, countParams...); err != nil { if err := pgxscan.Get(ctx, global.DB, &userCount, countSql, countParams...); err != nil {

View File

@ -3,10 +3,10 @@ package calculate
import ( import (
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/model/calculate" "electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository"
"errors" "errors"
"fmt" "fmt"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"log"
) )
func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []calculate.Meter, publics []calculate.Meter) (MeterMap, error) { func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []calculate.Meter, publics []calculate.Meter) (MeterMap, error) {
@ -14,20 +14,27 @@ func CollectMeters(tenements []calculate.PrimaryTenementStatistics, poolings []c
// Collect tenement meters // Collect tenement meters
for _, t := range tenements { for _, t := range tenements {
for _, m := range t.Meters { for _, m := range t.Meters {
log.Println("m000000000000000000000000000", m.Code)
key := Key{TenementID: t.Tenement.Id, Code: m.Code} key := Key{TenementID: t.Tenement.Id, Code: m.Code}
meters[key] = m meters[key] = m
} }
} }
// Collect poolings // Collect poolings
for _, m := range poolings { for _, m := range poolings {
log.Println("m111111111111111111111111", m.Code)
key := Key{TenementID: "", Code: m.Code} key := Key{TenementID: "", Code: m.Code}
meters[key] = m meters[key] = m
} }
// Collect publics // Collect publics
for _, m := range publics { for _, m := range publics {
log.Println("m222222222222222222222222222", m.Code)
key := Key{TenementID: "", Code: m.Code} key := Key{TenementID: "", Code: m.Code}
meters[key] = m meters[key] = m
} }
log.Println("m33333333333333333333333333333333333333", meters[Key{Code: "yq00001"}])
return meters, nil return meters, nil
} }
@ -144,9 +151,9 @@ func CalculateLossPooling(report model.ReportIndex, summary calculate.Summary, m
/// 计算所有商户类型表计的全周期电量。 /// 计算所有商户类型表计的全周期电量。
func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal, error) { func CalculateTenementConsumptions(meters *MeterMap) (map[string]decimal.Decimal, error) {
consumptions := make(map[string]decimal.Decimal) consumptions := make(map[string]decimal.Decimal)
for _, meter := range meters { for _, meter := range *meters {
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
amount, ok := consumptions[meter.Code] amount, ok := consumptions[meter.Code]
if !ok { if !ok {
@ -156,7 +163,7 @@ func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal,
consumptions[meter.Code] = amount consumptions[meter.Code] = amount
} }
} }
for _, meter := range meters { for _, meter := range *meters {
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
amount, ok := consumptions[meter.Code] amount, ok := consumptions[meter.Code]
if !ok { if !ok {
@ -176,273 +183,174 @@ func CalculateTenementConsumptions(meters MeterMap) (map[string]decimal.Decimal,
return consumptions, nil return consumptions, nil
} }
/*
/// 计算商户表计的公摊分摊
func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error {
for _, meter := range meters {
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
switch report.PublicPooled {
case model.POOLING_MODE_AREA:
for _, relation := range meterRelations {
if relation.SlaveMeter == meter.Code {
key := Key{
Code: relation.MasterMeter,
}
parentMeter, ok := meters[key]
if !ok {
return errors.New("父级表记未找到")
}
poolingAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea).
Mul(meter.SharedPoolingProportion).
Mul(parentMeter.Overall.Amount).Mul(summary.Overall.Price)
pooling := calculate.Pooling{
Code: parentMeter.Code,
Detail: model.ConsumptionUnit{
Amount: poolingAmount,
Fee: poolingAmount.Mul(summary.Overall.Price),
Price: summary.Overall.Price,
//后续debug此处需要判断
Proportion: poolingAmount.Div(parentMeter.Overall.Amount),
},
}
pooling := calculate.Pooling{
Code: parentMeter.Code,
Detail: model.ConsumptionUnit{
Amount: poolingAmount,
Fee: poolingAmount.Mul(summary.Overall.Price),
Price: summary.Overall.Price,
Proportion: poolingAmount.Div(parentMeter.Overall.Amount),
},
}
meter.PooledPublic = &ConsumptionUnit{
Amount: poolingAmount,
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
Price: summary.Overall.Price,
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
}
meter.Poolings = append(meter.Poolings, pooling)
}
}
case Consumption:
for _, relation := range meterRelations {
if relation.SlaveMeter == meter.Code {
parentMeter, ok := meters[relation.MasterMeter]
if !ok {
return errors.New("parent meter not found")
}
if parentMeter.Overall.Amount.Cmp(new(big.Rat)) == 0 {
poolingAmount := new(big.Rat)
parentAmount := new(big.Rat)
pooling := &Pooling{
Code: parentMeter.Code,
Detail: &ConsumptionUnit{
Amount: poolingAmount,
Fee: new(big.Rat),
Price: summary.Overall.Price,
Proportion: new(big.Rat),
},
}
meter.PooledPublic = &ConsumptionUnit{
Amount: poolingAmount,
Fee: new(big.Rat),
Price: summary.Overall.Price,
Proportion: new(big.Rat),
}
meter.Poolings = append(meter.Poolings, pooling)
} else {
poolingAmount := new(big.Rat).Mul(meter.Overall.Amount, new(big.Rat).Quo(parentMeter.Overall.Amount, parentMeter.Overall.Amount))
parentAmount := parentMeter.Overall.Amount
pooling := &Pooling{
Code: parentMeter.Code,
Detail: &ConsumptionUnit{
Amount: poolingAmount,
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
Price: summary.Overall.Price,
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
},
}
meter.PooledPublic = &ConsumptionUnit{
Amount: poolingAmount,
Fee: new(big.Rat).Mul(poolingAmount, summary.Overall.Price),
Price: summary.Overall.Price,
Proportion: new(big.Rat).Quo(poolingAmount, parentAmount),
}
meter.Poolings = append(meter.Poolings, pooling)
}
}
}
default:
// handle other pooling modes...
}
}
}
return nil
}
*/
// 计算商户表计的公摊分摊 // 计算商户表计的公摊分摊
func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error { func CalculateTenementPoolings(report model.ReportIndex, summary calculate.Summary, meters MeterMap, meterRelations []model.MeterRelation) error {
switch report.PublicPooled { switch report.PublicPooled {
case model.POOLING_MODE_AREA: case model.POOLING_MODE_AREA:
for _, meter := range meters { for _, meter := range meters {
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
var pooleds []struct { pooleds := make([]struct {
PooledAmount decimal.Decimal Electricity decimal.Decimal
ParentAmount decimal.Decimal ParentElectricity decimal.Decimal
ParentCode string Code string
} }, 0)
for _, relation := range meterRelations { for _, relation := range meterRelations {
if relation.SlaveMeter == meter.Code { if relation.SlaveMeter == meter.Code {
key := Key{ key := Key{
Code: relation.MasterMeter, Code: relation.MasterMeter,
TenementID: "",
} }
parentMeter, ok := meters[key] parentMeter, ok := meters[key]
if !ok { if !ok {
// 处理未找到父级表计的情况
continue continue
} }
// 计算分摊电量和父级表电量
pooledAmount := meter.Detail.Area.Decimal.Div(parentMeter.CoveredArea).Mul(parentMeter.Overall.Amount).Mul(meter.SharedPoolingProportion) area := parentMeter.CoveredArea
coveredArea := area
overall := parentMeter.Overall
proportion := meter.SharedPoolingProportion
electricity := area.InexactFloat64() / coveredArea.InexactFloat64() * overall.Amount.InexactFloat64() * proportion.InexactFloat64()
pooleds = append(pooleds, struct { pooleds = append(pooleds, struct {
PooledAmount decimal.Decimal Electricity decimal.Decimal
ParentAmount decimal.Decimal ParentElectricity decimal.Decimal
ParentCode string Code string
}{ }{
PooledAmount: pooledAmount, Electricity: decimal.NewFromFloat(electricity),
ParentAmount: parentMeter.Overall.Amount, ParentElectricity: overall.Amount,
ParentCode: parentMeter.Code, Code: parentMeter.Code,
}) })
} }
} }
// 计算总分摊电量和总父级电量 consumptions := 0.00
var consumptions, total decimal.Decimal total := 0.00
for _, p := range pooleds { var pooled []*calculate.Pooling
consumptions = consumptions.Add(p.PooledAmount)
total = total.Add(p.ParentAmount)
}
// 计算并更新公摊分摊信息
for _, p := range pooleds { for _, p := range pooleds {
poolingAmount := p.PooledAmount consumptions += p.Electricity.InexactFloat64()
proportion := p.PooledAmount.Div(p.ParentAmount) total += p.ParentElectricity.InexactFloat64()
fee := poolingAmount.Mul(summary.Overall.Price)
// 更新父级表计的公摊分摊信息 unit := model.ConsumptionUnit{
key := Key{ Amount: p.Electricity,
Code: p.ParentCode, Fee: decimal.NewFromFloat(p.Electricity.InexactFloat64() * summary.Overall.Price.InexactFloat64()),
Price: summary.Overall.Price,
Proportion: decimal.Zero,
} }
parentMeter := meters[key]
parentMeter.PooledPublic.Amount = consumptions if p.ParentElectricity != decimal.Zero {
parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price) unit.Proportion = decimal.NewFromFloat(p.Electricity.InexactFloat64() / p.ParentElectricity.InexactFloat64())
parentMeter.PooledPublic.Proportion = consumptions.Div(total) }
meters[Key{Code: p.ParentCode}] = parentMeter
// 创建并更新分摊信息
pooling := calculate.Pooling{ pooling := calculate.Pooling{
Code: p.ParentCode, Code: p.Code,
Detail: model.ConsumptionUnit{ Detail: unit,
Amount: poolingAmount,
Fee: fee,
Price: summary.Overall.Price,
Proportion: proportion,
},
} }
meter.Poolings = append(meter.Poolings, &pooling)
pooled = append(pooled, &pooling)
} }
meter.PooledPublic = model.ConsumptionUnit{
Amount: decimal.NewFromFloat(consumptions),
Fee: decimal.NewFromFloat(consumptions * summary.Overall.Price.InexactFloat64()),
Price: summary.Overall.Price,
Proportion: decimal.NewFromFloat(consumptions / total),
}
meter.Poolings = pooled
} }
} }
case model.PRICING_POLICY_CONSUMPTION:
case model.POOLING_MODE_CONSUMPTION:
for _, meter := range meters { for _, meter := range meters {
if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT { if meter.Detail.MeterType == model.METER_INSTALLATION_TENEMENT {
var pooled []struct { pooled := make([]struct {
PooledAmount decimal.Decimal Electricity decimal.Decimal
ParentAmount decimal.Decimal ParentElectricity decimal.Decimal
ParentCode string Code string
} }, 0)
for _, relation := range meterRelations { for _, relation := range meterRelations {
if relation.SlaveMeter == meter.Code { if relation.SlaveMeter == meter.Code {
parentMeter, ok := meters[Key{Code: relation.MasterMeter}] key := Key{
Code: relation.MasterMeter,
TenementID: "",
}
parentMeter, ok := meters[key]
if !ok { if !ok {
// 处理未找到父级表计的情况
continue continue
} }
// 计算分摊电量和父级电量
var pooledAmount decimal.Decimal overall := parentMeter.Overall
if parentMeter.Overall.Amount.IsZero() {
relations, err := repository.MeterRepository.ListPooledMeterRelations(report.Park, meter.Code) if overall.Amount == decimal.Zero {
if err != nil { pooled = append(pooled, struct {
return err Electricity decimal.Decimal
} ParentElectricity decimal.Decimal
//此处rust版本有误更新后的解决办法 Code string
pooledAmount = meter.Overall.Amount.Div(decimal.NewFromInt(int64(len(relations)))).Mul(parentMeter.Overall.Amount) }{
Electricity: decimal.Zero,
ParentElectricity: decimal.Zero,
Code: parentMeter.Code,
})
} else { //TODO: 2023.08.11 计算处理流程修改到此处,以下问题未作修改还存在问题
electricity := meter.Overall.Amount.InexactFloat64() / overall.Amount.InexactFloat64() * overall.Amount.InexactFloat64()
pooled = append(pooled, struct {
Electricity decimal.Decimal
ParentElectricity decimal.Decimal
Code string
}{
Electricity: decimal.NewFromFloat(electricity),
ParentElectricity: overall.Amount,
Code: parentMeter.Code,
})
} }
pooled = append(pooled, struct {
PooledAmount decimal.Decimal
ParentAmount decimal.Decimal
ParentCode string
}{
PooledAmount: pooledAmount,
ParentAmount: parentMeter.Overall.Amount,
ParentCode: parentMeter.Code,
})
} }
} }
// 计算总分摊电量和总父级表记电量 consumptions := decimal.Zero.InexactFloat64()
var consumptions, total decimal.Decimal total := decimal.Zero.InexactFloat64()
var poolings []*calculate.Pooling
for _, p := range pooled { for _, p := range pooled {
consumptions = consumptions.Add(p.PooledAmount) consumptions += p.Electricity.InexactFloat64()
total = total.Add(p.ParentAmount) total += p.ParentElectricity.InexactFloat64()
}
// 计算并更新公摊分摊信息 unit := model.ConsumptionUnit{
for _, p := range pooled { Amount: p.Electricity,
poolingAmount := p.PooledAmount Fee: decimal.NewFromFloat(p.Electricity.InexactFloat64() * summary.Overall.Price.InexactFloat64()),
proportion := p.PooledAmount.Div(p.ParentAmount) Price: summary.Overall.Price,
fee := poolingAmount.Mul(summary.Overall.Price) Proportion: decimal.Zero,
}
// 更新父级表计的公摊分摊信息 if p.ParentElectricity != decimal.Zero {
parentMeter := meters[Key{Code: p.ParentCode}] unit.Proportion = decimal.NewFromFloat(p.Electricity.InexactFloat64() / p.ParentElectricity.InexactFloat64())
parentMeter.PooledPublic.Amount = consumptions }
parentMeter.PooledPublic.Fee = consumptions.Mul(summary.Overall.Price)
parentMeter.PooledPublic.Proportion = consumptions.Div(total)
meters[Key{Code: p.ParentCode}] = parentMeter
// 创建并更新分摊信息
pooling := calculate.Pooling{ pooling := calculate.Pooling{
Code: p.ParentCode, Code: p.Code,
Detail: model.ConsumptionUnit{ Detail: unit,
Amount: poolingAmount,
Fee: fee,
Price: summary.Overall.Price,
Proportion: proportion,
},
} }
meter.Poolings = append(meter.Poolings, &pooling)
poolings = append(poolings, &pooling)
} }
meter.PooledPublic = model.ConsumptionUnit{
Amount: decimal.NewFromFloat(consumptions),
Fee: decimal.NewFromFloat(consumptions * summary.Overall.Price.InexactFloat64()),
Price: summary.Overall.Price,
Proportion: decimal.Zero,
}
if total != decimal.Zero.InexactFloat64() {
meter.SharedPoolingProportion = decimal.NewFromFloat(consumptions / total)
}
meter.Poolings = poolings
} }
} }
default: default:
// 处理其他分摊模式 return nil
} }
return nil return nil
} }

View File

@ -4,6 +4,7 @@ import (
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/model/calculate" "electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository" "electricity_bill_calc/repository"
"fmt"
"time" "time"
) )
@ -22,6 +23,11 @@ func MetersParkCalculate(report model.ReportIndex, periodStart time.Time,
parkMeterReadings = append(parkMeterReadings, lastTermParkMeterReadings...) parkMeterReadings = append(parkMeterReadings, lastTermParkMeterReadings...)
if len(parkMeterReadings) <= 0 {
fmt.Println(parkMeterReadings)
return []calculate.Meter{}, nil
}
var parkMetersReports []calculate.Meter var parkMetersReports []calculate.Meter
for _, meter := range meterDetail { for _, meter := range meterDetail {
if meter.MeterType == model.METER_INSTALLATION_PARK { if meter.MeterType == model.METER_INSTALLATION_PARK {

View File

@ -1,51 +1,44 @@
package calculate package calculate
import ( import (
"electricity_bill_calc/global" "context"
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/model/calculate" "electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository" "electricity_bill_calc/repository"
"fmt"
"github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5"
) )
// 向数据库保存核算概况结果 // 向数据库保存核算概况结果
func SaveSummary(tx pgx.Tx, summary calculate.Summary) error { func SaveSummary(tx pgx.Tx, ctx context.Context, summary calculate.Summary) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
// 保存核算概况结果到数据库 // 保存核算概况结果到数据库
err := repository.CalculateRepository.SaveReportSummary(tx, summary) err := repository.CalculateRepository.SaveReportSummary(tx,ctx, summary)
if err != nil { if err != nil {
return err return err
} }
tx.Commit(ctx)
return nil return nil
} }
// type MeterMap map[string]map[string]calculate.Meter // type MeterMap map[string]map[string]calculate.Meter
// 向数据库保存公共表计的计算结果 // 向数据库保存公共表计的计算结果
func SavePublics(tx pgx.Tx, report model.ReportIndex, meters MeterMap) error { func SavePublics(tx pgx.Tx, ctx context.Context, report model.ReportIndex, meters MeterMap) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
var filteredMeters []calculate.Meter var filteredMeters []calculate.Meter
for _, m := range meters { for _, m := range meters {
if m.Detail.MeterType == model.METER_INSTALLATION_PARK { if m.Detail.MeterType == model.METER_INSTALLATION_PARK {
filteredMeters = append(filteredMeters, m) filteredMeters = append(filteredMeters, m)
} }
} }
err := repository.CalculateRepository.SaveReportPublics(tx, report.Id, filteredMeters) fmt.Println(tx)
err := repository.CalculateRepository.SaveReportPublics(tx, ctx, report.Id, filteredMeters)
if err != nil { if err != nil {
return err return err
} }
tx.Commit(ctx)
return nil return nil
} }
func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relations []model.MeterRelation) error { func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relations []model.MeterRelation) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
var poolingMeters []calculate.Meter var poolingMeters []calculate.Meter
var tenementMeters []calculate.Meter var tenementMeters []calculate.Meter
// 根据条件筛选 Meter 并保存到对应的数组中 // 根据条件筛选 Meter 并保存到对应的数组中
@ -60,13 +53,9 @@ func SavePoolings(tx pgx.Tx, report model.ReportIndex, meters MeterMap, relation
if err != nil { if err != nil {
return err return err
} }
tx.Commit(ctx)
return nil return nil
} }
func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.PrimaryTenementStatistics, tc []calculate.TenementCharge) error { func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.PrimaryTenementStatistics, tc []calculate.TenementCharge) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
var ts []model.Tenement var ts []model.Tenement
for _, r := range tenement { for _, r := range tenement {
ts = append(ts, r.Tenement) ts = append(ts, r.Tenement)
@ -75,7 +64,5 @@ func SaveTenements(tx pgx.Tx, report model.ReportIndex, tenement []calculate.Pri
if err != nil { if err != nil {
return err return err
} }
tx.Commit(ctx)
return nil return nil
} }

View File

@ -4,12 +4,13 @@ import (
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/model/calculate" "electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository" "electricity_bill_calc/repository"
"electricity_bill_calc/types"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"time" "time"
"unsafe" "unsafe"
) )
//核算园区中的全部公摊表计的电量用量 // 核算园区中的全部公摊表计的电量用量
func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time, func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
periodEnd time.Time, meterDetails []*model.MeterDetail, periodEnd time.Time, meterDetails []*model.MeterDetail,
summary calculate.Summary) ([]calculate.Meter, error) { summary calculate.Summary) ([]calculate.Meter, error) {
@ -24,6 +25,9 @@ func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
} }
poolingMeterReadings = append(poolingMeterReadings, lastTermPoolingMeterReadings...) poolingMeterReadings = append(poolingMeterReadings, lastTermPoolingMeterReadings...)
if len(poolingMeterReadings) <= 0 {
return nil, nil
}
var poolingMetersReports []calculate.Meter var poolingMetersReports []calculate.Meter
for _, meter := range meterDetails { for _, meter := range meterDetails {
@ -36,10 +40,14 @@ func PooledMetersCalculate(report *model.ReportIndex, periodStart time.Time,
return poolingMetersReports, nil return poolingMetersReports, nil
} }
// 确定指定非商户表计在指定时间段内的全部电量 // 确定指定非商户表计在指定时间段内的全部电量
func determinePublicMeterConsumptions(meterId string, periodStart time.Time, func determinePublicMeterConsumptions(meterId string, periodStart time.Time,
periodEnd time.Time, readings []model.MeterReading, periodEnd time.Time, readings []model.MeterReading,
meterDetail model.MeterDetail, summary calculate.Summary) (calculate.Meter, error) { meterDetail model.MeterDetail, summary calculate.Summary) (calculate.Meter, error) {
if meterDetail.DetachedAt == nil {
zeroTime := time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
meterDetail.DetachedAt = &types.DateTime{Time: zeroTime}
}
startReading, err := DeterminePublicMeterStartReading(meterId, periodStart, meterDetail.DetachedAt.Time, readings) startReading, err := DeterminePublicMeterStartReading(meterId, periodStart, meterDetail.DetachedAt.Time, readings)
if err != nil { if err != nil {
return calculate.Meter{}, err return calculate.Meter{}, err

View File

@ -36,13 +36,15 @@ func DeterminePublicMeterStartReading(meterId string, periodStart time.Time,
for _, reading := range meterReadings { for _, reading := range meterReadings {
readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC()) readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC())
for _, startTime := range startTimes { for _, startTime := range startTimes {
if reading.Meter == meterId && readingAt.After(startTime) || readingAt.Equal(startTime) { if reading.Meter == meterId && readingAt.Truncate(24*time.Hour).Equal(startTime.Truncate(24*time.Hour)) || readingAt.After(startTime) {
startReading = append(startReading, reading) startReading = append(startReading, reading)
break break
} }
} }
} }
fmt.Println(startReading)
if len(startReading) <= 0 { if len(startReading) <= 0 {
return nil, errors.New(fmt.Sprintf("无法确定表计 %s 的计量的起始读数", meterId)) return nil, errors.New(fmt.Sprintf("无法确定表计 %s 的计量的起始读数", meterId))
} }
@ -71,20 +73,20 @@ func DeterminePublicMeterEndReading(meterId string, periodEnd time.Time,
minReading = reading.ReadAt minReading = reading.ReadAt
} }
} }
startTimes := []time.Time{ endTimes := []time.Time{
minReading.Time, minReading.Time,
periodEnding.Time, periodEnding.Time,
ShiftToAsiaShanghai(detachedAt), ShiftToAsiaShanghai(detachedAt),
} }
if len(startTimes) < 0 { if len(endTimes) < 0 {
return nil, errors.New(fmt.Sprintf("无法确定表计 {%s} 的计量的终止时间", meterId)) return nil, errors.New(fmt.Sprintf("无法确定表计 {%s} 的计量的终止时间", meterId))
} }
var startReading []model.MeterReading var startReading []model.MeterReading
for _, reading := range meterReadings { for _, reading := range meterReadings {
readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC()) readingAt := ShiftToAsiaShanghai(reading.ReadAt.UTC())
for _, startTime := range startTimes { for _, endTime := range endTimes {
if reading.Meter == meterId && readingAt.After(startTime) || readingAt.Equal(startTime) { if reading.Meter == meterId && readingAt.Truncate(24*time.Hour).Equal(endTime.Truncate(24*time.Hour)) || readingAt.Before(endTime) {
startReading = append(startReading, reading) startReading = append(startReading, reading)
break break
} }

View File

@ -13,6 +13,7 @@ import (
func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics, summary calculate.Summary) decimal.Decimal { func TotalConsumptionCalculate(tenements []calculate.PrimaryTenementStatistics, summary calculate.Summary) decimal.Decimal {
var areaMaters []calculate.Meter var areaMaters []calculate.Meter
for _, t := range tenements { for _, t := range tenements {
fmt.Println(t.Meters)
areaMaters = append(areaMaters, t.Meters...) areaMaters = append(areaMaters, t.Meters...)
} }
@ -42,7 +43,7 @@ func removeDuplicates(meters []calculate.Meter) []calculate.Meter {
} }
// 计算线损以及调整线损 // 计算线损以及调整线损
func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter, func LossCalculate(report *model.ReportIndex, Public []calculate.Meter,
publicTotal *decimal.Decimal, summary *calculate.Summary) error { publicTotal *decimal.Decimal, summary *calculate.Summary) error {
summary.Loss = summary.Overall.Amount.Sub(summary.TotalConsumption) summary.Loss = summary.Overall.Amount.Sub(summary.TotalConsumption)
@ -56,7 +57,7 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
summary.LossProportion = summary.Loss.Div(summaryAmount) summary.LossProportion = summary.Loss.Div(summaryAmount)
var authorizedLossRate decimal.Decimal var authorizedLossRate decimal.Decimal
//TODO: 2023.08.04 在此发现reportIndex结构体与数据库中的report表字段不对应缺少两个相应字段在此添加的如在其他地方有错误优先查找这里 // TODO: 2023.08.04 在此发现reportIndex结构体与数据库中的report表字段不对应缺少两个相应字段在此添加的如在其他地方有错误优先查找这里
if summary.LossProportion.InexactFloat64() > report.AuthorizedLossRate { if summary.LossProportion.InexactFloat64() > report.AuthorizedLossRate {
authorizedLossRate = summary.LossProportion authorizedLossRate = summary.LossProportion
} else { } else {
@ -72,11 +73,15 @@ func LossCalculate(report *model.ReportIndex, Public *[]calculate.Meter,
differentialLoss := summary.LossDilutedPrice.Sub(summary.AuthoizeLoss.Amount) differentialLoss := summary.LossDilutedPrice.Sub(summary.AuthoizeLoss.Amount)
fmt.Println(publicTotal.InexactFloat64())
if publicTotal.InexactFloat64() <= decimal.Zero.InexactFloat64() { if publicTotal.InexactFloat64() <= decimal.Zero.InexactFloat64() {
return errors.New("园区公共表计的电量总和为非正值,或者园区未设置公共表计,无法计算核定线损") return errors.New("园区公共表计的电量总和为非正值,或者园区未设置公共表计,无法计算核定线损")
} }
for _, meter := range *Public { if Public == nil {
return nil
}
for _, meter := range Public {
amountProportion := meter.Overall.Amount.InexactFloat64() / publicTotal.InexactFloat64() amountProportion := meter.Overall.Amount.InexactFloat64() / publicTotal.InexactFloat64()
adjustAmount := differentialLoss.InexactFloat64() * decimal.NewFromFloat(-1.0).InexactFloat64() adjustAmount := differentialLoss.InexactFloat64() * decimal.NewFromFloat(-1.0).InexactFloat64()
meter.AdjustLoss = model.ConsumptionUnit{ meter.AdjustLoss = model.ConsumptionUnit{

View File

@ -4,6 +4,7 @@ import (
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/model/calculate" "electricity_bill_calc/model/calculate"
"electricity_bill_calc/repository" "electricity_bill_calc/repository"
"electricity_bill_calc/types"
"errors" "errors"
"fmt" "fmt"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
@ -42,7 +43,6 @@ func TenementMetersCalculate(report *model.ReportIndex,
} }
var tenementReports []calculate.PrimaryTenementStatistics var tenementReports []calculate.PrimaryTenementStatistics
for _, tenement := range tenements { for _, tenement := range tenements {
var meters []model.TenementMeter var meters []model.TenementMeter
@ -79,13 +79,24 @@ func determineTenementConsumptions(tenement model.Tenement,
meterDetails []*model.MeterDetail, summary calculate.Summary) (calculate.PrimaryTenementStatistics, error) { meterDetails []*model.MeterDetail, summary calculate.Summary) (calculate.PrimaryTenementStatistics, error) {
var meters []calculate.Meter var meters []calculate.Meter
for _, meter := range relatedMeters { for _, meter := range relatedMeters {
startReading, err := determineTenementMeterStartReading(meter.MeterId, periodStart, ShiftToAsiaShanghai(tenement.MovedInAt.Time), meter, currentTermReadings, lastPeriodReadings)
movedInAt := tenement.MovedInAt
if movedInAt == nil {
shiftedTime := ShiftToAsiaShanghai(time.Time{})
movedInAt = &types.DateTime{Time: shiftedTime}
}
startReading, err := determineTenementMeterStartReading(meter.MeterId, periodStart, ShiftToAsiaShanghai(movedInAt.Time), meter, currentTermReadings, lastPeriodReadings)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return calculate.PrimaryTenementStatistics{}, err return calculate.PrimaryTenementStatistics{}, err
} }
endReading, err := determineTenementMeterEndReading(meter.MeterId, periodEnd, ShiftToAsiaShanghai(tenement.MovedOutAt.Time), meter, currentTermReadings) moveOutAt := tenement.MovedOutAt
if moveOutAt == nil {
shiftedTime := ShiftToAsiaShanghai(time.Time{})
moveOutAt = &types.DateTime{Time: shiftedTime} // 使用 types.DateTime 的零值表示时间的最大值
}
endReading, err := determineTenementMeterEndReading(meter.MeterId, periodEnd, ShiftToAsiaShanghai(moveOutAt.Time), meter, currentTermReadings)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return calculate.PrimaryTenementStatistics{}, err return calculate.PrimaryTenementStatistics{}, err
@ -142,7 +153,7 @@ func determineTenementConsumptions(tenement model.Tenement,
} }
currentTermReadingPtr := &currentTermReading currentTermReadingPtr := &currentTermReading
meter := calculate.Meter{ m := calculate.Meter{
Code: meter.MeterId, Code: meter.MeterId,
Detail: detail, Detail: detail,
CoveredArea: decimal.NewFromFloat(detail.Area.Decimal.InexactFloat64()), CoveredArea: decimal.NewFromFloat(detail.Area.Decimal.InexactFloat64()),
@ -165,7 +176,7 @@ func determineTenementConsumptions(tenement model.Tenement,
Poolings: nil, Poolings: nil,
} }
meters = append(meters, meter) meters = append(meters, m)
} }
return calculate.PrimaryTenementStatistics{ return calculate.PrimaryTenementStatistics{
@ -272,6 +283,7 @@ func ShiftToAsiaShanghai(t time.Time) time.Time {
func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics, func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
summary calculate.Summary, meters MeterMap) []calculate.TenementCharge { summary calculate.Summary, meters MeterMap) []calculate.TenementCharge {
result := make(map[string][]string) result := make(map[string][]string)
var tc []calculate.TenementCharge
for _, t := range tenements { for _, t := range tenements {
meterCodes := make([]string, 0) meterCodes := make([]string, 0)
for _, m := range t.Meters { for _, m := range t.Meters {
@ -281,11 +293,10 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
result[t.Tenement.Id] = meterCodes result[t.Tenement.Id] = meterCodes
} }
var Key Key var Key Key
var tc []calculate.TenementCharge
for tCode, meterCodes := range result { for tCode, meterCodes := range result {
relatedMeters := make([]calculate.Meter, 0) relatedMeters := make([]calculate.Meter, 0)
for _, code := range meterCodes { for _, code := range meterCodes {
Key.Code = code + "_" + tCode Key.Code = code
meter, ok := meters[Key] meter, ok := meters[Key]
if ok { if ok {
relatedMeters = append(relatedMeters, meter) relatedMeters = append(relatedMeters, meter)
@ -390,55 +401,77 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
} }
var CriticalProportion decimal.Decimal var CriticalProportion decimal.Decimal
if summary.Critical.Amount == decimal.Zero { if summary.Critical.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
CriticalProportion = decimal.Zero CriticalProportion = decimal.Zero
} else { } else {
CriticalProportion = decimal.NewFromFloat(critical.Amount.InexactFloat64() / summary.Critical.Amount.InexactFloat64()) CriticalProportion = decimal.NewFromFloat(critical.Amount.InexactFloat64() / summary.Critical.Amount.InexactFloat64())
} }
var PeakProportion decimal.Decimal var PeakProportion decimal.Decimal
if summary.Peak.Amount == decimal.Zero { if summary.Peak.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
PeakProportion = decimal.Zero PeakProportion = decimal.Zero
} else { } else {
PeakProportion = decimal.NewFromFloat(peak.Amount.InexactFloat64() / summary.Peak.Amount.InexactFloat64()) PeakProportion = decimal.NewFromFloat(peak.Amount.InexactFloat64() / summary.Peak.Amount.InexactFloat64())
} }
var FlatProportion decimal.Decimal var FlatProportion decimal.Decimal
if summary.Flat.Amount == decimal.Zero { if summary.Flat.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
FlatProportion = decimal.Zero FlatProportion = decimal.Zero
} else { } else {
FlatProportion = decimal.NewFromFloat(flat.Amount.InexactFloat64() / summary.Flat.Amount.InexactFloat64()) FlatProportion = decimal.NewFromFloat(flat.Amount.InexactFloat64() / summary.Flat.Amount.InexactFloat64())
} }
var ValleyProportion decimal.Decimal var ValleyProportion decimal.Decimal
if summary.Valley.Amount == decimal.Zero { if summary.Valley.Amount.InexactFloat64() == decimal.Zero.InexactFloat64() {
ValleyProportion = decimal.Zero ValleyProportion = decimal.Zero
} else { } else {
ValleyProportion = decimal.NewFromFloat(valley.Amount.InexactFloat64() / summary.Valley.Amount.InexactFloat64()) ValleyProportion = decimal.NewFromFloat(valley.Amount.InexactFloat64() / summary.Valley.Amount.InexactFloat64())
} }
var lossProportion decimal.Decimal
if summary.AuthoizeLoss.Amount == decimal.Zero {
lossProportion = decimal.Zero
} else {
lossProportion = decimal.NewFromFloat(lossAmount.InexactFloat64() / summary.AuthoizeLoss.Amount.InexactFloat64())
}
tenementCharge := calculate.TenementCharge{ tenementCharge := calculate.TenementCharge{
Tenement: tCode, Tenement: tCode,
Overall: model.ConsumptionUnit{ Overall: model.ConsumptionUnit{
Amount: overall.Amount,
Fee: overall.Fee,
Price: summary.Overall.Price, Price: summary.Overall.Price,
Proportion: OverallProportion, Proportion: OverallProportion,
}, },
Critical: model.ConsumptionUnit{ Critical: model.ConsumptionUnit{
Amount: critical.Amount,
Fee: critical.Fee,
Price: summary.Critical.Price, Price: summary.Critical.Price,
Proportion: CriticalProportion, Proportion: CriticalProportion,
}, },
Peak: model.ConsumptionUnit{ Peak: model.ConsumptionUnit{
Price: summary.Overall.Price, Amount: peak.Amount,
Fee: peak.Fee,
Price: summary.Peak.Price,
Proportion: PeakProportion, Proportion: PeakProportion,
}, },
Flat: model.ConsumptionUnit{ Flat: model.ConsumptionUnit{
Price: summary.Overall.Price, Amount: flat.Amount,
Fee: flat.Fee,
Price: summary.Flat.Price,
Proportion: FlatProportion, Proportion: FlatProportion,
}, },
Valley: model.ConsumptionUnit{ Valley: model.ConsumptionUnit{
Price: summary.Overall.Price, Amount: valley.Amount,
Fee: valley.Fee,
Price: summary.Valley.Price,
Proportion: ValleyProportion, Proportion: ValleyProportion,
}, },
Loss: model.ConsumptionUnit{
Amount: lossAmount,
Fee: lossPooled,
Price: summary.AuthoizeLoss.Price,
Proportion: lossProportion,
},
BasicFee: basicPooled, BasicFee: basicPooled,
AdjustFee: adjustPooled, AdjustFee: adjustPooled,
LossPooled: lossPooled, LossPooled: lossPooled,
@ -450,9 +483,9 @@ func TenementChargeCalculate(tenements []calculate.PrimaryTenementStatistics,
Submeters: nil, Submeters: nil,
Poolings: nil, Poolings: nil,
} }
tc = append(tc, tenementCharge) tc = append(tc, tenementCharge)
} }
} }
//fmt.Println(len(tc))
return tc return tc
} }

View File

@ -20,6 +20,7 @@ func MainCalculateProcess(rid string) error {
return err return err
} }
fmt.Println(report, reportSummary)
summary := calculate.FromReportSummary(reportSummary, report) summary := calculate.FromReportSummary(reportSummary, report)
periodStart := report.Period.SafeLower() periodStart := report.Period.SafeLower()
@ -66,8 +67,8 @@ func MainCalculateProcess(rid string) error {
// 计算所有表计的总电量 // 计算所有表计的总电量
parkTotal := TotalConsumptionCalculate(tenementReports, summary) parkTotal := TotalConsumptionCalculate(tenementReports, summary)
// 计算线损以及调整线损 //计算线损以及调整线损
err = LossCalculate(report, &parkMetersReports, &parkTotal, &summary) err = LossCalculate(report, parkMetersReports, &parkTotal, &summary)
if err != nil { if err != nil {
fmt.Println("9", err) fmt.Println("9", err)
return err return err
@ -79,15 +80,13 @@ func MainCalculateProcess(rid string) error {
fmt.Println("10", err) fmt.Println("10", err)
return err return err
} }
// 计算基本电费分摊、调整电费分摊、电费摊薄单价。
err = CalculatePrices(&summary) err = CalculatePrices(&summary)
if err != nil { if err != nil {
fmt.Println("11", err) fmt.Println("11", err)
return err return err
} }
fmt.Println("计算数据读取完成=======================================================================================================================================================================================")
//===========================================================================
// 计算基本电费分摊、调整电费分摊、电费摊薄单价。
err = CalculatePrices(&summary)
// 收集目前所有已经处理的表计,统一对其进行摊薄计算。 // 收集目前所有已经处理的表计,统一对其进行摊薄计算。
meters, err := CollectMeters(tenementReports, poolingMetersReports, parkMetersReports) meters, err := CollectMeters(tenementReports, poolingMetersReports, parkMetersReports)
if err != nil { if err != nil {
@ -95,9 +94,6 @@ func MainCalculateProcess(rid string) error {
return err return err
} }
// 计算商户的合计电费信息,并归总与商户相关联的表计记录
tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
// 根据核算报表中设置的摊薄内容,逐个表计进行计算 // 根据核算报表中设置的摊薄内容,逐个表计进行计算
err = CalculateBasicPooling(report, &summary, &meters) err = CalculateBasicPooling(report, &summary, &meters)
if err != nil { if err != nil {
@ -115,7 +111,7 @@ func MainCalculateProcess(rid string) error {
return err return err
} }
// 计算所有商户类型表计的全周期电量,并根据全周期电量计算共用过同一表计的商户的二次分摊比例。 // 计算所有商户类型表计的全周期电量,并根据全周期电量计算共用过同一表计的商户的二次分摊比例。
_, err = CalculateTenementConsumptions(meters) _, err = CalculateTenementConsumptions(&meters)
if err != nil { if err != nil {
fmt.Println("16", err) fmt.Println("16", err)
return err return err
@ -126,7 +122,7 @@ func MainCalculateProcess(rid string) error {
return err return err
} }
// 计算商户的合计电费信息,并归总与商户相关联的表计记录 // 计算商户的合计电费信息,并归总与商户相关联的表计记录
tenementCharges = TenementChargeCalculate(tenementReports, summary, meters) tenementCharges := TenementChargeCalculate(tenementReports, summary, meters)
// 从此处开始向数据库保存全部计算结果。 // 从此处开始向数据库保存全部计算结果。
ctx, cancel := global.TimeoutContext() ctx, cancel := global.TimeoutContext()
@ -134,35 +130,36 @@ func MainCalculateProcess(rid string) error {
tx, _ := global.DB.Begin(ctx) tx, _ := global.DB.Begin(ctx)
err = repository.CalculateRepository.ClearReportContent(tx, report.Id) err = repository.CalculateRepository.ClearReportContent(tx, report.Id)
if err != nil { if err != nil {
tx.Rollback(ctx) _ = tx.Rollback(ctx)
fmt.Println("18", err) fmt.Println("18", err)
return err return err
} }
err = SaveSummary(tx, summary) err = SaveSummary(tx, ctx, summary)
if err != nil { if err != nil {
tx.Rollback(ctx) _ = tx.Rollback(ctx)
fmt.Println("19", err) fmt.Println("19", err)
return err return err
} }
err = SavePublics(tx, *report, meters) err = SavePublics(tx, ctx, *report, meters)
if err != nil { if err != nil {
tx.Rollback(ctx) _ = tx.Rollback(ctx)
fmt.Println("20", err) fmt.Println("20", err)
return err return err
} }
err = SavePoolings(tx, *report, meters, meterRelations) err = SavePoolings(tx, *report, meters, meterRelations)
if err != nil { if err != nil {
tx.Rollback(ctx) _ = tx.Rollback(ctx)
fmt.Println("21", err) fmt.Println("21", err)
return err return err
} }
err = SaveTenements(tx, *report, tenementReports, tenementCharges) err = SaveTenements(tx, *report, tenementReports, tenementCharges)
if err != nil { if err != nil {
tx.Rollback(ctx) _ = tx.Rollback(ctx)
fmt.Println("22", err) fmt.Println("22", err)
return err return err
} }
tx.Commit(ctx) fmt.Println("商户分摊关系保存成功")
_ = tx.Commit(ctx)
return nil return nil
} }

View File

@ -49,7 +49,7 @@ func (ms _MeterService) CreateMeterRecord(pid string, form *vo.MeterCreationForm
return err return err
} }
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, form.Code, form.MeterType, form.Ratio, &form.MeterReadingForm) ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, form.Code, form.MeterType, form.Ratio, &form.Reading)
if err != nil { if err != nil {
ms.log.Error("无法记录表计读数。", zap.Error(err)) ms.log.Error("无法记录表计读数。", zap.Error(err))
tx.Rollback(ctx) tx.Rollback(ctx)
@ -222,7 +222,7 @@ func (ms _MeterService) BatchImportMeters(pid string, file *multipart.FileHeader
Building: element.Building, Building: element.Building,
OnFloor: element.OnFloor, OnFloor: element.OnFloor,
Area: element.Area, Area: element.Area,
MeterReadingForm: vo.MeterReadingForm{ Reading: vo.MeterReadingForm{
ReadAt: &element.ReadAt, ReadAt: &element.ReadAt,
Overall: element.Overall, Overall: element.Overall,
Critical: element.Critical.Decimal, Critical: element.Critical.Decimal,
@ -257,7 +257,7 @@ func (ms _MeterService) BatchImportMeters(pid string, file *multipart.FileHeader
} }
// 步骤5将全部抄表信息保存进入数据库 // 步骤5将全部抄表信息保存进入数据库
for _, record := range meterCreationForms { for _, record := range meterCreationForms {
_, err := repository.MeterRepository.RecordReading(tx, ctx, pid, record.Code, record.MeterType, record.Ratio, &record.MeterReadingForm) _, err := repository.MeterRepository.RecordReading(tx, ctx, pid, record.Code, record.MeterType, record.Ratio, &record.Reading)
if err != nil { if err != nil {
ms.log.Error("无法在数据插入阶段保存抄表信息。", zap.String("meter code", record.Code), zap.Error(err)) ms.log.Error("无法在数据插入阶段保存抄表信息。", zap.String("meter code", record.Code), zap.Error(err))
tx.Rollback(ctx) tx.Rollback(ctx)
@ -363,16 +363,16 @@ func (ms _MeterService) ReplaceMeter(
// 步骤6将旧表计的部分信息赋予新表计 // 步骤6将旧表计的部分信息赋予新表计
newMeterCreationForm := vo.MeterCreationForm{ newMeterCreationForm := vo.MeterCreationForm{
Code: newMeterCode, Code: newMeterCode,
Address: oldMeter.Address, Address: oldMeter.Address,
MeterType: oldMeter.MeterType, MeterType: oldMeter.MeterType,
Ratio: newMeterRatio, Ratio: newMeterRatio,
Seq: oldMeter.Seq, Seq: oldMeter.Seq,
Enabled: oldMeter.Enabled, Enabled: oldMeter.Enabled,
Building: oldMeter.Building, Building: oldMeter.Building,
OnFloor: oldMeter.OnFloor, OnFloor: oldMeter.OnFloor,
Area: oldMeter.Area, Area: oldMeter.Area,
MeterReadingForm: *newMeterReading, Reading: *newMeterReading,
} }
// 步骤7将新表计写入系统 // 步骤7将新表计写入系统
@ -389,7 +389,7 @@ func (ms _MeterService) ReplaceMeter(
} }
// 步骤8将新表计的读数写入系统 // 步骤8将新表计的读数写入系统
ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, newMeterCode, newMeterCreationForm.MeterType, newMeterCreationForm.Ratio, &newMeterCreationForm.MeterReadingForm) ok, err = repository.MeterRepository.RecordReading(tx, ctx, pid, newMeterCode, newMeterCreationForm.MeterType, newMeterCreationForm.Ratio, &newMeterCreationForm.Reading)
switch { switch {
case err != nil: case err != nil:
ms.log.Error("无法将新表计的读数写入系统。", zap.Error(err)) ms.log.Error("无法将新表计的读数写入系统。", zap.Error(err))
@ -444,6 +444,118 @@ func (ms _MeterService) ReplaceMeter(
return nil return nil
} }
//func replaceMeter(
// pid string,
// oldMeterCode string,
// oldMeterReading *MeterReadingForm,
// newMeterCode string,
// newMeterRatio *big.Float,
// newMeterReading *MeterReadingForm,
//) (bool, error) {
// ctx := context.Background()
// tx, err := PostgresPool{}.begin(ctx)
// if err != nil {
// return false, err
// }
//
// // 步骤1获取旧表计的信息
// oldMeter, err := repositories{}.meter_fetch_meter_detail(pid, oldMeterCode)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
// if oldMeter == nil {
// tx.rollback(ctx)
// return false, fmt.Errorf("要替换的旧表计不存在")
// }
//
// // 步骤2将旧表计的读数写入读数表
// err = repositories{}.meter_record_reading(tx, pid, oldMeterCode, oldMeter.MeterType, oldMeter.Ratio, oldMeterReading)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
//
// // 步骤3: 将旧表计从系统中移除
// err = repositories{}.meter_detach_meter(tx, pid, oldMeterCode)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
//
// // 步骤4: 获取旧表计的关联信息
// var oldMeterAssociations []*MeterRelation
// if oldMeter.MeterType == Pooling {
// oldMeterAssociations, err = repositories{}.meter_list_pooled_meter_relations(pid, oldMeterCode)
// } else {
// oldMeterAssociations, err = repositories{}.meter_list_meter_relations(pid, oldMeterCode)
// }
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
//
// // 步骤5: 将旧表计的关联信息全部置为解除
// for _, relation := range oldMeterAssociations {
// err = repositories{}.meter_unbind_meter(tx, pid, relation.MasterMeter, relation.SlaveMeter)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
// }
//
// // 步骤6: 将旧表计的部分信息赋予新表计
// newMeterCreationForm := &MeterCreationForm{
// Code: newMeterCode,
// Address: oldMeter.Address,
// MeterType: oldMeter.MeterType,
// Ratio: newMeterRatio,
// Seq: oldMeter.Seq,
// // Assign other fields
// Reading: newMeterReading,
// }
//
// // 步骤7: 将新表计写入系统
// err = repositories{}.meter_create_meter(tx, pid, newMeterCreationForm)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
//
// // 步骤8: 将新表计的读数写入读数表
// err = repositories{}.meter_record_reading(tx, pid, newMeterCode, oldMeter.MeterType, newMeterRatio, newMeterReading)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
//
// // 步骤9: 将旧表计的关联信息复制一份并赋予新表计
// if oldMeter.MeterType == Pooling {
// for _, relation := range oldMeterAssociations {
// err = repositories{}.meter_bind_meter(tx, pid, newMeterCode, relation.SlaveMeter)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
// }
// } else {
// for _, relation := range oldMeterAssociations {
// err = repositories{}.meter_bind_meter(tx, pid, relation.MasterMeter, newMeterCode)
// if err != nil {
// tx.rollback(ctx)
// return false, err
// }
// }
// }
//
// err = tx.commit(ctx)
// if err != nil {
// return false, err
// }
//
// return true, nil
//}
// 列出园区中指定公摊表计下的所有关联表计 // 列出园区中指定公摊表计下的所有关联表计
func (ms _MeterService) ListPooledMeterRelations(pid, masterMeter string) ([]*model.MeterDetail, error) { func (ms _MeterService) ListPooledMeterRelations(pid, masterMeter string) ([]*model.MeterDetail, error) {
ms.log.Info("列出园区中指定公摊表计下的所有关联表计", zap.String("park id", pid), zap.String("meter code", masterMeter)) ms.log.Info("列出园区中指定公摊表计下的所有关联表计", zap.String("park id", pid), zap.String("meter code", masterMeter))
@ -587,7 +699,7 @@ func (ms _MeterService) UnbindMeter(pid, masterMeter string, slaveMeters []strin
} }
// 查询符合条件的表计读数记录 // 查询符合条件的表计读数记录
func (ms _MeterService) SearchMeterReadings(pid string, building *string, start, end *types.Date, page uint, keyword *string) ([]*model.DetailedMeterReading, int64, error) { func (ms _MeterService) SearchMeterReadings(pid string, building *string, start, end *types.Date, page uint, keyword *string, mtype uint) ([]*model.DetailedMeterReading, int64, error) {
ms.log.Info( ms.log.Info(
"查询符合条件的表计读数记录", "查询符合条件的表计读数记录",
zap.String("park id", pid), zap.String("park id", pid),
@ -597,7 +709,7 @@ func (ms _MeterService) SearchMeterReadings(pid string, building *string, start,
zap.Uint("page", page), zap.Uint("page", page),
zap.Stringp("keyword", keyword), zap.Stringp("keyword", keyword),
) )
readings, total, err := repository.MeterRepository.ListMeterReadings(pid, keyword, page, start, end, building) readings, total, err := repository.MeterRepository.ListMeterReadings(pid, keyword, page, start, end, building, mtype)
if err != nil { if err != nil {
ms.log.Error("无法查询符合条件的表计读数记录。", zap.Error(err)) ms.log.Error("无法查询符合条件的表计读数记录。", zap.Error(err))
return make([]*model.DetailedMeterReading, 0), 0, err return make([]*model.DetailedMeterReading, 0), 0, err
@ -777,3 +889,10 @@ func (ms _MeterService) BatchImportReadings(pid string, file *multipart.FileHead
} }
return make([]excel.ExcelAnalysisError, 0), nil return make([]excel.ExcelAnalysisError, 0), nil
} }
//// 更换系统中的表计
//func (ms _MeterService) ReplaceMeter(pid string, oldMeterCode string, oldMeterReading vo.MeterReadingForm,
// newMeterCode string, newMeterRatio decimal.Decimal, newMeterDisplayRatio decimal.Decimal,
// newMeterReading vo.NewMeterForReplacingForm) {
//
//}

View File

@ -9,6 +9,7 @@ import (
"electricity_bill_calc/types" "electricity_bill_calc/types"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"github.com/pkg/errors" "github.com/pkg/errors"
"log"
"sync" "sync"
"github.com/doug-martin/goqu/v9" "github.com/doug-martin/goqu/v9"
@ -209,30 +210,35 @@ func (rs _ReportService) ReportCalcuateDispatch(rid string) error {
return nil return nil
} }
//创建一个新的核算报表,并同时完成核算报表的计算 // 创建一个新的核算报表,并同时完成核算报表的计算
func (rs _ReportService) CreateNewReport(createFrom *vo.ReportCreationForm) (bool, error) { func (rs _ReportService) CreateNewReport(createFrom *vo.ReportCreationForm) (bool, error) {
state, report, err := repository.ReportRepository.CreateReport(createFrom) state, report, err := repository.ReportRepository.CreateReport(createFrom)
if err != nil { if err != nil {
rs.log.Error("创建核算报表错误", zap.Error(err)) rs.log.Error("创建核算报表错误", zap.Error(err))
return false, err return false, err
} }
if !state { if !state {
status, err := repository.CalculateRepository.UpdateReportCalculateStatus(report, "InsufficientData", "创建报表时发生错误,需手动再次计算") status, err := repository.CalculateRepository.UpdateReportCalculateStatus(report, "InsufficientData",
"创建报表时发生错误,需手动再次计算")
if err != nil { if err != nil {
rs.log.Error("创建报表时发生错误,需手动再次计算", zap.Error(err)) rs.log.Error("创建报表时发生错误,需手动再次计算", zap.Error(err))
return false, err return false, err
} }
return status, nil return status, nil
} }
err = rs.CalculateReport(report) err = rs.CalculateReport(report)
if err != nil { if err != nil {
rs.log.Error("计算时出错", zap.Error(err)) rs.log.Error("计算时出错", zap.Error(err))
return false, err return false, err
} }
return true, nil return true, nil
} }
//更新一个核算报表中的数据,并同时完成计算 // 更新一个核算报表中的数据,并同时完成计算
func (rs _ReportService) UpdateRepoet(rid string, updateForm *vo.ReportModifyForm) (bool, error) { func (rs _ReportService) UpdateRepoet(rid string, updateForm *vo.ReportModifyForm) (bool, error) {
state, err := repository.ReportRepository.UpdateReportSummary(rid, updateForm) state, err := repository.ReportRepository.UpdateReportSummary(rid, updateForm)
if err != nil { if err != nil {
@ -258,10 +264,10 @@ var CALCULATE_TASK_PARALLEL_CONTROL = func() *sync.Mutex {
// 执行一个核算报表的计算任务 // 执行一个核算报表的计算任务
func (rs _ReportService) CalculateReport(rid string) error { func (rs _ReportService) CalculateReport(rid string) error {
semaphore := CALCULATE_TASK_PARALLEL_CONTROL //semaphore := CALCULATE_TASK_PARALLEL_CONTROL
//
semaphore.Lock() //semaphore.Lock()
defer semaphore.Unlock() //defer semaphore.Unlock()
errs := calculate.MainCalculateProcess(rid) errs := calculate.MainCalculateProcess(rid)

View File

@ -7,7 +7,6 @@ import (
"electricity_bill_calc/repository" "electricity_bill_calc/repository"
"electricity_bill_calc/vo" "electricity_bill_calc/vo"
"fmt" "fmt"
"github.com/samber/lo" "github.com/samber/lo"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -82,7 +81,7 @@ func (ts _TenementService) BindMeter(pid, tid, meterCode string, reading *vo.Met
tx.Rollback(ctx) tx.Rollback(ctx)
return fmt.Errorf("未能获取表计详细信息,%w", err) return fmt.Errorf("未能获取表计详细信息,%w", err)
} }
err = repository.TenementRepository.BindMeter(tx, ctx, pid, tid, meterCode) err = repository.TenementRepository.BindMeter(tx, ctx, pid, tid, meterCode, reading)
if err != nil { if err != nil {
ts.log.Error("向商户绑定一个新表计失败,未能绑定表计", zap.Error(err)) ts.log.Error("向商户绑定一个新表计失败,未能绑定表计", zap.Error(err))
tx.Rollback(ctx) tx.Rollback(ctx)
@ -201,7 +200,7 @@ func (ts _TenementService) MoveOutTenement(pid, tid string, reading []*vo.MeterR
tx.Rollback(ctx) tx.Rollback(ctx)
return fmt.Errorf("找不到指定表计[%s]的抄表信息,%w", meterCode, err) return fmt.Errorf("找不到指定表计[%s]的抄表信息,%w", meterCode, err)
} }
if reading.Validate() { if !reading.Validate() {
ts.log.Error("迁出指定商户失败,表计读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", zap.String("Meter", meterCode)) ts.log.Error("迁出指定商户失败,表计读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", zap.String("Meter", meterCode))
tx.Rollback(ctx) tx.Rollback(ctx)
return fmt.Errorf("表计[%s]读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", meterCode) return fmt.Errorf("表计[%s]读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。", meterCode)

View File

@ -1,22 +1,24 @@
package vo package vo
import ( import (
"electricity_bill_calc/model"
"electricity_bill_calc/types" "electricity_bill_calc/types"
"time"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
) )
type MeterCreationForm struct { type MeterCreationForm struct {
Code string `json:"code"` Code string `json:"code"`
Address *string `json:"address"` Address *string `json:"address"`
Ratio decimal.Decimal `json:"ratio"` Ratio decimal.Decimal `json:"ratio"`
Seq int64 `json:"seq"` Seq int64 `json:"seq"`
MeterType int16 `json:"type"` MeterType int16 `json:"type"`
Building *string `json:"building"` Building *string `json:"building"`
OnFloor *string `json:"onFloor"` OnFloor *string `json:"onFloor"`
Area decimal.NullDecimal `json:"area"` Area decimal.NullDecimal `json:"area"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
MeterReadingForm `json:"-"` Reading MeterReadingForm `json:"reading"`
} }
type MeterModificationForm struct { type MeterModificationForm struct {
@ -59,7 +61,7 @@ type SimplifiedMeterDetailResponse struct {
Area decimal.Decimal `json:"area"` Area decimal.Decimal `json:"area"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
MeterType int16 `json:"type"` MeterType int16 `json:"type"`
AttachedAt types.DateTime `json:"attachedAt"` AttachedAt *types.DateTime `json:"attachedAt"`
DetachedAt *types.DateTime `json:"detachedAt"` DetachedAt *types.DateTime `json:"detachedAt"`
} }
type ReadableMeterQueryResponse struct { type ReadableMeterQueryResponse struct {
@ -67,3 +69,54 @@ type ReadableMeterQueryResponse struct {
Address *string `json:"address"` Address *string `json:"address"`
Park string `json:"park"` Park string `json:"park"`
} }
type ReportPublishResponse struct {
//ID string
ReportID string `json:"report_id" db:"report_id"` // 报告ID
ParkMeterID string `json:"park_meter_id" db:"park_meter_id"` // 停车计费ID
Overall model.ConsumptionUnit `json:"overall" db:"overall"` // 总体信息
Critical model.ConsumptionUnit `json:"critical" db:"critical"` // 关键信息
Peak model.ConsumptionUnit `json:"peak" db:"peak"` // 高峰信息
Flat model.ConsumptionUnit `json:"flat" db:"flat"` // 平峰信息
Valley model.ConsumptionUnit `json:"valley" db:"valley"` // 谷峰信息
LossAdjust model.ConsumptionUnit `json:"loss_adjust" db:"loss_adjust"` // 损耗调整信息
ConsumptionTotal float64 `json:"consumption_total" db:"consumption_total"` // 总消费量
LossAdjustTotal float64 `json:"loss_adjust_total" db:"loss_adjust_total"` // 总损耗调整
FinalTotal float64 `json:"final_total" db:"final_total"` // 最终总量
CreatedAt time.Time `json:"created_at" db:"created_at"` // 创建时间
LastModifiedAt time.Time `json:"last_modified_at" db:"last_modified_at"` // 最后修改时间
Code string `json:"code" db:"code"` // 代码
ParkID string `json:"park_id" db:"park_id"` // 停车场ID
Address *string `json:"address" db:"address"` // 地址
Ratio decimal.Decimal `json:"ratio" db:"ratio"` // 比率
Seq int64 `json:"seq" db:"seq"` // 序列号
Enabled bool `json:"enabled" db:"enabled"` // 是否启用
MeterType int16 `json:"meter_type" db:"meter_type"` // 计量类型
Building *string `json:"building" db:"building"` // 建筑物
OnFloor *string `json:"on_floor" db:"on_floor"` // 楼层
Area decimal.NullDecimal `json:"area" db:"area"` // 面积
AttachedAt *types.DateTime `json:"attached_at" db:"attached_at"` // 附加时间
DetachedAt *types.DateTime `json:"detached_at" db:"detached_at"` // 分离时间
DisplayRatio float64 `json:"display_ratio" db:"display_ratio"` // 显示比例
BuildingName *string `json:"building_name" db:"building_name"` // 建筑物名称
PublicPooled int16 `json:"public_pooled" db:"public_pooled"` // 公共汇总
}
type Public struct {
Address *string `json:"address"` // 户址
AdjustLoss model.ConsumptionUnit `json:"adjustLoss"` // 调整线损数据,仅运维可见,仅使用其中`amount`内容
Area string `json:"area"` // 所辖面积
AttachedAt *types.DateTime `json:"attachedAt"` // 接入系统时间,挂表
Building *string `json:"building"` // 所在建筑ID
BuildingName *string `json:"buildingName"` // 所在建筑名称
Code string `json:"code"` // 表计表号
DetachedAt *types.DateTime `json:"detachedAt"` // 从系统移除时间,拆表
DisplayRatio string `json:"displayRatio"` // 表计表显倍率,仅用于展示。
Enabled bool `json:"enabled"` // 是否可用
OnFloor *string `json:"onFloor"` // 所在楼层
Overall model.ConsumptionUnit `json:"overall"` // 总电量部分
ParkID string `json:"parkId"` // 所属园区ID
Ratio string `json:"ratio"` // 表计计算倍率,参与表计读数计算。
Seq int64 `json:"seq"` // 抄表序号
Type float64 `json:"type"` // 表计类型0商户电表1园区电表2公摊电表
}

View File

@ -4,7 +4,6 @@ import (
"electricity_bill_calc/model" "electricity_bill_calc/model"
"electricity_bill_calc/types" "electricity_bill_calc/types"
"fmt" "fmt"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
) )
@ -19,7 +18,8 @@ type MeterReadingForm struct {
func (r MeterReadingForm) Validate() bool { func (r MeterReadingForm) Validate() bool {
flat := r.Overall.Sub(r.Critical).Sub(r.Peak).Sub(r.Valley) flat := r.Overall.Sub(r.Critical).Sub(r.Peak).Sub(r.Valley)
return flat.GreaterThanOrEqual(decimal.Zero) b := flat.GreaterThanOrEqual(decimal.Zero)
return b
} }
type MeterReadingFormWithCode struct { type MeterReadingFormWithCode struct {

View File

@ -18,6 +18,7 @@ type TenementCreationForm struct {
InvoicePhone *string `json:"invoicePhone"` InvoicePhone *string `json:"invoicePhone"`
Bank *string `json:"bank"` Bank *string `json:"bank"`
Account *string `json:"bankAccount"` Account *string `json:"bankAccount"`
MoveIn *string `json:"moveIn"`
} }
type TenementQueryResponse struct { type TenementQueryResponse struct {

View File

@ -22,4 +22,5 @@ type TopUpDetailQueryResponse struct {
Amount decimal.Decimal `json:"amount"` Amount decimal.Decimal `json:"amount"`
PaymentType int16 `json:"paymentType"` PaymentType int16 `json:"paymentType"`
SyncStatus int16 `json:"syncStatus" copier:"SyncStatus"` SyncStatus int16 `json:"syncStatus" copier:"SyncStatus"`
CancelledAt *types.DateTime `json:"cancelledAt"` // TODO: 2023.08.11 在查询充值记录的时候发现缺少该字段(已添加)
} }