# Business Intelligence API Documentation

## Overview

Business Intelligence APIs provide access to data warehouse views for reporting and analytics purposes. All endpoints require authentication with `SuperAdmin` or `CompanyAdmin` role.

**Base URL**: `/api/BusinessIntelligence`

**Authorization**: Bearer Token (JWT)

---

## Authentication

### Get Token

Obtain an access token for API authentication.

**Endpoint**: `POST /api/Account/GetToken`

**Authorization**: None (Anonymous)

**Request Body**:
```json
{
  "username": "string",
  "password": "string",
  "refreshToken": "string"
}
```

**Request Properties**:
- `username` (string, required for password grant): User's login username
- `password` (string, required for password grant): User's password
- `refreshToken` (string, required for refresh token grant): Refresh token for renewing access token

**Response** (200 OK):
```json
{
  "userId": "string", 
  "access_token": "string",
  "refresh_token": "string",
  "token_type": "Bearer",
  "expires_in": 0,
  "userName": "string",
  "email": "string",
  "emailConfirmed": "boolean",
  "issued": "2024-01-01T00:00:00Z",
  "expires": "2024-01-01T00:00:00Z",  
  "roles": "string",
  "imageUrl": "string",
  "language": "string",
  "hasCovers": "boolean",
  "error": "string",
  "error_description": "string"
}
```

**Response Properties**:
- `access_token` (string): JWT token to use in Authorization header as "Bearer {token}"
- `refresh_token` (string): Token to obtain a new access token when expired
- `token_type` (string): Always "Bearer"
- `expires_in` (integer): Token validity in seconds
- `userId` (string): Unique user identifier
- `userName` (string): User's login name
- `email` (string): User's email address
- `roles` (string): Comma-separated list of user roles
- `issued` (datetime): Token issue timestamp
- `expires` (datetime): Token expiration timestamp
- `error` (string): Error code if authentication failed
- `error_description` (string): Human-readable error description

**Error Responses**:
- `401 Unauthorized`: Invalid credentials or user disabled
- `404 Not Found`: User not found
- `500 Internal Server Error`: Server error during authentication

**Example Request (Password Grant)**:
```json
{
  "username": "admin@example.com",
  "password": "SecurePassword123!"
}
```

**Example Request (Refresh Token Grant)**:
```json
{
  "username": "admin@example.com",
  "refreshToken": "your-refresh-token-here"
}
```

**Usage in API Calls**:
```
Authorization: Bearer {access_token}
```

---

## Master Data Endpoints

### Get Categories

Retrieve all business intelligence categories from `vwBICategories` view.

**Endpoint**: `GET /api/BusinessIntelligence/Categories`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "name": "string",
    "fbType": 0,
    "isCover": false
  }
]
```

**Response Properties**:
- `id` (integer): Category unique identifier
- `name` (string): Category name
- `fbType` (integer): Food & Beverage type (0=Food, 1=Beverage, 2=Other)
- `isCover` (boolean): Whether this is a cover/service category

**Example Response**:
```json
[
  {
    "id": 1,
    "name": "Appetizers",
    "fbType": 0,
    "isCover": false
  },
  {
    "id": 2,
    "name": "Wine",
    "fbType": 1,
    "isCover": false
  }
]
```

---

### Get Cost Centers

Retrieve all business intelligence cost centers from `vwBICostCenters` view.

**Endpoint**: `GET /api/BusinessIntelligence/CostCenters`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "id": "string",
    "name": "string"
  }
]
```

**Response Properties**:
- `id` (string): Cost center unique identifier
- `name` (string): Cost center name

**Example Response**:
```json
[
  {
    "id": "CC001",
    "name": "Main Kitchen"
  },
  {
    "id": "CC002",
    "name": "Bar"
  }
]
```

---

### Get Products

Retrieve all business intelligence products from `vwBIProducts` view.

**Endpoint**: `GET /api/BusinessIntelligence/Products`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "categoryId": 0,
    "name": "string",
    "code": "string",
    "vat": 0.0,
    "type": 0,
    "yield": 0.0,
    "isCover": false,
    "unitId": 0
  }
]
```

**Response Properties**:
- `id` (integer): Product unique identifier
- `categoryId` (integer, nullable): Associated category ID
- `name` (string): Product name
- `code` (string): Product code
- `vat` (double, nullable): VAT percentage
- `type` (integer, nullable): Product type
- `yield` (double, nullable): Product yield percentage
- `isCover` (boolean): Whether this is a cover/service product
- `unitId` (integer, nullable): Base unit of measure ID

**Example Response**:
```json
[
  {
    "id": 101,
    "categoryId": 1,
    "name": "Caesar Salad",
    "code": "SALAD001",
    "vat": 10.0,
    "type": 1,
    "yield": 95.0,
    "isCover": false,
    "unitId": 5
  }
]
```

---

### Get Goods

Retrieve all business intelligence goods/items from `vwBIGoods` view.

**Endpoint**: `GET /api/BusinessIntelligence/Goods`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "code": "string",
    "name": "string",
    "aliasName": "string",
    "categoryId": 0,
    "categoryName": "string",
    "fbType": 0,
    "isFresh": false,
    "tag": "string",
    "supplier": "string",
    "unit1": "string",
    "unit2": "string",
    "ratio1": 0.0,
    "ratio2": 0.0
  }
]
```

**Response Properties**:
- `id` (integer): Goods unique identifier
- `code` (string): Goods code
- `name` (string): Goods name
- `aliasName` (string): Alternative name
- `categoryId` (integer, nullable): Associated category ID
- `categoryName` (string): Category name
- `fbType` (integer, nullable): Food & Beverage type
- `isFresh` (boolean): Whether this is a fresh product
- `tag` (string): Product tag/classification
- `supplier` (string): Default supplier name
- `unit1` (string): Primary unit of measure
- `unit2` (string): Secondary unit of measure
- `ratio1` (double, nullable): Primary conversion ratio
- `ratio2` (double, nullable): Secondary conversion ratio

**Example Response**:
```json
[
  {
    "id": 501,
    "code": "GOODS001",
    "name": "Tomatoes",
    "aliasName": "Fresh Tomatoes",
    "categoryId": 10,
    "categoryName": "Vegetables",
    "fbType": 0,
    "isFresh": true,
    "tag": "Organic",
    "supplier": "Local Farms Inc",
    "unit1": "kg",
    "unit2": "pcs",
    "ratio1": 1.0,
    "ratio2": 0.15
  }
]
```

---

### Get Stores

Retrieve all business intelligence stores from `vwBIStores` view.

**Endpoint**: `GET /api/BusinessIntelligence/Stores`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "code": "string",
    "name": "string",
    "area": "string",
    "group": "string",
    "company": "string"
  }
]
```

**Response Properties**:
- `code` (string): Store unique code
- `name` (string): Store name
- `area` (string): Geographical area
- `group` (string): Store group
- `company` (string): Owning company

**Example Response**:
```json
[
  {
    "code": "STORE001",
    "name": "Main Street Restaurant",
    "area": "Downtown",
    "group": "Premium Dining",
    "company": "MyBusiness Corp"
  }
]
```

---

### Get Units

Retrieve all business intelligence units of measure from `vwBIUnits` view.

**Endpoint**: `GET /api/BusinessIntelligence/Units`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "name": "string"
  }
]
```

**Response Properties**:
- `id` (integer): Unit unique identifier
- `name` (string): Unit name

**Example Response**:
```json
[
  {
    "id": 1,
    "name": "kg"
  },
  {
    "id": 2,
    "name": "liter"
  },
  {
    "id": 3,
    "name": "pcs"
  }
]
```

---

## Transaction Data Endpoints

All transaction endpoints use the following filter structure:

**DateAndStoreFilter** (Request Body):
```json
{
  "dateFilter": {
    "start": "2024-01-01T00:00:00Z",
    "end": "2024-01-31T23:59:59Z",
    "list": ["2024-01-01T00:00:00Z", "2024-01-15T00:00:00Z"]
  },
  "stores": ["STORE001", "STORE002"]
}
```

**Filter Properties**:
- `dateFilter` (object): Date range filter
  - `start` (datetime, nullable): Start date (inclusive)
  - `end` (datetime, nullable): End date (inclusive)
  - `list` (array of datetime, nullable): Specific dates to include
- `stores` (array of string, nullable): Store codes to filter by

---

### Get Sellings

Retrieve business intelligence sellings data from `vwBISellings` view.

**Endpoint**: `POST /api/BusinessIntelligence/Sellings`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter (see above)

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "date": "2024-01-01T00:00:00Z",
    "productId": 0,
    "foodCost": 0.0,
    "price": 0.0,
    "vat": 0.0,
    "quantity": 0.0,
    "store": "string",
    "type": "string",
    "costCenterId": "string",
    "documentNumber": "string",
    "time": "string",
    "isWaste": false,
    "discount": 0.0
  }
]
```

**Response Properties**:
- `id` (integer): Selling record ID
- `date` (datetime, nullable): Transaction date
- `productId` (integer, nullable): Product ID
- `foodCost` (double, nullable): Food cost amount
- `price` (double, nullable): Selling price
- `vat` (double, nullable): VAT amount
- `quantity` (double, nullable): Quantity sold
- `store` (string): Store code
- `type` (string): Transaction type
- `costCenterId` (string): Cost center ID
- `documentNumber` (string): Document/receipt number
- `time` (string): Transaction time
- `isWaste` (boolean): Whether this is a waste transaction
- `discount` (double, nullable): Discount applied

**Example Request**:
```json
{
  "dateFilter": {
    "start": "2024-01-01T00:00:00Z",
    "end": "2024-01-31T23:59:59Z"
  },
  "stores": ["STORE001"]
}
```

---

### Get Purchases

Retrieve business intelligence purchases data from `vwBIPurchase` view.

**Endpoint**: `POST /api/BusinessIntelligence/Purchases`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "store": "string",
    "costCenterId": "string",
    "costCenterName": "string",
    "goodsId": 0,
    "goodsCode": "string",
    "goodsName": "string",
    "goodsAlias": "string",
    "quantity": 0.0,
    "unit": "string",
    "quantityBase": 0.0,
    "unitBase": "string",
    "date": "2024-01-01T00:00:00Z",
    "price": 0.0,
    "priceBase": 0.0,
    "ratio": 0.0,
    "amount": 0.0,
    "documentNumber": "string",
    "supplierId": 0,
    "supplierName": "string",
    "discount": 0.0,
    "isTraining": false
  }
]
```

**Response Properties** (extends BIWarehouse):
- `id` (integer): Purchase record ID
- `store` (string): Store code
- `costCenterId` (string): Cost center ID
- `costCenterName` (string): Cost center name
- `goodsId` (integer, nullable): Goods ID
- `goodsCode` (string): Goods code
- `goodsName` (string): Goods name
- `goodsAlias` (string): Goods alias
- `quantity` (double, nullable): Purchase quantity in unit
- `unit` (string): Unit of measure
- `quantityBase` (double, nullable): Quantity in base unit
- `unitBase` (string): Base unit of measure
- `date` (datetime, nullable): Purchase date
- `price` (double, nullable): Unit price
- `priceBase` (double, nullable): Base unit price
- `ratio` (double, nullable): Conversion ratio
- `amount` (double, nullable): Total amount
- `documentNumber` (string): Invoice/document number
- `supplierId` (integer, nullable): Supplier ID
- `supplierName` (string): Supplier name
- `discount` (double, nullable): Discount percentage
- `isTraining` (boolean): Whether this is training data

---

### Get Wastes

Retrieve business intelligence wastes data from `vwBIWaste` view.

**Endpoint**: `POST /api/BusinessIntelligence/Wastes`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "store": "string",
    "costCenterId": "string",
    "costCenterName": "string",
    "goodsId": 0,
    "goodsCode": "string",
    "goodsName": "string",
    "goodsAlias": "string",
    "quantity": 0.0,
    "unit": "string",
    "quantityBase": 0.0,
    "unitBase": "string",
    "date": "2024-01-01T00:00:00Z",
    "price": 0.0,
    "priceBase": 0.0,
    "ratio": 0.0,
    "amount": 0.0,
    "wasteType": 0
  }
]
```

**Response Properties** (extends BIWarehouse):
- Common properties same as Purchases
- `wasteType` (integer, nullable): Type of waste (classification)

---

### Get Inventories

Retrieve business intelligence inventories data from `vwBIInventory` view.

**Endpoint**: `POST /api/BusinessIntelligence/Inventories`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "store": "string",
    "costCenterId": "string",
    "costCenterName": "string",
    "goodsId": 0,
    "goodsCode": "string",
    "goodsName": "string",
    "goodsAlias": "string",
    "quantity": 0.0,
    "unit": "string",
    "quantityBase": 0.0,
    "unitBase": "string",
    "date": "2024-01-01T00:00:00Z",
    "price": 0.0,
    "priceBase": 0.0,
    "ratio": 0.0,
    "amount": 0.0
  }
]
```

**Response Properties** (extends BIWarehouse):
- All properties same as Purchases (without supplier and discount fields)

---

### Get Transfers

Retrieve business intelligence transfers data from `vwBITransfers` view.

**Endpoint**: `POST /api/BusinessIntelligence/Transfers`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "sourceStore": "string",
    "targetStore": "string",
    "sourceCostCenterId": "string",
    "sourceCostCenterName": "string",
    "targetCostCenterId": "string",
    "targetCostCenterName": "string",
    "goodsId": 0,
    "goodsName": "string",
    "quantity": 0.0,
    "unit": "string",
    "quantityBase": 0.0,
    "unitBase": "string",
    "date": "2024-01-01T00:00:00Z",
    "price": 0.0,
    "priceBase": 0.0,
    "ratio": 0.0,
    "amount": 0.0
  }
]
```

**Response Properties**:
- `id` (integer): Transfer record ID
- `sourceStore` (string): Source store code
- `targetStore` (string): Target store code
- `sourceCostCenterId` (string): Source cost center ID
- `sourceCostCenterName` (string): Source cost center name
- `targetCostCenterId` (string): Target cost center ID
- `targetCostCenterName` (string): Target cost center name
- Other properties same as BIWarehouse base

---

### Get Consumptions

Retrieve business intelligence consumptions data from `vwBIConsumptions` view.

**Endpoint**: `POST /api/BusinessIntelligence/Consumptions`

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "inner_Code": "string",
    "store": "string",
    "costCenterId": "string",
    "costCenterName": "string",
    "goodsId": 0,
    "goodsName": "string",
    "quantity": 0.0,
    "unit": "string",
    "quantityBase": 0.0,
    "unitBase": "string",
    "date": "2024-01-01T00:00:00Z",
    "price": 0.0,
    "priceBase": 0.0,
    "ratio": 0.0,
    "amount": 0.0
  }
]
```

**Response Properties** (extends BIWarehouse):
- `inner_Code` (string): Internal consumption code
- Other properties same as BIWarehouse base

---

### Get Consumption Analysis

Retrieve detailed consumption analysis with thresholds and severity indicators.

**Endpoint**: `POST /api/BusinessIntelligence/Consumptions` (Note: Same route as above, returns analysis)

**Authorization**: Bearer Token (SuperAdmin or CompanyAdmin)

**Request Body**: DateAndStoreFilter

**Response** (200 OK):
```json
[
  {
    "id": 0,
    "code": "string",
    "category": {
      "id": 0,
      "name": "string"
    },
    "goods": {
      "id": 0,
      "name": "string",
      "code": "string"
    },
    "price": 0.0,
    "priceBase": 0.0,
    "units": {
      "baseUnit": "string",
      "warehouseUnit": "string"
    },
    "baseConsumption": 0.0,
    "warehouseConsumption": 0.0,
    "purchase": 0.0,
    "purchaseBase": 0.0,
    "transfert": 0.0,
    "transfertBase": 0.0,
    "inventory": {
      "quantity": 0.0,
      "quantityBase": 0.0,
      "date": "2024-01-01T00:00:00Z",
      "amount": 0.0
    },
    "prevInventory": {
      "quantity": 0.0,
      "quantityBase": 0.0,
      "date": "2024-01-01T00:00:00Z",
      "amount": 0.0
    },
    "inventoryExact": {
      "quantity": 0.0,
      "quantityBase": 0.0,
      "date": "2024-01-01T00:00:00Z",
      "amount": 0.0
    },
    "prevInventoryExact": {
      "quantity": 0.0,
      "quantityBase": 0.0,
      "date": "2024-01-01T00:00:00Z",
      "amount": 0.0
    },
    "adjustments": 0.0,
    "adjustmentsBase": 0.0,
    "available": 0.0,
    "final": 0.0,
    "effectiveConsumption": 0.0,
    "rest": 0.0,
    "availableBase": 0.0,
    "finalBase": 0.0,
    "effectiveConsumptionBase": 0.0,
    "restBase": 0.0,
    "effectiveConsumptionValue": 0.0,
    "effectiveConsumptionPerc": 0.0,
    "restValue": 0.0,
    "restVariancePerc": 0.0,
    "deviationAlert": false,
    "transfertAmount": 0.0,
    "adjustmentsAmount": 0.0,
    "purchaseAmount": 0.0,
    "noInitialInventoryDate": false,
    "err1": false,
    "err2": false,
    "err3": false,
    "absValue": 0.0,
    "absAmount": 0.0,
    "impact": 0.0,
    "weighthOverTotal": 0.0,
    "severityIndex": 0.0,
    "meaning": false,
    "severityStatus": "None"
  }
]
```

**Response Properties (ConsumptioItem)**:
- `id` (integer): Item ID
- `code` (string): Goods code
- `category` (object): Category information
- `goods` (object): Goods details
- `price` (double): Warehouse unit price
- `priceBase` (double): Base unit price
- `units` (object): Units of measure
- `baseConsumption` (double): Theoretical consumption (base unit)
- `warehouseConsumption` (double): Theoretical consumption (warehouse unit)
- `purchase` (double): Purchases in period
- `transfert` (double): Net transfers
- `inventory` (object): Final inventory
- `prevInventory` (object): Initial inventory
- `adjustments` (double): Adjustments/wastes
- `effectiveConsumption` (double): Calculated actual consumption
- `rest` (double): Variance (effective - theoretical)
- `restValue` (double): Variance value
- `severityIndex` (double): Severity score
- `severityStatus` (enum): Severity level (None, NotSignificant, Favorable, Ok, Warning, Critical)

**SeverityStatus Enum Values**:
- `None` (0): No status
- `NotSignificant` (1): Variance not significant
- `Favorable` (2): Positive variance
- `Ok` (4): Acceptable variance
- `Warning` (8): Variance requires attention
- `Critical` (16): Variance requires immediate action

---

## Common Data Models

### DateFilter
```json
{
  "start": "2024-01-01T00:00:00Z",
  "end": "2024-01-31T23:59:59Z",
  "list": ["2024-01-15T00:00:00Z"]
}
```

### BaseDTO
```json
{
  "id": 0,
  "name": "string"
}
```

### SimpleGoodsDTO
```json
{
  "id": 0,
  "name": "string",
  "code": "string"
}
```

### Units
```json
{
  "baseUnit": "string",
  "warehouseUnit": "string"
}
```

### InventoryQuantity
```json
{
  "quantity": 0.0,
  "quantityBase": 0.0,
  "date": "2024-01-01T00:00:00Z",
  "amount": 0.0
}
```

---

## Error Responses

All endpoints may return the following error responses:

### 400 Bad Request
```json
{
  "message": "string",
  "modelState": {}
}
```

### 401 Unauthorized
```json
{
  "message": "User is not authorized"
}
```

### 403 Forbidden
```json
{
  "message": "Access denied"
}
```

### 500 Internal Server Error
```json
{
  "message": "Internal server error occurred",
  "exceptionMessage": "string",
  "exceptionType": "string",
  "stackTrace": "string"
}
```

---

## Best Practices

1. **Authentication**: Always include Bearer token in Authorization header
2. **Date Ranges**: Use appropriate date ranges to limit data volume
3. **Store Filtering**: Filter by specific stores when possible
4. **Caching**: Master data (Categories, Products, etc.) changes infrequently - cache locally
5. **Pagination**: For large datasets, consider implementing client-side pagination
6. **Error Handling**: Implement retry logic for 500 errors, handle 401 by refreshing token

---

## Examples

### Get Token and Use API

```javascript
// 1. Get token
const tokenResponse = await fetch('/api/Account/GetToken', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'user@example.com',
    password: 'password123'
  })
});
const token = await tokenResponse.json();

// 2. Use token to call BI API
const sellingsResponse = await fetch('/api/BusinessIntelligence/Sellings', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token.access_token}`
  },
  body: JSON.stringify({
    dateFilter: {
      start: '2024-01-01T00:00:00Z',
      end: '2024-01-31T23:59:59Z'
    },
    stores: ['STORE001']
  })
});
const sellings = await sellingsResponse.json();
```

### C# Example
```csharp
// 1. Get token
var client = new HttpClient();
var tokenRequest = new { username = "user@example.com", password = "password123" };
var tokenResponse = await client.PostAsJsonAsync("/api/Account/GetToken", tokenRequest);
var token = await tokenResponse.Content.ReadAsAsync<TokenResponse>();

// 2. Use token
client.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", token.access_token);

var filter = new DateAndStoreFilter {
    DateFilter = new DateFilter { 
        Start = new DateTime(2024, 1, 1), 
        End = new DateTime(2024, 1, 31) 
    },
    Stores = new List<string> { "STORE001" }
};
var response = await client.PostAsJsonAsync("/api/BusinessIntelligence/Purchases", filter);
var purchases = await response.Content.ReadAsAsync<List<BIPurchaseDTO>>();
```

---

## Support

For technical support or questions, contact the development team.

**Version**: 1.0  
**Last Updated**: 2024
