From 7a286e3519619a8d974242fd98e0248204af9850 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Thu, 22 Aug 2024 22:59:33 +0200 Subject: [PATCH] =?UTF-8?q?Mail=20Modul=20=C3=BCberarbeitet,=20Korrekturen?= =?UTF-8?q?=20am=20PaymentService,=20neuer=20customerType=20seller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bizmatch-server/.vscode/launch.json | 28 ++++++- bizmatch-server/.vscode/tasks.json | 31 ++++++++ bizmatch-server/src/drizzle/schema.ts | 4 +- bizmatch-server/src/mail/mail.config.ts | 14 ++++ bizmatch-server/src/mail/mail.controller.ts | 5 ++ bizmatch-server/src/mail/mail.module.ts | 74 ++++++++++++++----- bizmatch-server/src/mail/mail.service.ts | 2 +- bizmatch-server/src/models/db.model.ts | 6 +- .../src/payment/payment.service.ts | 31 +++----- .../select-options/select-options.service.ts | 1 + .../validated-select.component.html | 10 ++- .../validated-select.component.ts | 1 + .../app/pages/pricing/pricing.component.ts | 2 +- .../account/account.component.html | 26 +++---- .../subscription/account/account.component.ts | 22 +++--- .../app/pages/success/success.component.ts | 2 +- 16 files changed, 183 insertions(+), 76 deletions(-) create mode 100644 bizmatch-server/.vscode/tasks.json create mode 100644 bizmatch-server/src/mail/mail.config.ts diff --git a/bizmatch-server/.vscode/launch.json b/bizmatch-server/.vscode/launch.json index e9b2e00..1a645a2 100644 --- a/bizmatch-server/.vscode/launch.json +++ b/bizmatch-server/.vscode/launch.json @@ -14,7 +14,8 @@ "console": "integratedTerminal", "env": { "HOST_NAME": "localhost" - } + }, + "preLaunchTask": "Start Stripe Listener" }, { "type": "node", @@ -60,5 +61,30 @@ "sourceMaps": true, "smartStep": true } + ], + "tasks": [ + { + "label": "Start Stripe Listener", + "type": "shell", + "command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook", + "isBackground": true, + "problemMatcher": [ + { + "pattern": [ + { + "regexp": ".", + "file": 1, + "location": 2, + "message": 3 + } + ], + "background": { + "activeOnStart": true, + "beginsPattern": ".", + "endsPattern": "." + } + } + ] + } ] } diff --git a/bizmatch-server/.vscode/tasks.json b/bizmatch-server/.vscode/tasks.json new file mode 100644 index 0000000..a3ae8fc --- /dev/null +++ b/bizmatch-server/.vscode/tasks.json @@ -0,0 +1,31 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Stripe Listener", + "type": "shell", + "command": "stripe listen -e checkout.session.completed --forward-to http://localhost:3000/bizmatch/payment/webhook", + "problemMatcher": [], + "isBackground": true, // Task läuft im Hintergrund + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + } + }, + { + "label": "Start Nest.js", + "type": "npm", + "script": "start:debug", + "isBackground": false, + "problemMatcher": [], + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + } + } + ] +} diff --git a/bizmatch-server/src/drizzle/schema.ts b/bizmatch-server/src/drizzle/schema.ts index a7180dc..8fb9115 100644 --- a/bizmatch-server/src/drizzle/schema.ts +++ b/bizmatch-server/src/drizzle/schema.ts @@ -2,7 +2,7 @@ import { boolean, char, doublePrecision, integer, jsonb, pgEnum, pgTable, serial import { AreasServed, LicensedIn } from '../models/db.model'; export const PG_CONNECTION = 'PG_CONNECTION'; export const genderEnum = pgEnum('gender', ['male', 'female']); -export const customerTypeEnum = pgEnum('customerType', ['buyer', 'professional']); +export const customerTypeEnum = pgEnum('customerType', ['buyer', 'seller', 'professional']); export const customerSubTypeEnum = pgEnum('customerSubType', ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']); export const listingsCategoryEnum = pgEnum('listingsCategory', ['commercialProperty', 'business']); export const subscriptionTypeEnum = pgEnum('subscriptionType', ['free', 'professional', 'broker']); @@ -33,8 +33,6 @@ export const users = pgTable('users', { longitude: doublePrecision('longitude'), stripeCustomerId: text('stripeCustomerId'), subscriptionId: text('subscriptionId'), - planActive: boolean('planActive').default(false), - planExpires: timestamp('planExpires'), subscriptionPlan: subscriptionTypeEnum('subscriptionType'), // embedding: vector('embedding', { dimensions: 1536 }), }); diff --git a/bizmatch-server/src/mail/mail.config.ts b/bizmatch-server/src/mail/mail.config.ts new file mode 100644 index 0000000..4b68707 --- /dev/null +++ b/bizmatch-server/src/mail/mail.config.ts @@ -0,0 +1,14 @@ +import { registerAs } from '@nestjs/config'; + +export default registerAs('mail', () => ({ + host: 'email-smtp.us-east-2.amazonaws.com', + port: 587, + secure: false, + auth: { + user: process.env.AMAZON_USER, + pass: process.env.AMAZON_PASSWORD, + }, + defaults: { + from: '"No Reply" ', + }, +})); diff --git a/bizmatch-server/src/mail/mail.controller.ts b/bizmatch-server/src/mail/mail.controller.ts index 256a6c9..20c3a3a 100644 --- a/bizmatch-server/src/mail/mail.controller.ts +++ b/bizmatch-server/src/mail/mail.controller.ts @@ -1,4 +1,5 @@ import { Body, Controller, Post } from '@nestjs/common'; +import { User } from 'src/models/db.model'; import { ErrorResponse, MailInfo } from '../models/main.model'; import { MailService } from './mail.service.js'; @@ -13,4 +14,8 @@ export class MailController { return this.mailService.sendRequest(mailInfo); } } + @Post('subscriptionConfirmation') + sendSubscriptionConfirmation(@Body() user: User): Promise { + return this.mailService.sendSubscriptionConfirmation(user); + } } diff --git a/bizmatch-server/src/mail/mail.module.ts b/bizmatch-server/src/mail/mail.module.ts index c2bc75d..6a5927c 100644 --- a/bizmatch-server/src/mail/mail.module.ts +++ b/bizmatch-server/src/mail/mail.module.ts @@ -13,33 +13,67 @@ import { MailController } from './mail.controller.js'; import { MailService } from './mail.service.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const user = process.env.amazon_user; -const password = process.env.amazon_password; +const user = process.env.AMAZON_USER; +const password = process.env.AMAZON_PASSWORD; +console.log('Amazon User:', process.env.AMAZON_USER); +console.log('Amazon Password:', process.env.AMAZON_PASSWORD); @Module({ imports: [ DrizzleModule, UserModule, GeoModule, - MailerModule.forRoot({ - transport: { - host: 'email-smtp.us-east-2.amazonaws.com', - secure: false, - port: 587, - auth: { - user: 'AKIAU6GDWVAQ2QNFLNWN', - pass: 'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7', + // ConfigModule.forFeature(mailConfig), + // MailerModule.forRoot({ + // transport: { + // host: 'email-smtp.us-east-2.amazonaws.com', + // secure: false, + // port: 587, + // auth: { + // user: user, //'AKIAU6GDWVAQ2QNFLNWN', + // pass: password, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7', + // }, + // }, + // defaults: { + // from: '"No Reply" ', + // }, + // template: { + // dir: join(__dirname, 'templates'), + // adapter: new HandlebarsAdapter({ + // eq: function (a, b) { + // return a === b; + // }, + // }), + // options: { + // strict: true, + // }, + // }, + // }), + MailerModule.forRootAsync({ + useFactory: () => ({ + transport: { + host: 'email-smtp.us-east-2.amazonaws.com', + secure: false, + port: 587, + auth: { + user: process.env.AMAZON_USER, //'AKIAU6GDWVAQ2QNFLNWN', + pass: process.env.AMAZON_PASSWORD, //'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7', + }, }, - }, - defaults: { - from: '"No Reply" ', - }, - template: { - dir: join(__dirname, 'templates'), - adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter() - options: { - strict: true, + defaults: { + from: '"No Reply" ', }, - }, + template: { + dir: join(__dirname, 'templates'), + adapter: new HandlebarsAdapter({ + eq: function (a, b) { + return a === b; + }, + }), + options: { + strict: true, + }, + }, + }), }), ], providers: [MailService, UserService, FileService, GeoService], diff --git a/bizmatch-server/src/mail/mail.service.ts b/bizmatch-server/src/mail/mail.service.ts index 03c1eb9..4d3337e 100644 --- a/bizmatch-server/src/mail/mail.service.ts +++ b/bizmatch-server/src/mail/mail.service.ts @@ -83,7 +83,7 @@ export class MailService { } async sendSubscriptionConfirmation(user: User): Promise { await this.mailerService.sendMail({ - to: 'support@bizmatch.net', + to: user.email, from: `"Bizmatch Support Team" `, subject: `Subscription Confirmation`, //template: './inquiry', // `.hbs` extension is appended automatically diff --git a/bizmatch-server/src/models/db.model.ts b/bizmatch-server/src/models/db.model.ts index 2c6e693..db7f987 100644 --- a/bizmatch-server/src/models/db.model.ts +++ b/bizmatch-server/src/models/db.model.ts @@ -17,18 +17,18 @@ export interface UserData { hasCompanyLogo?: boolean; licensedIn?: string[]; gender?: 'male' | 'female'; - customerType?: 'buyer' | 'broker' | 'professional'; + customerType?: 'buyer' | 'seller' | 'professional'; customerSubType?: 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser'; created?: Date; updated?: Date; } export type Gender = 'male' | 'female'; -export type CustomerType = 'buyer' | 'professional'; +export type CustomerType = 'buyer' | 'seller' | 'professional'; export type CustomerSubType = 'broker' | 'cpa' | 'attorney' | 'titleCompany' | 'surveyor' | 'appraiser'; export type ListingsCategory = 'commercialProperty' | 'business'; export const GenderEnum = z.enum(['male', 'female']); -export const CustomerTypeEnum = z.enum(['buyer', 'professional']); +export const CustomerTypeEnum = z.enum(['buyer', 'seller', 'professional']); export const SubscriptionTypeEnum = z.enum(['free', 'professional', 'broker']); export const CustomerSubTypeEnum = z.enum(['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']); export const ListingsCategoryEnum = z.enum(['commercialProperty', 'business']); diff --git a/bizmatch-server/src/payment/payment.service.ts b/bizmatch-server/src/payment/payment.service.ts index c401f10..86a8613 100644 --- a/bizmatch-server/src/payment/payment.service.ts +++ b/bizmatch-server/src/payment/payment.service.ts @@ -58,23 +58,19 @@ export class PaymentService { quantity: 1, }, ], - success_url: 'http://localhost:4200/success', - cancel_url: 'http://localhost:4200/pricing', + success_url: `${process.env.WEB_HOST}/success`, + cancel_url: `${process.env.WEB_HOST}/pricing`, // customer_email: checkout.email, customer: customerId, - // customer_details:{ - // name: checkout.name, // Hier wird der Name des Kunden übergeben - // }, shipping_address_collection: { allowed_countries: ['US'], }, - - client_reference_id: '1234', + client_reference_id: btoa(checkout.name), locale: 'en', subscription_data: { trial_end: Math.floor(new Date().setMonth(new Date().getMonth() + 3) / 1000), + metadata: { plan: product.name }, }, - metadata: { plan: product.name }, }); return session; } else { @@ -100,20 +96,11 @@ export class PaymentService { }); user.stripeCustomerId = session.customer as string; user.subscriptionId = session.subscription as string; - user.planActive = true; - //session.shipping_details -> - // "shipping_details": { - // "address": { - // "city": "Springfield", - // "country": "US", - // "line1": "West Maple Avenue South", - // "line2": null, - // "postal_code": "62704", - // "state": "IL" - // }, - // "name": "Johnathan Miller" - // } - user.subscriptionPlan = session.amount_total === 4900 ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker'; + user.customerType = 'professional'; + if (session.metadata['plan'] === 'Broker Plan') { + user.customerSubType = 'broker'; + } + user.subscriptionPlan = session.metadata['plan'] === 'Broker Plan' ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker'; this.userService.saveUser(user); this.mailService.sendSubscriptionConfirmation(user); } diff --git a/bizmatch-server/src/select-options/select-options.service.ts b/bizmatch-server/src/select-options/select-options.service.ts index c265c23..ae395e2 100644 --- a/bizmatch-server/src/select-options/select-options.service.ts +++ b/bizmatch-server/src/select-options/select-options.service.ts @@ -52,6 +52,7 @@ export class SelectOptionsService { ]; public customerTypes: Array = [ { name: 'Buyer', value: 'buyer' }, + { name: 'Commercial Property Seller', value: 'seller' }, { name: 'Professional', value: 'professional' }, ]; public customerSubTypes: Array = [ diff --git a/bizmatch/src/app/components/validated-select/validated-select.component.html b/bizmatch/src/app/components/validated-select/validated-select.component.html index 9431866..6eb9284 100644 --- a/bizmatch/src/app/components/validated-select/validated-select.component.html +++ b/bizmatch/src/app/components/validated-select/validated-select.component.html @@ -11,7 +11,15 @@ } -