I have list like this
[
{
"date":"2024/01/01",
"total":20
"detail":[
{
"person":"amir",
"income":5
},
{
"person":"james",
"income":10
},
{
"person":"kevin",
"income":3
}
]
},
{
"date":"2024/01/02",
"total":30
"detail":[
{
"person":"thomas",
"income":5
},
{
"person":"james",
"income":11
},
{
"person":"kevin",
"income":10
}
]
},
{
"date":"2024/02/01",
"total":20
"detail":[
{
"person":"amir",
"income":5
},
{
"person":"james",
"income":10
},
{
"person":"kevin",
"income":3
}
]
},
{
"date":"2024/02/03",
"total":20
"detail":[
{
"person":"amir",
"income":5
},
{
"person":"james",
"income":10
},
{
"person":"kevin",
"income":3
}
]
},
{
"date":"2024/02/04",
"total":20
"detail":[
{
"person":"rodrigo",
"income":5
},
{
"person":"james",
"income":10
},
{
"person":"kevin",
"income":3
}
]
},
{
"date":"2024/03/03",
"total":20
"detail":[
{
"person":"amir",
"income":5
},
{
"person":"james",
"income":10
},
{
"person":"frans",
"income":3
}
]
},
]
Which the original class is
class StaffIncome {
const StaffIncome({required this.person, required this.income});
final String person;
final double income;
}
class DailySummary {
const DailySummary({
required this.date,
required this.total,
this.incomeList = const <StaffIncome>[],
});
final DateTime date;
final double total;
final List<StaffIncome> incomeList;
}
I want to group it so it will based on month, and it sum for (total ), and for the income of each staff will be summed
so that list will be generated like this
[
{
"month":"01",
"year":"2024",
"total":50,
"detail":[
{
"person":"amir",
"monthlyIncome":5
},
{
"person":"james",
"monthlyIncome":21
},
{
"person":"kevin",
"monthlyIncome":13
},
{
"person":"thomas",
"monthlyIncome":5
},
]
},
{
"month":"02",
"year":"2024",
"total":60,
"detail":[
{
"person":"amir",
"monthlyIncome":10
},
{
"person":"james",
"monthlyIncome":30
},
{
"person":"kevin",
"monthlyIncome":9
},
{
"person":"rodrigo",
"monthlyIncome":5
},
]
},
{
"month":"03",
"year":"2024",
"total":20,
"detail":[
{
"person":"amir",
"monthlyIncome":5
},
{
"person":"james",
"monthlyIncome":10
},
{
"person":"frans",
"monthlyIncome":3
},
],
},
]
I have successfull with the use of fluter collection to group by month and year for the total
class MonthYearFilterModel extends Equatable {
const MonthYearFilterModel({required this.year, required this.month});
final int year;
final int month;
@override
List<Object?> get props => [
year,
month,
];
}
class MonthlyTotal extends Equatable {
const MonthlyTotal({
required this.monthYear,
required this.total,
});
final MonthYearFilterModel monthYear;
final double total;
@override
List<Object?> get props => [
monthYear,
total,
];
}
and the code is like this
Map<MonthYearFilterModel, double> _groupByMonthAndSumTotal(
List<DailySummary> list,
MonthYearFilterModel Function(DailySummary) groupByGetter,
double Function(List<double>) applyFunction,
) {
final tmpMap =
groupBy<DailySummary, MonthYearFilterModel>(list, groupByGetter);
return tmpMap.map((key, value) {
return MapEntry(
key,
applyFunction(
value.map((e) {
return e.total;
}).toList(),
),
);
});
}
List<MonthlyTotal> monthlySalesList({
required List<DailySummary> listDailySummary,
}) {
double sumDouble(List<double> list) => list.fold(
0,
(previousValue, element) => previousValue + element,
);
final mapRes = _groupByMonthAndSumTotal(
listDailySummary,
(e) {
return MonthYearFilterModel(
month: e.date.month,
year: e.date.year,
);
},
sumDouble,
);
final res = <MonthlyTotal>[];
mapRes.forEach((k, v) {
res.add(
MonthlyTotal(
monthYear: k,
total: v,
),
);
});
return res;
}
Note : ie, there are 6 person (amir, james, kevin, thomas, rodrigo, frans ), it may be more people
Thank you for your answer / contribution / help