BugFixing
This commit is contained in:
parent
097a6cb360
commit
cfddabbfe0
|
|
@ -103,8 +103,8 @@ export class BusinessListingService {
|
||||||
whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`)));
|
whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!user?.roles?.includes('ADMIN')) {
|
if (user?.role !== 'admin') {
|
||||||
whereConditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true)));
|
whereConditions.push(or(eq(businesses.email, user?.email), ne(businesses.draft, true)));
|
||||||
}
|
}
|
||||||
whereConditions.push(and(eq(schema.users.customerType, 'professional'), eq(schema.users.customerSubType, 'broker')));
|
whereConditions.push(and(eq(schema.users.customerType, 'professional'), eq(schema.users.customerSubType, 'broker')));
|
||||||
return whereConditions;
|
return whereConditions;
|
||||||
|
|
@ -186,8 +186,8 @@ export class BusinessListingService {
|
||||||
|
|
||||||
async findBusinessesById(id: string, user: JwtUser): Promise<BusinessListing> {
|
async findBusinessesById(id: string, user: JwtUser): Promise<BusinessListing> {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
if (!user?.roles?.includes('ADMIN')) {
|
if (user?.role !== 'admin') {
|
||||||
conditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true)));
|
conditions.push(or(eq(businesses.email, user?.email), ne(businesses.draft, true)));
|
||||||
}
|
}
|
||||||
conditions.push(sql`${businesses.id} = ${id}`);
|
conditions.push(sql`${businesses.id} = ${id}`);
|
||||||
const result = await this.conn
|
const result = await this.conn
|
||||||
|
|
@ -204,7 +204,7 @@ export class BusinessListingService {
|
||||||
async findBusinessesByEmail(email: string, user: JwtUser): Promise<BusinessListing[]> {
|
async findBusinessesByEmail(email: string, user: JwtUser): Promise<BusinessListing[]> {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
conditions.push(eq(businesses.email, email));
|
conditions.push(eq(businesses.email, email));
|
||||||
if (email !== user?.username && (!user?.roles?.includes('ADMIN'))) {
|
if (email !== user?.email && user?.role !== 'admin') {
|
||||||
conditions.push(ne(businesses.draft, true));
|
conditions.push(ne(businesses.draft, true));
|
||||||
}
|
}
|
||||||
const listings = (await this.conn
|
const listings = (await this.conn
|
||||||
|
|
@ -219,7 +219,7 @@ export class BusinessListingService {
|
||||||
const userFavorites = await this.conn
|
const userFavorites = await this.conn
|
||||||
.select()
|
.select()
|
||||||
.from(businesses)
|
.from(businesses)
|
||||||
.where(arrayContains(businesses.favoritesForUser, [user.username]));
|
.where(arrayContains(businesses.favoritesForUser, [user.email]));
|
||||||
return userFavorites;
|
return userFavorites;
|
||||||
}
|
}
|
||||||
// #### CREATE ########################################
|
// #### CREATE ########################################
|
||||||
|
|
@ -276,7 +276,7 @@ export class BusinessListingService {
|
||||||
await this.conn
|
await this.conn
|
||||||
.update(businesses)
|
.update(businesses)
|
||||||
.set({
|
.set({
|
||||||
favoritesForUser: sql`array_remove(${businesses.favoritesForUser}, ${user.username})`,
|
favoritesForUser: sql`array_remove(${businesses.favoritesForUser}, ${user.email})`,
|
||||||
})
|
})
|
||||||
.where(sql`${businesses.id} = ${id}`);
|
.where(sql`${businesses.id} = ${id}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ export class CommercialPropertyService {
|
||||||
if (criteria.title) {
|
if (criteria.title) {
|
||||||
whereConditions.push(or(ilike(schema.commercials.title, `%${criteria.title}%`), ilike(schema.commercials.description, `%${criteria.title}%`)));
|
whereConditions.push(or(ilike(schema.commercials.title, `%${criteria.title}%`), ilike(schema.commercials.description, `%${criteria.title}%`)));
|
||||||
}
|
}
|
||||||
if (!user?.roles?.includes('ADMIN')) {
|
if (user?.role !== 'admin') {
|
||||||
whereConditions.push(or(eq(commercials.email, user?.username), ne(commercials.draft, true)));
|
whereConditions.push(or(eq(commercials.email, user?.email), ne(commercials.draft, true)));
|
||||||
}
|
}
|
||||||
// whereConditions.push(and(eq(schema.users.customerType, 'professional')));
|
// whereConditions.push(and(eq(schema.users.customerType, 'professional')));
|
||||||
return whereConditions;
|
return whereConditions;
|
||||||
|
|
@ -113,8 +113,8 @@ export class CommercialPropertyService {
|
||||||
// #### Find by ID ########################################
|
// #### Find by ID ########################################
|
||||||
async findCommercialPropertiesById(id: string, user: JwtUser): Promise<CommercialPropertyListing> {
|
async findCommercialPropertiesById(id: string, user: JwtUser): Promise<CommercialPropertyListing> {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
if (!user?.roles?.includes('ADMIN')) {
|
if (user?.role !== 'admin') {
|
||||||
conditions.push(or(eq(commercials.email, user?.username), ne(commercials.draft, true)));
|
conditions.push(or(eq(commercials.email, user?.email), ne(commercials.draft, true)));
|
||||||
}
|
}
|
||||||
conditions.push(sql`${commercials.id} = ${id}`);
|
conditions.push(sql`${commercials.id} = ${id}`);
|
||||||
const result = await this.conn
|
const result = await this.conn
|
||||||
|
|
@ -132,7 +132,7 @@ export class CommercialPropertyService {
|
||||||
async findCommercialPropertiesByEmail(email: string, user: JwtUser): Promise<CommercialPropertyListing[]> {
|
async findCommercialPropertiesByEmail(email: string, user: JwtUser): Promise<CommercialPropertyListing[]> {
|
||||||
const conditions = [];
|
const conditions = [];
|
||||||
conditions.push(eq(commercials.email, email));
|
conditions.push(eq(commercials.email, email));
|
||||||
if (email !== user?.username && (!user?.roles?.includes('ADMIN'))) {
|
if (email !== user?.email && user?.role !== 'admin') {
|
||||||
conditions.push(ne(commercials.draft, true));
|
conditions.push(ne(commercials.draft, true));
|
||||||
}
|
}
|
||||||
const listings = (await this.conn
|
const listings = (await this.conn
|
||||||
|
|
@ -146,7 +146,7 @@ export class CommercialPropertyService {
|
||||||
const userFavorites = await this.conn
|
const userFavorites = await this.conn
|
||||||
.select()
|
.select()
|
||||||
.from(commercials)
|
.from(commercials)
|
||||||
.where(arrayContains(commercials.favoritesForUser, [user.username]));
|
.where(arrayContains(commercials.favoritesForUser, [user.email]));
|
||||||
return userFavorites;
|
return userFavorites;
|
||||||
}
|
}
|
||||||
// #### Find by imagePath ########################################
|
// #### Find by imagePath ########################################
|
||||||
|
|
@ -233,7 +233,7 @@ export class CommercialPropertyService {
|
||||||
await this.conn
|
await this.conn
|
||||||
.update(commercials)
|
.update(commercials)
|
||||||
.set({
|
.set({
|
||||||
favoritesForUser: sql`array_remove(${commercials.favoritesForUser}, ${user.username})`,
|
favoritesForUser: sql`array_remove(${commercials.favoritesForUser}, ${user.email})`,
|
||||||
})
|
})
|
||||||
.where(sql`${commercials.id} = ${id}`);
|
.where(sql`${commercials.id} = ${id}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -258,35 +258,59 @@ export type AreasServed = z.infer<typeof AreasServedSchema>;
|
||||||
export type LicensedIn = z.infer<typeof LicensedInSchema>;
|
export type LicensedIn = z.infer<typeof LicensedInSchema>;
|
||||||
export type User = z.infer<typeof UserSchema>;
|
export type User = z.infer<typeof UserSchema>;
|
||||||
|
|
||||||
export const BusinessListingSchema = z.object({
|
export const BusinessListingSchema = z
|
||||||
id: z.string().uuid().optional().nullable(),
|
.object({
|
||||||
email: z.string().email(),
|
id: z.string().uuid().optional().nullable(),
|
||||||
type: z.string().refine(val => TypeEnum.safeParse(val).success, {
|
email: z.string().email(),
|
||||||
message: 'Invalid type. Must be one of: ' + TypeEnum.options.join(', '),
|
type: z.string().refine(val => TypeEnum.safeParse(val).success, {
|
||||||
}),
|
message: 'Invalid type. Must be one of: ' + TypeEnum.options.join(', '),
|
||||||
title: z.string().min(10),
|
}),
|
||||||
description: z.string().min(10),
|
title: z.string().min(10),
|
||||||
location: GeoSchema,
|
description: z.string().min(10),
|
||||||
price: z.number().positive().max(1000000000),
|
location: GeoSchema,
|
||||||
favoritesForUser: z.array(z.string()),
|
price: z.number().positive(),
|
||||||
draft: z.boolean(),
|
favoritesForUser: z.array(z.string()),
|
||||||
listingsCategory: ListingsCategoryEnum,
|
draft: z.boolean(),
|
||||||
realEstateIncluded: z.boolean().optional().nullable(),
|
listingsCategory: ListingsCategoryEnum,
|
||||||
leasedLocation: z.boolean().optional().nullable(),
|
realEstateIncluded: z.boolean().optional().nullable(),
|
||||||
franchiseResale: z.boolean().optional().nullable(),
|
leasedLocation: z.boolean().optional().nullable(),
|
||||||
salesRevenue: z.number().positive().max(100000000),
|
franchiseResale: z.boolean().optional().nullable(),
|
||||||
cashFlow: z.number().positive().max(100000000),
|
salesRevenue: z.number().positive().nullable(),
|
||||||
supportAndTraining: z.string().min(5),
|
cashFlow: z.number().positive().max(100000000),
|
||||||
employees: z.number().int().positive().max(100000).optional().nullable(),
|
supportAndTraining: z.string().min(5),
|
||||||
established: z.number().int().min(1800).max(2030).optional().nullable(),
|
employees: z.number().int().positive().max(100000).optional().nullable(),
|
||||||
internalListingNumber: z.number().int().positive().optional().nullable(),
|
established: z.number().int().min(1800).max(2030).optional().nullable(),
|
||||||
reasonForSale: z.string().min(5).optional().nullable(),
|
internalListingNumber: z.number().int().positive().optional().nullable(),
|
||||||
brokerLicencing: z.string().optional().nullable(),
|
reasonForSale: z.string().min(5).optional().nullable(),
|
||||||
internals: z.string().min(5).optional().nullable(),
|
brokerLicencing: z.string().optional().nullable(),
|
||||||
imageName: z.string().optional().nullable(),
|
internals: z.string().min(5).optional().nullable(),
|
||||||
created: z.date(),
|
imageName: z.string().optional().nullable(),
|
||||||
updated: z.date(),
|
created: z.date(),
|
||||||
});
|
updated: z.date(),
|
||||||
|
})
|
||||||
|
.superRefine((data, ctx) => {
|
||||||
|
if (data.price && data.price > 1000000000) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'Price must less than or equal $1,000,000,000',
|
||||||
|
path: ['price'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (data.salesRevenue && data.salesRevenue > 100000000) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'SalesRevenue must less than or equal $100,000,000',
|
||||||
|
path: ['salesRevenue'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (data.cashFlow && data.cashFlow > 100000000) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'CashFlow must less than or equal $100,000,000',
|
||||||
|
path: ['cashFlow'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
export type BusinessListing = z.infer<typeof BusinessListingSchema>;
|
export type BusinessListing = z.infer<typeof BusinessListingSchema>;
|
||||||
|
|
||||||
export const CommercialPropertyListingSchema = z
|
export const CommercialPropertyListingSchema = z
|
||||||
|
|
@ -300,7 +324,7 @@ export const CommercialPropertyListingSchema = z
|
||||||
title: z.string().min(10),
|
title: z.string().min(10),
|
||||||
description: z.string().min(10),
|
description: z.string().min(10),
|
||||||
location: GeoSchema,
|
location: GeoSchema,
|
||||||
price: z.number().positive().max(1000000000),
|
price: z.number().positive(),
|
||||||
favoritesForUser: z.array(z.string()),
|
favoritesForUser: z.array(z.string()),
|
||||||
listingsCategory: ListingsCategoryEnum,
|
listingsCategory: ListingsCategoryEnum,
|
||||||
draft: z.boolean(),
|
draft: z.boolean(),
|
||||||
|
|
@ -309,7 +333,15 @@ export const CommercialPropertyListingSchema = z
|
||||||
created: z.date(),
|
created: z.date(),
|
||||||
updated: z.date(),
|
updated: z.date(),
|
||||||
})
|
})
|
||||||
.strict();
|
.superRefine((data, ctx) => {
|
||||||
|
if (data.price && data.price > 1000000000) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'Price must less than or equal $1,000,000,000',
|
||||||
|
path: ['price'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export type CommercialPropertyListing = z.infer<typeof CommercialPropertyListingSchema>;
|
export type CommercialPropertyListing = z.infer<typeof CommercialPropertyListingSchema>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,11 +123,9 @@ export interface KeycloakUser {
|
||||||
attributes?: Attributes;
|
attributes?: Attributes;
|
||||||
}
|
}
|
||||||
export interface JwtUser {
|
export interface JwtUser {
|
||||||
userId: string;
|
email: string;
|
||||||
username: string;
|
role: string;
|
||||||
firstname: string;
|
uid: string;
|
||||||
lastname: string;
|
|
||||||
roles: string[];
|
|
||||||
}
|
}
|
||||||
interface Attributes {
|
interface Attributes {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,10 @@ export class UserService {
|
||||||
if (criteria.state) {
|
if (criteria.state) {
|
||||||
whereConditions.push(sql`EXISTS (SELECT 1 FROM jsonb_array_elements(${schema.users.areasServed}) AS area WHERE area->>'state' = ${criteria.state})`);
|
whereConditions.push(sql`EXISTS (SELECT 1 FROM jsonb_array_elements(${schema.users.areasServed}) AS area WHERE area->>'state' = ${criteria.state})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//never show user which denied
|
//never show user which denied
|
||||||
whereConditions.push(eq(schema.users.showInDirectory, true))
|
whereConditions.push(eq(schema.users.showInDirectory, true));
|
||||||
|
|
||||||
return whereConditions;
|
return whereConditions;
|
||||||
}
|
}
|
||||||
async searchUserListings(criteria: UserListingCriteria): Promise<{ results: User[]; totalCount: number }> {
|
async searchUserListings(criteria: UserListingCriteria): Promise<{ results: User[]; totalCount: number }> {
|
||||||
|
|
@ -63,7 +63,7 @@ export class UserService {
|
||||||
const length = criteria.length ? criteria.length : 12;
|
const length = criteria.length ? criteria.length : 12;
|
||||||
const query = this.conn.select().from(schema.users);
|
const query = this.conn.select().from(schema.users);
|
||||||
const whereConditions = this.getWhereConditions(criteria);
|
const whereConditions = this.getWhereConditions(criteria);
|
||||||
|
|
||||||
if (whereConditions.length > 0) {
|
if (whereConditions.length > 0) {
|
||||||
const whereClause = and(...whereConditions);
|
const whereClause = and(...whereConditions);
|
||||||
query.where(whereClause);
|
query.where(whereClause);
|
||||||
|
|
@ -110,7 +110,7 @@ export class UserService {
|
||||||
.from(schema.users)
|
.from(schema.users)
|
||||||
.where(sql`email = ${email}`)) as User[];
|
.where(sql`email = ${email}`)) as User[];
|
||||||
if (users.length === 0) {
|
if (users.length === 0) {
|
||||||
const user: User = { id: undefined, customerType: 'professional', ...createDefaultUser(email, jwtuser.firstname ? jwtuser.firstname : '', jwtuser.lastname ? jwtuser.lastname : '', null) };
|
const user: User = { id: undefined, customerType: 'professional', ...createDefaultUser(email, '', '', null) };
|
||||||
const u = await this.saveUser(user, false);
|
const u = await this.saveUser(user, false);
|
||||||
return u;
|
return u;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,10 @@
|
||||||
<li>
|
<li>
|
||||||
<a routerLink="/myListings" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Listings</a>
|
<a routerLink="/myListings" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Listings</a>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
<li>
|
<li>
|
||||||
<a routerLink="/myFavorites" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Favorites</a>
|
<a routerLink="/myFavorites" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Favorites</a>
|
||||||
</li>
|
</li>
|
||||||
}
|
|
||||||
<li>
|
<li>
|
||||||
<a routerLink="/emailUs" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">EMail Us</a>
|
<a routerLink="/emailUs" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">EMail Us</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,9 @@ export class DetailsBusinessListingComponent extends BaseDetailsComponent {
|
||||||
const result = [
|
const result = [
|
||||||
{ label: 'Category', value: this.selectOptions.getBusiness(this.listing.type) },
|
{ label: 'Category', value: this.selectOptions.getBusiness(this.listing.type) },
|
||||||
{ label: 'Located in', value: `${this.listing.location.name ? this.listing.location.name : this.listing.location.county}, ${this.selectOptions.getState(this.listing.location.state)}` },
|
{ label: 'Located in', value: `${this.listing.location.name ? this.listing.location.name : this.listing.location.county}, ${this.selectOptions.getState(this.listing.location.state)}` },
|
||||||
{ label: 'Asking Price', value: `$${this.listing.price?.toLocaleString()}` },
|
{ label: 'Asking Price', value: `${this.listing.price ? `$${this.listing.price.toLocaleString()}` : ''}` },
|
||||||
{ label: 'Sales revenue', value: `$${this.listing.salesRevenue?.toLocaleString()}` },
|
{ label: 'Sales revenue', value: `${this.listing.salesRevenue ? `$${this.listing.salesRevenue.toLocaleString()}` : ''}` },
|
||||||
{ label: 'Cash flow', value: `$${this.listing.cashFlow?.toLocaleString()}` },
|
{ label: 'Cash flow', value: `${this.listing.cashFlow ? `$${this.listing.cashFlow.toLocaleString()}` : ''}` },
|
||||||
{ label: 'Type of Real Estate', value: typeOfRealEstate },
|
{ label: 'Type of Real Estate', value: typeOfRealEstate },
|
||||||
{ label: 'Employees', value: this.listing.employees },
|
{ label: 'Employees', value: this.listing.employees },
|
||||||
{ label: 'Established since', value: this.listing.established },
|
{ label: 'Established since', value: this.listing.established },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue