export function reducer()

in src/app/accounting/store/ledger/ledgers.reducer.ts [40:179]


export function reducer(state = initialState, action: ledger.Actions): State {
  switch (action.type) {

    case ledger.LOAD_ALL_TOP_LEVEL_COMPLETE: {
      const ledgers: Ledger[] = action.payload;

      const newLedgers: Ledger[] = ledgers.filter(ledger => !state.entities[ledger.identifier]);

      const newLedgerIds: string[] = newLedgers.map(ledger => ledger.identifier);

      const newLedgerEntities = resourcesToHash(newLedgers);

      const newLoadedAt = newLedgers.reduce((entities: { [id: string]: any }, ledger: Ledger) => {
        return Object.assign(entities, {
          [ledger.identifier]: Date.now()
        });
      }, {});

      return {
        ids: [ ...state.ids, ...newLedgerIds ],
        topLevelIds: [ ...state.topLevelIds, ...newLedgerIds],
        entities: Object.assign({}, state.entities, newLedgerEntities),
        loadedAt: Object.assign({}, state.loadedAt, newLoadedAt),
        selectedLedgerId: state.selectedLedgerId
      };
    }

    case ledger.LOAD: {
      const ledger: Ledger = action.payload;

      const newIds = state.ids.filter(id => id !== ledger.identifier);

      return {
        ids: [ ...newIds, ledger.identifier ],
        topLevelIds: state.topLevelIds,
        entities: Object.assign({}, state.entities, {
          [ledger.identifier]: ledger
        }),
        loadedAt: Object.assign({}, state.entities, {
          [ledger.identifier]: Date.now()
        }),
        selectedLedgerId: state.selectedLedgerId
      };
    }

    case ledger.SELECT: {
      return Object.assign({}, state, {
        selectedLedgerId: action.payload
      });
    }

    case ledger.CREATE_SUCCESS: {
      const ledger: Ledger = action.payload.ledger;

      return {
        ids: [ ...state.ids, ledger.identifier ],
        topLevelIds: [ ...state.topLevelIds, ledger.identifier ],
        entities: Object.assign({}, state.entities, {
          [ledger.identifier]: ledger
        }),
        selectedLedgerId: state.selectedLedgerId,
        loadedAt: state.loadedAt
      };
    }

    case ledger.UPDATE_SUCCESS: {
      const ledger: Ledger = action.payload.ledger;

      return {
        ids: [ ...state.ids ],
        topLevelIds: [ ...state.topLevelIds ],
        entities: Object.assign({}, state.entities, {
          [ledger.identifier]: ledger
        }),
        selectedLedgerId: state.selectedLedgerId,
        loadedAt: state.loadedAt
      };
    }

    case ledger.CREATE_SUB_LEDGER_SUCCESS: {
      const subLedger: Ledger = action.payload.ledger;
      const parentLedgerId = action.payload.parentLedgerId;
      const parentLedger: Ledger = Object.assign({}, state.entities[parentLedgerId]);
      subLedger.parentLedgerIdentifier = parentLedgerId;
      parentLedger.subLedgers.push(subLedger);

      return {
        ids: [ ...state.ids, subLedger.identifier ],
        topLevelIds: [ ...state.topLevelIds ],
        entities: Object.assign({}, state.entities, {
          [subLedger.identifier]: subLedger,
          [parentLedger.identifier]: parentLedger
        }),
        selectedLedgerId: state.selectedLedgerId,
        loadedAt: state.loadedAt
      };
    }

    case ledger.DELETE_SUCCESS: {
      const deletedLedger: Ledger = action.payload.ledger;

      const newIds: string[] = state.ids.filter(id => id !== deletedLedger.identifier);
      const newTopLevelIds: string[] = state.topLevelIds.filter(id => id !== deletedLedger.identifier);

      const newEntities = newIds.reduce((entities: { [id: string]: Ledger }, id: string) => {
        let ledger = state.entities[id];

        // Remove sub ledger from parent ledger
        if (ledger.identifier === deletedLedger.parentLedgerIdentifier) {
          ledger = Object.assign({}, ledger, {
            subLedgers: ledger.subLedgers.filter(subLedger => subLedger.identifier !== deletedLedger.identifier)
          });
        }

        return Object.assign(entities, {
          [ledger.identifier]: ledger
        });
      }, {});

      const newLoadedAt = newIds.reduce((entities: { [id: string]: any }, id: string) => {
        const loadedAt = state.loadedAt[id];
        return Object.assign(entities, {
          [id]: loadedAt
        });
      }, {});

      return {
        ids: [...newIds],
        topLevelIds: [...newTopLevelIds],
        entities: newEntities,
        loadedAt: newLoadedAt,
        selectedLedgerId: state.selectedLedgerId
      };
    }

    default: {
      return state;
    }
  }
}