added cetak laporan
This commit is contained in:
@ -22,86 +22,18 @@ class DanaSosialAdminView extends StatelessWidget {
|
||||
Widget? child,
|
||||
) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15, vertical: 10),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: const Offset(
|
||||
0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Dana Sosial Bulan Ini',
|
||||
style: boldTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Total Dana Sosial',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Rp. ${OtherFunction().commaFormat(model.jumlahDonasi)}',
|
||||
style: regularTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: mainColor,
|
||||
),
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
model.filterDialog(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Expanded(
|
||||
child: Container(
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Laporan Harian",
|
||||
style:
|
||||
boldTextStyle.copyWith(fontSize: 15, color: Colors.black),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
height: MediaQuery.of(context).size.height * 0.45,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
@ -124,25 +56,384 @@ class DanaSosialAdminView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
)
|
||||
: const TheData(),
|
||||
: const TheDataNewly(),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Laporan Bulanan",
|
||||
style:
|
||||
boldTextStyle.copyWith(fontSize: 15, color: Colors.black),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height * 0.25,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset:
|
||||
const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: model.monthIncomeOutcome.isEmpty
|
||||
? const Center(
|
||||
child: Text(
|
||||
'Tidak ada data',
|
||||
))
|
||||
: const HasilIncomeOutcome(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Text(
|
||||
"Laporan Tahunan",
|
||||
style:
|
||||
boldTextStyle.copyWith(fontSize: 15, color: Colors.black),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
width: double.infinity,
|
||||
height: MediaQuery.of(context).size.height * 0.25,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset:
|
||||
const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: model.yearIncomeOutcome.isNotEmpty
|
||||
? const TahunanWidget()
|
||||
: const Center(
|
||||
child: Text(
|
||||
'Tidak ada data',
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: mainGrey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset:
|
||||
const Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
'Total Pemasukan :',
|
||||
),
|
||||
const Expanded(child: SizedBox()),
|
||||
Text(
|
||||
'Rp. ${OtherFunction().commaFormat(model.totalIncome)}',
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
'Total Pengeluaran :',
|
||||
),
|
||||
const Expanded(child: SizedBox()),
|
||||
Text(
|
||||
'Rp. ${OtherFunction().commaFormat(model.totalOutcome)}',
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: model.role == 'admin'
|
||||
? FloatingActionButton(
|
||||
floatingActionButton: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (model.role == 'admin')
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: 'btn11',
|
||||
onPressed: () {
|
||||
model.goToTambahDanaSosial();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: 'btn22',
|
||||
onPressed: () {
|
||||
model.filterDialog(context);
|
||||
},
|
||||
child: const Icon(Icons.filter_list),
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.miniEndTop,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TahunanWidget extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
const TahunanWidget({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
for (int i = 0; i < viewModel.yearIncomeOutcome.length; i++)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Tahun ${viewModel.yearIncomeOutcome[i]['tahun']}",
|
||||
style: boldTextStyle.copyWith(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (viewModel.role == 'admin' ||
|
||||
viewModel.role == 'pimpinan')
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
// sini untuk laporan bulanan
|
||||
await viewModel.goToLaporanTahunan(
|
||||
viewModel.yearIncomeOutcome[i]['tahun']);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.list_alt_outlined,
|
||||
color: Colors.white,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Table(
|
||||
border: TableBorder.all(
|
||||
color: Colors.grey,
|
||||
),
|
||||
children: [
|
||||
const TableRow(children: [
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pemasukan',
|
||||
style: boldTextStyle,
|
||||
))),
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pengeluaran',
|
||||
style: boldTextStyle,
|
||||
)))
|
||||
]),
|
||||
TableRow(children: [
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Rp. ${OtherFunction().commaFormat(viewModel.yearIncomeOutcome[i]['pemasukan'])}',
|
||||
style: italicTextStyle,
|
||||
))),
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Rp. ${OtherFunction().commaFormat(viewModel.yearIncomeOutcome[i]['pengeluaran'])}',
|
||||
style: italicTextStyle,
|
||||
)))
|
||||
]),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
const Divider(
|
||||
color: Colors.grey,
|
||||
thickness: 1,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class HasilIncomeOutcome extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
const HasilIncomeOutcome({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
for (int i = 0; i < viewModel.monthIncomeOutcome.length; i++)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
viewModel.otherFunction.changeMonthYear(
|
||||
viewModel.monthIncomeOutcome[i]['month']),
|
||||
style: boldTextStyle.copyWith(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (viewModel.role == 'admin' ||
|
||||
viewModel.role == 'pimpinan')
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
// sini untuk laporan bulanan
|
||||
await viewModel.goToLaporanBulanan(
|
||||
viewModel.monthIncomeOutcome[i]['month']);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.list_alt_outlined,
|
||||
color: Colors.white,
|
||||
size: 15,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Table(
|
||||
border: TableBorder.all(
|
||||
color: Colors.grey,
|
||||
),
|
||||
children: [
|
||||
const TableRow(children: [
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pemasukan',
|
||||
style: boldTextStyle,
|
||||
))),
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Pengeluaran',
|
||||
style: boldTextStyle,
|
||||
)))
|
||||
]),
|
||||
TableRow(children: [
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['income'])}',
|
||||
style: italicTextStyle,
|
||||
))),
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['outcome'])}',
|
||||
style: italicTextStyle,
|
||||
)))
|
||||
]),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
const Divider(
|
||||
color: Colors.grey,
|
||||
thickness: 1,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TheData extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
const TheData({
|
||||
super.key,
|
||||
@ -154,6 +445,8 @@ class TheData extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
itemCount: viewModel.danaSosialModelList.length,
|
||||
itemBuilder: (context, index) {
|
||||
// viewModel.log.i(viewModel.danaSosialModelList[index].tanggal);
|
||||
|
||||
String jumlahDonasi = viewModel
|
||||
.danaSosialModelList[index].jenisDonasi !=
|
||||
'Barang'
|
||||
@ -278,3 +571,329 @@ class TheData extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TheDataNewly extends ViewModelWidget<DanaSosialAdminViewModel> {
|
||||
const TheDataNewly({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) {
|
||||
return ListView.builder(
|
||||
itemCount: viewModel.filteredByDateData.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${viewModel.otherFunction.changeMonthYear(viewModel.filteredByDateData[index]['month'])} ',
|
||||
style: boldTextStyle.copyWith(
|
||||
decoration: TextDecoration.underline,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
for (int i = 0;
|
||||
i < viewModel.filteredByDateData[index]['data'].length;
|
||||
i++)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${viewModel.filteredByDateData[index]['data'][i]['date']} : ${viewModel.otherFunction.getDayOfWeek(viewModel.filteredByDateData[index]['data'][i]['date'])}',
|
||||
style: italicTextStyle.copyWith(
|
||||
fontWeight: FontWeight.bold, fontSize: 15),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (viewModel.role == 'admin' ||
|
||||
viewModel.role == 'pimpinan')
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 35,
|
||||
height: 35,
|
||||
decoration: BoxDecoration(
|
||||
color: mainColor,
|
||||
borderRadius: BorderRadius.circular(35),
|
||||
),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
viewModel.getLaporanHarian(
|
||||
viewModel.filteredByDateData[index]
|
||||
['data'][i]['date'],
|
||||
viewModel.otherFunction.getDayOfWeek(
|
||||
viewModel.filteredByDateData[index]
|
||||
['data'][i]['date']));
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.list_alt_outlined,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Table(
|
||||
border: TableBorder.all(
|
||||
color: Colors.grey,
|
||||
),
|
||||
columnWidths: viewModel.role == 'admin'
|
||||
? const {
|
||||
0: FlexColumnWidth(
|
||||
1), // 1/3 of the available width
|
||||
1: FlexColumnWidth(
|
||||
1.5), // 2/3 of the available width
|
||||
2: FlexColumnWidth(
|
||||
2.5), // 2/3 of the available width
|
||||
3: FlexColumnWidth(
|
||||
3), // 2/3 of the available width
|
||||
4: FlexColumnWidth(
|
||||
2), // 2/3 of the available width
|
||||
}
|
||||
: const {
|
||||
0: FlexColumnWidth(
|
||||
1), // 1/3 of the available width
|
||||
1: FlexColumnWidth(
|
||||
2), // 2/3 of the available width
|
||||
2: FlexColumnWidth(
|
||||
2), // 2/3 of the available width
|
||||
3: FlexColumnWidth(
|
||||
3), // 2/3 of the available width
|
||||
},
|
||||
children: [
|
||||
TableRow(
|
||||
children: [
|
||||
const TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'No',
|
||||
style: boldTextStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
const TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Jenis',
|
||||
style: boldTextStyle,
|
||||
))),
|
||||
const TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Donatur',
|
||||
style: boldTextStyle,
|
||||
))),
|
||||
const TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Jumlah /\nKeterangan',
|
||||
style: boldTextStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (viewModel.role == 'admin')
|
||||
const TableCell(
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Aksi',
|
||||
style: boldTextStyle,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
for (int j = 0;
|
||||
j <
|
||||
viewModel
|
||||
.filteredByDateData[index]['data'][i]
|
||||
['data_dana']
|
||||
.length;
|
||||
j++)
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'${j + 1}',
|
||||
style: regularTextStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: Center(
|
||||
// circle icon
|
||||
child: viewModel
|
||||
.filteredByDateData[index]
|
||||
['data'][i]['data_dana']
|
||||
[j]
|
||||
.bentuk ==
|
||||
'Pemasukan'
|
||||
? const JenisIconContainer(
|
||||
color: Colors.green,
|
||||
icon: Icons.arrow_upward,
|
||||
)
|
||||
: const JenisIconContainer(
|
||||
color: Colors.red,
|
||||
icon: Icons.arrow_downward,
|
||||
)),
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'${viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama == '' ? '-' : viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama}',
|
||||
style: regularTextStyle,
|
||||
)),
|
||||
)),
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
viewModel
|
||||
.filteredByDateData[index]
|
||||
['data'][i]['data_dana']
|
||||
[j]
|
||||
.jenisDonasi ==
|
||||
'Uang'
|
||||
? 'Rp. ${viewModel.otherFunction.commaFormat(int.parse(viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].jumlah))}'
|
||||
: viewModel
|
||||
.filteredByDateData[index]
|
||||
['data'][i]['data_dana'][j]
|
||||
.keterangan,
|
||||
style: regularTextStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (viewModel.role == 'admin')
|
||||
TableCell(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 4,
|
||||
),
|
||||
child: Wrap(
|
||||
spacing: 5,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
viewModel.goToEditDanaSosial(
|
||||
int.parse(viewModel
|
||||
.filteredByDateData[
|
||||
index]['data'][i]
|
||||
['data_dana'][j]
|
||||
.idDanaSosial));
|
||||
},
|
||||
child: JenisIconContainer(
|
||||
color: Colors.blue[600]!,
|
||||
icon: Icons.edit,
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
viewModel.deleteData(
|
||||
int.parse(viewModel
|
||||
.filteredByDateData[index]
|
||||
['data'][i]
|
||||
['data_dana'][j]
|
||||
.idDanaSosial!),
|
||||
);
|
||||
},
|
||||
child: const JenisIconContainer(
|
||||
color: Colors.red,
|
||||
icon: Icons.delete,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// create a horizontal line
|
||||
const Divider(
|
||||
color: Colors.grey,
|
||||
thickness: 1.0,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class JenisIconContainer extends StatelessWidget {
|
||||
const JenisIconContainer({
|
||||
super.key,
|
||||
required this.color,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
final Color color;
|
||||
final IconData icon;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.white,
|
||||
size: 15,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_file_downloader/flutter_file_downloader.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../../../app/app.dialogs.dart';
|
||||
@ -16,15 +18,23 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
final log = getLogger('DanaSosialAdminViewModel');
|
||||
final _httpService = locator<MyHttpServices>();
|
||||
final easyLoading = locator<MyEasyLoading>();
|
||||
// final otherF
|
||||
String url = dotenv.env['url']!;
|
||||
|
||||
int bulan = DateTime.now().month;
|
||||
|
||||
List<DanaSosialModel> danaSosialModelList = [];
|
||||
List<Map<String, dynamic>> filteredByDateData = []; // newly added
|
||||
List<Map<String, dynamic>> monthIncomeOutcome = []; // newly added
|
||||
List<Map<String, dynamic>> yearIncomeOutcome = []; // newly added
|
||||
int totalIncome = 0; // newly added
|
||||
int totalOutcome = 0; // newly added
|
||||
|
||||
String? role;
|
||||
bool? isLogin;
|
||||
|
||||
int jumlahDonasi = 0;
|
||||
int jumlahPengeluaran = 0;
|
||||
|
||||
Future<void> init() async {
|
||||
await getData();
|
||||
@ -41,15 +51,16 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
easyLoading.showLoading();
|
||||
// get the month
|
||||
var bulan = DateTime.now().month;
|
||||
log.i(bulan);
|
||||
// log.i(bulan);
|
||||
// change bulan to string and add 0 if it is less than 10
|
||||
String bulanString = bulan.toString().length == 1 ? '0$bulan' : '$bulan';
|
||||
log.i(bulanString);
|
||||
// log.i(bulanString);
|
||||
try {
|
||||
var response = await _httpService.get('pemasukan?bulan=$bulanString');
|
||||
log.i(response.data['jumlah']);
|
||||
// log.i(response.data['jumlah']);
|
||||
// var theJumlahDonasi = response.data['jumlah'];
|
||||
jumlahDonasi = response.data['jumlah'];
|
||||
jumlahPengeluaran = response.data['jumlah_pengeluaran'];
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
} finally {
|
||||
@ -74,17 +85,110 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
setBusy(false);
|
||||
changeByDate(danaSosialModelList);
|
||||
getTahunan();
|
||||
notifyListeners();
|
||||
log.i(danaSosialModelList);
|
||||
// log.i(danaSosialModelList.length);
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
setBusy(false);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
easyLoading.dismissLoading();
|
||||
}
|
||||
}
|
||||
|
||||
getTahunan() async {
|
||||
try {
|
||||
var response = await _httpService.get('data_tahunan');
|
||||
|
||||
var datanya = response.data['data'];
|
||||
log.i(datanya.length);
|
||||
for (int i = 0; i < datanya.length; i++) {
|
||||
log.i(datanya[i]);
|
||||
yearIncomeOutcome.add(datanya[i]);
|
||||
}
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
//newly added
|
||||
changeByDate(List<DanaSosialModel> data) {
|
||||
filteredByDateData = [];
|
||||
|
||||
for (var item in data) {
|
||||
var monthKey =
|
||||
item.tanggal!.substring(0, 7); // Extracting the year and month
|
||||
var dateKey = item.tanggal; // The full date
|
||||
|
||||
var monthData = filteredByDateData.firstWhere(
|
||||
(element) => element['month'] == monthKey,
|
||||
orElse: () => {
|
||||
'month': monthKey,
|
||||
'data': [],
|
||||
});
|
||||
|
||||
var dateData =
|
||||
monthData['data'].firstWhere((element) => element['date'] == dateKey,
|
||||
orElse: () => {
|
||||
'date': dateKey,
|
||||
'data_dana': [],
|
||||
});
|
||||
|
||||
dateData['data_dana'].add(item);
|
||||
|
||||
if (!monthData['data'].contains(dateData)) {
|
||||
monthData['data'].add(dateData);
|
||||
}
|
||||
|
||||
if (!filteredByDateData.contains(monthData)) {
|
||||
filteredByDateData.add(monthData);
|
||||
}
|
||||
}
|
||||
filteredByDateData.sort((a, b) => a['month'].compareTo(b['month']));
|
||||
// log.i(filteredByDateData);
|
||||
|
||||
// group the data by month
|
||||
|
||||
monthIncomeOutcome = [];
|
||||
|
||||
for (var item in filteredByDateData) {
|
||||
var income = 0;
|
||||
var outcome = 0;
|
||||
|
||||
for (var dateData in item['data']) {
|
||||
for (var danaSosialModel in dateData['data_dana']) {
|
||||
if (danaSosialModel.bentuk == 'Pemasukan' &&
|
||||
danaSosialModel.jenisDonasi == 'Uang') {
|
||||
income += int.parse(danaSosialModel.jumlah ?? '0');
|
||||
} else if (danaSosialModel.bentuk == 'Pengeluaran' &&
|
||||
danaSosialModel.jenisDonasi == 'Uang') {
|
||||
outcome += int.parse(danaSosialModel.jumlah ?? '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
monthIncomeOutcome.add({
|
||||
'month': item['month'],
|
||||
'income': income,
|
||||
'outcome': outcome,
|
||||
});
|
||||
}
|
||||
|
||||
// log.i(monthIncomeOutcome);
|
||||
totalIncome = 0;
|
||||
totalOutcome = 0;
|
||||
|
||||
for (var item in monthIncomeOutcome) {
|
||||
totalIncome += int.parse(item['income'].toString());
|
||||
totalOutcome += int.parse(item['outcome'].toString());
|
||||
}
|
||||
|
||||
log.i(totalIncome);
|
||||
log.i(totalOutcome);
|
||||
}
|
||||
|
||||
goToTambahDanaSosial() {
|
||||
navigationService.navigateTo(Routes.tambahDanaSosialView);
|
||||
}
|
||||
@ -104,6 +208,8 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
danaSosialModelList = [];
|
||||
|
||||
var datanya = response.data['data'];
|
||||
jumlahDonasi = response.data['jumlah_donasi'];
|
||||
jumlahPengeluaran = response.data['jumlah_pengeluaran'];
|
||||
// log.i(datanya.length);
|
||||
if (datanya.length > 0) {
|
||||
for (var item in datanya) {
|
||||
@ -112,8 +218,9 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
}
|
||||
|
||||
setBusy(false);
|
||||
changeByDate(danaSosialModelList);
|
||||
notifyListeners();
|
||||
log.i(danaSosialModelList);
|
||||
// log.i(danaSosialModelList);
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
setBusy(false);
|
||||
@ -163,7 +270,7 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
sql = sql.substring(0, sql.length - 4);
|
||||
}
|
||||
|
||||
log.i(sql);
|
||||
// log.i(sql);
|
||||
|
||||
getFilter(sql);
|
||||
}
|
||||
@ -194,12 +301,12 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
easyLoading.showLoading();
|
||||
setBusy(true);
|
||||
try {
|
||||
var response = await _httpService.postWithFormData(
|
||||
await _httpService.postWithFormData(
|
||||
'hapus_dana_sosial',
|
||||
FormData.fromMap({
|
||||
'id_dana_sosial': parse,
|
||||
}));
|
||||
log.i(response.data);
|
||||
// log.i(response.data);
|
||||
easyLoading.dismissLoading();
|
||||
easyLoading.showSuccess('Data berhasil dihapus');
|
||||
getData();
|
||||
@ -213,10 +320,152 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
|
||||
easyLoading.dismissLoading();
|
||||
}
|
||||
} else {
|
||||
log.i('cancel');
|
||||
// log.i('cancel');
|
||||
return;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
goToLaporanBulanan(data) async {
|
||||
// seeperate by "-", the first index is year, the second index is month
|
||||
String year = data.substring(0, data.indexOf('-'));
|
||||
String month = data.substring(data.indexOf('-') + 1);
|
||||
|
||||
try {
|
||||
setBusy(true);
|
||||
easyLoading.customLoading("Mengunduh Laporan Bulanan...");
|
||||
await _httpService.get('laporan_bulanan?tahun=$year&bulan=$month');
|
||||
|
||||
// if (response.data) {
|
||||
|
||||
String urlPdf = '${url}assets/pdf/laporan_bulanan_$month,$year.pdf';
|
||||
log.i(urlPdf);
|
||||
FileDownloader.downloadFile(
|
||||
url: urlPdf,
|
||||
// name: "THE FILE NAME AFTER DOWNLOADING", //(optional)
|
||||
onProgress: (fileName, progress) {
|
||||
// change progress to 0-1
|
||||
double progressPercent = progress / 100;
|
||||
|
||||
easyLoading.showProgress(
|
||||
progressPercent,
|
||||
"Downloading: $progress%",
|
||||
);
|
||||
},
|
||||
onDownloadCompleted: (String path) {
|
||||
easyLoading.dismissLoading();
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Bulanan Berhasil Tersimpan di $path",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
},
|
||||
onDownloadError: (String error) {
|
||||
// log.i('DOWNLOAD ERROR: $error');
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Bulanan Gagal Tersimpan: $error",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
});
|
||||
// }
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
easyLoading.dismissLoading();
|
||||
}
|
||||
}
|
||||
|
||||
getLaporanHarian(String filteredByDateData, String dayOfWeek) async {
|
||||
String date = filteredByDateData;
|
||||
String day = dayOfWeek;
|
||||
|
||||
try {
|
||||
setBusy(true);
|
||||
easyLoading.customLoading("Mengunduh Laporan Harian...");
|
||||
await _httpService.get('laporan_harian?tanggal=$date&hari=$day');
|
||||
|
||||
String urlPdf = '${url}assets/pdf/laporan_harian_$day,$date.pdf';
|
||||
log.i(urlPdf);
|
||||
|
||||
FileDownloader.downloadFile(
|
||||
url: urlPdf,
|
||||
// name: "THE FILE NAME AFTER DOWNLOADING", //(optional)
|
||||
onProgress: (fileName, progress) {
|
||||
// change progress to 0-1
|
||||
double progressPercent = progress / 100;
|
||||
|
||||
easyLoading.showProgress(
|
||||
progressPercent,
|
||||
"Downloading: $progress%",
|
||||
);
|
||||
},
|
||||
onDownloadCompleted: (String path) {
|
||||
easyLoading.dismissLoading();
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Harian Berhasil Tersimpan di $path",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
},
|
||||
onDownloadError: (String error) {
|
||||
// log.i('DOWNLOAD ERROR: $error');
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Harian Gagal Tersimpan: $error",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
easyLoading.dismissLoading();
|
||||
}
|
||||
}
|
||||
|
||||
goToLaporanTahunan(String yearIncomeOutcome) async {
|
||||
// log.i(yearIncomeOutcome);
|
||||
|
||||
try {
|
||||
setBusy(true);
|
||||
easyLoading.customLoading("Mengunduh Laporan Tahun...");
|
||||
await _httpService.get('laporan_tahunan?tahun=$yearIncomeOutcome');
|
||||
|
||||
// if (response.data) {
|
||||
|
||||
String urlPdf = '${url}assets/pdf/laporan_tahunan_$yearIncomeOutcome.pdf';
|
||||
log.i(urlPdf);
|
||||
FileDownloader.downloadFile(
|
||||
url: urlPdf,
|
||||
// name: "THE FILE NAME AFTER DOWNLOADING", //(optional)
|
||||
onProgress: (fileName, progress) {
|
||||
// change progress to 0-1
|
||||
double progressPercent = progress / 100;
|
||||
|
||||
easyLoading.showProgress(
|
||||
progressPercent,
|
||||
"Downloading: $progress%",
|
||||
);
|
||||
},
|
||||
onDownloadCompleted: (String path) {
|
||||
easyLoading.dismissLoading();
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Tahunan Berhasil Tersimpan di $path",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
},
|
||||
onDownloadError: (String error) {
|
||||
// log.i('DOWNLOAD ERROR: $error');
|
||||
snackbarService.showSnackbar(
|
||||
message: "Laporan Tahunan Gagal Tersimpan: $error",
|
||||
duration: const Duration(seconds: 3),
|
||||
);
|
||||
});
|
||||
// }
|
||||
} catch (e) {
|
||||
log.e(e);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
easyLoading.dismissLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user