Saturday, 7 April 2012

Limited Availability

Just talking to myself here, figuring out how this is going to work.

We need to be able to limit how many tickets someone can buy, because otherwise the touts buy up hundreds then try to resell them.

Fair enough.

But it breaks down into lots of different use cases, and I want to be clear I'm catching them all.

1. Limit number of tickets per order, for a given product.

You've got something that's going to sell fast, but you aren't too concerned about fraud. 6 tickets per order, nothing to stop anyone buying another order.

2. Limit number of tickets per account, for a given product.

You're a bit more worried about people coming back for another order, so you want the quantity limit to be per account.

3. Limit number of tickets per delivery address / billing credit card, for a given product.

You're even more worried that people will be buying as many tickets as they can for resale, so you want to limit the tickets per delivery address or credit card, across accounts.

4. Limit number of tickets for a given show

It's not just per product, you've got 5 performances to sell, and you want a maximum number of tickets sold across all the performances.

5. Limit number of tickets at a given discount

There's no limit in general, but a customer can use their "Membership" discount on at most 2 tickets - themselves and a guest - and the rest have to be full price.

6. Limit number of tickets at a given discount, AND the total number of tickets

A customer can have at most 5 tickets, of which at most 1 can be at the membership discount.

So the problems are:
Q. How to we define whether the limits are per product, or per group of products?
A. We could create a "ProductLimit" group thing, and all products that reference the same ProductLimit share a counter... but that means that if we have 50 performances and the limit is per performance, we have to create 50 product limits, that are identical in every respect.

We could give the ProductLimit a property "Per Product", so that all products reference the same ProductLimit, but that limit can be either global (5 tickets per show) or individual (5 tickets per performance). That doesn't help if the requirement is "at most 5 tickets per performance AND at most 15 tickets across all performances".

We could give the ProductLimit two properties: MaxQuantity and MaxQuantityPerProduct, either of which are nullable.

And then it gets 10x more complicated because of the membership discount issue. If we just store the MaxQuantity in the DiscountScheme, then we can say "At most 2 tickets at the membership price", but what does that apply to? The order and just that product? The account, and all the performances in the show?


Ok, so we're going to have to add ProductLimitRules

Each rule will state:
1. Applies to products individually, or all products that share this product limit. "ProductLimitRuleShared"
2. Applies per: order / accounts / address  + cc. "ProductLimitRuleScopeId"
3. Applies to Discount (i.e. "Child", though I struggle to imagine a show where you're allowed to buy at most two Child tickets and at most two Adult tickets, and aren't allowed to buy 4 Adult tickets). "DiscountId"
4. Applies to User Status (i.e. Membership). "UserStatusTypeId"
5. Maximum Quantity. "MaxQuantity"