apskel-pos-flutter/lib/presentation/setting/widgets/receipt_printer_page.dart
2025-08-07 15:30:05 +07:00

333 lines
15 KiB
Dart

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/core/components/components.dart';
import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/data/models/response/print_model.dart';
import 'package:enaklo_pos/presentation/setting/bloc/create_printer/create_printer_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/get_printer_receipt/get_printer_receipt_bloc.dart';
import 'package:enaklo_pos/presentation/setting/bloc/update_printer/update_printer_bloc.dart';
import 'package:enaklo_pos/presentation/setting/widgets/dialog_search_printer.dart';
import 'package:enaklo_pos/core/utils/printer_service.dart';
import 'package:enaklo_pos/data/dataoutputs/print_dataoutputs.dart';
import 'package:enaklo_pos/data/datasources/settings_local_datasource.dart';
class ReceiptPrinterPage extends StatefulWidget {
const ReceiptPrinterPage({super.key});
@override
State<ReceiptPrinterPage> createState() => _ReceiptPrinterPageState();
}
class _ReceiptPrinterPageState extends State<ReceiptPrinterPage> {
String selectedPrinter = 'Bluetooth';
TextEditingController? addressController;
TextEditingController? printNameController;
String paper = '58';
bool isInitialized = false;
@override
void initState() {
// TODO: implement initState
super.initState();
addressController = TextEditingController();
printNameController = TextEditingController();
context.read<GetPrinterReceiptBloc>().add(GetPrinterReceiptEvent.get());
}
@override
void dispose() {
addressController!.dispose();
printNameController!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: BlocBuilder<GetPrinterReceiptBloc, GetPrinterReceiptState>(
builder: (context, state) {
return state.maybeWhen(
orElse: () {
return SizedBox.shrink();
},
loading: () {
return Center(child: CircularProgressIndicator());
},
success: (data) {
if (data != null && !isInitialized) {
addressController!.text = data.address;
printNameController!.text = data.name;
selectedPrinter = data.type;
paper = data.paper;
isInitialized = true;
}
return Container(
// width: 300,
width: context.deviceWidth,
padding: const EdgeInsets.all(16.0),
color: Colors.white,
child: ListView(
children: [
const Text(
'Receipt Printer',
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
SpaceHeight(16),
DropdownButtonFormField<String>(
decoration: InputDecoration(
labelText: 'Printer Type',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
value: selectedPrinter, // nilai default
items: const [
DropdownMenuItem(
value: 'Bluetooth',
child: Text('Bluetooth'),
),
DropdownMenuItem(
value: 'Network',
child: Text('Network'),
),
],
onChanged: (value) {
selectedPrinter = value ?? 'Bluetooth';
setState(() {});
},
),
SpaceHeight(8),
//button search
selectedPrinter == 'Bluetooth'
? Button.outlined(
onPressed: () {
showDialog(
context: context,
builder: (context) => DialogSearchPrinter(
onSelected: (value) {
addressController!.text = value;
setState(() {});
},
),
);
},
label: 'Search')
: CustomTextField(
controller: addressController!,
label: 'Address',
showLabel: false,
),
SpaceHeight(16),
// Textfield for name
CustomTextField(
controller: printNameController!,
label: 'Print Name',
showLabel: false,
),
SpaceHeight(16),
// Textfield for width paper
DropdownButtonFormField<String>(
decoration: InputDecoration(
labelText: 'Width Paper',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
value: paper, // nilai default
items: const [
DropdownMenuItem(
value: '58',
child: Text('58 mm'),
),
DropdownMenuItem(
value: '80',
child: Text('80 mm'),
),
],
onChanged: (value) {
paper = value ?? '58';
log('Paper : $paper');
},
),
SpaceHeight(16),
// button test print
Button.outlined(
onPressed: () async {
if (addressController!.text.isNotEmpty &&
printNameController!.text.isNotEmpty) {
try {
// Get actual tax and service charge settings
final settingsLocalDatasource =
SettingsLocalDatasource();
final taxModel =
await settingsLocalDatasource.getTax();
final serviceChargeValue =
await settingsLocalDatasource
.getServiceCharge();
// Create a test print model
final testPrinter = PrintModel(
code: 'receipt',
name: printNameController!.text,
address: addressController!.text,
paper: paper,
type: selectedPrinter,
);
// Generate test print data
final testPrintData = await PrintDataoutputs
.instance
.printOrderV3(
[], // Empty product list for test
0,
0,
'Test',
0,
0,
0,
0,
0,
1,
'Test Cashier',
'Test Customer',
int.parse(paper),
taxPercentage: taxModel.value,
serviceChargePercentage: serviceChargeValue,
);
// Print test
await PrinterService().printWithPrinter(
testPrinter,
testPrintData,
context,
);
} catch (e) {
log("Error test printing: $e");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error test printing: $e')),
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Please fill in printer details first')),
);
}
},
label: 'Test Print'),
SpaceHeight(8),
// button save
data == null
? BlocConsumer<CreatePrinterBloc, CreatePrinterState>(
listener: (context, state) {
state.maybeWhen(
orElse: () {},
success: (message) {
final snackBar = SnackBar(
content: Text(message),
backgroundColor: AppColors.primary,
);
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
context
.read<GetPrinterReceiptBloc>()
.add(GetPrinterReceiptEvent.get());
},
);
},
builder: (context, state) {
return state.maybeWhen(
orElse: () {
return Button.filled(
onPressed: () {
final printData = PrintModel(
code: 'receipt',
name: printNameController!.text,
address: addressController!.text,
paper: paper,
type: selectedPrinter,
);
context.read<CreatePrinterBloc>().add(
CreatePrinterEvent.createPrinter(
printData),
);
},
label: 'Save',
);
},
loading: () {
return CircularProgressIndicator();
},
);
},
)
: BlocConsumer<UpdatePrinterBloc, UpdatePrinterState>(
listener: (context, state) {
state.maybeWhen(
orElse: () {},
success: (message) {
final snackBar = SnackBar(
content: Text(message),
backgroundColor: AppColors.primary,
);
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
context
.read<GetPrinterReceiptBloc>()
.add(GetPrinterReceiptEvent.get());
},
);
},
builder: (context, state) {
return state.maybeWhen(
orElse: () {
return Button.filled(
onPressed: () {
final printData = PrintModel(
id: data.id,
code: 'receipt',
name: printNameController!.text,
address: addressController!.text,
paper: paper,
type: selectedPrinter,
);
log("Print Data : ${printData.toMap()}");
context.read<UpdatePrinterBloc>().add(
UpdatePrinterEvent.updatePrinter(
printData,
),
);
},
label: 'Save',
);
},
loading: () {
return CircularProgressIndicator();
},
);
},
),
SpaceHeight(16),
],
),
);
},
);
},
));
}
}