# Apskel POS Flutter

Aplikasi Point of Sale (POS) berbasis Flutter untuk manajemen kasir restoran. Mendukung manajemen order, produk, meja, pelanggan, pembayaran, printer bluetooth/network, analitik, dan push notification via FCM.

---

## Fitur Utama

- **Autentikasi** — Login dengan email & password, logout, session management
- **Order Management** — Buat, kelola, dan proses order
- **Produk & Kategori** — Manajemen menu dan kategori produk
- **Meja** — Manajemen meja restoran
- **Pelanggan** — Data pelanggan dan riwayat transaksi
- **Checkout & Pembayaran** — Proses checkout dengan berbagai metode pembayaran
- **Split Bill** — Pembagian tagihan
- **Void & Refund** — Pembatalan dan pengembalian transaksi
- **Printer** — Cetak struk via Bluetooth dan Network printer
- **Analitik** — Dashboard, laporan penjualan, produk, kategori, payment method, profit/loss, inventory
- **Sinkronisasi** — Sinkronisasi data offline/online
- **Push Notification (FCM)** — Notifikasi real-time via Firebase Cloud Messaging

---

## Tech Stack

| Kategori | Library |
|---|---|
| State Management | `flutter_bloc` + `bloc` |
| Dependency Injection | `get_it` + `injectable` |
| Navigation | `auto_route` |
| HTTP Client | `dio` |
| Local Database | `sqflite` |
| Local Storage | `shared_preferences` |
| Firebase | `firebase_core`, `firebase_crashlytics`, `firebase_messaging` |
| Push Notification | `flutter_local_notifications` |
| Device Info | `device_info_plus`, `package_info_plus` |
| Code Generation | `freezed`, `json_serializable` |
| Printer | `print_bluetooth_thermal`, `flutter_esc_pos_network` |
| Chart | `fl_chart` |
| Connectivity | `connectivity_plus` |

---

## Arsitektur

Project menggunakan **Clean Architecture** dengan 4 layer:

```
lib/
├── application/        # BLoC — state management per fitur
├── domain/             # Entity, repository interface, failure
├── infrastructure/     # Implementasi repository, DTO, datasource
├── presentation/       # UI — pages, components, router
└── common/             # Shared utilities, DI modules, service, theme
```

### Struktur per Fitur

```
feature/
├── application/
│   └── feature_bloc.dart         # BLoC
├── domain/
│   ├── entities/                 # Domain model (freezed)
│   ├── repositories/             # Interface repository
│   └── failures/                 # Failure types
└── infrastructure/
    ├── datasources/
    │   ├── remote_data_provider.dart
    │   └── local_data_provider.dart
    ├── dtos/                     # Data Transfer Object (json_serializable)
    └── repositories/             # Implementasi repository
```

---

## Setup & Menjalankan

### Prasyarat

- Flutter SDK `^3.8.1`
- Dart SDK `^3.8.1`
- Android SDK / Xcode (untuk iOS)
- Firebase project yang sudah dikonfigurasi

### Instalasi

```bash
# Clone repository
git clone <repo-url>
cd apskel-pos-flutter-v2

# Install dependencies
flutter pub get

# Generate kode (freezed, injectable, auto_route, json_serializable)
dart run build_runner build --delete-conflicting-outputs
```

### Menjalankan App

```bash
# Development
flutter run

# Release
flutter run --release
```

App otomatis menggunakan environment `dev` saat debug dan `prod` saat release.

---

## Environment

Konfigurasi environment ada di `lib/env.dart`:

| Environment | Base URL | Database |
|---|---|---|
| `dev` | `https://api-pos.apskel.id` | `apskel_pos_dev.db` |
| `prod` | `https://api-pos.apskel.id` | `apskel_pos_dev.db` |

Environment dipilih otomatis di `main.dart`:

```dart
await configureDependencies(
  kReleaseMode ? Environment.prod : Environment.dev,
);
```

---

## Dependency Injection

DI menggunakan `get_it` + `injectable`. Semua service, repository, dan BLoC didaftarkan via annotation.

### Modul DI

| File | Isi |
|---|---|
| `di_firebase.dart` | `FirebaseMessaging`, `FlutterLocalNotificationsPlugin`, `DeviceInfoPlugin`, `PackageInfo` |
| `di_dio.dart` | `Dio` HTTP client |
| `di_shared_preferences.dart` | `SharedPreferences` |
| `di_database.dart` | `DatabaseHelper` (SQLite) |
| `di_auto_route.dart` | `AppRouter` |
| `di_connectivity.dart` | `Connectivity` |

Setelah menambah atau mengubah class yang menggunakan annotation injectable, jalankan:

```bash
dart run build_runner build --delete-conflicting-outputs
```

---

## Firebase & FCM

### Setup

Firebase sudah dikonfigurasi di `android/app/google-services.json`. Inisialisasi dilakukan di `main.dart` sebelum app berjalan.

### FCM Service

`FcmService` (`lib/common/service/fcm_service.dart`) menangani:

- Request permission notifikasi (Android 13+ / iOS)
- Ambil dan log FCM token
- Foreground notification via `flutter_local_notifications`
- Background & terminated message handler
- Subscribe/unsubscribe topic

FCM token dikirim ke server saat login bersama device info.

### Login Payload

Saat login, app mengirim data berikut ke API:

```json
{
  "email": "user@example.com",
  "password": "secret",
  "fcm_token": "dXj3k9...",
  "device_id": "abc123",
  "device_name": "Samsung Galaxy Tab S8",
  "device_type": "tablet",
  "platform": "android",
  "app_version": "1.0.4+9",
  "os_version": "Android 13 (SDK 33)"
}
```

Nilai valid: `device_type` → `mobile | tablet | desktop`, `platform` → `android | ios | web`

---

## Printer

Mendukung dua jenis printer:

- **Bluetooth** — via `print_bluetooth_thermal`
- **Network (LAN)** — via `flutter_esc_pos_network`

---

## Orientasi Layar

App dikunci ke mode **landscape** (kiri & kanan) karena didesain untuk tablet POS.

---

## Catatan Development

- Jangan edit `injection.config.dart` dan file `*.freezed.dart` / `*.g.dart` secara manual — file tersebut di-generate otomatis
- Gunakan `log()` dari `dart:developer` untuk logging, bukan `print()`
- `print()` dinonaktifkan di release mode
