efrilm 951e154623 chore: base URL dev, exclude platform dir dari analyzer, dan naikkan versi ke 1.0.12+18
Perubahan ini sudah ada di working tree sebelum pekerjaan print dimulai; dikumpulkan di sini supaya tidak tercampur dengan commit perbaikan printer. Ditambah pembersihan import injectable yang tidak terpakai di main.dart.
2026-09-02 20:45:13 +07:00
2025-10-25 02:09:47 +07:00
2025-10-23 23:06:02 +07:00
2025-10-23 23:06:02 +07:00
2026-05-10 22:51:04 +07:00
2025-10-23 22:16:53 +07:00
2026-05-07 17:44:03 +07:00
2025-10-23 23:06:02 +07:00
2025-11-04 14:58:51 +07:00
2026-09-02 20:43:49 +07:00
2026-09-02 20:43:49 +07:00
2025-10-23 22:00:33 +07:00
2025-11-10 16:56:12 +07:00

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
Version Manager fvm — Flutter dipin di .fvmrc
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

  • FVM — project ini mengunci versi Flutter, jangan pakai Flutter global
  • Flutter 3.41.9 (Dart 3.11.5) — dipin di .fvmrc
  • Android SDK / Xcode (untuk iOS)
  • Firebase project yang sudah dikonfigurasi

Kenapa versinya dikunci? Stack code generation project ini (freezed 2.x, build_runner 2.5, analyzer 7.7.1) hanya paham bahasa Dart sampai 3.9. Flutter 3.44 ke atas membawa framework yang ditulis di bahasa 3.10+, dan analyzer 7.7.1 crash saat membacanya. Selama stack codegen belum dinaikkan, Flutter 3.41.9 adalah versi terbaru yang masih bisa menjalankan build_runner. Lihat Troubleshooting.

Instalasi

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

# Pasang FVM (sekali per mesin)
dart pub global activate fvm

# Ambil & pakai versi Flutter yang dipin di .fvmrc
fvm install
fvm use

# Install dependencies
fvm flutter pub get

# Generate kode
fvm dart run build_runner build

Semua perintah Flutter/Dart di project ini harus diawali fvm. flutter run tanpa fvm memakai Flutter global dan hasilnya bisa berbeda.

Menjalankan App

Environment tidak ditentukan otomatis dari debug/release — harus dioper lewat --dart-define:

# Development
fvm flutter run --dart-define=ENV=dev

# Production
fvm flutter run --dart-define=ENV=prod

# Production, release mode
fvm flutter run --release --dart-define=ENV=prod

Kalau ENV tidak dioper, nilainya jatuh ke dev (lihat defaultValue di lib/main.dart).

Di VSCode sudah tersedia konfigurasi Dev dan Prod di .vscode/launch.json, tinggal pilih di panel Run and Debug.

Build

--dart-define=ENV=prod wajib ikut, kalau tidak APK-nya akan memakai database dan base URL milik dev:

# APK
fvm flutter build apk --release --dart-define=ENV=prod

# App Bundle (Play Store)
fvm flutter build appbundle --release --dart-define=ENV=prod

# iOS
fvm flutter build ipa --release --dart-define=ENV=prod

Code Generation

Project ini banyak memakai kode generated (freezed, injectable, auto_route, json_serializable, flutter_gen). Kode itu wajib di-generate ulang setiap kali kamu:

  • menambah/mengubah kelas @freezed (entity, event, state, DTO)
  • menambah/mengubah anotasi DI (@injectable, @LazySingleton, @Injectable(as: ...))
  • menambah halaman baru dengan @RoutePage()
  • menambah aset di pubspec.yaml
# Sekali jalan
fvm dart run build_runner build

# Mode watch — regenerate otomatis saat file berubah, enak dipakai saat ngoding
fvm dart run build_runner watch

Hindari --delete-conflicting-outputs. Flag itu menghapus seluruh file generated sebelum mulai build. Kalau build-nya gagal di tengah jalan, kamu berakhir tanpa kode generated sama sekali dan project tidak bisa di-compile. Pakai hanya kalau build_runner benar-benar mengeluh soal konflik output, dan pastikan working tree-mu bersih dulu supaya bisa git restore.


Environment

Konfigurasi environment ada di lib/env.dart — itu sumber kebenarannya, jangan disalin ke sini karena gampang basi.

Environment Database
dev apskel_pos_staging.db
prod apskel_pos_prod.db

Environment dipilih dari --dart-define=ENV=... di lib/main.dart:

const String env = String.fromEnvironment('ENV', defaultValue: 'dev');
await configureDependencies(env);

Nilai env diteruskan ke injectable, yang lalu memilih antara DevEnv (@dev) dan ProdEnv (@prod). Menambah environment baru berarti menambah kelas ber-anotasi di lib/env.dart, lalu generate ulang.

Karena dev dan prod memakai nama database berbeda, berpindah environment di perangkat yang sama tidak akan mencampur datanya.


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:

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:

{
  "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

  • Selalu pakai fvm flutter / fvm dart, bukan flutter / dart global
  • Jangan edit injection.config.dart dan file *.freezed.dart / *.g.dart secara manual — file tersebut di-generate otomatis
  • Setelah mengubah kelas @freezed atau anotasi DI, jalankan build_runner sebelum menjalankan app
  • Gunakan log() dari dart:developer untuk logging, bukan print()
  • print() dinonaktifkan di release mode

Troubleshooting

build_runner gagal: Missing implementation of visitDotShorthandPropertyAccess

Kamu sedang memakai Flutter yang terlalu baru. Cek:

fvm flutter --version   # harus 3.41.9
flutter --version       # ini Flutter global, boleh versi apa saja

Kalau versinya bukan 3.41.9, artinya perintahnya jalan tanpa fvm. Log build juga memberi petunjuk yang sama:

SDK language version 3.13.0 is newer than `analyzer` language version 3.9.0

Perbaikannya: fvm use, lalu ulangi dengan awalan fvm.

Menaikkan Flutter melewati 3.41.x mengharuskan seluruh stack codegen ikut naik — freezed 2 → 3/4, build_runner → 2.16, injectable_generator 2 → 3, auto_route 9 → 10. freezed 3 mewajibkan tiap kelas dideklarasikan abstract/sealed dan menghapus when/map (diganti pattern matching), jadi ini pekerjaan tersendiri, bukan sambilan.

Project tidak bisa di-compile, banyak error _$Something tidak ditemukan

Kode generated-nya hilang atau belum dibuat. Jalankan:

fvm dart run build_runner build

fvm: command not found

FVM terpasang di ~/AppData/Local/Pub/Cache/bin (Windows) atau ~/.pub-cache/bin (macOS/Linux) yang mungkin belum ada di PATH. Tambahkan direktori itu ke PATH, atau panggil dengan path lengkap.

S
Description
No description provided
Readme
2.5 MiB
Languages
C++ 44.2%
CMake 36.3%
Dart 11%
Swift 3.3%
C 2.6%
Other 2.5%