294 lines
7.2 KiB
Dart
294 lines
7.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:cashumit/models/receipt_item.dart';
|
|
|
|
/// Widget untuk header struk
|
|
class ReceiptHeader extends StatelessWidget {
|
|
final String storeName;
|
|
final String storeAddress;
|
|
final String storePhone;
|
|
|
|
const ReceiptHeader({
|
|
super.key,
|
|
required this.storeName,
|
|
required this.storeAddress,
|
|
required this.storePhone,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final courierPrime = GoogleFonts.courierPrime(
|
|
textStyle: const TextStyle(
|
|
fontSize: 14,
|
|
height: 1.2,
|
|
),
|
|
);
|
|
|
|
return Column(
|
|
children: [
|
|
Text(
|
|
storeName,
|
|
style: courierPrime.copyWith(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(storeAddress, style: courierPrime, textAlign: TextAlign.center),
|
|
Text(storePhone, style: courierPrime, textAlign: TextAlign.center),
|
|
const SizedBox(height: 4),
|
|
const Divider(thickness: 1, height: 1, color: Colors.black),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Widget untuk informasi transaksi (tanggal, kasir, nota)
|
|
class ReceiptTransactionInfo extends StatelessWidget {
|
|
final DateTime transactionDate;
|
|
final String cashierId;
|
|
final String transactionId;
|
|
|
|
const ReceiptTransactionInfo({
|
|
super.key,
|
|
required this.transactionDate,
|
|
required this.cashierId,
|
|
required this.transactionId,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final courierPrime = GoogleFonts.courierPrime(
|
|
textStyle: const TextStyle(
|
|
fontSize: 14,
|
|
height: 1.2,
|
|
),
|
|
);
|
|
|
|
return Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('TANGGAL:', style: courierPrime),
|
|
Text(
|
|
'${transactionDate.day.toString().padLeft(2, '0')}/${transactionDate.month.toString().padLeft(2, '0')}/${transactionDate.year}',
|
|
style: courierPrime,
|
|
),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('KASIR:', style: courierPrime),
|
|
Text(cashierId, style: courierPrime),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('NOTA:', style: courierPrime),
|
|
Text(transactionId, style: courierPrime),
|
|
],
|
|
),
|
|
const SizedBox(height: 4),
|
|
const Divider(thickness: 1, height: 1, color: Colors.black),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Widget untuk header daftar item
|
|
class ReceiptItemHeader extends StatelessWidget {
|
|
const ReceiptItemHeader({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const Column(
|
|
children: [
|
|
SizedBox(height: 4),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
flex: 4,
|
|
child: Text(
|
|
'ITEM',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
'Q',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
'@HARGA',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
textAlign: TextAlign.right,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
'TOTAL',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
textAlign: TextAlign.right,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 2),
|
|
Divider(thickness: 1, height: 1, color: Colors.black),
|
|
SizedBox(height: 4),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Widget untuk menampilkan satu item dalam struk
|
|
class ReceiptItemRow extends StatelessWidget {
|
|
final ReceiptItem item;
|
|
|
|
const ReceiptItemRow({
|
|
super.key,
|
|
required this.item,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final courierPrime = GoogleFonts.courierPrime(
|
|
textStyle: const TextStyle(
|
|
fontSize: 14,
|
|
height: 1.2,
|
|
),
|
|
);
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 2.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
flex: 4,
|
|
child: Text(
|
|
item.description,
|
|
style: courierPrime,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
item.quantity.toString(),
|
|
textAlign: TextAlign.center,
|
|
style: courierPrime,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
item.price.toStringAsFixed(0),
|
|
textAlign: TextAlign.right,
|
|
style: courierPrime,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
item.total.toStringAsFixed(0),
|
|
textAlign: TextAlign.right,
|
|
style: courierPrime,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Widget untuk menampilkan total
|
|
class ReceiptTotal extends StatelessWidget {
|
|
final double total;
|
|
|
|
const ReceiptTotal({
|
|
super.key,
|
|
required this.total,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final courierPrime = GoogleFonts.courierPrime(
|
|
textStyle: const TextStyle(
|
|
fontSize: 14,
|
|
height: 1.2,
|
|
),
|
|
);
|
|
|
|
return Column(
|
|
children: [
|
|
const SizedBox(height: 4),
|
|
const Divider(thickness: 1, height: 1, color: Colors.black),
|
|
const SizedBox(height: 4),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'TOTAL:',
|
|
style: courierPrime.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
Text(
|
|
total.toStringAsFixed(0),
|
|
style: courierPrime.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Widget untuk footer struk
|
|
class ReceiptFooter extends StatelessWidget {
|
|
const ReceiptFooter({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final courierPrime = GoogleFonts.courierPrime(
|
|
textStyle: const TextStyle(
|
|
fontSize: 14,
|
|
height: 1.2,
|
|
),
|
|
);
|
|
|
|
return Column(
|
|
children: [
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'*** TERIMA KASIH ***',
|
|
style: courierPrime.copyWith(fontWeight: FontWeight.bold),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
Text(
|
|
'Barang yang sudah dibeli tidak dapat',
|
|
style: courierPrime,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
Text(
|
|
'dikembalikan/ditukar',
|
|
style: courierPrime,
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
} |