81a94b4879
continuous-integration/drone/push Build is passing
- Introduced `PickAssignedCompanyID` function to determine the appropriate company ID for company-scoped operations, improving company assignment logic. - Added `ResolveMongoID` method in the tender service to map MongoDB IDs and AI procedure references to canonical tender IDs, enhancing ID resolution. - Updated `ToggleTenderApproval` to handle company ID validation and improve error handling, ensuring robust processing of tender approvals. - Enhanced logging for error scenarios in the tender approval service, providing better insights into failures during operations. - Refactored the `GetByID` and `GetByTenderAndCompany` methods in the tender approval repository to utilize custom error types for improved clarity. This update significantly improves the handling of company and tender operations, enhancing error management and overall service reliability.
104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
package customer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
// ErrCompanyNotAssigned is returned when the requested company is not assigned to the customer.
|
|
var ErrCompanyNotAssigned = errors.New("company is not assigned to customer")
|
|
|
|
var errCompanyNotAssigned = ErrCompanyNotAssigned
|
|
|
|
func normalizeAssignedCompanyIDs(assigned []string) []string {
|
|
normalized := make([]string, 0, len(assigned))
|
|
seen := make(map[string]struct{}, len(assigned))
|
|
for _, id := range assigned {
|
|
clean := strings.TrimSpace(id)
|
|
if clean == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[clean]; ok {
|
|
continue
|
|
}
|
|
seen[clean] = struct{}{}
|
|
normalized = append(normalized, clean)
|
|
}
|
|
return normalized
|
|
}
|
|
|
|
// pickActiveCompanyID chooses the company context for a customer request.
|
|
// When requestedCompanyID is set it must be in assigned; otherwise a still-valid
|
|
// token company is kept; if the token company was removed, the first assignment is used.
|
|
func pickActiveCompanyID(assigned []string, tokenCompanyID, requestedCompanyID string) (string, error) {
|
|
assigned = normalizeAssignedCompanyIDs(assigned)
|
|
if len(assigned) == 0 {
|
|
return "", nil
|
|
}
|
|
|
|
requested := strings.TrimSpace(requestedCompanyID)
|
|
if requested != "" {
|
|
for _, id := range assigned {
|
|
if id == requested {
|
|
return requested, nil
|
|
}
|
|
}
|
|
return "", errCompanyNotAssigned
|
|
}
|
|
|
|
token := strings.TrimSpace(tokenCompanyID)
|
|
if token != "" {
|
|
for _, id := range assigned {
|
|
if id == token {
|
|
return token, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
return assigned[0], nil
|
|
}
|
|
|
|
// PickAssignedCompanyID chooses the company for a company-scoped write (e.g. tender approval).
|
|
// When requestedCompanyID is set it must be in assigned; otherwise activeCompanyID is used.
|
|
func PickAssignedCompanyID(activeCompanyID string, assigned []string, requestedCompanyID string) (string, error) {
|
|
activeCompanyID = strings.TrimSpace(activeCompanyID)
|
|
requestedCompanyID = strings.TrimSpace(requestedCompanyID)
|
|
|
|
if requestedCompanyID != "" {
|
|
for _, id := range normalizeAssignedCompanyIDs(assigned) {
|
|
if id == requestedCompanyID {
|
|
return requestedCompanyID, nil
|
|
}
|
|
}
|
|
return "", ErrCompanyNotAssigned
|
|
}
|
|
|
|
if activeCompanyID == "" {
|
|
return "", errors.New("company ID is required")
|
|
}
|
|
return activeCompanyID, nil
|
|
}
|
|
|
|
// ResolveCompanyContext resolves the active company and assigned companies for an authenticated customer.
|
|
func (s *customerService) ResolveCompanyContext(ctx context.Context, customerID, tokenCompanyID, requestedCompanyID string) (string, []string, error) {
|
|
customer, err := s.repository.GetByID(ctx, customerID)
|
|
if err != nil {
|
|
return "", nil, errors.New("customer not found")
|
|
}
|
|
|
|
assigned := normalizeAssignedCompanyIDs(customer.Companies)
|
|
companyID, err := pickActiveCompanyID(assigned, tokenCompanyID, requestedCompanyID)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
return companyID, assigned, nil
|
|
}
|
|
|
|
// ResolveActiveCompanyID resolves the active company for an authenticated customer.
|
|
func (s *customerService) ResolveActiveCompanyID(ctx context.Context, customerID, tokenCompanyID, requestedCompanyID string) (string, error) {
|
|
companyID, _, err := s.ResolveCompanyContext(ctx, customerID, tokenCompanyID, requestedCompanyID)
|
|
return companyID, err
|
|
}
|