Overview

This document describes how subscriptions, payments, orders and products are related in this application. It is intended to be used as a reference when creating billing records, admin displays and when implementing billing/reporting features.

Entities

- Payment (`App\Models\Payment`)
  - Fields of interest: `id`, `user_id`, `payable_type`, `payable_id`, `subscription_date`, `expiry_date`, `plan`, `amount`, `amount_paid`, `currency`, `status`, `data`
  - Relationship: `payment->payable` is polymorphic (can point to an `Order` or other payable entity).

- Order (Vanilo Order)
  - Contains order-level data and `items` (order items).
  - Relationship: `order->items()` returns `OrderItem` models.

- OrderItem (Vanilo OrderItem)
  - Fields of interest: `product_type`, `product_id`, `quantity`, `price`.
  - Relationship: `orderItem->product` resolves the product model (polymorphic / proxied by Vanilo).

- Product (`App\Models\Product`, Vanilo)
  - Standard Vanilo product with `sku`, `name`, media, etc.

- GiftedProduct (`App\Models\GiftedProduct` / `gifted_products` table)
  - Grants temporary access for a given `user_id` + `sku` between `start_date` and `end_date`.
  - Not connected to Order/Payment records; middleware checks these rows as a fallback for plugin access.

Relationship summary

Payment -> (polymorphic) payable -> Order -> OrderItem -> Product

- Typical flow for a purchased subscription:
  1. An `Order` is created with `OrderItem` rows pointing to products.
  2. A `Payment` is created for the order and stores `payable_type=Order` and `payable_id=<order_id>`, plus `subscription_date` / `expiry_date`.
  3. Admin/UI can follow the `Payment` → `payable` (Order) → `items` → `product` chain to show which products a subscription covers.

- Gifted access flow:
  - `GiftedProduct` rows are created and contain `user_id`, `sku` (and optional `product_type`/`product_id`), `start_date`, `end_date`.
  - The middleware checks completed orders first; if none found, it queries `gifted_products` for an active row matching the user and SKU.

Example queries and code snippets

Get payments (subscriptions) for a user:

```php
$payments = \App\Models\Payment::where('user_id', $user->id)
    ->orderByDesc('subscription_date')
    ->get();
```

Resolve products covered by a payment (if payable is an Order):

```php
$payment = $payments->first();
$payable = $payment->payable; // check instance
if ($payable instanceof \Vanilo\Order\Models\Order) {
    foreach ($payable->items as $item) {
        $product = $item->product; // Vanilo product
        // use $product->sku, $product->name
    }
}
```

Check gifted access for a user and SKU (middleware):

```php
$now = now();
$hasGift = \App\Models\GiftedProduct::where('user_id', $user->id)
    ->where('sku', $sku)
    ->where('start_date', '<=', $now)
    ->where('end_date', '>=', $now)
    ->exists();
```

Notes & Recommendations

- When generating billing reports, prefer to use `Payment` rows as your primary subscription records (they contain dates/status and link to the payable).
- Not all `Payment.payable` values are guaranteed to be `Order` instances — check `payable_type` / class before assuming methods.
- Consider adding Eloquent accessors/helpers on `Payment` and `User` for convenience, e.g. `Payment::payableOrder()` or `User::subscriptions()` which return normalized structures for UI consumption.
- If you need a visual diagram, I can add a Mermaid diagram file under `docs/` to show the relationships graphically.

Questions

- Do you want a `User::subscriptions()` helper implemented that returns payments with attached product lists?
- Should I add a Mermaid diagram file `docs/billing-relationships.mmd` to visualize this?