Files
Vocasia-LMS-Mobile-apps--TA…/lib/screens/profile/account_sign_in/invoice.dart

492 lines
22 KiB
Dart

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:initial_folder/base_service.dart';
import 'package:initial_folder/models/history_transaction_model.dart';
import 'package:initial_folder/providers/user_info_provider.dart';
import 'package:initial_folder/size_config.dart';
import 'package:initial_folder/theme.dart';
import 'package:initial_folder/widgets/login_regist/default_button_payment.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:flutter/rendering.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:initial_folder/providers/detail_invoice_provider.dart'
as invProv;
class Invoice extends StatefulWidget {
Invoice({
super.key,
this.dataHistoryTransactionModel,
});
final HistoryTransactionModel? dataHistoryTransactionModel;
@override
State<Invoice> createState() => _InvoiceState();
}
class _InvoiceState extends State<Invoice> {
final GlobalKey _globalKey = GlobalKey();
bool _isDownloading = false;
Future<void> _captureAndSave() async {
setState(() {
_isDownloading = true;
});
RenderRepaintBoundary boundary =
_globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage();
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
if (!(await Permission.storage.status.isGranted)) {
await Permission.storage.request();
}
final result = await ImageGallerySaver.saveImage(
pngBytes,
quality: 100,
name: "invoice_${widget.dataHistoryTransactionModel!.orderId}",
);
setState(() {
_isDownloading = false;
});
print(result);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Invoice sudah terdownload!')),
);
}
@override
Widget build(BuildContext context) {
var dataUser = Provider.of<UserInfoProvider>(context, listen: false).result;
return Scaffold(
appBar: AppBar(
centerTitle: true,
scrolledUnderElevation: 0.0,
backgroundColor: Theme.of(context).colorScheme.background,
title: Text(
"Invoice",
style: thirdTextStyle.copyWith(
fontWeight: semiBold,
fontSize: getProportionateScreenWidth(15),
),
),
),
body: SingleChildScrollView(
child: Consumer<invProv.DetailInvoiceProvider>(
builder: (context, invoiceProvider, child) {
if (invoiceProvider.state == invProv.ResultState.loading) {
return Center(child: CircularProgressIndicator());
} else if (invoiceProvider.state == invProv.ResultState.hasData) {
Widget buildTextWidget() {
String text = "";
if (invoiceProvider.detailInvoice![0].permataVaNumber != null) {
text = "Permata Virtual Account";
} else if (invoiceProvider.detailInvoice![0].billerCode !=
null) {
text = "Mandiri Virtual Account";
} else if (invoiceProvider.detailInvoice![0].vaNumbers !=
null &&
invoiceProvider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bni')) {
text = "BNI Virtual Account";
} else if (invoiceProvider.detailInvoice![0].vaNumbers !=
null &&
invoiceProvider.detailInvoice![0].vaNumbers!
.any((va) => va.bank == 'bca')) {
text = "BCA Virtual Account";
} else if (invoiceProvider.detailInvoice![0].billerCode !=
null) {
text = "Mandiri Virtual Account";
} else if (invoiceProvider.detailInvoice![0].store ==
"alfamart") {
text = "Alfamart";
} else if (invoiceProvider.detailInvoice![0].store ==
"indomaret") {
text = "Indomart";
} else if (invoiceProvider.detailInvoice![0].paymentType ==
"credit_card") {
text = "Credit Card";
} else {
text = "Transaski Gratis";
}
return Text(
text,
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(11)),
);
}
return Center(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: getProportionateScreenWidth(25)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
RepaintBoundary(
key: _globalKey,
child: Stack(
children: [
Image.asset(
Theme.of(context).colorScheme.brightness ==
Brightness.dark
? "assets/images/invoices_dark.png"
: "assets/images/invoices.png",
width: getProportionateScreenWidth(370),
height: getProportionateScreenHeight(470),
fit: BoxFit.fill,
),
Padding(
padding: EdgeInsets.only(
left: getProportionateScreenWidth(25),
right: getProportionateScreenWidth(25),
top: getProportionateScreenHeight(70),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Order ID',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11),
),
),
Text(
widget.dataHistoryTransactionModel!
.orderId!,
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11),
),
),
],
),
SizedBox(
height: getProportionateScreenHeight(5)),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Tanggal Pembelian',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11),
),
),
Text(
DateFormat('E, d MMM y').format(
DateTime.parse(widget
.dataHistoryTransactionModel!
.date
.toString())),
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
11)),
),
],
),
SizedBox(
height: getProportionateScreenHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Informasi Pembeli',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11),
),
),
],
),
Divider(
color: secondaryColor,
thickness: 0.5,
height: 20,
),
Text(
'Nama',
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(9),
),
),
SizedBox(
height: getProportionateScreenHeight(5)),
Text(
dataUser!.data[0].fullname!,
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11)),
),
SizedBox(
height: getProportionateScreenHeight(6)),
Text(
'Email',
style: thirdTextStyle.copyWith(
fontSize: getProportionateScreenWidth(9),
),
),
SizedBox(
height: getProportionateScreenHeight(5)),
Text(
dataUser.data[0].email!,
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11)),
),
SizedBox(
height: getProportionateScreenHeight(10)),
Text(
"Kursus",
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11)),
),
Divider(
color: secondaryColor,
thickness: 0.5,
height: 20,
),
Column(
children: widget
.dataHistoryTransactionModel!.courses!
.map((e) => listCourse(
imageUrl: e.thumbnail,
title: e.title,
instructor: e.instructor,
price: e.price,
))
.toList(),
),
SizedBox(
height: getProportionateScreenHeight(15)),
Text(
"Informasi Pembayaran",
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(11)),
),
Divider(
color: secondaryColor,
thickness: 0.5,
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Metode Pembayaran',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
),
buildTextWidget(),
],
),
Divider(
color: secondaryColor,
thickness: 0.5,
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Total Harga',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
),
Text(
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(invoiceProvider.detailInvoice![0].grossAmount! ?? "0"))}',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
11)),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Potongan Kupon',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
),
Text(
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse("0"))}',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
11)),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Biaya Layanan',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
),
Text(
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse("0"))}',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(
11)),
),
],
),
Divider(
color: secondaryColor,
thickness: 0.5,
height: 20,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Total Bayar',
style: thirdTextStyle.copyWith(
fontWeight: reguler,
fontSize:
getProportionateScreenWidth(10),
),
),
Text(
'Rp. ${NumberFormat.currency(locale: 'id', symbol: '', decimalDigits: 0).format(double.parse(invoiceProvider.detailInvoice![0].grossAmount! ?? "0"))}',
style: thirdTextStyle.copyWith(
fontSize:
getProportionateScreenWidth(13),
fontWeight: semiBold,
),
),
],
),
],
),
),
SizedBox(height: getProportionateScreenHeight(20)),
],
),
),
SizedBox(height: getProportionateScreenHeight(15)),
_isDownloading
? CircularProgressIndicator()
: DefaultButtonPayment(
text: "Download",
press: () {
_captureAndSave();
},
width: double.infinity,
height: 37,
isInvoice: true,
),
],
),
),
);
} else if (invoiceProvider.state == invProv.ResultState.noData) {
return Center(child: Text('No Data'));
} else if (invoiceProvider.state == invProv.ResultState.error) {
return Center(child: Text('Error'));
} else {
return Center(child: Text('Unexpected state'));
}
},
),
),
);
}
Widget listCourse({
String? imageUrl,
String? title,
String? instructor,
String? price,
String? discountPrice,
int? totalPrices,
}) {
return Container(
padding: EdgeInsets.only(
top: getProportionateScreenHeight(6),
bottom: getProportionateScreenHeight(12),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: getProportionateScreenWidth(60),
height: getProportionateScreenHeight(30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
image: DecorationImage(
image: NetworkImage(imageUrl != null && imageUrl.isNotEmpty
? "$baseUrl/uploads/thumbnail/course_thumbnails/$imageUrl"
: "https://api.vokasia.id/images/default-thumbnail.png"),
fit: BoxFit.cover,
),
),
),
SizedBox(width: getProportionateScreenWidth(10)),
Flexible(
flex: 7,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title!,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: thirdTextStyle.copyWith(
letterSpacing: 0.5,
fontWeight: reguler,
fontSize: getProportionateScreenWidth(11),
),
),
],
),
),
],
),
);
}
}