Files
FamilyHUB/backend/src/api/requests/transactions.go
T

128 lines
4.0 KiB
Go

package requests
import (
"FamilyHub/src/api/dto"
"FamilyHub/src/api/services"
"FamilyHub/src/domain"
"FamilyHub/src/utils"
"errors"
"strings"
"time"
)
type PhotoCreateTransactionFields struct {
Image []byte
FamilyID *int64
CreatedBy *int64
Type *string
Category *string
Description *string
}
func BuildCreateTransactionInput(req dto.CreateTransactionRequest) (services.CreateTransactionInput, error) {
if req.ReceiptNumber != nil || req.ReceiptDate != nil {
receiptReq, err := BuildReceiptTransactionRequest(req)
if err != nil {
return services.CreateTransactionInput{}, err
}
return services.CreateTransactionInput{Receipt: &receiptReq}, nil
}
manualReq, err := BuildManualTransactionRequest(req)
if err != nil {
return services.CreateTransactionInput{}, err
}
return services.CreateTransactionInput{Manual: &manualReq}, nil
}
func BuildPhotoCreateTransactionInput(fields PhotoCreateTransactionFields) (services.CreateTransactionInput, error) {
return services.CreateTransactionInput{
Photo: &services.CreateTransactionPhotoInput{
Image: fields.Image,
FamilyID: fields.FamilyID,
CreatedBy: fields.CreatedBy,
Type: trimOptionalString(fields.Type),
Category: trimOptionalString(fields.Category),
Description: trimOptionalString(fields.Description),
},
}, nil
}
func BuildManualTransactionRequest(req dto.CreateTransactionRequest) (domain.CreateTransactionRequest, error) {
if req.FamilyID == nil || req.CreatedBy == nil {
return domain.CreateTransactionRequest{}, errors.New("family_id and created_by are required")
}
if req.Type == nil || strings.TrimSpace(*req.Type) == "" {
return domain.CreateTransactionRequest{}, errors.New("type is required")
}
if req.Category == nil || strings.TrimSpace(*req.Category) == "" {
return domain.CreateTransactionRequest{}, errors.New("category is required")
}
if req.Amount == nil {
return domain.CreateTransactionRequest{}, errors.New("amount is required")
}
if req.DateTime == nil || strings.TrimSpace(*req.DateTime) == "" {
return domain.CreateTransactionRequest{}, errors.New("datetime is required")
}
dateTime, err := time.Parse(time.RFC3339, *req.DateTime)
if err != nil {
return domain.CreateTransactionRequest{}, errors.New("datetime must be RFC3339")
}
return domain.CreateTransactionRequest{
FamilyID: *req.FamilyID,
Description: req.Description,
Type: strings.TrimSpace(*req.Type),
DateTime: dateTime,
Category: strings.TrimSpace(*req.Category),
Amount: *req.Amount,
CreatedBy: *req.CreatedBy,
ReceiptID: req.ReceiptID,
}, nil
}
func BuildReceiptTransactionRequest(req dto.CreateTransactionRequest) (domain.AddReceiptRequest, error) {
if req.ReceiptNumber == nil || strings.TrimSpace(*req.ReceiptNumber) == "" {
return domain.AddReceiptRequest{}, errors.New("receipt_number is required")
}
if req.ReceiptDate == nil || strings.TrimSpace(*req.ReceiptDate) == "" {
return domain.AddReceiptRequest{}, errors.New("receipt_date is required")
}
if req.FamilyID == nil || req.CreatedBy == nil {
return domain.AddReceiptRequest{}, errors.New("family_id and created_by are required")
}
if req.Amount != nil || req.DateTime != nil || req.ReceiptID != nil {
return domain.AddReceiptRequest{}, errors.New("manual transaction fields cannot be combined with receipt input")
}
isoDate, err := utils.NormalizeDateToISO(strings.TrimSpace(*req.ReceiptDate))
if err != nil {
return domain.AddReceiptRequest{}, errors.New("invalid receipt_date format")
}
return domain.AddReceiptRequest{
Number: strings.TrimSpace(*req.ReceiptNumber),
Date: isoDate,
FamilyID: req.FamilyID,
CreatedBy: req.CreatedBy,
Type: trimOptionalString(req.Type),
Category: trimOptionalString(req.Category),
Description: trimOptionalString(req.Description),
}, nil
}
func trimOptionalString(value *string) *string {
if value == nil {
return nil
}
trimmed := strings.TrimSpace(*value)
if trimmed == "" {
return nil
}
return &trimmed
}