{ "generated_from": "reference/odoo-c2c_bundle_offers/models/bundle_engine.py", "rounding": "per offer: largest remainder to cents (see largest_remainder_cents)", "vectors": [ { "name": "fixed_percent_complete", "note": "Odoo test: 20% of (10 + 2 x 5) = 4.00, spread 2.00 / 2.00 by price.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "diya", "product_id": "P-diya", "collection_ids": [], "unit_price": 10.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "camphor", "product_id": "P-camphor", "collection_ids": [], "unit_price": 5.0, "quantity": 2 } ] }, "offers": [ { "id": "kit", "type": "fixed", "discount_type": "percent", "value": 20, "lines": [ { "variant_id": "diya", "quantity": 1 }, { "variant_id": "camphor", "quantity": 2 } ] } ], "expected": { "applications": [ { "offer_id": "kit", "discount": 4.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "kit", "line_id": "gid://shopify/CartLine/1", "amount_exact": 2.0, "amount": 2.0 }, { "offer_id": "kit", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.0, "amount": 2.0 } ], "total_discount": 4.0 } }, { "name": "fixed_incomplete_no_discount", "note": "Bundle needs 2 camphor; only 1 in cart -> nothing.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "diya", "product_id": "P-diya", "collection_ids": [], "unit_price": 10.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "camphor", "product_id": "P-camphor", "collection_ids": [], "unit_price": 5.0, "quantity": 1 } ] }, "offers": [ { "id": "kit", "type": "fixed", "discount_type": "percent", "value": 20, "lines": [ { "variant_id": "diya", "quantity": 1 }, { "variant_id": "camphor", "quantity": 2 } ] } ], "expected": { "applications": [], "allocations": [], "total_discount": 0 } }, { "name": "fixed_three_tax_groups_split", "note": "Odoo split per tax; on Shopify the discount is allocated per line (tax follows the line).", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 5.0, "quantity": 2 }, { "id": "gid://shopify/CartLine/3", "variant_id": "c", "product_id": "P-c", "collection_ids": [], "unit_price": 4.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "percent", "value": 20, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 2 }, { "variant_id": "c", "quantity": 1 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 4.8, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2", "gid://shopify/CartLine/3" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 2.0, "amount": 2.0 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.0, "amount": 2.0 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/3", "amount_exact": 0.8, "amount": 0.8 } ], "total_discount": 4.8 } }, { "name": "fixed_repeats_twice", "note": "Enough items for 2 bundles and no limit -> applied twice ($6).", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 2 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 5.0, "quantity": 4 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "amount", "value": 3, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 2 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 3, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2" ] }, { "offer_id": "F", "discount": 3, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 3.0, "amount": 3.0 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 3.0, "amount": 3.0 } ], "total_discount": 6.0 } }, { "name": "fixed_max_uses_1", "note": "\"Max uses per order\" = 1.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 2 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 5.0, "quantity": 4 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "amount", "value": 3, "max_uses": 1, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 2 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 3, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 1.5, "amount": 1.5 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 1.5, "amount": 1.5 } ], "total_discount": 3.0 } }, { "name": "fixed_amount_capped_at_regular", "note": "$ off never exceeds the items' price (discount 3.00, not 10.00).", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 2.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 1.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "amount", "value": 10, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 3.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 2.0, "amount": 2.0 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 1.0, "amount": 1.0 } ], "total_discount": 3.0 } }, { "name": "fixed_price_bundle", "note": "Bundle price 20 for items worth 29 -> 9.00 off.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 12.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 9.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "c", "product_id": "P-c", "collection_ids": [], "unit_price": 8.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "fixed_price", "value": 20, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 }, { "variant_id": "c", "quantity": 1 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 9.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/3" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 3.724138, "amount": 3.73 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.793103, "amount": 2.79 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/3", "amount_exact": 2.482759, "amount": 2.48 } ], "total_discount": 9.0 } }, { "name": "fixed_price_above_regular_gives_nothing", "note": "Bundle price higher than the items -> no discount, items stay free for other offers.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 5.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 5.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "fixed_price", "value": 15, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 } ] } ], "expected": { "applications": [], "allocations": [], "total_discount": 0 } }, { "name": "mix_fixed_price_uses_cheapest_no_gain", "note": "Cheapest 3 (3+8+9=20) already cost 20 -> no discount (Odoo test).", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "p1", "product_id": "P-p1", "collection_ids": [ "sweets" ], "unit_price": 12.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "p2", "product_id": "P-p2", "collection_ids": [ "sweets" ], "unit_price": 9.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "p3", "product_id": "P-p3", "collection_ids": [ "sweets" ], "unit_price": 8.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/4", "variant_id": "p4", "product_id": "P-p4", "collection_ids": [ "sweets" ], "unit_price": 3.0, "quantity": 1 } ] }, "offers": [ { "id": "M", "type": "mix", "discount_type": "fixed_price", "value": 20, "qty": 3, "scope": { "variant_ids": [], "collection_ids": [ "sweets" ] } } ], "expected": { "applications": [], "allocations": [], "total_discount": 0 } }, { "name": "mix_fixed_price_any_3_for_20", "note": "29 -> 20: 9.00 off, spread by price.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "p1", "product_id": "P-p1", "collection_ids": [ "sweets" ], "unit_price": 12.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "p2", "product_id": "P-p2", "collection_ids": [ "sweets" ], "unit_price": 9.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "p3", "product_id": "P-p3", "collection_ids": [ "sweets" ], "unit_price": 8.0, "quantity": 1 } ] }, "offers": [ { "id": "M", "type": "mix", "discount_type": "fixed_price", "value": 20, "qty": 3, "scope": { "variant_ids": [], "collection_ids": [ "sweets" ] } } ], "expected": { "applications": [ { "offer_id": "M", "discount": 9.0, "line_ids_used": [ "gid://shopify/CartLine/3", "gid://shopify/CartLine/2", "gid://shopify/CartLine/1" ] } ], "allocations": [ { "offer_id": "M", "line_id": "gid://shopify/CartLine/1", "amount_exact": 3.724138, "amount": 3.73 }, { "offer_id": "M", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.793103, "amount": 2.79 }, { "offer_id": "M", "line_id": "gid://shopify/CartLine/3", "amount_exact": 2.482759, "amount": 2.48 } ], "total_discount": 9.0 } }, { "name": "mix_percent_twice_cheapest_first", "note": "Two uses: first takes the three 4.00 items, second the three 10.00 items.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "p1", "product_id": "P-p1", "collection_ids": [ "g" ], "unit_price": 10.0, "quantity": 3 }, { "id": "gid://shopify/CartLine/2", "variant_id": "p2", "product_id": "P-p2", "collection_ids": [ "g" ], "unit_price": 4.0, "quantity": 3 } ] }, "offers": [ { "id": "M", "type": "mix", "discount_type": "percent", "value": 10, "qty": 3, "scope": { "variant_ids": [], "collection_ids": [ "g" ] } } ], "expected": { "applications": [ { "offer_id": "M", "discount": 1.2, "line_ids_used": [ "gid://shopify/CartLine/2", "gid://shopify/CartLine/2", "gid://shopify/CartLine/2" ] }, { "offer_id": "M", "discount": 3.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/1", "gid://shopify/CartLine/1" ] } ], "allocations": [ { "offer_id": "M", "line_id": "gid://shopify/CartLine/1", "amount_exact": 3.0, "amount": 3.0 }, { "offer_id": "M", "line_id": "gid://shopify/CartLine/2", "amount_exact": 1.2, "amount": 1.2 } ], "total_discount": 4.2 } }, { "name": "mix_by_variants_and_collections", "note": "A unit matches if its variant OR any of its collections is in the scope.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "x", "product_id": "P-x", "collection_ids": [], "unit_price": 6.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "y", "product_id": "P-y", "collection_ids": [ "flowers" ], "unit_price": 7.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "z", "product_id": "P-z", "collection_ids": [], "unit_price": 50.0, "quantity": 1 } ] }, "offers": [ { "id": "M", "type": "mix", "discount_type": "amount", "value": 5, "qty": 2, "scope": { "variant_ids": [ "x" ], "collection_ids": [ "flowers" ] } } ], "expected": { "applications": [ { "offer_id": "M", "discount": 5, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "M", "line_id": "gid://shopify/CartLine/1", "amount_exact": 2.307692, "amount": 2.31 }, { "offer_id": "M", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.692308, "amount": 2.69 } ], "total_discount": 5.0 } }, { "name": "bxgy_same_scope_cheapest_free", "note": "Most expensive count as \"buy\", cheapest remaining is free -> 6.00 (Odoo test).", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 8.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "c", "product_id": "P-c", "collection_ids": [], "unit_price": 6.0, "quantity": 1 } ] }, "offers": [ { "id": "B", "type": "bxgy", "buy_qty": 2, "get_qty": 1, "get_percent": 100, "buy_scope": { "variant_ids": [ "a", "b", "c" ], "collection_ids": [] }, "get_scope": { "variant_ids": [ "a", "b", "c" ], "collection_ids": [] } } ], "expected": { "applications": [ { "offer_id": "B", "discount": 6.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/3" ] } ], "allocations": [ { "offer_id": "B", "line_id": "gid://shopify/CartLine/1", "amount_exact": 2.5, "amount": 2.5 }, { "offer_id": "B", "line_id": "gid://shopify/CartLine/2", "amount_exact": 2.0, "amount": 2.0 }, { "offer_id": "B", "line_id": "gid://shopify/CartLine/3", "amount_exact": 1.5, "amount": 1.5 } ], "total_discount": 6.0 } }, { "name": "bxgy_get_item_missing", "note": "Buy part complete but no \"get\" item -> nothing, buy items released.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 2 } ] }, "offers": [ { "id": "B", "type": "bxgy", "buy_qty": 2, "get_qty": 1, "get_percent": 50, "buy_scope": { "variant_ids": [ "a" ], "collection_ids": [] }, "get_scope": { "variant_ids": [ "gift" ], "collection_ids": [] } } ], "expected": { "applications": [], "allocations": [], "total_discount": 0 } }, { "name": "bxgy_half_price", "note": "Get item at 50% -> 2.00. Discount is spread over ALL used units (buy + get) by price, as Odoo does.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 2 }, { "id": "gid://shopify/CartLine/2", "variant_id": "gift", "product_id": "P-gift", "collection_ids": [], "unit_price": 4.0, "quantity": 1 } ] }, "offers": [ { "id": "B", "type": "bxgy", "buy_qty": 2, "get_qty": 1, "get_percent": 50, "buy_scope": { "variant_ids": [ "a" ], "collection_ids": [] }, "get_scope": { "variant_ids": [ "gift" ], "collection_ids": [] } } ], "expected": { "applications": [ { "offer_id": "B", "discount": 2.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/1", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "B", "line_id": "gid://shopify/CartLine/1", "amount_exact": 1.666667, "amount": 1.67 }, { "offer_id": "B", "line_id": "gid://shopify/CartLine/2", "amount_exact": 0.333333, "amount": 0.33 } ], "total_discount": 2.0 } }, { "name": "bxgy_repeats", "note": "6 items: buy 2 get 1 twice -> 20.00.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 6 } ] }, "offers": [ { "id": "B", "type": "bxgy", "buy_qty": 2, "get_qty": 1, "get_percent": 100, "buy_scope": { "variant_ids": [ "a" ], "collection_ids": [] }, "get_scope": { "variant_ids": [ "a" ], "collection_ids": [] } } ], "expected": { "applications": [ { "offer_id": "B", "discount": 10.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/1", "gid://shopify/CartLine/1" ] }, { "offer_id": "B", "discount": 10.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/1", "gid://shopify/CartLine/1" ] } ], "allocations": [ { "offer_id": "B", "line_id": "gid://shopify/CartLine/1", "amount_exact": 20.0, "amount": 20.0 } ], "total_discount": 20.0 } }, { "name": "priority_incomplete_first_offer_frees_items", "note": "Odoo test: the incomplete fixed bundle leaves the item for the next offer.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "percent", "value": 50, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 } ] }, { "id": "M", "type": "mix", "discount_type": "percent", "value": 10, "qty": 1, "scope": { "variant_ids": [ "a" ], "collection_ids": [] } } ], "expected": { "applications": [ { "offer_id": "M", "discount": 1.0, "line_ids_used": [ "gid://shopify/CartLine/1" ] } ], "allocations": [ { "offer_id": "M", "line_id": "gid://shopify/CartLine/1", "amount_exact": 1.0, "amount": 1.0 } ], "total_discount": 1.0 } }, { "name": "priority_item_used_once", "note": "Offers in priority order: the first takes both items, the better second offer gets nothing.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 10.0, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 10.0, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "percent", "value": 10, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 } ] }, { "id": "M", "type": "mix", "discount_type": "percent", "value": 50, "qty": 2, "scope": { "variant_ids": [ "a", "b" ], "collection_ids": [] } } ], "expected": { "applications": [ { "offer_id": "F", "discount": 2.0, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 1.0, "amount": 1.0 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 1.0, "amount": 1.0 } ], "total_discount": 2.0 } }, { "name": "rounding_three_way_split", "note": "Per-line cents use largest remainder so they add up to exactly 1.00.", "cart": { "lines": [ { "id": "gid://shopify/CartLine/1", "variant_id": "a", "product_id": "P-a", "collection_ids": [], "unit_price": 3.33, "quantity": 1 }, { "id": "gid://shopify/CartLine/2", "variant_id": "b", "product_id": "P-b", "collection_ids": [], "unit_price": 3.33, "quantity": 1 }, { "id": "gid://shopify/CartLine/3", "variant_id": "c", "product_id": "P-c", "collection_ids": [], "unit_price": 3.34, "quantity": 1 } ] }, "offers": [ { "id": "F", "type": "fixed", "discount_type": "amount", "value": 1, "lines": [ { "variant_id": "a", "quantity": 1 }, { "variant_id": "b", "quantity": 1 }, { "variant_id": "c", "quantity": 1 } ] } ], "expected": { "applications": [ { "offer_id": "F", "discount": 1, "line_ids_used": [ "gid://shopify/CartLine/1", "gid://shopify/CartLine/2", "gid://shopify/CartLine/3" ] } ], "allocations": [ { "offer_id": "F", "line_id": "gid://shopify/CartLine/1", "amount_exact": 0.333, "amount": 0.33 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/2", "amount_exact": 0.333, "amount": 0.33 }, { "offer_id": "F", "line_id": "gid://shopify/CartLine/3", "amount_exact": 0.334, "amount": 0.34 } ], "total_discount": 1.0 } } ] }