bcgov/common-forms-toolkit

View on GitHub
app/frontend/src/store/modules/agriseafoodopscreening/agriSeafoodOpScreeningForm.js

Summary

Maintainability
F
1 wk
Test Coverage
F
0%
import moment from 'moment';

import commonFormService from '@/services/commonFormService';
import { FormNames } from '@/utils/constants';
import { SampleData, RandomCities } from './sampleData.js';

// Change the supplied state to the exact format required by the API endpoint
// Any data guards/sanitation can go in here
function transformToPost(state) {
  // TODO: unit test this!
  const copy = JSON.parse(JSON.stringify(state));

  // Recursive remove all '' fields from body to post
  // https://stackoverflow.com/questions/286141/remove-blank-attributes-from-an-object-in-javascript
  // const cleanEmpty = copy => Object.entries(copy)
  //   .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
  //   .reduce((a, [k, v]) => (v === '' ? a : { ...a, [k]: v }), {});

  // Sanitize the optional fields in case they get checked, filled out, unchecked
  if (!copy.location.accTents) {
    delete copy.location.tentDetails;
  }
  if (!copy.location.accMotel) {
    delete copy.location.motelName;
    delete copy.location.motelAddressLine1;
    delete copy.location.motelAddressLine2;
    delete copy.location.motelCity;
    delete copy.location.motelProvince;
    delete copy.location.motelPostalCode;
  }

  const contacts = [copy.primaryContact, copy.covidContact];
  copy.location.numberOfWorkers = Number.parseInt(copy.location.numberOfWorkers, 10);
  const body = {
    type: copy.type,
    business: copy.business,
    contacts: contacts,
    attestation: copy.attestation,
    location: copy.location
  };

  return body;
}

// Change the results of the API fetch to the store state format
function transformToState(data) {
  // TODO: unit test this!
  const copy = JSON.parse(JSON.stringify(data));

  const primary = copy.contacts ? copy.contacts.find(({ contactType }) => contactType === 'PRIMARY') : {};
  const covid = copy.contacts ? copy.contacts.find(({ contactType }) => contactType === 'COVID_COORDINATOR') : {};
  copy.location.startDate = moment(copy.location.startDate).format('YYYY-MM-DD');
  copy.location.endDate = moment(copy.location.endDate).format('YYYY-MM-DD');
  return {
    type: copy.operationType,
    business: copy.business,
    primaryContact: primary,
    covidContact: covid,
    attestation: copy.attestation,
    location: copy.location
  };
}

export default {
  namespaced: true,
  state: {
    getFormError: '',
    gettingForm: false,
    submitting: false,
    step: 0,
    submissionComplete: false,
    submissionDetails: null,
    submissionError: '',

    // Form schema
    type: '',
    business: {
      name: '',
      orgBookId: '',
      addressLine1: '',
      addressLine2: '',
      city: '',
      province: '',
      postalCode: ''
    },
    primaryContact: {
      contactType: 'PRIMARY',
      firstName: '',
      lastName: '',
      phone1: '',
      phone2: '',
      email: ''
    },
    covidContact: {
      contactType: 'COVID_COORDINATOR',
      firstName: '',
      lastName: '',
      phone1: '',
      phone2: '',
      email: ''
    },
    location: {
      startDate: '',
      endDate: '',
      city: '',
      cityLatitude: undefined,
      cityLongitude: undefined,
      numberOfWorkers: '',
      accTents: false,
      tentDetails: '',
      accMotel: false,
      motelName: '',
      motelAddressLine1: '',
      motelAddressLine2: '',
      motelCity: '',
      motelProvince: '',
      motelPostalCode: '',
      accWorkersHome: false
    },
    attestation: {
      guidelinesRead: false,
      assessmentCompleted: false,
      developedPlan: false,
      protectionSignage: false,
      workerContactPersonnel: false,
      sharedSleepingDistancing: false,
      sharedSleepingCommunication: false,
      sharedSleepingProvidedAccommodations: false,
      selfIsolateUnderstood: false,
      selfIsolateAccommodation: false,
      laundryServices: false,
      wasteManagementGloves: false,
      wasteManagementSchedule: false,
      wasteManagementBags: false,
      handWashingStations: false,
      handWashingSoapWater: false,
      handWashingWaterless: false,
      handWashingPaperTowels: false,
      handWashingSignage: false,
      distancingMaintained: false,
      distancingFaceShields: false,
      disinfectingSchedule: false,
      transportationSingleOccupant: false,
      transportationBusesVans: false,
      transportationHelicopter: false,
      transportationTrucksCars: false,
      transportationTravelPod: false,
      transportationCleaningDistancing: false,
      educationSignage: false,
      educationContactPersonnel: false,
      trainingCovid19: false,
      trainingEtiquette: false,
      trainingLocations: false,
      trainingFirstAid: false,
      trainingReporting: false,
      mealsDistancing: false,
      mealsDishware: false,
      mealsDishwashing: false,
      infectionSeparation: false,
      infectionSymptoms: false,
      infectionHeathLinkBC: false,
      infectionSanitization: false,
      infectedFeeding: false,
      infectedHousekeeping: false,
      infectedWaste: false,
      infectionAccommodation: false,
      certifyAccurateInformation: false,
      agreeToInspection: false
    }
  },
  getters: {
    getFormError: state => state.getFormError,
    gettingForm: state => state.gettingForm,
    step: state => state.step,
    submitting: state => state.submitting,
    submissionComplete: state => state.submissionComplete,
    submissionDetails: state => state.submissionDetails,
    submissionError: state => state.submissionError,

    // Form objects
    operationType: state => state.type,
    business: state => state.business,
    primaryContact: state => state.primaryContact,
    covidContact: state => state.covidContact,
    attestation: state => state.attestation,
    location: state => state.location
  },
  mutations: {
    setGetFormError(state, errorMessage) {
      state.getFormError = errorMessage;
    },
    setGettingForm(state, isGetting) {
      state.gettingForm = isGetting;
    },
    setSubmitting(state, isSubmitting) {
      state.submitting = isSubmitting;
    },
    setStep: (state, step) => {
      window.scrollTo(0, 0);
      state.step = step;
    },
    setSubmissionComplete(state) {
      state.submissionComplete = true;
      window.scrollTo(0, 0);
    },
    setSubmissionDetails(state, responseData) {
      state.submissionDetails = responseData;
    },
    setSubmissionError(state, errorMessage) {
      state.submissionError = errorMessage;
    },

    // Form updates
    setOperationType(state, type) {
      state.type = type;
    },
    updateBusiness: (state, obj) => {
      Object.assign(state.business, obj);
    },
    updatePrimaryContact: (state, obj) => {
      Object.assign(state.primaryContact, obj);
    },
    updateCovidContact: (state, obj) => {
      Object.assign(state.covidContact, obj);
    },
    updateAttestation: (state, obj) => {
      Object.assign(state.attestation, obj);
    },
    updateLocation: (state, obj) => {
      Object.assign(state.location, obj);
    }
  },
  actions: {
    async getForm({ commit }, id) {
      commit('setGettingForm', true);
      commit('setGetFormError', '');
      try {
        const response = await commonFormService.getSubmission(FormNames.AGRISEAFOODOPSCREENING, id);
        if (!response.data) {
          throw new Error(`Failed to GET for ${id}`);
        }
        const transformed = transformToState(response.data);

        commit('updateAttestation', transformed.attestation);
        commit('updateBusiness', transformed.business);
        commit('updatePrimaryContact', transformed.primaryContact);
        commit('updateCovidContact', transformed.covidContact);
        commit('updateLocation', transformed.location);
        commit('setOperationType', transformed.type ? transformed.type.display : '');
        commit('setSubmissionComplete');
      } catch (error) {
        console.error(`Error getting form: ${error}`); // eslint-disable-line no-console
        commit('setGetFormError', 'An error occurred while attempting to fetch details. Please refresh and try again.');
      } finally {
        commit('setGettingForm', false);
      }
    },
    async submitForm({ commit, state }) {
      commit('setSubmitting', true);
      commit('setSubmissionError', '');
      try {
        const body = transformToPost(state);
        const response = await commonFormService.sendSubmission(FormNames.AGRISEAFOODOPSCREENING, body);
        if (!response.data) {
          throw new Error('No response data from API while submitting form');
        }
        commit('setSubmissionDetails', response.data);
        commit('setSubmissionComplete');
      } catch (error) {
        console.error(`Error submitting form: ${error} - ${error.message}`); // eslint-disable-line no-console
        commit('setSubmissionError', 'An error occurred while attempting to submit the form. Please try again.');
      } finally {
        commit('setSubmitting', false);
      }
    },
    async sampleData({ commit }) {
      commit('updateBusiness', SampleData.business);
      commit('updatePrimaryContact', SampleData.primaryContact);
      commit('updateCovidContact', SampleData.covidContact);
      const l = SampleData.location;
      l.city = RandomCities[Math.floor(Math.random() * RandomCities.length)];
      commit('updateLocation', l);
    }
  }
};