# @vulog/aima-promocode

Promo codes and referral system — validate, submit, and query promo/referral codes.

## Installation

```sh
npm install @vulog/aima-promocode @vulog/aima-client @vulog/aima-core
```

## Usage

```ts
import { getClient } from '@vulog/aima-client';
import { checkInvitationCode, getPromoCodeByReference, submitPromoCode } from '@vulog/aima-promocode';

const client = getClient({ ... });

const referral = await checkInvitationCode(client, 'REFERRAL-CODE');

const promo = await getPromoCodeByReference(client, 'SUMMER2024');

await submitPromoCode(client, 'user-id', 'entity-id', 'PROMO-CODE');
```

## API Reference

### checkInvitationCode

```ts
checkInvitationCode(client: Client, referralCode: string): Promise<ReferralInfo | undefined>
```

Validates a referral/invitation code. Returns `undefined` on 404. `referralCode` must be non-empty.

| Param          | Type     | Description               |
| -------------- | -------- | ------------------------- |
| `client`       | `Client` | Authenticated AIMA client |
| `referralCode` | `string` | Non-empty referral code   |

**Returns:** `Promise<ReferralInfo | undefined>`

---

### getPromoCodeByReference

```ts
getPromoCodeByReference(client: Client, reference: string): Promise<PromoCode | undefined>
```

Returns the first promo code matching the given reference, or `undefined` if none found. `reference` must be non-empty.

| Param       | Type     | Description                    |
| ----------- | -------- | ------------------------------ |
| `client`    | `Client` | Authenticated AIMA client      |
| `reference` | `string` | Non-empty promo code reference |

**Returns:** `Promise<PromoCode | undefined>`

---

### getPromoCodeById

```ts
getPromoCodeById(client: Client, id: number): Promise<PromoCode | undefined>
```

Retrieves a promo code by its numeric ID. Returns `undefined` on 404. `id` must be a positive number.

| Param    | Type     | Description               |
| -------- | -------- | ------------------------- |
| `client` | `Client` | Authenticated AIMA client |
| `id`     | `number` | Positive promo code ID    |

**Returns:** `Promise<PromoCode | undefined>`

---

### submitPromoCode

```ts
submitPromoCode(client: Client, userId: string, entityId: string, code: string): Promise<string>
```

Submits a promo code for a user. Returns the raw API response string.

| Param      | Type     | Description               |
| ---------- | -------- | ------------------------- |
| `client`   | `Client` | Authenticated AIMA client |
| `userId`   | `string` | User identifier           |
| `entityId` | `string` | Entity identifier         |
| `code`     | `string` | Promo code to submit      |

**Returns:** `Promise<string>`

---

### submitReferral

```ts
submitReferral(client: Client, userId: string, entityId: string, code: string): Promise<void>
```

Submits a referral code for a user.

| Param      | Type     | Description               |
| ---------- | -------- | ------------------------- |
| `client`   | `Client` | Authenticated AIMA client |
| `userId`   | `string` | User identifier           |
| `entityId` | `string` | Entity identifier         |
| `code`     | `string` | Referral code to submit   |

**Returns:** `Promise<void>`

## Types

### ReferralInfo

```ts
{
    referralUserId: string;
    referralCode: string;
    referralPromocodeId: number;
    refereePromocodeId: number;
}
```

### PromoCode

```ts
{
    reference: string;
    walletType: string;
    status: 'ACTIVE' | 'INACTIVE';
    validityDuration: number;
    effectiveDate: string;
    expiryDate: string;
    validityEndDate: string;
    description?: string;
    id: number;
    fleetId: string;
    registration: boolean;
    maxUses: number;
    usages: PromoCodeUsage[];
}
```

### PromoCodeUsage

```ts
{
    id: number;
    walletUsage: 'TRIP' | 'PRODUCTS';
    discountCategory: 'CREDITS';
    percentage: number;
    amount: number;
    cappedPercentage: null;
    isOneTimeUsage: boolean;
    productGroup?: ProductGroup | null;
}
```

### ProductGroup

```ts
{
    id: string;
    name: string;
    status: 'ACTIVE' | 'INACTIVE';
}
```
