123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- package fms
- import (
- "fmt"
- "github.com/shopspring/decimal"
- "hongze/fms_api/models/crm"
- "hongze/fms_api/models/fms"
- "hongze/fms_api/services/alarm_msg"
- "hongze/fms_api/utils"
- "strconv"
- "time"
- )
- // CalculateContractPaymentType 计算到款登记付款方式
- // 计算公式: 到款金额 / ( 合同金额 / round( (合同结束日期 - 合同开始日期) / 365) )
- func CalculateContractPaymentType(paymentAmount, contractAmount, dayDiff float64) (payEnum int) {
- payEnum = fms.ContractPaymentPayTypeAbnormal // 默认异常
- if paymentAmount <= 0 || contractAmount <= 0 || dayDiff <= 0 {
- return
- }
- // 年份四舍五入
- days := decimal.NewFromFloat(dayDiff)
- yearDays := decimal.NewFromFloat(365)
- yearRound := days.DivRound(yearDays, 2)
- if yearRound.IsZero() {
- return
- }
- years := yearRound.Add(decimal.NewFromFloat(0.5)).Floor()
- if years.IsZero() {
- return
- }
- // 分母
- contractDec := decimal.NewFromFloat(contractAmount)
- contractDeno := contractDec.DivRound(years, 2)
- if contractDeno.IsZero() {
- return
- }
- paymentDec := decimal.NewFromFloat(paymentAmount)
- // 结果
- resultDec := paymentDec.DivRound(contractDeno, 2)
- // 标准比例
- yearPay := decimal.NewFromFloat(1)
- halfYearPay := decimal.NewFromFloat(0.5)
- quarterPay := decimal.NewFromFloat(0.25)
- zeroPay := decimal.NewFromFloat(0)
- payEnum = fms.ContractPaymentPayTypeOther
- // 异常
- if yearPay.LessThan(resultDec) || resultDec.LessThanOrEqual(zeroPay) {
- payEnum = fms.ContractPaymentPayTypeAbnormal
- return
- }
- // 年付
- if resultDec.Equal(yearPay) {
- payEnum = fms.ContractPaymentPayTypeYear
- return
- }
- // 半年付
- if resultDec.Equal(halfYearPay) {
- payEnum = fms.ContractPaymentPayTypeHalfYear
- return
- }
- // 季付
- if resultDec.Equal(quarterPay) {
- payEnum = fms.ContractPaymentPayTypeQuarter
- return
- }
- return
- }
- // MergeInvoiceList2InvoicePaymentCensusInfo 合同登记-合并开票到款列表
- func MergeInvoiceList2InvoicePaymentCensusInfo(invoiceList []*fms.ContractInvoice, paymentList []*fms.ContractInvoice, serviceList []*fms.ContractService, serviceAmountList []*fms.ContractPaymentServiceAmount) (mergeList []*fms.InvoicePaymentCensusInfo) {
- invoiceLen := len(invoiceList)
- paymentLen := len(paymentList)
- if invoiceLen == 0 && paymentLen == 0 {
- return
- }
- // 到款套餐分配信息
- amountMap := make(map[string]*fms.ContractPaymentServiceAmount)
- for i := range serviceAmountList {
- k := fmt.Sprintf("%d-%d", serviceAmountList[i].ContractPaymentId, serviceAmountList[i].ServiceTemplateId)
- amountMap[k] = serviceAmountList[i]
- }
- serviceAmountMap := make(map[int][]*fms.ContractPaymentServiceAmountItem)
- for i := range paymentList {
- l := make([]*fms.ContractPaymentServiceAmountItem, 0)
- for ii := range serviceList {
- v := new(fms.ContractPaymentServiceAmountItem)
- v.ServiceTemplateId = serviceList[ii].ServiceTemplateId
- v.ServiceTemplateName = serviceList[ii].Title
- k := fmt.Sprintf("%d-%d", paymentList[i].ContractInvoiceId, serviceList[ii].ServiceTemplateId)
- a := amountMap[k]
- if a != nil {
- v.ContractPaymentServiceAmountId = a.ContractPaymentServiceAmountId
- v.ContractPaymentId = a.ContractPaymentId
- v.Amount = a.Amount
- }
- l = append(l, v)
- }
- serviceAmountMap[paymentList[i].ContractInvoiceId] = l
- }
- // 开票和到款列表, 条数多的为最后的合并条数
- mergeList = make([]*fms.InvoicePaymentCensusInfo, 0)
- if invoiceLen >= paymentLen {
- for i := range invoiceList {
- v := new(fms.InvoicePaymentCensusInfo)
- v.InvoiceId = invoiceList[i].ContractInvoiceId
- v.InvoiceDate = invoiceList[i].InvoiceDate.Format(utils.FormatDate)
- v.InvoiceAmount = invoiceList[i].OriginAmount
- v.SellerId = invoiceList[i].SellerId
- v.SellerName = invoiceList[i].SellerName
- v.SellerGroupId = invoiceList[i].SellerGroupId
- v.SellerGroupName = invoiceList[i].SellerGroupName
- // 直接取对应键的到款列表
- if i+1 <= paymentLen {
- payItem := paymentList[i]
- if payItem != nil {
- v.PaymentId = payItem.ContractInvoiceId
- v.PaymentDate = payItem.InvoiceDate.Format(utils.FormatDate)
- v.PaymentAmount = payItem.OriginAmount
- v.PayType = payItem.PayType
- v.ServiceAmountList = serviceAmountMap[payItem.ContractInvoiceId]
- }
- }
- mergeList = append(mergeList, v)
- }
- return
- }
- // 到款多于开票
- if paymentLen > invoiceLen {
- for i := range paymentList {
- v := new(fms.InvoicePaymentCensusInfo)
- v.PaymentId = paymentList[i].ContractInvoiceId
- v.PaymentDate = paymentList[i].InvoiceDate.Format(utils.FormatDate)
- v.PaymentAmount = paymentList[i].OriginAmount
- v.PayType = paymentList[i].PayType
- v.ServiceAmountList = serviceAmountMap[paymentList[i].ContractInvoiceId]
- // 直接取对应键的开票
- if i+1 <= invoiceLen {
- invoiceItem := invoiceList[i]
- if invoiceItem != nil {
- v.InvoiceId = invoiceItem.ContractInvoiceId
- v.InvoiceDate = invoiceItem.InvoiceDate.Format(utils.FormatDate)
- v.InvoiceAmount = invoiceItem.OriginAmount
- v.SellerId = invoiceItem.SellerId
- v.SellerName = invoiceItem.SellerName
- v.SellerGroupId = invoiceList[i].SellerGroupId
- v.SellerGroupName = invoiceList[i].SellerGroupName
- }
- }
- mergeList = append(mergeList, v)
- }
- return
- }
- return
- }
- // SummaryInvoicePaymentByContractRegisterId 汇总合同登记的开票到款, 即一一进行对应存入汇总表
- func SummaryInvoicePaymentByContractRegisterId(registerId int) {
- var err error
- defer func() {
- if err != nil {
- alarm_msg.SendAlarmMsg(fmt.Sprintf("汇总开票到款失败, ErrMsg: \n%s", err.Error()), 3)
- }
- }()
- // 获取开票到款信息
- cond := `contract_register_id = ?`
- pars := make([]interface{}, 0)
- pars = append(pars, registerId)
- list, e := fms.GetContractInvoiceItemList(cond, pars)
- if e != nil {
- err = fmt.Errorf("获取开票到款列表失败, Err: %s", e.Error())
- return
- }
- ficcInvoiceIds := make([]int, 0)
- ficcPaymentIds := make([]int, 0)
- raiInvoiceIds := make([]int, 0)
- raiPaymentIds := make([]int, 0)
- noProductPaymentIds := make([]int, 0)
- for i := range list {
- if list[i].InvoiceType == fms.ContractInvoiceTypeMake {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcInvoiceIds = append(ficcInvoiceIds, list[i].ContractInvoiceId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiInvoiceIds = append(raiInvoiceIds, list[i].ContractInvoiceId)
- }
- continue
- }
- if list[i].InvoiceType == fms.ContractInvoiceTypePay {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcPaymentIds = append(ficcPaymentIds, list[i].ContractInvoiceId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiPaymentIds = append(raiPaymentIds, list[i].ContractInvoiceId)
- }
- continue
- }
- if list[i].InvoiceType == fms.ContractInvoiceTypePreMake {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcInvoiceIds = append(ficcInvoiceIds, list[i].ContractInvoiceId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiInvoiceIds = append(raiInvoiceIds, list[i].ContractInvoiceId)
- }
- continue
- }
- if list[i].InvoiceType == fms.ContractInvoiceTypePrePay {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcPaymentIds = append(ficcPaymentIds, list[i].ContractInvoiceId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiPaymentIds = append(raiPaymentIds, list[i].ContractInvoiceId)
- } else {
- noProductPaymentIds = append(noProductPaymentIds, list[i].ContractInvoiceId)
- }
- continue
- }
- }
- ficcInvoiceLen := len(ficcInvoiceIds)
- raiInvoiceLen := len(raiInvoiceIds)
- ficcPaymentLen := len(ficcPaymentIds)
- raiPaymentLen := len(raiPaymentIds)
- noProductPaymentLen := len(noProductPaymentIds)
- // 汇总数据
- nowTime := time.Now().Local()
- summaryList := make([]*fms.InvoicePaymentSummary, 0)
- // ficc
- if ficcInvoiceLen >= ficcPaymentLen {
- for i := range ficcInvoiceIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.InvoiceId = ficcInvoiceIds[i]
- v.ServiceProductId = crm.CompanyProductFicc
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的到款ID
- if i+1 <= ficcPaymentLen {
- v.PaymentId = ficcPaymentIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- if ficcPaymentLen > ficcInvoiceLen {
- for i := range ficcPaymentIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.PaymentId = ficcPaymentIds[i]
- v.ServiceProductId = crm.CompanyProductFicc
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的开票ID
- if i+1 <= ficcInvoiceLen {
- v.InvoiceId = ficcInvoiceIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- // rai
- if raiInvoiceLen >= raiPaymentLen {
- for i := range raiInvoiceIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.InvoiceId = raiInvoiceIds[i]
- v.ServiceProductId = crm.CompanyProductRai
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的到款ID
- if i+1 <= raiPaymentLen {
- v.PaymentId = raiPaymentIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- if raiPaymentLen > raiInvoiceLen {
- for i := range raiPaymentIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.PaymentId = raiPaymentIds[i]
- v.ServiceProductId = crm.CompanyProductRai
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的开票ID
- if i+1 <= raiInvoiceLen {
- v.InvoiceId = raiInvoiceIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- if noProductPaymentLen > 0 {
- for i := range noProductPaymentIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.PaymentId = noProductPaymentIds[i]
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- summaryList = append(summaryList, v)
- }
- }
- // 删除并新增汇总数据
- summaryOB := new(fms.InvoicePaymentSummary)
- if e = summaryOB.DeleteAndCreate(registerId, summaryList); e != nil {
- err = fmt.Errorf("新增汇总数据失败, Err: %s", e.Error())
- }
- return
- }
- // CalculatePaymentServiceAmount
- func CalculatePaymentServiceAmount(registerId int) (err error) {
- // todo 判断是否符合均分金额的条件,如果符合,需要生成金额分配记录表
- // 查询所有的到款记录,如果没有到款记录则无需分配到款金额
- cond := `contract_register_id = ? and invoice_type=2 and service_product_id=2`
- pars := make([]interface{}, 0)
- pars = append(pars, registerId)
- paymentList, err := fms.GetContractInvoiceItemList(cond, pars)
- if err != nil {
- err = fmt.Errorf("获取开票到款列表失败, Err: %s", err.Error())
- return
- }
- if len(paymentList) == 0 {
- return
- }
- var contractPaymentIds []int
- for _, v := range paymentList {
- contractPaymentIds = append(contractPaymentIds, v.ContractInvoiceId)
- }
- // 获取服务套餐
- servicesList, err := fms.GetContractServiceAndDetailList(registerId)
- if err != nil {
- err = fmt.Errorf("获取服务套餐失败, Err: " + err.Error())
- return
- }
- industrySlice := []string{
- "行业套餐",
- "医药",
- "消费",
- "科技",
- "智造",
- "策略",
- "主观",
- "客观",
- }
- unNeedAsign := false
- industryFlag := false
- servicesListMap := make(map[int]*fms.ContractServiceAndDetail)
- // 判断当前套餐是否符合分配规则
- for _, v := range servicesList {
- if v.ProductId == crm.CompanyProductRai {
- industryFlag = true
- }
- servicesListMap[v.ServiceTemplateId] = v
- if v.ProductId == crm.CompanyProductRai && !utils.InArray(v.Title, industrySlice) {
- unNeedAsign = true
- }
- }
- if unNeedAsign || !industryFlag {
- //不符合自动分配规则,则直接删除之前的自动分配记录
- err = fms.DeletePaymentServiceAmountByRegisterId(registerId)
- if err != nil {
- return
- }
- return
- } else {
- //遍历所有的到款记录,筛选出需要删除并新增的到款记录ID
- _, serviceFormatMap, e := GetContractServiceNameFormat([]int{registerId})
- if e != nil {
- err = fmt.Errorf("获取合同套餐失败, Err: %s", e.Error())
- return
- }
- servicesFormatList, ok := serviceFormatMap[registerId]
- if !ok {
- err = fmt.Errorf("查不到合同套餐")
- return
- }
- servicesFormatStr := ""
- length := 0
- for _, v := range servicesFormatList {
- if servicesListMap[v.ServiceTemplateId].ProductId == crm.CompanyProductRai {
- length++
- servicesFormatStr += fmt.Sprintf("%d_", v.ServiceTemplateId)
- }
- }
- if length == 0 {
- return
- }
- payAverageAmountMap := make(map[int]float64)
- for _, v := range paymentList {
- payAverageAmountMap[v.ContractInvoiceId] = v.Amount / float64(length)
- payAverageAmountMap[v.ContractInvoiceId], _ = strconv.ParseFloat(fmt.Sprintf("%.2f", payAverageAmountMap[v.ContractInvoiceId]), 64)
- }
- //查询原来的金额分配记录
- serviceAmountCond := `contract_payment_id = ? and contract_payment_id in ?`
- serviceAmountPars := make([]interface{}, 0)
- serviceAmountPars = append(serviceAmountPars, registerId, contractPaymentIds)
- serviceAmountOB := new(fms.ContractPaymentServiceAmount)
- serviceAmountList, e := serviceAmountOB.List(serviceAmountCond, serviceAmountPars)
- if e != nil {
- err = fmt.Errorf("获取到款套餐分配列表失败, Err: %s", e.Error())
- return
- }
- oldPaymentServiceMap := make(map[int]string)
- oldPaymentAmountMap := make(map[int]float64)
- for _, v := range serviceAmountList {
- oldPaymentServiceMap[v.ContractPaymentId] += fmt.Sprintf("%d_", v.ServiceTemplateId)
- oldPaymentAmountMap[v.ContractPaymentId] = v.Amount
- }
- var newPaymentIds []int
- for _, v := range paymentList {
- if _, ok1 := oldPaymentServiceMap[v.ContractInvoiceId]; !ok1 {
- newPaymentIds = append(newPaymentIds, v.ContractInvoiceId)
- continue
- }
- if oldPaymentServiceMap[v.ContractInvoiceId] != servicesFormatStr {
- newPaymentIds = append(newPaymentIds, v.ContractInvoiceId)
- continue
- }
- if oldPaymentAmountMap[v.ContractInvoiceId] != payAverageAmountMap[v.ContractInvoiceId] {
- newPaymentIds = append(newPaymentIds, v.ContractInvoiceId)
- continue
- }
- }
- // 删除旧的金额分配记录并生成新的自动分配记录
- if len(newPaymentIds) == 0 {
- return
- }
- for _, v := range newPaymentIds {
- addList := make([]*fms.ContractPaymentServiceAmount, 0)
- for _, f := range servicesFormatList {
- if servicesListMap[f.ServiceTemplateId].ProductId == crm.CompanyProductRai {
- t := &fms.ContractPaymentServiceAmount{
- ContractRegisterId: registerId,
- ContractPaymentId: v,
- ServiceTemplatePid: f.ServiceTemplatePid,
- ServiceTemplateId: f.ServiceTemplateId,
- Amount: payAverageAmountMap[v],
- InitType: 1,
- }
- t.Set()
- addList = append(addList, t)
- }
- }
- if e := fms.CreatePaymentServiceAmount(registerId, v, addList); e != nil {
- err = fmt.Errorf("新增到款套餐金额失败, Err: " + e.Error())
- return
- }
- }
- }
- return
- }
- // SummaryInvoicePaymentByPreRegister 预登记时汇总
- func SummaryInvoicePaymentByPreRegister(registerId int) {
- var err error
- defer func() {
- if err != nil {
- alarm_msg.SendAlarmMsg(fmt.Sprintf("汇总开票到款失败, ErrMsg: \n%s", err.Error()), 3)
- }
- }()
- // 获取开票到款信息
- cond := `contract_register_id = ?`
- pars := make([]interface{}, 0)
- pars = append(pars, registerId)
- list, e := fms.GetContractPreRegisterItemList(cond, pars)
- if e != nil {
- err = fmt.Errorf("获取开票到款列表失败, Err: %s", e.Error())
- return
- }
- ficcInvoiceIds := make([]int, 0)
- ficcPaymentIds := make([]int, 0)
- raiInvoiceIds := make([]int, 0)
- raiPaymentIds := make([]int, 0)
- for i := range list {
- if list[i].InvoiceType == fms.ContractInvoiceTypePreMake {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcInvoiceIds = append(ficcInvoiceIds, list[i].PreRegisterId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiInvoiceIds = append(raiInvoiceIds, list[i].PreRegisterId)
- }
- continue
- }
- if list[i].InvoiceType == fms.ContractInvoiceTypePrePay {
- if list[i].ServiceProductId == crm.CompanyProductFicc {
- ficcPaymentIds = append(ficcPaymentIds, list[i].PreRegisterId)
- } else if list[i].ServiceProductId == crm.CompanyProductRai {
- raiPaymentIds = append(raiPaymentIds, list[i].PreRegisterId)
- }
- continue
- }
- }
- ficcInvoiceLen := len(ficcInvoiceIds)
- raiInvoiceLen := len(raiInvoiceIds)
- ficcPaymentLen := len(ficcPaymentIds)
- raiPaymentLen := len(raiPaymentIds)
- // 汇总数据
- nowTime := time.Now().Local()
- summaryList := make([]*fms.InvoicePaymentSummary, 0)
- // ficc
- if ficcInvoiceLen >= ficcPaymentLen {
- for i := range ficcInvoiceIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.InvoiceId = ficcInvoiceIds[i]
- v.ServiceProductId = crm.CompanyProductFicc
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的到款ID
- if i+1 <= ficcPaymentLen {
- v.PaymentId = ficcPaymentIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- if ficcPaymentLen > ficcInvoiceLen {
- for i := range ficcPaymentIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.PaymentId = ficcPaymentIds[i]
- v.ServiceProductId = crm.CompanyProductFicc
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的开票ID
- if i+1 <= ficcInvoiceLen {
- v.InvoiceId = ficcInvoiceIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- // rai
- if raiInvoiceLen >= raiPaymentLen {
- for i := range raiInvoiceIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.InvoiceId = raiInvoiceIds[i]
- v.ServiceProductId = crm.CompanyProductRai
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的到款ID
- if i+1 <= raiPaymentLen {
- v.PaymentId = raiPaymentIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- if raiPaymentLen > raiInvoiceLen {
- for i := range raiPaymentIds {
- v := new(fms.InvoicePaymentSummary)
- v.RegisterId = registerId
- v.PaymentId = raiPaymentIds[i]
- v.ServiceProductId = crm.CompanyProductRai
- v.CreateTime = nowTime
- v.ModifyTime = nowTime
- // 取对应key的开票ID
- if i+1 <= raiInvoiceLen {
- v.InvoiceId = raiInvoiceIds[i]
- }
- summaryList = append(summaryList, v)
- }
- }
- // 删除并新增汇总数据
- summaryOB := new(fms.InvoicePaymentSummary)
- if e = summaryOB.DeleteAndCreate(registerId, summaryList); e != nil {
- err = fmt.Errorf("新增汇总数据失败, Err: %s", e.Error())
- }
- return
- }
|