Null safety

This commit is contained in:
Hillel Coren 2023-09-27 14:30:49 +03:00
parent ea508a9540
commit d89270bcd9
12 changed files with 165 additions and 172 deletions

View File

@ -553,21 +553,21 @@ abstract class CompanyEntity extends Object
bool get enableFirstInvoiceTaxRate => numberOfInvoiceTaxRates >= 1; bool get enableFirstInvoiceTaxRate => numberOfInvoiceTaxRates >= 1;
bool get enableSecondInvoiceTaxRate => (numberOfInvoiceTaxRates) >= 2; bool get enableSecondInvoiceTaxRate => numberOfInvoiceTaxRates >= 2;
bool get enableThirdInvoiceTaxRate => (numberOfInvoiceTaxRates) >= 3; bool get enableThirdInvoiceTaxRate => numberOfInvoiceTaxRates >= 3;
bool get enableFirstItemTaxRate => (numberOfItemTaxRates) >= 1; bool get enableFirstItemTaxRate => numberOfItemTaxRates >= 1;
bool get enableSecondItemTaxRate => (numberOfItemTaxRates) >= 2; bool get enableSecondItemTaxRate => numberOfItemTaxRates >= 2;
bool get enableThirdItemTaxRate => (numberOfItemTaxRates) >= 3; bool get enableThirdItemTaxRate => numberOfItemTaxRates >= 3;
bool get enableFirstExpenseTaxRate => (numberOfExpenseTaxRates) >= 1; bool get enableFirstExpenseTaxRate => numberOfExpenseTaxRates >= 1;
bool get enableSecondExpenseTaxRate => (numberOfExpenseTaxRates) >= 2; bool get enableSecondExpenseTaxRate => numberOfExpenseTaxRates >= 2;
bool get enableThirdExpenseTaxRate => (numberOfExpenseTaxRates) >= 3; bool get enableThirdExpenseTaxRate => numberOfExpenseTaxRates >= 3;
bool get hasInvoiceTaxes => numberOfInvoiceTaxRates > 0; bool get hasInvoiceTaxes => numberOfInvoiceTaxRates > 0;

View File

@ -489,7 +489,7 @@ abstract class PaymentEntity extends Object
return startDate.compareTo(date) <= 0 && endDate!.compareTo(date) >= 0; return startDate.compareTo(date) <= 0 && endDate!.compareTo(date) >= 0;
} }
bool get isOnline => (companyGatewayId).isNotEmpty; bool get isOnline => companyGatewayId.isNotEmpty;
bool get isCompletedOrPartiallyRefunded => [ bool get isCompletedOrPartiallyRefunded => [
kPaymentStatusCompleted, kPaymentStatusCompleted,
@ -511,7 +511,7 @@ abstract class PaymentEntity extends Object
return 0; return 0;
} }
return amount - (refunded); return amount - refunded;
} }
// ignore: unused_element // ignore: unused_element

View File

@ -209,107 +209,106 @@ abstract class ProjectEntity extends Object
} }
int compareTo( int compareTo(
ProjectEntity? project, ProjectEntity project,
String sortField, String sortField,
bool sortAscending, bool sortAscending,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ClientEntity?> clientMap) { BuiltMap<String, ClientEntity> clientMap) {
int response = 0; int response = 0;
final ProjectEntity? projectA = sortAscending ? this : project; final ProjectEntity projectA = sortAscending ? this : project;
final ProjectEntity? projectB = sortAscending ? project : this; final ProjectEntity projectB = sortAscending ? project : this;
switch (sortField) { switch (sortField) {
case ProjectFields.name: case ProjectFields.name:
response = projectA!.name response =
.toLowerCase() projectA.name.toLowerCase().compareTo(projectB.name.toLowerCase());
.compareTo(projectB!.name.toLowerCase());
break; break;
case ProjectFields.taskRate: case ProjectFields.taskRate:
response = projectA!.taskRate.compareTo(projectB!.taskRate); response = projectA.taskRate.compareTo(projectB.taskRate);
break; break;
case ProjectFields.client: case ProjectFields.client:
final clientA = clientMap[projectA!.clientId] ?? ClientEntity(); final clientA = clientMap[projectA.clientId] ?? ClientEntity();
final clientB = clientMap[projectB!.clientId] ?? ClientEntity(); final clientB = clientMap[projectB.clientId] ?? ClientEntity();
response = removeDiacritics(clientA.listDisplayName) response = removeDiacritics(clientA.listDisplayName)
.toLowerCase() .toLowerCase()
.compareTo(removeDiacritics(clientB.listDisplayName).toLowerCase()); .compareTo(removeDiacritics(clientB.listDisplayName).toLowerCase());
break; break;
case ProjectFields.clientNumber: case ProjectFields.clientNumber:
final clientA = clientMap[projectA!.clientId] ?? ClientEntity(); final clientA = clientMap[projectA.clientId] ?? ClientEntity();
final clientB = clientMap[projectB!.clientId] ?? ClientEntity(); final clientB = clientMap[projectB.clientId] ?? ClientEntity();
response = clientA.number response = clientA.number
.toLowerCase() .toLowerCase()
.compareTo(clientB.number.toLowerCase()); .compareTo(clientB.number.toLowerCase());
break; break;
case ProjectFields.clientIdNumber: case ProjectFields.clientIdNumber:
final clientA = clientMap[projectA!.clientId] ?? ClientEntity(); final clientA = clientMap[projectA.clientId] ?? ClientEntity();
final clientB = clientMap[projectB!.clientId] ?? ClientEntity(); final clientB = clientMap[projectB.clientId] ?? ClientEntity();
response = clientA.idNumber response = clientA.idNumber
.toLowerCase() .toLowerCase()
.compareTo(clientB.idNumber.toLowerCase()); .compareTo(clientB.idNumber.toLowerCase());
break; break;
case ProjectFields.dueDate: case ProjectFields.dueDate:
response = projectA!.dueDate.compareTo(projectB!.dueDate); response = projectA.dueDate.compareTo(projectB.dueDate);
break; break;
case ProjectFields.privateNotes: case ProjectFields.privateNotes:
response = projectA!.privateNotes.compareTo(projectB!.privateNotes); response = projectA.privateNotes.compareTo(projectB.privateNotes);
break; break;
case ProjectFields.publicNotes: case ProjectFields.publicNotes:
response = projectA!.publicNotes.compareTo(projectB!.publicNotes); response = projectA.publicNotes.compareTo(projectB.publicNotes);
break; break;
case ProjectFields.budgetedHours: case ProjectFields.budgetedHours:
response = projectA!.budgetedHours.compareTo(projectB!.budgetedHours); response = projectA.budgetedHours.compareTo(projectB.budgetedHours);
break; break;
case ProjectFields.totalHours: case ProjectFields.totalHours:
response = projectA!.totalHours.compareTo(projectB!.totalHours); response = projectA.totalHours.compareTo(projectB.totalHours);
break; break;
case EntityFields.state: case EntityFields.state:
final stateA = EntityState.valueOf(projectA!.entityState); final stateA = EntityState.valueOf(projectA.entityState);
final stateB = EntityState.valueOf(projectB!.entityState); final stateB = EntityState.valueOf(projectB.entityState);
response = response =
stateA.name.toLowerCase().compareTo(stateB.name.toLowerCase()); stateA.name.toLowerCase().compareTo(stateB.name.toLowerCase());
break; break;
case EntityFields.createdAt: case EntityFields.createdAt:
response = projectA!.createdAt.compareTo(projectB!.createdAt); response = projectA.createdAt.compareTo(projectB.createdAt);
break; break;
case ProjectFields.archivedAt: case ProjectFields.archivedAt:
response = projectA!.archivedAt.compareTo(projectB!.archivedAt); response = projectA.archivedAt.compareTo(projectB.archivedAt);
break; break;
case ProjectFields.updatedAt: case ProjectFields.updatedAt:
response = projectA!.updatedAt.compareTo(projectB!.updatedAt); response = projectA.updatedAt.compareTo(projectB.updatedAt);
break; break;
case EntityFields.assignedTo: case EntityFields.assignedTo:
final userA = userMap[projectA!.assignedUserId] ?? UserEntity(); final userA = userMap[projectA.assignedUserId] ?? UserEntity();
final userB = userMap[projectB!.assignedUserId] ?? UserEntity(); final userB = userMap[projectB.assignedUserId] ?? UserEntity();
response = userA.listDisplayName response = userA.listDisplayName
.toLowerCase() .toLowerCase()
.compareTo(userB.listDisplayName.toLowerCase()); .compareTo(userB.listDisplayName.toLowerCase());
break; break;
case EntityFields.createdBy: case EntityFields.createdBy:
final userA = userMap[projectA!.createdUserId] ?? UserEntity(); final userA = userMap[projectA.createdUserId] ?? UserEntity();
final userB = userMap[projectB!.createdUserId] ?? UserEntity(); final userB = userMap[projectB.createdUserId] ?? UserEntity();
response = userA.listDisplayName response = userA.listDisplayName
.toLowerCase() .toLowerCase()
.compareTo(userB.listDisplayName.toLowerCase()); .compareTo(userB.listDisplayName.toLowerCase());
break; break;
case ProjectFields.documents: case ProjectFields.documents:
response = response =
projectA!.documents.length.compareTo(projectB!.documents.length); projectA.documents.length.compareTo(projectB.documents.length);
break; break;
case ProjectFields.number: case ProjectFields.number:
response = (projectA!.number ?? '').compareTo(projectB!.number ?? ''); response = projectA.number.compareTo(projectB.number);
break; break;
case ProjectFields.customValue1: case ProjectFields.customValue1:
response = projectA!.customValue1.compareTo(projectB!.customValue1); response = projectA.customValue1.compareTo(projectB.customValue1);
break; break;
case ProjectFields.customValue2: case ProjectFields.customValue2:
response = projectA!.customValue2.compareTo(projectB!.customValue2); response = projectA.customValue2.compareTo(projectB.customValue2);
break; break;
case ProjectFields.customValue3: case ProjectFields.customValue3:
response = projectA!.customValue3.compareTo(projectB!.customValue3); response = projectA.customValue3.compareTo(projectB.customValue3);
break; break;
case ProjectFields.customValue4: case ProjectFields.customValue4:
response = projectA!.customValue4.compareTo(projectB!.customValue4); response = projectA.customValue4.compareTo(projectB.customValue4);
break; break;
default: default:
print('## ERROR: sort by project.$sortField is not implemented'); print('## ERROR: sort by project.$sortField is not implemented');
@ -317,7 +316,7 @@ abstract class ProjectEntity extends Object
} }
if (response == 0) { if (response == 0) {
response = project!.number.toLowerCase().compareTo(number.toLowerCase()); response = project.number.toLowerCase().compareTo(number.toLowerCase());
} }
return response; return response;

View File

@ -188,7 +188,7 @@ abstract class TaskTime implements Built<TaskTime, TaskTimeBuilder> {
} }
TaskTime copyWithStartDate(String date, {bool syncDates = false}) { TaskTime copyWithStartDate(String date, {bool syncDates = false}) {
if ((date ?? '').isEmpty) { if (date.isEmpty) {
return this; return this;
} }
@ -220,7 +220,7 @@ abstract class TaskTime implements Built<TaskTime, TaskTimeBuilder> {
} }
TaskTime copyWithEndDate(String date) { TaskTime copyWithEndDate(String date) {
if ((date ?? '').isEmpty) { if (date.isEmpty) {
return this; return this;
} }
@ -666,7 +666,7 @@ abstract class TaskEntity extends Object
if (!isInvoiced && !isRunning) { if (!isInvoiced && !isRunning) {
if (userCompany.canCreate(EntityType.invoice)) { if (userCompany.canCreate(EntityType.invoice)) {
actions.add(EntityAction.invoiceTask); actions.add(EntityAction.invoiceTask);
if ((clientId ?? '').isNotEmpty) { if (clientId.isNotEmpty) {
actions.add(EntityAction.addToInvoice); actions.add(EntityAction.addToInvoice);
} }
} }
@ -697,114 +697,111 @@ abstract class TaskEntity extends Object
} }
int compareTo( int compareTo(
TaskEntity? task, TaskEntity task,
String sortField, String sortField,
bool sortAscending, bool sortAscending,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltMap<String, InvoiceEntity> invoiceMap, BuiltMap<String, InvoiceEntity> invoiceMap,
BuiltMap<String?, TaskStatusEntity?> taskStatusMap, BuiltMap<String, TaskStatusEntity> taskStatusMap,
) { ) {
int response = 0; int response = 0;
final TaskEntity? taskA = sortAscending ? this : task; final TaskEntity taskA = sortAscending ? this : task;
final TaskEntity? taskB = sortAscending ? task : this; final TaskEntity taskB = sortAscending ? task : this;
switch (sortField) { switch (sortField) {
case TaskFields.duration: case TaskFields.duration:
case TaskFields.amount: case TaskFields.amount:
response = response =
taskA!.calculateDuration().compareTo(taskB!.calculateDuration()); taskA.calculateDuration().compareTo(taskB.calculateDuration());
break; break;
case TaskFields.description: case TaskFields.description:
response = taskA!.description.compareTo(taskB!.description); response = taskA.description.compareTo(taskB.description);
break; break;
case TaskFields.customValue1: case TaskFields.customValue1:
response = taskA!.customValue1.compareTo(taskB!.customValue1); response = taskA.customValue1.compareTo(taskB.customValue1);
break; break;
case TaskFields.customValue2: case TaskFields.customValue2:
response = taskA!.customValue2.compareTo(taskB!.customValue2); response = taskA.customValue2.compareTo(taskB.customValue2);
break; break;
case TaskFields.customValue3: case TaskFields.customValue3:
response = taskA!.customValue3.compareTo(taskB!.customValue3); response = taskA.customValue3.compareTo(taskB.customValue3);
break; break;
case TaskFields.customValue4: case TaskFields.customValue4:
response = taskA!.customValue4.compareTo(taskB!.customValue4); response = taskA.customValue4.compareTo(taskB.customValue4);
break; break;
case TaskFields.clientId: case TaskFields.clientId:
case TaskFields.client: case TaskFields.client:
final clientA = clientMap[taskA!.clientId] ?? ClientEntity(); final clientA = clientMap[taskA.clientId] ?? ClientEntity();
final clientB = clientMap[taskB!.clientId] ?? ClientEntity(); final clientB = clientMap[taskB.clientId] ?? ClientEntity();
response = removeDiacritics(clientA.listDisplayName) response = removeDiacritics(clientA.listDisplayName)
.toLowerCase() .toLowerCase()
.compareTo(removeDiacritics(clientB.listDisplayName).toLowerCase()); .compareTo(removeDiacritics(clientB.listDisplayName).toLowerCase());
break; break;
case TaskFields.projectId: case TaskFields.projectId:
case TaskFields.project: case TaskFields.project:
final projectA = projectMap[taskA!.projectId] ?? ProjectEntity(); final projectA = projectMap[taskA.projectId] ?? ProjectEntity();
final projectB = projectMap[taskB!.projectId] ?? ProjectEntity(); final projectB = projectMap[taskB.projectId] ?? ProjectEntity();
response = projectA.listDisplayName response = projectA.listDisplayName
.toLowerCase() .toLowerCase()
.compareTo(projectB.listDisplayName.toLowerCase()); .compareTo(projectB.listDisplayName.toLowerCase());
break; break;
case TaskFields.invoiceId: case TaskFields.invoiceId:
final invoiceA = invoiceMap[taskA!.invoiceId] ?? InvoiceEntity(); final invoiceA = invoiceMap[taskA.invoiceId] ?? InvoiceEntity();
final invoiceB = invoiceMap[taskB!.invoiceId] ?? InvoiceEntity(); final invoiceB = invoiceMap[taskB.invoiceId] ?? InvoiceEntity();
response = invoiceA.listDisplayName response = invoiceA.listDisplayName
.toLowerCase() .toLowerCase()
.compareTo(invoiceB.listDisplayName.toLowerCase()); .compareTo(invoiceB.listDisplayName.toLowerCase());
break; break;
case EntityFields.state: case EntityFields.state:
final stateA = final stateA = EntityState.valueOf(taskA.entityState);
EntityState.valueOf(taskA!.entityState) ?? EntityState.active; final stateB = EntityState.valueOf(taskB.entityState);
final stateB =
EntityState.valueOf(taskB!.entityState) ?? EntityState.active;
response = response =
stateA.name.toLowerCase().compareTo(stateB.name.toLowerCase()); stateA.name.toLowerCase().compareTo(stateB.name.toLowerCase());
break; break;
case TaskFields.date: case TaskFields.date:
case TaskFields.timeLog: case TaskFields.timeLog:
response = taskA!.timeLog response =
.toLowerCase() taskA.timeLog.toLowerCase().compareTo(taskB.timeLog.toLowerCase());
.compareTo(taskB!.timeLog.toLowerCase());
break; break;
case EntityFields.createdAt: case EntityFields.createdAt:
response = taskA!.createdAt.compareTo(taskB!.createdAt); response = taskA.createdAt.compareTo(taskB.createdAt);
break; break;
case TaskFields.archivedAt: case TaskFields.archivedAt:
response = taskA!.archivedAt.compareTo(taskB!.archivedAt); response = taskA.archivedAt.compareTo(taskB.archivedAt);
break; break;
case TaskFields.updatedAt: case TaskFields.updatedAt:
response = taskA!.updatedAt.compareTo(taskB!.updatedAt); response = taskA.updatedAt.compareTo(taskB.updatedAt);
break; break;
case TaskFields.documents: case TaskFields.documents:
response = taskA!.documents.length.compareTo(taskB!.documents.length); response = taskA.documents.length.compareTo(taskB.documents.length);
break; break;
case TaskFields.number: case TaskFields.number:
response = compareNatural( response = compareNatural(
taskA!.number.toLowerCase(), taskB!.number.toLowerCase()); taskA.number.toLowerCase(), taskB.number.toLowerCase());
break; break;
case TaskFields.createdBy: case TaskFields.createdBy:
final userA = userMap[taskA!.createdUserId] ?? UserEntity(); final userA = userMap[taskA.createdUserId] ?? UserEntity();
final userB = userMap[taskB!.createdUserId] ?? UserEntity(); final userB = userMap[taskB.createdUserId] ?? UserEntity();
response = userA.fullName response = userA.fullName
.toLowerCase() .toLowerCase()
.compareTo(userB.fullName.toLowerCase()); .compareTo(userB.fullName.toLowerCase());
break; break;
case TaskFields.assignedTo: case TaskFields.assignedTo:
final userA = userMap[taskA!.assignedUserId] ?? UserEntity(); final userA = userMap[taskA.assignedUserId] ?? UserEntity();
final userB = userMap[taskB!.assignedUserId] ?? UserEntity(); final userB = userMap[taskB.assignedUserId] ?? UserEntity();
response = userA.fullName response = userA.fullName
.toLowerCase() .toLowerCase()
.compareTo(userB.fullName.toLowerCase()); .compareTo(userB.fullName.toLowerCase());
break; break;
case TaskFields.status: case TaskFields.status:
final taskAStatus = taskA!.isRunning final taskAStatus = taskA.isRunning
? -1 ? -1
: taskA.isInvoiced : taskA.isInvoiced
? 999999 ? 999999
: (taskStatusMap[taskA.statusId]?.statusOrder ?? 0); : (taskStatusMap[taskA.statusId]?.statusOrder ?? 0);
final taskBStatus = taskB!.isRunning final taskBStatus = taskB.isRunning
? -1 ? -1
: taskB.isInvoiced : taskB.isInvoiced
? 999999 ? 999999
@ -817,7 +814,7 @@ abstract class TaskEntity extends Object
} }
if (response == 0) { if (response == 0) {
response = task!.number.toLowerCase().compareTo(number.toLowerCase()); response = task.number.toLowerCase().compareTo(number.toLowerCase());
} }
return response; return response;

View File

@ -50,8 +50,7 @@ List<String> dropdownCreditSelector(
if (excludedIds.contains(creditId)) { if (excludedIds.contains(creditId)) {
return false; return false;
} }
if (clientId.isNotEmpty && if (clientId.isNotEmpty && credit!.clientId != clientId) {
credit!.clientId != clientId) {
return false; return false;
} }
if (!clientMap.containsKey(credit!.clientId) || if (!clientMap.containsKey(credit!.clientId) ||

View File

@ -199,22 +199,21 @@ List<TaskEntity?> _runningTasks({
} }
var memoizedRecentTasks = memo2(( var memoizedRecentTasks = memo2((
BuiltMap<String?, TaskEntity?> taskMap, BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
) => ) =>
_recentTasks( _recentTasks(
taskMap: taskMap, taskMap: taskMap,
clientMap: clientMap, clientMap: clientMap,
)); ));
List<TaskEntity?> _recentTasks({ List<TaskEntity> _recentTasks({
required BuiltMap<String?, TaskEntity?> taskMap, required BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?>? clientMap, required BuiltMap<String, ClientEntity> clientMap,
}) { }) {
final tasks = <TaskEntity?>[]; final tasks = <TaskEntity>[];
taskMap.forEach((index, task) { taskMap.forEach((index, task) {
final client = final client = clientMap[task.clientId] ?? ClientEntity(id: task.clientId);
clientMap![task!.clientId] ?? ClientEntity(id: task.clientId);
if (task.isNotActive || client.isNotActive) { if (task.isNotActive || client.isNotActive) {
// do noting // do noting
} else if (!task.isRunning) { } else if (!task.isRunning) {

View File

@ -111,19 +111,19 @@ List<InvoiceItemEntity> convertProjectToInvoiceItem({
} }
var memoizedDropdownProjectList = memo5( var memoizedDropdownProjectList = memo5(
(BuiltMap<String?, ProjectEntity?> projectMap, (BuiltMap<String, ProjectEntity> projectMap,
BuiltList<String> projectList, BuiltList<String> projectList,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
String? clientId) => String? clientId) =>
dropdownProjectsSelector( dropdownProjectsSelector(
projectMap, projectList, clientMap, userMap, clientId)); projectMap, projectList, clientMap, userMap, clientId));
List<String> dropdownProjectsSelector( List<String> dropdownProjectsSelector(
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltList<String> projectList, BuiltList<String> projectList,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
String? clientId) { String? clientId) {
final list = projectList.where((projectId) { final list = projectList.where((projectId) {
final project = projectMap[projectId]; final project = projectMap[projectId];
@ -142,7 +142,7 @@ List<String> dropdownProjectsSelector(
list.sort((projectAId, projectBId) { list.sort((projectAId, projectBId) {
final projectA = projectMap[projectAId]!; final projectA = projectMap[projectAId]!;
final projectB = projectMap[projectBId]; final projectB = projectMap[projectBId]!;
return projectA.compareTo( return projectA.compareTo(
projectB, ProjectFields.name, true, userMap, clientMap); projectB, ProjectFields.name, true, userMap, clientMap);
}); });
@ -151,21 +151,21 @@ List<String> dropdownProjectsSelector(
} }
var memoizedFilteredProjectList = memo6((SelectionState selectionState, var memoizedFilteredProjectList = memo6((SelectionState selectionState,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltList<String> projectList, BuiltList<String> projectList,
ListUIState projectListState, ListUIState projectListState,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap) => BuiltMap<String, UserEntity> userMap) =>
filteredProjectsSelector(selectionState, projectMap, projectList, filteredProjectsSelector(selectionState, projectMap, projectList,
projectListState, clientMap, userMap)); projectListState, clientMap, userMap));
List<String> filteredProjectsSelector( List<String> filteredProjectsSelector(
SelectionState selectionState, SelectionState selectionState,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltList<String> projectList, BuiltList<String> projectList,
ListUIState projectListState, ListUIState projectListState,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap) { BuiltMap<String, UserEntity> userMap) {
final filterEntityId = selectionState.filterEntityId; final filterEntityId = selectionState.filterEntityId;
final filterEntityType = selectionState.filterEntityType; final filterEntityType = selectionState.filterEntityType;
@ -223,7 +223,7 @@ List<String> filteredProjectsSelector(
list.sort((projectAId, projectBId) { list.sort((projectAId, projectBId) {
final projectA = projectMap[projectAId]!; final projectA = projectMap[projectAId]!;
final projectB = projectMap[projectBId]; final projectB = projectMap[projectBId]!;
return projectA.compareTo(projectB, projectListState.sortField, return projectA.compareTo(projectB, projectListState.sortField,
projectListState.sortAscending, userMap, clientMap); projectListState.sortAscending, userMap, clientMap);
}); });

View File

@ -57,8 +57,7 @@ List<String> dropdownQuoteSelector(
if (excludedIds.contains(invoiceId)) { if (excludedIds.contains(invoiceId)) {
return false; return false;
} }
if (clientId.isNotEmpty && if (clientId.isNotEmpty && invoice!.clientId != clientId) {
invoice!.clientId != clientId) {
return false; return false;
} }
if (!clientMap.containsKey(invoice!.clientId) || if (!clientMap.containsKey(invoice!.clientId) ||

View File

@ -244,7 +244,7 @@ List<String> dropdownTasksSelector(
list.sort((taskAId, taskBId) { list.sort((taskAId, taskBId) {
final taskA = taskMap[taskAId]!; final taskA = taskMap[taskAId]!;
final taskB = taskMap[taskBId]; final taskB = taskMap[taskBId]!;
return taskA.compareTo( return taskA.compareTo(
taskB, taskB,
TaskFields.updatedAt, TaskFields.updatedAt,
@ -261,12 +261,12 @@ List<String> dropdownTasksSelector(
} }
var memoizedKanbanTaskList = memo9((SelectionState selectionState, var memoizedKanbanTaskList = memo9((SelectionState selectionState,
BuiltMap<String?, TaskEntity?> taskMap, BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltMap<String, InvoiceEntity> invoiceMap, BuiltMap<String, InvoiceEntity> invoiceMap,
BuiltMap<String?, TaskStatusEntity?> taskStatusMap, BuiltMap<String, TaskStatusEntity> taskStatusMap,
BuiltList<String> taskList, BuiltList<String> taskList,
ListUIState taskListState) => ListUIState taskListState) =>
kanbanTasksSelector(selectionState, taskMap, clientMap, userMap, projectMap, kanbanTasksSelector(selectionState, taskMap, clientMap, userMap, projectMap,
@ -274,12 +274,12 @@ var memoizedKanbanTaskList = memo9((SelectionState selectionState,
List<String> kanbanTasksSelector( List<String> kanbanTasksSelector(
SelectionState selectionState, SelectionState selectionState,
BuiltMap<String?, TaskEntity?> taskMap, BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltMap<String, InvoiceEntity> invoiceMap, BuiltMap<String, InvoiceEntity> invoiceMap,
BuiltMap<String?, TaskStatusEntity?> taskStatusMap, BuiltMap<String, TaskStatusEntity> taskStatusMap,
BuiltList<String> taskList, BuiltList<String> taskList,
ListUIState taskListState) { ListUIState taskListState) {
final filterEntityId = selectionState.filterEntityId; final filterEntityId = selectionState.filterEntityId;
@ -303,7 +303,7 @@ List<String> kanbanTasksSelector(
list.sort((taskAId, taskBId) { list.sort((taskAId, taskBId) {
final taskA = taskMap[taskAId]!; final taskA = taskMap[taskAId]!;
final taskB = taskMap[taskBId]; final taskB = taskMap[taskBId]!;
return taskA.compareTo( return taskA.compareTo(
taskB, taskB,
taskListState.sortField, taskListState.sortField,
@ -321,12 +321,12 @@ List<String> kanbanTasksSelector(
var memoizedFilteredTaskList = memo9(( var memoizedFilteredTaskList = memo9((
SelectionState selectionState, SelectionState selectionState,
BuiltMap<String?, TaskEntity?> taskMap, BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltMap<String, InvoiceEntity> invoiceMap, BuiltMap<String, InvoiceEntity> invoiceMap,
BuiltMap<String?, TaskStatusEntity?> taskStatusMap, BuiltMap<String, TaskStatusEntity> taskStatusMap,
BuiltList<String> taskList, BuiltList<String> taskList,
ListUIState taskListState, ListUIState taskListState,
) => ) =>
@ -344,12 +344,12 @@ var memoizedFilteredTaskList = memo9((
List<String> filteredTasksSelector( List<String> filteredTasksSelector(
SelectionState selectionState, SelectionState selectionState,
BuiltMap<String?, TaskEntity?> taskMap, BuiltMap<String, TaskEntity> taskMap,
BuiltMap<String?, ClientEntity?> clientMap, BuiltMap<String, ClientEntity> clientMap,
BuiltMap<String?, UserEntity?> userMap, BuiltMap<String, UserEntity> userMap,
BuiltMap<String?, ProjectEntity?> projectMap, BuiltMap<String, ProjectEntity> projectMap,
BuiltMap<String, InvoiceEntity> invoiceMap, BuiltMap<String, InvoiceEntity> invoiceMap,
BuiltMap<String?, TaskStatusEntity?> taskStatusMap, BuiltMap<String, TaskStatusEntity> taskStatusMap,
BuiltList<String> taskList, BuiltList<String> taskList,
ListUIState taskListState) { ListUIState taskListState) {
final filterEntityId = selectionState.filterEntityId; final filterEntityId = selectionState.filterEntityId;
@ -426,7 +426,7 @@ List<String> filteredTasksSelector(
list.sort((taskAId, taskBId) { list.sort((taskAId, taskBId) {
final taskA = taskMap[taskAId]!; final taskA = taskMap[taskAId]!;
final taskB = taskMap[taskBId]; final taskB = taskMap[taskBId]!;
return taskA.compareTo( return taskA.compareTo(
taskB, taskB,
taskListState.sortField, taskListState.sortField,

View File

@ -119,7 +119,7 @@ class InvoiceSidebar extends StatelessWidget {
itemCount: upcomingInvoices.length, itemCount: upcomingInvoices.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InvoiceListItem( return InvoiceListItem(
invoice: upcomingInvoices[index], invoice: upcomingInvoices[index]!,
showSelected: false, showSelected: false,
); );
}, },
@ -133,7 +133,7 @@ class InvoiceSidebar extends StatelessWidget {
itemCount: pastDueInvoices.length, itemCount: pastDueInvoices.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return InvoiceListItem( return InvoiceListItem(
invoice: pastDueInvoices[index], invoice: pastDueInvoices[index]!,
showSelected: false, showSelected: false,
); );
}, },

View File

@ -28,7 +28,7 @@ class InvoiceListItem extends StatelessWidget {
this.showSelected = true, this.showSelected = true,
}); });
final InvoiceEntity? invoice; final InvoiceEntity invoice;
final String? filter; final String? filter;
final bool showCheckbox; final bool showCheckbox;
final bool isChecked; final bool isChecked;
@ -39,42 +39,42 @@ class InvoiceListItem extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final client = state.clientState.get(invoice!.clientId); final client = state.clientState.get(invoice.clientId);
final uiState = state.uiState; final uiState = state.uiState;
final invoiceUIState = uiState.invoiceUIState; final invoiceUIState = uiState.invoiceUIState;
final textStyle = TextStyle(fontSize: 16); final textStyle = TextStyle(fontSize: 16);
final localization = AppLocalization.of(context)!; final localization = AppLocalization.of(context)!;
final filterMatch = filter != null && filter!.isNotEmpty final filterMatch = filter != null && filter!.isNotEmpty
? (invoice!.matchesFilterValue(filter) ?? ? (invoice.matchesFilterValue(filter) ??
client!.matchesFilterValue(filter)) client!.matchesFilterValue(filter))
: null; : null;
final statusLabel = final statusLabel =
localization.lookup(kInvoiceStatuses[invoice!.calculatedStatusId]); localization.lookup(kInvoiceStatuses[invoice.calculatedStatusId]);
final statusColor = InvoiceStatusColors(state.prefState.colorThemeModel) final statusColor = InvoiceStatusColors(state.prefState.colorThemeModel)
.colors[invoice!.calculatedStatusId]; .colors[invoice.calculatedStatusId];
final textColor = Theme.of(context).textTheme.bodyLarge!.color; final textColor = Theme.of(context).textTheme.bodyLarge!.color;
String subtitle = ''; String subtitle = '';
if (invoice!.date.isNotEmpty) { if (invoice.date.isNotEmpty) {
subtitle = formatDate(invoice!.date, context); subtitle = formatDate(invoice.date, context);
} }
if (invoice!.partialDueDate.isNotEmpty && invoice!.partial != 0) { if (invoice.partialDueDate.isNotEmpty && invoice.partial != 0) {
if (subtitle.isNotEmpty) { if (subtitle.isNotEmpty) {
subtitle += ''; subtitle += '';
} }
subtitle += formatDate(invoice!.partialDueDate, context); subtitle += formatDate(invoice.partialDueDate, context);
} else if (invoice!.dueDate.isNotEmpty) { } else if (invoice.dueDate.isNotEmpty) {
if (subtitle.isNotEmpty) { if (subtitle.isNotEmpty) {
subtitle += ''; subtitle += '';
} }
subtitle += formatDate(invoice!.dueDate, context); subtitle += formatDate(invoice.dueDate, context);
} }
return DismissibleEntity( return DismissibleEntity(
isSelected: isDesktop(context) && isSelected: isDesktop(context) &&
showSelected && showSelected &&
invoice!.id == invoice.id ==
(uiState.isEditing (uiState.isEditing
? invoiceUIState.editing!.id ? invoiceUIState.editing!.id
: invoiceUIState.selectedId), : invoiceUIState.selectedId),
@ -88,12 +88,12 @@ class InvoiceListItem extends StatelessWidget {
onTap: () => onTap != null onTap: () => onTap != null
? onTap!() ? onTap!()
: selectEntity( : selectEntity(
entity: invoice!, entity: invoice,
forceView: !showCheckbox, forceView: !showCheckbox,
), ),
onLongPress: () => onTap != null onLongPress: () => onTap != null
? null ? null
: selectEntity(entity: invoice!, longPress: true), : selectEntity(entity: invoice, longPress: true),
child: Padding( child: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 10, left: 10,
@ -118,7 +118,7 @@ class InvoiceListItem extends StatelessWidget {
), ),
) )
: ActionMenuButton( : ActionMenuButton(
entityActions: invoice!.getActions( entityActions: invoice.getActions(
userCompany: state.userCompany, userCompany: state.userCompany,
client: client, client: client,
includeEdit: true, includeEdit: true,
@ -134,13 +134,13 @@ class InvoiceListItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Text(
(invoice!.number ?? '').isEmpty (invoice.number ?? '').isEmpty
? localization.pending ? localization.pending
: invoice!.number, : invoice.number,
style: textStyle, style: textStyle,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
if (!invoice!.isActive) EntityStateLabel(invoice) if (!invoice.isActive) EntityStateLabel(invoice)
], ],
), ),
), ),
@ -151,7 +151,7 @@ class InvoiceListItem extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Text( Text(
client!.displayName + client!.displayName +
(invoice!.documents.isNotEmpty (invoice.documents.isNotEmpty
? ' 📎' ? ' 📎'
: ''), : ''),
style: textStyle), style: textStyle),
@ -173,9 +173,9 @@ class InvoiceListItem extends StatelessWidget {
SizedBox(width: 10), SizedBox(width: 10),
Text( Text(
formatNumber( formatNumber(
invoice!.balance != 0 invoice.balance != 0
? invoice!.balance ? invoice.balance
: invoice!.amount, : invoice.amount,
context, context,
clientId: client.id)!, clientId: client.id)!,
style: textStyle, style: textStyle,
@ -191,10 +191,10 @@ class InvoiceListItem extends StatelessWidget {
onTap: () => onTap != null onTap: () => onTap != null
? onTap!() ? onTap!()
: selectEntity( : selectEntity(
entity: invoice!, forceView: !showCheckbox), entity: invoice, forceView: !showCheckbox),
onLongPress: () => onTap != null onLongPress: () => onTap != null
? null ? null
: selectEntity(entity: invoice!, longPress: true), : selectEntity(entity: invoice, longPress: true),
leading: showCheckbox leading: showCheckbox
? IgnorePointer( ? IgnorePointer(
child: Checkbox( child: Checkbox(
@ -221,11 +221,11 @@ class InvoiceListItem extends StatelessWidget {
SizedBox(width: 4), SizedBox(width: 4),
Text( Text(
formatNumber( formatNumber(
invoice!.balance != 0 invoice.balance != 0
? invoice!.balance ? invoice.balance
: invoice!.amount, : invoice.amount,
context, context,
clientId: invoice!.clientId)!, clientId: invoice.clientId)!,
style: Theme.of(context).textTheme.titleMedium), style: Theme.of(context).textTheme.titleMedium),
], ],
), ),
@ -237,13 +237,13 @@ class InvoiceListItem extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: filterMatch == null child: filterMatch == null
? Text((((invoice!.number ?? '').isEmpty ? Text((((invoice.number ?? '').isEmpty
? localization.pending ? localization.pending
: invoice!.number) + : invoice.number) +
'' + '' +
formatDate( formatDate(
invoice!.primaryDate, context) + invoice.primaryDate, context) +
(invoice!.documents.isNotEmpty (invoice.documents.isNotEmpty
? ' 📎' ? ' 📎'
: '')) : ''))
.trim()) .trim())
@ -256,7 +256,7 @@ class InvoiceListItem extends StatelessWidget {
Text(statusLabel!, Text(statusLabel!,
style: TextStyle( style: TextStyle(
color: color:
!invoice!.isSent ? textColor : statusColor, !invoice.isSent ? textColor : statusColor,
)), )),
], ],
), ),

View File

@ -581,7 +581,7 @@ class _MatchDepositsState extends State<_MatchDeposits> {
separatorBuilder: (context, index) => ListDivider(), separatorBuilder: (context, index) => ListDivider(),
itemCount: _invoices.length, itemCount: _invoices.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final invoice = _invoices[index]; final invoice = _invoices[index]!;
return InvoiceListItem( return InvoiceListItem(
invoice: invoice, invoice: invoice,
showCheckbox: true, showCheckbox: true,