|
@@ -6,6 +6,7 @@ import (
|
|
|
"fmt"
|
|
|
"github.com/gin-gonic/gin"
|
|
|
"github.com/go-playground/validator/v10"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
"github.com/tealeg/xlsx"
|
|
|
"hongze/fms_api/controller/resp"
|
|
|
"hongze/fms_api/global"
|
|
@@ -45,12 +46,12 @@ func (rg *RegisterController) List(c *gin.Context) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // TODO:代付方
|
|
|
cond := `1 = 1`
|
|
|
pars := make([]interface{}, 0)
|
|
|
+ // 合同编号/客户姓名/销售/代付方
|
|
|
if req.Keyword != "" {
|
|
|
kw := "%" + req.Keyword + "%"
|
|
|
- cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ?)`
|
|
|
+ cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ? OR pay_company_name LIKE ?)`
|
|
|
pars = append(pars, kw, kw, kw)
|
|
|
}
|
|
|
if req.StartDate != "" && req.EndDate != "" {
|
|
@@ -206,12 +207,13 @@ func (rg *RegisterController) Add(c *gin.Context) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // TODO:代付、补充协议
|
|
|
nowTime := time.Now().Local()
|
|
|
ob.ContractCode = req.ContractCode
|
|
|
+ ob.PayContractCode = req.PayContractCode
|
|
|
ob.CrmContractId = req.CrmContractId
|
|
|
ob.ContractSource = req.ContractSource
|
|
|
ob.CompanyName = req.CompanyName
|
|
|
+ ob.PayCompanyName = req.PayCompanyName
|
|
|
ob.ProductId = req.ProductId
|
|
|
ob.SellerId = req.SellerId
|
|
|
ob.SellerName = req.SellerName
|
|
@@ -225,6 +227,10 @@ func (rg *RegisterController) Add(c *gin.Context) {
|
|
|
ob.RegisterStatus = fms.ContractRegisterStatusIng
|
|
|
ob.Remark = req.Remark
|
|
|
ob.Set()
|
|
|
+ // 补充协议直接完成
|
|
|
+ if req.ContractType == fms.ContractTypePlus {
|
|
|
+ ob.RegisterStatus = fms.ContractRegisterStatusComplete
|
|
|
+ }
|
|
|
|
|
|
// 套餐信息
|
|
|
serviceList, e := fmsService.HandleContractServiceAndDetail(req.ProductId, req.Services, true)
|
|
@@ -326,9 +332,11 @@ func (rg *RegisterController) Edit(c *gin.Context) {
|
|
|
|
|
|
nowTime := time.Now().Local()
|
|
|
item.ContractCode = req.ContractCode
|
|
|
+ item.PayContractCode = req.PayContractCode
|
|
|
item.CrmContractId = req.CrmContractId
|
|
|
item.ContractSource = req.ContractSource
|
|
|
item.CompanyName = req.CompanyName
|
|
|
+ item.PayCompanyName = req.PayCompanyName
|
|
|
item.SellerId = req.SellerId
|
|
|
item.SellerName = req.SellerName
|
|
|
item.ContractType = req.ContractType
|
|
@@ -339,6 +347,10 @@ func (rg *RegisterController) Edit(c *gin.Context) {
|
|
|
item.AgreedPayTime = req.AgreedPayTime
|
|
|
item.ContractStatus = req.ContractStatus
|
|
|
item.RegisterStatus = fms.ContractRegisterStatusIng
|
|
|
+ // 补充协议直接完成
|
|
|
+ if req.ContractType == fms.ContractTypePlus {
|
|
|
+ item.RegisterStatus = fms.ContractRegisterStatusComplete
|
|
|
+ }
|
|
|
item.Remark = req.Remark
|
|
|
item.ModifyTime = nowTime
|
|
|
updateCols := []string{
|
|
@@ -360,8 +372,10 @@ func (rg *RegisterController) Edit(c *gin.Context) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 校验金额-是否修改状态
|
|
|
- go fmsService.CheckContractRegisterAmount(item.ContractRegisterId)
|
|
|
+ // 非补充协议校验金额-是否修改状态
|
|
|
+ if item.ContractType != fms.ContractTypePlus {
|
|
|
+ go fmsService.CheckContractRegisterAmount(item.ContractRegisterId)
|
|
|
+ }
|
|
|
|
|
|
// 操作日志
|
|
|
go func() {
|
|
@@ -561,8 +575,10 @@ func (rg *RegisterController) UpdateStatus(c *gin.Context) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 校验金额-是否修改状态
|
|
|
- go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
|
|
|
+ // 非补充协议校验金额-是否修改状态
|
|
|
+ if item.ContractType != fms.ContractTypePlus {
|
|
|
+ go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
|
|
|
+ }
|
|
|
|
|
|
// 操作日志
|
|
|
go func() {
|
|
@@ -609,6 +625,22 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
|
|
|
claims, _ := c.Get("adminInfo")
|
|
|
adminInfo := claims.(*system.SysAdmin)
|
|
|
|
|
|
+ registerOB := new(fms.ContractRegister)
|
|
|
+ item, e := registerOB.Fetch(req.ContractRegisterId)
|
|
|
+ if e != nil {
|
|
|
+ if e == utils.ErrNoRow {
|
|
|
+ resp.Fail("合同登记不存在或已被删除", c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ resp.FailMsg("获取合同登记失败", "Err:"+e.Error(), c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if item.ContractType == fms.ContractTypePlus {
|
|
|
+ resp.Fail("补充协议不允许添加开票/到款登记", c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ noChangeInvoiceIds := make([]int, 0)
|
|
|
newInvoice := make([]*fms.ContractInvoice, 0)
|
|
|
if len(req.AmountList) > 0 {
|
|
|
for i := range req.AmountList {
|
|
@@ -625,22 +657,84 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
|
|
|
resp.FailData("日期格式有误", "Err:"+e.Error(), c)
|
|
|
return
|
|
|
}
|
|
|
- v := &fms.ContractInvoice{
|
|
|
+ if req.AmountList[i].InvoiceId > 0 {
|
|
|
+ noChangeInvoiceIds = append(noChangeInvoiceIds, req.AmountList[i].InvoiceId)
|
|
|
+ } else {
|
|
|
+ v := &fms.ContractInvoice{
|
|
|
+ ContractRegisterId: req.ContractRegisterId,
|
|
|
+ ContractCode: item.ContractCode,
|
|
|
+ Amount: req.AmountList[i].Amount,
|
|
|
+ InvoiceType: req.InvoiceType,
|
|
|
+ InvoiceDate: t,
|
|
|
+ AdminId: int(adminInfo.AdminId),
|
|
|
+ AdminName: adminInfo.RealName,
|
|
|
+ }
|
|
|
+ v.Set()
|
|
|
+ newInvoice = append(newInvoice, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取原有的登记信息
|
|
|
+ invoiceCond := `contract_register_id = ? AND invoice_type = ?`
|
|
|
+ invoicePars := make([]interface{}, 0)
|
|
|
+ invoicePars = append(invoicePars, req.ContractRegisterId, req.InvoiceType)
|
|
|
+ originInvoiceList, e := fms.GetContractInvoiceItemList(invoiceCond, invoicePars)
|
|
|
+ if e != nil {
|
|
|
+ resp.FailMsg("获取失败", "获取开票/到款列表失败, Err: "+e.Error(), c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 比对原有和现有的登记信息
|
|
|
+ logList := make([]*fms.ContractRegisterLog, 0)
|
|
|
+ opData := ""
|
|
|
+ opDataByte, e := json.Marshal(req)
|
|
|
+ if e != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ opData = string(opDataByte)
|
|
|
+ opType := fms.ContractRegisterOpTypeInvoice
|
|
|
+ if req.InvoiceType == fms.ContractInvoiceTypePay {
|
|
|
+ opType = fms.ContractRegisterOpTypePayment
|
|
|
+ }
|
|
|
+ nowTime := time.Now().Local()
|
|
|
+ // 需要删除的记录
|
|
|
+ deleteInvoiceIds := make([]int, 0)
|
|
|
+ for i := range originInvoiceList {
|
|
|
+ if !utils.InArrayByInt(noChangeInvoiceIds, originInvoiceList[i].ContractInvoiceId) {
|
|
|
+ deleteInvoiceIds = append(deleteInvoiceIds, originInvoiceList[i].ContractInvoiceId)
|
|
|
+ logList = append(logList, &fms.ContractRegisterLog{
|
|
|
ContractRegisterId: req.ContractRegisterId,
|
|
|
- Amount: req.AmountList[i].Amount,
|
|
|
- InvoiceType: req.InvoiceType,
|
|
|
- InvoiceDate: t,
|
|
|
AdminId: int(adminInfo.AdminId),
|
|
|
AdminName: adminInfo.RealName,
|
|
|
- }
|
|
|
- v.Set()
|
|
|
- newInvoice = append(newInvoice, v)
|
|
|
+ OpData: opData,
|
|
|
+ OpType: opType,
|
|
|
+ CreateTime: nowTime,
|
|
|
+ Remark: fmt.Sprint(adminInfo.RealName, " 删除", fms.ContractInvoiceKeyNameMap[opType], "金额", originInvoiceList[i].Amount, "元"),
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
+ // 新增的记录
|
|
|
+ if len(newInvoice) > 0 {
|
|
|
+ newAmount := decimal.NewFromFloat(0).Round(2)
|
|
|
+ for i := range newInvoice {
|
|
|
+ a := decimal.NewFromFloat(newInvoice[i].Amount).Round(2)
|
|
|
+ newAmount = newAmount.Add(a)
|
|
|
+ }
|
|
|
+ ia, _ := newAmount.Round(2).Float64()
|
|
|
+ logList = append(logList, &fms.ContractRegisterLog{
|
|
|
+ ContractRegisterId: req.ContractRegisterId,
|
|
|
+ AdminId: int(adminInfo.AdminId),
|
|
|
+ AdminName: adminInfo.RealName,
|
|
|
+ OpData: opData,
|
|
|
+ OpType: opType,
|
|
|
+ CreateTime: nowTime,
|
|
|
+ Remark: fmt.Sprint(adminInfo.RealName, " 新增", fms.ContractInvoiceKeyNameMap[opType], "金额", ia, "元"),
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
// 删除并新增登记
|
|
|
ob := new(fms.ContractInvoice)
|
|
|
- if e := ob.DeleteAndCreateNewInvoice(req.ContractRegisterId, req.InvoiceType, newInvoice); e != nil {
|
|
|
+ if e := ob.DeleteAndCreateNewInvoice(req.ContractRegisterId, req.InvoiceType, deleteInvoiceIds, newInvoice); e != nil {
|
|
|
resp.FailData("日期格式有误", "Err:"+e.Error(), c)
|
|
|
return
|
|
|
}
|
|
@@ -650,25 +744,8 @@ func (rg *RegisterController) Invoice(c *gin.Context) {
|
|
|
|
|
|
// 操作日志
|
|
|
go func() {
|
|
|
- opData := ""
|
|
|
- opDataByte, e := json.Marshal(req)
|
|
|
- if e != nil {
|
|
|
- return
|
|
|
- }
|
|
|
- opData = string(opDataByte)
|
|
|
- opType := fms.ContractRegisterOpTypeInvoice
|
|
|
- if req.InvoiceType == fms.ContractInvoiceTypePay {
|
|
|
- opType = fms.ContractRegisterOpTypePayment
|
|
|
- }
|
|
|
-
|
|
|
- logItem := new(fms.ContractRegisterLog)
|
|
|
- logItem.ContractRegisterId = req.ContractRegisterId
|
|
|
- logItem.AdminId = int(adminInfo.AdminId)
|
|
|
- logItem.AdminName = adminInfo.RealName
|
|
|
- logItem.OpData = opData
|
|
|
- logItem.OpType = opType
|
|
|
- logItem.CreateTime = time.Now().Local()
|
|
|
- if e = logItem.Create(); e != nil {
|
|
|
+ logOB := new(fms.ContractRegisterLog)
|
|
|
+ if e := logOB.AddInBatches(logList); e != nil {
|
|
|
return
|
|
|
}
|
|
|
}()
|
|
@@ -808,7 +885,7 @@ func (rg *RegisterController) Export(c *gin.Context) {
|
|
|
|
|
|
// 获取开票/到款详情, 并取最大的开票/到款数(用于动态扩展第二列表头)
|
|
|
ci := new(fms.ContractInvoice)
|
|
|
- invoiceList, e := ci.List(csCond, csPars)
|
|
|
+ invoiceList, e := ci.List(csCond, csPars, "")
|
|
|
if e != nil {
|
|
|
resp.FailData("获取开票/到款列表失败", "Err:"+e.Error(), c)
|
|
|
return
|
|
@@ -950,6 +1027,7 @@ func (rg *RegisterController) Export(c *gin.Context) {
|
|
|
row2NameKeyMap[row2Title[i]] = i
|
|
|
}
|
|
|
|
|
|
+ // TODO:代付和补充协议
|
|
|
contractTMap := map[int]int{
|
|
|
fms.ContractTypeNew: 1,
|
|
|
fms.ContractTypeRenew: 0,
|
|
@@ -1078,3 +1156,168 @@ func (rg *RegisterController) Export(c *gin.Context) {
|
|
|
c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
|
http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
|
|
|
}
|
|
|
+
|
|
|
+// InvoiceList
|
|
|
+// @Title 开票/到款列表
|
|
|
+// @Description 开票/到款列表
|
|
|
+// @Param InvoiceType query int false "类型: 1-开票登记; 2-到款登记"
|
|
|
+// @Param ContractCode query string false "合同编号"
|
|
|
+// @Param StartDate query string false "开始日期"
|
|
|
+// @Param EndDate query string false "结束日期"
|
|
|
+// @Param MinAmount query float64 false "开票金额区间-最小值"
|
|
|
+// @Param MaxAmount query float64 false "开票金额区间-最大值"
|
|
|
+// @Success 200 {object} fms.ContractInvoiceItem
|
|
|
+// @router /contract/register/invoice_list [get]
|
|
|
+func (rg *RegisterController) InvoiceList(c *gin.Context) {
|
|
|
+ var req fms.ContractInvoiceListReq
|
|
|
+ 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 := `invoice_type = ?`
|
|
|
+ pars := make([]interface{}, 0)
|
|
|
+ pars = append(pars, req.InvoiceType)
|
|
|
+ // 合同编号
|
|
|
+ if req.ContractCode != "" {
|
|
|
+ cond += ` AND contract_code = ?`
|
|
|
+ pars = append(pars, req.ContractCode)
|
|
|
+ }
|
|
|
+ if req.StartDate != "" && req.EndDate != "" {
|
|
|
+ st := fmt.Sprint(req.StartDate, " 00:00:00")
|
|
|
+ ed := fmt.Sprint(req.EndDate, " 23:59:59")
|
|
|
+ cond += ` AND (create_time BETWEEN ? AND ?)`
|
|
|
+ pars = append(pars, st, ed)
|
|
|
+ }
|
|
|
+ if req.MinAmount > 0 && req.MaxAmount > 0 {
|
|
|
+ cond += ` AND (amount BETWEEN ? AND ?)`
|
|
|
+ pars = append(pars, req.MinAmount, req.MaxAmount)
|
|
|
+ }
|
|
|
+
|
|
|
+ page := new(base.Page)
|
|
|
+ page.SetPageSize(req.PageSize)
|
|
|
+ page.SetCurrent(req.Current)
|
|
|
+ page.AddOrderItem(base.OrderItem{Column: "invoice_time", Asc: false})
|
|
|
+
|
|
|
+ total, list, e := fms.GetContractInvoiceItemPageList(page, cond, pars)
|
|
|
+ if e != nil {
|
|
|
+ resp.FailMsg("获取失败", "获取合同开票/到款列表失败, Err: "+e.Error(), c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ page.SetTotal(total)
|
|
|
+ baseData := new(base.BaseData)
|
|
|
+ baseData.SetPage(page)
|
|
|
+ baseData.SetList(list)
|
|
|
+ resp.OkData("获取成功", baseData, c)
|
|
|
+}
|
|
|
+
|
|
|
+// InvoiceExport
|
|
|
+// @Title 开票/到款列表-导出
|
|
|
+// @Description 合同登记-导出
|
|
|
+// @Param InvoiceType query int false "类型: 1-开票登记; 2-到款登记"
|
|
|
+// @Param ContractCode query string false "合同编号"
|
|
|
+// @Param StartDate query string false "开始日期"
|
|
|
+// @Param EndDate query string false "结束日期"
|
|
|
+// @Param MinAmount query float64 false "开票金额区间-最小值"
|
|
|
+// @Param MaxAmount query float64 false "开票金额区间-最大值"
|
|
|
+// @Success 200 string "操作成功"
|
|
|
+// @router /contract/register/invoice_export [get]
|
|
|
+func (rg *RegisterController) InvoiceExport(c *gin.Context) {
|
|
|
+ var req fms.ContractInvoiceListReq
|
|
|
+ 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 := `invoice_type = ?`
|
|
|
+ pars := make([]interface{}, 0)
|
|
|
+ pars = append(pars, req.InvoiceType)
|
|
|
+ // 合同编号
|
|
|
+ if req.ContractCode != "" {
|
|
|
+ cond += ` AND contract_code = ?`
|
|
|
+ pars = append(pars, req.ContractCode)
|
|
|
+ }
|
|
|
+ if req.StartDate != "" && req.EndDate != "" {
|
|
|
+ st := fmt.Sprint(req.StartDate, " 00:00:00")
|
|
|
+ ed := fmt.Sprint(req.EndDate, " 23:59:59")
|
|
|
+ cond += ` AND (create_time BETWEEN ? AND ?)`
|
|
|
+ pars = append(pars, st, ed)
|
|
|
+ }
|
|
|
+ if req.MinAmount > 0 && req.MaxAmount > 0 {
|
|
|
+ cond += ` AND (amount BETWEEN ? AND ?)`
|
|
|
+ pars = append(pars, req.MinAmount, req.MaxAmount)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取列表数据
|
|
|
+ cr := new(fms.ContractInvoice)
|
|
|
+ orderRule := `invoice_time DESC`
|
|
|
+ list, e := cr.List(cond, pars, orderRule)
|
|
|
+ if e != nil {
|
|
|
+ resp.FailData("获取开票/到款列表失败", "Err:"+e.Error(), c)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ 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
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表头
|
|
|
+ titleRow := sheet.AddRow()
|
|
|
+ titleRow.SetHeight(40)
|
|
|
+ cell1 := titleRow.AddCell()
|
|
|
+ cell1.SetValue("合同编号")
|
|
|
+ cell1.SetStyle(style)
|
|
|
+ cell2 := titleRow.AddCell()
|
|
|
+ cell2.SetValue("开票金额")
|
|
|
+ cell2.SetStyle(style)
|
|
|
+ cell3 := titleRow.AddCell()
|
|
|
+ cell3.SetValue("开票日期")
|
|
|
+ cell3.SetStyle(style)
|
|
|
+
|
|
|
+ for _, v := range list {
|
|
|
+ dataRow := sheet.AddRow()
|
|
|
+ dataRow.SetHeight(20)
|
|
|
+ dataRow.AddCell().SetString(v.ContractCode)
|
|
|
+ dataRow.AddCell().SetString(fmt.Sprint(v.Amount))
|
|
|
+ dataRow.AddCell().SetString(utils.TimeTransferString("2006-01-02", v.InvoiceDate))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 输出文件
|
|
|
+ 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)
|
|
|
+}
|