feat: add party-size queueing and call modes
This commit is contained in:
47
server/internal/domain/call_selection.go
Normal file
47
server/internal/domain/call_selection.go
Normal file
@@ -0,0 +1,47 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user