Files
tyapi-server/internal/domains/finance/services/user_invoice_info_service.go
2025-08-02 02:54:21 +08:00

250 lines
9.4 KiB
Go

package services
import (
"context"
"fmt"
"tyapi-server/internal/domains/finance/entities"
"tyapi-server/internal/domains/finance/repositories"
"tyapi-server/internal/domains/finance/value_objects"
"github.com/google/uuid"
)
// UserInvoiceInfoService 用户开票信息服务接口
type UserInvoiceInfoService interface {
// GetUserInvoiceInfo 获取用户开票信息
GetUserInvoiceInfo(ctx context.Context, userID string) (*entities.UserInvoiceInfo, error)
// GetUserInvoiceInfoWithEnterpriseInfo 获取用户开票信息(包含企业认证信息)
GetUserInvoiceInfoWithEnterpriseInfo(ctx context.Context, userID string, companyName, taxpayerID string) (*entities.UserInvoiceInfo, error)
// CreateOrUpdateUserInvoiceInfo 创建或更新用户开票信息
CreateOrUpdateUserInvoiceInfo(ctx context.Context, userID string, invoiceInfo *value_objects.InvoiceInfo) (*entities.UserInvoiceInfo, error)
// CreateOrUpdateUserInvoiceInfoWithEnterpriseInfo 创建或更新用户开票信息(包含企业认证信息)
CreateOrUpdateUserInvoiceInfoWithEnterpriseInfo(ctx context.Context, userID string, invoiceInfo *value_objects.InvoiceInfo, companyName, taxpayerID string) (*entities.UserInvoiceInfo, error)
// ValidateInvoiceInfo 验证开票信息
ValidateInvoiceInfo(ctx context.Context, invoiceInfo *value_objects.InvoiceInfo, invoiceType value_objects.InvoiceType) error
// DeleteUserInvoiceInfo 删除用户开票信息
DeleteUserInvoiceInfo(ctx context.Context, userID string) error
}
// UserInvoiceInfoServiceImpl 用户开票信息服务实现
type UserInvoiceInfoServiceImpl struct {
userInvoiceInfoRepo repositories.UserInvoiceInfoRepository
}
// NewUserInvoiceInfoService 创建用户开票信息服务
func NewUserInvoiceInfoService(userInvoiceInfoRepo repositories.UserInvoiceInfoRepository) UserInvoiceInfoService {
return &UserInvoiceInfoServiceImpl{
userInvoiceInfoRepo: userInvoiceInfoRepo,
}
}
// GetUserInvoiceInfo 获取用户开票信息
func (s *UserInvoiceInfoServiceImpl) GetUserInvoiceInfo(ctx context.Context, userID string) (*entities.UserInvoiceInfo, error) {
info, err := s.userInvoiceInfoRepo.FindByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("获取用户开票信息失败: %w", err)
}
// 如果没有找到开票信息记录,创建新的实体
if info == nil {
info = &entities.UserInvoiceInfo{
ID: uuid.New().String(),
UserID: userID,
CompanyName: "",
TaxpayerID: "",
BankName: "",
BankAccount: "",
CompanyAddress: "",
CompanyPhone: "",
ReceivingEmail: "",
}
}
return info, nil
}
// GetUserInvoiceInfoWithEnterpriseInfo 获取用户开票信息(包含企业认证信息)
func (s *UserInvoiceInfoServiceImpl) GetUserInvoiceInfoWithEnterpriseInfo(ctx context.Context, userID string, companyName, taxpayerID string) (*entities.UserInvoiceInfo, error) {
info, err := s.userInvoiceInfoRepo.FindByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("获取用户开票信息失败: %w", err)
}
// 如果没有找到开票信息记录,创建新的实体
if info == nil {
info = &entities.UserInvoiceInfo{
ID: uuid.New().String(),
UserID: userID,
CompanyName: companyName, // 使用企业认证信息填充
TaxpayerID: taxpayerID, // 使用企业认证信息填充
BankName: "",
BankAccount: "",
CompanyAddress: "",
CompanyPhone: "",
ReceivingEmail: "",
}
} else {
// 如果已有记录,使用传入的企业认证信息覆盖公司名称和纳税人识别号
if companyName != "" {
info.CompanyName = companyName
}
if taxpayerID != "" {
info.TaxpayerID = taxpayerID
}
}
return info, nil
}
// CreateOrUpdateUserInvoiceInfo 创建或更新用户开票信息
func (s *UserInvoiceInfoServiceImpl) CreateOrUpdateUserInvoiceInfo(ctx context.Context, userID string, invoiceInfo *value_objects.InvoiceInfo) (*entities.UserInvoiceInfo, error) {
// 验证开票信息
if err := s.ValidateInvoiceInfo(ctx, invoiceInfo, value_objects.InvoiceTypeGeneral); err != nil {
return nil, err
}
// 检查是否已存在
exists, err := s.userInvoiceInfoRepo.Exists(ctx, userID)
if err != nil {
return nil, fmt.Errorf("检查用户开票信息失败: %w", err)
}
var userInvoiceInfo *entities.UserInvoiceInfo
if exists {
// 更新现有记录
userInvoiceInfo, err = s.userInvoiceInfoRepo.FindByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("获取用户开票信息失败: %w", err)
}
// 更新字段
userInvoiceInfo.CompanyName = invoiceInfo.CompanyName
userInvoiceInfo.TaxpayerID = invoiceInfo.TaxpayerID
userInvoiceInfo.BankName = invoiceInfo.BankName
userInvoiceInfo.BankAccount = invoiceInfo.BankAccount
userInvoiceInfo.CompanyAddress = invoiceInfo.CompanyAddress
userInvoiceInfo.CompanyPhone = invoiceInfo.CompanyPhone
userInvoiceInfo.ReceivingEmail = invoiceInfo.ReceivingEmail
err = s.userInvoiceInfoRepo.Update(ctx, userInvoiceInfo)
} else {
// 创建新记录
userInvoiceInfo = &entities.UserInvoiceInfo{
ID: uuid.New().String(),
UserID: userID,
CompanyName: invoiceInfo.CompanyName,
TaxpayerID: invoiceInfo.TaxpayerID,
BankName: invoiceInfo.BankName,
BankAccount: invoiceInfo.BankAccount,
CompanyAddress: invoiceInfo.CompanyAddress,
CompanyPhone: invoiceInfo.CompanyPhone,
ReceivingEmail: invoiceInfo.ReceivingEmail,
}
err = s.userInvoiceInfoRepo.Create(ctx, userInvoiceInfo)
}
if err != nil {
return nil, fmt.Errorf("保存用户开票信息失败: %w", err)
}
return userInvoiceInfo, nil
}
// CreateOrUpdateUserInvoiceInfoWithEnterpriseInfo 创建或更新用户开票信息(包含企业认证信息)
func (s *UserInvoiceInfoServiceImpl) CreateOrUpdateUserInvoiceInfoWithEnterpriseInfo(ctx context.Context, userID string, invoiceInfo *value_objects.InvoiceInfo, companyName, taxpayerID string) (*entities.UserInvoiceInfo, error) {
// 检查企业认证信息
if companyName == "" || taxpayerID == "" {
return nil, fmt.Errorf("用户未完成企业认证,无法创建开票信息")
}
// 创建新的开票信息对象,使用传入的企业认证信息
updatedInvoiceInfo := &value_objects.InvoiceInfo{
CompanyName: companyName, // 从企业认证信息获取
TaxpayerID: taxpayerID, // 从企业认证信息获取
BankName: invoiceInfo.BankName, // 用户输入
BankAccount: invoiceInfo.BankAccount, // 用户输入
CompanyAddress: invoiceInfo.CompanyAddress, // 用户输入
CompanyPhone: invoiceInfo.CompanyPhone, // 用户输入
ReceivingEmail: invoiceInfo.ReceivingEmail, // 用户输入
}
// 验证开票信息
if err := s.ValidateInvoiceInfo(ctx, updatedInvoiceInfo, value_objects.InvoiceTypeGeneral); err != nil {
return nil, err
}
// 检查是否已存在
exists, err := s.userInvoiceInfoRepo.Exists(ctx, userID)
if err != nil {
return nil, fmt.Errorf("检查用户开票信息失败: %w", err)
}
var userInvoiceInfo *entities.UserInvoiceInfo
if exists {
// 更新现有记录
userInvoiceInfo, err = s.userInvoiceInfoRepo.FindByUserID(ctx, userID)
if err != nil {
return nil, fmt.Errorf("获取用户开票信息失败: %w", err)
}
// 更新字段(公司名称和纳税人识别号从企业认证信息获取,其他字段从用户输入获取)
userInvoiceInfo.CompanyName = companyName
userInvoiceInfo.TaxpayerID = taxpayerID
userInvoiceInfo.BankName = invoiceInfo.BankName
userInvoiceInfo.BankAccount = invoiceInfo.BankAccount
userInvoiceInfo.CompanyAddress = invoiceInfo.CompanyAddress
userInvoiceInfo.CompanyPhone = invoiceInfo.CompanyPhone
userInvoiceInfo.ReceivingEmail = invoiceInfo.ReceivingEmail
err = s.userInvoiceInfoRepo.Update(ctx, userInvoiceInfo)
} else {
// 创建新记录
userInvoiceInfo = &entities.UserInvoiceInfo{
ID: uuid.New().String(),
UserID: userID,
CompanyName: companyName, // 从企业认证信息获取
TaxpayerID: taxpayerID, // 从企业认证信息获取
BankName: invoiceInfo.BankName, // 用户输入
BankAccount: invoiceInfo.BankAccount, // 用户输入
CompanyAddress: invoiceInfo.CompanyAddress, // 用户输入
CompanyPhone: invoiceInfo.CompanyPhone, // 用户输入
ReceivingEmail: invoiceInfo.ReceivingEmail, // 用户输入
}
err = s.userInvoiceInfoRepo.Create(ctx, userInvoiceInfo)
}
if err != nil {
return nil, fmt.Errorf("保存用户开票信息失败: %w", err)
}
return userInvoiceInfo, nil
}
// ValidateInvoiceInfo 验证开票信息
func (s *UserInvoiceInfoServiceImpl) ValidateInvoiceInfo(ctx context.Context, invoiceInfo *value_objects.InvoiceInfo, invoiceType value_objects.InvoiceType) error {
if invoiceType == value_objects.InvoiceTypeGeneral {
return invoiceInfo.ValidateForGeneralInvoice()
} else if invoiceType == value_objects.InvoiceTypeSpecial {
return invoiceInfo.ValidateForSpecialInvoice()
}
return fmt.Errorf("无效的发票类型: %s", invoiceType)
}
// DeleteUserInvoiceInfo 删除用户开票信息
func (s *UserInvoiceInfoServiceImpl) DeleteUserInvoiceInfo(ctx context.Context, userID string) error {
err := s.userInvoiceInfoRepo.Delete(ctx, userID)
if err != nil {
return fmt.Errorf("删除用户开票信息失败: %w", err)
}
return nil
}