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

View File

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

View File

@ -14,9 +14,9 @@ class ThankYouPantun extends StatefulWidget {
class _ThankYouPantunState extends State<ThankYouPantun> {
String _thankYouText = '*** TERIMA KASIH ***';
String _pantunText = 'Belanja di toko kami, hemat dan nyaman,\n'
'Dengan penuh semangat, kami siap melayani,\n'
'Harapan kami, Anda selalu puas,\n'
String _pantunText = 'Belanja di toko kami, hemat dan nyaman,\\n'
'Dengan penuh semangat, kami siap melayani,\\n'
'Harapan kami, Anda selalu puas,\\n'
'Sampai jumpa lagi, selamat tinggal.';
@override
@ -25,6 +25,13 @@ class _ThankYouPantunState extends State<ThankYouPantun> {
_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
Future<void> _loadThankYouText() async {
final prefs = await SharedPreferences.getInstance();
@ -34,9 +41,9 @@ class _ThankYouPantunState extends State<ThankYouPantun> {
if (mounted) {
setState(() {
_thankYouText = savedThankYou ?? '*** TERIMA KASIH ***';
_pantunText = savedPantun ?? 'Belanja di toko kami, hemat dan nyaman,\n'
'Dengan penuh semangat, kami siap melayani,\n'
'Harapan kami, Anda selalu puas,\n'
_pantunText = savedPantun ?? 'Belanja di toko kami, hemat dan nyaman,\\n'
'Dengan penuh semangat, kami siap melayani,\\n'
'Harapan kami, Anda selalu puas,\\n'
'Sampai jumpa lagi, selamat tinggal.';
});
}

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: archive
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "4.0.7"
version: "3.6.1"
async:
dependency: transitive
description:
@ -25,14 +25,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.9"
bidi:
dependency: transitive
description:
name: bidi
sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d"
url: "https://pub.dev"
source: hosted
version: "2.0.13"
bluetooth_print:
dependency: "direct main"
description:
@ -96,6 +88,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.6"
csslib:
dependency: transitive
description:
name: csslib
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
cupertino_icons:
dependency: "direct main"
description:
@ -165,6 +165,14 @@ packages:
description: flutter
source: sdk
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:
dependency: "direct dev"
description:
@ -199,6 +207,14 @@ packages:
description: flutter
source: sdk
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:
dependency: "direct main"
description:
@ -207,6 +223,22 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct main"
description:
@ -232,13 +264,13 @@ packages:
source: hosted
version: "4.0.2"
image:
dependency: transitive
dependency: "direct main"
description:
name: image
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev"
source: hosted
version: "4.5.4"
version: "3.3.0"
image_picker:
dependency: "direct main"
description:
@ -383,6 +415,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
open_file:
dependency: "direct main"
description:
@ -515,10 +555,10 @@ packages:
dependency: "direct main"
description:
name: pdf
sha256: "28eacad99bffcce2e05bba24e50153890ad0255294f4dd78a17075a2ba5c8416"
sha256: "10659b915e65832b106f6d1d213e09b789cc1f24bf282ee911e49db35b96be4d"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
version: "3.8.4"
petitparser:
dependency: transitive
description:
@ -543,14 +583,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
posix:
dependency: transitive
provider:
dependency: "direct main"
description:
name: posix
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
name: provider
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev"
source: hosted
version: "6.0.3"
version: "6.1.5+1"
qr:
dependency: transitive
description:

View File

@ -49,6 +49,7 @@ dependencies:
flutter_speed_dial: ^7.0.0
image_picker: ^1.0.0
webview_flutter: ^4.10.0
provider: ^6.1.1
dev_dependencies:
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.');
}