Adds the system payment method for paying with EnakPoint (docs/prd-point-coin.md F9, §8, §10.5, PC-303). Migration 000094 allows the point type, keeps one per organization with a partial unique index, creates it for every existing organization, and adds a trigger that creates it for new ones, as the walk-in customer is. It adds payments.points_used and point_value. Their CHECK is written so it can never be NULL: the PRD form, (both NULL) OR (both > 0), is NULL for points_used with a NULL point_value, which a CHECK lets through, so a payment could have lost the value a refund depends on. A test caught it. The API cannot create, delete or retype the EnakPoint method, nor turn another method into one; that answers 400. Renaming it is allowed. The method list takes the outlet from ?outlet_id= or the user's outlet and leaves EnakPoint out when that outlet does not accept it, filtered in the query so the count stays right. The organization-wide active list is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package models
|
|
|
|
import (
|
|
"apskel-pos-be/internal/constants"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type PaymentMethod struct {
|
|
ID uuid.UUID
|
|
OrganizationID uuid.UUID
|
|
Name string
|
|
Type constants.PaymentMethodType
|
|
Processor *string
|
|
Configuration map[string]interface{}
|
|
IsActive bool
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type CreatePaymentMethodRequest struct {
|
|
OrganizationID uuid.UUID `validate:"required"`
|
|
OutletID uuid.UUID `validate:"required"`
|
|
Name string `validate:"required,min=1,max=100"`
|
|
Type constants.PaymentMethodType `validate:"required"`
|
|
Processor *string `validate:"omitempty,max=100"`
|
|
Configuration map[string]interface{} `validate:"omitempty"`
|
|
IsActive *bool `validate:"omitempty"`
|
|
}
|
|
|
|
type UpdatePaymentMethodRequest struct {
|
|
Name *string `validate:"omitempty,min=1,max=100"`
|
|
Type *constants.PaymentMethodType `validate:"omitempty"`
|
|
Processor *string `validate:"omitempty,max=100"`
|
|
Configuration map[string]interface{} `validate:"omitempty"`
|
|
IsActive *bool `validate:"omitempty"`
|
|
}
|
|
|
|
type PaymentMethodResponse struct {
|
|
ID uuid.UUID
|
|
OrganizationID uuid.UUID
|
|
Name string
|
|
Type constants.PaymentMethodType
|
|
Processor *string
|
|
Configuration map[string]interface{}
|
|
IsActive bool
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type ListPaymentMethodsRequest struct {
|
|
OrganizationID *uuid.UUID
|
|
// When set, EnakPoint is left out unless the outlet accepts it (F9).
|
|
OutletID *uuid.UUID
|
|
Type *constants.PaymentMethodType
|
|
IsActive *bool
|
|
Search string
|
|
Page int `validate:"min=1"`
|
|
Limit int `validate:"min=1,max=100"`
|
|
}
|
|
|
|
type ListPaymentMethodsResponse struct {
|
|
PaymentMethods []PaymentMethodResponse
|
|
TotalCount int
|
|
Page int
|
|
Limit int
|
|
TotalPages int
|
|
}
|
|
|
|
func (pm *PaymentMethod) IsDigital() bool {
|
|
return pm.Type == constants.PaymentMethodTypeCard ||
|
|
pm.Type == constants.PaymentMethodTypeDigitalWallet ||
|
|
pm.Type == constants.PaymentMethodTypeEDC ||
|
|
pm.Type == constants.PaymentMethodTypeQR
|
|
}
|
|
|
|
func (pm *PaymentMethod) RequiresProcessor() bool {
|
|
return pm.IsDigital() && pm.Processor != nil
|
|
}
|