From 74d5f92aba3d20f26087aa2fdbae7f01eb63687c Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Fri, 23 Aug 2024 19:54:55 +0200 Subject: [PATCH] =?UTF-8?q?=C3=9Cberarbeitung=20des=20Stripe=20Prozesses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bizmatch-server/src/drizzle/schema.ts | 3 +- .../templates/subscriptionConfirmation.hbs | 2 +- bizmatch-server/src/main.ts | 2 +- bizmatch-server/src/models/db.model.ts | 3 -- bizmatch-server/src/models/main.model.ts | 3 -- .../src/payment/payment.controller.ts | 5 +- .../src/payment/payment.service.ts | 49 ++++++++++++------- bizmatch-server/src/user/user.controller.ts | 30 ++++++++++-- bizmatch-server/src/user/user.service.ts | 21 +++----- .../app/interceptors/loading.interceptor.ts | 15 ++++-- .../src/app/pages/home/home.component.html | 2 +- .../app/pages/pricing/pricing.component.ts | 4 +- .../account/account.component.html | 14 ++++-- .../subscription/account/account.component.ts | 43 ++++++++++++++-- .../app/pages/success/success.component.html | 10 +++- .../app/pages/success/success.component.ts | 7 ++- bizmatch/src/app/services/user.service.ts | 13 +++-- bizmatch/src/app/utils/utils.ts | 6 +++ 18 files changed, 164 insertions(+), 68 deletions(-) diff --git a/bizmatch-server/src/drizzle/schema.ts b/bizmatch-server/src/drizzle/schema.ts index 8fb9115..b90185a 100644 --- a/bizmatch-server/src/drizzle/schema.ts +++ b/bizmatch-server/src/drizzle/schema.ts @@ -31,9 +31,8 @@ export const users = pgTable('users', { updated: timestamp('updated'), latitude: doublePrecision('latitude'), longitude: doublePrecision('longitude'), - stripeCustomerId: text('stripeCustomerId'), subscriptionId: text('subscriptionId'), - subscriptionPlan: subscriptionTypeEnum('subscriptionType'), + subscriptionPlan: subscriptionTypeEnum('subscriptionPlan'), // embedding: vector('embedding', { dimensions: 1536 }), }); diff --git a/bizmatch-server/src/mail/templates/subscriptionConfirmation.hbs b/bizmatch-server/src/mail/templates/subscriptionConfirmation.hbs index b0d7ed5..dde877e 100644 --- a/bizmatch-server/src/mail/templates/subscriptionConfirmation.hbs +++ b/bizmatch-server/src/mail/templates/subscriptionConfirmation.hbs @@ -60,7 +60,7 @@

Your subscription details are as follows:

-

{{#if (eq subscriptionPlan "professional")}}Professional (CPA, Attorney, Title Company) Plan{{else if (eq subscriptionPlan "broker")}}Business Broker Plan{{/if}}

+

{{#if (eq subscriptionPlan "professional")}}Professional Plan (CPA, Attorney, Title Company, Surveyor, Appraiser){{else if (eq subscriptionPlan "broker")}}Business Broker Plan{{/if}}

If you have any questions or need further assistance, please feel free to contact our support team at any time.

diff --git a/bizmatch-server/src/main.ts b/bizmatch-server/src/main.ts index d3f9216..0eff9f2 100644 --- a/bizmatch-server/src/main.ts +++ b/bizmatch-server/src/main.ts @@ -12,7 +12,7 @@ async function bootstrap() { origin: '*', //origin: 'http://localhost:4200', // Die URL Ihrer Angular-App methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', - allowedHeaders: 'Content-Type, Accept, Authorization', + allowedHeaders: 'Content-Type, Accept, Authorization, x-hide-loading', }); //origin: 'http://localhost:4200', await app.listen(3000); diff --git a/bizmatch-server/src/models/db.model.ts b/bizmatch-server/src/models/db.model.ts index db7f987..ea1be25 100644 --- a/bizmatch-server/src/models/db.model.ts +++ b/bizmatch-server/src/models/db.model.ts @@ -157,10 +157,7 @@ export const UserSchema = z customerSubType: CustomerSubTypeEnum.optional().nullable(), created: z.date().optional().nullable(), updated: z.date().optional().nullable(), - stripeCustomerId: z.string().optional().nullable(), subscriptionId: z.string().optional().nullable(), - planActive: z.boolean().optional().nullable(), - planExpires: z.date().optional().nullable(), subscriptionPlan: SubscriptionTypeEnum.optional().nullable(), }) .superRefine((data, ctx) => { diff --git a/bizmatch-server/src/models/main.model.ts b/bizmatch-server/src/models/main.model.ts index 1e52697..363f3ae 100644 --- a/bizmatch-server/src/models/main.model.ts +++ b/bizmatch-server/src/models/main.model.ts @@ -322,10 +322,7 @@ export function createDefaultUser(email: string, firstname: string, lastname: st customerSubType: null, created: new Date(), updated: new Date(), - stripeCustomerId: null, subscriptionId: null, - planActive: false, - planExpires: null, subscriptionPlan: subscriptionPlan, }; } diff --git a/bizmatch-server/src/payment/payment.controller.ts b/bizmatch-server/src/payment/payment.controller.ts index 254700c..a59a6ea 100644 --- a/bizmatch-server/src/payment/payment.controller.ts +++ b/bizmatch-server/src/payment/payment.controller.ts @@ -21,7 +21,10 @@ export class PaymentController { const signature = req.headers['stripe-signature'] as string; try { - const event = await this.paymentService.constructEvent(req.body, signature); + // Konvertieren Sie den req.body Buffer in einen lesbaren String + const payload = req.body instanceof Buffer ? req.body.toString('utf8') : req.body; + const event = await this.paymentService.constructEvent(payload, signature); + // const event = await this.paymentService.constructEvent(req.body, signature); if (event.type === 'checkout.session.completed') { await this.paymentService.handleCheckoutSessionCompleted(event.data.object as Stripe.Checkout.Session); diff --git a/bizmatch-server/src/payment/payment.service.ts b/bizmatch-server/src/payment/payment.service.ts index 86a8613..f2f7ea7 100644 --- a/bizmatch-server/src/payment/payment.service.ts +++ b/bizmatch-server/src/payment/payment.service.ts @@ -43,6 +43,14 @@ export class PaymentService { const newCustomer = await this.stripe.customers.create({ email: checkout.email, name: checkout.name, + shipping: { + name: checkout.name, + address: { + city: '', + state: '', + country: 'US', + }, + }, }); customerId = newCustomer.id; } @@ -60,7 +68,6 @@ export class PaymentService { ], success_url: `${process.env.WEB_HOST}/success`, cancel_url: `${process.env.WEB_HOST}/pricing`, - // customer_email: checkout.email, customer: customerId, shipping_address_collection: { allowed_countries: ['US'], @@ -84,25 +91,29 @@ export class PaymentService { return this.stripe.webhooks.constructEvent(body, signature, process.env.STRIPE_WEBHOOK_SECRET!); } async handleCheckoutSessionCompleted(session: Stripe.Checkout.Session): Promise { - this.logger.info(JSON.stringify(session)); - const keycloakUsers = await this.authService.getUsers(); - const keycloakUser = keycloakUsers.find(u => u.email === session.customer_details.email); - const user = await this.userService.getUserByMail(session.customer_details.email, { - userId: keycloakUser.id, - firstname: keycloakUser.firstName, - lastname: keycloakUser.lastName, - username: keycloakUser.email, - roles: [], - }); - user.stripeCustomerId = session.customer as string; - user.subscriptionId = session.subscription as string; - user.customerType = 'professional'; - if (session.metadata['plan'] === 'Broker Plan') { - user.customerSubType = 'broker'; + try { + const keycloakUsers = await this.authService.getUsers(); + const keycloakUser = keycloakUsers.find(u => u.email === session.customer_details.email); + const user = await this.userService.getUserByMail(session.customer_details.email, { + userId: keycloakUser.id, + firstname: keycloakUser.firstName, + lastname: keycloakUser.lastName, + username: keycloakUser.email, + roles: [], + }); + this.logger.info(JSON.stringify(session)); + user.subscriptionId = session.subscription as string; + const subscription = await this.stripe.subscriptions.retrieve(user.subscriptionId); + user.customerType = 'professional'; + if (subscription.metadata['plan'] === 'Broker Plan') { + user.customerSubType = 'broker'; + } + user.subscriptionPlan = subscription.metadata['plan'] === 'Broker Plan' ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker'; + await this.userService.saveUser(user, false); + await this.mailService.sendSubscriptionConfirmation(user); + } catch (error) { + this.logger.error(error); } - user.subscriptionPlan = session.metadata['plan'] === 'Broker Plan' ? 'broker' : 'professional'; //session.metadata['subscriptionPlan'] as 'free' | 'professional' | 'broker'; - this.userService.saveUser(user); - this.mailService.sendSubscriptionConfirmation(user); } async getSubscription(email: string): Promise { const existingCustomers = await this.stripe.customers.list({ diff --git a/bizmatch-server/src/user/user.controller.ts b/bizmatch-server/src/user/user.controller.ts index 98bb50e..f8ce70e 100644 --- a/bizmatch-server/src/user/user.controller.ts +++ b/bizmatch-server/src/user/user.controller.ts @@ -1,6 +1,7 @@ -import { Body, Controller, Get, Inject, Param, Post, Query, Request, UseGuards } from '@nestjs/common'; +import { BadRequestException, Body, Controller, Get, Inject, Param, Post, Query, Request, UseGuards } from '@nestjs/common'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { Logger } from 'winston'; +import { ZodError } from 'zod'; import { FileService } from '../file/file.service.js'; import { OptionalJwtAuthGuard } from '../jwt-auth/optional-jwt-auth.guard.js'; import { User } from '../models/db.model'; @@ -31,13 +32,32 @@ export class UserController { return user; } @Post() - save(@Body() user: any): Promise { + async save(@Body() user: any): Promise { this.logger.info(`Saving user: ${JSON.stringify(user)}`); - const savedUser = this.userService.saveUser(user); - this.logger.info(`User persisted: ${JSON.stringify(savedUser)}`); + try { + const savedUser = await this.userService.saveUser(user); + this.logger.info(`User persisted: ${JSON.stringify(savedUser)}`); + return savedUser; + } catch (error) { + if (error instanceof ZodError) { + const filteredErrors = error.errors + .map(item => ({ + ...item, + field: item.path[0], + })) + .filter((item, index, self) => index === self.findIndex(t => t.path[0] === item.path[0])); + throw new BadRequestException(filteredErrors); + } + throw error; // Andere Fehler einfach durchreichen + } + } + @Post('guaranteed') + async saveGuaranteed(@Body() user: any): Promise { + this.logger.info(`Saving user guaranteed: ${JSON.stringify(user)}`); + const savedUser = await this.userService.saveUser(user, false); + this.logger.info(`User persisted guaranteed: ${JSON.stringify(savedUser)}`); return savedUser; } - @Post('search') find(@Body() criteria: UserListingCriteria): any { this.logger.info(`Searching for users with criteria: ${JSON.stringify(criteria)}`); diff --git a/bizmatch-server/src/user/user.service.ts b/bizmatch-server/src/user/user.service.ts index 24fae5a..9a70253 100644 --- a/bizmatch-server/src/user/user.service.ts +++ b/bizmatch-server/src/user/user.service.ts @@ -1,9 +1,8 @@ -import { BadRequestException, Inject, Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { and, count, eq, ilike, inArray, or, SQL, sql } from 'drizzle-orm'; import { NodePgDatabase } from 'drizzle-orm/node-postgres/driver.js'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { Logger } from 'winston'; -import { ZodError } from 'zod'; import * as schema from '../drizzle/schema.js'; import { customerSubTypeEnum, PG_CONNECTION } from '../drizzle/schema.js'; import { FileService } from '../file/file.service.js'; @@ -97,7 +96,7 @@ export class UserService { .where(sql`email = ${email}`)) as User[]; if (users.length === 0) { const user: User = { id: undefined, customerType: 'buyer', ...createDefaultUser(email, jwtuser.firstname, jwtuser.lastname, null) }; - const u = await this.saveUser(user); + const u = await this.saveUser(user, false); return convertDrizzleUserToUser(u); } else { const user = users[0]; @@ -117,7 +116,7 @@ export class UserService { user.hasProfile = this.fileService.hasProfile(emailToDirName(user.email)); return convertDrizzleUserToUser(user); } - async saveUser(user: User): Promise { + async saveUser(user: User, processValidation = true): Promise { try { user.updated = new Date(); if (user.id) { @@ -125,7 +124,10 @@ export class UserService { } else { user.created = new Date(); } - const validatedUser = UserSchema.parse(user); + let validatedUser = user; + if (processValidation) { + validatedUser = UserSchema.parse(user); + } const drizzleUser = convertUserToDrizzleUser(validatedUser); if (user.id) { const [updateUser] = await this.conn.update(schema.users).set(drizzleUser).where(eq(schema.users.id, user.id)).returning(); @@ -135,15 +137,6 @@ export class UserService { return convertDrizzleUserToUser(newUser) as User; } } catch (error) { - if (error instanceof ZodError) { - const filteredErrors = error.errors - .map(item => ({ - ...item, - field: item.path[0], - })) - .filter((item, index, self) => index === self.findIndex(t => t.path[0] === item.path[0])); - throw new BadRequestException(filteredErrors); - } throw error; } } diff --git a/bizmatch/src/app/interceptors/loading.interceptor.ts b/bizmatch/src/app/interceptors/loading.interceptor.ts index bcb7f35..6fe6dbf 100644 --- a/bizmatch/src/app/interceptors/loading.interceptor.ts +++ b/bizmatch/src/app/interceptors/loading.interceptor.ts @@ -7,15 +7,22 @@ import { LoadingService } from '../services/loading.service'; @Injectable() export class LoadingInterceptor implements HttpInterceptor { constructor(private loadingService: LoadingService) {} + intercept(request: HttpRequest, next: HttpHandler): Observable> { + const hideLoading = request.headers.get('X-Hide-Loading') === 'true'; const requestId = `HTTP-${v4()}`; - this.loadingService.startLoading(requestId, request.url); + + if (!hideLoading) { + this.loadingService.startLoading(requestId, request.url); + } return next.handle(request).pipe( tap({ - finalize: () => this.loadingService.stopLoading(requestId), // Stoppt den Ladevorgang, wenn die Anfrage abgeschlossen ist - // Beachte, dass 'error' und 'complete' hier entfernt wurden, da 'finalize' in allen Fällen aufgerufen wird, - // egal ob die Anfrage erfolgreich war, einen Fehler geworfen hat oder abgeschlossen wurde. + finalize: () => { + if (!hideLoading) { + this.loadingService.stopLoading(requestId); + } + }, }), ); } diff --git a/bizmatch/src/app/pages/home/home.component.html b/bizmatch/src/app/pages/home/home.component.html index 36e3dec..a6be726 100644 --- a/bizmatch/src/app/pages/home/home.component.html +++ b/bizmatch/src/app/pages/home/home.component.html @@ -4,7 +4,7 @@ @if(user){ Account } @else { - Pricing + Log In Register } diff --git a/bizmatch/src/app/pages/pricing/pricing.component.ts b/bizmatch/src/app/pages/pricing/pricing.component.ts index 3d8d5ae..5a2c276 100644 --- a/bizmatch/src/app/pages/pricing/pricing.component.ts +++ b/bizmatch/src/app/pages/pricing/pricing.component.ts @@ -43,7 +43,9 @@ export class PricingComponent { } } else { if (priceId) { - this.keycloakService.register({ redirectUri: `${window.location.origin}/pricing/${btoa(priceId)}` }); + this.keycloakService.register({ + redirectUri: `${window.location.origin}/pricing/${btoa(priceId)}`, + }); } else { this.keycloakService.register({ redirectUri: `${window.location.origin}/account` }); } diff --git a/bizmatch/src/app/pages/subscription/account/account.component.html b/bizmatch/src/app/pages/subscription/account/account.component.html index 73b99fe..21fa694 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.html +++ b/bizmatch/src/app/pages/subscription/account/account.component.html @@ -243,9 +243,7 @@ -
- -
+

Membership Level

@@ -279,6 +277,16 @@ }
+ @if(user.subscriptionPlan==='free'){ +
+ +
+ } } diff --git a/bizmatch/src/app/pages/subscription/account/account.component.ts b/bizmatch/src/app/pages/subscription/account/account.component.ts index d70f23f..8c2aad0 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.ts +++ b/bizmatch/src/app/pages/subscription/account/account.component.ts @@ -1,6 +1,6 @@ import { DatePipe, TitleCasePipe } from '@angular/common'; import { ChangeDetectorRef, Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { NgSelectModule } from '@ng-select/ng-select'; import { initFlowbite } from 'flowbite'; @@ -32,7 +32,7 @@ import { SharedService } from '../../../services/shared.service'; import { SubscriptionsService } from '../../../services/subscriptions.service'; import { UserService } from '../../../services/user.service'; import { SharedModule } from '../../../shared/shared/shared.module'; -import { map2User } from '../../../utils/utils'; +import { checkAndUpdate, map2User } from '../../../utils/utils'; import { TOOLBAR_OPTIONS } from '../../utils/defaults'; @Component({ selector: 'app-account', @@ -93,6 +93,7 @@ export class AccountComponent { private validationMessagesService: ValidationMessagesService, private subscriptionService: SubscriptionsService, private datePipe: DatePipe, + private router: Router, ) {} async ngOnInit() { setTimeout(() => { @@ -108,9 +109,11 @@ export class AccountComponent { } this.subscriptions = await lastValueFrom(this.subscriptionService.getAllSubscriptions(this.user.email)); - if (this.subscriptions.length === 0) { - this.subscriptions = [{ ended_at: null, start_date: Math.floor(new Date(this.user.created).getTime() / 1000), status: null, metadata: { plan: 'Free Plan' } }]; - } + await this.synchronizeSubscriptions(this.subscriptions); + // if (this.subscriptions.length === 0) { + // this.subscriptions = [{ ended_at: null, start_date: Math.floor(new Date(this.user.created).getTime() / 1000), status: null, metadata: { plan: 'Free Plan' } }]; + // } + this.profileUrl = this.user.hasProfile ? `${this.env.imageBaseUrl}/pictures/profile/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`; this.companyLogoUrl = this.user.hasCompanyLogo ? `${this.env.imageBaseUrl}/pictures/logo/${emailToDirName(this.user.email)}.avif?_ts=${new Date().getTime()}` : `/assets/images/placeholder.png`; @@ -128,6 +131,36 @@ export class AccountComponent { label: this.titleCasePipe.transform(type.name), })); } + async synchronizeSubscriptions(subscriptions: StripeSubscription[]) { + let changed = false; + if (this.subscriptions.length === 0) { + if (!this.user.subscriptionPlan) { + this.router.navigate(['pricing']); + } else { + this.subscriptions = [{ ended_at: null, start_date: Math.floor(new Date(this.user.created).getTime() / 1000), status: null, metadata: { plan: 'Free Plan' } }]; + changed = checkAndUpdate(changed, this.user.customerType !== 'buyer' && this.user.customerType !== 'seller', () => (this.user.customerType = 'buyer')); + changed = checkAndUpdate(changed, !!this.user.customerSubType, () => (this.user.customerSubType = null)); + changed = checkAndUpdate(changed, this.user.subscriptionPlan !== 'free', () => (this.user.subscriptionPlan = 'free')); + changed = checkAndUpdate(changed, !!this.user.subscriptionId, () => (this.user.subscriptionId = null)); + } + } else { + const subscription = subscriptions[0]; + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Broker Plan' && this.user.customerType !== 'professional', () => (this.user.customerType = 'professional')); + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Broker Plan' && this.user.customerSubType !== 'broker', () => (this.user.customerSubType = 'broker')); + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Broker Plan' && this.user.subscriptionPlan !== 'broker', () => (this.user.subscriptionPlan = 'broker')); + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Broker Plan' && !this.user.subscriptionId, () => (this.user.subscriptionId = subscription.id)); + + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Professional Plan' && this.user.customerType !== 'professional', () => (this.user.customerType = 'professional')); + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Professional Plan' && this.user.subscriptionPlan !== 'professional', () => (this.user.subscriptionPlan = 'professional')); + changed = checkAndUpdate(changed, subscription.metadata['plan'] === 'Professional Plan' && this.user.subscriptionId !== 'professional', () => (this.user.subscriptionId = subscription.id)); + } + if (changed) { + await this.userService.saveGuaranteed(this.user); + this.cdref.detectChanges(); + this.cdref.markForCheck(); + } + } + ngOnDestroy() { this.validationMessagesService.clearMessages(); // Löschen Sie alle bestehenden Validierungsnachrichten } diff --git a/bizmatch/src/app/pages/success/success.component.html b/bizmatch/src/app/pages/success/success.component.html index 76e99c2..0163f12 100644 --- a/bizmatch/src/app/pages/success/success.component.html +++ b/bizmatch/src/app/pages/success/success.component.html @@ -1,7 +1,15 @@
- @if(user && (user.subscriptionPlan==='professional' || user.subscriptionPlan==='broker')){ + + @if(maxAttemptsReached) { +

We're sorry!

+

+ We regret to inform you that we have not yet received any response from our payment service provider regarding the status of your subscription. Please log in to the + website and check your subscription status under the Account menu. If you have any questions, please contact us at + support@bizmatch.net. +

+ } @else if(user && (user.subscriptionPlan==='professional' || user.subscriptionPlan==='broker')) { diff --git a/bizmatch/src/app/pages/success/success.component.ts b/bizmatch/src/app/pages/success/success.component.ts index e538537..2646f3c 100644 --- a/bizmatch/src/app/pages/success/success.component.ts +++ b/bizmatch/src/app/pages/success/success.component.ts @@ -16,7 +16,10 @@ import { map2User } from '../../utils/utils'; }) export class SuccessComponent { user: User; + maxAttemptsReached: boolean = false; // Neue Variable hinzufügen + constructor(private keycloakService: KeycloakService, private userService: UserService, private logService: LogService, private router: Router) {} + async ngOnInit() { let email = null; try { @@ -29,6 +32,7 @@ export class SuccessComponent { this.checkSubscriptionPlan(email, e.message); } } + async checkSubscriptionPlan(email: string, error?: string) { if (!email) { this.logService.log({ severity: 'error', text: `Unauthorized Access to Success Page ${error}` }); @@ -44,12 +48,13 @@ export class SuccessComponent { if (attempts >= maxAttempts) { clearInterval(intervalId); console.error('Max attempts reached'); + this.maxAttemptsReached = true; // Setze die Variable auf true, wenn die max. Versuche erreicht wurden return; } attempts++; - this.user = await this.userService.getByMail(email); + this.user = await this.userService.getByMail(email, true); if (this.user && this.user.subscriptionPlan) { clearInterval(intervalId); diff --git a/bizmatch/src/app/services/user.service.ts b/bizmatch/src/app/services/user.service.ts index 1bc4cc0..3005f07 100644 --- a/bizmatch/src/app/services/user.service.ts +++ b/bizmatch/src/app/services/user.service.ts @@ -1,4 +1,4 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { lastValueFrom, Observable } from 'rxjs'; import urlcat from 'urlcat'; @@ -20,12 +20,19 @@ export class UserService { async save(user: User): Promise { return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/user`, user)); } + async saveGuaranteed(user: User): Promise { + return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/user/guaranteed`, user)); + } async getById(id: string): Promise { return await lastValueFrom(this.http.get(`${this.apiBaseUrl}/bizmatch/user/${id}`)); } - async getByMail(mail: string): Promise { + async getByMail(mail: string, hideLoading: boolean = true): Promise { const url = urlcat(`${this.apiBaseUrl}/bizmatch/user`, { mail }); - return await lastValueFrom(this.http.get(url)); + let headers = new HttpHeaders(); + if (hideLoading) { + headers = headers.set('X-Hide-Loading', 'true'); + } + return await lastValueFrom(this.http.get(url, { headers })); } async search(criteria?: UserListingCriteria): Promise { return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/user/search`, criteria)); diff --git a/bizmatch/src/app/utils/utils.ts b/bizmatch/src/app/utils/utils.ts index fe9b031..638fede 100644 --- a/bizmatch/src/app/utils/utils.ts +++ b/bizmatch/src/app/utils/utils.ts @@ -287,6 +287,12 @@ export function assignProperties(target, source) { } return target; } +export function checkAndUpdate(changed: boolean, condition: boolean, assignment: () => any): boolean { + if (condition) { + assignment(); + } + return changed || condition; +} // ----------------------------- // Criteria Proxy // -----------------------------