Skip to content
Snippets Groups Projects
Commit dc982584 authored by Rémi PAILHAREY's avatar Rémi PAILHAREY :fork_knife_plate:
Browse files

fix: removed contract start date limitation

parent 4d757145
No related branches found
No related tags found
2 merge requests!50merge dev into master,!48fix: removed contract start date limitation
......@@ -28,21 +28,30 @@
],
"cSpell.words": [
"acces",
"adresse",
"apikey",
"appartement",
"arret",
"Arret",
"autorisation",
"backoffice",
"catched",
"cicid",
"collecte",
"contractuelles",
"contrat",
"Corrigees",
"courbe",
"cozyclient",
"criteres",
"demande",
"Derniere",
"Detaillees",
"ecolyo",
"enedis",
"Enedis",
"enedissgegrandlyon",
"escalier",
"Etage",
"etat",
"faultstring",
......@@ -50,19 +59,31 @@
"Generales",
"grandlyon",
"HISTO",
"initiateur",
"insee",
"konnector",
"konnectors",
"lastname",
"Libelle",
"llle",
"maxpower",
"mesure",
"mesures",
"numerique",
"numero",
"Perimetre",
"periodicite",
"personne",
"PMAX",
"rechercher",
"Recurrente",
"resultat",
"soapenv"
"soapenv",
"sociale",
"souscrit",
"souscrits",
"soutirage",
"utilisateur",
"voie"
]
}
const { errors } = require('cozy-konnector-libs')
const { getContractStartDate } = require('../../src/core/contractStartDate')
const xml2js = require('xml2js')
const mockSoapRequest = jest.fn()
jest.mock('easy-soap-request', () => async () => mockSoapRequest())
const responseMock = {
response: {
body: `<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns7:consulterDonneesTechniquesContractuellesResponse xmlns:ns0="http://www.erdf.fr/tube/exposition/finalisation" xmlns:ns7="http://www.enedis.fr/sge/b2b/services/consulterdonneestechniquescontractuelles/v1.0">
<point id="19160781274487">
<donneesGenerales>
<dateDerniereModificationFormuleTarifaireAcheminement>2021-08-01+02:00</dateDerniereModificationFormuleTarifaireAcheminement>
<niveauOuvertureServices>2</niveauOuvertureServices>
</donneesGenerales>
</point>
</ns7:consulterDonneesTechniquesContractuellesResponse>
</soap:Body>
</soapenv:Envelope>`,
},
}
const responseIssueMock = {
response: {
body: `<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns7:consulterDonneesTechniquesContractuellesResponse xmlns:ns0="http://www.erdf.fr/tube/exposition/finalisation" xmlns:ns7="http://www.enedis.fr/sge/b2b/services/consulterdonneestechniquescontractuelles/v1.0">
<point id="19160781274487">
</point>
</ns7:consulterDonneesTechniquesContractuellesResponse>
</soap:Body>
</soapenv:Envelope>`,
},
}
describe('getContractStartDate', () => {
it('should return void when successfully got contract start date ✅', async () => {
mockSoapRequest.mockResolvedValueOnce(responseMock)
expect.assertions(1)
try {
await getContractStartDate(
'http://pouet.com',
'apiAuthKey',
'pouet@pouet.com',
'1111111111'
)
expect(true).toBeTruthy()
} catch (error) {
expect(true).toBe(false)
}
})
it('should throw VENDOR_DOWN when failing request 🚫', async () => {
mockSoapRequest.mockRejectedValueOnce('error')
try {
await getContractStartDate()
expect(true).toBe(false)
} catch (error) {
expect(error.message).toBe(errors.VENDOR_DOWN)
}
})
it('should throw NOT_EXISTING_DIRECTORY when failing parsing 🚫', async () => {
mockSoapRequest.mockResolvedValueOnce(responseIssueMock)
jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
Envelope: {
Body: {
Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
faultstring: 'Mock error',
},
},
})
try {
await getContractStartDate(
'http://pouet.com',
'apiAuthKey',
'pouet@pouet.com',
'1111111111'
)
expect(true).toBe(false)
} catch (error) {
expect(error.message).toBe(errors.NOT_EXISTING_DIRECTORY)
}
})
})
const {
parseUserPdl,
parseContractStartDate,
parseContracts,
parseServiceId,
parseSgeXmlData,
......@@ -27,24 +26,6 @@ describe('parsing', () => {
const reply = parseUserPdl(result)
expect(reply).toEqual(1)
})
it('should parse contract start date', () => {
const result = {
Envelope: {
Body: {
consulterDonneesTechniquesContractuellesResponse: {
point: {
donneesGenerales: {
dateDerniereModificationFormuleTarifaireAcheminement:
'01/01/2022',
},
},
},
},
},
}
const reply = parseContractStartDate(result)
expect(reply).toEqual('01/01/2022')
})
it('should parse contract', () => {
const result = {
Envelope: {
......
// @ts-check
const { log, errors } = require('cozy-konnector-libs')
const soapRequest = require('easy-soap-request')
const {
parseTags,
parseValue,
parseContractStartDate,
} = require('../helpers/parsing')
const xml2js = require('xml2js')
const { consulterDonneesTechniquesContractuelles } = require('../requests/sge')
const Sentry = require('@sentry/node')
/**
* Get user contract start date
* @param {string} url
* @param {string} apiAuthKey
* @param {string} userLogin
* @param {string} pointId
* @returns {Promise<string>}
*/
async function getContractStartDate(url, apiAuthKey, userLogin, pointId) {
log('info', 'Fetching data start date')
const sgeHeaders = {
'Content-Type': 'text/xml;charset=UTF-8',
apikey: apiAuthKey,
}
const { response } = await soapRequest({
url: `${url}/enedis_SGE_ConsultationDonneesTechniquesContractuelles/1.0`,
headers: sgeHeaders,
xml: consulterDonneesTechniquesContractuelles(pointId, userLogin),
}).catch(err => {
const errorMessage =
'Error while fetching contract start date : ' + err.message
log('error', errorMessage)
Sentry.captureException(errorMessage, {
tags: {
section: 'getContractStartDate',
},
extra: {
pointId: pointId,
},
})
throw new Error(errors.VENDOR_DOWN)
})
const result = await xml2js.parseStringPromise(response.body, {
tagNameProcessors: [parseTags],
valueProcessors: [parseValue],
explicitArray: false,
})
try {
return parseContractStartDate(result)
} catch (error) {
const errorMessage =
'Error while processing contract start date: ' + error.message
log('error', errorMessage)
Sentry.captureException(errorMessage)
log(
'error',
`Enedis issue ${result.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${result.Envelope.Body.Fault.faultstring}`
)
throw new Error(errors.NOT_EXISTING_DIRECTORY)
}
}
module.exports = { getContractStartDate }
const { activateContract } = require('./contractActivation')
const { getContractStartDate } = require('./contractStartDate')
const { terminateContract } = require('./contractTermination')
const { verifyContract } = require('./contractVerification')
const { findUserPdl } = require('./findUserPdl')
......@@ -8,7 +7,6 @@ const { findUserAddress } = require('./findUserAddress')
module.exports = {
activateContract,
getContractStartDate,
terminateContract,
verifyContract,
findUserPdl,
......
......@@ -53,7 +53,7 @@
* @property {string} address
* @property {string} inseeCode
* @property {string} city
* @property {boolean} hasBeenThroughtSafetyOnBoarding
* @property {boolean} hasBeenThroughSafetyOnBoarding
*/
/**
......
......@@ -153,7 +153,7 @@ async function verifyUserIdentity(
inseeCode,
postalCode: fields.postalCode,
address: fields.address,
hasBeenThroughtSafetyOnBoarding: userSafetyOnBoarding,
hasBeenThroughSafetyOnBoarding: userSafetyOnBoarding,
city: fields.city,
}
}
......
......@@ -16,20 +16,6 @@ function parseUserPdl(result) {
]['point']['$'].id
}
/**
* Return User contract start date
* @param {string} result
* @returns {string}
*/
function parseContractStartDate(result) {
log('info', 'Parsing contract start date')
const json = JSON.stringify(result)
return JSON.parse(json)['Envelope']['Body'][
'consulterDonneesTechniquesContractuellesResponse'
]['point']['donneesGenerales'][
'dateDerniereModificationFormuleTarifaireAcheminement'
]
}
/**
* Return User address
* @param {string} result
......@@ -88,7 +74,7 @@ function parseSgeXmlData(result) {
* @returns {Promise<EnedisKonnectorData[]>} Parsed timestamp array
*/
async function formateDataForDoctype(data) {
log('info', 'Formating data')
log('info', 'Formatting data')
return data.map(record => {
const date = moment(record.d, 'YYYY/MM/DD h:mm:ss')
return {
......@@ -228,7 +214,6 @@ module.exports = {
checkContractExists,
formateDataForDoctype,
parseContracts,
parseContractStartDate,
parsePointId,
parseServiceId,
parseSgeXmlData,
......
......@@ -34,7 +34,6 @@ const {
activateContract,
verifyContract,
terminateContract,
getContractStartDate,
} = require('./core')
const { getAccount, saveAccountData } = require('./requests/cozy')
const { isLocal, isDev } = require('./helpers/env')
......@@ -47,13 +46,12 @@ moment.locale('fr') // set the language
moment.tz.setDefault('Europe/Paris') // set the timezone
/** Connector Constants **/
const manualExecution =
process.env.COZY_JOB_MANUAL_EXECUTION === 'true' ? true : false
let startDailyDate = manualExecution
const manualExecution = process.env.COZY_JOB_MANUAL_EXECUTION === 'true'
let startDate = manualExecution
? moment().subtract(12, 'month')
: moment().subtract(6, 'month')
let startDailyDateString = startDailyDate.format('YYYY-MM-DD')
const startLoadDate = moment().subtract(7, 'day')
: moment().subtract(36, 'month')
let startDateString = startDate.format('YYYY-MM-DD')
const startHalfHourDate = moment().subtract(7, 'day')
const endDate = moment()
const endDateString = endDate.format('YYYY-MM-DD')
const ACCOUNT_ID = isLocal() ? 'default_account_id' : 'enedissgegrandlyon'
......@@ -172,20 +170,9 @@ async function start(fields, cozyParameters) {
user.postalCode,
user.inseeCode,
user.city,
user.hasBeenThroughtSafetyOnBoarding
user.hasBeenThroughSafetyOnBoarding
)
// handle user contract start date in order to properly request data
const userContractStartDate = await getContractStartDate(
baseUrl,
apiAuthKey,
sgeLogin,
pointId
)
startDailyDate = moment(userContractStartDate, 'YYYY-MM-DD')
startDailyDateString = startDailyDate.format('YYYY-MM-DD')
const contractStartDate = moment().format('YYYY-MM-DD')
const contractEndDate = moment()
.add(1, 'year') // SGE force 1 year duration
......@@ -357,16 +344,6 @@ async function deleteConsent(
*/
async function gatherData(baseUrl, apiAuthKey, sgeLogin, pointId) {
log('info', 'Querying data...')
const userContractStartDate = await getContractStartDate(
baseUrl,
apiAuthKey,
sgeLogin,
pointId
)
startDailyDate = moment(userContractStartDate, 'YYYY-MM-DD')
startDailyDateString = startDailyDate.format('YYYY-MM-DD')
await getData(
`${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees_v3/1.0`,
apiAuthKey,
......@@ -402,15 +379,13 @@ async function getData(url, apiAuthKey, userLogin, pointId) {
apikey: apiAuthKey,
}
limitStartDate()
const { response } = await soapRequest({
url: url,
headers: sgeHeaders,
xml: consultationMesuresDetaillees(
pointId,
userLogin,
startDailyDateString,
startDateString,
endDateString,
'ENERGIE',
'EA'
......@@ -449,15 +424,13 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) {
apikey: apiAuthKey,
}
limitStartDate()
const { response } = await soapRequest({
url: url,
headers: sgeHeaders,
xml: consultationMesuresDetailleesMaxPower(
pointId,
userLogin,
startDailyDateString,
startDateString,
endDateString
),
}).catch(err => {
......@@ -480,27 +453,6 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) {
)
}
/**
* If start date exceed the maximum amount of data we can get with one query
* get only 36 month. Or 12 month if manual execution
* On manual execution, set the start date to one year ago.
*/
function limitStartDate() {
const livingDuration = moment(endDate).diff(startDailyDate, 'months', true)
// We need to prevent case that there is less than 12 month data
if (manualExecution && livingDuration > 12) {
startDailyDate = moment(endDate).subtract(12, 'month')
startDailyDateString = startDailyDate.format('YYYY-MM-DD')
} else if (livingDuration > 36) {
log(
'info',
'Start date exceed 36 month, setting start date to current date minus 36 month'
)
startDailyDate = moment(endDate).subtract(36, 'month')
startDailyDateString = startDailyDate.format('YYYY-MM-DD')
}
}
/**
* Get half-hour data
* @param {string} url
......@@ -520,7 +472,7 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) {
for (let i = 0; i < MAX_HISTO; i++) {
log('info', 'launch process with history')
const incrementedStartDateString = moment(startLoadDate)
const incrementedStartDateString = moment(startHalfHourDate)
.subtract(7 * i, 'day')
.format('YYYY-MM-DD')
const incrementedEndDateString = moment(endDate)
......@@ -657,7 +609,7 @@ async function aggregateMonthAndYearData(data) {
* @returns {boolean}
*/
function isFirstStart(account) {
if (account && account.data && account.data.consentId) {
if (account?.data?.consentId) {
log('info', 'Konnector not first start')
return false
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment