Expenses
This commit is contained in:
parent
d202a9cfcf
commit
cf4eb360bb
|
|
@ -275,7 +275,9 @@ abstract class ExpenseEntity extends Object
|
|||
return true;
|
||||
} else if (status.id == kExpenseStatusPending && isPending) {
|
||||
return true;
|
||||
} else if (status.id == kExpenseStatusLogged && !isInvoiced && !isPending) {
|
||||
} else if (status.id == kExpenseStatusLogged &&
|
||||
!isInvoiced &&
|
||||
!isPending) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -292,6 +294,10 @@ abstract class ExpenseEntity extends Object
|
|||
}
|
||||
}
|
||||
|
||||
bool isBetween(String startDate, String endDate) {
|
||||
return startDate.compareTo(endDate) <= 0 && endDate.compareTo(endDate) >= 0;
|
||||
}
|
||||
|
||||
@override
|
||||
double get listDisplayAmount => null;
|
||||
|
||||
|
|
|
|||
|
|
@ -320,14 +320,6 @@ List<ChartDataGroup> chartPayments(
|
|||
return data;
|
||||
}
|
||||
|
||||
var memoizedChartTasks = memo6((CompanyEntity company,
|
||||
DashboardUIState settings,
|
||||
BuiltMap<int, TaskEntity> taskMap,
|
||||
BuiltMap<int, InvoiceEntity> invoiceMap,
|
||||
BuiltMap<int, ProjectEntity> projectMap,
|
||||
BuiltMap<int, ClientEntity> clientMap) =>
|
||||
chartTasks(company, settings, taskMap, invoiceMap, projectMap, clientMap));
|
||||
|
||||
List<ChartDataGroup> chartTasks(
|
||||
CompanyEntity company,
|
||||
DashboardUIState settings,
|
||||
|
|
@ -436,3 +428,126 @@ List<ChartDataGroup> chartTasks(
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
var memoizedChartTasks = memo6((CompanyEntity company,
|
||||
DashboardUIState settings,
|
||||
BuiltMap<int, TaskEntity> taskMap,
|
||||
BuiltMap<int, InvoiceEntity> invoiceMap,
|
||||
BuiltMap<int, ProjectEntity> projectMap,
|
||||
BuiltMap<int, ClientEntity> clientMap) =>
|
||||
chartTasks(company, settings, taskMap, invoiceMap, projectMap, clientMap));
|
||||
|
||||
List<ChartDataGroup> chartExpenses(
|
||||
CompanyEntity company,
|
||||
DashboardUIState settings,
|
||||
BuiltMap<int, InvoiceEntity> invoiceMap,
|
||||
BuiltMap<int, ExpenseEntity> expenseMap) {
|
||||
const STATUS_LOGGED = 'logged';
|
||||
const STATUS_PENDING = 'pending';
|
||||
const STATUS_INVOICED = 'invoiced';
|
||||
const STATUS_PAID = 'paid';
|
||||
|
||||
final Map<String, int> counts = {
|
||||
STATUS_LOGGED: 0,
|
||||
STATUS_PENDING: 0,
|
||||
STATUS_INVOICED: 0,
|
||||
STATUS_PAID: 0,
|
||||
};
|
||||
|
||||
final Map<String, Map<String, double>> totals = {
|
||||
STATUS_LOGGED: {},
|
||||
STATUS_PENDING: {},
|
||||
STATUS_INVOICED: {},
|
||||
STATUS_PAID: {},
|
||||
};
|
||||
|
||||
expenseMap.forEach((int, expense) {
|
||||
final currencyId = expense.expenseCurrencyId;
|
||||
final date = expense.expenseDate;
|
||||
final amount = expense.amountWithTax;
|
||||
|
||||
if (expense.isDeleted) {
|
||||
// skip it
|
||||
} else if (!expense.isBetween(
|
||||
settings.startDate(company), settings.endDate(company))) {
|
||||
// skip it
|
||||
} else if (settings.currencyId > 0 && settings.currencyId != currencyId) {
|
||||
// skip it
|
||||
} else {
|
||||
if (totals[STATUS_LOGGED][date] == null) {
|
||||
totals[STATUS_LOGGED][date] = 0.0;
|
||||
totals[STATUS_PENDING][date] = 0.0;
|
||||
totals[STATUS_INVOICED][date] = 0.0;
|
||||
totals[STATUS_PAID][date] = 0.0;
|
||||
}
|
||||
|
||||
if (expense.isInvoiced) {
|
||||
final invoice = invoiceMap[expense.invoiceId] ?? InvoiceEntity();
|
||||
if (invoice.isPaid) {
|
||||
totals[STATUS_PAID][date] += amount;
|
||||
counts[STATUS_PAID]++;
|
||||
} else {
|
||||
totals[STATUS_INVOICED][date] += amount;
|
||||
counts[STATUS_INVOICED]++;
|
||||
}
|
||||
} else if (expense.isPending) {
|
||||
totals[STATUS_PENDING][date] += amount;
|
||||
counts[STATUS_PENDING]++;
|
||||
} else {
|
||||
totals[STATUS_LOGGED][date] += amount;
|
||||
counts[STATUS_LOGGED]++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final ChartDataGroup loggedData = ChartDataGroup(STATUS_LOGGED);
|
||||
final ChartDataGroup pendingData = ChartDataGroup(STATUS_PENDING);
|
||||
final ChartDataGroup invoicedData = ChartDataGroup(STATUS_INVOICED);
|
||||
final ChartDataGroup paidData = ChartDataGroup(STATUS_PAID);
|
||||
|
||||
var date = DateTime.parse(settings.startDate(company));
|
||||
final endDate = DateTime.parse(settings.endDate(company));
|
||||
|
||||
while (!date.isAfter(endDate)) {
|
||||
final key = convertDateTimeToSqlDate(date);
|
||||
if (totals[STATUS_LOGGED].containsKey(key)) {
|
||||
loggedData.rawSeries
|
||||
.add(ChartMoneyData(date, totals[STATUS_LOGGED][key]));
|
||||
loggedData.total += totals[STATUS_LOGGED][key];
|
||||
pendingData.rawSeries
|
||||
.add(ChartMoneyData(date, totals[STATUS_PENDING][key]));
|
||||
pendingData.total += totals[STATUS_PENDING][key];
|
||||
invoicedData.rawSeries
|
||||
.add(ChartMoneyData(date, totals[STATUS_INVOICED][key]));
|
||||
invoicedData.total += totals[STATUS_INVOICED][key];
|
||||
paidData.rawSeries.add(ChartMoneyData(date, totals[STATUS_PAID][key]));
|
||||
paidData.total += totals[STATUS_PAID][key];
|
||||
} else {
|
||||
loggedData.rawSeries.add(ChartMoneyData(date, 0.0));
|
||||
pendingData.rawSeries.add(ChartMoneyData(date, 0.0));
|
||||
invoicedData.rawSeries.add(ChartMoneyData(date, 0.0));
|
||||
paidData.rawSeries.add(ChartMoneyData(date, 0.0));
|
||||
}
|
||||
date = date.add(Duration(days: 1));
|
||||
}
|
||||
|
||||
loggedData.average =
|
||||
round(loggedData.total ?? 0 / counts[STATUS_LOGGED] ?? 0, 2);
|
||||
invoicedData.average =
|
||||
round(invoicedData.total ?? 0 / counts[STATUS_INVOICED] ?? 0, 2);
|
||||
paidData.average = round(paidData.total ?? 0 / counts[STATUS_PAID] ?? 0, 2);
|
||||
|
||||
final List<ChartDataGroup> data = [
|
||||
loggedData,
|
||||
invoicedData,
|
||||
paidData,
|
||||
];
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
var memoizedChartExpenses = memo4((CompanyEntity company,
|
||||
DashboardUIState settings,
|
||||
BuiltMap<int, InvoiceEntity> invoiceMap,
|
||||
BuiltMap<int, ExpenseEntity> expenseMap) =>
|
||||
chartExpenses(company, settings, invoiceMap, expenseMap));
|
||||
|
|
|
|||
|
|
@ -280,6 +280,30 @@ class DashboardPanels extends StatelessWidget {
|
|||
title: AppLocalization.of(context).tasks);
|
||||
}
|
||||
|
||||
Widget _expenseChart(BuildContext context) {
|
||||
final settings = viewModel.dashboardUIState;
|
||||
final state = viewModel.state;
|
||||
final isLoaded = state.expenseState.isLoaded;
|
||||
final currentData = memoizedChartExpenses(state.selectedCompany, settings,
|
||||
state.invoiceState.map, state.expenseState.map);
|
||||
|
||||
List<ChartDataGroup> previousData;
|
||||
if (settings.enableComparison) {
|
||||
previousData = memoizedChartExpenses(
|
||||
state.selectedCompany,
|
||||
settings.rebuild((b) => b..offset += 1),
|
||||
state.invoiceState.map,
|
||||
state.expenseState.map);
|
||||
}
|
||||
|
||||
return _buildChart(
|
||||
context: context,
|
||||
currentData: currentData,
|
||||
previousData: previousData,
|
||||
isLoaded: isLoaded,
|
||||
title: AppLocalization.of(context).expenses);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = viewModel.state;
|
||||
|
|
@ -300,6 +324,9 @@ class DashboardPanels extends StatelessWidget {
|
|||
company.isModuleEnabled(EntityType.task)
|
||||
? _taskChart(context)
|
||||
: SizedBox(),
|
||||
company.isModuleEnabled(EntityType.expense)
|
||||
? _expenseChart(context)
|
||||
: SizedBox(),
|
||||
],
|
||||
),
|
||||
ConstrainedBox(
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ class ExpenseList extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final localization = AppLocalization.of(context);
|
||||
final listState = viewModel.listState;
|
||||
final filteredClientId = listState.filterEntityId;
|
||||
final state = viewModel.state;
|
||||
final widgets = <Widget>[];
|
||||
BaseEntity filteredEntity;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class _ExpenseViewState extends State<ExpenseView>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final localization = AppLocalization.of(context);
|
||||
//final localization = AppLocalization.of(context);
|
||||
final viewModel = widget.viewModel;
|
||||
|
||||
return WillPopScope(
|
||||
|
|
|
|||
Loading…
Reference in New Issue