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

Merge branch '29-profondeur-donnees-lors-du-1er-appel' into 'dev'

fix: removed contract start date limitation

See merge request !48
parents 58bb1a98 dc982584
No related branches found
No related tags found
2 merge requests!50merge dev into master,!48fix: removed contract start date limitation
Pipeline #79246 passed
...@@ -28,21 +28,30 @@ ...@@ -28,21 +28,30 @@
], ],
"cSpell.words": [ "cSpell.words": [
"acces", "acces",
"adresse",
"apikey", "apikey",
"appartement",
"arret", "arret",
"Arret", "Arret",
"autorisation",
"backoffice", "backoffice",
"catched", "catched",
"cicid", "cicid",
"collecte",
"contractuelles",
"contrat",
"Corrigees", "Corrigees",
"courbe",
"cozyclient", "cozyclient",
"criteres", "criteres",
"demande",
"Derniere", "Derniere",
"Detaillees", "Detaillees",
"ecolyo", "ecolyo",
"enedis", "enedis",
"Enedis", "Enedis",
"enedissgegrandlyon", "enedissgegrandlyon",
"escalier",
"Etage", "Etage",
"etat", "etat",
"faultstring", "faultstring",
...@@ -50,19 +59,31 @@ ...@@ -50,19 +59,31 @@
"Generales", "Generales",
"grandlyon", "grandlyon",
"HISTO", "HISTO",
"initiateur",
"insee", "insee",
"konnector", "konnector",
"konnectors", "konnectors",
"lastname", "lastname",
"Libelle",
"llle", "llle",
"maxpower", "maxpower",
"mesure",
"mesures",
"numerique", "numerique",
"numero", "numero",
"Perimetre", "Perimetre",
"periodicite", "periodicite",
"personne",
"PMAX", "PMAX",
"rechercher",
"Recurrente", "Recurrente",
"resultat", "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 { const {
parseUserPdl, parseUserPdl,
parseContractStartDate,
parseContracts, parseContracts,
parseServiceId, parseServiceId,
parseSgeXmlData, parseSgeXmlData,
...@@ -27,24 +26,6 @@ describe('parsing', () => { ...@@ -27,24 +26,6 @@ describe('parsing', () => {
const reply = parseUserPdl(result) const reply = parseUserPdl(result)
expect(reply).toEqual(1) 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', () => { it('should parse contract', () => {
const result = { const result = {
Envelope: { 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 { activateContract } = require('./contractActivation')
const { getContractStartDate } = require('./contractStartDate')
const { terminateContract } = require('./contractTermination') const { terminateContract } = require('./contractTermination')
const { verifyContract } = require('./contractVerification') const { verifyContract } = require('./contractVerification')
const { findUserPdl } = require('./findUserPdl') const { findUserPdl } = require('./findUserPdl')
...@@ -8,7 +7,6 @@ const { findUserAddress } = require('./findUserAddress') ...@@ -8,7 +7,6 @@ const { findUserAddress } = require('./findUserAddress')
module.exports = { module.exports = {
activateContract, activateContract,
getContractStartDate,
terminateContract, terminateContract,
verifyContract, verifyContract,
findUserPdl, findUserPdl,
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
* @property {string} address * @property {string} address
* @property {string} inseeCode * @property {string} inseeCode
* @property {string} city * @property {string} city
* @property {boolean} hasBeenThroughtSafetyOnBoarding * @property {boolean} hasBeenThroughSafetyOnBoarding
*/ */
/** /**
......
...@@ -153,7 +153,7 @@ async function verifyUserIdentity( ...@@ -153,7 +153,7 @@ async function verifyUserIdentity(
inseeCode, inseeCode,
postalCode: fields.postalCode, postalCode: fields.postalCode,
address: fields.address, address: fields.address,
hasBeenThroughtSafetyOnBoarding: userSafetyOnBoarding, hasBeenThroughSafetyOnBoarding: userSafetyOnBoarding,
city: fields.city, city: fields.city,
} }
} }
......
...@@ -16,20 +16,6 @@ function parseUserPdl(result) { ...@@ -16,20 +16,6 @@ function parseUserPdl(result) {
]['point']['$'].id ]['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 * Return User address
* @param {string} result * @param {string} result
...@@ -88,7 +74,7 @@ function parseSgeXmlData(result) { ...@@ -88,7 +74,7 @@ function parseSgeXmlData(result) {
* @returns {Promise<EnedisKonnectorData[]>} Parsed timestamp array * @returns {Promise<EnedisKonnectorData[]>} Parsed timestamp array
*/ */
async function formateDataForDoctype(data) { async function formateDataForDoctype(data) {
log('info', 'Formating data') log('info', 'Formatting data')
return data.map(record => { return data.map(record => {
const date = moment(record.d, 'YYYY/MM/DD h:mm:ss') const date = moment(record.d, 'YYYY/MM/DD h:mm:ss')
return { return {
...@@ -228,7 +214,6 @@ module.exports = { ...@@ -228,7 +214,6 @@ module.exports = {
checkContractExists, checkContractExists,
formateDataForDoctype, formateDataForDoctype,
parseContracts, parseContracts,
parseContractStartDate,
parsePointId, parsePointId,
parseServiceId, parseServiceId,
parseSgeXmlData, parseSgeXmlData,
......
...@@ -34,7 +34,6 @@ const { ...@@ -34,7 +34,6 @@ const {
activateContract, activateContract,
verifyContract, verifyContract,
terminateContract, terminateContract,
getContractStartDate,
} = require('./core') } = require('./core')
const { getAccount, saveAccountData } = require('./requests/cozy') const { getAccount, saveAccountData } = require('./requests/cozy')
const { isLocal, isDev } = require('./helpers/env') const { isLocal, isDev } = require('./helpers/env')
...@@ -47,13 +46,12 @@ moment.locale('fr') // set the language ...@@ -47,13 +46,12 @@ moment.locale('fr') // set the language
moment.tz.setDefault('Europe/Paris') // set the timezone moment.tz.setDefault('Europe/Paris') // set the timezone
/** Connector Constants **/ /** Connector Constants **/
const manualExecution = const manualExecution = process.env.COZY_JOB_MANUAL_EXECUTION === 'true'
process.env.COZY_JOB_MANUAL_EXECUTION === 'true' ? true : false let startDate = manualExecution
let startDailyDate = manualExecution
? moment().subtract(12, 'month') ? moment().subtract(12, 'month')
: moment().subtract(6, 'month') : moment().subtract(36, 'month')
let startDailyDateString = startDailyDate.format('YYYY-MM-DD') let startDateString = startDate.format('YYYY-MM-DD')
const startLoadDate = moment().subtract(7, 'day') const startHalfHourDate = moment().subtract(7, 'day')
const endDate = moment() const endDate = moment()
const endDateString = endDate.format('YYYY-MM-DD') const endDateString = endDate.format('YYYY-MM-DD')
const ACCOUNT_ID = isLocal() ? 'default_account_id' : 'enedissgegrandlyon' const ACCOUNT_ID = isLocal() ? 'default_account_id' : 'enedissgegrandlyon'
...@@ -172,20 +170,9 @@ async function start(fields, cozyParameters) { ...@@ -172,20 +170,9 @@ async function start(fields, cozyParameters) {
user.postalCode, user.postalCode,
user.inseeCode, user.inseeCode,
user.city, 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 contractStartDate = moment().format('YYYY-MM-DD')
const contractEndDate = moment() const contractEndDate = moment()
.add(1, 'year') // SGE force 1 year duration .add(1, 'year') // SGE force 1 year duration
...@@ -357,16 +344,6 @@ async function deleteConsent( ...@@ -357,16 +344,6 @@ async function deleteConsent(
*/ */
async function gatherData(baseUrl, apiAuthKey, sgeLogin, pointId) { async function gatherData(baseUrl, apiAuthKey, sgeLogin, pointId) {
log('info', 'Querying data...') 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( await getData(
`${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees_v3/1.0`, `${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees_v3/1.0`,
apiAuthKey, apiAuthKey,
...@@ -402,15 +379,13 @@ async function getData(url, apiAuthKey, userLogin, pointId) { ...@@ -402,15 +379,13 @@ async function getData(url, apiAuthKey, userLogin, pointId) {
apikey: apiAuthKey, apikey: apiAuthKey,
} }
limitStartDate()
const { response } = await soapRequest({ const { response } = await soapRequest({
url: url, url: url,
headers: sgeHeaders, headers: sgeHeaders,
xml: consultationMesuresDetaillees( xml: consultationMesuresDetaillees(
pointId, pointId,
userLogin, userLogin,
startDailyDateString, startDateString,
endDateString, endDateString,
'ENERGIE', 'ENERGIE',
'EA' 'EA'
...@@ -449,15 +424,13 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) { ...@@ -449,15 +424,13 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) {
apikey: apiAuthKey, apikey: apiAuthKey,
} }
limitStartDate()
const { response } = await soapRequest({ const { response } = await soapRequest({
url: url, url: url,
headers: sgeHeaders, headers: sgeHeaders,
xml: consultationMesuresDetailleesMaxPower( xml: consultationMesuresDetailleesMaxPower(
pointId, pointId,
userLogin, userLogin,
startDailyDateString, startDateString,
endDateString endDateString
), ),
}).catch(err => { }).catch(err => {
...@@ -480,27 +453,6 @@ async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) { ...@@ -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 * Get half-hour data
* @param {string} url * @param {string} url
...@@ -520,7 +472,7 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) { ...@@ -520,7 +472,7 @@ async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) {
for (let i = 0; i < MAX_HISTO; i++) { for (let i = 0; i < MAX_HISTO; i++) {
log('info', 'launch process with history') log('info', 'launch process with history')
const incrementedStartDateString = moment(startLoadDate) const incrementedStartDateString = moment(startHalfHourDate)
.subtract(7 * i, 'day') .subtract(7 * i, 'day')
.format('YYYY-MM-DD') .format('YYYY-MM-DD')
const incrementedEndDateString = moment(endDate) const incrementedEndDateString = moment(endDate)
...@@ -657,7 +609,7 @@ async function aggregateMonthAndYearData(data) { ...@@ -657,7 +609,7 @@ async function aggregateMonthAndYearData(data) {
* @returns {boolean} * @returns {boolean}
*/ */
function isFirstStart(account) { function isFirstStart(account) {
if (account && account.data && account.data.consentId) { if (account?.data?.consentId) {
log('info', 'Konnector not first start') log('info', 'Konnector not first start')
return false 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