From f5f1bf6daf79bb4eefdf6bb4cca4d9e555ef1a23 Mon Sep 17 00:00:00 2001
From: David Hochbaum
Date: Tue, 10 Dec 2024 11:22:00 -0500
Subject: [PATCH] Individual emails for each segment
---
...auth.module.ts => listserv-auth.module.ts} | 2 +-
...th.service.ts => listserv-auth.service.ts} | 0
.../src/send-update/send-update.controller.ts | 101 +++++++++++++-----
server/src/send-update/send-update.module.ts | 4 +-
server/src/send-update/send-update.service.ts | 13 ++-
5 files changed, 85 insertions(+), 35 deletions(-)
rename server/src/listserv/{auth.module.ts => listserv-auth.module.ts} (76%)
rename server/src/listserv/{auth.service.ts => listserv-auth.service.ts} (100%)
diff --git a/server/src/listserv/auth.module.ts b/server/src/listserv/listserv-auth.module.ts
similarity index 76%
rename from server/src/listserv/auth.module.ts
rename to server/src/listserv/listserv-auth.module.ts
index 9edfb4be..0ed03cc8 100644
--- a/server/src/listserv/auth.module.ts
+++ b/server/src/listserv/listserv-auth.module.ts
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
-import { ListservAuthService } from './auth.service';
+import { ListservAuthService } from './listserv-auth.service';
import { ConfigModule } from '../config/config.module';
@Module({
diff --git a/server/src/listserv/auth.service.ts b/server/src/listserv/listserv-auth.service.ts
similarity index 100%
rename from server/src/listserv/auth.service.ts
rename to server/src/listserv/listserv-auth.service.ts
diff --git a/server/src/send-update/send-update.controller.ts b/server/src/send-update/send-update.controller.ts
index 808d8e45..66b61cec 100644
--- a/server/src/send-update/send-update.controller.ts
+++ b/server/src/send-update/send-update.controller.ts
@@ -2,7 +2,7 @@ import { Controller, Param, Post, Req, Res } from "@nestjs/common";
import { ConfigService } from "../config/config.service";
import { SendUpdateService } from "./send-update.service";
import { ProjectService } from "../project/project.service";
-import { ListservAuthService } from "../listserv/auth.service";
+import { ListservAuthService } from "../listserv/listserv-auth.service";
import { Request } from "express";
@Controller()
@@ -32,47 +32,92 @@ export class SendUpdateController {
const project = await this.projectService.findOneByName(params.id);
// If no project is found, projectService returns HTTP error automatically, and this function does not continue
-
+
// Production names use underscores, staging use dashes
- const segmentName = `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}${project["data"]["attributes"]["dcp-borough"] === "Citywide" ? "CW" : project["data"]["attributes"]["dcp-validatedcommunitydistricts"]}`
- const segmentIdResult = await this.sendUpdateService.getSegmentId(segmentName)
+ var segments = project["data"]["attributes"]["dcp-borough"] === "Citywide" ? [{ name: "CW", envSegment: `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}CW`, segmentId: "" }] : [];
- if(segmentIdResult.isError) {
- response.status(500).send(segmentIdResult);
- return;
+ if(project["data"]["attributes"]["dcp-validatedcommunitydistricts"]) {
+ project["data"]["attributes"]["dcp-validatedcommunitydistricts"].split(",").forEach(element => {
+ segments.push({ name: element, envSegment: `zap${this.sendgridEnvironment === "production" ? "_production_" : "-staging-"}${element}`, segmentId: "" })
+ });
}
- const emailData = {
- "domain": this.sendgridEnvironment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc",
- "id": params.id,
- "name": project["data"]["attributes"]["dcp-projectname"],
- "borocd": project["data"]["attributes"]["dcp-borough"] === "Citywide" ? "Citywide" : `${project["data"]["attributes"]["dcp-borough"]} CD ${project["data"]["attributes"]["dcp-validatedcommunitydistricts"].slice(1 )}`,
- "status": project["data"]["attributes"]["dcp-publicstatus"],
- "date": new Date().toLocaleDateString(),
- "additionalpublicinformation": project["data"]["attributes"]["dcp-additionalpublicinformation"],
- "dcpIsApplicant": project["data"]["attributes"]["dcp-applicant-customer-value"] === "DCP - Department of City Planning (NYC)"
- }
-
- const emailHtml = this.sendUpdateService.createProjectUpdateContent(emailData);
-
- const createUpdate = await this.sendUpdateService.createSingleSendProjectUpdate(params.id, emailHtml, segmentIdResult.segmentId);
-
- if (createUpdate.isError) {
- response.status(createUpdate.code).send({
+ if (!segments.length) {
+ response.status(400).send({
isError: true,
project,
- createUpdate
+ error: "No associated segments found."
})
return;
}
- const sendUpdate = await this.sendUpdateService.scheduleSingleSendProjectUpdate(createUpdate["0"]["body"]["id"]);
+ for (const segment of segments) {
+ const segmentIdResult = await this.sendUpdateService.getSegmentId(segment.envSegment);
+ if(segmentIdResult.isError) {
+ response.status(500).send(segmentIdResult);
+ return;
+ }
+ segment.segmentId = segmentIdResult.segmentId;
+ }
+
+ var creationUpdates = [];
+ var sendUpdates = [];
+
+ const boros = {
+ K: 'Brooklyn',
+ X: 'Bronx',
+ M: 'Manhattan',
+ Q: 'Queens',
+ R: 'Staten Island',
+ };
+
+ for (const segment of segments) {
+ const emailData = {
+ "domain": this.sendgridEnvironment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc",
+ "id": params.id,
+ "name": project["data"]["attributes"]["dcp-projectname"],
+ "borocd": segment.name === "CW" ? "Citywide" : `${boros[segment.name.slice(0,1)]} CD ${parseInt(segment.name.slice(1), 10)}`,
+ "status": project["data"]["attributes"]["dcp-publicstatus"],
+ "date": new Date().toLocaleDateString(),
+ "additionalpublicinformation": project["data"]["attributes"]["dcp-additionalpublicinformation"],
+ "dcpIsApplicant": project["data"]["attributes"]["dcp-applicant-customer-value"] === "DCP - Department of City Planning (NYC)",
+ "spansMoreThanOneCD": (project["data"]["attributes"]["dcp-validatedcommunitydistricts"] && (project["data"]["attributes"]["dcp-validatedcommunitydistricts"].split(",").length > 1))
+ }
+
+ const emailHtml = this.sendUpdateService.createProjectUpdateContent(emailData);
+
+ const createUpdate = await this.sendUpdateService.createSingleSendProjectUpdate(params.id, emailHtml, segment.segmentId);
+
+ if (createUpdate.isError) {
+ response.status(createUpdate.code).send({
+ isError: true,
+ project,
+ createUpdate
+ })
+ return;
+ }
+
+ const sendUpdate = await this.sendUpdateService.scheduleSingleSendProjectUpdate(createUpdate["0"]["body"]["id"]);
+
+ if (sendUpdate.isError) {
+ response.status(sendUpdate.code).send({
+ isError: true,
+ project,
+ createUpdate,
+ sendUpdate
+ })
+ return;
+ }
+
+ creationUpdates.push(createUpdate);
+ sendUpdates.push(sendUpdate);
+ }
response.status(201).send({
isError: false,
project,
- createUpdate,
- sendUpdate
+ creationUpdates,
+ sendUpdates
});
return;
}
diff --git a/server/src/send-update/send-update.module.ts b/server/src/send-update/send-update.module.ts
index de2ff6fd..2bd4666a 100644
--- a/server/src/send-update/send-update.module.ts
+++ b/server/src/send-update/send-update.module.ts
@@ -13,8 +13,8 @@ import { CrmModule } from "../crm/crm.module";
import { DocumentModule } from "../document/document.module";
import { DispositionModule } from "../disposition/disposition.module";
import { GeometryService } from "../project/geometry/geometry.service";
-import { ListservAuthModule } from "../listserv/auth.module";
-import { ListservAuthService } from "../listserv/auth.service";
+import { ListservAuthModule } from "../listserv/listserv-auth.module";
+import { ListservAuthService } from "../listserv/listserv-auth.service";
@Module({
imports: [
diff --git a/server/src/send-update/send-update.service.ts b/server/src/send-update/send-update.service.ts
index e754083d..adca0c3e 100644
--- a/server/src/send-update/send-update.service.ts
+++ b/server/src/send-update/send-update.service.ts
@@ -51,12 +51,12 @@ export class SendUpdateService {
*/
async createSingleSendProjectUpdate(id: string, emailHtml: string, segmentId: string) {
const data = {
- name: "Single Send Test 2024-12-06 v5",
+ name: "Single Send Test 2024-12-10 v3",
send_to: {
segment_ids: [segmentId]
},
email_config: {
- subject: "Single Send Test 2024-12-06 v5",
+ subject: "Single Send Test 2024-12-10 v3",
html_content: emailHtml,
generate_plain_content: true,
custom_unsubscribe_url: `https://${this.environment === "production" ? "zap.planning.nyc.gov" : "zap-staging.planninglabs.nyc"}/subscribers/{{${this.environment === "production" ? "zap_production_id" : "zap_staging_id"}}}`,
@@ -115,9 +115,10 @@ export class SendUpdateService {
* @param {string} date
* @param {string} additionalpublicinformation
* @param {string} dcpIsApplicant
+ * @param {boolean} spansMoreThanOneCD
* @returns {object}
*/
- createProjectUpdateContent({domain, id, name, borocd, status, date, additionalpublicinformation, dcpIsApplicant}) {
+ createProjectUpdateContent({domain, id, name, borocd, status, date, additionalpublicinformation, dcpIsApplicant, spansMoreThanOneCD}) {
var htmlContent = `
@@ -175,7 +176,7 @@ export class SendUpdateService {
- ${name}
+ ${name}${spansMoreThanOneCD ? "*" : ""}
in ${borocd}
`;
@@ -192,6 +193,10 @@ export class SendUpdateService {
htmlContent += `
New York City Department of City Planning is the applicant. Click here to learn more.
`
}
+ if (spansMoreThanOneCD) {
+ htmlContent += `
*Project spans more than one CD.
`
+ }
+
htmlContent += `