import * as eligibility from '../entities/Eligibility'; import { EligibilityStatus } from '../entities/Enums'; import { SmartMeterBookingClient } from '../clients/SmartMeterBookingClient'; import { UserDataState } from '../state/UserDataState'; import { isEmpty, minBy } from 'lodash'; export class EligibilityService { eligibilityState: eligibility.Eligibility; availabilityState: eligibility.Availability; constructor(private smartMeterBookingClient: SmartMeterBookingClient, private userDataState: UserDataState, private $q: QService) { } clear() { delete this.eligibilityState; } /** For internal use only - doesn't store the generated eligibility state. */ private _checkSupplyAddress(): Promise { const getAreaEligibility: () => Promise = () => this.smartMeterBookingClient.getAreaEligibility(this.userDataState.postcode).then(response => response.data.isEligible ? 'Eligible' : 'AreaNotEligible' ); const getMeterEligibility: () => Promise = () => { const address = this.userDataState.supplyAddress; const params: eligibility.MeterEligibilityRequestParams = { ...(address.mprns ? { mprns: address.mprns.join() } : {}), ...(address.electricMeterType ? { electricMeterTypes: address.electricMeterType.join() } : {}), ...(address.elecMeterSerials ? { elecMsns: address.elecMeterSerials.join() } : {}), ...(address.gasMeterSerials ? { gasMsns: address.gasMeterSerials.join() } : {}), ...(address.profileClass ? { profileClasses: address.profileClass.join() } : {}) }; return this.smartMeterBookingClient.getMeterEligibility(params).then(response => ({ // You are still eligible for PAYG+ if you already have a compatible smart meter status: response.data.isEligible || !response.data.smartMeterRequired ? 'Eligible' : 'MeterNotEligible', isIGT: response.data.isIGT, smartMeterRequired: response.data.smartMeterRequired })); } return getMeterEligibility().then(meterEligibility => { if (meterEligibility.status === 'Eligible' && meterEligibility.smartMeterRequired) return getAreaEligibility().then(areaEligibility => ({ ...meterEligibility, status: areaEligibility })); else return meterEligibility; }); } /** For internal use only - doesn't store the generated availability state. */ private _checkAvailability(): Promise { const address = this.userDataState.supplyAddress; const fuel = this.userDataState.fuel; // If there are no MPANs (or MPRNs for dual fuel customers then we can't get an appointment) if (isEmpty(address.mpans)) return this.$q.reject(); if (fuel === 'Dual' && isEmpty(address.mprns)) return this.$q.reject(); const params: eligibility.AvailableAppointmentsRequestParams = { postcode: address.postcode, fuel: fuel, mpan: address.mpans[0], ...(this.userDataState.fuel === 'Dual' ? { mprn: address.mprns[0] } : {}) } return this.smartMeterBookingClient.getAvailableAppointments(params).then(response => ({ appointmentAvailability: response.data.appointmentAvailability, firstAppointment: minBy(response.data.availableAppointments, t => t.start) })); } checkSupplyAddress(): Promise { return this.eligibilityState ? this.$q.when(this.eligibilityState) : this._checkSupplyAddress().then(state => { this.eligibilityState = state; return state; }); } checkAvailability(): Promise { return this.availabilityState ? this.$q.when(this.availabilityState) : this._checkAvailability().then(state => { this.availabilityState = state; return state; }); } }