{
  "description": "Табак (ограниченный товар) не участвует ни в чём; на хлеб нельзя списать баллы; на молоко баллы не начисляются. Доля списания считается от строк, принимающих баллы.",
  "calculation": [
    "Табак ограничен: ни списания, ни начисления. Хлеб не принимает баллы, молоко не получает баллы.",
    "Баллы принимает только молоко: доля 100 % от 10 000, ёмкость 10 000 → предел 100 баллов (баланс 1000).",
    "База начисления — только хлеб: 5000 → ⌊2,5⌋ = 2."
  ],
  "rules": {
    "schema": 1,
    "program_id": "01900000-0000-7000-8000-000000000001",
    "timezone": "Europe/Moscow",
    "points": {
      "point_type_id": "01900000-0000-7000-8000-000000000002",
      "precision": 0,
      "value_minor": 100
    },
    "accrual": {
      "percent_bp": 500
    },
    "redemption": {
      "max_share_bp": 10000,
      "min_unit_remainder_minor": 0,
      "min_receipt_minor": 0,
      "confirmation": "weak_identifiers"
    },
    "lifecycle": {
      "activation_delay_days": null,
      "expiration_policy": "after_days",
      "expiration_days": null,
      "expiration_date": null,
      "expiration_years": null
    },
    "returns": {
      "spent_points_policy": "ignore",
      "restore_into_new_lot": false
    },
    "campaigns": [],
    "tiers": null,
    "bonuses": {
      "welcome": null,
      "birthday": null,
      "referral": null
    },
    "stamp_cards": []
  },
  "basket": {
    "purchased_at": "2026-10-03T12:00:00+03:00",
    "redeem_points": 0,
    "redeem_maximum": true,
    "lines": [
      {
        "id": "1",
        "sku": "CIGARETTES",
        "quantity": 1000,
        "amount": 20000,
        "restricted": true
      },
      {
        "id": "2",
        "sku": "BREAD",
        "quantity": 1000,
        "amount": 5000,
        "excluded_from_redemption": true
      },
      {
        "id": "3",
        "sku": "MILK",
        "quantity": 1000,
        "amount": 10000,
        "excluded_from_accrual": true
      }
    ]
  },
  "member": {
    "member_id": "m-1",
    "spendable_points": 1000,
    "can_redeem": true,
    "can_accrue": true
  },
  "expected": {
    "total": 35000,
    "discount": 0,
    "redeemed_money": 10000,
    "redeemed_points": 100,
    "points_earned": 2,
    "payable": 25000,
    "max_redeemable_points": 100,
    "lines": [
      {
        "id": "1",
        "amount": 20000,
        "discount": 0,
        "redeemed_money": 0,
        "redeemed_points": 0,
        "points_earned": 0,
        "payable": 20000
      },
      {
        "id": "2",
        "amount": 5000,
        "discount": 0,
        "redeemed_money": 0,
        "redeemed_points": 0,
        "points_earned": 2,
        "payable": 5000
      },
      {
        "id": "3",
        "amount": 10000,
        "discount": 0,
        "redeemed_money": 10000,
        "redeemed_points": 100,
        "points_earned": 0,
        "payable": 0
      }
    ],
    "campaigns": [],
    "stamps": [],
    "trace": [
      {
        "code": "line.restricted",
        "data": {
          "line": "1"
        }
      },
      {
        "code": "line.no_redemption",
        "data": {
          "line": "2"
        }
      },
      {
        "code": "line.no_accrual",
        "data": {
          "line": "3"
        }
      },
      {
        "code": "redemption.limit",
        "data": {
          "eligible_total": 10000,
          "capacity": 10000,
          "max_share_bp": 10000,
          "balance": 1000,
          "max_points": 100
        }
      },
      {
        "code": "redemption.applied",
        "data": {
          "points": 100,
          "money": 10000
        }
      },
      {
        "code": "accrual.base",
        "data": {
          "base": 5000,
          "percent_bp": 500,
          "points": 2
        }
      }
    ]
  }
}
