diff --git a/manage/app/controllers/email/reporting.js b/manage/app/controllers/email/reporting.js index f8ca5801..d21f4e43 100644 --- a/manage/app/controllers/email/reporting.js +++ b/manage/app/controllers/email/reporting.js @@ -9,6 +9,7 @@ import query from 'leads-manage/gql/queries/email-report/run'; export default Controller.extend(ComponentQueryManager, LoadingMixin, { center: moment(), isRunning: false, + excludeDeploymentTypeEntities: false, canSubmit: computed('isRunning', 'range.{start,end}', function() { if (this.get('isRunning')) return false; @@ -28,12 +29,31 @@ export default Controller.extend(ComponentQueryManager, LoadingMixin, { return end.valueOf(); }), + exportUrl: computed('range.{start,end}', 'excludeDeploymentTypeEntities', 'deploymentTypeEntities.[]', function() { + const { start, end } = this.getProperties('start', 'end'); + const types = this.get('deploymentTypeEntities'); + const exclude = this.get('excludeDeploymentTypeEntities'); + const entities = (types || []).map(type => encodeURIComponent(type.entity)).join(','); + const params = new URLSearchParams(); + params.set('start', start); + params.set('end', end); + if (entities) { + if (exclude) { + params.set('excludeDeploymentTypeEntities', entities); + } else { + params.set('includeDeploymentTypeEntities', entities); + } + } + return `/export/email-deployment-report?${params}`; + }), + init() { this._super(...arguments); this.set('range', { start: moment().startOf('week'), end: moment().endOf('week'), }); + this.set('deploymentTypeEntities', []); }, actions: { @@ -50,9 +70,16 @@ export default Controller.extend(ComponentQueryManager, LoadingMixin, { this.set('isRunning', true); this.showLoading(); + const types = this.get('deploymentTypeEntities'); + const exclude = this.get('excludeDeploymentTypeEntities'); + const entities = (types || []).map(type => type.entity); + const input = { start: this.get('range.start').valueOf(), end: this.get('range.end').valueOf(), + ...(entities.length && { + ...(exclude ? { excludeDeploymentTypeEntities: entities } : { includeDeploymentTypeEntities: entities }) + }) } const variables = { input }; diff --git a/manage/app/templates/email/reporting.hbs b/manage/app/templates/email/reporting.hbs index c21ba7ae..4bc50933 100644 --- a/manage/app/templates/email/reporting.hbs +++ b/manage/app/templates/email/reporting.hbs @@ -8,89 +8,130 @@
- {{#power-calendar-range - center=center - selected=range - onCenterChange=(action (mut center) value="moment") - onSelect=(action "setRange" value="moment") - as |calendar| - }} - {{calendar.nav}} - {{calendar.days}} - {{/power-calendar-range}} - -
- - {{#if result}} - {{entypo-icon "download"}} Export Report - {{/if}} +
+
+
+ + {{type-ahead + placeholder="Begin typing to find a deployment type..." + type="email-deployment-type" + field="data.Name" + selected=deploymentTypeEntities + multiple=true + allowClear=true + onChange=(action (mut deploymentTypeEntities)) + }} +
+ {{input type="checkbox" checked=excludeDeploymentTypeEntities class="custom-control-input" id="exclude-deployment-type-ids"}} + +
+ Optional. The deployment types to {{#if excludeDeploymentTypeEntities}}exclude from{{else}}include in{{/if}} this report. +
+
+
+
+
+ + {{#power-calendar-range + center=center + selected=range + onCenterChange=(action (mut center) value="moment") + onSelect=(action "setRange" value="moment") + as |calendar| + }} + {{calendar.nav}} + {{calendar.days}} + {{/power-calendar-range}} +

+ {{#if (and range.start range.end)}} + {{moment-format range.start "MMM Do, YYYY"}} + - + {{moment-format range.end "MMM Do, YYYY"}} + {{else}} + Select a date range... + {{/if}} +

+
+
+
+
+ +
- {{#each result.weeks as |week|}} -
- - - - - - - - - - - - - - - - - - - - - - - {{#each week.types as |c|}} - - - - - - - - - - - - - - - - - - - {{/each}} - -
YearWeekStartingCategory# SentTotal SentAvg. SentAvg. DeliveredAvg. Delivery RateTotal Unique OpensAvg. Unique OpensAvg. Unq Open RateTotal Unique ClicksAvg. Unique ClicksAvg. Unq CTRAvg. Unq CTOR
{{week.year}}{{week.number}}{{moment-format week.starting "MMM D"}}{{c.name}}{{c.deploymentCount}}{{format-number c.totalSent format="0,0"}}{{format-number c.avgSent format="0,0"}}{{format-number c.avgDelivered format="0,0"}}{{format-number c.avgDeliveryRate format="00.0%"}}{{format-number c.totalUniqueOpens format="0,0"}}{{format-number c.avgUniqueOpens format="0,0"}}{{format-number c.avgUniqueOpenRate format="00.0%"}}{{format-number c.totalUniqueClicks format="0,0"}}{{format-number c.avgUniqueClicks format="0,0"}}{{format-number c.avgUniqueClickToDeliveredRate format="00.0%"}}{{format-number c.avgUniqueClickToOpenRate format="00.0%"}}
-
- {{else}} - - No results found. - - {{/each}} +{{#if result}} +
+
+
+
+
+
{{moment-format result.start "MMM Do, YYYY"}} through {{moment-format result.end "MMM Do, YYYY"}}
+ {{#each result.weeks as |week|}} +
+ + + + + + + + + + + + + + + + + + + + + + + {{#each week.types as |c|}} + + + + + + + + + + + + + + + + + + + {{/each}} + +
YearWeekStartingCategory# SentTotal SentAvg. SentAvg. DeliveredAvg. Delivery RateTotal Unique OpensAvg. Unique OpensAvg. Unq Open RateTotal Unique ClicksAvg. Unique ClicksAvg. Unq CTRAvg. Unq CTOR
{{week.year}}{{week.number}}{{moment-format week.starting "MMM D"}}{{c.name}}{{c.deploymentCount}}{{format-number c.totalSent format="0,0"}}{{format-number c.avgSent format="0,0"}}{{format-number c.avgDelivered format="0,0"}}{{format-number c.avgDeliveryRate format="00.0%"}}{{format-number c.totalUniqueOpens format="0,0"}}{{format-number c.avgUniqueOpens format="0,0"}}{{format-number c.avgUniqueOpenRate format="00.0%"}}{{format-number c.totalUniqueClicks format="0,0"}}{{format-number c.avgUniqueClicks format="0,0"}}{{format-number c.avgUniqueClickToDeliveredRate format="00.0%"}}{{format-number c.avgUniqueClickToOpenRate format="00.0%"}}
-
- - {{/if}} + {{else}} + + No results found. + + {{/each}} +
+
-
- +{{/if}} diff --git a/monorepo/services/server/src/graphql/definitions/email-deployment.js b/monorepo/services/server/src/graphql/definitions/email-deployment.js index 5b7adc5e..f575901a 100644 --- a/monorepo/services/server/src/graphql/definitions/email-deployment.js +++ b/monorepo/services/server/src/graphql/definitions/email-deployment.js @@ -140,6 +140,10 @@ type EmailDeploymentTypeEdge { input EmailDeploymentReportInput { start: Date end: Date + + "The EmailDeploymentType entities that should be included/excluded from the query." + includeDeploymentTypeEntities: [String!]! = [] + excludeDeploymentTypeEntities: [String!]! = [] } input EmailDeploymentSortInput { diff --git a/monorepo/services/server/src/graphql/resolvers/email-deployment.js b/monorepo/services/server/src/graphql/resolvers/email-deployment.js index cd85292a..b631db90 100644 --- a/monorepo/services/server/src/graphql/resolvers/email-deployment.js +++ b/monorepo/services/server/src/graphql/resolvers/email-deployment.js @@ -115,8 +115,20 @@ module.exports = { */ emailDeploymentReport: (_, { input }, { auth }) => { auth.check(); - const { start, end } = input; - return emailDeploymentReportService.create({ start, end }); + const { + start, + end, + includeDeploymentTypeEntities = [], + excludeDeploymentTypeEntities = [], + } = input; + const includeOmedaDeploymentTypeIds = includeDeploymentTypeEntities.map((e) => parseInt(e.split('*')[1], 10)); + const excludeOmedaDeploymentTypeIds = excludeDeploymentTypeEntities.map((e) => parseInt(e.split('*')[1], 10)); + return emailDeploymentReportService.create({ + start, + end, + includeOmedaDeploymentTypeIds, + excludeOmedaDeploymentTypeIds, + }); }, /** diff --git a/monorepo/services/server/src/routes/exports/index.js b/monorepo/services/server/src/routes/exports/index.js index 9e906fee..a546e4c4 100644 --- a/monorepo/services/server/src/routes/exports/index.js +++ b/monorepo/services/server/src/routes/exports/index.js @@ -59,8 +59,17 @@ router.get('/line-item/:hash/email/metrics', asyncRoute(async (req, res) => { router.get('/email-deployment-report', asyncRoute(async (req, res) => { const start = new Date(parseInt(req.query.start, 10)); const end = new Date(parseInt(req.query.end, 10)); + const includeDeploymentTypeEntities = (req.query.includeDeploymentTypeEntities && req.query.includeDeploymentTypeEntities.split(',')) || []; + const excludeDeploymentTypeEntities = (req.query.excludeDeploymentTypeEntities && req.query.excludeDeploymentTypeEntities.split(',')) || []; + const includeOmedaDeploymentTypeIds = includeDeploymentTypeEntities.map((e) => parseInt(e.split('*')[1], 10)); + const excludeOmedaDeploymentTypeIds = excludeDeploymentTypeEntities.map((e) => parseInt(e.split('*')[1], 10)); - const rows = await emailDeploymentReportService.export({ start, end }); + const rows = await emailDeploymentReportService.export({ + start, + end, + includeOmedaDeploymentTypeIds, + excludeOmedaDeploymentTypeIds, + }); let csv; if (rows.length) { diff --git a/monorepo/services/server/src/services/email-deployment-report.js b/monorepo/services/server/src/services/email-deployment-report.js index 299ebad7..2471be36 100644 --- a/monorepo/services/server/src/services/email-deployment-report.js +++ b/monorepo/services/server/src/services/email-deployment-report.js @@ -10,8 +10,18 @@ module.exports = { return parseFloat((Math.round((num * Math.pow(10, dec)) + (sign * 0.0001)) / Math.pow(10, dec)).toFixed(dec)); }, - async export({ start, end }) { - const results = await this.create({ start, end }); + async export({ + start, + end, + includeOmedaDeploymentTypeIds = [], + excludeOmedaDeploymentTypeIds = [], + }) { + const results = await this.create({ + start, + end, + includeOmedaDeploymentTypeIds, + excludeOmedaDeploymentTypeIds, + }); if (!isArray(results.weeks)) return []; return results.weeks.reduce((arr, week) => { const { year, week: weekNumber, types } = week; @@ -56,7 +66,12 @@ module.exports = { }, []); }, - async create({ start, end }) { + async create({ + start, + end, + includeOmedaDeploymentTypeIds = [], + excludeOmedaDeploymentTypeIds = [], + }) { const now = new Date(); const starting = start @@ -82,6 +97,12 @@ module.exports = { $match: { 'omeda.SentDate': { $gte: starting, $lte: ending }, 'omeda.DeploymentDesignation': 'Newsletter', + ...((includeOmedaDeploymentTypeIds.length || excludeOmedaDeploymentTypeIds.length) && { + 'omeda.DeploymentTypeId': { + ...(includeOmedaDeploymentTypeIds.length && { $in: includeOmedaDeploymentTypeIds }), + ...(excludeOmedaDeploymentTypeIds.length && { $nin: excludeOmedaDeploymentTypeIds }), + }, + }), }, }, {