@simitgroup/simpleapp-generator 1.6.3-alpha → 1.6.4-b-alpha
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/changehistories.d.ts +3 -0
- package/dist/buildinschemas/changehistories.d.ts.map +1 -0
- package/dist/buildinschemas/changehistories.js +36 -0
- package/dist/buildinschemas/changehistories.js.map +1 -0
- package/dist/buildinschemas/index.d.ts +1 -0
- package/dist/buildinschemas/index.d.ts.map +1 -1
- package/dist/buildinschemas/index.js +3 -1
- package/dist/buildinschemas/index.js.map +1 -1
- package/dist/buildinschemas/organization.js +2 -2
- package/dist/buildinschemas/organization.js.map +1 -1
- package/dist/buildinschemas/user.d.ts.map +1 -1
- package/dist/buildinschemas/user.js +5 -1
- package/dist/buildinschemas/user.js.map +1 -1
- package/dist/buildinschemas/webhook.d.ts +3 -0
- package/dist/buildinschemas/webhook.d.ts.map +1 -0
- package/dist/buildinschemas/webhook.js +33 -0
- package/dist/buildinschemas/webhook.js.map +1 -0
- package/dist/framework.d.ts.map +1 -1
- package/dist/framework.js +3 -2
- package/dist/framework.js.map +1 -1
- package/dist/generate.js +30 -11
- package/dist/generate.js.map +1 -1
- package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
- package/dist/processors/jsonschemabuilder.js +10 -2
- package/dist/processors/jsonschemabuilder.js.map +1 -1
- package/dist/type.d.ts +2 -0
- package/dist/type.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/buildinschemas/branch.ts +1 -0
- package/src/buildinschemas/changehistories.ts +33 -0
- package/src/buildinschemas/index.ts +2 -1
- package/src/buildinschemas/organization.ts +2 -2
- package/src/buildinschemas/user.ts +5 -1
- package/src/buildinschemas/webhook.ts +31 -0
- package/src/framework.ts +3 -2
- package/src/generate.ts +35 -15
- package/src/processors/jsonschemabuilder.ts +10 -2
- package/src/type.ts +2 -0
- package/templates/basic/nest/controller.ts.eta +24 -3
- package/templates/basic/nest/model.ts.eta +9 -1
- package/templates/basic/nest/resolver.ts.eta +2 -2
- package/templates/basic/nuxt/pages.[id].vue.eta +7 -7
- package/templates/basic/nuxt/pages.form.vue.eta +1 -4
- package/templates/basic/nuxt/pages.landing.vue.eta +1 -20
- package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +8 -1
- package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +2 -0
- package/templates/nest/src/simpleapp/generate/commons/dicts/documents.ts.eta +9 -2
- package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +21 -8
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.enum.ts.eta +5 -10
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -0
- package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +50 -0
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +22 -8
- package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +9 -1
- package/templates/nest/src/simpleapp/generate/processors/branch.processor.ts.eta +12 -6
- package/templates/nest/src/simpleapp/generate/processors/org.processor.ts.eta +7 -12
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +133 -28
- package/templates/nest/src/simpleapp/generate/types/schema.type.ts.eta +3 -1
- package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -0
- package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +19 -0
- package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +33 -8
- package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +15 -9
- package/templates/nuxt/assets/css/calendar.css._eta +3 -0
- package/templates/nuxt/assets/css/style.css._eta +1 -1
- package/templates/nuxt/assets/images/unknown.png.eta +0 -0
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +6 -1
- package/templates/nuxt/components/button/ButtonAction.vue._eta +40 -39
- package/templates/nuxt/components/button/ButtonDanger.vue._eta +11 -3
- package/templates/nuxt/components/button/ButtonDefault.vue._eta +11 -3
- package/templates/nuxt/components/button/ButtonPrimary.vue._eta +9 -3
- package/templates/nuxt/components/button/ButtonSecondary.vue._eta +33 -0
- package/templates/nuxt/components/button/ButtonText.vue._eta +9 -5
- package/templates/nuxt/components/button/ButtonWarning.vue._eta +11 -3
- package/templates/nuxt/components/calendar/CalendarInput.vue.eta +4 -3
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +76 -52
- package/templates/nuxt/components/chart/card.vue._eta +1 -1
- package/templates/nuxt/components/debug/DebugDocumentData.vue.eta +36 -26
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +35 -13
- package/templates/nuxt/components/form/FormBranch.vue._eta +52 -5
- package/templates/nuxt/components/form/FormDocnoformat.vue.eta +14 -10
- package/templates/nuxt/components/form/FormUser.vue._eta +2 -4
- package/templates/nuxt/components/form/user/FormUserPermission.vue.eta +77 -59
- package/templates/nuxt/components/header/HeaderSelectBranch.vue.eta +42 -35
- package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +30 -0
- package/templates/nuxt/components/image/ImageOrganization.vue.eta.vue +34 -14
- package/templates/nuxt/components/image/ImageToBase64Uploader.vue.eta.vue +67 -50
- package/templates/nuxt/components/list/ListDocumentTable.vue.eta +20 -12
- package/templates/nuxt/components/list/ListView.vue.eta +64 -35
- package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +5 -4
- package/templates/nuxt/components/overlay/OverlayViewer.vue.eta +8 -8
- package/templates/nuxt/components/page/PageDocList.vue.eta +36 -13
- package/templates/nuxt/components/renderer/RendererDate.vue.eta +8 -2
- package/templates/nuxt/components/renderer/RendererDateTime.vue.eta +7 -1
- package/templates/nuxt/components/renderer/RendererDocHistories.vue.eta +56 -0
- package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +14 -8
- package/templates/nuxt/components/renderer/RendererLink.vue.eta +7 -4
- package/templates/nuxt/components/renderer/RendererMoney.vue.eta +25 -17
- package/templates/nuxt/components/renderer/RendererTime.vue.eta +7 -1
- package/templates/nuxt/components/renderer/RendererViewer.vue.eta +19 -9
- package/templates/nuxt/components/select/SelectTemplate.vue.eta +53 -22
- package/templates/nuxt/components/session/SessionBlock.vue.eta +44 -46
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +25 -16
- package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +60 -0
- package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +16 -8
- package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -8
- package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +1 -1
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +114 -38
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +89 -168
- package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +44 -40
- package/templates/nuxt/components/simpleApp/SimpleAppUserPicker.vue.eta +387 -0
- package/templates/nuxt/components/text/TextDocStatus.vue._eta +22 -0
- package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +13 -15
- package/templates/nuxt/components/user/UserButtonPermissionInfo.vue.eta +138 -95
- package/templates/nuxt/components/user/UserInvitation.vue.eta +53 -45
- package/templates/nuxt/components/user/UserTenantPicker.vue.eta +32 -71
- package/templates/nuxt/composables/date.generate.ts.eta +105 -8
- package/templates/nuxt/composables/getDocument.generate.ts.eta +8 -6
- package/templates/nuxt/composables/getOpenApi.generate.ts.eta +58 -10
- package/templates/nuxt/composables/getUserStore.generate.ts.eta +39 -6
- package/templates/nuxt/composables/goTo.generate.ts.eta +14 -1
- package/templates/nuxt/composables/graphquery.generate.ts.eta +20 -2
- package/templates/nuxt/composables/recently.generate.ts.eta +16 -0
- package/templates/nuxt/composables/roles.generate.ts.eta +9 -13
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +52 -0
- package/templates/nuxt/composables/sysmessage.generate.ts.eta +1 -1
- package/templates/nuxt/error.vue._eta +4 -2
- package/templates/nuxt/pages/[xorg]/{organization.vue.eta → organization.vue._eta} +38 -9
- package/templates/nuxt/pages/[xorg]/user.vue.eta +12 -9
- package/templates/nuxt/pages/login.vue._eta +4 -1
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +54 -26
- package/templates/nuxt/plugins/70.recently.ts.eta +55 -0
- package/templates/nuxt/providers/my-provider.ts.eta +22 -0
- package/templates/nuxt/server/api/[xorg]/{[...].ts.eta → [...].ts._eta} +47 -21
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +44 -3
- package/templates/nuxt/types/events.ts.eta +3 -2
- package/templates/nuxt/types/others.ts.eta +11 -1
- package/templates/nuxt/types/schema.ts.eta +3 -1
- package/templates/nuxt/types/simpleappinput.ts.eta +1 -1
- package/templates/nuxt/types/user.ts.eta +8 -7
- package/templates/project/jsonschemas/branch.json._eta +1 -0
- package/templates/project/jsonschemas/invoice.json._eta +4 -3
- package/templates/project/jsonschemas/organization.json._eta +2 -2
- package/templates/project/lang/default._json +6 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/components/image/ImageAvatar.vue.eta.vue +0 -38
- /package/templates/nuxt/pages/[xorg]/mobile/docnoformat/{index.vue.eta → index.vue.etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/{index.vue._eta → index.vue._etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/organization/{[id].vue._eta → [id].vue._etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/{pickgroup.vue._eta → pickgroup.vue._etaxxx} +0 -0
- /package/templates/nuxt/pages/[xorg]/mobile/user/{index.vue.eta → index.vue.etaxxx} +0 -0
|
@@ -90,7 +90,9 @@ export class UserContext {
|
|
|
90
90
|
getFullname = () => this.fullname;
|
|
91
91
|
getTenantId = () => this.tenantId;
|
|
92
92
|
getOrgId = () => this.orgId;
|
|
93
|
+
getOrgRecordId = () => this.orgRecordId;
|
|
93
94
|
getBranchId = () => this.branchId;
|
|
95
|
+
getBranchCode = () => this.branchCode;
|
|
94
96
|
getEmail = () => this.email;
|
|
95
97
|
getTimeZone = () => this.timeZone;
|
|
96
98
|
getCountry = () => this.country;
|
|
@@ -218,7 +220,7 @@ export class UserContext {
|
|
|
218
220
|
}
|
|
219
221
|
}
|
|
220
222
|
|
|
221
|
-
userinfo.branchRecordId = myperm.currentbranch[0].
|
|
223
|
+
userinfo.branchRecordId = myperm.currentbranch[0]._id;
|
|
222
224
|
userinfo.branchCode = myperm.currentbranch[0].branchCode;
|
|
223
225
|
userinfo.branchName = myperm.currentbranch[0].branchName;
|
|
224
226
|
userinfo.orgRecordId = myperm.currentorg[0]._id;
|
|
@@ -258,7 +260,7 @@ export class UserContext {
|
|
|
258
260
|
const tokeninfo = jwt.decode(tokenstr);
|
|
259
261
|
this.token = tokenstr;
|
|
260
262
|
this.uid = tokeninfo?.sub ?? '';
|
|
261
|
-
this.email = tokeninfo?.email ??'';
|
|
263
|
+
this.email = tokeninfo?.email ?? '';
|
|
262
264
|
this.uname = tokeninfo?.preferred_username ?? '';
|
|
263
265
|
this.fullname = tokeninfo?.name ?? [];
|
|
264
266
|
this.ssoACL = tokeninfo?.resource_access ?? [];
|
|
@@ -535,7 +537,7 @@ export class UserContext {
|
|
|
535
537
|
};
|
|
536
538
|
|
|
537
539
|
searchInsertedRecordId(collection: string, _id: string) {
|
|
538
|
-
if(!this.modifiedRecords.createds[collection]) return undefined
|
|
540
|
+
if (!this.modifiedRecords.createds[collection]) return undefined;
|
|
539
541
|
return this.modifiedRecords.createds[collection].find(
|
|
540
542
|
(item) => item === _id,
|
|
541
543
|
);
|
|
@@ -608,6 +610,7 @@ export class UserContext {
|
|
|
608
610
|
as: 'org',
|
|
609
611
|
},
|
|
610
612
|
},
|
|
613
|
+
{$unwind:'$org'},
|
|
611
614
|
{
|
|
612
615
|
$lookup: {
|
|
613
616
|
from: 'branch',
|
|
@@ -616,6 +619,7 @@ export class UserContext {
|
|
|
616
619
|
as: 'branch',
|
|
617
620
|
},
|
|
618
621
|
},
|
|
622
|
+
{$unwind:'$branch'},
|
|
619
623
|
],
|
|
620
624
|
},
|
|
621
625
|
};
|
|
@@ -638,7 +642,7 @@ export class UserContext {
|
|
|
638
642
|
activeusers.forEach((u) => {
|
|
639
643
|
const permissions = u.permissions
|
|
640
644
|
.filter((item: any) => {
|
|
641
|
-
return item.org
|
|
645
|
+
return item.org.active && item.branch.active;
|
|
642
646
|
})
|
|
643
647
|
.map((item: any) => {
|
|
644
648
|
return {
|
|
@@ -646,10 +650,11 @@ export class UserContext {
|
|
|
646
650
|
orgId: item.orgId,
|
|
647
651
|
branchId: item.branchId,
|
|
648
652
|
groups: item.groups,
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
+
orgRecordId:item.org._id,
|
|
654
|
+
orgCode: item.org.orgCode,
|
|
655
|
+
orgName: item.org.orgName,
|
|
656
|
+
branchCode: item.branch.branchCode,
|
|
657
|
+
branchName: item.branch.branchName,
|
|
653
658
|
xOrg: this.generateXorg(u.tenantId, item.orgId, item.branchId),
|
|
654
659
|
};
|
|
655
660
|
});
|
|
@@ -724,4 +729,13 @@ export class UserContext {
|
|
|
724
729
|
}
|
|
725
730
|
return data;
|
|
726
731
|
}
|
|
732
|
+
|
|
733
|
+
offsetDate(date: string): string {
|
|
734
|
+
const timestamp = new Date(date).getTime();
|
|
735
|
+
const offsets = this.getOffsetMinute() * 60000;
|
|
736
|
+
const isodate =
|
|
737
|
+
new Date(timestamp + offsets).toISOString().split('.')[0] + 'Z';
|
|
738
|
+
// console.log("Generate schedule ",date,":",appuser.getOffsetMinute()," => ",isodate)
|
|
739
|
+
return isodate;
|
|
740
|
+
}
|
|
727
741
|
}
|
|
@@ -30,6 +30,7 @@ type ServiceType = {
|
|
|
30
30
|
findIdThenPatch: Function;
|
|
31
31
|
setData: Function;
|
|
32
32
|
getAutoComplete: Function;
|
|
33
|
+
fullTextSearch:Function;
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
// @ApiTags(doctype)
|
|
@@ -50,15 +51,22 @@ export class SimpleAppAbstractController<
|
|
|
50
51
|
async _list(appuser: UserContext) {
|
|
51
52
|
return this.service.list(appuser);
|
|
52
53
|
}
|
|
54
|
+
async _fulltextsearch(appuser: UserContext, keyword: string) {
|
|
55
|
+
return this.service.fullTextSearch(
|
|
56
|
+
appuser,
|
|
57
|
+
keyword
|
|
58
|
+
);
|
|
59
|
+
}
|
|
53
60
|
async _search(appuser: UserContext, searchObject: SearchBody) {
|
|
54
61
|
return this.service.search(
|
|
55
62
|
appuser,
|
|
56
63
|
searchObject['filter'],
|
|
57
64
|
searchObject['fields'],
|
|
58
65
|
searchObject['sorts'],
|
|
66
|
+
searchObject['lookup'],
|
|
59
67
|
);
|
|
60
68
|
}
|
|
61
|
-
async _autocomplete(appuser: UserContext, keyword:string,data?:T) {
|
|
69
|
+
async _autocomplete(appuser: UserContext, keyword: string, data?: T) {
|
|
62
70
|
return this.service.getAutoComplete(appuser, keyword, data);
|
|
63
71
|
}
|
|
64
72
|
async _findOne(appuser: UserContext, id: string) {
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { UserContext } from '../commons/user.context';
|
|
8
8
|
import * as sharelibs from '../sharelibs';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
Injectable,
|
|
11
|
+
Inject,
|
|
12
|
+
InternalServerErrorException,
|
|
13
|
+
} from '@nestjs/common';
|
|
10
14
|
import { InjectModel } from '@nestjs/mongoose';
|
|
11
15
|
import * as jsonpath from 'jsonpath';
|
|
12
16
|
import { Model } from 'mongoose';
|
|
@@ -17,7 +21,7 @@ import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
|
|
|
17
21
|
import { AutoincreamentService } from '../../services/autoinc.service';
|
|
18
22
|
import { alldocuments } from '../commons/dicts/documents';
|
|
19
23
|
import { Docnoformat, DocnoformatService } from '../../services/docno.service';
|
|
20
|
-
import { BranchOrganization, Branch,BranchHooks } from '../types/branch.type';
|
|
24
|
+
import { BranchOrganization, Branch, BranchHooks } from '../types/branch.type';
|
|
21
25
|
import {
|
|
22
26
|
DefaultBranchOrganization,
|
|
23
27
|
DefaultBranch,
|
|
@@ -32,9 +36,11 @@ export class BranchProcessor extends SimpleAppService<Branch> {
|
|
|
32
36
|
protected strictIsolation = false;
|
|
33
37
|
protected documentIdentityCode = 'branchCode';
|
|
34
38
|
protected documentIdentityLabel = 'branchName';
|
|
35
|
-
protected hooks: BranchHooks = {
|
|
36
|
-
beforeCreate: async (appuser: UserContext, data: Branch) =>
|
|
37
|
-
|
|
39
|
+
protected hooks: BranchHooks = {
|
|
40
|
+
beforeCreate: async (appuser: UserContext, data: Branch) =>
|
|
41
|
+
await this.branchBeforeCreate(appuser, data),
|
|
42
|
+
afterCreate: async (appuser: UserContext, data: Branch) =>
|
|
43
|
+
await this.branchAfterCreate(appuser, data),
|
|
38
44
|
};
|
|
39
45
|
protected foreignkeys = { organization: ['$.organization._id'] };
|
|
40
46
|
constructor(mydoc: Model<Branch>) {
|
|
@@ -74,7 +80,7 @@ export class BranchProcessor extends SimpleAppService<Branch> {
|
|
|
74
80
|
const docformats = alldocuments.filter((item) => item.docNumber);
|
|
75
81
|
for (let i = 0; i < docformats.length; i++) {
|
|
76
82
|
const doc = docformats[i];
|
|
77
|
-
const pattern =
|
|
83
|
+
const pattern = doc.docNoPattern.replace('@BranchCode',branchCode);
|
|
78
84
|
const formatdata: Docnoformat = {
|
|
79
85
|
_id: crypto.randomUUID(),
|
|
80
86
|
docNoFormatNo: `${doc.docType}-${branchCode}`,
|
|
@@ -32,8 +32,6 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
32
32
|
protected documentIdentityLabel = 'orgName';
|
|
33
33
|
protected strictIsolation = false;
|
|
34
34
|
protected foreignkeys = {};
|
|
35
|
-
protected defaultlogo =
|
|
36
|
-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=';
|
|
37
35
|
protected hooks: OrganizationHooks = {
|
|
38
36
|
beforeCreate: async (appuser: UserContext, data: Organization) =>
|
|
39
37
|
await this.orgBeforeCreate(appuser, data),
|
|
@@ -65,23 +63,22 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
65
63
|
async runGetlogo(appuser: UserContext) {
|
|
66
64
|
const logo = await this.searchLogo(appuser);
|
|
67
65
|
if (logo) return logo.value;
|
|
68
|
-
else return
|
|
66
|
+
else return ''
|
|
69
67
|
}
|
|
70
68
|
|
|
71
69
|
async searchLogo(appuser: UserContext) {
|
|
72
70
|
const keyvaluepair = await this.kvpairService.search(appuser, {
|
|
73
|
-
key: '
|
|
71
|
+
key: 'org-'+appuser.getOrgRecordId(),
|
|
74
72
|
});
|
|
75
73
|
if (keyvaluepair && keyvaluepair.length > 0) return keyvaluepair[0];
|
|
76
74
|
else return null;
|
|
77
75
|
}
|
|
78
|
-
async runUploadlogo(appuser: UserContext, data: KeyValue) {
|
|
79
|
-
// this.setDefaultLogo(data.value);
|
|
76
|
+
async runUploadlogo(appuser: UserContext, data: KeyValue) {
|
|
80
77
|
const key = data.key;
|
|
81
78
|
|
|
82
79
|
let kvdata: Keyvaluepair = await this.searchLogo(appuser);
|
|
83
80
|
if (kvdata) {
|
|
84
|
-
kvdata.value=data.value
|
|
81
|
+
kvdata.value = data.value;
|
|
85
82
|
const res = await this.kvpairService.findIdThenUpdate(
|
|
86
83
|
appuser,
|
|
87
84
|
kvdata._id,
|
|
@@ -95,7 +92,7 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
95
92
|
} else {
|
|
96
93
|
kvdata = {
|
|
97
94
|
_id: crypto.randomUUID(),
|
|
98
|
-
key: '
|
|
95
|
+
key: 'org-'+appuser.getOrgRecordId(),
|
|
99
96
|
value: data.value,
|
|
100
97
|
};
|
|
101
98
|
const res = await this.kvpairService.create(appuser, kvdata);
|
|
@@ -106,10 +103,8 @@ export class OrganizationProcessor extends SimpleAppService<Organization> {
|
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
return
|
|
106
|
+
return ''
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
this.defaultlogo = data;
|
|
114
|
-
}
|
|
109
|
+
|
|
115
110
|
}
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
WorkflowName,
|
|
44
44
|
} from '../types';
|
|
45
45
|
@Injectable()
|
|
46
|
-
export class SimpleAppService<T extends { _id?: string
|
|
46
|
+
export class SimpleAppService<T extends { _id?: string; __v?: number }> {
|
|
47
47
|
@Inject(EventEmitter2)
|
|
48
48
|
protected eventEmitter: EventEmitter2;
|
|
49
49
|
@Inject(CloudApiService)
|
|
@@ -53,7 +53,12 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
53
53
|
protected hooks: DefaultHooks<T> = {};
|
|
54
54
|
protected logger = new Logger();
|
|
55
55
|
protected strictIsolation = true;
|
|
56
|
-
protected jsonschema
|
|
56
|
+
protected jsonschema: any = {
|
|
57
|
+
type: 'object',
|
|
58
|
+
'x-simpleapp-config': {},
|
|
59
|
+
properties: {},
|
|
60
|
+
required: [],
|
|
61
|
+
};
|
|
57
62
|
protected documentIdentityCode = 'code';
|
|
58
63
|
protected documentIdentityLabel = 'label';
|
|
59
64
|
protected documentName = '-unknowndocname-';
|
|
@@ -97,6 +102,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
97
102
|
getRecordId = (): string => this.data._id;
|
|
98
103
|
setSchema = (newschema) => (this.jsonschema = newschema);
|
|
99
104
|
getSchema = () => this.doc.schema.obj;
|
|
105
|
+
getJsonSchema = () => this.jsonschema;
|
|
100
106
|
getHooks = () => this.hooks;
|
|
101
107
|
getData = () => {
|
|
102
108
|
//console.log('thisdata', this.data);
|
|
@@ -224,8 +230,10 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
224
230
|
this.polishIsolationFilter(isolationFilter);
|
|
225
231
|
|
|
226
232
|
Object.assign(pipeline[0]['$match'], isolationFilter);
|
|
227
|
-
|
|
228
|
-
return await this.doc.aggregate(pipeline
|
|
233
|
+
this.logger.verbose(pipeline, `${this.documentName} aggregate:`);
|
|
234
|
+
return await this.doc.aggregate(pipeline, {
|
|
235
|
+
session: appuser.getDBSession(),
|
|
236
|
+
});
|
|
229
237
|
} catch (err) {
|
|
230
238
|
throw new InternalServerErrorException(err);
|
|
231
239
|
}
|
|
@@ -238,8 +246,9 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
238
246
|
async search(
|
|
239
247
|
appuser: UserContext,
|
|
240
248
|
filters: FilterQuery<T>,
|
|
241
|
-
projection:
|
|
249
|
+
projection: string[] = undefined,
|
|
242
250
|
sort: any = undefined,
|
|
251
|
+
lookup: { [key: string]: string } = undefined,
|
|
243
252
|
) {
|
|
244
253
|
try {
|
|
245
254
|
const isolationFilter = { ...this.getIsolationFilter(appuser) };
|
|
@@ -252,24 +261,47 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
252
261
|
await this.hooks.beforeSearch(appuser, newfilters);
|
|
253
262
|
// console.log("before _find",newfilters)
|
|
254
263
|
// console.log("this.doc",this.doc)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
.
|
|
258
|
-
|
|
259
|
-
|
|
264
|
+
let searchResults: T[] = [];
|
|
265
|
+
if (lookup === undefined) {
|
|
266
|
+
this.logger.debug('after search', newfilters);
|
|
267
|
+
searchResults = await this.doc
|
|
268
|
+
.find(newfilters, projection, { session: appuser.getDBSession() })
|
|
269
|
+
.sort(sort);
|
|
270
|
+
} else {
|
|
271
|
+
const pipelines = this.searchToAggregate(
|
|
272
|
+
filters,
|
|
273
|
+
projection,
|
|
274
|
+
sort,
|
|
275
|
+
lookup,
|
|
276
|
+
);
|
|
277
|
+
this.logger.debug('after aggregate', pipelines);
|
|
278
|
+
|
|
279
|
+
searchResults = await this.aggregate(appuser, pipelines);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const list: T[] = searchResults.map((p: T) => {
|
|
260
283
|
return p;
|
|
261
284
|
});
|
|
262
285
|
// console.log("after map",productlist)
|
|
263
|
-
if (this.hooks.afterSearch)
|
|
264
|
-
await this.hooks.afterSearch(appuser, productlist);
|
|
286
|
+
if (this.hooks.afterSearch) await this.hooks.afterSearch(appuser, list);
|
|
265
287
|
|
|
266
288
|
// console.log(products);
|
|
267
|
-
return
|
|
289
|
+
return list;
|
|
268
290
|
} catch (err) {
|
|
269
291
|
throw new BadRequestException(err.message);
|
|
270
292
|
}
|
|
271
293
|
// return this;
|
|
272
294
|
}
|
|
295
|
+
|
|
296
|
+
async fullTextSearch(appuser: UserContext, keyword: string) {
|
|
297
|
+
const isolationFilter = { ...this.getIsolationFilter(appuser) };
|
|
298
|
+
this.polishIsolationFilter(isolationFilter);
|
|
299
|
+
|
|
300
|
+
const filters = { $text: { $search: keyword } };
|
|
301
|
+
const newfilters: FilterQuery<T> = { ...filters, ...isolationFilter };
|
|
302
|
+
|
|
303
|
+
return await this.doc.find(newfilters);
|
|
304
|
+
}
|
|
273
305
|
async findById(appuser: UserContext, id: string) {
|
|
274
306
|
if (this.hooks.beforeFetchRecord)
|
|
275
307
|
await this.hooks.beforeFetchRecord(appuser, id);
|
|
@@ -364,6 +396,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
364
396
|
// result = await newdoc.save()
|
|
365
397
|
try {
|
|
366
398
|
if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
|
|
399
|
+
this.callWebhook(appuser, 'create', result);
|
|
367
400
|
return result as T;
|
|
368
401
|
} catch (err) {
|
|
369
402
|
throw new InternalServerErrorException(
|
|
@@ -416,6 +449,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
416
449
|
ajv.addFormat('text', /.*$/);
|
|
417
450
|
ajv.addFormat('html', /.*$/);
|
|
418
451
|
ajv.addFormat('documentno', /.*$/);
|
|
452
|
+
ajv.addFormat('money', /.*$/);
|
|
419
453
|
|
|
420
454
|
ajv.addKeyword({ keyword: 'x-foreignkey', schemaType: 'string' });
|
|
421
455
|
ajv.addKeyword({ keyword: 'x-simpleapp-config', schemaType: 'object' });
|
|
@@ -524,6 +558,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
524
558
|
if (this.hooks.afterDelete)
|
|
525
559
|
await this.hooks.afterDelete(appuser, deleteresult, id);
|
|
526
560
|
//this.doc.findByIdAndDelete(id);
|
|
561
|
+
this.callWebhook(appuser, 'delete', deletedata);
|
|
527
562
|
return deleteresult;
|
|
528
563
|
} else {
|
|
529
564
|
this.logger.debug('reject query', dependency);
|
|
@@ -541,18 +576,24 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
541
576
|
// };
|
|
542
577
|
|
|
543
578
|
findIdThenUpdate = async (appuser: UserContext, id: string, data: T) => {
|
|
544
|
-
|
|
545
|
-
|
|
579
|
+
|
|
580
|
+
try {
|
|
546
581
|
//version exists, need ensure different only 1
|
|
547
|
-
|
|
548
|
-
throw new
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
data.__v = existingdata.__v+1
|
|
552
|
-
if (!existingdata) {
|
|
553
|
-
throw new NotFoundException(`${id} not found`, 'not found');
|
|
554
|
-
}
|
|
582
|
+
const existingdata = await this.findById(appuser, id);
|
|
583
|
+
if(!existingdata) throw new NotFoundException(`${this.documentName} findIdThenUpdate: _id:${id} not found`, 'not found');
|
|
555
584
|
|
|
585
|
+
this.logger.debug("update id:"+id,this.documentName+' findIdThenUpdate')
|
|
586
|
+
if (typeof data.__v == 'number' && data.__v != existingdata.__v) {
|
|
587
|
+
throw new BadRequestException(
|
|
588
|
+
`You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
this.logger.debug("warn1",existingdata)
|
|
592
|
+
data.__v = existingdata.__v + 1;
|
|
593
|
+
// if (!existingdata) {
|
|
594
|
+
// throw new NotFoundException(`${id} not found`, 'not found');
|
|
595
|
+
// }
|
|
596
|
+
this.logger.debug("warn2")
|
|
556
597
|
if (this.hooks.beforeUpdate)
|
|
557
598
|
await this.hooks.beforeUpdate(appuser, id, data, existingdata);
|
|
558
599
|
|
|
@@ -574,7 +615,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
574
615
|
this.polishIsolationFilter(isolationFilter);
|
|
575
616
|
isolationFilter['_id'] = id;
|
|
576
617
|
this.applyNestedDateTime(appuser, data, 'update');
|
|
577
|
-
|
|
618
|
+
|
|
578
619
|
const result = await this.doc.findOneAndReplace(isolationFilter, data, {
|
|
579
620
|
session: dbsession,
|
|
580
621
|
new: true,
|
|
@@ -582,6 +623,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
582
623
|
appuser.addUpdatedRecordId(this.documentName, data._id);
|
|
583
624
|
if (this.hooks.afterUpdate)
|
|
584
625
|
await this.hooks.afterUpdate(appuser, id, existingdata, result);
|
|
626
|
+
this.callWebhook(appuser, 'update', result);
|
|
585
627
|
return result; // await this.findById(appuser, id);
|
|
586
628
|
} catch (err) {
|
|
587
629
|
this.logger.error(err);
|
|
@@ -599,12 +641,13 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
599
641
|
if (!existingdata) {
|
|
600
642
|
throw new NotFoundException(`${id} not found`, 'not found');
|
|
601
643
|
}
|
|
602
|
-
if(typeof data.__v=='number' && data.__v != existingdata.__v
|
|
603
|
-
throw new BadRequestException(
|
|
644
|
+
if (typeof data.__v == 'number' && data.__v != existingdata.__v) {
|
|
645
|
+
throw new BadRequestException(
|
|
646
|
+
`You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
|
|
647
|
+
);
|
|
604
648
|
}
|
|
605
649
|
|
|
606
|
-
data.__v = existingdata.__v+1
|
|
607
|
-
|
|
650
|
+
data.__v = existingdata.__v + 1;
|
|
608
651
|
|
|
609
652
|
if (this.hooks.beforeUpdate)
|
|
610
653
|
await this.hooks.beforeUpdate(appuser, id, data, existingdata);
|
|
@@ -641,6 +684,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
641
684
|
|
|
642
685
|
if (this.hooks.afterUpdate)
|
|
643
686
|
await this.hooks.afterUpdate(appuser, id, existingdata, result);
|
|
687
|
+
this.callWebhook(appuser, 'update', result);
|
|
644
688
|
return result; //await this.findById(appuser, id);
|
|
645
689
|
} catch (err) {
|
|
646
690
|
throw new InternalServerErrorException(err.message);
|
|
@@ -744,6 +788,7 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
744
788
|
if (this.hooks.afterSetStatus)
|
|
745
789
|
await this.hooks.afterSetStatus(appuser, docstatus, finaldata);
|
|
746
790
|
|
|
791
|
+
this.callWebhook(appuser, docstatus, finaldata);
|
|
747
792
|
return updateresult;
|
|
748
793
|
}
|
|
749
794
|
}
|
|
@@ -928,4 +973,64 @@ export class SimpleAppService<T extends { _id?: string, __v?:number }> {
|
|
|
928
973
|
const pdfresult = await this.printapi.getBase64Pdf(appuser, formatid, id);
|
|
929
974
|
return pdfresult;
|
|
930
975
|
}
|
|
976
|
+
|
|
977
|
+
searchToAggregate(
|
|
978
|
+
filter: FilterQuery<T>,
|
|
979
|
+
columns: string[],
|
|
980
|
+
sort: string[][],
|
|
981
|
+
lookup: { [key: string]: string },
|
|
982
|
+
) {
|
|
983
|
+
const pipelines: PipelineStage[] = [];
|
|
984
|
+
const projection = {};
|
|
985
|
+
// console.log('sortsort', sort);
|
|
986
|
+
|
|
987
|
+
pipelines.push({ $match: filter });
|
|
988
|
+
if (Array.isArray(columns) && columns.length > 0) {
|
|
989
|
+
columns.forEach((col) => {
|
|
990
|
+
projection[col] = 1;
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
const collections = Object.keys(lookup);
|
|
995
|
+
collections.forEach((tokey: string) => {
|
|
996
|
+
const toarr = tokey.split('.');
|
|
997
|
+
const to = toarr[0];
|
|
998
|
+
const foreignField = toarr[1] ?? '_id';
|
|
999
|
+
pipelines.push({
|
|
1000
|
+
$lookup: {
|
|
1001
|
+
from: to,
|
|
1002
|
+
as: '_' + to,
|
|
1003
|
+
localField: lookup[tokey],
|
|
1004
|
+
foreignField: foreignField,
|
|
1005
|
+
},
|
|
1006
|
+
});
|
|
1007
|
+
pipelines.push({ $unwind: '$_' + to });
|
|
1008
|
+
|
|
1009
|
+
if (Object.keys(projection).length > 0) projection['_' + to] = 1;
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
if (Object.keys(projection).length > 0)
|
|
1013
|
+
pipelines.push({ $project: projection });
|
|
1014
|
+
|
|
1015
|
+
if (Array.isArray(sort) && sort.length > 0) {
|
|
1016
|
+
const sortobj = {};
|
|
1017
|
+
sort.forEach((item) => {
|
|
1018
|
+
sortobj[item[0]] = item[1].toLowerCase() == 'asc' ? 1 : -1;
|
|
1019
|
+
});
|
|
1020
|
+
pipelines.push({ $sort: sortobj });
|
|
1021
|
+
}
|
|
1022
|
+
// console.log('pipelinespipelinespipelines', pipelines);
|
|
1023
|
+
|
|
1024
|
+
return pipelines;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
callWebhook(appuser: UserContext, actionName: string, data: any) {
|
|
1028
|
+
this.eventEmitter.emit(
|
|
1029
|
+
'webhook',
|
|
1030
|
+
appuser,
|
|
1031
|
+
this.documentName,
|
|
1032
|
+
actionName,
|
|
1033
|
+
data,
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
931
1036
|
}
|
|
@@ -30,17 +30,19 @@ export type DocumentStatus = {
|
|
|
30
30
|
formula:string //example "jslib.getDocumentSubTotal(@F{$.details})"
|
|
31
31
|
}
|
|
32
32
|
export type SchemaConfig = {
|
|
33
|
-
isolationType:
|
|
33
|
+
isolationType: string
|
|
34
34
|
requiredRoles?:string[]
|
|
35
35
|
pageType?: string
|
|
36
36
|
uniqueKey?:string
|
|
37
37
|
uniqueKeys?:string[][]
|
|
38
38
|
documentTitle?:string
|
|
39
39
|
generateDocumentNumber?:boolean
|
|
40
|
+
docNoPattern?:string
|
|
40
41
|
documentDate?:string
|
|
41
42
|
allStatus?:DocumentStatus[]
|
|
42
43
|
additionalApis?:DocumentApi[]
|
|
43
44
|
additionalAutoCompleteFields ?: string[]
|
|
45
|
+
search?:string[]
|
|
44
46
|
// libs?:ImportLibs[] // both process class and frontend client class will import same lib
|
|
45
47
|
formulas?: Formula[]
|
|
46
48
|
documentType: string
|
|
@@ -160,4 +160,23 @@ export class ProfileController {
|
|
|
160
160
|
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
+
@Post('/tour-complete/:guidename')
|
|
164
|
+
@Roles(Role.User)
|
|
165
|
+
@ApiOperation({
|
|
166
|
+
operationId: 'runTourComplete',
|
|
167
|
+
description: 'complete specific tour guide',
|
|
168
|
+
})
|
|
169
|
+
@ApiResponse({ status: 201, type: Object, description: 'Success' })
|
|
170
|
+
async runTourComplete(
|
|
171
|
+
@AppUser() appuser: UserContext,
|
|
172
|
+
@Param('guidename') guidename: string,
|
|
173
|
+
|
|
174
|
+
) {
|
|
175
|
+
const result = await this.profileservice.runTourComplete(appuser,guidename,);
|
|
176
|
+
if (result) {
|
|
177
|
+
return result;
|
|
178
|
+
} else {
|
|
179
|
+
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
163
182
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Author: Ks Tan
|
|
6
6
|
*/
|
|
7
7
|
import { UserService, User } from './../services/user.service';
|
|
8
|
-
import countrytimezone from 'countries-and-timezones'
|
|
9
|
-
import countryToCurrency, { Currencies, Countries } from
|
|
8
|
+
import countrytimezone from 'countries-and-timezones';
|
|
9
|
+
import countryToCurrency, { Currencies, Countries } from 'country-to-currency';
|
|
10
10
|
import {
|
|
11
11
|
Injectable,
|
|
12
12
|
Scope,
|
|
@@ -91,14 +91,14 @@ export class ProfileService {
|
|
|
91
91
|
appuser: UserContext,
|
|
92
92
|
tenantName: string,
|
|
93
93
|
timeZone: string,
|
|
94
|
-
utcOffset: number
|
|
94
|
+
utcOffset: number,
|
|
95
95
|
) {
|
|
96
96
|
// try{
|
|
97
|
-
const timezonedata = countrytimezone.getCountriesForTimezone(timeZone)[0]
|
|
98
|
-
const countryCode
|
|
99
|
-
const countryName
|
|
100
|
-
const currencyCode = countryToCurrency[countryCode]
|
|
101
|
-
|
|
97
|
+
const timezonedata = countrytimezone.getCountriesForTimezone(timeZone)[0];
|
|
98
|
+
const countryCode = timezonedata['id'];
|
|
99
|
+
const countryName = timezonedata['name'];
|
|
100
|
+
const currencyCode = countryToCurrency[countryCode];
|
|
101
|
+
|
|
102
102
|
appuser.getDBSession().startTransaction();
|
|
103
103
|
const tenantdata: Tenant = {
|
|
104
104
|
tenantId: 1,
|
|
@@ -124,6 +124,7 @@ export class ProfileService {
|
|
|
124
124
|
orgName: tenantName,
|
|
125
125
|
active: true,
|
|
126
126
|
orgCode: 'HQ',
|
|
127
|
+
registrationNo: '000000',
|
|
127
128
|
timeZone: timeZone,
|
|
128
129
|
offsetMinute: utcOffset,
|
|
129
130
|
currency: currencyCode,
|
|
@@ -143,6 +144,13 @@ export class ProfileService {
|
|
|
143
144
|
branchId: 1,
|
|
144
145
|
branchCode: 'HQ',
|
|
145
146
|
branchName: tenantName,
|
|
147
|
+
street1: '11,my street 1',
|
|
148
|
+
street2: 'my street 2',
|
|
149
|
+
postcode: '11111',
|
|
150
|
+
city: 'my city',
|
|
151
|
+
tel: '99999999999',
|
|
152
|
+
email: 'change-email@email.com',
|
|
153
|
+
region: 'my region',
|
|
146
154
|
country: countryName,
|
|
147
155
|
active: true,
|
|
148
156
|
orgId: orgResult.orgId,
|
|
@@ -245,4 +253,21 @@ export class ProfileService {
|
|
|
245
253
|
async getSession(appuser: UserContext) {
|
|
246
254
|
return 'OK';
|
|
247
255
|
}
|
|
256
|
+
|
|
257
|
+
async runTourComplete(appuser: UserContext, guideName: string) {
|
|
258
|
+
if (!guideName || guideName == '')
|
|
259
|
+
throw new BadRequestException('undefine guideName');
|
|
260
|
+
|
|
261
|
+
const user = await this.usersvc.findById(appuser, appuser.getId());
|
|
262
|
+
if (!Array.isArray(user.completedTours)) {
|
|
263
|
+
user.completedTours = [];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!user.completedTours.includes(guideName)) {
|
|
267
|
+
user.completedTours.push(guideName);
|
|
268
|
+
const res = await this.usersvc.findIdThenUpdate(appuser, user._id, user);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return 'ok';
|
|
272
|
+
}
|
|
248
273
|
}
|