Skip to content
Snippets Groups Projects
parsing.js 6.18 KiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    // @ts-check
    const { log } = require('cozy-konnector-libs')
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    const moment = require('moment')
    
    const Sentry = require('@sentry/node')
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    /**
     * Return User PDL
     * @param {string} result
     * @returns {string}
     */
    function parseUserPdl(result) {
      log('info', 'Parsing User Pdl')
      const json = JSON.stringify(result)
      return JSON.parse(json)['Envelope']['Body']['rechercherPointResponse'][
        'points'
      ]['point']['$'].id
    }
    
    
    /**
     * Return User address
     * @param {string} result
     * @returns {Address}
     */
    function parseUserAddress(result) {
      log('info', 'Parsing user Address')
      const json = JSON.stringify(result)
      return JSON.parse(json)['Envelope']['Body'][
        'consulterDonneesTechniquesContractuellesResponse'
      ]['point']['donneesGenerales']['adresseInstallation']
    }
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    
    
    /**
     * Return User off-peak hours
     * @param {string} result
     * @returns {string}
     * @example "3H00-8H00;13H30-16H30"
     */
    function parseUserOffPeakHours(result) {
      log('info', 'Parsing user off-peak hours')
      const json = JSON.stringify(result)
      const rawOffPeakHours =
        JSON.parse(json)['Envelope']['Body'][
          'consulterDonneesTechniquesContractuellesResponse'
        ]['point']['situationComptage']['dispositifComptage']['relais'][
          'plageHeuresCreuses'
        ]
      // extract off-peak hours from parentheses
      let match = rawOffPeakHours.match(/\((.*?)\)/)
      // Check if there is a match and return the content
      if (match) {
        return match[1]
      } else {
        throw new Error('invalid off-peak hours format')
      }
    }
    
    
    /**
     * Return User contract start date
     * @param {string} result
     * @returns {Contract[] | Contract}
     */
    function parseContracts(result) {
      log('info', 'Parsing contract')
      const json = JSON.stringify(result)
      return JSON.parse(json)['Envelope']['Body'][
        'rechercherServicesSouscritsMesuresResponse'
      ]['servicesSouscritsMesures']['serviceSouscritMesures']
    }
    
    /**
     * Return User contract start date
     * @param {string} result
     * @returns {number}
     */
    function parseServiceId(result) {
      log('info', 'Parsing serviceId')
      const json = JSON.stringify(result)
      return JSON.parse(json)['Envelope']['Body'][
        'commanderCollectePublicationMesuresResponse'
      ]['serviceSouscritId']
    }
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    /**
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
     * Parsing SGE xml reply to get only mesure data
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
     * @param {string} result
     * @returns {SGEData[]}
     */
    function parseSgeXmlData(result) {
      log('info', 'Parsing list of documents')
    
      const json = JSON.stringify(result)
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      return JSON.parse(json)['Envelope']['Body'][
    
        'consulterMesuresDetailleesResponseV3'
      ]['grandeur']['points']
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    /**
     * Format data for DB storage
     * @param {SGEData[]} data
     * @returns {Promise<EnedisKonnectorData[]>} Parsed timestamp array
     */
    async function formateDataForDoctype(data) {
    
      log('info', 'Formatting data')
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      return data.map(record => {
    
        const date = moment(record.d, 'YYYY/MM/DD h:mm:ss')
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
        return {
          year: parseInt(date.format('YYYY')),
          month: parseInt(date.format('M')),
          day: parseInt(date.format('D')),
          hour: parseInt(date.format('H')),
          minute: parseInt(date.format('m')),
    
          load: record.v,
    
    /**
     * Check if response contains contracts
     * @param {string} parsedReply
     * @return {boolean}
     */
    function checkContractExists(parsedReply) {
      const json = JSON.stringify(parsedReply)
      return JSON.parse(json)['Envelope']['Body'][
        'rechercherServicesSouscritsMesuresResponse'
      ]['servicesSouscritsMesures']
    }
    
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    /**
    
     * Format tag in order to be manipulated easily
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
     * @param {string} name
     * @returns {string} name
     */
    function parseTags(name) {
      if (name.split(':')[1] !== undefined) {
        return name.split(':')[1]
      }
      return name
    }
    
    /**
     *
     * @param {string} value
     * @param {string} name
     * @returns {string|number} value
     */
    function parseValue(value, name) {
      // Wh => KWh
      if (name === 'v') {
        return parseFloat((parseInt(value) / 1000).toFixed(2))
      }
      return value
    }
    
    
    /**
     *
     * @param {string} value
     * @param {string} name
     * @returns {string|number} value
     */
    function parseValueHalfHour(value, name) {
      // W * 1/2h => KW * h
      if (name === 'v') {
        return parseFloat((parseInt(value) / 2000).toFixed(2))
      }
      return value
    }
    
    
    /**
     * Remove SGE useless multiple white spaces
     * @param {string} str
     * @returns {string}
     */
    function removeMultipleSpaces(str) {
      return str.replace(/  +/g, ' ')
    }
    
    
    /**
     * Remove SGE useless dots
     * This regular expression matches one or more consecutive dots
     * and then in the replacement function, it checks if the dots are surrounded by non-dot characters.
     * If so, it replaces them with a space; otherwise, it removes them
     * @example
     * console.log(removeDots(".....03G2")); // Outputs: "03G2"
     * console.log(removeDots("....ETG..4...D")); // Outputs: "ETG 4 D"
     * console.log(removeDots("ETG 4 D")); // Outputs: "ETG 4 D"
     * @param {string} input - The input string containing dots to be removed.
     * @returns {string} The input string without dots.
     */
    function removeDots(input) {
      return input.replace(/\.+/g, (match, offset, string) => {
        if (
          offset > 0 &&
          offset < string.length - match.length &&
          string[offset - 1] !== '.' &&
          string[offset + match.length] !== '.'
        ) {
          return ' '
        }
        return ''
      })
    }
    
    
    /**
     * Remove SGE address number
     * @param {string} str
     * @returns {string}
     */
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
    function removeAddressNumber(str) {
    
      return str.replace(/\d+ |b |B |T |t |\d+/g, '')
    }
    
    
    /**
     * Parse PDL and to validate correct length of 14 digits
     * @param {number} pointId - some pdl start with 0
     * @returns {string} pointId with 14 digits
     * @example "07123456789012"
     */
    function parsePointId(pointId) {
      const strPointId = pointId.toString()
      if (strPointId.length === 14) {
        return strPointId
      } else if (strPointId.length === 13) {
        return `0${strPointId}`
      } else {
    
        const errorMessage = 'PointId is malformed'
        Sentry.captureException(errorMessage, {
          tags: {
            section: 'parsePointId',
          },
          extra: {
            pointId: pointId,
          },
        })
        throw new Error(errorMessage)
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    module.exports = {
    
      checkContractExists,
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
      formateDataForDoctype,
    
      parsePointId,
    
      parseSgeXmlData,
      parseTags,
    
      parseUserOffPeakHours,
    
      parseUserPdl,
      parseValue,
      parseValueHalfHour,
    
    Bastien DUMONT's avatar
    Bastien DUMONT committed
      removeAddressNumber,
    
      removeMultipleSpaces,
    
    Hugo SUBTIL's avatar
    Hugo SUBTIL committed
    }