package service import ( "aps_crm/constvar" "aps_crm/model" "aps_crm/pkg/ecode" "errors" "github.com/shopspring/decimal" "gorm.io/gorm" ) type SalesRefundService struct{} func (SalesRefundService) AddSalesRefund(salesRefund *model.SalesRefund) int { salesReturnRecord, err := model.NewSalesReturnSearch().SetId(salesRefund.SalesReturnId).SetPreload(true).First() if err != nil { return ecode.SalesReturnNotExist } if code := CheckProduct(salesReturnRecord.Products, salesRefund.Products); code != ecode.OK { return code } var amount decimal.Decimal for _, product := range salesRefund.Products { amount = amount.Add(product.Amount.Mul(product.Price)) } code := ecode.OK err = model.WithTransaction(func(db *gorm.DB) error { err = model.NewSalesRefundSearch().Create(salesRefund) if err != nil { code = ecode.DBErr return err } salesReturnRecord.AmountHasRefund = salesReturnRecord.AmountHasRefund.Add(amount).Round(2) if salesReturnRecord.AmountHasRefund.GreaterThan(salesReturnRecord.AmountTotal) { code = ecode.SalesRefundProductBeyondTotalAmount return errors.New("退货产品对应总价超出应退总价") } salesReturnRecord.AmountShouldRefund = salesReturnRecord.AmountTotal.Sub(salesReturnRecord.AmountHasRefund).Round(2) err = model.NewSalesReturnSearch().SetId(salesRefund.SalesReturnId).Update(salesReturnRecord) if err != nil { code = ecode.DBErr return err } return nil }) if err != nil { return code } return ecode.OK } func CheckProduct(returnProducts, refundProducts []*model.Product) int { returnProductsMap := make(map[uint]*model.Product, len(returnProducts)) for _, product := range returnProducts { returnProductsMap[product.Id] = product } for _, product := range refundProducts { if returnProductsMap[product.Id] == nil { return ecode.SalesRefundProductNotExist } if !returnProductsMap[product.Id].Price.Equal(product.Price) || product.Amount.GreaterThan(returnProductsMap[product.Id].Amount) { return ecode.SalesRefundProductPriceOrAmountErr } } return ecode.OK } func (slf SalesRefundService) DeleteSalesRefund(id int) int { refund, err := model.NewSalesRefundSearch().SetId(id).First() if err != nil { return ecode.SalesRefundNotExist } salesReturnRecord, err := model.NewSalesReturnSearch().SetId(refund.SalesReturnId).SetPreload(true).First() if err != nil { return ecode.SalesReturnNotExist } var amount decimal.Decimal for _, product := range refund.Products { amount = amount.Add(product.Amount.Mul(product.Price)) } err = model.WithTransaction(func(db *gorm.DB) error { err = model.NewSalesRefundSearch().SetId(id).Delete() if err != nil { return err } salesReturnRecord.AmountHasRefund = salesReturnRecord.AmountHasRefund.Sub(amount).Round(2) salesReturnRecord.AmountShouldRefund = salesReturnRecord.AmountTotal.Sub(salesReturnRecord.AmountHasRefund).Round(2) err = model.NewSalesReturnSearch().SetId(refund.SalesReturnId).Update(salesReturnRecord) if err != nil { return err } return nil }) if err != nil { return ecode.SalesRefundNotExist } return ecode.OK } func (slf SalesRefundService) BatchDeleteSalesRefund(ids []int) (failIds []int, code int) { for _, id := range ids { code = slf.DeleteSalesRefund(id) if code != ecode.OK { failIds = append(failIds, id) } } return failIds, code } func (SalesRefundService) UpdateSalesRefund(salesRefund *model.SalesRefund) int { // check salesRefund exist oldRefund, err := model.NewSalesRefundSearch().SetId(salesRefund.Id).First() if err != nil { return ecode.SalesRefundNotExist } salesReturnRecord, err := model.NewSalesReturnSearch().SetId(salesRefund.SalesReturnId).SetPreload(true).First() if err != nil { return ecode.SalesReturnNotExist } if code := CheckProduct(salesReturnRecord.Products, salesRefund.Products); code != ecode.OK { return code } var diffAmount decimal.Decimal for _, product := range salesRefund.Products { diffAmount = diffAmount.Add(product.Amount.Mul(product.Price)) } for _, product := range oldRefund.Products { diffAmount = diffAmount.Sub(product.Amount.Mul(product.Price)) } code := ecode.OK err = model.WithTransaction(func(db *gorm.DB) error { err = model.NewSalesRefundSearch().SetId(salesRefund.Id).Update(salesRefund) if err != nil { code = ecode.DBErr return err } salesReturnRecord.AmountHasRefund = salesReturnRecord.AmountHasRefund.Sub(diffAmount).Round(2) salesReturnRecord.AmountShouldRefund = salesReturnRecord.AmountTotal.Sub(salesReturnRecord.AmountHasRefund).Round(2) if salesReturnRecord.AmountHasRefund.GreaterThan(salesReturnRecord.AmountTotal) { code = ecode.SalesRefundProductBeyondTotalAmount return errors.New("退货产品对应总价超出应退总价") } err = model.NewSalesReturnSearch().SetId(salesRefund.SalesReturnId).Update(salesReturnRecord) if err != nil { code = ecode.DBErr return err } return nil }) if err != nil { return code } return ecode.OK } func (SalesRefundService) GetSalesRefundList(page, pageSize int, keywordType constvar.SalesRefundKeywordType, keyword string, sourceId int, memberIds []int) ([]*model.SalesRefund, int64, int) { // get contact list contacts, total, err := model.NewSalesRefundSearch(). SetKeywordType(keywordType). SetKeyword(keyword). SetSourceId(sourceId). SetPreload(true). SetMemberIds(memberIds). SetPage(page, pageSize).FindAll() if err != nil { return nil, 0, ecode.SalesRefundListErr } return contacts, total, ecode.OK } func (SalesRefundService) GetSalesRefundListByIds(ids []int) ([]*model.SalesRefund, int) { // get contact list salesRefunds, err := model.NewSalesRefundSearch(). SetIds(ids). Find() if err != nil { return nil, ecode.SalesReturnListErr } return salesRefunds, ecode.OK }