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 }