feat(report):基本完成报表查看部分内容的迁移。
This commit is contained in:
parent
fa03bf5dbd
commit
2792959d1e
424
controller/report.go
Normal file
424
controller/report.go
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/logger"
|
||||||
|
"electricity_bill_calc/model"
|
||||||
|
"electricity_bill_calc/repository"
|
||||||
|
"electricity_bill_calc/response"
|
||||||
|
"electricity_bill_calc/security"
|
||||||
|
"electricity_bill_calc/service"
|
||||||
|
"electricity_bill_calc/tools"
|
||||||
|
"electricity_bill_calc/types"
|
||||||
|
"electricity_bill_calc/vo"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var reportLog = logger.Named("Handler", "Report")
|
||||||
|
|
||||||
|
func InitializeReportHandlers(router *fiber.App) {
|
||||||
|
router.Get("/repotrs", security.MustAuthenticated, reportComprehensiveSearch)
|
||||||
|
router.Post("/report", security.EnterpriseAuthorize, initNewReportCalculateTask)
|
||||||
|
router.Get("/report/draft", security.EnterpriseAuthorize, listDraftReportIndicies)
|
||||||
|
router.Post("/report/calcualte", security.EnterpriseAuthorize, testCalculateReportSummary)
|
||||||
|
router.Get("/report/calculate/status", security.EnterpriseAuthorize, listCalculateTaskStatus)
|
||||||
|
router.Get("/report/:rid", security.EnterpriseAuthorize, getReportDetail)
|
||||||
|
router.Put("/report/:rid", security.EnterpriseAuthorize, updateReportCalculateTask)
|
||||||
|
router.Post("/report/:rid/publish", security.EnterpriseAuthorize, publishReport)
|
||||||
|
router.Put("/report/:rid/calculate", security.EnterpriseAuthorize, initiateCalculateTask)
|
||||||
|
router.Get("/report/:rid/publics", security.MustAuthenticated, listPublicMetersInReport)
|
||||||
|
router.Get("/report/:rid/summary", security.MustAuthenticated, getReportSummary)
|
||||||
|
router.Get("/report/:rid/summary/filled", security.EnterpriseAuthorize, getParkFilledSummary)
|
||||||
|
router.Get("/report/:rid/pooled", security.MustAuthenticated, listPooledMetersInReport)
|
||||||
|
router.Get("/report/:rid/:code/submeters", security.MustAuthenticated, listSubmetersInPooledMeter)
|
||||||
|
router.Get("/report/:rid/tenement", security.MustAuthenticated, listTenementsInReport)
|
||||||
|
router.Get("/report/:rid/tenement/:tid", security.MustAuthenticated, getTenementDetailInReport)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查指定报表是否属于当前用户
|
||||||
|
func checkReportBelongs(reportId string, log *zap.Logger, c *fiber.Ctx, result *response.Result) (bool, error) {
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||||
|
return false, result.Unauthorized("无法获取当前用户的会话信息。")
|
||||||
|
}
|
||||||
|
ok, err := repository.ReportRepository.IsBelongsTo(reportId, session.Uid)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("无法检查核算报表的所有权", zap.Error(err))
|
||||||
|
return false, result.Error(fiber.StatusInternalServerError, "无法检查核算报表的所有权。")
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
log.Error("核算报表不属于当前用户")
|
||||||
|
return false, result.Forbidden("核算报表不属于当前用户。")
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前登录用户下所有园区的尚未发布的核算报表索引
|
||||||
|
func listDraftReportIndicies(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||||
|
return result.Unauthorized("无法获取当前用户的会话信息。")
|
||||||
|
}
|
||||||
|
reportLog.Info("检索指定用户下的未发布核算报表索引", zap.String("User", session.Uid))
|
||||||
|
indicies, err := service.ReportService.ListDraftReportIndicies(session.Uid)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取当前用户的核算报表索引", zap.Error(err))
|
||||||
|
return result.NotFound("当前用户下未找到核算报表索引。")
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定用户的报表索引。",
|
||||||
|
fiber.Map{"reports": indicies},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化一个新的核算任务
|
||||||
|
func initNewReportCalculateTask(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||||
|
return result.Unauthorized("无法获取当前用户的会话信息。")
|
||||||
|
}
|
||||||
|
reportLog.Info("初始化指定用户的一个新核算任务", zap.String("User", session.Uid))
|
||||||
|
var form vo.ReportCreationForm
|
||||||
|
if err := c.BodyParser(&form); err != nil {
|
||||||
|
reportLog.Error("无法解析创建核算报表的请求数据。", zap.Error(err))
|
||||||
|
return result.BadRequest("无法解析创建核算报表的请求数据。")
|
||||||
|
}
|
||||||
|
if pass, err := checkParkBelongs(form.Park, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ok, err := repository.ReportRepository.CreateReport(&form)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法创建核算报表", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法创建核算报表。")
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
reportLog.Error("未能完成核算报表的保存。")
|
||||||
|
return result.NotAccept("未能完成核算报表的保存。")
|
||||||
|
}
|
||||||
|
return result.Success("已经成功创建核算报表。")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新指定的核算任务
|
||||||
|
func updateReportCalculateTask(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
if pass, err := checkReportBelongs(reportId, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var form vo.ReportModifyForm
|
||||||
|
if err := c.BodyParser(&form); err != nil {
|
||||||
|
reportLog.Error("无法解析更新核算报表的请求数据。", zap.Error(err))
|
||||||
|
return result.BadRequest("无法解析更新核算报表的请求数据。")
|
||||||
|
}
|
||||||
|
ok, err := repository.ReportRepository.UpdateReportSummary(reportId, &form)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法更新核算报表", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法更新核算报表。")
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
reportLog.Error("未能完成核算报表的更新。")
|
||||||
|
return result.NotAccept("未能完成核算报表的更新。")
|
||||||
|
}
|
||||||
|
return result.Success("已经成功更新核算报表。")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动指定的核算任务
|
||||||
|
func initiateCalculateTask(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
if pass, err := checkReportBelongs(reportId, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := service.ReportService.DispatchReportCalculate(reportId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法启动核算报表计算任务", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法启动核算报表计算任务。")
|
||||||
|
}
|
||||||
|
return result.Success("已经成功启动核算报表计算任务。")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取自己园区的已经填写的园区电量信息
|
||||||
|
func getParkFilledSummary(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
if pass, err := checkReportBelongs(reportId, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
reportLog.Info("获取园区电量信息", zap.String("Report", reportId))
|
||||||
|
summary, err := repository.ReportRepository.RetrieveReportSummary(reportId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表的园区电量信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表的园区电量信息。")
|
||||||
|
}
|
||||||
|
if summary == nil {
|
||||||
|
reportLog.Error("未找到核算报表的园区电量信息")
|
||||||
|
return result.NotFound("未找到核算报表的园区电量信息。")
|
||||||
|
}
|
||||||
|
var summaryResponse vo.SimplifiedReportSummary
|
||||||
|
copier.Copy(&summaryResponse, summary)
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到核算报表的园区电量信息。",
|
||||||
|
fiber.Map{"summary": summaryResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对提供的园区电量信息进行试计算,返回试计算结果
|
||||||
|
func testCalculateReportSummary(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportLog.Info("试计算园区电量信息")
|
||||||
|
var form vo.TestCalculateForm
|
||||||
|
if err := c.BodyParser(&form); err != nil {
|
||||||
|
reportLog.Error("无法解析试计算核算报表的请求数据。", zap.Error(err))
|
||||||
|
return result.BadRequest("无法解析试计算核算报表的请求数据。")
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"电量电费试计算已经完成。",
|
||||||
|
fiber.Map{"summary": form.Calculate()},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定园区中尚未发布的核算报表计算状态
|
||||||
|
func listCalculateTaskStatus(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||||
|
return result.Unauthorized("无法获取当前用户的会话信息。")
|
||||||
|
}
|
||||||
|
status, err := repository.ReportRepository.GetReportTaskStatus(session.Uid)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表计算状态", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表计算状态。")
|
||||||
|
}
|
||||||
|
var statusResponse []*vo.ReportCalculateTaskStatusResponse
|
||||||
|
copier.Copy(&statusResponse, &status)
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到核算报表计算状态。",
|
||||||
|
fiber.Map{"status": statusResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定报表的详细信息
|
||||||
|
func getReportDetail(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
reportLog.Info("获取核算报表的详细信息", zap.String("Report", reportId))
|
||||||
|
user, park, report, err := service.ReportService.RetrieveReportIndexDetail(reportId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表的详细信息", zap.Error(err))
|
||||||
|
return result.NotFound("无法获取核算报表的详细信息。")
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到核算报表的详细信息。",
|
||||||
|
fiber.Map{
|
||||||
|
"detail": vo.NewReportDetailQueryResponse(user, park, report),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定核算报表的总览信息
|
||||||
|
func getReportSummary(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
report, err := repository.ReportRepository.RetrieveReportSummary(reportId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表的总览信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表的总览信息。")
|
||||||
|
}
|
||||||
|
if report == nil {
|
||||||
|
reportLog.Error("未找到核算报表的总览信息")
|
||||||
|
return result.NotFound("未找到核算报表的总览信息。")
|
||||||
|
}
|
||||||
|
var summaryResponse vo.ParkSummaryResponse
|
||||||
|
copier.Copy(&summaryResponse, report)
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到核算报表的总览信息。",
|
||||||
|
fiber.Map{"summary": summaryResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定报表中分页的公共表计的核算摘要信息
|
||||||
|
func listPublicMetersInReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
reportLog.Info("获取核算报表中的公共表计信息", zap.String("Report", reportId))
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
keyword := tools.EmptyToNil(c.Query("keyword"))
|
||||||
|
meters, total, err := repository.ReportRepository.ListPublicMetersInReport(reportId, uint(page), keyword)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表中的公共表计信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公共表计信息。")
|
||||||
|
}
|
||||||
|
meterResponse := lo.Map(meters, func(meter *model.ReportDetailedPublicConsumption, _ int) *vo.ReportPublicQueryResponse {
|
||||||
|
m := &vo.ReportPublicQueryResponse{}
|
||||||
|
m.FromReportDetailPublicConsumption(meter)
|
||||||
|
return m
|
||||||
|
})
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表中的分页公共表计的核算信息。",
|
||||||
|
response.NewPagedResponse(page, total).ToMap(),
|
||||||
|
fiber.Map{"public": meterResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定报表中的分页的公摊表计的核算摘要信息
|
||||||
|
func listPooledMetersInReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
reportLog.Info("获取核算报表中的公摊表计信息", zap.String("Report", reportId))
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
keyword := tools.EmptyToNil(c.Query("keyword"))
|
||||||
|
meters, total, err := repository.ReportRepository.ListPooledMetersInReport(reportId, uint(page), keyword)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表中的公摊表计信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公摊表计信息。")
|
||||||
|
}
|
||||||
|
meterResponse := lo.Map(meters, func(meter *model.ReportDetailedPooledConsumption, _ int) *vo.ReportPooledQueryResponse {
|
||||||
|
m := &vo.ReportPooledQueryResponse{}
|
||||||
|
m.FromReportDetailPooledConsumption(meter)
|
||||||
|
return m
|
||||||
|
})
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表中的分页公摊表计的核算信息。",
|
||||||
|
response.NewPagedResponse(page, total).ToMap(),
|
||||||
|
fiber.Map{"pooled": meterResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列出指定报表中指定公共表计下各个分摊表计的消耗数据
|
||||||
|
func listSubmetersInPooledMeter(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
meterId := c.Params("code")
|
||||||
|
if len(meterId) == 0 {
|
||||||
|
reportLog.Error("未提供公共表计的编号")
|
||||||
|
return result.BadRequest("未提供公共表计的编号。")
|
||||||
|
}
|
||||||
|
meters, err := repository.ReportRepository.ListPooledMeterDetailInReport(reportId, meterId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表中的公共表计信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的公共表计信息。")
|
||||||
|
}
|
||||||
|
meterResponse := lo.Map(meters, func(meter *model.ReportDetailNestedMeterConsumption, _ int) *vo.ReportPooledQueryResponse {
|
||||||
|
m := &vo.ReportPooledQueryResponse{}
|
||||||
|
m.FromReportDetailNestedMeterConsumption(meter)
|
||||||
|
return m
|
||||||
|
})
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表中的公共表计的核算信息。",
|
||||||
|
fiber.Map{"meters": meterResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定报表中分页的商户核算电量电费概要数据
|
||||||
|
func listTenementsInReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
keyword := tools.EmptyToNil(c.Query("keyword"))
|
||||||
|
tenements, total, err := repository.ReportRepository.ListTenementInReport(reportId, uint(page), keyword)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表中的商户信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的商户信息。")
|
||||||
|
}
|
||||||
|
tenementsResponse := lo.Map(tenements, func(tenement *model.ReportTenement, _ int) *vo.ReportTenementSummaryResponse {
|
||||||
|
t := &vo.ReportTenementSummaryResponse{}
|
||||||
|
t.FromReportTenement(tenement)
|
||||||
|
return t
|
||||||
|
})
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表中的分页商户的核算信息。",
|
||||||
|
response.NewPagedResponse(page, total).ToMap(),
|
||||||
|
fiber.Map{"tenements": tenementsResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取指定报表中指定商户的详细核算信息
|
||||||
|
func getTenementDetailInReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
tenementId := c.Params("tid")
|
||||||
|
detail, err := repository.ReportRepository.GetTenementDetailInReport(reportId, tenementId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取核算报表中的商户信息", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法获取核算报表中的商户信息。")
|
||||||
|
}
|
||||||
|
var detailResponse vo.ReportTenementDetailResponse
|
||||||
|
detailResponse.FromReportTenement(detail)
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表中的商户的详细核算信息。",
|
||||||
|
fiber.Map{"detail": detailResponse},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布指定的核算报表
|
||||||
|
func publishReport(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
reportId := c.Params("rid")
|
||||||
|
if pass, err := checkReportBelongs(reportId, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ok, err := repository.ReportRepository.PublishReport(reportId)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法发布核算报表", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "发布核算报表出错。")
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
reportLog.Error("未能完成核算报表的发布。")
|
||||||
|
return result.NotAccept("未能完成核算报表的发布。")
|
||||||
|
}
|
||||||
|
return result.Success("已经成功发布核算报表。")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对核算报表进行综合检索
|
||||||
|
func reportComprehensiveSearch(c *fiber.Ctx) error {
|
||||||
|
result := response.NewResult(c)
|
||||||
|
user := tools.EmptyToNil(c.Query("user"))
|
||||||
|
session, err := _retreiveSession(c)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法获取当前用户的会话信息", zap.Error(err))
|
||||||
|
return result.Unauthorized("无法获取当前用户的会话信息。")
|
||||||
|
}
|
||||||
|
park := tools.EmptyToNil(c.Query("park_id"))
|
||||||
|
if session.Type == model.USER_TYPE_ENT && park != nil && len(*park) > 0 {
|
||||||
|
if pass, err := checkParkBelongs(*park, reportLog, c, &result); !pass {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var requestUser *string
|
||||||
|
if session.Type == model.USER_TYPE_ENT {
|
||||||
|
requestUser = lo.ToPtr(tools.DefaultTo(user, session.Uid))
|
||||||
|
} else {
|
||||||
|
requestUser = user
|
||||||
|
}
|
||||||
|
page := c.QueryInt("page", 1)
|
||||||
|
keyword := tools.EmptyToNil(c.Query("keyword"))
|
||||||
|
startDate, err := types.ParseDatep(c.Query("period_start"))
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法解析核算报表查询的开始日期", zap.Error(err))
|
||||||
|
return result.BadRequest("无法解析核算报表查询的开始日期。")
|
||||||
|
}
|
||||||
|
endDate, err := types.ParseDatep(c.Query("period_end"))
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法解析核算报表查询的结束日期", zap.Error(err))
|
||||||
|
return result.BadRequest("无法解析核算报表查询的结束日期。")
|
||||||
|
}
|
||||||
|
reports, total, err := service.ReportService.QueryReports(requestUser, park, uint(page), keyword, startDate, endDate)
|
||||||
|
if err != nil {
|
||||||
|
reportLog.Error("无法查询核算报表", zap.Error(err))
|
||||||
|
return result.Error(fiber.StatusInternalServerError, "无法查询核算报表。")
|
||||||
|
}
|
||||||
|
return result.Success(
|
||||||
|
"已经获取到指定核算报表的分页信息。",
|
||||||
|
response.NewPagedResponse(page, total).ToMap(),
|
||||||
|
fiber.Map{"reports": reports},
|
||||||
|
)
|
||||||
|
}
|
|
@ -52,6 +52,13 @@ type ReportSummary struct {
|
||||||
FinalDilutedOverall decimal.NullDecimal `json:"finalDilutedOverall" db:"final_diluted_overall"`
|
FinalDilutedOverall decimal.NullDecimal `json:"finalDilutedOverall" db:"final_diluted_overall"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rs ReportSummary) GetConsumptionFee() decimal.Decimal {
|
||||||
|
if !rs.ConsumptionFee.Valid {
|
||||||
|
return rs.Overall.Fee.Sub(rs.BasicFee).Sub(rs.AdjustFee)
|
||||||
|
}
|
||||||
|
return rs.ConsumptionFee.Decimal
|
||||||
|
}
|
||||||
|
|
||||||
type ReportPublicConsumption struct {
|
type ReportPublicConsumption struct {
|
||||||
ReportId string `json:"reportId" db:"report_id"`
|
ReportId string `json:"reportId" db:"report_id"`
|
||||||
MeterId string `json:"parkMeterId" db:"park_meter_id"`
|
MeterId string `json:"parkMeterId" db:"park_meter_id"`
|
||||||
|
|
|
@ -51,6 +51,7 @@ func App() *fiber.App {
|
||||||
controller.InitializeMeterHandlers(app)
|
controller.InitializeMeterHandlers(app)
|
||||||
controller.InitializeInvoiceHandler(app)
|
controller.InitializeInvoiceHandler(app)
|
||||||
controller.InitializeTopUpHandlers(app)
|
controller.InitializeTopUpHandlers(app)
|
||||||
|
controller.InitializeReportHandlers(app)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
22
vo/meter.go
22
vo/meter.go
|
@ -1,6 +1,10 @@
|
||||||
package vo
|
package vo
|
||||||
|
|
||||||
import "github.com/shopspring/decimal"
|
import (
|
||||||
|
"electricity_bill_calc/types"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
type MeterCreationForm struct {
|
type MeterCreationForm struct {
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
|
@ -42,3 +46,19 @@ type SimplifiedMeterQueryResponse struct {
|
||||||
Address *string `json:"address"`
|
Address *string `json:"address"`
|
||||||
Park string `json:"parkId"`
|
Park string `json:"parkId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SimplifiedMeterDetailResponse struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Park string `json:"parkId"`
|
||||||
|
Address *string `json:"address"`
|
||||||
|
Seq int64 `json:"seq"`
|
||||||
|
Ratio decimal.Decimal `json:"ratio"`
|
||||||
|
Building *string `json:"building"`
|
||||||
|
BuildingName *string `json:"buildingName"`
|
||||||
|
OnFloor *string `json:"onFloor"`
|
||||||
|
Area decimal.Decimal `json:"area"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
MeterType int16 `json:"meterType"`
|
||||||
|
AttachedAt types.DateTime `json:"attachedAt"`
|
||||||
|
DetachedAt *types.DateTime `json:"detachedAt"`
|
||||||
|
}
|
||||||
|
|
247
vo/report.go
247
vo/report.go
|
@ -1,8 +1,10 @@
|
||||||
package vo
|
package vo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/types"
|
"electricity_bill_calc/types"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,3 +72,248 @@ type ComprehensiveReportQueryResponse struct {
|
||||||
Park SimplifiedParkDetail `json:"park"`
|
Park SimplifiedParkDetail `json:"park"`
|
||||||
User SimplifiedUserDetail `json:"user"`
|
User SimplifiedUserDetail `json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BasicReportIndexResponse struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Park string `json:"park_id"`
|
||||||
|
PeriodBegin types.Date `json:"period_begin"`
|
||||||
|
PeriodEnd types.Date `json:"period_end"`
|
||||||
|
Category int16 `json:"category"`
|
||||||
|
MeterType int16 `json:"meter04kvType"`
|
||||||
|
PricePolicy int16 `json:"pricePolicy"`
|
||||||
|
BasisPooled int16 `json:"basisDiluted"`
|
||||||
|
AdjustPooled int16 `json:"adjustDiluted"`
|
||||||
|
LossPooled int16 `json:"lossDiluted"`
|
||||||
|
PublicPooled int16 `json:"publicDiluted"`
|
||||||
|
Published bool `json:"published"`
|
||||||
|
PublishedAt *types.DateTime `json:"published_at"`
|
||||||
|
Withdraw int16 `json:"withdraw"`
|
||||||
|
LastWithdrawAppliedAt *types.DateTime `json:"last_withdraw_applied_at"`
|
||||||
|
LastWithdrawAuditAt *types.DateTime `json:"last_withdraw_audit_at"`
|
||||||
|
Status int16 `json:"status"`
|
||||||
|
Message *string `json:"message"`
|
||||||
|
CreatedAt types.DateTime `json:"created_at"`
|
||||||
|
LastModifiedAt types.DateTime `json:"last_modified_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bri *BasicReportIndexResponse) Period(p types.DateRange) {
|
||||||
|
bri.PeriodBegin = p.SafeLower()
|
||||||
|
bri.PeriodEnd = p.SafeUpper()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportDetailQueryResponse struct {
|
||||||
|
Enterprise SimplifiedUserDetail `json:"enterprise"`
|
||||||
|
Park SimplifiedParkDetail `json:"park"`
|
||||||
|
Report BasicReportIndexResponse `json:"report"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReportDetailQueryResponse(user *model.UserDetail, park *model.Park, report *model.ReportIndex) ReportDetailQueryResponse {
|
||||||
|
var response ReportDetailQueryResponse
|
||||||
|
copier.Copy(&response.Enterprise, user)
|
||||||
|
copier.Copy(&response.Park, park)
|
||||||
|
copier.Copy(&response.Report, report)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParkSummaryResponse struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Overall ConsumptionDisplay `json:"overall"`
|
||||||
|
Area decimal.Decimal `json:"area"`
|
||||||
|
BasicFee decimal.Decimal `json:"basicFee"`
|
||||||
|
PooledBasicFeeByAmount decimal.Decimal `json:"pooledBasicFeeByAmount"`
|
||||||
|
PooledBasicFeeByArea decimal.Decimal `json:"pooledBasicFeeByArea"`
|
||||||
|
AdjustFee decimal.Decimal `json:"adjustFee"`
|
||||||
|
PooledAdjustFeeByAmount decimal.Decimal `json:"pooledAdjustFeeByAmount"`
|
||||||
|
PooledAdjustFeeByArea decimal.Decimal `json:"pooledAdjustFeeByArea"`
|
||||||
|
Consumption decimal.Decimal `json:"consumption"`
|
||||||
|
Loss decimal.Decimal `json:"loss"`
|
||||||
|
LossRate decimal.Decimal `json:"lossRate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SimplifiedReportSummary struct {
|
||||||
|
Overall model.ConsumptionUnit `json:"overall"`
|
||||||
|
Critical model.ConsumptionUnit `json:"critical"`
|
||||||
|
Peak model.ConsumptionUnit `json:"peak"`
|
||||||
|
Flat model.ConsumptionUnit `json:"flat"`
|
||||||
|
Valley model.ConsumptionUnit `json:"valley"`
|
||||||
|
BasicFee decimal.Decimal `json:"basicFee"`
|
||||||
|
AdjustFee decimal.Decimal `json:"adjustFee"`
|
||||||
|
ConsumptionFee decimal.Decimal `json:"consumptionFee" copier:"GetConsumptionFee"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestCalculateForm struct {
|
||||||
|
Overall decimal.Decimal `json:"overall"`
|
||||||
|
OverallFee decimal.Decimal `json:"overallFee"`
|
||||||
|
Critical decimal.Decimal `json:"critical"`
|
||||||
|
CriticalFee decimal.Decimal `json:"criticalFee"`
|
||||||
|
Peak decimal.Decimal `json:"peak"`
|
||||||
|
PeakFee decimal.Decimal `json:"peakFee"`
|
||||||
|
Valley decimal.Decimal `json:"valley"`
|
||||||
|
ValleyFee decimal.Decimal `json:"valleyFee"`
|
||||||
|
BasicFee decimal.Decimal `json:"basicFee"`
|
||||||
|
AdjustFee decimal.Decimal `json:"adjustFee"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestCalculateResult struct {
|
||||||
|
OverallPrice decimal.Decimal `json:"overallPrice"`
|
||||||
|
CriticalPrice decimal.Decimal `json:"criticalPrice"`
|
||||||
|
PeakPrice decimal.Decimal `json:"peakPrice"`
|
||||||
|
Flat decimal.Decimal `json:"flat"`
|
||||||
|
FlatFee decimal.Decimal `json:"flatFee"`
|
||||||
|
FlatPrice decimal.Decimal `json:"flatPrice"`
|
||||||
|
ValleyPrice decimal.Decimal `json:"valleyPrice"`
|
||||||
|
ConsumptionFee decimal.Decimal `json:"consumptionFee"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TestCalculateForm) Calculate() TestCalculateResult {
|
||||||
|
var r TestCalculateResult = TestCalculateResult{}
|
||||||
|
r.ConsumptionFee = t.OverallFee.Sub(t.BasicFee).Sub(t.AdjustFee)
|
||||||
|
if t.Overall.GreaterThan(decimal.Zero) {
|
||||||
|
r.OverallPrice = r.ConsumptionFee.Div(t.Overall).RoundBank(8)
|
||||||
|
}
|
||||||
|
if t.Critical.GreaterThan(decimal.Zero) {
|
||||||
|
r.CriticalPrice = t.CriticalFee.Div(t.Critical).RoundBank(8)
|
||||||
|
}
|
||||||
|
if t.Peak.GreaterThan(decimal.Zero) {
|
||||||
|
r.PeakPrice = t.PeakFee.Div(t.Peak).RoundBank(8)
|
||||||
|
}
|
||||||
|
r.Flat = t.Overall.Sub(t.Critical).Sub(t.Peak).Sub(t.Valley)
|
||||||
|
r.FlatFee = r.ConsumptionFee.Sub(t.CriticalFee).Sub(t.PeakFee).Sub(t.ValleyFee).RoundBank(8)
|
||||||
|
if r.Flat.GreaterThan(decimal.Zero) {
|
||||||
|
r.FlatPrice = r.FlatFee.Div(r.Flat).RoundBank(8)
|
||||||
|
}
|
||||||
|
r.ConsumptionFee = r.ConsumptionFee.RoundBank(8)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportCalculateTaskStatusResponse struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Status int16 `json:"status"`
|
||||||
|
Message *string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportPublicQueryResponse struct {
|
||||||
|
SimplifiedMeterQueryResponse
|
||||||
|
Overall ConsumptionDisplay `json:"overall"`
|
||||||
|
AdjustLoss ConsumptionDisplay `json:"adjustLoss"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rpqr *ReportPublicQueryResponse) FromReportDetailPublicConsumption(value *model.ReportDetailedPublicConsumption) {
|
||||||
|
copier.Copy(&rpqr.SimplifiedMeterQueryResponse, &value.MeterDetail)
|
||||||
|
rpqr.Overall = FromConsumptionUnit(&value.ReportPublicConsumption.Overall)
|
||||||
|
rpqr.Overall.Amount(value.ReportPublicConsumption.Overall.Amount.Add(value.ReportPublicConsumption.LossAdjust.Amount))
|
||||||
|
rpqr.AdjustLoss = FromConsumptionUnit(&value.ReportPublicConsumption.LossAdjust)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportPooledQueryResponse struct {
|
||||||
|
SimplifiedMeterQueryResponse
|
||||||
|
Overall ConsumptionDisplay `json:"overall"`
|
||||||
|
PoolMethod int16 `json:"poolMethod"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rpqr *ReportPooledQueryResponse) FromReportDetailPooledConsumption(value *model.ReportDetailedPooledConsumption) {
|
||||||
|
copier.Copy(&rpqr.SimplifiedMeterQueryResponse, &value.MeterDetail)
|
||||||
|
rpqr.Overall = FromConsumptionUnit(&value.ReportPooledConsumption.Overall)
|
||||||
|
rpqr.PoolMethod = value.PublicPooled
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rqpr *ReportPooledQueryResponse) FromReportDetailNestedMeterConsumption(value *model.ReportDetailNestedMeterConsumption) {
|
||||||
|
copier.Copy(&rqpr.SimplifiedMeterQueryResponse, &value.Meter)
|
||||||
|
rqpr.Overall = FromConsumptionUnit(&value.Consumption.Overall)
|
||||||
|
rqpr.PoolMethod = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportTenementSummaryResponse struct {
|
||||||
|
SimplifiedTenementDetailResponse
|
||||||
|
Consumption decimal.Decimal `json:"consumption"`
|
||||||
|
Fee decimal.Decimal `json:"fee"`
|
||||||
|
Pooled decimal.Decimal `json:"pooled"`
|
||||||
|
Total decimal.Decimal `json:"final"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtsr *ReportTenementSummaryResponse) FromReportTenement(value *model.ReportTenement) {
|
||||||
|
copier.Copy(&rtsr.SimplifiedTenementDetailResponse, &value.Detail)
|
||||||
|
fee := value.BasicFeePooled.Add(value.AdjustFeePooled).Add(value.LossFeePooled)
|
||||||
|
rtsr.Consumption = value.Overall.Amount
|
||||||
|
rtsr.Fee = fee
|
||||||
|
rtsr.Pooled = value.FinalPooled
|
||||||
|
rtsr.Total = value.FinalCharge
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportTenementComprehensiveDetailResponse struct {
|
||||||
|
Consumption decimal.Decimal `json:"consumption"`
|
||||||
|
Fee decimal.Decimal `json:"fee"`
|
||||||
|
Price decimal.Decimal `json:"price"`
|
||||||
|
BasicPooled decimal.Decimal `json:"basicPooled"`
|
||||||
|
AdjustPooled decimal.Decimal `json:"adjustPooled"`
|
||||||
|
LossPooled decimal.Decimal `json:"lossPooled"`
|
||||||
|
PublicPooled decimal.Decimal `json:"publicPooled"`
|
||||||
|
Total decimal.Decimal `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtcdr *ReportTenementComprehensiveDetailResponse) FromReportTenement(value *model.ReportTenement) {
|
||||||
|
rtcdr.Consumption = value.Overall.Amount
|
||||||
|
rtcdr.Fee = value.Overall.Fee
|
||||||
|
rtcdr.Price = value.Overall.Price
|
||||||
|
rtcdr.BasicPooled = value.BasicFeePooled
|
||||||
|
rtcdr.AdjustPooled = value.AdjustFeePooled
|
||||||
|
rtcdr.LossPooled = value.LossFeePooled
|
||||||
|
rtcdr.PublicPooled = value.FinalPooled
|
||||||
|
rtcdr.Total = value.FinalCharge
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportMeterDetailResponse struct {
|
||||||
|
SimplifiedMeterDetailResponse
|
||||||
|
Overall ConsumptionDisplay `json:"overall"`
|
||||||
|
Critical ConsumptionDisplay `json:"critical"`
|
||||||
|
Peak ConsumptionDisplay `json:"peak"`
|
||||||
|
Flat ConsumptionDisplay `json:"flat"`
|
||||||
|
Valley ConsumptionDisplay `json:"valley"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rmdr *ReportMeterDetailResponse) FromNestedMeter(value *model.NestedMeter) {
|
||||||
|
copier.Copy(&rmdr.SimplifiedMeterDetailResponse, &value.MeterDetail)
|
||||||
|
rmdr.Overall = FromConsumptionUnit(&value.Overall)
|
||||||
|
rmdr.Critical = FromConsumptionUnit(&value.Critical)
|
||||||
|
rmdr.Peak = FromConsumptionUnit(&value.Peak)
|
||||||
|
rmdr.Flat = FromConsumptionUnit(&value.Flat)
|
||||||
|
rmdr.Valley = FromConsumptionUnit(&value.Valley)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportMeterExtendedDetailResponse struct {
|
||||||
|
ReportMeterDetailResponse
|
||||||
|
BasicPooled decimal.Decimal `json:"basicPooled"`
|
||||||
|
AdjustPooled decimal.Decimal `json:"adjustPooled"`
|
||||||
|
LossPooled decimal.Decimal `json:"lossPooled"`
|
||||||
|
PublicPooled decimal.Decimal `json:"publicPooled"`
|
||||||
|
FinalTotal decimal.Decimal `json:"finalTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rmedr *ReportMeterExtendedDetailResponse) FromNestedMeter(value *model.NestedMeter) {
|
||||||
|
rmedr.ReportMeterDetailResponse.FromNestedMeter(value)
|
||||||
|
rmedr.BasicPooled = value.BasicPooled
|
||||||
|
rmedr.AdjustPooled = value.AdjustPooled
|
||||||
|
rmedr.LossPooled = value.LossPooled
|
||||||
|
rmedr.PublicPooled = value.PublicPooled
|
||||||
|
rmedr.FinalTotal = value.FinalTotal
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportTenementDetailResponse struct {
|
||||||
|
Tenement SimplifiedTenementDetailResponse `json:"tenement"`
|
||||||
|
Comprehensive ReportTenementComprehensiveDetailResponse `json:"comprehensive"`
|
||||||
|
Meters []ReportMeterExtendedDetailResponse `json:"meters"`
|
||||||
|
Pooled []ReportMeterDetailResponse `json:"pooled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rtdr *ReportTenementDetailResponse) FromReportTenement(value *model.ReportTenement) {
|
||||||
|
copier.Copy(&rtdr.Tenement, &value.Detail)
|
||||||
|
rtdr.Comprehensive.FromReportTenement(value)
|
||||||
|
rtdr.Meters = make([]ReportMeterExtendedDetailResponse, len(value.Meters))
|
||||||
|
for i, v := range value.Meters {
|
||||||
|
rtdr.Meters[i].FromNestedMeter(&v)
|
||||||
|
}
|
||||||
|
rtdr.Pooled = make([]ReportMeterDetailResponse, len(value.Pooled))
|
||||||
|
for i, v := range value.Pooled {
|
||||||
|
rtdr.Pooled[i].FromNestedMeter(&v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
40
vo/shares.go
40
vo/shares.go
|
@ -1,5 +1,45 @@
|
||||||
package vo
|
package vo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"electricity_bill_calc/model"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
type StateForm struct {
|
type StateForm struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ConsumptionDisplay struct {
|
||||||
|
AmountStr string `json:"amount"`
|
||||||
|
FeeStr string `json:"fee"`
|
||||||
|
PriceStr string `json:"price"`
|
||||||
|
ProportionStr string `json:"proportion"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd ConsumptionDisplay) Amount(a decimal.Decimal) ConsumptionDisplay {
|
||||||
|
cd.AmountStr = a.StringFixedBank(4)
|
||||||
|
return cd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd ConsumptionDisplay) Fee(f decimal.Decimal) ConsumptionDisplay {
|
||||||
|
cd.FeeStr = f.StringFixedBank(4)
|
||||||
|
return cd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd ConsumptionDisplay) Price(p decimal.Decimal) ConsumptionDisplay {
|
||||||
|
cd.PriceStr = p.StringFixedBank(8)
|
||||||
|
return cd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd ConsumptionDisplay) Proportion(p decimal.Decimal) ConsumptionDisplay {
|
||||||
|
cd.ProportionStr = p.StringFixedBank(8)
|
||||||
|
return cd
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromConsumptionUnit(cu *model.ConsumptionUnit) ConsumptionDisplay {
|
||||||
|
cd := &ConsumptionDisplay{}
|
||||||
|
copier.Copy(cd, cu)
|
||||||
|
return *cd
|
||||||
|
}
|
||||||
|
|
|
@ -59,3 +59,17 @@ type TenementDetailResponse struct {
|
||||||
CreatedAt types.DateTime `json:"createdAt"`
|
CreatedAt types.DateTime `json:"createdAt"`
|
||||||
LastModifiedAt *types.DateTime `json:"lastModifiedAt"`
|
LastModifiedAt *types.DateTime `json:"lastModifiedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SimplifiedTenementDetailResponse struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
FullName string `json:"fullName"`
|
||||||
|
ShortName *string `json:"shortName"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Contact string `json:"contact" copier:"ContactName"`
|
||||||
|
Phone string `json:"phone" copier:"ContactPhone"`
|
||||||
|
Building string `json:"building"`
|
||||||
|
BuildingName *string `json:"buildingName"`
|
||||||
|
OnFloor *string `json:"onFloor"`
|
||||||
|
MovedInAt *types.Date `json:"movedInAt"`
|
||||||
|
MovedOutAt *types.Date `json:"movedOutAt"`
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user