Skip to content

Commit 7243088

Browse files
authored
Merge pull request #90 from wbbly/dev
Updates
2 parents 1040346 + a47c6d7 commit 7243088

29 files changed

Lines changed: 1050 additions & 353 deletions

app/src/client/client.controller.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Patch,
66
Delete,
77
Param,
8+
Query,
89
Response,
910
HttpStatus,
1011
Body,
@@ -30,15 +31,19 @@ export class ClientController {
3031

3132
@Get('list')
3233
@UseGuards(AuthGuard())
33-
async clientList(@Headers() headers: any, @Response() res: any) {
34+
async clientList(@Headers() headers: any, @Response() res: any, @Query() params) {
3435
const userId = await this.authService.getVerifiedUserId(headers.authorization);
3536
if (!userId) {
3637
throw new UnauthorizedException();
3738
}
38-
39+
let clientList: any = null;
40+
const { order_by, sort } = params;
3941
try {
40-
const clientList = await this.clientService.getClientList(userId);
41-
42+
if (order_by) {
43+
clientList = await this.clientService.getClientList(userId, order_by, sort);
44+
} else {
45+
clientList = await this.clientService.getClientList(userId);
46+
}
4247
return res.status(HttpStatus.OK).json(clientList);
4348
} catch (e) {
4449
const error: AxiosError = e;
@@ -81,6 +86,7 @@ export class ClientController {
8186
},
8287
@UploadedFile() file
8388
) {
89+
const { name, language, country, city, state, phone, email, zip, companyName } = body;
8490
const userId = await this.authService.getVerifiedUserId(headers.authorization);
8591
if (!userId) {
8692
throw new UnauthorizedException();
@@ -93,17 +99,18 @@ export class ClientController {
9399
try {
94100
const clientRequest = {
95101
userId,
96-
name: body.name,
97-
language: body.language,
98-
country: body.country,
99-
city: body.city,
100-
state: body.state,
101-
phone: body.phone,
102-
email: body.email,
103-
zip: body.zip,
102+
name,
103+
language,
104+
country,
105+
city,
106+
state,
107+
phone,
108+
email,
109+
zip,
104110
avatar: (file && file.path) || null,
105-
companyName: body.companyName.trim(),
111+
companyName: companyName.trim(),
106112
};
113+
107114
await this.clientService.addClient(clientRequest);
108115
const clientList = await this.clientService.getClientList(userId);
109116

@@ -204,7 +211,7 @@ export class ClientController {
204211
email: body.email,
205212
zip: body.zip,
206213
avatar: (file && file.path) || client.avatar,
207-
companyName: body.companyName.trim(),
214+
companyName: body.companyName.trim().replace(/\\([\s\S])|(")/g, '\\$1$2'),
208215
};
209216

210217
await this.clientService.patchClient(clientRequest);

app/src/client/client.service.ts

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,26 @@ export class ClientService {
1313
private readonly roleCollaborationService: RoleCollaborationService
1414
) {}
1515

16-
async getClientList(userId: string) {
16+
async getClientList(userId: string, orderBy: string = 'created_at', sort: string = 'asc') {
1717
const currentTeamData: any = await this.teamService.getCurrentTeam(userId);
1818
const currentTeamId = currentTeamData.data.user_team[0].team.id;
1919
const isAdmin =
2020
currentTeamData.data.user_team[0].role_collaboration_id ===
2121
this.roleCollaborationService.ROLES_IDS.ROLE_ADMIN;
2222

23-
if (isAdmin) {
23+
const isOwner =
24+
currentTeamData.data.user_team[0].role_collaboration_id ===
25+
this.roleCollaborationService.ROLES_IDS.ROLE_OWNER;
26+
27+
if (isAdmin || isOwner) {
2428
const query = `{
2529
client(
2630
where: {
2731
team_id: {
2832
_eq: "${currentTeamId}"
2933
}
3034
}
31-
order_by: {created_at: asc}
35+
order_by: {${orderBy}: ${sort}}
3236
) {
3337
id
3438
name
@@ -68,32 +72,38 @@ export class ClientService {
6872
currentTeamData.data.user_team[0].role_collaboration_id ===
6973
this.roleCollaborationService.ROLES_IDS.ROLE_ADMIN;
7074

71-
if (isAdmin) {
72-
const query = `mutation {
73-
insert_client(
74-
objects: {
75-
name: ${name ? '"' + name + '"' : null}
76-
team_id: "${currentTeamId}"
77-
language: ${language ? '"' + language + '"' : null}
78-
avatar: ${avatar ? '"' + avatar + '"' : null}
79-
country: ${country ? '"' + country + '"' : null}
80-
city: ${city ? '"' + city + '"' : null}
81-
state: ${state ? '"' + state + '"' : null}
82-
phone: ${phone ? '"' + phone + '"' : null}
83-
email: ${email ? '"' + email + '"' : null}
84-
zip: ${zip ? '"' + zip + '"' : null}
85-
company_name: "${companyName}"
86-
}
87-
) {
88-
returning {
89-
id
90-
}
91-
}
92-
}`;
75+
const isOwner =
76+
currentTeamData.data.user_team[0].role_collaboration_id ===
77+
this.roleCollaborationService.ROLES_IDS.ROLE_OWNER;
78+
79+
if (isAdmin || isOwner) {
80+
const variables = {
81+
object: {
82+
name: name || null,
83+
team_id: currentTeamId,
84+
language: language || null,
85+
avatar: avatar || null,
86+
country: country || null,
87+
city: city || null,
88+
state: state || null,
89+
phone: phone || null,
90+
email: email || null,
91+
zip: zip || null,
92+
company_name: companyName,
93+
},
94+
};
95+
96+
const query = `mutation insert_client($object: [client_insert_input!]!) {
97+
insert_client:insert_client(objects: $object) {
98+
returning {
99+
id
100+
}
101+
}
102+
}`;
93103

94104
return new Promise((resolve, reject) => {
95105
this.httpRequestsService
96-
.request(query)
106+
.graphql(query, variables)
97107
.subscribe((res: AxiosResponse) => resolve(res), (error: AxiosError) => reject(error));
98108
});
99109
} else {
@@ -107,7 +117,11 @@ export class ClientService {
107117
currentTeamData.data.user_team[0].role_collaboration_id ===
108118
this.roleCollaborationService.ROLES_IDS.ROLE_ADMIN;
109119

110-
if (isAdmin) {
120+
const isOwner =
121+
currentTeamData.data.user_team[0].role_collaboration_id ===
122+
this.roleCollaborationService.ROLES_IDS.ROLE_OWNER;
123+
124+
if (isAdmin || isOwner) {
111125
const query = `mutation {
112126
delete_client(
113127
where: {
@@ -150,7 +164,11 @@ export class ClientService {
150164
currentTeamData.data.user_team[0].role_collaboration_id ===
151165
this.roleCollaborationService.ROLES_IDS.ROLE_ADMIN;
152166

153-
if (isAdmin) {
167+
const isOwner =
168+
currentTeamData.data.user_team[0].role_collaboration_id ===
169+
this.roleCollaborationService.ROLES_IDS.ROLE_OWNER;
170+
171+
if (isAdmin || isOwner) {
154172
const query = `mutation {
155173
update_client(
156174
where: {

app/src/core/core.module.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { MailService } from './mail/mail.service';
66
import { EncryptionService } from './encryption/encryption.service';
77
import { JiraAuthService } from './jira-auth/jira-auth.service';
88
import { JiraService } from './sync/jira/jira.service';
9+
import { CrmService } from './sync/crm/crm.service';
10+
import { CrmAuthService } from './crm-auth/crm-auth.service';
911
import { CurrencyService } from './currency/currency.service';
1012

1113
@Module({
@@ -18,7 +20,25 @@ import { CurrencyService } from './currency/currency.service';
1820
},
1921
}),
2022
],
21-
providers: [HttpRequestsService, MailService, EncryptionService, JiraAuthService, JiraService, CurrencyService],
22-
exports: [HttpRequestsService, MailService, EncryptionService, JiraAuthService, JiraService, CurrencyService],
23+
providers: [
24+
HttpRequestsService,
25+
MailService,
26+
EncryptionService,
27+
JiraAuthService,
28+
JiraService,
29+
CurrencyService,
30+
CrmService,
31+
CrmAuthService,
32+
],
33+
exports: [
34+
HttpRequestsService,
35+
MailService,
36+
EncryptionService,
37+
JiraAuthService,
38+
JiraService,
39+
CurrencyService,
40+
CrmService,
41+
CrmAuthService,
42+
],
2343
})
2444
export class CoreModule {}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Injectable } from '@nestjs/common';
2+
3+
import { HttpRequestsService } from '../http-requests/http-requests.service';
4+
import { AxiosResponse } from 'axios';
5+
import { IAuthCrm } from './interfaces/crm-auth.iterface';
6+
7+
@Injectable()
8+
export class CrmAuthService {
9+
constructor(private readonly httpRequestsService: HttpRequestsService) {}
10+
11+
async authenticate(): Promise<any | { message: string }> {
12+
const URL: string = `${process.env.CRM_URL}/web/session/authenticate/`;
13+
14+
if (
15+
!Boolean(process.env.CRM_AUTH_LOGIN) ||
16+
!Boolean(process.env.CRM_AUTH_PASSWORD) ||
17+
!Boolean(process.env.CRM_AUTH_DB)
18+
) {
19+
return Promise.reject({
20+
message: 'Check for credentials.',
21+
});
22+
}
23+
24+
const authCredentials: IAuthCrm = {
25+
jsonrpc: '2.0',
26+
params: {
27+
login: process.env.CRM_AUTH_LOGIN,
28+
password: process.env.CRM_AUTH_PASSWORD,
29+
db: process.env.CRM_AUTH_DB,
30+
},
31+
};
32+
33+
return new Promise(async (resolve, reject) => {
34+
this.httpRequestsService.requestCrmPost(URL, authCredentials).subscribe(
35+
async (res: AxiosResponse) => {
36+
if (res.data.error) {
37+
return reject({
38+
message: res.data.error.message,
39+
});
40+
}
41+
return resolve(res);
42+
},
43+
() => {
44+
return reject({
45+
message: 'ERROR.AUTHENTICATE.CRM',
46+
});
47+
}
48+
);
49+
});
50+
}
51+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface IAuthCrm {
2+
jsonrpc: string;
3+
params: {
4+
login: string;
5+
password: string;
6+
db: string;
7+
};
8+
}

app/src/core/http-requests/http-requests.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,16 @@ export class HttpRequestsService {
5757
})
5858
.pipe(map(response => response.data));
5959
}
60+
requestCrmPost(url: string, data: any, cookies: string = ``): Observable<AxiosResponse | AxiosError> {
61+
return this.httpService
62+
.post(url, data, {
63+
headers: {
64+
'Content-Type': 'application/json',
65+
Cookie: cookies,
66+
},
67+
})
68+
.pipe(response => {
69+
return response;
70+
});
71+
}
6072
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Injectable } from '@nestjs/common';
2+
3+
import { AxiosResponse } from 'axios';
4+
import { HttpRequestsService } from '../../http-requests/http-requests.service';
5+
import { CrmAuthService } from '../../crm-auth/crm-auth.service';
6+
7+
import { ISyncMail } from './interfaces/sync-mail.iterface';
8+
9+
@Injectable()
10+
export class CrmService {
11+
constructor(
12+
private readonly httpRequestsService: HttpRequestsService,
13+
private readonly crmAuthService: CrmAuthService
14+
) {}
15+
16+
async addUserEmailToCRM(email: string): Promise<any | { message: string }> {
17+
const URL: string = `${process.env.CRM_URL}/api/mailing.contact/`;
18+
19+
if (!Boolean(process.env.CRM_URL)) {
20+
return Promise.reject({
21+
message: 'Check crm url availability.',
22+
});
23+
}
24+
25+
let authResponseCRM = null;
26+
try {
27+
authResponseCRM = await this.crmAuthService.authenticate();
28+
} catch (error) {
29+
return Promise.reject(error);
30+
}
31+
32+
const sessionIdCookies: string = authResponseCRM.headers['set-cookie'].find(header =>
33+
header.startsWith('session_id=')
34+
);
35+
36+
const emailData: ISyncMail = {
37+
params: {
38+
data: {
39+
email,
40+
},
41+
},
42+
};
43+
44+
return new Promise(async (resolve, reject) => {
45+
this.httpRequestsService.requestCrmPost(URL, emailData, sessionIdCookies).subscribe(
46+
async (res: AxiosResponse) => {
47+
if (res.data.error) {
48+
return reject({
49+
message: res.data.error.message,
50+
});
51+
}
52+
return resolve(res.data);
53+
},
54+
() => {
55+
return reject({
56+
message: 'ERROR.ADD.EMAIL.CRM',
57+
});
58+
}
59+
);
60+
});
61+
}
62+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface ISyncMail {
2+
params: {
3+
data: {
4+
email: string;
5+
};
6+
};
7+
}

0 commit comments

Comments
 (0)