48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"calllinesystem/server/internal/model"
|
|
)
|
|
|
|
var ErrFirstTicketExceedsPeopleTarget = errors.New("first ticket party size exceeds people target")
|
|
|
|
// SelectTicketsForCall preserves the incoming FIFO order. Ticket mode selects
|
|
// up to target tickets. People mode selects the longest leading sequence whose
|
|
// total party size does not exceed target; tickets are never split or skipped.
|
|
func SelectTicketsForCall(tickets []model.QueueTicket, mode string, target int) ([]model.QueueTicket, int, error) {
|
|
if target < 1 || len(tickets) == 0 {
|
|
return nil, 0, nil
|
|
}
|
|
if mode == model.CallModeTicket {
|
|
count := min(target, len(tickets))
|
|
selected := tickets[:count]
|
|
return selected, totalPartySize(selected), nil
|
|
}
|
|
if mode != model.CallModePeople {
|
|
return nil, 0, errors.New("unsupported call mode")
|
|
}
|
|
total := 0
|
|
count := 0
|
|
for _, ticket := range tickets {
|
|
if total+ticket.PartySize > target {
|
|
break
|
|
}
|
|
total += ticket.PartySize
|
|
count++
|
|
}
|
|
if count == 0 {
|
|
return nil, 0, ErrFirstTicketExceedsPeopleTarget
|
|
}
|
|
return tickets[:count], total, nil
|
|
}
|
|
|
|
func totalPartySize(tickets []model.QueueTicket) int {
|
|
total := 0
|
|
for _, ticket := range tickets {
|
|
total += ticket.PartySize
|
|
}
|
|
return total
|
|
}
|