forked from free-lancers/electricity_bill_calc_service
		
	feat(report):基本完成报表查看部分内容的迁移。
This commit is contained in:
		
							
								
								
									
										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"` | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user