import 'package:built_collection/built_collection.dart'; import 'package:invoiceninja_flutter/data/models/client_model.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/invoice_model.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_state.dart'; import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; import 'package:redux/redux.dart'; EntityUIState quoteUIReducer(QuoteUIState state, dynamic action) { return state.rebuild((b) => b ..listUIState.replace(quoteListReducer(state.listUIState, action)) ..editing.replace(editingReducer(state.editing, action)) ..editingItemIndex = editingItemReducer(state.editingItemIndex, action) ..selectedId = selectedIdReducer(state.selectedId, action) ..tabIndex = tabIndexReducer(state.tabIndex, action) ..historyActivityId = historyActivityIdReducer(state.historyActivityId, action)); } final tabIndexReducer = combineReducers([ TypedReducer((completer, action) { return action.tabIndex; }), TypedReducer((completer, action) { return 0; }), ]); final historyActivityIdReducer = combineReducers([ TypedReducer((index, action) => action.activityId), ]); final editingItemReducer = combineReducers([ TypedReducer((index, action) => action.quoteItemIndex), TypedReducer((index, action) => action.quoteItemIndex), ]); Reducer dropdownFilterReducer = combineReducers([ TypedReducer(filterquoteDropdownReducer), ]); String filterquoteDropdownReducer( String dropdownFilter, FilterQuoteDropdown action) { return action.filter; } Reducer selectedIdReducer = combineReducers([ TypedReducer((selectedId, action) => action.entityType == EntityType.quote ? action.entityId : selectedId), TypedReducer((selectedId, action) => action.quoteId), TypedReducer( (selectedId, action) => action.quote.id), TypedReducer((selectedId, action) => action.quote.id), TypedReducer((selectedId, action) => action.quote.id), TypedReducer( (selectedId, action) => action.clearSelection ? '' : selectedId), TypedReducer((selectedId, action) => ''), TypedReducer((selectedId, action) => action.entityType == EntityType.quote ? '' : selectedId), TypedReducer( (selectedId, action) => action.clearSelection ? '' : action.entityType == EntityType.quote ? action.entityId : selectedId), ]); final editingReducer = combineReducers([ TypedReducer(_updateEditing), TypedReducer(_updateEditing), TypedReducer(_updateEditing), TypedReducer((quote, action) { return action.quote.rebuild((b) => b..isChanged = true); }), TypedReducer((invoice, action) { return invoice.rebuild((b) => b..isChanged = true); }), TypedReducer((invoice, action) { return invoice.rebuild((b) => b..isChanged = true); }), TypedReducer((invoice, action) { return invoice.rebuild((b) => b..isChanged = true); }), TypedReducer((quote, action) { final client = action.client; return quote.rebuild((b) => b ..isChanged = true ..clientId = client?.id ?? '' ..invitations.replace((client?.contacts ?? []) .where((contact) => contact.sendEmail) .map((contact) => InvitationEntity(contactId: contact.id)) .toList())); }), TypedReducer((quotes, action) { return action.quotes[0]; }), TypedReducer((quotes, action) { return action.quotes[0]; }), TypedReducer((quotes, action) { return action.quotes[0]; }), TypedReducer(_addQuoteItem), TypedReducer(_addQuoteItems), TypedReducer(_removeQuoteItem), TypedReducer(_updateQuoteItem), TypedReducer(_clearEditing), TypedReducer((invoice, action) { return invoice.rebuild((b) => b ..invitations.add( action.invitation ?? InvitationEntity(contactId: action.contact.id))); }), TypedReducer((invoice, action) { return invoice.rebuild((b) => b..invitations.remove(action.invitation)); }), ]); InvoiceEntity _clearEditing(InvoiceEntity quote, dynamic action) { return InvoiceEntity(); } InvoiceEntity _updateEditing(InvoiceEntity quote, dynamic action) { return action.quote; } InvoiceEntity _addQuoteItem(InvoiceEntity quote, AddQuoteItem action) { return quote.rebuild( (b) => b..lineItems.add(action.quoteItem ?? InvoiceItemEntity())); } InvoiceEntity _addQuoteItems(InvoiceEntity quote, AddQuoteItems action) { return quote.rebuild((b) => b..lineItems.addAll(action.quoteItems)); } InvoiceEntity _removeQuoteItem(InvoiceEntity quote, DeleteQuoteItem action) { if (quote.lineItems.length <= action.index) { return quote; } return quote.rebuild((b) => b..lineItems.removeAt(action.index)); } InvoiceEntity _updateQuoteItem(InvoiceEntity quote, UpdateQuoteItem action) { if (quote.lineItems.length <= action.index) { return quote; } return quote.rebuild((b) => b..lineItems[action.index] = action.quoteItem); } final quoteListReducer = combineReducers([ TypedReducer(_sortQuotes), TypedReducer(_filterQuotesByState), TypedReducer(_filterQuotesByStatus), TypedReducer(_filterQuotes), TypedReducer(_filterQuotesByCustom1), TypedReducer(_filterQuotesByCustom2), TypedReducer(_filterQuotesByCustom3), TypedReducer(_filterQuotesByCustom4), TypedReducer(_startListMultiselect), TypedReducer(_addToListMultiselect), TypedReducer( _removeFromListMultiselect), TypedReducer(_clearListMultiselect), ]); ListUIState _filterQuotesByCustom1( ListUIState quoteListState, FilterQuotesByCustom1 action) { if (quoteListState.custom1Filters.contains(action.value)) { return quoteListState .rebuild((b) => b..custom1Filters.remove(action.value)); } else { return quoteListState.rebuild((b) => b..custom1Filters.add(action.value)); } } ListUIState _filterQuotesByCustom2( ListUIState quoteListState, FilterQuotesByCustom2 action) { if (quoteListState.custom2Filters.contains(action.value)) { return quoteListState .rebuild((b) => b..custom2Filters.remove(action.value)); } else { return quoteListState.rebuild((b) => b..custom2Filters.add(action.value)); } } ListUIState _filterQuotesByCustom3( ListUIState quoteListState, FilterQuotesByCustom3 action) { if (quoteListState.custom3Filters.contains(action.value)) { return quoteListState .rebuild((b) => b..custom3Filters.remove(action.value)); } else { return quoteListState.rebuild((b) => b..custom3Filters.add(action.value)); } } ListUIState _filterQuotesByCustom4( ListUIState quoteListState, FilterQuotesByCustom4 action) { if (quoteListState.custom4Filters.contains(action.value)) { return quoteListState .rebuild((b) => b..custom4Filters.remove(action.value)); } else { return quoteListState.rebuild((b) => b..custom4Filters.add(action.value)); } } ListUIState _filterQuotesByState( ListUIState quoteListState, FilterQuotesByState action) { if (quoteListState.stateFilters.contains(action.state)) { return quoteListState.rebuild((b) => b..stateFilters.remove(action.state)); } else { return quoteListState.rebuild((b) => b..stateFilters.add(action.state)); } } ListUIState _filterQuotesByStatus( ListUIState quoteListState, FilterQuotesByStatus action) { if (quoteListState.statusFilters.contains(action.status)) { return quoteListState .rebuild((b) => b..statusFilters.remove(action.status)); } else { return quoteListState.rebuild((b) => b..statusFilters.add(action.status)); } } ListUIState _filterQuotes(ListUIState quoteListState, FilterQuotes action) { return quoteListState.rebuild((b) => b ..filter = action.filter ..filterClearedAt = action.filter == null ? DateTime.now().millisecondsSinceEpoch : quoteListState.filterClearedAt); } ListUIState _sortQuotes(ListUIState quoteListState, SortQuotes action) { return quoteListState.rebuild((b) => b ..sortAscending = b.sortField != action.field || !b.sortAscending ..sortField = action.field); } ListUIState _startListMultiselect( ListUIState quoteListState, StartQuoteMultiselect action) { return quoteListState.rebuild((b) => b..selectedIds = ListBuilder()); } ListUIState _addToListMultiselect( ListUIState quoteListState, AddToQuoteMultiselect action) { return quoteListState.rebuild((b) => b..selectedIds.add(action.entity.id)); } ListUIState _removeFromListMultiselect( ListUIState quoteListState, RemoveFromQuoteMultiselect action) { return quoteListState.rebuild((b) => b..selectedIds.remove(action.entity.id)); } ListUIState _clearListMultiselect( ListUIState quoteListState, ClearQuoteMultiselect action) { return quoteListState.rebuild((b) => b..selectedIds = null); } final quotesReducer = combineReducers([ TypedReducer(_updateQuote), TypedReducer(_addQuote), TypedReducer(_setLoadedQuotes), TypedReducer(_updateQuote), TypedReducer(_setLoadedCompany), TypedReducer(_markSentQuoteSuccess), TypedReducer(_archiveQuoteSuccess), TypedReducer(_deleteQuoteSuccess), TypedReducer(_restoreQuoteSuccess), TypedReducer(_convertQuoteSuccess), ]); QuoteState _markSentQuoteSuccess( QuoteState quoteState, MarkSentQuoteSuccess action) { final quoteMap = Map.fromIterable( action.quotes, key: (dynamic item) => item.id, value: (dynamic item) => item, ); return quoteState.rebuild((b) => b..map.addAll(quoteMap)); } QuoteState _archiveQuoteSuccess( QuoteState quoteState, ArchiveQuotesSuccess action) { return quoteState.rebuild((b) { for (final quote in action.quotes) { b.map[quote.id] = quote; } }); } QuoteState _deleteQuoteSuccess( QuoteState quoteState, DeleteQuotesSuccess action) { return quoteState.rebuild((b) { for (final quote in action.quotes) { b.map[quote.id] = quote; } }); } QuoteState _restoreQuoteSuccess( QuoteState quoteState, RestoreQuotesSuccess action) { return quoteState.rebuild((b) { for (final quote in action.quotes) { b.map[quote.id] = quote; } }); } QuoteState _convertQuoteSuccess( QuoteState quoteState, ConvertQuoteSuccess action) { final quoteMap = Map.fromIterable( action.quotes, key: (dynamic item) => item.id, value: (dynamic item) => item, ); return quoteState.rebuild((b) => b..map.addAll(quoteMap)); } QuoteState _addQuote(QuoteState quoteState, AddQuoteSuccess action) { return quoteState.rebuild((b) => b ..map[action.quote.id] = action.quote ..list.add(action.quote.id)); } QuoteState _updateQuote(QuoteState invoiceState, dynamic action) { final InvoiceEntity quote = action.quote; return invoiceState.rebuild((b) => b ..map[quote.id] = quote .rebuild((b) => b..loadedAt = DateTime.now().millisecondsSinceEpoch)); } QuoteState _setLoadedQuotes(QuoteState quoteState, LoadQuotesSuccess action) => quoteState.loadQuotes(action.quotes); QuoteState _setLoadedCompany(QuoteState quoteState, LoadCompanySuccess action) { final company = action.userCompany.company; return quoteState.loadQuotes(company.quotes); }