efrilmandClaude Opus 5 1b4caf45d5 fix: cetak semua station tanpa saling membatalkan
printStruckOrder berhenti di kegagalan pertama, jadi satu station gagal membuat semua station sesudahnya tidak pernah dicoba. Karena checker (Bluetooth) berada sebelum kitchen dan bar (Network) dalam rantai, satu kegagalan koneksi Bluetooth menghilangkan tiga tiket sekaligus, dua di antaranya di jaringan yang sehat.

Jalur printer Network juga mengembalikan right(false) saat gagal, yang lolos sebagai sukses ke pemanggil, sehingga kasir melihat 'berhasil dicetak' padahal tidak ada kertas keluar.

Perubahan: repository kini mengembalikan Stream<List<PrintStationResult>> dan tetap mencoba semua station; kegagalan Network jadi left; station Network berjalan paralel dengan rantai Bluetooth; station Bluetooth dikelompokkan per alamat agar perpindahan koneksi seminimal mungkin; CapabilityProfile di-cache.

Bluetooth: retry connect dengan backoff dan disconnect di tiap percobaan ulang (socket RFCOMM setengah terbuka membuat connect berulang gagal identik), jeda settle dikembalikan setelah dipangkas ke 300ms, satu lock untuk seluruh radio (bukan per MAC), izin runtime dipastikan di jalur cetak, dan repository jadi LazySingleton agar state koneksi benar-benar dibagi.

UI: dialog progres per-station menggantikan toast tunggal, lengkap dengan durasi tiap station dan tombol cetak ulang khusus yang gagal. Enam listener duplikat di halaman diganti satu listener terpusat di AppWidget. Menu Print di detail transaksi dapat item Print All.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 20:44:14 +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
2026-03-01 20:02:12 +07:00
2025-11-10 16:56:12 +07:00
2026-05-24 00:59:02 +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
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

# 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

# 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:

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:

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

  • 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
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%