diff --git a/src/notifications/monthlyReport.hbs b/src/notifications/monthlyReport.hbs index 0a1fc0225184b32ac917d97d49ce9628543636a6..29dfae79d423a3cefff2d65ce5342e5b49ae12d8 100644 --- a/src/notifications/monthlyReport.hbs +++ b/src/notifications/monthlyReport.hbs @@ -3,17 +3,17 @@ {{#> style}} {{/style}} <mj-style> - .elec-text { - color: #d87b39 !important; - font-weight: normal !important; + .text { + margin: 0; } - .gas-text { - color: #45d1b8 !important; - font-weight: normal !important; + .elec { + color: #d87b39; } - .water-text { - color: #3a98ec !important; - font-weight: normal !important; + .gas { + color: #45d1b8; + } + .water { + color: #3a98ec; } </mj-style> </mj-head> @@ -22,24 +22,32 @@ {{/base/header}} <mj-section background-color="#121212"> - <mj-column width="55%" vertical-align="middle"> + <mj-column padding="0 32px" vertical-align="middle"> + <mj-image src={{consoImageUrl}} width="132px" align="center" alt="consommation"></mj-image> <mj-text color="white" font-weight="900" font-size="24px"> Bonjour {{username}}, </mj-text> - {{#if consumptionTextExist }} - <mj-text color="white" font-weight="400" font-size="18px">Par rapport au mois {{previousMonth}}, vous avez consommé :{{{consumptionText}}}<br /></mj-text> + {{#if comparisonExist }} + <mj-text color="white" font-weight="700" font-size="18px">Votre bilan {{currentMonth}} {{currentYear}} est prêt. Voilà l’évolution de vos consommations :</mj-text> + {{#if yearComparisonExist }} + <mj-text color="white" font-weight="400" font-size="18px"> + Par rapport au mois + <span class="bold gold">{{currentMonth}} {{previousYear}}</span> + , vous avez consommé :{{{yearComparisonText}}} + </mj-text> + {{/if}} + {{#if monthComparisonExist }} + <mj-text color="white" font-weight="400" font-size="18px"> + Par rapport au mois + <span class="bold gold">{{previousMonth}} {{currentYear}}</span> + , vous avez consommé :{{{monthComparisonText}}} + </mj-text> + {{/if}} {{/if}} - </mj-column> - <mj-column width="45%" vertical-align="middle"> - <mj-image src={{consoImageUrl}} width="132px" align="center" alt="consommation"></mj-image> - </mj-column> - </mj-section> - <mj-section background-color="#121212"> - <mj-column> - <mj-text color="white" font-weight="400" font-size="18px">Retrouvez le détail de vos consommations et plus d'informations dans votre bilan Ecolyo.<br /><br /></mj-text> - <mj-social css-class="button-with-icon" icon-size="36px" mode="horizontal" font-size="20px" font-weight="700"> + <mj-text color="#A0A0A0" font-weight="400" font-size="18px" align="center">Retrouvez le détail de vos consommations et plus d’informations dans votre bilan Ecolyo.</mj-text> + <mj-social css-class="button-with-icon" icon-size="32px" mode="horizontal" font-size="20px" font-weight="700"> <mj-social-element src="{{baseUrl}}/assets/ecolyo-icon.png" name="ecolyo" padding="0 10px 0 0" href="{{clientUrl}}"> - Voir mon bilan + J’ouvre mon Ecolyo </mj-social-element> </mj-social> </mj-column> @@ -48,7 +56,7 @@ <mj-section background-color="#1B1C22"> <mj-column> {{#if isInfo}} - <mj-text css-class="title" color="white" font-weight="900" font-size="24px" align="center" > + <mj-text css-class="title" color="white" font-weight="900" font-size="24px" align="center"> L'info du mois </mj-text> <mj-image src="{{infoImage}}" width="82px" alt="nouveauté"></mj-image> @@ -58,20 +66,20 @@ <mj-divider css-class="m-divider"></mj-divider> {{/if}} {{#if isServiceNews}} - <mj-text css-class="title custom-link" color="white" font-weight="900" font-size="24px" align="center" > + <mj-text css-class="title custom-link" color="white" font-weight="900" font-size="24px" align="center"> {{newsTitle}} </mj-text> - <mj-text color="white" font-weight="400" font-size="18px" css-class="custom-link" >{{{newsContent}}}</mj-text> + <mj-text color="white" font-weight="400" font-size="18px" css-class="custom-link">{{{newsContent}}}</mj-text> {{/if}} {{#if divider2}} - <mj-divider css-class="m-divider"></mj-divider> + <mj-divider css-class="m-divider"></mj-divider> {{/if}} {{#if isPoll}} - <mj-text css-class="title " color="white" font-weight="900" font-size="24px" align="center" > + <mj-text css-class="title " color="white" font-weight="900" font-size="24px" align="center"> Votre avis nous intéresse </mj-text> - <mj-text color="white" font-weight="400" font-size="18px" css-class="custom-link" >{{{pollText}}}</mj-text> - <mj-button color="black" background-color="#F1C017" css-class="button" font-size="20px" font-weight="700" > + <mj-text color="white" font-weight="400" font-size="18px" css-class="custom-link">{{{pollText}}}</mj-text> + <mj-button color="black" background-color="#F1C017" css-class="button" font-size="20px" font-weight="700"> <a href="{{pollUrl}}" style="text-decoration: none; color: black">C'est parti !</a> </mj-button> {{/if}} diff --git a/src/notifications/style.hbs b/src/notifications/style.hbs index 4e9de2c7d000f731ad21100c9a0c6f1f6a82327e..b1b78eb982639ca0ea1dcfda5871e2063e0c14be 100644 --- a/src/notifications/style.hbs +++ b/src/notifications/style.hbs @@ -51,4 +51,7 @@ U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } @font-face { font-family: 'Lato-Bold'; font-style: normal; font-weight: 800; src: asset-url('Lato-Bold.woff2') format('woff2'); } +</mj-style> +<mj-style> + .gold { color: #F1C017 } .bold { font-weight: 700 } </mj-style> \ No newline at end of file diff --git a/src/targets/services/monthlyReportNotification.ts b/src/targets/services/monthlyReportNotification.ts index 82d62f731dc40dfbb374a01b227c858b45f950a8..db404d87f2bbad3b97a6fce53b933623e9a4a584 100644 --- a/src/targets/services/monthlyReportNotification.ts +++ b/src/targets/services/monthlyReportNotification.ts @@ -8,7 +8,7 @@ import { import { FluidType } from 'enum/fluid.enum' import { TimeStep } from 'enum/timeStep.enum' import get from 'lodash/get' -import { DateTime } from 'luxon' +import { DateTime, DurationLike } from 'luxon' import mjml2html from 'mjml' import { PerformanceIndicator } from 'models' import { MonthlyReport } from 'models/monthlyReport.model' @@ -33,25 +33,28 @@ interface MonthlyReportNotificationProps { */ const getConsumptionValue = async ( client: Client, - fluidType: FluidType[] + fluidType: FluidType[], + period: 'month' | 'year' ): Promise<PerformanceIndicator[]> => { const consumptionService = new ConsumptionService(client) const analysisDate = DateTime.local().setZone('utc', { keepLocalTime: true }) - const periods = { - timePeriod: { - startDate: analysisDate.minus({ month: 1 }).startOf('month'), - endDate: analysisDate.minus({ month: 1 }).endOf('month'), - }, - comparisonTimePeriod: { - startDate: analysisDate.minus({ month: 2 }).startOf('month'), - endDate: analysisDate.minus({ month: 2 }).endOf('month'), - }, + const timePeriod = { + startDate: analysisDate.minus({ month: 1 }).startOf('month'), + endDate: analysisDate.minus({ month: 1 }).endOf('month'), } + const minusPeriod: DurationLike = + period === 'year' ? { year: 1, month: 1 } : { month: 2 } + + const comparisonTimePeriod = { + startDate: analysisDate.minus(minusPeriod).startOf('month'), + endDate: analysisDate.minus(minusPeriod).endOf('month'), + } + return consumptionService.getPerformanceIndicators( - periods.timePeriod, + timePeriod, TimeStep.MONTH, fluidType, - periods.comparisonTimePeriod + comparisonTimePeriod ) } @@ -60,70 +63,57 @@ const getConsumptionValue = async ( * @param client * @returns string */ -const buildConsumptionText = async (client: Client) => { +const buildComparisonText = async ( + client: Client, + period: 'month' | 'year' +) => { logStack('info', 'Building consumption text...') - const consumption = await getConsumptionValue(client, [ - FluidType.ELECTRICITY, - FluidType.GAS, - FluidType.WATER, - ]) - let text = '' - if (consumption[FluidType.ELECTRICITY]) { + const consumption = await getConsumptionValue( + client, + [FluidType.ELECTRICITY, FluidType.GAS, FluidType.WATER], + period + ) + const fluidTexts = [] + + if (consumption[FluidType.ELECTRICITY]?.percentageVariation) { const value = consumption[FluidType.ELECTRICITY].percentageVariation - ? consumption[FluidType.ELECTRICITY].percentageVariation - : 0 - if (value) { - if (value > 0) { - text += - '<span class="elec-text"><br>+ ' + - Math.ceil(value * 100) + - " % d'électricité</span>" - } else { - text += - '<span class="elec-text"><br>- ' + - Math.ceil(Math.abs(value * 100)) + - " % d'électricité</span>" - } - } + const sign = value > 0 ? '+' : '-' + fluidTexts.push( + `<p class="elec text">${sign} ${formatConsumptionValue( + value + )} % d'électricité</p>` + ) } - if (consumption[FluidType.GAS]) { - const value = - consumption[FluidType.GAS]?.percentageVariation !== null - ? consumption[FluidType.GAS].percentageVariation - : 0 - if (value) { - if (value > 0) { - text += - '<span class="gas-text"><br>+ ' + - Math.ceil(value * 100) + - ' % de gaz</span>' - } else { - text += - '<span class="gas-text"><br>- ' + - Math.ceil(Math.abs(value * 100)) + - ' % de gaz</span>' - } - } + + if (consumption[FluidType.GAS]?.percentageVariation) { + const value = consumption[FluidType.GAS].percentageVariation + const sign = value > 0 ? '+' : '-' + fluidTexts.push( + `<p class="gas text">${sign} ${formatConsumptionValue( + value + )} % de gaz</p>` + ) } - if (consumption[FluidType.WATER]) { + + if (consumption[FluidType.WATER]?.percentageVariation) { const value = consumption[FluidType.WATER].percentageVariation - ? consumption[FluidType.WATER].percentageVariation - : 0 - if (value) { - if (value > 0) { - text += - '<span class="water-text"><br>+ ' + - Math.ceil(value * 100) + - " % d'eau</span>" - } else { - text += - '<span class="water-text"><br>- ' + - Math.ceil(Math.abs(value * 100)) + - " % d'eau</span>" - } - } + const sign = value > 0 ? '+' : '-' + fluidTexts.push( + `<p class="water text">${sign} ${formatConsumptionValue( + value + )} % d'eau</p>` + ) } - return text + + return fluidTexts.join('') +} + +/** + * Get the ceiled absolute percentage representation of a number + * @example (ex: -0.1234 => 13) + */ +const formatConsumptionValue = (value: number): number => { + return Math.ceil(Math.abs(value * 100)) } /** @@ -249,7 +239,8 @@ const monthlyReportNotification = async ({ unsubscribeUrl = url.replace('analysis', 'unsubscribe') } - const consumptionText = await buildConsumptionText(client) + const monthComparisonText = await buildComparisonText(client, 'month') + const yearComparisonText = await buildComparisonText(client, 'year') const isInfo: boolean = monthlyReport.info !== '' @@ -272,8 +263,12 @@ const monthlyReportNotification = async ({ username: username, clientUrl: url, unsubscribeUrl: unsubscribeUrl, - consumptionTextExist: consumptionText.length > 0, - consumptionText: consumptionText.replace(/{cozyUrl}/g, appLink + '#/'), + comparisonExist: + monthComparisonText.length > 0 || yearComparisonText.length > 0, + monthComparisonExist: monthComparisonText.length > 0, + monthComparisonText: monthComparisonText, + yearComparisonExist: yearComparisonText.length > 0, + yearComparisonText: yearComparisonText, infoText: monthlyReport.info.replace(/{cozyUrl}/g, appLink + '#/'), infoImage: monthlyReport.image !== '' @@ -285,7 +280,7 @@ const monthlyReportNotification = async ({ isServiceNews: isServiceNews, divider2: isServiceNews && isPoll, isPoll: isPoll, - newsTitle: monthlyReport.newsTitle.replace(/{cozyUrl}/g, appLink + '#/'), + newsTitle: monthlyReport.newsTitle, newsContent: monthlyReport.newsContent.replace( /{cozyUrl}/g, appLink + '#/' @@ -293,6 +288,9 @@ const monthlyReportNotification = async ({ pollText: monthlyReport.question.replace(/{cozyUrl}/g, appLink + '#/'), pollUrl: monthlyReport.link, previousMonth: getMonthNameWithPrep(date.minus({ month: 1 })), + currentMonth: getMonthNameWithPrep(date), + previousYear: date.year - 1, + currentYear: date.year, consoImageUrl: baseUrl + '/assets/multifluidConsumption.png', feedbackImageUrl: baseUrl + '/assets/feedback.png', })