Переглянути джерело

Merge branch 'new_2.6'

# Conflicts:
#	controller/census/invoice_payment.go
ziwen 1 рік тому
батько
коміт
5ad7d67ee9

+ 1228 - 4
controller/census/invoice_payment.go

@@ -10,8 +10,10 @@ import (
 	"hongze/fms_api/global"
 	"hongze/fms_api/models"
 	"hongze/fms_api/models/base"
+	"hongze/fms_api/models/crm"
 	"hongze/fms_api/models/fms"
 	"hongze/fms_api/services/alarm_msg"
+	crmService "hongze/fms_api/services/crm"
 	fmsService "hongze/fms_api/services/fms"
 	"hongze/fms_api/utils"
 	"net/http"
@@ -413,7 +415,6 @@ func ExportInvoicePaymentCensusList(c *gin.Context, results *fms.InvoicePaymentC
 	}
 
 	newCompanyMap := map[int]string{0: "/", 1: "是", 2: "否"}
-	sellerTypeMap := map[int]string{1: "FICC销售", 2: "权益销售"}
 	for k, v := range list {
 		dataRow := sheet.AddRow()
 		// 前四个单元格根据每行开票到款条数向下合并
@@ -446,7 +447,7 @@ func ExportInvoicePaymentCensusList(c *gin.Context, results *fms.InvoicePaymentC
 				fms.ContractPaymentPayTypeNameMap[v2.PayType], // 付款方式
 				v2.SellerName,                                 // 销售
 				v2.SellerGroupName,                            // 组别
-				sellerTypeMap[v2.SellerType],                  // 销售类型
+				v2.SellerType,                                 // 销售类型
 			}
 			// 套餐金额信息
 			serviceTempShowAmount := make(map[int]string)
@@ -758,7 +759,16 @@ func (ct *InvoicePaymentController) List(c *gin.Context) {
 					serviceAmountMap[serviceAmountList[i].ContractPaymentId] = append(serviceAmountMap[serviceAmountList[i].ContractPaymentId], serviceAmountList[i])
 				}
 			}
-
+			sellerTypeMap := map[int]string{2: "FICC销售", 5: "权益销售"}
+			sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
+			if e != nil {
+				resp.FailData("获取销售失败", "Err:"+e.Error(), c)
+				return
+			}
+			sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
+			for i := range sellerList {
+				sellerMap[sellerList[i].SellerId] = sellerList[i]
+			}
 			// 重组汇总数据
 			summaryMap := make(map[int][]*fms.InvoicePaymentCensusInfo)
 			amountMap := make(map[string]*fms.ContractPaymentServiceAmount)
@@ -771,7 +781,7 @@ func (ct *InvoicePaymentController) List(c *gin.Context) {
 				v.SellerName = summaryList[i].SellerName
 				v.SellerGroupId = summaryList[i].SellerGroupId
 				v.SellerGroupName = summaryList[i].SellerGroupName
-				v.SellerType = summaryList[i].ServiceProductId
+				v.SellerType = sellerTypeMap[sellerMap[summaryList[i].SellerId].DepartmentId]
 				v.PaymentId = summaryList[i].PaymentId
 				v.PaymentDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].PaymentDate)
 				v.PaymentAmount = summaryList[i].PaymentAmount
@@ -1514,3 +1524,1217 @@ func ExportIncomeList(c *gin.Context, list []*fms.IncomeSummaryItem) {
 	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
 	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
 }
+
+// List
+// @Title 未开票统计列表
+// @Description 未开票统计列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   SellGroupId		query	int		false	"销售组别ID"
+// @Param   ServiceType		query	int		false	"套餐类型"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   TimeType		query	int		false	"时间类型: 1-开票时间; 2-到款时间"
+// @Param   HasInvoice		query	string		false	"是否已开票: 0-否; 1-是; 空-全部"
+// @Param   HasPayment		query	string		false	"是否已到款: 0-否; 1-是; 空-全部"
+// @Param   IsExport		query	int		false	"是否导出: 0-否; 1-是"
+// @Param   ListParam		query	int		false	"套餐类型: 0-全部; 1-ficc; 2-权益"
+// @Param   SortParam       query   string  false      "排序字段参数,用来排序的字段, 枚举值:'start_date':开票日 、 'end_date':到款日"
+// @Param   SortType        query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /census/invoice_payment/not_invoice/list [get]
+func (ct *InvoicePaymentController) NotInvoiceList(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	if e := c.BindQuery(&req); e != nil {
+		err, ok := e.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+e.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", err.Translate(global.Trans), c)
+		return
+	}
+
+	cond := `1 = 1`
+	pars := make([]interface{}, 0)
+	noSummaryCond := `1 = 1`
+	noSummaryPars := make([]interface{}, 0)
+	// 客户姓名/合同编号
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		pars = append(pars, kw, kw)
+		noSummaryCond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		noSummaryPars = append(noSummaryPars, kw, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (b.seller_id in ? OR b.rai_seller_id in ?)`
+		pars = append(pars, sellerIds, sellerIds)
+		noSummaryCond += ` AND (b.seller_id in ? OR b.rai_seller_id in ?)`
+		noSummaryPars = append(noSummaryPars, sellerIds, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+			noSummaryCond += ` AND b.register_id IN ? `
+			noSummaryPars = append(noSummaryPars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+			noSummaryCond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+		noSummaryCond += ` AND b.product_ids = '1' `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+		noSummaryCond += ` AND b.product_ids = '2' `
+	}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "asc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortParam == "" {
+		page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: true})
+	} else if req.SortParam == "start_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.start_date", Asc: false})
+		}
+	} else if req.SortParam == "end_date" {
+		if req.SortType == "asc" {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: true})
+		} else {
+			page.AddOrderItem(base.OrderItem{Column: "e.end_date", Asc: false})
+		}
+	} else {
+		resp.Fail("排序字段不正确", c)
+		return
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	cond += `  AND b.contract_amount <> b.invoiced_amount AND b.is_deleted = 0 AND b.contract_amount <> b.payment_amount `
+	registerList, total, e := fms.GetInvoiceCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for _, v := range registerList {
+		queryRegisterIds = append(queryRegisterIds, v.ContractRegisterId)
+	}
+	fmt.Println("queryRegisterIds:", queryRegisterIds)
+	results := new(fms.NotInvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取合同的套餐金额信息
+		serviceAmountList, e := fms.GetContractServiceAmountByContractRegisterIds(queryRegisterIds)
+		if e != nil {
+			resp.FailData("获取合同的套餐金额信息失败", "Err:"+e.Error(), c)
+			return
+		}
+		serviceAmountMap := make(map[int]map[int]*fms.ContractServiceAmount, 0)
+		for _, v := range serviceAmountList {
+			if _, ok := serviceAmountMap[v.ContractRegisterId]; !ok {
+				serviceAmountMap[v.ContractRegisterId] = make(map[int]*fms.ContractServiceAmount)
+			}
+			serviceAmountMap[v.ContractRegisterId][v.ProductId] = v
+			fmt.Println("ServiceAmount,ProductId", v.ServiceAmount, v.ProductId, v.ContractRegisterId)
+		}
+
+		// 获取汇总数据IDs, 用于查询合计数据
+		//summaryIdsCond := cond
+		//summaryIdsPars := pars
+		//if req.SellerIds != "" {
+		//	sellerIds := strings.Split(req.SellerIds, ",")
+		//	summaryIdsCond += ` AND c.seller_id in ?  AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+		//	summaryIdsPars = append(summaryIdsPars, sellerIds)
+		//} else {
+		//	summaryIdsCond += `  AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+		//	summaryIdsPars = append(summaryIdsPars)
+		//}
+		//summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		//if e != nil {
+		//	resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+		//	return
+		//}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.NotPaymentCensusItem, 0)
+		summaryList := make([]*fms.NotInvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			//if req.SellerIds != "" {
+			//	sellerIds := strings.Split(req.SellerIds, ",")
+			//	summaryCond += ` AND c.seller_id in ? AND a.payment_id <> 0 AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			//	summaryPars = append(summaryPars, sellerIds, sellerIds)
+			//} else {
+			//	summaryCond += ` AND a.payment_id <> 0 AND (d.origin_amount > c.origin_amount OR c.origin_amount IS NULL) `
+			//	summaryPars = append(summaryPars)
+			//}
+
+			summaryData, e := fms.GetNotInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			notQueryRegisterIds := make([]int, 0)
+			for _, v := range summaryData {
+				notQueryRegisterIds = append(notQueryRegisterIds, v.ContractRegisterId)
+			}
+
+			noSummaryCond += ` AND b.is_deleted = 0`
+			noSummaryCond += ` AND b.contract_register_id IN ? AND b.contract_register_id NOT IN ?`
+			noSummaryPars = append(noSummaryPars, queryRegisterIds, notQueryRegisterIds)
+			noSummaryData, e := fms.GetNoInvoicePaymentCensusData(noSummaryCond, noSummaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "GetNoInvoicePaymentCensusData, Err: "+e.Error(), c)
+				return
+			}
+			fmt.Println("len(summaryData)", len(summaryData))
+			fmt.Println("len(noSummaryData)", len(noSummaryData))
+			summaryList = summaryData
+			NotInvoiceSummaryMap := make(map[int][]*fms.NotInvoicePaymentSummaryItem, 0)
+			for _, v := range summaryList {
+				fmt.Println("v2.ContractRegisterId", v.ContractRegisterId)
+				NotInvoiceSummaryMap[v.RegisterId] = append(NotInvoiceSummaryMap[v.RegisterId], v)
+			}
+
+			summaryList = append(summaryList, noSummaryData...)
+
+			//summaryIds := make([]int, 0)
+			//paymentIds := make([]int, 0)
+			//for i := range summaryList {
+			//	//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+			//}
+
+			fmt.Println("len(NotInvoiceSummaryMap):", len(NotInvoiceSummaryMap))
+
+			for _, v := range summaryList {
+				fmt.Println("ProductIds:", v.ProductIds)
+				fmt.Println("ContractRegisterId:", v.ContractRegisterId)
+				fmt.Println("ServiceProductId:", v.ServiceProductId)
+				fmt.Println("RegisterId:", v.RegisterId)
+				fmt.Println("len(NotInvoiceSummaryMap[v.RegisterId]):", len(NotInvoiceSummaryMap[v.ContractRegisterId]))
+				if (v.ProductIds == "1,2" || v.ProductIds == "2,1") && len(NotInvoiceSummaryMap[v.ContractRegisterId]) == 1 {
+					if v.ServiceProductId == 1 {
+						item := fms.NotInvoicePaymentSummaryItem{
+							NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][2].ServiceAmount,
+							ServiceProductId:       2,
+						}
+						item.SellerId = v.SellerId
+						item.SellerName = v.SellerName
+						item.RaiSellerId = v.RaiSellerId
+						item.RaiSellerName = v.RaiSellerName
+
+						NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item)
+					} else {
+
+						item := fms.NotInvoicePaymentSummaryItem{
+							NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][1].ServiceAmount,
+							ServiceProductId:       1,
+						}
+						item.SellerId = v.SellerId
+						item.SellerName = v.SellerName
+						item.RaiSellerId = v.RaiSellerId
+						item.RaiSellerName = v.RaiSellerName
+
+						NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item)
+					}
+				} else if (v.ProductIds == "1,2" || v.ProductIds == "2,1") && len(NotInvoiceSummaryMap[v.ContractRegisterId]) == 0 {
+					item1 := fms.NotInvoicePaymentSummaryItem{
+						NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][2].ServiceAmount,
+						ServiceProductId:       2,
+					}
+					item1.SellerId = v.SellerId
+					item1.SellerName = v.SellerName
+					item1.RaiSellerId = v.RaiSellerId
+					item1.RaiSellerName = v.RaiSellerName
+					NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item1)
+
+					item2 := fms.NotInvoicePaymentSummaryItem{
+						NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][1].ServiceAmount,
+						ServiceProductId:       1,
+					}
+					item2.SellerId = v.SellerId
+					item2.SellerName = v.SellerName
+					item2.RaiSellerId = v.RaiSellerId
+					item2.RaiSellerName = v.RaiSellerName
+
+					NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item2)
+				} else if v.ProductIds == "1" && len(NotInvoiceSummaryMap[v.ContractRegisterId]) == 0 {
+					item1 := fms.NotInvoicePaymentSummaryItem{
+						NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][1].ServiceAmount,
+						ServiceProductId:       1,
+					}
+					item1.SellerId = v.SellerId
+					item1.SellerName = v.SellerName
+					item1.RaiSellerId = v.RaiSellerId
+					item1.RaiSellerName = v.RaiSellerName
+
+					NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item1)
+
+				} else if v.ProductIds == "2" && len(NotInvoiceSummaryMap[v.ContractRegisterId]) == 0 {
+					item2 := fms.NotInvoicePaymentSummaryItem{
+						NotInvoicedAmountTotal: serviceAmountMap[v.ContractRegisterId][2].ServiceAmount,
+						ServiceProductId:       2,
+					}
+					item2.SellerId = v.SellerId
+					item2.SellerName = v.SellerName
+					item2.RaiSellerId = v.RaiSellerId
+					item2.RaiSellerName = v.RaiSellerName
+
+					NotInvoiceSummaryMap[v.ContractRegisterId] = append(NotInvoiceSummaryMap[v.ContractRegisterId], &item2)
+				}
+			}
+
+			// 重组汇总数据
+			sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
+			if e != nil {
+				resp.FailData("获取销售失败", "Err:"+e.Error(), c)
+				return
+			}
+			sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
+			for i := range sellerList {
+				sellerMap[sellerList[i].SellerId] = sellerList[i]
+			}
+			sellerTypeMap := map[int]string{2: "FICC销售", 5: "权益销售"}
+			// 货币列表
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+			}
+
+			for registerId, list := range NotInvoiceSummaryMap {
+				for _, v := range list {
+					fmt.Println("v.ContractRegisterId", v.ContractRegisterId)
+					fmt.Println("v.ServiceProductId:", v.ServiceProductId)
+					fmt.Println("v.NotInvoicedAmountTotal:", v.NotInvoicedAmountTotal)
+					if v.NotInvoicedAmountTotal == 0 {
+						if v.InvoiceAmountTotal > v.PaymentAmountTotal {
+							v.NotInvoicedAmountTotal = serviceAmountMap[registerId][v.ServiceProductId].ServiceAmount - v.InvoiceAmountTotal
+						} else {
+							v.NotInvoicedAmountTotal = serviceAmountMap[registerId][v.ServiceProductId].ServiceAmount - v.PaymentAmountTotal
+						}
+					}
+					if v.SellerId > 0 && v.RaiSellerId > 0 {
+						if v.ServiceProductId == 1 {
+							v.SellerGroupId = sellerMap[v.SellerId].GroupId
+							v.SellerGroupName = sellerMap[v.SellerId].GroupName
+							v.SellerType = sellerTypeMap[sellerMap[v.SellerId].DepartmentId]
+						} else {
+							v.RaiSellerGroupId = sellerMap[v.RaiSellerId].GroupId
+							v.RaiSellerGroupName = sellerMap[v.RaiSellerId].GroupName
+							v.SellerType = sellerTypeMap[sellerMap[v.RaiSellerId].DepartmentId]
+						}
+					} else if v.SellerId > 0 && v.RaiSellerId == 0 {
+						v.SellerGroupId = sellerMap[v.SellerId].GroupId
+						v.SellerGroupName = sellerMap[v.SellerId].GroupName
+						v.SellerType = sellerTypeMap[sellerMap[v.SellerId].DepartmentId]
+					} else if v.SellerId == 0 && v.RaiSellerId > 0 {
+						v.RaiSellerGroupId = sellerMap[v.RaiSellerId].GroupId
+						v.RaiSellerGroupName = sellerMap[v.RaiSellerId].GroupName
+						v.SellerType = sellerTypeMap[sellerMap[v.RaiSellerId].DepartmentId]
+					}
+				}
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.NotPaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.ContractType = registerList[i].ContractType
+				v.ContractCode = registerList[i].ContractCode
+				v.ContractAmount = registerList[i].ContractAmount
+				v.UnitName = unitMap[registerList[i].CurrencyUnit]
+				v.ProductIds = registerList[i].ProductIds
+				//if registerList[i].InvoicedAmount != 0 {
+				//	v.NotInvoiceTotal = registerList[i].ContractAmount - registerList[i].InvoicedAmount
+				//} else {
+				//	v.NotInvoiceTotal = registerList[i].ContractAmount - registerList[i].PaymentAmount
+				//}
+
+				v.NotInvoiceList = NotInvoiceSummaryMap[registerList[i].ContractRegisterId]
+				respList = append(respList, v)
+			}
+		}()
+
+		// 开票到款金额合计(换算后)
+		//var invoiceTotal, paymentTotal, contractAmount float64
+		//wg.Add(1)
+		//go func() {
+		//	defer wg.Done()
+		//
+		//	if len(summaryIds) == 0 {
+		//		return
+		//	}
+		//	amountTotalCond := `a.id IN ?`
+		//	amountTotalPars := make([]interface{}, 0)
+		//	amountTotalPars = append(amountTotalPars, summaryIds)
+		//	invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+		//	if e != nil {
+		//		totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+		//		return
+		//	}
+		//	invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+		//	paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+		//	if e != nil {
+		//		totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+		//		return
+		//	}
+		//	paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+		//}()
+
+		// 开票到款金额合计(换算后)V2
+		var invoiceTotal, contractAmount float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			registerList, e := fms.GetInvoiceCensusList(cond, pars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+				return
+			}
+			contractIdSumMap := make(map[int]int)
+
+			for _, v := range registerList {
+				if v.InvoicedAmountCount >= v.PaymentAmountCount {
+					invoiceTotal += v.InvoicedAmountCount
+				} else if v.InvoicedAmountCount == 0 {
+					invoiceTotal += v.PaymentAmountCount
+				}
+				rate := v.RMBRate
+				if rate == 0.0 {
+					rate = 1.0
+				}
+				if _,ok := contractIdSumMap[v.ContractRegisterId]; !ok{
+					contractIdSumMap[v.ContractRegisterId] = 1
+					contractAmount += v.ContractAmount / v.RMBRate
+				}
+			}
+
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		contractAmountCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				contractAmountCurrencyTotals = append(contractAmountCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+			}
+
+			registerList, e := fms.GetInvoiceCensusList(cond, pars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+				return
+			}
+
+			invoiceSumMap := make(map[string]float64)
+			contractSumMap := make(map[string]float64)
+			contractIdSumMap := make(map[int]int)
+
+			for _, v := range registerList {
+				if v.InvoiceOrigin >= v.PaymentOrigin {
+					invoiceSumMap[v.CurrencyUnit] += v.InvoicedAmount
+				} else {
+					invoiceSumMap[v.CurrencyUnit] += v.PaymentAmount
+				}
+				if _,ok := contractIdSumMap[v.ContractRegisterId]; !ok{
+					contractIdSumMap[v.ContractRegisterId] = 1
+					contractSumMap[v.CurrencyUnit] += v.ContractAmount
+				}
+			}
+
+			for _, v := range contractAmountCurrencyTotals {
+				v.Amount = contractSumMap[v.Code] - invoiceSumMap[v.Code]
+			}
+
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.NotInvoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", contractAmount-invoiceTotal), 64)
+		results.InvoiceCurrencyTotal = invoiceCurrencyTotals
+		results.PaymentCurrencyTotal = paymentCurrencyTotals
+		results.NotInvoiceCurrencyTotal = contractAmountCurrencyTotals
+	}
+
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportNotInvoiceCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)
+}
+
+// List
+// @Title 开票未到款统计列表
+// @Description 开票未到款统计列表
+// @Param   Keyword			query	string	false	"关键词"
+// @Param   SellGroupId		query	int		false	"销售组别ID"
+// @Param   ServiceType		query	int		false	"套餐类型"
+// @Param   StartDate		query	string	false	"合同开始日期"
+// @Param   EndDate			query	string	false	"合同结束日期"
+// @Param   TimeType		query	int		false	"时间类型: 1-开票时间; 2-到款时间"
+// @Param   HasInvoice		query	string		false	"是否已开票: 0-否; 1-是; 空-全部"
+// @Param   HasPayment		query	string		false	"是否已到款: 0-否; 1-是; 空-全部"
+// @Param   IsExport		query	int		false	"是否导出: 0-否; 1-是"
+// @Param   ListParam		query	int		false	"套餐类型: 0-全部; 1-ficc; 2-权益"
+// @Param   SortParam       query   string  false      "排序字段参数,用来排序的字段, 枚举值:'invoice_time':开票日 、 'payment_date':到款日"
+// @Param   SortType        query   string  true       "如何排序,是正序还是倒序,枚举值:`asc 正序`,`desc 倒叙`"
+// @Success 200 {object} fms.ContractRegisterItem
+// @router /census/invoice_payment/not_payment/list [get]
+func (ct *InvoicePaymentController) NotPaymentList(c *gin.Context) {
+	var req fms.InvoicePaymentCensusListReq
+	if e := c.BindQuery(&req); e != nil {
+		err, ok := e.(validator.ValidationErrors)
+		if !ok {
+			resp.FailData("参数解析失败", "Err:"+e.Error(), c)
+			return
+		}
+		resp.FailData("参数解析失败", err.Translate(global.Trans), c)
+		return
+	}
+
+	cond := `1 = 1`
+	pars := make([]interface{}, 0)
+	// 客户姓名/销售
+	if req.Keyword != "" {
+		kw := "%" + req.Keyword + "%"
+		cond += ` AND (b.company_name LIKE ? OR b.contract_code LIKE ?)`
+		pars = append(pars, kw, kw)
+	}
+	if req.SellerIds != "" {
+		sellerIds := strings.Split(req.SellerIds, ",")
+		cond += ` AND (c.seller_id in ?)`
+		pars = append(pars, sellerIds)
+	}
+	// 套餐筛选
+	if req.ServiceTypes != "" {
+		serviceTypes := strings.Split(req.ServiceTypes, ",")
+		tempRegisterIds, e := fms.GetContractRegisterIdsByTempId(serviceTypes)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
+			return
+		}
+		if len(tempRegisterIds) > 0 {
+			cond += ` AND a.register_id IN ?`
+			pars = append(pars, tempRegisterIds)
+		} else {
+			cond += ` AND 1 = 2`
+		}
+	}
+
+	if req.ListParam == 1 {
+		cond += ` AND a.service_product_id = 1 `
+	} else if req.ListParam == 2 {
+		cond += ` AND a.service_product_id = 2 `
+	}
+
+	page := new(base.Page)
+	page.SetPageSize(req.PageSize)
+	page.SetCurrent(req.Current)
+	//排序
+	if req.SortType == "" {
+		req.SortType = "asc"
+	}
+	if req.SortType != "desc" && req.SortType != "asc" {
+		resp.Fail("排序类型不正确", c)
+		return
+	}
+	if req.SortType == "asc" {
+		page.AddOrderItem(base.OrderItem{Column: "e.invoice_time", Asc: true})
+		page.AddOrderItem(base.OrderItem{Column: "e.modify_time", Asc: false})
+	} else {
+		page.AddOrderItem(base.OrderItem{Column: "e.invoice_time", Asc: false})
+		page.AddOrderItem(base.OrderItem{Column: "e.modify_time", Asc: false})
+	}
+
+	if req.IsExport == 1 {
+		page.SetPageSize(10000)
+		page.SetCurrent(1)
+	}
+
+	registerList, total, e := fms.GetNoPaymentCensusPageList(page, cond, pars)
+	if e != nil {
+		resp.FailMsg("获取失败", "获取商品到款统计列表总数失败, Err: "+e.Error(), c)
+		return
+	}
+	queryRegisterIds := make([]int, 0)
+	for i := range registerList {
+		queryRegisterIds = append(queryRegisterIds, registerList[i].ContractRegisterId)
+	}
+	fmt.Println("queryRegisterIds:", queryRegisterIds)
+
+	//fmt.Println("queryRegisterIds:",queryRegisterIds)
+	results := new(fms.NotInvoicePaymentCensusResp)
+	if len(queryRegisterIds) > 0 {
+		// 获取汇总数据IDs, 用于查询合计数据
+		summaryIdsCond := cond
+		summaryIdsPars := pars
+		if req.SellerIds != "" {
+			sellerIds := strings.Split(req.SellerIds, ",")
+			summaryIdsCond += ` AND c.seller_id in ? AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars, sellerIds)
+		} else {
+			summaryIdsCond += ` AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+			summaryIdsPars = append(summaryIdsPars)
+		}
+		summaryIds, e := fms.GetInvoicePaymentCensusSummaryDataIds(summaryIdsCond, summaryIdsPars)
+		if e != nil {
+			resp.FailMsg("获取失败", "获取商品到款汇总IDs失败, Err: "+e.Error(), c)
+			return
+		}
+
+		//fmt.Println("summaryIds:",summaryIds)
+		var listErr, totalErr, totalGroupErr error
+		wg := sync.WaitGroup{}
+
+		// 响应列表
+		respList := make([]*fms.NotPaymentCensusItem, 0)
+		summaryList := make([]*fms.InvoicePaymentSummaryItem, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			// 获取汇总数据
+			summaryCond := cond
+			summaryCond += ` AND a.register_id IN ?`
+			summaryPars := pars
+			summaryPars = append(summaryPars, queryRegisterIds)
+			if req.SellerIds != "" {
+				sellerIds := strings.Split(req.SellerIds, ",")
+				summaryCond += ` AND c.seller_id in ? AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+				summaryPars = append(summaryPars, sellerIds)
+			} else {
+				summaryCond += ` AND a.invoice_id <> 0  AND (c.origin_amount > d.origin_amount OR d.origin_amount IS NULL) `
+				summaryPars = append(summaryPars)
+			}
+			summaryData, e := fms.GetInvoicePaymentCensusSummaryData(summaryCond, summaryPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取商品到款汇总列表失败, Err: "+e.Error(), c)
+				return
+			}
+			summaryList = summaryData
+			//summaryIds := make([]int, 0)
+			//for i := range summaryList {
+			//	//summaryIds = append(summaryIds, summaryList[i].SummaryId)
+			//
+			//}
+			// 货币列表
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				resp.FailMsg("获取失败", "获取货币列表失败, Err: "+e.Error(), c)
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+			}
+			//// 获取合同的套餐金额信息
+			//serviceAmountList, e := fms.GetContractServiceAmountByContractRegisterIds(queryRegisterIds)
+			//if e != nil {
+			//	resp.FailData("获取合同的套餐金额信息失败", "Err:"+e.Error(), c)
+			//	return
+			//}
+			//serviceAmountMap := make(map[int]map[int]*fms.ContractServiceAmount, 0)
+			//for _, v := range serviceAmountList {
+			//	if _, ok := serviceAmountMap[v.ContractRegisterId]; !ok {
+			//		serviceAmountMap[v.ContractRegisterId] = make(map[int]*fms.ContractServiceAmount)
+			//	}
+			//	serviceAmountMap[v.ContractRegisterId][v.ProductId] = v
+			//}
+			sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
+			if e != nil {
+				resp.FailData("获取销售失败", "Err:"+e.Error(), c)
+				return
+			}
+			sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
+			for i := range sellerList {
+				sellerMap[sellerList[i].SellerId] = sellerList[i]
+			}
+			sellerTypeMap := map[int]int{crm.SellerDepartmentId: 1, crm.RaiSellerDepartmentId: 2}
+			// 重组汇总数据
+			summaryMap := make(map[int][]*fms.NotPaymentCensusInfo)
+			for i := range summaryList {
+				v := new(fms.NotPaymentCensusInfo)
+				v.InvoiceId = summaryList[i].InvoiceId
+				v.InvoiceDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].InvoiceDate)
+				v.InvoiceAmount = summaryList[i].InvoiceAmount
+				v.SellerId = summaryList[i].SellerId
+				v.SellerName = summaryList[i].SellerName
+				v.SellerGroupId = summaryList[i].SellerGroupId
+				v.SellerGroupName = summaryList[i].SellerGroupName
+				v.SellerType = sellerTypeMap[sellerMap[summaryList[i].SellerId].DepartmentId]
+				v.PaymentId = summaryList[i].PaymentId
+				v.PaymentDate = utils.TimeTransferString(utils.FormatDate, summaryList[i].PaymentDate)
+				v.PaymentAmount = summaryList[i].PaymentAmount
+				v.PayType = summaryList[i].PayType
+				v.NotPaymentAmount = summaryList[i].InvoiceAmount - summaryList[i].PaymentAmount
+				v.ServiceProductId = summaryList[i].ServiceProductId
+				v.UnitName = unitMap[summaryList[i].CurrencyUnit]
+				summaryMap[summaryList[i].SummaryId] = append(summaryMap[summaryList[i].SummaryId], v)
+			}
+
+			// 响应列表
+			for i := range registerList {
+				v := new(fms.NotPaymentCensusItem)
+				v.SummaryId = registerList[i].SummaryId
+				v.ContractRegisterId = registerList[i].ContractRegisterId
+				v.CompanyName = registerList[i].CompanyName
+				v.NewCompany = registerList[i].NewCompany
+				v.StartDate = utils.TimeTransferString(utils.FormatDate, registerList[i].StartDate)
+				v.EndDate = utils.TimeTransferString(utils.FormatDate, registerList[i].EndDate)
+				v.InvoicePaymentList = summaryMap[registerList[i].SummaryId]
+				v.ContractType = registerList[i].ContractType
+				v.ContractCode = registerList[i].ContractCode
+				v.ContractAmount = registerList[i].ContractAmount
+				v.UnitName = unitMap[registerList[i].CurrencyUnit]
+				v.ProductIds = registerList[i].ProductIds
+				respList = append(respList, v)
+			}
+		}()
+		// 开票到款金额合计(换算后)
+		var invoiceTotal, paymentTotal float64
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			amountTotalCond := `a.id IN ?`
+			amountTotalPars := make([]interface{}, 0)
+			amountTotalPars = append(amountTotalPars, summaryIds)
+			invoiceSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 1)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总开票金额合计失败, Err: %s", e.Error())
+				return
+			}
+			invoiceTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSum), 64)
+			paymentSum, e := fms.GetContractSummaryInvoicePaymentAmountTotal(amountTotalCond, amountTotalPars, 2)
+			if e != nil {
+				totalErr = fmt.Errorf("获取汇总到款金额合计失败, Err: %s", e.Error())
+				return
+			}
+			paymentTotal, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSum), 64)
+		}()
+
+		// 分币种金额统计
+		invoiceCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		paymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		notpaymentCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		//contractAmountCurrencyTotals := make([]*fms.InvoiceListCurrencyTotal, 0)
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+
+			currencyOB := new(fms.CurrencyUnit)
+			currencyCond := `enable = 1`
+			currencyPars := make([]interface{}, 0)
+			currencyList, e := currencyOB.List(currencyCond, currencyPars)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取货币列表失败, Err: %s", e.Error())
+				return
+			}
+			unitMap := make(map[string]string)
+			for i := range currencyList {
+				unitMap[currencyList[i].Code] = currencyList[i].UnitName
+				invoiceCurrencyTotals = append(invoiceCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				paymentCurrencyTotals = append(paymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				notpaymentCurrencyTotals = append(notpaymentCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+					Name:     currencyList[i].Name,
+					UnitName: currencyList[i].UnitName,
+					Code:     currencyList[i].Code,
+					FlagImg:  currencyList[i].FlagImg,
+				})
+				//contractAmountCurrencyTotals = append(contractAmountCurrencyTotals, &fms.InvoiceListCurrencyTotal{
+				//	Name:     currencyList[i].Name,
+				//	UnitName: currencyList[i].UnitName,
+				//	Code:     currencyList[i].Code,
+				//	FlagImg:  currencyList[i].FlagImg,
+				//})
+			}
+
+			if len(summaryIds) == 0 {
+				return
+			}
+			totalGroupCond := `a.id IN ?`
+			totalGroupPars := make([]interface{}, 0)
+			totalGroupPars = append(totalGroupPars, summaryIds)
+			invoiceSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 1)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计开票金额失败, Err: %s", e.Error())
+				return
+			}
+			paymentSumGroup, e := fms.GetSummaryListCurrencySum(totalGroupCond, totalGroupPars, 2)
+			if e != nil {
+				totalGroupErr = fmt.Errorf("获取汇总货币合计到款金额失败, Err: %s", e.Error())
+				return
+			}
+			invoiceSumMap := make(map[string]float64)
+			paymentSumMap := make(map[string]float64)
+			//contractSumMap := make(map[string]float64)
+
+			for i := range invoiceSumGroup {
+				invoiceSumMap[invoiceSumGroup[i].CurrencyUnit] = invoiceSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range paymentSumGroup {
+				paymentSumMap[paymentSumGroup[i].CurrencyUnit] = paymentSumGroup[i].OriginAmountTotal
+				continue
+			}
+			for i := range invoiceCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]), 64)
+				invoiceCurrencyTotals[i].Amount = a
+			}
+			for i := range paymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				paymentCurrencyTotals[i].Amount = a
+			}
+			for i := range notpaymentCurrencyTotals {
+				a, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", invoiceSumMap[invoiceCurrencyTotals[i].Code]-paymentSumMap[paymentCurrencyTotals[i].Code]), 64)
+				notpaymentCurrencyTotals[i].Amount = a
+			}
+
+			//contractRegisters, err := fms.GetContractInfoByRegisterIds(queryRegisterIds)
+			//if err != nil {
+			//	resp.FailMsg("查询合同信息失败", "查询合同信息失败, Err: "+err.Error(), c)
+			//	return
+			//}
+			//for _, v := range contractRegisters {
+			//	if v.RMBRate == 0.0 {
+			//		v.RMBRate = 1
+			//	}
+			//	amount, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", v.ContractAmount/v.RMBRate), 64)
+			//	contractAmount += amount
+			//	contractSumMap[v.CurrencyUnit] = v.ContractAmount
+			//}
+			//for _, v := range contractAmountCurrencyTotals {
+			//	v.Amount = contractSumMap[v.Code] - invoiceSumMap[v.Code]
+			//}
+
+		}()
+
+		wg.Wait()
+
+		if listErr != nil {
+			resp.FailMsg("获取失败", listErr.Error(), c)
+			return
+		}
+		if totalErr != nil {
+			resp.FailMsg("获取失败", totalErr.Error(), c)
+			return
+		}
+		if totalGroupErr != nil {
+			resp.FailMsg("获取失败", totalGroupErr.Error(), c)
+			return
+		}
+		results.DataList = respList
+		results.InvoiceTotal = invoiceTotal
+		results.PaymentTotal = paymentTotal
+		results.NotPaymentTotal = invoiceTotal - paymentTotal
+		results.NotPaymentCurrencyTotal = notpaymentCurrencyTotals
+	}
+	// 是否导出
+	if req.IsExport == 1 {
+		ExportNotPaymentCensusList(c, results)
+		return
+	}
+	page.SetTotal(total)
+	baseData := new(base.BaseData)
+	baseData.SetPage(page)
+	baseData.SetList(results)
+	resp.OkData("获取成功", baseData, c)
+}
+
+// ExportNotInvoiceCensusList 导出未开票统计列表
+func ExportNotInvoiceCensusList(c *gin.Context, results *fms.NotInvoicePaymentCensusResp) {
+	list := results.DataList
+	if len(list) == 0 {
+		resp.Fail("列表数据为空", c)
+		return
+	}
+	// 生成Excel文件
+	xlsxFile := xlsx.NewFile()
+	style := xlsx.NewStyle()
+	alignment := xlsx.Alignment{
+		Horizontal: "center",
+		Vertical:   "center",
+		WrapText:   true,
+	}
+	style.Alignment = alignment
+	style.ApplyAlignment = true
+
+	sheetName := "未开票统计表"
+	sheet, err := xlsxFile.AddSheet(sheetName)
+	if err != nil {
+		resp.FailData("新增Sheet失败", "Err:"+err.Error(), c)
+		return
+	}
+
+	// 数据表头
+	rowTitle := []string{"序号", "客户名称", "合同编号", "合同开始时间", "合同结束时间", "合同金额", "金额单位", "未开票金额", "套餐类型", "销售", "销售组别", "销售类型"}
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+	}
+	incomeSummaryItemList := make([]*fms.NotPaymentCensusItem, 0)
+	incomeSummaryItemList = list
+
+	sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
+	if e != nil {
+		resp.FailData("获取销售失败", "Err:"+e.Error(), c)
+		return
+	}
+	sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
+	for i := range sellerList {
+		sellerMap[sellerList[i].SellerId] = sellerList[i]
+	}
+	sellerTypeMap := map[int]string{2: "FICC销售", 5: "权益销售"}
+	serviceProductIdMap := map[int]string{
+		1: "FICC套餐",
+		2: "权益套餐",
+	}
+	// 填充数据
+	for i, v := range incomeSummaryItemList {
+		dataRow := sheet.AddRow()
+		dataRow2 := sheet.AddRow()
+
+		cell := dataRow.AddCell()
+		cell.VMerge = 1
+		cell.SetString(strconv.Itoa(i + 1)) //序号
+		dataRow2.AddCell().SetString("")
+
+		cell2 := dataRow.AddCell()
+		cell2.VMerge = 1
+		cell2.SetString(v.CompanyName) // 客户名称
+		dataRow2.AddCell().SetString("")
+
+		cell3 := dataRow.AddCell()
+		cell3.VMerge = 1
+		cell3.SetString(v.ContractCode) // 合同编号
+		dataRow2.AddCell().SetString("")
+
+		cell4 := dataRow.AddCell()
+		cell4.VMerge = 1
+		cell4.SetString(v.StartDate) // 合同开始时间
+		dataRow2.AddCell().SetString("")
+
+		cell5 := dataRow.AddCell()
+		cell5.VMerge = 1
+		cell5.SetString(v.EndDate) // 合同结束时间
+		dataRow2.AddCell().SetString("")
+
+		cell6 := dataRow.AddCell()
+		cell6.VMerge = 1
+		cell6.SetString(fmt.Sprintf("%.2f", v.ContractAmount)) // 合同金额
+		dataRow2.AddCell().SetString("")
+
+		cell7 := dataRow.AddCell()
+		cell7.VMerge = 1
+		cell7.SetString(v.UnitName) // 金额单位
+		dataRow2.AddCell().SetString("")
+
+		for j, item := range v.NotInvoiceList {
+			if j == 1 {
+				dataRow2.AddCell().SetString(fmt.Sprintf("%.2f", item.NotInvoicedAmountTotal)) // 未开票金额
+				dataRow2.AddCell().SetString(serviceProductIdMap[item.ServiceProductId])       // 套餐类型
+
+				if item.SellerId > 0 && item.RaiSellerId > 0 {
+					if item.ServiceProductId == 1 {
+						item.SellerGroupName = sellerMap[item.SellerId].GroupName
+						item.SellerType = sellerTypeMap[sellerMap[item.SellerId].DepartmentId]
+						dataRow2.AddCell().SetString(item.SellerName)      // 销售
+						dataRow2.AddCell().SetString(item.SellerGroupName) // 销售组别
+						dataRow2.AddCell().SetString(item.SellerType)      // 销售类型
+					} else {
+						item.RaiSellerGroupName = sellerMap[item.RaiSellerId].GroupName
+						item.SellerType = sellerTypeMap[sellerMap[item.RaiSellerId].DepartmentId]
+						dataRow2.AddCell().SetString(item.RaiSellerName)      // 销售
+						dataRow2.AddCell().SetString(item.RaiSellerGroupName) // 销售组别
+						dataRow2.AddCell().SetString(item.SellerType)         // 销售类型
+					}
+				} else if item.SellerId > 0 && item.RaiSellerId == 0 {
+					item.SellerGroupName = sellerMap[item.SellerId].GroupName
+					item.SellerType = sellerTypeMap[sellerMap[item.SellerId].DepartmentId]
+					dataRow2.AddCell().SetString(item.SellerName)      // 销售
+					dataRow2.AddCell().SetString(item.SellerGroupName) // 销售组别
+					dataRow2.AddCell().SetString(item.SellerType)      // 销售类型
+				} else if item.SellerId == 0 && item.RaiSellerId > 0 {
+					item.RaiSellerGroupName = sellerMap[item.RaiSellerId].GroupName
+					item.SellerType = sellerTypeMap[sellerMap[item.RaiSellerId].DepartmentId]
+					dataRow2.AddCell().SetString(item.RaiSellerName)      // 销售
+					dataRow2.AddCell().SetString(item.RaiSellerGroupName) // 销售组别
+					dataRow2.AddCell().SetString(item.SellerType)         // 销售类型
+				}
+
+			} else {
+
+				dataRow.AddCell().SetString(fmt.Sprintf("%.2f", item.NotInvoicedAmountTotal)) // 未开票金额
+
+				dataRow.AddCell().SetString(serviceProductIdMap[item.ServiceProductId])       // 套餐类型
+
+
+				if item.SellerId > 0 && item.RaiSellerId > 0 {
+					if item.ServiceProductId == 1 {
+						item.SellerGroupName = sellerMap[item.SellerId].GroupName
+						item.SellerType = sellerTypeMap[sellerMap[item.SellerId].DepartmentId]
+						dataRow.AddCell().SetString(item.SellerName)      // 销售
+						dataRow.AddCell().SetString(item.SellerGroupName) // 销售组别
+						dataRow.AddCell().SetString(item.SellerType)      // 销售类型
+					} else {
+						item.RaiSellerGroupName = sellerMap[item.RaiSellerId].GroupName
+						item.SellerType = sellerTypeMap[sellerMap[item.RaiSellerId].DepartmentId]
+						dataRow.AddCell().SetString(item.RaiSellerName)      // 销售
+						dataRow.AddCell().SetString(item.RaiSellerGroupName) // 销售组别
+						dataRow.AddCell().SetString(item.SellerType)         // 销售类型
+					}
+				} else if item.SellerId > 0 && item.RaiSellerId == 0 {
+					item.SellerGroupName = sellerMap[item.SellerId].GroupName
+					item.SellerType = sellerTypeMap[sellerMap[item.SellerId].DepartmentId]
+					dataRow.AddCell().SetString(item.SellerName)      // 销售
+					dataRow.AddCell().SetString(item.SellerGroupName) // 销售组别
+					dataRow.AddCell().SetString(item.SellerType)      // 销售类型
+				} else if item.SellerId == 0 && item.RaiSellerId > 0 {
+					item.RaiSellerGroupName = sellerMap[item.RaiSellerId].GroupName
+					item.SellerType = sellerTypeMap[sellerMap[item.RaiSellerId].DepartmentId]
+					dataRow.AddCell().SetString(item.RaiSellerName)      // 销售
+					dataRow.AddCell().SetString(item.RaiSellerGroupName) // 销售组别
+					dataRow.AddCell().SetString(item.SellerType)         // 销售类型
+				}
+			}
+
+		}
+	}
+
+	// 输出文件
+	var buffer bytes.Buffer
+	_ = xlsxFile.Write(&buffer)
+	content := bytes.NewReader(buffer.Bytes())
+	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
+	fileName := sheetName + randStr + ".xlsx"
+
+	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
+	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
+}
+
+// ExportNotPaymentCensusList 导出开票未到款统计列表
+func ExportNotPaymentCensusList(c *gin.Context, results *fms.NotInvoicePaymentCensusResp) {
+	list := results.DataList
+	if len(list) == 0 {
+		resp.Fail("列表数据为空", c)
+		return
+	}
+
+	// 生成Excel文件
+	xlsxFile := xlsx.NewFile()
+	style := xlsx.NewStyle()
+	alignment := xlsx.Alignment{
+		Horizontal: "center",
+		Vertical:   "center",
+		WrapText:   true,
+	}
+	style.Alignment = alignment
+	style.ApplyAlignment = true
+
+	sheet, err := xlsxFile.AddSheet("开票未到款统计")
+	if err != nil {
+		resp.FailData("新增Sheet失败", "Err:"+err.Error(), c)
+		return
+	}
+	_ = sheet.SetColWidth(1, 1, 30)
+	_ = sheet.SetColWidth(3, 3, 30)
+
+	// 前三行-开票金额合计
+	rowA := sheet.AddRow()
+	cellAA := rowA.AddCell()
+	cellAA.SetString(fmt.Sprintf("开票未到款合计金额(换算后):%.2f(元)", results.InvoiceTotal))
+	rowBData := "开票未到款金额:"
+	for _, v := range results.NotPaymentCurrencyTotal {
+		rowBData += fmt.Sprintf("%s%.2f(%s)  ", v.Name, v.Amount, v.UnitName)
+	}
+	rowB := sheet.AddRow()
+	rowB.AddCell().SetString(rowBData)
+	sheet.AddRow()
+
+	// 表头, 套餐动态获取
+	rowTitle := []string{"序号", "客户名称", "合同编号", "合同有效期", "套餐类型", "开票日", "开票金额", "金额单位", "开票销售",
+		"销售组别", "销售类型"}
+
+	titleRow := sheet.AddRow()
+	for i := range rowTitle {
+		v := titleRow.AddCell()
+		v.SetString(rowTitle[i])
+		v.SetStyle(style)
+	}
+	serviceProductIdMap := map[int]string{
+		1: "FICC套餐",
+		2: "权益套餐",
+	}
+	sellerTypeMap := map[int]string{1: "FICC销售", 2: "权益销售"}
+	for k, v := range list {
+		dataRow := sheet.AddRow()
+		// 前四个单元格根据每行开票到款条数向下合并
+		l := len(v.InvoicePaymentList)
+		mergeRowNum := l - 1
+		// 序号
+		sortNum := k + 1
+		colA := dataRow.AddCell()
+		colA.VMerge = mergeRowNum
+		colA.SetString(fmt.Sprint(sortNum))
+		// 客户名称
+		colB := dataRow.AddCell()
+		colB.VMerge = mergeRowNum
+		colB.SetString(v.CompanyName)
+		// 合同编号
+		colC := dataRow.AddCell()
+		colC.VMerge = mergeRowNum
+		colC.SetString(v.ContractCode)
+		// 合同有效期
+		colD := dataRow.AddCell()
+		colD.VMerge = mergeRowNum
+		colD.SetString(fmt.Sprint(v.StartDate, "至", v.EndDate))
+		// 套餐类型
+		colE := dataRow.AddCell()
+		colE.VMerge = mergeRowNum
+		colE.SetString(serviceProductIdMap[v.InvoicePaymentList[0].ServiceProductId])
+
+		// 开票到款信息
+		for _, v2 := range v.InvoicePaymentList {
+			rowData := []string{
+				v2.InvoiceDate,               // 开票日
+				fmt.Sprint(v2.InvoiceAmount), // 开票金额
+				v2.UnitName,                  // 开票金额
+				v2.SellerName,                // 销售
+				v2.SellerGroupName,           // 组别
+				sellerTypeMap[v2.SellerType], // 销售类型
+			}
+			for i := range rowData {
+				dataRow.AddCell().SetString(rowData[i])
+			}
+		}
+	}
+
+	// 输出文件
+	var buffer bytes.Buffer
+	_ = xlsxFile.Write(&buffer)
+	content := bytes.NewReader(buffer.Bytes())
+	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
+	fileName := "商品到款统计_" + randStr + ".xlsx"
+
+	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
+	c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+	http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
+}

+ 58 - 11
models/fms/contract_invoice.go

@@ -348,6 +348,11 @@ type InvoicePaymentCensusItem struct {
 	ContractType       int                         `json:"contract_type" description:"合同类型: 0-无 1-新签; 2-续约"`
 	ActualPayCompanies string                      `json:"actual_pay_companies" description:"该合同关联的所有代付方, 英文逗号拼接"`
 	InvoicePaymentList []*InvoicePaymentCensusInfo `json:"invoice_payment_list" description:"开票到款列表"`
+	ContractCode       string                      `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	ContractAmount     float64                     `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	UnitName           string                      `gorm:"unit_name" json:"unit_name" description:"单位名称"`
+	ProductIds         string                      `gorm:"column:product_ids" json:"product_ids" description:"产品ID:1-FICC; 2-权益, 如果两者都有,则用英文逗号拼接"`
+	NotInvoiceTotal    float64                     `json:"not_invoice_total" description:"未开票总金额(换算后)"`
 }
 
 // InvoicePaymentCensusInfo 开票到款统计信息
@@ -364,7 +369,7 @@ type InvoicePaymentCensusInfo struct {
 	PaymentAmount     float64                             `json:"payment_amount" description:"到款金额"`
 	PayType           int                                 `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
 	ServiceAmountList []*ContractPaymentServiceAmountItem `json:"service_amount_list" description:"到款套餐金额分配信息"`
-	SellerType        int                                 `json:"seller_type" description:"销售类型:1ficc销售,2权益销售"`
+	SellerType        string                               `json:"seller_type" description:"销售类型:1ficc销售,2权益销售"`
 }
 
 // ContractInvoiceAmountTotal 开票到款金额合计信息
@@ -605,7 +610,7 @@ func GetDuplicateContractInvoiceDetailItemListWithType(companyName, startDate, e
 	err = global.DEFAULT_MYSQL.Table("contract_invoice as a ").
 		Select(" a.* ").
 		Joins(" JOIN contract_register as b ON a.contract_register_id = b.contract_register_id ").
-		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) AND a.invoice_type = %v ",companyName, startDate, endDate, invoiceType)).
+		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) AND a.invoice_type = %v ", companyName, startDate, endDate, invoiceType)).
 		Order("a.contract_invoice_id ASC").
 		Find(&list).Error
 	if err != nil {
@@ -631,7 +636,7 @@ func GetDuplicateContractInvoiceDetailItemList(companyName, startDate, endDate s
 		Select(" a.*,GROUP_CONCAT(c.service_template_id ORDER BY c.service_template_id ) AS template_ids ").
 		Joins(" JOIN contract_register as b ON a.contract_register_id = b.contract_register_id ").
 		Joins("JOIN contract_service AS c ON a.contract_register_id = c.contract_register_id").
-		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) ",companyName, startDate, endDate)).
+		Where(fmt.Sprintf("a.is_deleted = 0 AND b.company_name = '%s' AND b.start_date= '%s' AND b.end_date= '%s' AND b.is_deleted=0 AND (a.invoice_type=3 OR a.invoice_type=4) ", companyName, startDate, endDate)).
 		Group("a.contract_register_id").
 		Order("a.contract_invoice_id ASC").
 		Find(&list).Error
@@ -642,15 +647,15 @@ func GetDuplicateContractInvoiceDetailItemList(companyName, startDate, endDate s
 }
 
 type IncomeListReq struct {
-	SellerIds    string `json:"seller_ids" form:"seller_ids" description:"销售ID,多个ID之间用逗号拼接"`
-	StartDate    string `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01" description:"开始日期"`
-	EndDate      string `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01" description:"结束日期"`
-	IsExport     int    `json:"is_export" form:"is_export" description:"是否导出: 0-否; 1-是"`
-	ListParam    string    `json:"list_param" form:"list_param" description:"套餐类型: 0-月度; 1-季度; 2-半年度;3-年度;4-月度累计"`
-	CompanyType     int    `json:"company_type" form:"company_type" description:"客户类型 0全部 1新客户 2老客户"`
+	SellerIds   string `json:"seller_ids" form:"seller_ids" description:"销售ID,多个ID之间用逗号拼接"`
+	StartDate   string `json:"start_date" form:"start_date" binding:"omitempty,datetime=2006-01" description:"开始日期"`
+	EndDate     string `json:"end_date" form:"end_date" binding:"omitempty,datetime=2006-01" description:"结束日期"`
+	IsExport    int    `json:"is_export" form:"is_export" description:"是否导出: 0-否; 1-是"`
+	ListParam   string `json:"list_param" form:"list_param" description:"套餐类型: 0-月度; 1-季度; 2-半年度;3-年度;4-月度累计"`
+	CompanyType int    `json:"company_type" form:"company_type" description:"客户类型 0全部 1新客户 2老客户"`
 }
 
-//获取最新的开票或到款日期
+// 获取最新的开票或到款日期
 func GetLatestIncome(condition string, pars []interface{}) (result *ContractInvoice, err error) {
 	sql := `SELECT
 	a.* 
@@ -663,4 +668,46 @@ WHERE
 	sql += `ORDER BY a.invoice_time DESC  `
 	err = global.DEFAULT_MYSQL.Raw(sql, pars...).First(&result).Error
 	return
-}
+}
+
+// NotPaymentCensusItem 商品到款统计信息
+type NotPaymentCensusItem struct {
+	SummaryId          int                     `json:"summary_id" description:"汇总ID"`
+	ContractRegisterId int                     `json:"contract_register_id" description:"登记ID"`
+	CompanyName        string                  `json:"company_name" description:"客户名称"`
+	NewCompany         int                     `json:"new_company" description:"是否为新客户: 0-否; 1-是"`
+	StartDate          string                  `json:"start_date" description:"合同开始日期"`
+	EndDate            string                  `json:"end_date" description:"合同结束日期"`
+	ServicesName       string                  `json:"services_name" description:"套餐信息字符串拼接"`
+	ContractType       int                     `json:"contract_type" description:"合同类型: 0-无 1-新签; 2-续约"`
+	ActualPayCompanies string                  `json:"actual_pay_companies" description:"该合同关联的所有代付方, 英文逗号拼接"`
+	InvoicePaymentList []*NotPaymentCensusInfo `json:"invoice_payment_list" description:"开票到款列表"`
+	ContractCode       string                  `gorm:"column:contract_code" json:"contract_code" description:"合同编号"`
+	ContractAmount     float64                 `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	UnitName           string                  `gorm:"unit_name" json:"unit_name" description:"单位名称"`
+	ProductIds         string                  `gorm:"column:product_ids" json:"product_ids" description:"产品ID:1-FICC; 2-权益, 如果两者都有,则用英文逗号拼接"`
+	NotInvoiceTotal    float64                 `json:"not_invoice_total" description:"未开票总金额(换算后)"`
+	NotInvoiceList    []*NotInvoicePaymentSummaryItem     `json:"not_invoice_list" description:"未开票invoice列表"`
+}
+
+// NotPaymentCensusInfo 开票到款统计信息
+type NotPaymentCensusInfo struct {
+	InvoiceId         int                                 `json:"invoice_id" description:"开票ID"`
+	InvoiceDate       string                              `json:"invoice_time" description:"开票日期"`
+	InvoiceAmount     float64                             `json:"invoice_amount" description:"开票金额"`
+	SellerId          int                                 `json:"seller_id" description:"销售ID"`
+	SellerName        string                              `json:"seller_name" description:"销售名称"`
+	SellerGroupId     int                                 `json:"seller_group_id" description:"销售组别ID"`
+	SellerGroupName   string                              `json:"seller_group_name" description:"销售组别名称"`
+	PaymentId         int                                 `json:"payment_id" description:"到款ID"`
+	PaymentDate       string                              `json:"payment_date" description:"到款日期"`
+	PaymentAmount     float64                             `json:"payment_amount" description:"到款金额"`
+	PayType           int                                 `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+	ServiceAmountList []*ContractPaymentServiceAmountItem `json:"service_amount_list" description:"到款套餐金额分配信息"`
+	SellerType        int                                 `json:"seller_type" description:"销售类型:1ficc销售,2权益销售"`
+	NotPaymentAmount  float64                             `json:"not_payment_amount" description:"开票未到款金额"`
+	ServiceProductId int       `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	UnitName string  `json:"unit_name" description:"单位名称"`
+}
+
+

+ 151 - 7
models/fms/invoice_payment_summary.go

@@ -92,13 +92,18 @@ type InvoicePaymentSummaryItem struct {
 	PaymentAmount    float64   `json:"payment_amount" description:"到款金额"`
 	PayType          int       `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
 	ServiceProductId int       `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	ContractAmount   float64   `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	InvoicedAmount   float64   `gorm:"column:invoiced_amount" json:"invoiced_amount" description:"开票金额"`
+	CurrencyUnit     string    `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+	RMBRate          float64   `gorm:"column:rmb_rate" json:"rmb_rate" description:"人民币汇率(create_time当日)"`
+	UnitName         string    `json:"unit_name" description:"单位名称"`
 }
 
 // GetInvoicePaymentCensusSummaryData 获取商品到款统计列表-汇总数据
 func GetInvoicePaymentCensusSummaryData(condition string, pars []interface{}) (results []*InvoicePaymentSummaryItem, err error) {
 	fields := []string{"a.id AS summary_id", "a.register_id", "a.invoice_id", "a.payment_id", "a.service_product_id", "b.company_name", "b.start_date", "b.end_date",
 		"c.origin_amount AS invoice_amount", "c.invoice_time AS invoice_date", "IF(c.seller_id > 0, c.seller_id, d.seller_id) AS seller_id", "IF(c.seller_name = '' OR c.seller_name IS NULL, d.seller_name, c.seller_name) AS seller_name", "IF(c.seller_group_id > 0,c.seller_group_id,d.seller_group_id) AS seller_group_id",
-		"IF(c.seller_group_name = '' OR c.seller_group_name IS NULL, d.seller_group_name, c.seller_group_name) AS seller_group_name", "d.origin_amount AS payment_amount", "d.invoice_time AS payment_date", "d.pay_type",
+		"IF(c.seller_group_name = '' OR c.seller_group_name IS NULL, d.seller_group_name, c.seller_group_name) AS seller_group_name", "d.origin_amount AS payment_amount", "d.invoice_time AS payment_date", "d.pay_type", "b.currency_unit",
 	}
 	query := global.DEFAULT_MYSQL.Table("invoice_payment_summary AS a").
 		Select(strings.Join(fields, ",")).
@@ -187,11 +192,11 @@ func GetInvoicePaymentSummaryByRegisterIdAndInvoiceId(registerId, invocieId int)
 }
 
 type IncomeSummaryItem struct {
-	CompanyName string    `json:"company_name" description:"客户名称"`
-	ContractType  int       `json:"contract_type" description:"是否为新客户: 2-否; 1-是"`
-	InvoiceDate time.Time `json:"invoice_time" description:"开票日期"`
-	Amount      float64   `json:"amount" description:"金额"`
-	SellerName  string    `json:"seller_name" description:"销售名称"`
+	CompanyName  string    `json:"company_name" description:"客户名称"`
+	ContractType int       `json:"contract_type" description:"是否为新客户: 2-否; 1-是"`
+	InvoiceDate  time.Time `json:"invoice_time" description:"开票日期"`
+	Amount       float64   `json:"amount" description:"金额"`
+	SellerName   string    `json:"seller_name" description:"销售名称"`
 }
 
 // GetContractSummaryIncomeAmount 获取汇总金额合计信息
@@ -209,6 +214,74 @@ func GetContractSummaryIncomeAmount(condition string, pars []interface{}) (resul
 	return
 }
 
+type InvoiceSummary struct {
+	SummaryId           int     `json:"summary_id" description:"汇总ID"`
+	PaymentAmountCount  float64 `gorm:"column:payment_amount_count" json:"payment_amount_count" description:"到款金额"`
+	InvoicedAmountCount float64 `gorm:"column:invoiced_amount_count" json:"invoiced_amount_count" description:"开票金额"`
+	InvoiceOrigin       float64 `gorm:"column:invoice_origin" json:"invoice_origin" description:"开票原始金额"`
+	PaymentOrigin       float64 `gorm:"column:payment_origin" json:"payment_origin" description:"到款原始金额"`
+	ServiceProductId    int     `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	ContractRegister
+}
+
+// GetInvoiceCensusPageList 获取未开票统计列表-总数
+func GetInvoiceCensusPageList(page base.IPage, condition string, pars []interface{}) (results []*InvoiceSummary, count int64, err error) {
+	query := global.DEFAULT_MYSQL.Table("contract_register AS b").
+		Select("b.*, a.id as summary_id, IF(a.invoice_id >0, 1,0) as sort_invoice_id, IF(a.payment_id >0, 1,0) as sort_payment_id, COALESCE(SUM( c.amount ),0) AS invoiced_amount_count,COALESCE(SUM( d.amount ),0) AS payment_amount_count ").
+		Joins("left JOIN invoice_payment_summary AS a ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("contract_register_id")
+
+	nq := global.DEFAULT_MYSQL.Table("(?) AS e", query).
+		Select("*").Where(" e.invoiced_amount_count <>  e.contract_amount ")
+	nq.Count(&count)
+	if len(page.GetOrderItemsString()) > 0 {
+		nq = nq.Order(page.GetOrderItemsString())
+	}
+	err = nq.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&results).Error
+	if err != nil {
+		return
+	}
+	return
+}
+
+// GetNoPaymentCensusPageList 获取开票未到款统计计列表-总数
+func GetNoPaymentCensusPageList(page base.IPage, condition string, pars []interface{}) (results []*InvoiceSummary, count int64, err error) {
+	query := global.DEFAULT_MYSQL.Table("invoice_payment_summary AS a").
+		Select("b.*, a.id as summary_id, IF(a.invoice_id >0, 1,0) as sort_invoice_id, IF(a.payment_id >0, 1,0) as sort_payment_id, COALESCE(SUM( c.amount ),0) AS invoiced_amount_count,COALESCE(SUM( d.amount ),0) AS payment_amount_count "+
+			" ,c.invoice_time ", "c.origin_amount AS summary_invoice_amount", "d.origin_amount AS summary_payment_amount", "a.invoice_id", "a.payment_id").
+		Joins("JOIN contract_register AS b ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("id")
+
+	nq := global.DEFAULT_MYSQL.Table("(?) AS e", query).
+		Select("*").Where(" e.invoiced_amount_count <> 0 AND e.invoice_id <> 0 AND ( e.summary_invoice_amount > e.summary_payment_amount OR e.summary_payment_amount IS NULL ) ")
+	nq.Count(&count)
+	if len(page.GetOrderItemsString()) > 0 {
+		nq = nq.Order(page.GetOrderItemsString())
+	}
+	err = nq.Limit(int(page.GetPageSize())).Offset(int(page.Offset())).Find(&results).Error
+	if err != nil {
+		return
+	}
+	return
+}
+
+// NotInvoicePaymentCensusResp 未开票到款到款统计响应体
+type NotInvoicePaymentCensusResp struct {
+	DataList                []*NotPaymentCensusItem     `json:"data_list"`
+	InvoiceTotal            float64                     `json:"invoice_total" description:"开票总金额(换算后)"`
+	PaymentTotal            float64                     `json:"payment_total" description:"到款总金额(换算后)"`
+	InvoiceCurrencyTotal    []*InvoiceListCurrencyTotal `json:"invoice_currency_total" description:"开票-分币种总金额"`
+	PaymentCurrencyTotal    []*InvoiceListCurrencyTotal `json:"payment_currency_total" description:"到款-分币种总金额"`
+	NotInvoiceTotal         float64                     `json:"not_invoice_total" description:"未开票总金额(换算后)"`
+	NotInvoiceCurrencyTotal []*InvoiceListCurrencyTotal `json:"not_invoice_currency_total" description:"未开票-分币种总金额"`
+	NotPaymentTotal         float64                     `json:"not_payment_total" description:"未开票总金额(换算后)"`
+	NotPaymentCurrencyTotal []*InvoiceListCurrencyTotal `json:"not_payment_currency_total" description:"未开票-分币种总金额"`
+}
+
 type IncomeSummaryItemList []*IncomeSummaryItem
 
 func (c IncomeSummaryItemList) Len() int {
@@ -221,4 +294,75 @@ func (c IncomeSummaryItemList) Less(i, j int) bool {
 
 func (c IncomeSummaryItemList) Swap(i, j int) {
 	c[i], c[j] = c[j], c[i]
-}
+}
+
+type NotInvoicePaymentSummaryItem struct {
+	SummaryId              int       `json:"summary_id" description:"汇总ID"`
+	RegisterId             int       `json:"register_id" description:"登记ID"`
+	NewCompany             int       `json:"new_company" description:"是否为新客户: 0-否; 1-是"`
+	InvoiceId              int       `json:"invoice_id" description:"开票ID"`
+	InvoiceDate            time.Time `json:"invoice_time" description:"开票日期"`
+	InvoiceAmount          float64   `json:"invoice_amount" description:"开票金额"`
+	SellerGroupId          int       `json:"seller_group_id" description:"销售组别ID"`
+	SellerGroupName        string    `json:"seller_group_name" description:"销售组别名称"`
+	RaiSellerGroupId       int       `json:"rai_seller_group_id" description:"销售组别ID"`
+	RaiSellerGroupName     string    `json:"rai_seller_group_name" description:"销售组别名称"`
+	PaymentId              int       `json:"payment_id" description:"到款ID"`
+	PaymentDate            time.Time `json:"payment_date" description:"到款日期"`
+	PaymentAmount          float64   `json:"payment_amount" description:"到款金额"`
+	PayType                int       `json:"pay_type" description:"付款方式:0-无;1-年付;2-半年付;3-季付;4-次付;5-异常"`
+	ServiceProductId       int       `json:"service_product_id" description:"套餐类型:1ficc套餐,2权益套餐"`
+	ContractAmount         float64   `gorm:"column:contract_amount" json:"contract_amount" description:"合同金额"`
+	InvoicedAmount         float64   `gorm:"column:invoiced_amount" json:"invoiced_amount" description:"开票金额"`
+	CurrencyUnit           string    `gorm:"column:currency_unit" json:"currency_unit" description:"货币国际代码"`
+	RMBRate                float64   `gorm:"column:rmb_rate" json:"rmb_rate" description:"人民币汇率(create_time当日)"`
+	PaymentAmountTotal     float64   `gorm:"column:payment_amount_total" json:"payment_amount_total" description:"合同金额"`
+	InvoiceAmountTotal     float64   `gorm:"column:invoice_amount_total" json:"invoice_amount_total" description:"开票金额"`
+	NotInvoicedAmountTotal float64   ` json:"not_invoiced_amount_total" description:"未开票金额"`
+	SellerType             string    `json:"seller_type" description:"销售类型"`
+	ContractRegister
+}
+
+// GetNotInvoicePaymentCensusSummaryData 获取商品到款统计列表-汇总数据
+func GetNotInvoicePaymentCensusSummaryData(condition string, pars []interface{}) (results []*NotInvoicePaymentSummaryItem, err error) {
+	fields := []string{"a.id AS summary_id", "a.register_id", "a.invoice_id", "a.payment_id", "a.service_product_id", "b.*",
+		"c.origin_amount AS invoice_amount", "c.invoice_time AS invoice_date", "d.origin_amount AS payment_amount", "d.invoice_time AS payment_date",
+		"d.pay_type", "COALESCE(SUM( c.origin_amount ),0) AS invoice_amount_total", "COALESCE(SUM( d.origin_amount ),0) AS payment_amount_total",
+	}
+	query := global.DEFAULT_MYSQL.Table("contract_register AS b").
+		Select(strings.Join(fields, ",")).
+		Joins("left JOIN invoice_payment_summary AS a ON a.register_id = b.contract_register_id  AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("a.register_id,service_product_id")
+	query.Find(&results)
+	return
+}
+
+// GetNoInvoicePaymentCensusData
+func GetNoInvoicePaymentCensusData(condition string, pars []interface{}) (results []*NotInvoicePaymentSummaryItem, err error) {
+	query := global.DEFAULT_MYSQL.Table("contract_register AS b").
+		Select("*").
+		Where(condition, pars...).Group("contract_register_id")
+	query.Find(&results)
+	return
+}
+
+// GetInvoiceCensusList 获取未开票统计列表
+func GetInvoiceCensusList(condition string, pars []interface{}) (results []*InvoiceSummary, err error) {
+	query := global.DEFAULT_MYSQL.Table("contract_register AS b").
+		Select("b.*, a.id as summary_id, IF(a.invoice_id >0, 1,0) as sort_invoice_id, IF(a.payment_id >0, 1,0) as sort_payment_id, COALESCE(SUM( c.amount ),0) AS invoiced_amount_count,COALESCE(SUM( d.amount ),0) AS payment_amount_count,a.service_product_id,c.origin_amount AS invoice_origin,d.origin_amount AS payment_origin ").
+		Joins("left JOIN invoice_payment_summary AS a ON a.register_id = b.contract_register_id AND b.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS c ON a.invoice_id = c.contract_invoice_id AND c.is_deleted = 0").
+		Joins("LEFT JOIN contract_invoice AS d ON a.payment_id = d.contract_invoice_id AND d.is_deleted = 0").
+		Where(condition, pars...).Group("contract_register_id,service_product_id")
+
+	nq := global.DEFAULT_MYSQL.Table("(?) AS e", query).
+		Select("*").Where(" e.invoiced_amount_count <>  e.contract_amount ")
+
+	err = nq.Find(&results).Error
+	if err != nil {
+		return
+	}
+	return
+}

+ 3 - 0
routers/census.go

@@ -11,8 +11,11 @@ func InitCensus(rg *gin.RouterGroup) {
 	inv := new(census.InvoicePaymentController)
 	invGroup := rg.Group("invoice_payment/").Use(middleware.Token())
 	invGroup.GET("list", inv.List)
+	invGroup.GET("not_invoice/list", inv.NotInvoiceList)
+	invGroup.GET("not_payment/list", inv.NotPaymentList)
 	invGroup.GET("income/list", inv.IncomeList)
 
+
 	// 销售
 	sel := new(census.SellerController)
 	selGroup := rg.Group("seller/").Use(middleware.Token())