Packages are easily the most complicated part of the system and the aspect that people tend to require the most support for.
I have long wanted to add a way of expressing a package “Three tickets to different performances on the same day”, but have not been able to think of a way of doing so that didn’t make packages EVEN MORE complicated. But I just had a realisation that will make building this functionality much easier.
In the existing system, you can set up a package for “at least 4 tickets for the same performance” and you can set up a package for “at least 4 tickets for different performances”, and the “4” is the same value in the database. We have the min/max quantity in one field, and the scope in the other.
What I have just realised is that those two "4"s are completely different, and should be stored separately. In the “different performances” package there is an implicit “1” quantity: “at least 1 ticket for each of 4 different performances”. The “4” counts the performances, not the tickets, and I just assume it’s 1 ticket per performance.
What we’re going to do, to work out whether a basket qualifies for a package or not, is:
- Group all the products in the basket by the thing that should be the “same” about all of them. Think of getting all the items in your basket, and then putting them into separate shopping bags, so that each bag contains only items that are on the same day (or in the same show, or in the same performance, or whatever). If “same” isn’t an important constraint, then just put everything in one bag.
Then, we can go through each bag one at a time, and for each bag
Group all the products in the bag by the thing that should be “different” about all of them. If that’s performance, put the items into smaller bags, one bag per performance. Or show, or day, or whatever.
Filter these smaller bags by “how many ticket per bag”
Check the number of remaining smaller bags for “how many different things”.
So the package rule will look like
In the same [day|performance|show|venue|space|genre] between A and B tickets at a given discount, price band, price etc for each of between N and M different [days|performances|shows|venues|spaces|genres]
Which means we will be able to say
“In the same day, between 1 and 1 tickets for each of 3 different shows” for a festival style multibuy, and
“In the same performance, between 10 and infinity tickets” for a group booking discount, and
“In the same performance, between 3 and 3 tickets” for a 3 for 2 offer and
“In the same show, between 2 and 2 tickets for more than 2 performances” for a why are you buying tickets for different performances of the same show are you mad offer, and so on.
Effectively, the scope will change from “same show | same performance | different show | different performance | any mixture” to “day | performance | show”, and the quantity will expand from “min, max” to “min max number of distinct things” + “min max number of things per distinct thing”.