checkpoint

master
a2nr 2025-08-24 13:49:16 +07:00
parent 28e99e4e2f
commit c2e6f6b945
9 changed files with 94 additions and 208 deletions

3
.gitignore vendored
View File

@ -41,3 +41,6 @@ app.*.map.json
/android/app/debug /android/app/debug
/android/app/profile /android/app/profile
/android/app/release /android/app/release
# Deprecated files
/deprecated/

View File

@ -1,23 +0,0 @@
# Instruksi untuk menambahkan logo toko ke aplikasi:
1. Tambahkan file gambar logo ke folder `assets/images/` dengan nama `store_logo.png`
2. Tambahkan path ke file `pubspec.yaml` agar file gambar tersebut tersedia di aplikasi:
```yaml
flutter:
assets:
- assets/images/
```
3. Untuk menyimpan path logo ke shared preferences, panggil fungsi:
```dart
import 'package:cashumit/utils/store_logo_utils.dart';
// Simpan path logo
await saveStoreLogoPath('assets/images/store_logo.png');
// Hapus path logo jika diperlukan
await removeStoreLogoPath();
```
4. Untuk menguji pencetakan logo, pastikan printer thermal mendukung pencetakan gambar.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

After

Width:  |  Height:  |  Size: 91 B

View File

@ -3,6 +3,8 @@ import 'package:cashumit/screens/transaction_screen.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cashumit/screens/receipt_screen.dart'; import 'package:cashumit/screens/receipt_screen.dart';
import 'package:cashumit/utils/store_logo_utils.dart'; import 'package:cashumit/utils/store_logo_utils.dart';
import 'package:provider/provider.dart';
import 'package:cashumit/providers/receipt_provider.dart';
void main() async { void main() async {
// Ensure WidgetsFlutterBinding is initialized for async operations // Ensure WidgetsFlutterBinding is initialized for async operations
@ -11,7 +13,14 @@ void main() async {
// Initialize the store logo from asset // Initialize the store logo from asset
await copyAndSaveStoreLogoFromAsset('assets/images/store_logo.png'); await copyAndSaveStoreLogoFromAsset('assets/images/store_logo.png');
runApp(const MyApp()); runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ReceiptProvider()),
],
child: const MyApp(),
),
);
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {

View File

@ -22,6 +22,13 @@ class _StoreDisclaimerState extends State<StoreDisclaimer> {
_loadDisclaimerText(); _loadDisclaimerText();
} }
@override
void didUpdateWidget(covariant StoreDisclaimer oldWidget) {
super.didUpdateWidget(oldWidget);
// Memuat ulang teks ketika widget diupdate
_loadDisclaimerText();
}
/// Memuat teks disclaimer dari shared preferences /// Memuat teks disclaimer dari shared preferences
Future<void> _loadDisclaimerText() async { Future<void> _loadDisclaimerText() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();

View File

@ -14,9 +14,9 @@ class ThankYouPantun extends StatefulWidget {
class _ThankYouPantunState extends State<ThankYouPantun> { class _ThankYouPantunState extends State<ThankYouPantun> {
String _thankYouText = '*** TERIMA KASIH ***'; String _thankYouText = '*** TERIMA KASIH ***';
String _pantunText = 'Belanja di toko kami, hemat dan nyaman,\n' String _pantunText = 'Belanja di toko kami, hemat dan nyaman,\\n'
'Dengan penuh semangat, kami siap melayani,\n' 'Dengan penuh semangat, kami siap melayani,\\n'
'Harapan kami, Anda selalu puas,\n' 'Harapan kami, Anda selalu puas,\\n'
'Sampai jumpa lagi, selamat tinggal.'; 'Sampai jumpa lagi, selamat tinggal.';
@override @override
@ -25,6 +25,13 @@ class _ThankYouPantunState extends State<ThankYouPantun> {
_loadThankYouText(); _loadThankYouText();
} }
@override
void didUpdateWidget(covariant ThankYouPantun oldWidget) {
super.didUpdateWidget(oldWidget);
// Memuat ulang teks ketika widget diupdate
_loadThankYouText();
}
/// Memuat teks terima kasih dan pantun dari shared preferences /// Memuat teks terima kasih dan pantun dari shared preferences
Future<void> _loadThankYouText() async { Future<void> _loadThankYouText() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
@ -34,9 +41,9 @@ class _ThankYouPantunState extends State<ThankYouPantun> {
if (mounted) { if (mounted) {
setState(() { setState(() {
_thankYouText = savedThankYou ?? '*** TERIMA KASIH ***'; _thankYouText = savedThankYou ?? '*** TERIMA KASIH ***';
_pantunText = savedPantun ?? 'Belanja di toko kami, hemat dan nyaman,\n' _pantunText = savedPantun ?? 'Belanja di toko kami, hemat dan nyaman,\\n'
'Dengan penuh semangat, kami siap melayani,\n' 'Dengan penuh semangat, kami siap melayani,\\n'
'Harapan kami, Anda selalu puas,\n' 'Harapan kami, Anda selalu puas,\\n'
'Sampai jumpa lagi, selamat tinggal.'; 'Sampai jumpa lagi, selamat tinggal.';
}); });
} }

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: archive name: archive
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.7" version: "3.6.1"
async: async:
dependency: transitive dependency: transitive
description: description:
@ -25,14 +25,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.9" version: "2.2.9"
bidi:
dependency: transitive
description:
name: bidi
sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d"
url: "https://pub.dev"
source: hosted
version: "2.0.13"
bluetooth_print: bluetooth_print:
dependency: "direct main" dependency: "direct main"
description: description:
@ -96,6 +88,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.6" version: "3.0.6"
csslib:
dependency: transitive
description:
name: csslib
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -165,6 +165,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_esc_pos_utils:
dependency: "direct main"
description:
name: flutter_esc_pos_utils
sha256: dd0dbd9738c07ea9a6b078f5db18feb2d5d970b4de0ce34427d66665f639eaec
url: "https://pub.dev"
source: hosted
version: "0.0.5"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -199,6 +207,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
gbk_codec:
dependency: transitive
description:
name: gbk_codec
sha256: "3af5311fc9393115e3650ae6023862adf998051a804a08fb804f042724999f61"
url: "https://pub.dev"
source: hosted
version: "0.4.0"
google_fonts: google_fonts:
dependency: "direct main" dependency: "direct main"
description: description:
@ -207,6 +223,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.3.0"
hex:
dependency: transitive
description:
name: hex
sha256: "4e7cd54e4b59ba026432a6be2dd9d96e4c5205725194997193bf871703b82c4a"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
html:
dependency: transitive
description:
name: html
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
url: "https://pub.dev"
source: hosted
version: "0.15.6"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -232,13 +264,13 @@ packages:
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
image: image:
dependency: transitive dependency: "direct main"
description: description:
name: image name: image
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.5.4" version: "3.3.0"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -383,6 +415,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
open_file: open_file:
dependency: "direct main" dependency: "direct main"
description: description:
@ -515,10 +555,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: pdf name: pdf
sha256: "28eacad99bffcce2e05bba24e50153890ad0255294f4dd78a17075a2ba5c8416" sha256: "10659b915e65832b106f6d1d213e09b789cc1f24bf282ee911e49db35b96be4d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.11.3" version: "3.8.4"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
@ -543,14 +583,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
posix: provider:
dependency: transitive dependency: "direct main"
description: description:
name: posix name: provider
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.3" version: "6.1.5+1"
qr: qr:
dependency: transitive dependency: transitive
description: description:

View File

@ -49,6 +49,7 @@ dependencies:
flutter_speed_dial: ^7.0.0 flutter_speed_dial: ^7.0.0
image_picker: ^1.0.0 image_picker: ^1.0.0
webview_flutter: ^4.10.0 webview_flutter: ^4.10.0
provider: ^6.1.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -1,158 +0,0 @@
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
/// Script untuk menguji integrasi dengan Firefly III API
/// Menjalankan beberapa operasi dasar:
/// 1. Menguji koneksi ke instance Firefly III
/// 2. Menguji autentikasi dengan token
/// 3. Mengambil daftar akun
/// 4. Mengirim transaksi dummy
void main() async {
// Konfigurasi - Ganti dengan nilai yang sesuai untuk instance Firefly III Anda
const String baseUrl = 'http://192.168.1.100:8080'; // Contoh URL
const String accessToken = 'your_access_token_here'; // Contoh token
const String sourceAccountId = '1'; // ID akun sumber (revenue)
const String destinationAccountId = '2'; // ID akun tujuan (asset)
print('=== MENGUJI INTEGRASI FIREFLY III ===\n');
// 1. Menguji koneksi
print('1. Menguji koneksi ke Firefly III...');
try {
final connectivityResponse = await http.get(Uri.parse('$baseUrl/api/v1/about'));
if (connectivityResponse.statusCode == 200) {
print(' ✓ Koneksi berhasil');
} else {
print(' ✗ Koneksi gagal (Status code: ${connectivityResponse.statusCode})');
return;
}
} catch (e) {
print(' ✗ Koneksi gagal dengan error: $e');
return;
}
// 2. Menguji autentikasi
print('\n2. Menguji autentikasi dengan token...');
try {
final authResponse = await http.get(
Uri.parse('$baseUrl/api/v1/about/user'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
},
);
if (authResponse.statusCode == 200) {
print(' ✓ Autentikasi berhasil');
} else {
print(' ✗ Autentikasi gagal (Status code: ${authResponse.statusCode})');
print(' Response body: ${authResponse.body}');
return;
}
} catch (e) {
print(' ✗ Autentikasi gagal dengan error: $e');
return;
}
// 3. Mengambil daftar akun
print('\n3. Mengambil daftar akun...');
try {
final accountsResponse = await http.get(
Uri.parse('$baseUrl/api/v1/accounts'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
},
);
if (accountsResponse.statusCode == 200) {
final accountsData = json.decode(accountsResponse.body);
if (accountsData is Map<String, dynamic> && accountsData.containsKey('data')) {
final accounts = accountsData['data'] as List;
print(' ✓ Berhasil mengambil ${accounts.length} akun');
// Tampilkan 3 akun pertama
print(' Contoh akun:');
for (int i = 0; i < accounts.length && i < 3; i++) {
final account = accounts[i];
if (account is Map<String, dynamic> && account.containsKey('id') && account.containsKey('attributes')) {
final attributes = account['attributes'];
if (attributes is Map<String, dynamic> && attributes.containsKey('name') && attributes.containsKey('type')) {
print(' - ID: ${account['id']}, Nama: ${attributes['name']}, Tipe: ${attributes['type']}');
}
}
}
} else {
print(' ✗ Format respons akun tidak sesuai harapan');
return;
}
} else {
print(' ✗ Gagal mengambil akun (Status code: ${accountsResponse.statusCode})');
print(' Response body: ${accountsResponse.body}');
return;
}
} catch (e) {
print(' ✗ Gagal mengambil akun dengan error: $e');
return;
}
// 4. Mengirim transaksi dummy
print('\n4. Mengirim transaksi dummy...');
try {
final transactionPayload = jsonEncode({
"transactions": [
{
"type": "deposit",
"date": "2025-08-21",
"amount": "50.00",
"description": "Transaksi Dummy via Test Script",
"source_id": sourceAccountId,
"destination_id": destinationAccountId,
}
]
});
final transactionResponse = await http.post(
Uri.parse('$baseUrl/api/v1/transactions'),
headers: {
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: transactionPayload,
);
if (transactionResponse.statusCode == 200 || transactionResponse.statusCode == 201) {
print(' ✓ Transaksi berhasil dikirim');
// Coba parse transaction ID
try {
final transactionData = json.decode(transactionResponse.body);
if (transactionData is Map<String, dynamic> &&
transactionData.containsKey('data') &&
transactionData['data'] is List &&
transactionData['data'].isNotEmpty) {
final firstTransaction = transactionData['data'][0];
if (firstTransaction is Map<String, dynamic> && firstTransaction.containsKey('transaction_id')) {
print(' Transaction ID: ${firstTransaction['transaction_id']}');
} else if (firstTransaction is Map<String, dynamic> && firstTransaction.containsKey('id')) {
print(' Transaction ID: ${firstTransaction['id']}');
}
}
} catch (e) {
print(' Tidak dapat mem-parsing transaction ID: $e');
}
} else {
print(' ✗ Gagal mengirim transaksi (Status code: ${transactionResponse.statusCode})');
print(' Response body: ${transactionResponse.body}');
return;
}
} catch (e) {
print(' ✗ Gagal mengirim transaksi dengan error: $e');
return;
}
print('\n=== PENGUJIAN SELESAI ===');
print('Semua pengujian berhasil! Integrasi dengan Firefly III berfungsi dengan baik.');
}