163 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package entities
 | ||
| 
 | ||
| import (
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"github.com/google/uuid"
 | ||
| 	"github.com/shopspring/decimal"
 | ||
| 	"gorm.io/gorm"
 | ||
| 
 | ||
| 	"tyapi-server/internal/domains/finance/value_objects"
 | ||
| )
 | ||
| 
 | ||
| // ApplicationStatus 申请状态枚举
 | ||
| type ApplicationStatus string
 | ||
| 
 | ||
| const (
 | ||
| 	ApplicationStatusPending   ApplicationStatus = "pending"   // 待处理
 | ||
| 	ApplicationStatusCompleted ApplicationStatus = "completed" // 已完成(已上传发票)
 | ||
| 	ApplicationStatusRejected  ApplicationStatus = "rejected"  // 已拒绝
 | ||
| )
 | ||
| 
 | ||
| // InvoiceApplication 发票申请聚合根
 | ||
| type InvoiceApplication struct {
 | ||
| 	// 基础标识
 | ||
| 	ID          string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"申请唯一标识"`
 | ||
| 	UserID      string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"申请用户ID"`
 | ||
| 
 | ||
| 	// 申请信息
 | ||
| 	InvoiceType value_objects.InvoiceType `gorm:"type:varchar(20);not null" json:"invoice_type" comment:"发票类型"`
 | ||
| 	Amount      decimal.Decimal           `gorm:"type:decimal(20,8);not null" json:"amount" comment:"申请金额"`
 | ||
| 	Status      ApplicationStatus         `gorm:"type:varchar(20);not null;default:'pending';index" json:"status" comment:"申请状态"`
 | ||
| 
 | ||
| 	// 开票信息快照(申请时的信息,用于历史记录追踪)
 | ||
| 	CompanyName    string `gorm:"type:varchar(200);not null" json:"company_name" comment:"公司名称"`
 | ||
| 	TaxpayerID     string `gorm:"type:varchar(50);not null" json:"taxpayer_id" comment:"纳税人识别号"`
 | ||
| 	BankName       string `gorm:"type:varchar(100)" json:"bank_name" comment:"开户银行"`
 | ||
| 	BankAccount    string `gorm:"type:varchar(50)" json:"bank_account" comment:"银行账号"`
 | ||
| 	CompanyAddress string `gorm:"type:varchar(500)" json:"company_address" comment:"企业地址"`
 | ||
| 	CompanyPhone   string `gorm:"type:varchar(20)" json:"company_phone" comment:"企业电话"`
 | ||
| 	ReceivingEmail string `gorm:"type:varchar(100);not null" json:"receiving_email" comment:"发票接收邮箱"`
 | ||
| 	
 | ||
| 	// 开票信息引用(关联到用户开票信息表,用于模板功能)
 | ||
| 	UserInvoiceInfoID string `gorm:"type:varchar(36);not null" json:"user_invoice_info_id" comment:"用户开票信息ID"`
 | ||
| 
 | ||
| 	// 文件信息(申请通过后才有)
 | ||
| 	FileID       *string    `gorm:"type:varchar(200)" json:"file_id,omitempty" comment:"文件ID"`
 | ||
| 	FileName     *string    `gorm:"type:varchar(200)" json:"file_name,omitempty" comment:"文件名"`
 | ||
| 	FileSize     *int64     `json:"file_size,omitempty" comment:"文件大小"`
 | ||
| 	FileURL      *string    `gorm:"type:varchar(500)" json:"file_url,omitempty" comment:"文件URL"`
 | ||
| 	
 | ||
| 	// 处理信息
 | ||
| 	ProcessedBy   *string    `gorm:"type:varchar(36)" json:"processed_by,omitempty" comment:"处理人ID"`
 | ||
| 	ProcessedAt   *time.Time `json:"processed_at,omitempty" comment:"处理时间"`
 | ||
| 	RejectReason  *string    `gorm:"type:varchar(500)" json:"reject_reason,omitempty" comment:"拒绝原因"`
 | ||
| 	AdminNotes    *string    `gorm:"type:varchar(500)" json:"admin_notes,omitempty" comment:"管理员备注"`
 | ||
| 
 | ||
| 	// 时间戳字段
 | ||
| 	CreatedAt time.Time      `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"`
 | ||
| 	UpdatedAt time.Time      `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"`
 | ||
| 	DeletedAt gorm.DeletedAt `gorm:"index" json:"-" comment:"软删除时间"`
 | ||
| }
 | ||
| 
 | ||
| // TableName 指定数据库表名
 | ||
| func (InvoiceApplication) TableName() string {
 | ||
| 	return "invoice_applications"
 | ||
| }
 | ||
| 
 | ||
| // BeforeCreate GORM钩子:创建前自动生成UUID
 | ||
| func (ia *InvoiceApplication) BeforeCreate(tx *gorm.DB) error {
 | ||
| 	if ia.ID == "" {
 | ||
| 		ia.ID = uuid.New().String()
 | ||
| 	}
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // IsPending 检查是否为待处理状态
 | ||
| func (ia *InvoiceApplication) IsPending() bool {
 | ||
| 	return ia.Status == ApplicationStatusPending
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // IsCompleted 检查是否为已完成状态
 | ||
| func (ia *InvoiceApplication) IsCompleted() bool {
 | ||
| 	return ia.Status == ApplicationStatusCompleted
 | ||
| }
 | ||
| 
 | ||
| // IsRejected 检查是否为已拒绝状态
 | ||
| func (ia *InvoiceApplication) IsRejected() bool {
 | ||
| 	return ia.Status == ApplicationStatusRejected
 | ||
| }
 | ||
| 
 | ||
| // CanProcess 检查是否可以处理
 | ||
| func (ia *InvoiceApplication) CanProcess() bool {
 | ||
| 	return ia.IsPending()
 | ||
| }
 | ||
| 
 | ||
| // CanReject 检查是否可以拒绝
 | ||
| func (ia *InvoiceApplication) CanReject() bool {
 | ||
| 	return ia.IsPending()
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // MarkCompleted 标记为已完成
 | ||
| func (ia *InvoiceApplication) MarkCompleted(processedBy string) {
 | ||
| 	ia.Status = ApplicationStatusCompleted
 | ||
| 	ia.ProcessedBy = &processedBy
 | ||
| 	now := time.Now()
 | ||
| 	ia.ProcessedAt = &now
 | ||
| }
 | ||
| 
 | ||
| // MarkRejected 标记为已拒绝
 | ||
| func (ia *InvoiceApplication) MarkRejected(reason string, processedBy string) {
 | ||
| 	ia.Status = ApplicationStatusRejected
 | ||
| 	ia.RejectReason = &reason
 | ||
| 	ia.ProcessedBy = &processedBy
 | ||
| 	now := time.Now()
 | ||
| 	ia.ProcessedAt = &now
 | ||
| }
 | ||
| 
 | ||
| // SetFileInfo 设置文件信息
 | ||
| func (ia *InvoiceApplication) SetFileInfo(fileID, fileName, fileURL string, fileSize int64) {
 | ||
| 	ia.FileID = &fileID
 | ||
| 	ia.FileName = &fileName
 | ||
| 	ia.FileURL = &fileURL
 | ||
| 	ia.FileSize = &fileSize
 | ||
| }
 | ||
| 
 | ||
| // NewInvoiceApplication 工厂方法
 | ||
| func NewInvoiceApplication(userID string, invoiceType value_objects.InvoiceType, amount decimal.Decimal, userInvoiceInfoID string) *InvoiceApplication {
 | ||
| 	return &InvoiceApplication{
 | ||
| 		UserID:             userID,
 | ||
| 		InvoiceType:        invoiceType,
 | ||
| 		Amount:             amount,
 | ||
| 		Status:             ApplicationStatusPending,
 | ||
| 		UserInvoiceInfoID:  userInvoiceInfoID,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // SetInvoiceInfoSnapshot 设置开票信息快照
 | ||
| func (ia *InvoiceApplication) SetInvoiceInfoSnapshot(info *value_objects.InvoiceInfo) {
 | ||
| 	ia.CompanyName = info.CompanyName
 | ||
| 	ia.TaxpayerID = info.TaxpayerID
 | ||
| 	ia.BankName = info.BankName
 | ||
| 	ia.BankAccount = info.BankAccount
 | ||
| 	ia.CompanyAddress = info.CompanyAddress
 | ||
| 	ia.CompanyPhone = info.CompanyPhone
 | ||
| 	ia.ReceivingEmail = info.ReceivingEmail
 | ||
| }
 | ||
| 
 | ||
| // GetInvoiceInfoSnapshot 获取开票信息快照
 | ||
| func (ia *InvoiceApplication) GetInvoiceInfoSnapshot() *value_objects.InvoiceInfo {
 | ||
| 	return value_objects.NewInvoiceInfo(
 | ||
| 		ia.CompanyName,
 | ||
| 		ia.TaxpayerID,
 | ||
| 		ia.BankName,
 | ||
| 		ia.BankAccount,
 | ||
| 		ia.CompanyAddress,
 | ||
| 		ia.CompanyPhone,
 | ||
| 		ia.ReceivingEmail,
 | ||
| 	)
 | ||
| }  |