81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/gofrs/uuid/v5"
|
|
)
|
|
|
|
// ErrInsufficientCredit is returned when order exceeds available credit
|
|
var ErrInsufficientCredit = errors.New("insufficient credit: order total exceeds available credit line")
|
|
|
|
// CheckCreditLine verifies if a company has enough credit to place an order
|
|
func (s *Service) CheckCreditLine(ctx context.Context, companyID uuid.UUID, orderTotalCents int64) (bool, error) {
|
|
company, err := s.repo.GetCompany(ctx, companyID)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if company == nil {
|
|
return false, errors.New("company not found")
|
|
}
|
|
|
|
// If no credit limit, credit line is not enabled
|
|
if company.CreditLimitCents == 0 {
|
|
return false, errors.New("credit line not enabled for this company")
|
|
}
|
|
|
|
availableCredit := company.CreditLimitCents - company.CreditUsedCents
|
|
return orderTotalCents <= availableCredit, nil
|
|
}
|
|
|
|
// UseCreditLine reserves credit for an order (call during CreateOrder with payment_method=CREDIT_LINE)
|
|
func (s *Service) UseCreditLine(ctx context.Context, companyID uuid.UUID, amountCents int64) error {
|
|
company, err := s.repo.GetCompany(ctx, companyID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if company == nil {
|
|
return errors.New("company not found")
|
|
}
|
|
|
|
availableCredit := company.CreditLimitCents - company.CreditUsedCents
|
|
if amountCents > availableCredit {
|
|
return ErrInsufficientCredit
|
|
}
|
|
|
|
// Update credit used
|
|
company.CreditUsedCents += amountCents
|
|
return s.repo.UpdateCompany(ctx, company)
|
|
}
|
|
|
|
// ReleaseCreditLine releases credit when order is paid or cancelled
|
|
func (s *Service) ReleaseCreditLine(ctx context.Context, companyID uuid.UUID, amountCents int64) error {
|
|
company, err := s.repo.GetCompany(ctx, companyID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if company == nil {
|
|
return errors.New("company not found")
|
|
}
|
|
|
|
company.CreditUsedCents -= amountCents
|
|
if company.CreditUsedCents < 0 {
|
|
company.CreditUsedCents = 0
|
|
}
|
|
return s.repo.UpdateCompany(ctx, company)
|
|
}
|
|
|
|
// SetCreditLimit updates a company's credit limit (admin only)
|
|
func (s *Service) SetCreditLimit(ctx context.Context, companyID uuid.UUID, limitCents int64) error {
|
|
company, err := s.repo.GetCompany(ctx, companyID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if company == nil {
|
|
return errors.New("company not found")
|
|
}
|
|
|
|
company.CreditLimitCents = limitCents
|
|
return s.repo.UpdateCompany(ctx, company)
|
|
}
|