@simitgroup/simpleapp-generator 1.0.59 → 1.0.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/buildinschemas/branch.d.ts.map +1 -1
- package/dist/buildinschemas/branch.js +1 -0
- package/dist/buildinschemas/branch.js.map +1 -1
- package/dist/buildinschemas/organization.d.ts.map +1 -1
- package/dist/buildinschemas/organization.js +1 -0
- package/dist/buildinschemas/organization.js.map +1 -1
- package/dist/buildinschemas/permission.js +1 -1
- package/dist/buildinschemas/permission.js.map +1 -1
- package/dist/buildinschemas/user.d.ts.map +1 -1
- package/dist/buildinschemas/user.js +4 -1
- package/dist/buildinschemas/user.js.map +1 -1
- package/dist/framework.js +1 -1
- package/dist/framework.js.map +1 -1
- package/dist/generate.js +6 -1
- package/dist/generate.js.map +1 -1
- package/dist/type.d.ts +1 -0
- package/dist/type.d.ts.map +1 -1
- package/docs/jsonschema.md +1 -0
- package/package.json +1 -1
- package/src/buildinschemas/branch.ts +1 -0
- package/src/buildinschemas/organization.ts +1 -0
- package/src/buildinschemas/permission.ts +1 -1
- package/src/buildinschemas/user.ts +4 -1
- package/src/framework.ts +1 -1
- package/src/generate.ts +6 -1
- package/src/type.ts +1 -0
- package/templates/basic/nest/controller.ts.eta +5 -3
- package/templates/basic/nest/model.ts.eta +32 -7
- package/templates/basic/nuxt/pages.crud.vue.eta +59 -163
- package/templates/basic/nuxt/pages.index.vue.eta +225 -0
- package/templates/nest/.env._eta +1 -0
- package/templates/nest/src/simpleapp/generate/commons/exceptions/SimpleAppExceptionFilter.ts.eta +1 -1
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -1
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +127 -22
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +1 -1
- package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +25 -2
- package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +20 -2
- package/templates/nest/src/simpleapp/services/branch.service.ts.eta +41 -40
- package/templates/nest/src/simpleapp/services/user.service.ts.eta +10 -9
- package/templates/nuxt/app.vue.eta +2 -1
- package/templates/nuxt/assets/css/style.css._eta +3 -12
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +24 -20
- package/templates/nuxt/components/ButtonCreateTenant.vue.eta +30 -23
- package/templates/nuxt/components/ButtonHome.vue.eta +15 -2
- package/templates/nuxt/components/ButtonMenuPicker.vue.eta +5 -20
- package/templates/nuxt/components/ButtonPermissionInfo.vue.eta +5 -7
- package/templates/nuxt/components/ButtonProfile.vue.eta +42 -25
- package/templates/nuxt/components/CrudSimple.vue.eta +1 -1
- package/templates/nuxt/components/EventDecision.vue.eta +115 -0
- package/templates/nuxt/components/EventNotification.vue.eta +157 -0
- package/templates/nuxt/components/HeaderBar.vue.eta +2 -2
- package/templates/nuxt/components/Invitation.vue.eta +3 -3
- package/templates/nuxt/components/SelectBranch.vue.eta +5 -2
- package/templates/nuxt/components/SimpleAppDatatable.vue.eta +151 -5
- package/templates/nuxt/components/TenantPicker.vue.eta +75 -0
- package/templates/nuxt/components/UserProfileListItem.vue.eta +65 -0
- package/templates/nuxt/components/renderers/BooleanRender.vue.eta +7 -0
- package/templates/nuxt/components/renderers/DateRender.vue.eta +6 -0
- package/templates/nuxt/components/renderers/ForeignKeyRender.vue.eta +10 -0
- package/templates/nuxt/components/renderers/MoneyRender.vue.eta +7 -0
- package/templates/nuxt/components/renderers/MultiTextRender.vue.eta +11 -0
- package/templates/nuxt/composables/getDocument.generate.ts.eta +4 -0
- package/templates/nuxt/composables/getMenus.generate.ts.eta +35 -31
- package/templates/nuxt/composables/getUserStore.generate.ts.eta +6 -1
- package/templates/nuxt/composables/goTo.generate.ts.eta +15 -0
- package/templates/nuxt/composables/notifications.generate.ts.eta +21 -0
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +11 -1
- package/templates/nuxt/error.vue._eta +20 -5
- package/templates/nuxt/layouts/documentlist.vue.eta +166 -0
- package/templates/nuxt/middleware/30.acl.global.ts.eta +4 -1
- package/templates/nuxt/pages/[xorg]/organization/index.vue.eta +4 -4
- package/templates/nuxt/pages/[xorg]/profile.vue.eta +6 -0
- package/templates/nuxt/pages/[xorg]/user/[id].vue.eta +6 -0
- package/templates/nuxt/pages/[xorg]/user/index.vue.eta +211 -377
- package/templates/nuxt/pages/[xorg]/user.vue.eta +197 -0
- package/templates/nuxt/pages/index.vue._eta +101 -0
- package/templates/nuxt/pages/profile.vue.eta +94 -0
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +4 -4
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +11 -10
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +69 -17
- package/templates/nuxt/simpleapp/generate/commons/documents.ts.eta +6 -3
- package/templates/nuxt/tailwind.config.ts._eta +10 -0
- package/templates/nuxt/types/documentlist.ts.eta +9 -0
- package/templates/nuxt/types/events.ts.eta +20 -0
- package/templates/nuxt/types/index.ts.eta +6 -79
- package/templates/nuxt/types/notifications.ts.eta +16 -0
- package/templates/nuxt/types/others.ts.eta +42 -0
- package/templates/nuxt/types/user.ts.eta +44 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nest/src/simpleapp/generate/models/perm.model.ts.eta +0 -52
- package/templates/nest/src/simpleapp/generate/models/tenant.model.ts.eta +0 -43
- package/templates/nest/src/simpleapp/generate/models/user.model.ts.eta +0 -56
- package/templates/nuxt/components/EventMonitor.vue.eta +0 -85
- package/templates/nuxt/pages/[xorg]/tenant/index.vue.eta +0 -89
- package/templates/nuxt/pages/index.vue.eta +0 -116
- package/templates/nuxt/simpleapp/generate/commons/events.ts.eta +0 -11
|
@@ -21,8 +21,10 @@ import { Permission, } from './../types/perm.type';
|
|
|
21
21
|
import {ProfileUserBranch , ProfileUserInvites} from '../../profile/profile.types'
|
|
22
22
|
|
|
23
23
|
import {ClientSession} from 'mongoose'
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
@Injectable({scope:Scope.REQUEST})
|
|
25
26
|
export class UserContext {
|
|
27
|
+
protected sessionId : string =crypto.randomUUID()
|
|
26
28
|
protected logger = new Logger()
|
|
27
29
|
protected uid: string = '';
|
|
28
30
|
protected _id: string = '';
|
|
@@ -42,6 +44,7 @@ export class UserContext {
|
|
|
42
44
|
protected orgCode: string = '';
|
|
43
45
|
protected orgName: string = '';
|
|
44
46
|
protected branches: any[] = []
|
|
47
|
+
protected lastActivity : string = new Date().toISOString()
|
|
45
48
|
protected invites: any[] = [] //User + field tenant:Tenant[]
|
|
46
49
|
protected roles: string[] = [];
|
|
47
50
|
protected modifiedRecords:ModifiedRecords = {createds:{},updateds:{},deleteds:{}}
|
|
@@ -49,7 +52,8 @@ export class UserContext {
|
|
|
49
52
|
constructor(
|
|
50
53
|
private readonly usermodel:Model<User>,
|
|
51
54
|
private readonly permmodel:Model<Permission>,
|
|
52
|
-
private dbsession:ClientSession
|
|
55
|
+
private dbsession:ClientSession,
|
|
56
|
+
|
|
53
57
|
) {
|
|
54
58
|
|
|
55
59
|
}
|
|
@@ -119,21 +123,19 @@ export class UserContext {
|
|
|
119
123
|
*/
|
|
120
124
|
obtainProfileFromDb = async () : Promise<User|undefined>=>{
|
|
121
125
|
const filter = { $match:{uid:this.uid,tenantId:this.tenantId} }
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
126
|
|
|
126
127
|
const joinpermission:PipelineStage = {$lookup: {
|
|
127
128
|
from : 'permission',
|
|
128
|
-
localField : '
|
|
129
|
-
foreignField : '
|
|
129
|
+
localField : '_id',
|
|
130
|
+
foreignField : 'userId',
|
|
130
131
|
as : 'permissions',
|
|
131
132
|
pipeline:[
|
|
132
|
-
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
{
|
|
134
|
+
$match:{
|
|
135
|
+
// userId:this.getId(),
|
|
136
|
+
tenantId:this.tenantId,
|
|
137
|
+
orgId:this.orgId,
|
|
138
|
+
branchId:this.branchId,
|
|
137
139
|
}},
|
|
138
140
|
{$lookup:{from: 'branch',localField: 'branchId',foreignField:'branchId',as: 'currentbranch'}},
|
|
139
141
|
{$lookup:{from: 'organization',localField: 'orgId',foreignField:'orgId',as: 'currentorg'}}
|
|
@@ -154,22 +156,38 @@ export class UserContext {
|
|
|
154
156
|
// console.log("obtainProfileFromDbobtainProfileFromDb ",users)
|
|
155
157
|
if(users && users.length>0){
|
|
156
158
|
const userinfo = users[0]
|
|
157
|
-
|
|
159
|
+
console.log("userinfouserinfouserinfouserinfouserinfouserinfo ",userinfo)
|
|
158
160
|
|
|
159
161
|
if(this.tenantId>0){
|
|
160
162
|
const myperm=userinfo.permissions[0]
|
|
161
163
|
if(myperm && myperm.group){
|
|
162
164
|
userinfo.group = myperm.group
|
|
163
|
-
userinfo.roles = rolegroups[userinfo.group]
|
|
165
|
+
userinfo.roles = rolegroups[userinfo.group]()
|
|
164
166
|
userinfo.branchCode = myperm.currentbranch[0].branchCode
|
|
165
167
|
userinfo.branchName = myperm.currentbranch[0].branchName
|
|
166
168
|
userinfo.orgCode = myperm.currentorg[0].orgCode
|
|
167
169
|
userinfo.orgName = myperm.currentorg[0].orgName
|
|
170
|
+
|
|
168
171
|
}
|
|
169
172
|
}else{
|
|
170
173
|
userinfo.group = ''
|
|
171
174
|
}
|
|
175
|
+
console.log('userinfouserinfouserinfouserinfo',userinfo)
|
|
176
|
+
const currentitme = new Date(this.lastActivity).getTime()
|
|
177
|
+
console.log(" userinfo.lastactivity userinfo.lastactivity userinfo.lastactivity ", userinfo.lastActivity )
|
|
178
|
+
const dblastactivity = userinfo.lastActivity ?? '2000-01-01T00:00:00Z'
|
|
179
|
+
const lastvisit = new Date( dblastactivity).getTime() ?? 0
|
|
180
|
+
// if(currentitme - lastvisit)
|
|
181
|
+
console.log(`${userinfo._id}: ${this.lastActivity}: ${currentitme} - ${dblastactivity}:${lastvisit} = ${currentitme - lastvisit}`)
|
|
182
|
+
|
|
183
|
+
//update last activtity dont too frequent
|
|
184
|
+
if(!dblastactivity || currentitme - lastvisit > 5000 ){
|
|
185
|
+
const newusermodel = await this.usermodel.findById(userinfo._id)
|
|
186
|
+
newusermodel.lastActivity= this.lastActivity
|
|
187
|
+
const result = await newusermodel.save()
|
|
188
|
+
}
|
|
172
189
|
|
|
190
|
+
// const result = await this.usermodel.findOneAndUpdate({_id: userinfo._id},{lastActivity: new Date().toISOString})
|
|
173
191
|
return userinfo
|
|
174
192
|
}else{
|
|
175
193
|
return undefined
|
|
@@ -200,7 +218,7 @@ export class UserContext {
|
|
|
200
218
|
this.orgCode = userinfo['orgCode'] ?? ''
|
|
201
219
|
this.orgName = userinfo['orgName'] ?? ''
|
|
202
220
|
this.group = userinfo['group'] ?? ''
|
|
203
|
-
this.roles = userinfo['roles'] ?? [Role.Everyone,Role.User
|
|
221
|
+
this.roles = userinfo['roles'] ?? [Role.Everyone,Role.User]
|
|
204
222
|
}else{
|
|
205
223
|
this.logger.debug(`Set unknown id of current user`,'setUserToken' )
|
|
206
224
|
// this.group = ''
|
|
@@ -291,6 +309,7 @@ export class UserContext {
|
|
|
291
309
|
// obtain basic user info
|
|
292
310
|
const userinfo = {
|
|
293
311
|
_id: this.getId() ,
|
|
312
|
+
sessionId:this.sessionId,
|
|
294
313
|
tenantId: this.getTenantId(),
|
|
295
314
|
orgId: this.getOrgId(),
|
|
296
315
|
branchId: this.getBranchId(),
|
|
@@ -310,14 +329,17 @@ export class UserContext {
|
|
|
310
329
|
|
|
311
330
|
if(this.getId()!=''){
|
|
312
331
|
this.logger.debug(userinfo,"obtain permissions and invitations")
|
|
313
|
-
const filter:PipelineStage ={ $match:{
|
|
332
|
+
const filter:PipelineStage ={ $match:{
|
|
333
|
+
uid:this.uid,
|
|
334
|
+
tenantId :this.tenantId
|
|
335
|
+
}} as PipelineStage
|
|
314
336
|
const permission:PipelineStage = {$lookup: {
|
|
315
337
|
from : 'permission',
|
|
316
|
-
localField : '
|
|
317
|
-
foreignField : '
|
|
338
|
+
localField : '_id',
|
|
339
|
+
foreignField : 'userId',
|
|
318
340
|
as : 'permissions',
|
|
319
341
|
pipeline:[
|
|
320
|
-
{$match:{
|
|
342
|
+
// {$match:{userId: this.getId(),},},
|
|
321
343
|
{$lookup:{from : 'branch',localField : 'branchId',foreignField : 'branchId',as : 'branch',}},
|
|
322
344
|
]
|
|
323
345
|
}}
|
|
@@ -340,6 +362,7 @@ export class UserContext {
|
|
|
340
362
|
this.logger.debug(pipeline,"getUserInfo")
|
|
341
363
|
// // // const users = await usermodel.find(filter)
|
|
342
364
|
const users = await this.usermodel.aggregate(pipeline)
|
|
365
|
+
this.logger.debug(users,'users from aggregate')
|
|
343
366
|
|
|
344
367
|
|
|
345
368
|
this.invites = users[0].invites
|
|
@@ -388,11 +411,13 @@ export class UserContext {
|
|
|
388
411
|
const o = this.ssoACL
|
|
389
412
|
const ssoclient = process.env.OAUTH2_CLIENTID
|
|
390
413
|
const adminRole = process.env.OAUTH2_ADMINROLE
|
|
391
|
-
|
|
392
|
-
|
|
414
|
+
// return false
|
|
415
|
+
if(this.getEmail()===process.env.ADMIN_EMAIL){
|
|
416
|
+
return true
|
|
417
|
+
}
|
|
418
|
+
else if( o[ssoclient] && o[ssoclient]['roles'] && o[ssoclient]['roles'] == adminRole ){
|
|
393
419
|
return true
|
|
394
420
|
}else{
|
|
395
|
-
//console.log("not admin")
|
|
396
421
|
return false
|
|
397
422
|
}
|
|
398
423
|
|
|
@@ -425,4 +450,84 @@ export class UserContext {
|
|
|
425
450
|
}
|
|
426
451
|
|
|
427
452
|
}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
async getAllTenants (){
|
|
456
|
+
const results = []
|
|
457
|
+
if(this.getId()!=''){
|
|
458
|
+
const filteruser:PipelineStage ={ $match:{
|
|
459
|
+
uid:this.uid,
|
|
460
|
+
tenantId :{'$gt':0}
|
|
461
|
+
}} as PipelineStage
|
|
462
|
+
|
|
463
|
+
const getTenantData:PipelineStage = { $lookup:{
|
|
464
|
+
from : 'tenant',
|
|
465
|
+
localField : 'tenantId',
|
|
466
|
+
foreignField : 'tenantId',
|
|
467
|
+
as : 'tenant',}}
|
|
468
|
+
|
|
469
|
+
const permission:PipelineStage = {$lookup: {
|
|
470
|
+
from : 'permission',
|
|
471
|
+
localField : '_id',
|
|
472
|
+
foreignField : 'userId',
|
|
473
|
+
as : 'permissions',
|
|
474
|
+
pipeline:[
|
|
475
|
+
|
|
476
|
+
{$lookup:{from : 'organization',localField : 'orgId',foreignField : 'orgId',as : 'org',}},
|
|
477
|
+
{$lookup:{from : 'branch',localField : 'branchId',foreignField : 'branchId',as : 'branch',}},
|
|
478
|
+
]
|
|
479
|
+
}}
|
|
480
|
+
|
|
481
|
+
const pipelines:PipelineStage[] =[filteruser,getTenantData,permission]
|
|
482
|
+
// const users=[]
|
|
483
|
+
this.logger.warn(pipelines,"pipelines")
|
|
484
|
+
const users = await this.usermodel.aggregate(pipelines)
|
|
485
|
+
|
|
486
|
+
if(users){
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
const activeusers = users.filter((u)=>{
|
|
490
|
+
// console.log(u.active,'===',true, ' && ',u.tenant[0].active,'===',true)
|
|
491
|
+
return u.active===true && u.tenant[0].active===true
|
|
492
|
+
})
|
|
493
|
+
// return activeusers
|
|
494
|
+
activeusers.forEach((u)=>{
|
|
495
|
+
|
|
496
|
+
const permissions = u.permissions.filter((item:any)=>{
|
|
497
|
+
return item.org[0].active && item.branch[0].active
|
|
498
|
+
})
|
|
499
|
+
.map((item:any)=>{
|
|
500
|
+
|
|
501
|
+
return {
|
|
502
|
+
_id: item._id,
|
|
503
|
+
orgId: item.orgId,
|
|
504
|
+
branchId: item.branchId,
|
|
505
|
+
group: item.group,
|
|
506
|
+
orgCode: item.org[0].orgCode,
|
|
507
|
+
orgName: item.org[0].orgName,
|
|
508
|
+
branchCode: item.branch[0].branchCode,
|
|
509
|
+
branchName: item.branch[0].branchName,
|
|
510
|
+
xOrg: this.generateXorg(u.tenantId,item.orgId,item.branchId)
|
|
511
|
+
}
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
results.push({
|
|
518
|
+
_id: u._id,
|
|
519
|
+
fullname : u.fullname,
|
|
520
|
+
tenantId: u.tenantId,
|
|
521
|
+
tenantName: u.tenant[0].tenantName,
|
|
522
|
+
permissions: permissions
|
|
523
|
+
})
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
}
|
|
531
|
+
return results
|
|
532
|
+
}
|
|
428
533
|
}
|
|
@@ -236,7 +236,7 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
236
236
|
await this.hook(appuser,HookType.beforeSearch, newfilters);
|
|
237
237
|
// console.log("before _find",newfilters)
|
|
238
238
|
// console.log("this.doc",this.doc)
|
|
239
|
-
const products = await this.doc.find(newfilters,projection).sort(sort);
|
|
239
|
+
const products = await this.doc.find(newfilters,projection,{session:appuser.getDBSession()}).sort(sort);
|
|
240
240
|
// console.log("after search",products)
|
|
241
241
|
const productlist = products.map((p: T) => {
|
|
242
242
|
return p;
|
|
@@ -67,6 +67,31 @@ export class ProfileController {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
@Get('/tenants')
|
|
71
|
+
@Roles(Role.Everyone, Role.User)
|
|
72
|
+
@ApiOperation({
|
|
73
|
+
operationId: 'getAllTenants',
|
|
74
|
+
description: 'Get all tenants',
|
|
75
|
+
})
|
|
76
|
+
@ApiResponse({
|
|
77
|
+
status: 200,
|
|
78
|
+
type: () => [MyProfileApiSchema],
|
|
79
|
+
description: 'Success',
|
|
80
|
+
})
|
|
81
|
+
@ApiResponse({ status: 401, type: Object, description: 'Undefine profile' })
|
|
82
|
+
async getAllTenants(@AppUser() appuser: UserContext) {
|
|
83
|
+
this.logger.debug(
|
|
84
|
+
`access getAllTenants API by ${appuser.getUid()},(${appuser.getId()})`,
|
|
85
|
+
);
|
|
86
|
+
const result = await this.profileservice.getAllTenants(appuser);
|
|
87
|
+
this.logger.debug('getProfile result is:');
|
|
88
|
+
this.logger.debug(result);
|
|
89
|
+
if (result) {
|
|
90
|
+
return result;
|
|
91
|
+
} else {
|
|
92
|
+
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
70
95
|
|
|
71
96
|
@Post('/tenant')
|
|
72
97
|
@Roles(Role.Everyone)
|
|
@@ -106,10 +131,8 @@ export class ProfileController {
|
|
|
106
131
|
decision,
|
|
107
132
|
);
|
|
108
133
|
if (result) {
|
|
109
|
-
console.log('result', result);
|
|
110
134
|
return result;
|
|
111
135
|
} else {
|
|
112
|
-
console.log('throw error');
|
|
113
136
|
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
114
137
|
}
|
|
115
138
|
}
|
|
@@ -74,7 +74,11 @@ export class ProfileService {
|
|
|
74
74
|
active: true,
|
|
75
75
|
doctype: 'user',
|
|
76
76
|
} as User;
|
|
77
|
-
|
|
77
|
+
if (appuser.getTenantId() == 0) {
|
|
78
|
+
data.tenantId = 0;
|
|
79
|
+
data.orgId = 0;
|
|
80
|
+
data.branchId = 0;
|
|
81
|
+
}
|
|
78
82
|
const createresult = await this.usersvc.create(appuser, data);
|
|
79
83
|
const userinfo = await appuser.getUserInfo();
|
|
80
84
|
userinfo._id = createresult._id;
|
|
@@ -161,7 +165,7 @@ export class ProfileService {
|
|
|
161
165
|
orgId: orgResult.orgId,
|
|
162
166
|
branchId: branchResult.branchId,
|
|
163
167
|
uid: appuser.getUid(),
|
|
164
|
-
|
|
168
|
+
userId: userRecordId,
|
|
165
169
|
group: 'admin',
|
|
166
170
|
};
|
|
167
171
|
this.logger.log(permdata, 'create Permission data');
|
|
@@ -172,6 +176,16 @@ export class ProfileService {
|
|
|
172
176
|
|
|
173
177
|
this.logger.log(permResult, 'create Permission result');
|
|
174
178
|
|
|
179
|
+
|
|
180
|
+
//tenant owner shall map to userId for that tenant
|
|
181
|
+
|
|
182
|
+
const tenantUpdateData = await this.tenantsvc.findById(appuser,tenantResult._id)
|
|
183
|
+
this.logger.log(tenantUpdateData, `update tenant owner(${tenantResult._id})`);
|
|
184
|
+
tenantUpdateData.owner._id = userRecordId
|
|
185
|
+
const updateTenantOwnerResult = await this.tenantsvc.findIdThenUpdate(appuser,tenantResult._id,tenantUpdateData)
|
|
186
|
+
if (!updateTenantOwnerResult) {
|
|
187
|
+
throw new BadRequestException('Update tenant owner failed');
|
|
188
|
+
}
|
|
175
189
|
const xorg: string = Base64URL.encodeText(
|
|
176
190
|
`${tenantResult.tenantId}-${orgResult.orgId}-${branchResult.branchId}`,
|
|
177
191
|
);
|
|
@@ -197,4 +211,8 @@ export class ProfileService {
|
|
|
197
211
|
async decideInvitation(appuser: UserContext, id: string, decision: string) {
|
|
198
212
|
return await appuser.decideInvitation(id, decision);
|
|
199
213
|
}
|
|
214
|
+
|
|
215
|
+
async getAllTenants(appuser: UserContext) {
|
|
216
|
+
return await appuser.getAllTenants();
|
|
217
|
+
}
|
|
200
218
|
}
|
|
@@ -9,19 +9,19 @@ import { Model } from 'mongoose';
|
|
|
9
9
|
import { Injectable, InternalServerErrorException } from '@nestjs/common';
|
|
10
10
|
import { BranchProcessor } from '../generate/processors/branch.processor';
|
|
11
11
|
import { Branch } from '../generate/types/branch.type';
|
|
12
|
-
import {alldocuments} from '../generate/commons/dicts/documents'
|
|
12
|
+
import { alldocuments } from '../generate/commons/dicts/documents';
|
|
13
13
|
export { Branch } from '../generate/types/branch.type';
|
|
14
14
|
import { AutoincreamentService } from './autoinc.service';
|
|
15
15
|
import { UserContext } from '../generate/commons/user.context';
|
|
16
|
-
import { Docnoformat,DocnoformatService } from './docno.service';
|
|
16
|
+
import { Docnoformat, DocnoformatService } from './docno.service';
|
|
17
17
|
// import { Docnoformat } from '../generate/types/docno.type';
|
|
18
18
|
@Injectable()
|
|
19
19
|
export class BranchService extends BranchProcessor {
|
|
20
20
|
protected strictIsolation = false;
|
|
21
21
|
constructor(
|
|
22
22
|
@InjectModel('Branch') mydoc: Model<Branch>,
|
|
23
|
-
private increament: AutoincreamentService,
|
|
24
|
-
private docnoservice:DocnoformatService
|
|
23
|
+
private increament: AutoincreamentService,
|
|
24
|
+
private docnoservice: DocnoformatService,
|
|
25
25
|
) {
|
|
26
26
|
super(mydoc);
|
|
27
27
|
}
|
|
@@ -46,9 +46,9 @@ export class BranchService extends BranchProcessor {
|
|
|
46
46
|
);
|
|
47
47
|
data.branchId = searchresult.nextno;
|
|
48
48
|
break;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
case 'afterCreate':
|
|
50
|
+
await this.generateDefaultDocNumbers(appuser, data);
|
|
51
|
+
break;
|
|
52
52
|
// case 'beforeUpdate':
|
|
53
53
|
// break;
|
|
54
54
|
// case 'afterUpdate':
|
|
@@ -67,40 +67,41 @@ export class BranchService extends BranchProcessor {
|
|
|
67
67
|
return true;
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
generateDefaultDocNumbers =async (appuser,data) => {
|
|
71
|
-
const branchName = data.branchName
|
|
72
|
-
const branchCode = data.branchCode
|
|
73
|
-
const recordId = data._id
|
|
74
|
-
const branchId= data.branchId
|
|
75
|
-
const orgId = data.orgId
|
|
76
|
-
const tenantId = data.tenantId
|
|
77
|
-
const docformats = alldocuments.filter((item)=>item.docNumber)
|
|
78
|
-
for(let i=0; i< docformats.length; i++){
|
|
79
|
-
const doc = docformats[i]
|
|
80
|
-
const pattern = `${doc.docType}-${branchCode}-[00000]
|
|
81
|
-
const formatdata:Docnoformat = {
|
|
82
|
-
_id:crypto.randomUUID(),
|
|
83
|
-
docNoFormatNo:
|
|
84
|
-
docNoFormatName:
|
|
70
|
+
generateDefaultDocNumbers = async (appuser, data) => {
|
|
71
|
+
const branchName = data.branchName;
|
|
72
|
+
const branchCode = data.branchCode;
|
|
73
|
+
const recordId = data._id;
|
|
74
|
+
const branchId = data.branchId;
|
|
75
|
+
const orgId = data.orgId;
|
|
76
|
+
const tenantId = data.tenantId;
|
|
77
|
+
const docformats = alldocuments.filter((item) => item.docNumber);
|
|
78
|
+
for (let i = 0; i < docformats.length; i++) {
|
|
79
|
+
const doc = docformats[i];
|
|
80
|
+
const pattern = `${doc.docType}-${branchCode}-[00000]`;
|
|
81
|
+
const formatdata: Docnoformat = {
|
|
82
|
+
_id: crypto.randomUUID(),
|
|
83
|
+
docNoFormatNo: doc.docType,
|
|
84
|
+
docNoFormatName: `Default ${doc.docType}`,
|
|
85
85
|
docNoType: doc.docType,
|
|
86
|
-
docNoPattern:
|
|
87
|
-
branch:{_id:recordId,branchId:branchId,label:branchName},
|
|
88
|
-
branchId:branchId,
|
|
89
|
-
orgId:orgId,
|
|
90
|
-
tenantId:tenantId,
|
|
91
|
-
nextNumber:1,
|
|
92
|
-
} as Docnoformat
|
|
93
|
-
try{
|
|
94
|
-
const result = await this.docnoservice.create(appuser,formatdata)
|
|
95
|
-
if(!result){
|
|
96
|
-
throw new InternalServerErrorException(
|
|
86
|
+
docNoPattern: pattern,
|
|
87
|
+
branch: { _id: recordId, branchId: branchId, label: branchName },
|
|
88
|
+
branchId: branchId,
|
|
89
|
+
orgId: orgId,
|
|
90
|
+
tenantId: tenantId,
|
|
91
|
+
nextNumber: 1,
|
|
92
|
+
} as Docnoformat;
|
|
93
|
+
try {
|
|
94
|
+
const result = await this.docnoservice.create(appuser, formatdata);
|
|
95
|
+
if (!result) {
|
|
96
|
+
throw new InternalServerErrorException(
|
|
97
|
+
`Generate default document number for "${branchCode}" failed. Pattern: ${pattern}`,
|
|
98
|
+
'generateDefaultDocNumbers',
|
|
99
|
+
);
|
|
97
100
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
throw new InternalServerErrorException(err)
|
|
101
|
+
} catch (err) {
|
|
102
|
+
this.logger.error(err);
|
|
103
|
+
throw new InternalServerErrorException(err);
|
|
102
104
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
106
107
|
}
|
|
@@ -14,7 +14,6 @@ import { User } from '../generate/types/user.type';
|
|
|
14
14
|
|
|
15
15
|
export { User } from '../generate/types/user.type';
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
@Injectable()
|
|
19
18
|
export class UserService extends UserProcessor {
|
|
20
19
|
protected strictIsolation = false;
|
|
@@ -45,14 +44,16 @@ export class UserService extends UserProcessor {
|
|
|
45
44
|
// break;
|
|
46
45
|
// case 'afterUpdate':
|
|
47
46
|
// break;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
case 'beforeDelete':
|
|
48
|
+
console.log("before delete",data)
|
|
49
|
+
const result = await this.permdoc.deleteMany({
|
|
50
|
+
user_id: data['data'], //delete hook data = _id
|
|
51
|
+
});
|
|
52
|
+
this.logger.log(result, 'user deleteHook');
|
|
53
|
+
break;
|
|
54
|
+
// case 'afterDelete':
|
|
55
|
+
|
|
56
|
+
// break;
|
|
56
57
|
// case 'beforeFetchRecord':
|
|
57
58
|
// break;
|
|
58
59
|
// case 'afterFetchRecord':
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
.
|
|
2
|
-
@apply
|
|
3
|
-
}
|
|
4
|
-
.btn-primary{
|
|
5
|
-
@apply bg-primary-600 text-white
|
|
6
|
-
}
|
|
7
|
-
.btn-danger{
|
|
8
|
-
@apply bg-danger-600 text-white
|
|
9
|
-
}
|
|
10
|
-
.btn-warning{
|
|
11
|
-
@apply bg-danger-600 text-white
|
|
12
|
-
}
|
|
1
|
+
.router-link-exact-active{
|
|
2
|
+
@apply bg-primary-100 block
|
|
3
|
+
}
|
|
@@ -5,29 +5,33 @@ import Tailwind from "primevue/passthrough/tailwind";
|
|
|
5
5
|
const CustomTailwind = usePassThrough(
|
|
6
6
|
Tailwind,
|
|
7
7
|
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
8
|
+
|
|
9
|
+
toast:{
|
|
10
|
+
root:{ class:'w-1/3 '},
|
|
11
|
+
message:{},
|
|
12
|
+
container:{class:'w-full ' },
|
|
13
|
+
content:{class:'flex flex-row-reverse w-full'},
|
|
14
|
+
buttonContainer:{class:'hidden'},
|
|
12
15
|
},
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
16
|
+
card:{root:{class:'shadow p-4'}},
|
|
17
|
+
tabpanel:{headerTitle:{class:'m-3 p-3 bg bg-text-300'},},
|
|
18
|
+
selectbutton:{
|
|
19
|
+
root:{class:'flex flex-row gap-1'},
|
|
20
|
+
button: ({ context }) => ({
|
|
21
|
+
class: ['text-center border rounded p-2 cursor-pointer hover:bg-primary-400 hover:text-white', context.active ? 'bg-primary-600 text-white' : '']
|
|
22
|
+
}),
|
|
23
|
+
label:{class: 'text-sm'},
|
|
24
|
+
},
|
|
25
|
+
button:{root:{class: 'focus:outline-none transition duration-150 ease-in-out rounded px-8 py-2 m-1 border'}},
|
|
26
|
+
dialog:{root:{class:['border p-2']}},
|
|
27
|
+
sidebar:{
|
|
28
|
+
root:{class:'w-1/2 bg-white border p-2 h-full'}
|
|
17
29
|
},
|
|
18
30
|
panel: {
|
|
19
|
-
root:{
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
class: ['leading-none font-light text-2xl']
|
|
24
|
-
},
|
|
25
|
-
header:{
|
|
26
|
-
class:['bg bg-gray-200 h-10 content-middle']
|
|
27
|
-
},
|
|
28
|
-
content:{
|
|
29
|
-
class:['']
|
|
30
|
-
}
|
|
31
|
+
root:{class:['border']},
|
|
32
|
+
title: {class: ['leading-none font-light text-2xl']},
|
|
33
|
+
header:{class:['bg bg-gray-200 h-10 content-middle']},
|
|
34
|
+
content:{class:['']}
|
|
31
35
|
}
|
|
32
36
|
},
|
|
33
37
|
);
|
|
@@ -1,31 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<Button class="btn-primary " @click="visible = true">
|
|
4
|
-
<i class="pi pi-sitemap mr-2"></i>Create My Company
|
|
5
|
-
</Button>
|
|
6
|
-
<Dialog
|
|
7
|
-
v-model:visible="visible"
|
|
8
|
-
modal
|
|
9
|
-
:header="createtitle"
|
|
10
|
-
class="crudsimple-dialog"
|
|
11
|
-
>
|
|
12
|
-
<form @submit.prevent="true" class="flex flex-col text-center">
|
|
13
|
-
<div v-if="errCreateTenant" class="text-error">
|
|
14
|
-
{{ errCreateTenant }}
|
|
15
|
-
</div>
|
|
16
|
-
<InputText
|
|
17
|
-
v-else
|
|
18
|
-
type="text"
|
|
19
|
-
autofocus="true"
|
|
20
|
-
v-model:model-value="data.tenantName"
|
|
21
|
-
placeholder="Organization Name"
|
|
22
|
-
/>
|
|
23
3
|
|
|
24
|
-
|
|
25
|
-
|
|
4
|
+
<div class="mt-8 md:flex justify-start md:gap-4">
|
|
5
|
+
<!-- <input placeholder="Company Name"
|
|
6
|
+
class="placeholder-gray-600 dark:bg-gray-800 dark:border-transparent dark:placeholder-gray-200 dark:text-white w-full md:w-1/2 p-4 grid place-items-center border rounded-md focus:outline-none"
|
|
7
|
+
v-model:model-value="data.tenantName"
|
|
8
|
+
/> -->
|
|
9
|
+
|
|
10
|
+
<!-- <button class="">Create</button> -->
|
|
11
|
+
<form @submit.prevent="true" class="flex flex-row text-center">
|
|
12
|
+
<div class="flex flex-col">
|
|
13
|
+
<InputText
|
|
14
|
+
type="text"
|
|
15
|
+
autofocus="true"
|
|
16
|
+
v-model:model-value="data.tenantName"
|
|
17
|
+
placeholder="Organization Name"
|
|
18
|
+
/>
|
|
19
|
+
<div v-if="errCreateTenant" class="text-error">{{ errCreateTenant }}</div>
|
|
20
|
+
</div>
|
|
21
|
+
<Button class="w-full md:w-auto bg-primary-800 dark:border-transparent text-white px-8 py-4 border rounded-md hover:bg-primary-800 grid place-items-center font-semibold mt-4 md:mt-0 focus:outline-none focus:ring-2 focus:ring-primary-700 focus:ring-primary-50" type="submit" @click="createTenant" :loading="onhold">
|
|
22
|
+
Create
|
|
26
23
|
</Button>
|
|
27
24
|
</form>
|
|
28
|
-
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
<!--
|
|
32
|
+
<Button @click="visible = true" v-bind="$attrs">
|
|
33
|
+
<slot>Create Company</slot>
|
|
34
|
+
</Button> -->
|
|
35
|
+
|
|
29
36
|
</div>
|
|
30
37
|
|
|
31
38
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<button class="flex flex-row">
|
|
2
|
+
<button class="flex flex-row" @click="goHome">
|
|
3
3
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
|
4
4
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
|
5
5
|
</svg>
|
|
@@ -7,4 +7,17 @@
|
|
|
7
7
|
<span>{{ getUserProfile().orgName }}</span>
|
|
8
8
|
|
|
9
9
|
</button>
|
|
10
|
-
</template>
|
|
10
|
+
</template>
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
|
|
13
|
+
const goHome = () =>{
|
|
14
|
+
|
|
15
|
+
if(getCurrentXorg()){
|
|
16
|
+
navigateTo(`/${getCurrentXorg()}`)
|
|
17
|
+
}else{
|
|
18
|
+
navigateTo(`/`)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
</script>
|