@rentcheck/biz 1.0.63 → 1.0.65

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.
Files changed (40) hide show
  1. package/dist/permissions/inspections.d.ts +8 -1
  2. package/dist/permissions/inspections.js +17 -1
  3. package/dist/rules/inspections/index.d.ts +33 -4
  4. package/dist/rules/inspections/index.js +395 -2
  5. package/dist/rules/teammates/index.js +1 -1
  6. package/dist/utils/dates/index.d.ts +3 -1
  7. package/dist/utils/dates/index.js +11 -3
  8. package/dist/utils/index.d.ts +1 -0
  9. package/dist/utils/index.js +2 -1
  10. package/dist/utils/inspection-features/sorting.d.ts +1 -1
  11. package/dist/utils/inspection-templates/build-template-features.js +1 -0
  12. package/dist/utils/inspection-templates/common.d.ts +15 -0
  13. package/dist/utils/inspection-templates/common.js +42 -1
  14. package/dist/utils/inspection-templates/template-logic.d.ts +2 -2
  15. package/dist/utils/inspections/index.d.ts +2 -0
  16. package/dist/utils/inspections/index.js +13 -0
  17. package/dist/utils/permission-groups/index.d.ts +2 -0
  18. package/dist/utils/permission-groups/index.js +11 -0
  19. package/dist/utils/properties/index.d.ts +3 -0
  20. package/dist/utils/properties/index.js +30 -0
  21. package/dist/utils/subscriptions/index.d.ts +1 -0
  22. package/dist/utils/subscriptions/index.js +8 -1
  23. package/dist/utils/tenants/index.d.ts +2 -2
  24. package/dist/utils/tenants/index.js +3 -3
  25. package/package.json +5 -1
  26. package/src/permissions/inspections.ts +47 -1
  27. package/src/rules/inspections/index.ts +450 -5
  28. package/src/rules/teammates/index.ts +1 -1
  29. package/src/utils/dates/index.ts +10 -1
  30. package/src/utils/index.ts +1 -0
  31. package/src/utils/inspection-features/sorting.ts +2 -2
  32. package/src/utils/inspection-templates/build-template-features.ts +2 -0
  33. package/src/utils/inspection-templates/common.ts +51 -0
  34. package/src/utils/inspection-templates/template-logic.ts +2 -2
  35. package/src/utils/inspections/index.ts +15 -0
  36. package/src/utils/permission-groups/index.ts +11 -0
  37. package/src/utils/properties/index.ts +47 -0
  38. package/src/utils/subscriptions/index.ts +10 -0
  39. package/src/utils/tenants/index.ts +6 -6
  40. package/tsconfig.tsbuildinfo +1 -1
@@ -1,5 +1,12 @@
1
- import { AccountSettings, ApiSubscription } from '@rentcheck/types';
1
+ import { AccountSettings, ApiSubscription, Inspection, PermissionGroup, Profile } from '@rentcheck/types';
2
2
  export declare const canRecordVideo: (subscription?: ApiSubscription | null) => boolean;
3
3
  export declare const canTake360Photos: (subscription?: ApiSubscription | null) => boolean;
4
4
  export declare const canRenterReportMaintenance: (accountSettings?: AccountSettings | null, subscription?: ApiSubscription | null) => boolean;
5
5
  export declare const areFlagDefaultPhotosEnabled: (accountSettings?: AccountSettings | null) => boolean;
6
+ type CanAccessParams = {
7
+ user: Profile;
8
+ inspection: Inspection;
9
+ permissionGroups: PermissionGroup[];
10
+ };
11
+ export declare const canAccess: ({ user, inspection, permissionGroups, }: CanAccessParams) => boolean;
12
+ export {};
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.areFlagDefaultPhotosEnabled = exports.canRenterReportMaintenance = exports.canTake360Photos = exports.canRecordVideo = void 0;
26
+ exports.canAccess = exports.areFlagDefaultPhotosEnabled = exports.canRenterReportMaintenance = exports.canTake360Photos = exports.canRecordVideo = void 0;
27
27
  const Utils = __importStar(require("../utils"));
28
28
  const canRecordVideo = (subscription) => {
29
29
  if (!subscription) {
@@ -61,3 +61,19 @@ const areFlagDefaultPhotosEnabled = (accountSettings) => {
61
61
  return accountSettings.is_maintenance_flag_default_photos_enabled;
62
62
  };
63
63
  exports.areFlagDefaultPhotosEnabled = areFlagDefaultPhotosEnabled;
64
+ const canAccess = ({ user, inspection, permissionGroups, }) => {
65
+ var _a, _b;
66
+ const userIdIsInAuthorizedUserIds = inspection.authorized_user_ids.includes(user.id);
67
+ if (userIdIsInAuthorizedUserIds)
68
+ return true;
69
+ const userOrgIds = user.organizations.map((org) => org.id);
70
+ const userOrOrgsHaveAccessToInspection = userOrgIds.some((orgId) => inspection.authorized_user_ids.includes(orgId));
71
+ const validInspectionTemplatesForUser = (_b = (_a = permissionGroups === null || permissionGroups === void 0 ? void 0 : permissionGroups.map((permissionGroup) => permissionGroup.inspection_templates)) === null || _a === void 0 ? void 0 : _a.flat()) !== null && _b !== void 0 ? _b : [];
72
+ const userPermissionGroupsHaveAccessToInspectionTemplate = validInspectionTemplatesForUser === null || validInspectionTemplatesForUser === void 0 ? void 0 : validInspectionTemplatesForUser.includes(inspection.inspection_template.id);
73
+ if (userOrOrgsHaveAccessToInspection &&
74
+ userPermissionGroupsHaveAccessToInspectionTemplate) {
75
+ return true;
76
+ }
77
+ return false;
78
+ };
79
+ exports.canAccess = canAccess;
@@ -1,4 +1,33 @@
1
- import { ApiInspectionWithTemplate, Profile } from '@rentcheck/types';
2
- export declare const shouldShowLibraryOption: (inspection?: ApiInspectionWithTemplate, profile?: Profile) => boolean;
3
- export declare const shouldShow360Option: (inspection?: ApiInspectionWithTemplate) => boolean;
4
- export declare const shouldShowVideoOption: (inspection?: ApiInspectionWithTemplate, profile?: Profile) => boolean;
1
+ import { APIProperty, ApiInspection, ApiInspectionWithTemplate, Feature, Profile } from '@rentcheck/types';
2
+ export declare const shouldShowLibraryOption: (inspection?: ApiInspection, profile?: Profile) => boolean;
3
+ export declare const shouldShow360Option: (inspection?: ApiInspection) => boolean;
4
+ export declare const shouldShowVideoOption: (inspection?: ApiInspection, profile?: Profile, feature?: Feature) => boolean;
5
+ export declare const canApprove: (inspection: ApiInspection, profile?: Profile) => boolean;
6
+ export declare const canReject: (inspection: ApiInspection, profile?: Profile) => boolean;
7
+ export declare const canEditLabel: (inspection: ApiInspection) => boolean;
8
+ export declare const canCancelReviewRequest: (inspection: ApiInspection) => boolean;
9
+ export declare const canCancelRevisionRequest: (inspection: ApiInspection) => boolean;
10
+ export declare const canArchive: (inspection: ApiInspection) => boolean;
11
+ export declare const canUnarchive: (inspection: ApiInspection) => boolean;
12
+ export declare const canDelete: (inspection: ApiInspection) => boolean;
13
+ export declare const canSendReminder: (inspection: ApiInspection) => boolean;
14
+ export declare const canMarkAsComplete: (inspection: ApiInspection) => boolean;
15
+ export declare const canDownloadImages: (inspection: ApiInspection, features: Feature[]) => boolean;
16
+ export declare const canDownloadMaintenanceFlags: (inspection: ApiInspection, features: Feature[]) => boolean;
17
+ export declare const canRequestSignatures: (inspection: ApiInspection) => boolean;
18
+ export declare const canCreateMaintenanceReport: (inspection: ApiInspection, features: Feature[]) => boolean;
19
+ export declare const canShowCompletedDate: (inspection: ApiInspection) => boolean;
20
+ export declare const canShowCompletedBy: (inspection: ApiInspection) => boolean;
21
+ export declare const canShowDueDate: (inspection: ApiInspection) => boolean;
22
+ export declare const canShowAssignee: (inspection: ApiInspection) => boolean;
23
+ export declare const canEditAssignee: (inspection: ApiInspection) => boolean;
24
+ export declare const canShowInviteDate: (inspection: ApiInspection) => boolean;
25
+ export declare const canShowRevisionDueDate: (inspection: ApiInspection) => boolean;
26
+ export declare const canShowReviewDueDate: (inspection: ApiInspection) => boolean;
27
+ export declare const canShowHyperlinkToPropertyPage: (inspection: ApiInspection) => boolean;
28
+ export declare const canEditDueDate: (inspection: ApiInspection) => boolean;
29
+ export declare const canShare: (inspection: ApiInspection) => boolean;
30
+ export declare const canDownloadReport: (inspection: ApiInspection) => boolean;
31
+ export declare const canCopyInspectionDeeplink: (inspection: ApiInspection) => boolean;
32
+ export declare const canManualSync: (inspection: ApiInspectionWithTemplate, property: APIProperty) => boolean;
33
+ export declare const canShowSyncStatus: (inspection: ApiInspectionWithTemplate) => boolean;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.shouldShowVideoOption = exports.shouldShow360Option = exports.shouldShowLibraryOption = void 0;
3
+ exports.canShowSyncStatus = exports.canManualSync = exports.canCopyInspectionDeeplink = exports.canDownloadReport = exports.canShare = exports.canEditDueDate = exports.canShowHyperlinkToPropertyPage = exports.canShowReviewDueDate = exports.canShowRevisionDueDate = exports.canShowInviteDate = exports.canEditAssignee = exports.canShowAssignee = exports.canShowDueDate = exports.canShowCompletedBy = exports.canShowCompletedDate = exports.canCreateMaintenanceReport = exports.canRequestSignatures = exports.canDownloadMaintenanceFlags = exports.canDownloadImages = exports.canMarkAsComplete = exports.canSendReminder = exports.canDelete = exports.canUnarchive = exports.canArchive = exports.canCancelRevisionRequest = exports.canCancelReviewRequest = exports.canEditLabel = exports.canReject = exports.canApprove = exports.shouldShowVideoOption = exports.shouldShow360Option = exports.shouldShowLibraryOption = void 0;
4
4
  const utils_1 = require("../../utils");
5
+ const inspections_1 = require("../../utils/inspections");
5
6
  const shouldShowLibraryOption = (inspection, profile) => {
6
7
  if (!inspection)
7
8
  return false;
@@ -16,7 +17,9 @@ const shouldShow360Option = (inspection) => {
16
17
  : false;
17
18
  };
18
19
  exports.shouldShow360Option = shouldShow360Option;
19
- const shouldShowVideoOption = (inspection, profile) => {
20
+ const shouldShowVideoOption = (inspection, profile, feature) => {
21
+ if (feature === null || feature === void 0 ? void 0 : feature.is_video_enabled)
22
+ return true;
20
23
  if (!inspection)
21
24
  return false;
22
25
  return inspection.settings.can_record_video && !utils_1.Users.isRenter(profile)
@@ -24,3 +27,393 @@ const shouldShowVideoOption = (inspection, profile) => {
24
27
  : false;
25
28
  };
26
29
  exports.shouldShowVideoOption = shouldShowVideoOption;
30
+ const canApprove = (inspection, profile) => {
31
+ const validStatuses = [
32
+ 'Awaiting Review',
33
+ 'Revision Review',
34
+ ];
35
+ if (!profile)
36
+ return false;
37
+ if (!validStatuses.includes(inspection.inspection_status))
38
+ return false;
39
+ if (inspection.role !== 'creator')
40
+ return false;
41
+ return true;
42
+ };
43
+ exports.canApprove = canApprove;
44
+ const canReject = (inspection, profile) => {
45
+ const validStatuses = [
46
+ 'Awaiting Review',
47
+ 'Revision Review',
48
+ ];
49
+ if (!profile)
50
+ return false;
51
+ if (!validStatuses.includes(inspection.inspection_status))
52
+ return false;
53
+ if (inspection.role !== 'creator')
54
+ return false;
55
+ if (inspection.review)
56
+ return false;
57
+ return true;
58
+ };
59
+ exports.canReject = canReject;
60
+ const canEditLabel = (inspection) => {
61
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
62
+ return true;
63
+ const validRoles = ['creator', 'self-perform'];
64
+ if (!validRoles.includes(inspection.role))
65
+ return false;
66
+ return true;
67
+ };
68
+ exports.canEditLabel = canEditLabel;
69
+ const canCancelReviewRequest = (inspection) => {
70
+ const validRoles = ['creator'];
71
+ if (!validRoles.includes(inspection.role))
72
+ return false;
73
+ if (inspection.inspection_status !== 'In Review')
74
+ return false;
75
+ if (inspection.assigned_recipients.type !== 'emails')
76
+ return false;
77
+ return true;
78
+ };
79
+ exports.canCancelReviewRequest = canCancelReviewRequest;
80
+ const canCancelRevisionRequest = (inspection) => {
81
+ const validRoles = ['creator'];
82
+ if (!validRoles.includes(inspection.role))
83
+ return false;
84
+ if (inspection.inspection_status !== 'Revision Requested')
85
+ return false;
86
+ return true;
87
+ };
88
+ exports.canCancelRevisionRequest = canCancelRevisionRequest;
89
+ const canArchive = (inspection) => {
90
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
91
+ return true;
92
+ const validRoles = ['creator', 'self-perform'];
93
+ if (!validRoles.includes(inspection.role))
94
+ return false;
95
+ if (inspection.archived)
96
+ return false;
97
+ return true;
98
+ };
99
+ exports.canArchive = canArchive;
100
+ const canUnarchive = (inspection) => {
101
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
102
+ return true;
103
+ const validRoles = ['creator', 'self-perform'];
104
+ if (!validRoles.includes(inspection.role))
105
+ return false;
106
+ if (!inspection.archived)
107
+ return false;
108
+ return true;
109
+ };
110
+ exports.canUnarchive = canUnarchive;
111
+ const canDelete = (inspection) => {
112
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
113
+ return true;
114
+ const validRoles = ['creator', 'self-perform'];
115
+ const validStatuses = ['Scheduled', 'Not Started'];
116
+ if (!validRoles.includes(inspection.role))
117
+ return false;
118
+ if (!validStatuses.includes(inspection.inspection_status))
119
+ return false;
120
+ return true;
121
+ };
122
+ exports.canDelete = canDelete;
123
+ const canSendReminder = (inspection) => {
124
+ const validRoles = ['creator'];
125
+ const validStatuses = [
126
+ 'Not Started',
127
+ 'Started',
128
+ 'Revision Requested',
129
+ ];
130
+ if (!validRoles.includes(inspection.role))
131
+ return false;
132
+ if (!validStatuses.includes(inspection.inspection_status))
133
+ return false;
134
+ return true;
135
+ };
136
+ exports.canSendReminder = canSendReminder;
137
+ const canMarkAsComplete = (inspection) => {
138
+ const validRoles = ['creator', 'self-perform'];
139
+ const validStatuses = [
140
+ 'Started',
141
+ 'Revision Requested',
142
+ ];
143
+ if (!validRoles.includes(inspection.role))
144
+ return false;
145
+ if (!validStatuses.includes(inspection.inspection_status))
146
+ return false;
147
+ return true;
148
+ };
149
+ exports.canMarkAsComplete = canMarkAsComplete;
150
+ const canDownloadImages = (inspection, features) => {
151
+ const validStatuses = [
152
+ 'In Review',
153
+ 'Completed',
154
+ 'Awaiting Review',
155
+ 'Revision Review',
156
+ 'Approved',
157
+ ];
158
+ if (!validStatuses.includes(inspection.inspection_status))
159
+ return false;
160
+ if (!features.some((f) => f.images.length > 0 || f.videos.length > 0))
161
+ return false;
162
+ return true;
163
+ };
164
+ exports.canDownloadImages = canDownloadImages;
165
+ const canDownloadMaintenanceFlags = (inspection, features) => {
166
+ const validStatuses = [
167
+ 'In Review',
168
+ 'Completed',
169
+ 'Awaiting Review',
170
+ 'Revision Review',
171
+ 'Approved',
172
+ ];
173
+ if (!validStatuses.includes(inspection.inspection_status))
174
+ return false;
175
+ if (!features.some((f) => f.maintenance_flags.length > 0))
176
+ return false;
177
+ return true;
178
+ };
179
+ exports.canDownloadMaintenanceFlags = canDownloadMaintenanceFlags;
180
+ const canRequestSignatures = (inspection) => {
181
+ const validRoles = ['creator', 'self-perform'];
182
+ const validStatuses = [
183
+ 'In Review',
184
+ 'Completed',
185
+ 'Awaiting Review',
186
+ 'Revision Review',
187
+ 'Approved',
188
+ ];
189
+ if (!validRoles.includes(inspection.role))
190
+ return false;
191
+ if (!validStatuses.includes(inspection.inspection_status))
192
+ return false;
193
+ return true;
194
+ };
195
+ exports.canRequestSignatures = canRequestSignatures;
196
+ const canCreateMaintenanceReport = (inspection, features) => {
197
+ const validRoles = ['creator', 'self-perform'];
198
+ const validStatuses = [
199
+ 'In Review',
200
+ 'Completed',
201
+ 'Awaiting Review',
202
+ 'Revision Review',
203
+ 'Approved',
204
+ ];
205
+ if (!validRoles.includes(inspection.role))
206
+ return false;
207
+ if (!validStatuses.includes(inspection.inspection_status))
208
+ return false;
209
+ if (!features.some((f) => f.maintenance_flags.length > 0))
210
+ return false;
211
+ return true;
212
+ };
213
+ exports.canCreateMaintenanceReport = canCreateMaintenanceReport;
214
+ const canShowCompletedDate = (inspection) => {
215
+ const validStatuses = [
216
+ 'Awaiting Review',
217
+ 'Completed',
218
+ 'Revision Requested',
219
+ 'Revision Review',
220
+ 'In Review',
221
+ 'Approved',
222
+ ];
223
+ if (!validStatuses.includes(inspection.inspection_status))
224
+ return false;
225
+ if (!inspection.completed_date)
226
+ return false;
227
+ return true;
228
+ };
229
+ exports.canShowCompletedDate = canShowCompletedDate;
230
+ const canShowCompletedBy = (inspection) => {
231
+ const validStatuses = [
232
+ 'Awaiting Review',
233
+ 'Completed',
234
+ 'Revision Requested',
235
+ 'Revision Review',
236
+ 'In Review',
237
+ 'Approved',
238
+ ];
239
+ if (!validStatuses.includes(inspection.inspection_status))
240
+ return false;
241
+ if (!inspection.completed_by)
242
+ return false;
243
+ return true;
244
+ };
245
+ exports.canShowCompletedBy = canShowCompletedBy;
246
+ const canShowDueDate = (inspection) => {
247
+ const validStatuses = [
248
+ 'Scheduled',
249
+ 'Not Started',
250
+ 'Started',
251
+ ];
252
+ if (!validStatuses.includes(inspection.inspection_status))
253
+ return false;
254
+ return true;
255
+ };
256
+ exports.canShowDueDate = canShowDueDate;
257
+ const canShowAssignee = (inspection) => {
258
+ const validStatuses = [
259
+ 'Scheduled',
260
+ 'Not Started',
261
+ 'Started',
262
+ ];
263
+ if (!validStatuses.includes(inspection.inspection_status))
264
+ return false;
265
+ return true;
266
+ };
267
+ exports.canShowAssignee = canShowAssignee;
268
+ const canEditAssignee = (inspection) => {
269
+ if (!(0, exports.canShowAssignee)(inspection))
270
+ return false;
271
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
272
+ return true;
273
+ const validRoles = ['creator', 'self-perform'];
274
+ if (!validRoles.includes(inspection.role))
275
+ return false;
276
+ return true;
277
+ };
278
+ exports.canEditAssignee = canEditAssignee;
279
+ const canShowInviteDate = (inspection) => {
280
+ const validStatuses = ['Scheduled'];
281
+ const validAssigneeTypes = [
282
+ 'emails',
283
+ 'residents',
284
+ 'teammates',
285
+ ];
286
+ if (!validStatuses.includes(inspection.inspection_status))
287
+ return false;
288
+ if (!validAssigneeTypes.includes(inspection.assigned_recipients.type))
289
+ return false;
290
+ if (!inspection.invite_date)
291
+ return false;
292
+ return true;
293
+ };
294
+ exports.canShowInviteDate = canShowInviteDate;
295
+ const canShowRevisionDueDate = (inspection) => {
296
+ var _a;
297
+ const validStatuses = ['Revision Requested'];
298
+ if (!validStatuses.includes(inspection.inspection_status))
299
+ return false;
300
+ if (!((_a = inspection.rejection) === null || _a === void 0 ? void 0 : _a.due_date))
301
+ return false;
302
+ return true;
303
+ };
304
+ exports.canShowRevisionDueDate = canShowRevisionDueDate;
305
+ const canShowReviewDueDate = (inspection) => {
306
+ var _a;
307
+ const validStatuses = ['In Review'];
308
+ if (!validStatuses.includes(inspection.inspection_status))
309
+ return false;
310
+ if (!((_a = inspection.review) === null || _a === void 0 ? void 0 : _a.due_date))
311
+ return false;
312
+ return true;
313
+ };
314
+ exports.canShowReviewDueDate = canShowReviewDueDate;
315
+ const canShowHyperlinkToPropertyPage = (inspection) => {
316
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
317
+ return true;
318
+ const validRoles = ['creator', 'self-perform'];
319
+ if (!validRoles.includes(inspection.role))
320
+ return false;
321
+ return true;
322
+ };
323
+ exports.canShowHyperlinkToPropertyPage = canShowHyperlinkToPropertyPage;
324
+ const canEditDueDate = (inspection) => {
325
+ if (!(0, exports.canShowDueDate)(inspection))
326
+ return false;
327
+ const validRoles = ['creator', 'self-perform'];
328
+ if (!validRoles.includes(inspection.role))
329
+ return false;
330
+ return true;
331
+ };
332
+ exports.canEditDueDate = canEditDueDate;
333
+ const canShare = (inspection) => {
334
+ const validStatuses = [
335
+ 'In Review',
336
+ 'Completed',
337
+ 'Awaiting Review',
338
+ 'Revision Review',
339
+ 'Approved',
340
+ ];
341
+ if (!validStatuses.includes(inspection.inspection_status))
342
+ return false;
343
+ return true;
344
+ };
345
+ exports.canShare = canShare;
346
+ const canDownloadReport = (inspection) => {
347
+ const validStatuses = [
348
+ 'In Review',
349
+ 'Completed',
350
+ 'Awaiting Review',
351
+ 'Revision Review',
352
+ 'Approved',
353
+ ];
354
+ if (!validStatuses.includes(inspection.inspection_status))
355
+ return false;
356
+ return true;
357
+ };
358
+ exports.canDownloadReport = canDownloadReport;
359
+ const canCopyInspectionDeeplink = (inspection) => {
360
+ const validStatuses = [
361
+ 'Scheduled',
362
+ 'Not Started',
363
+ 'Started',
364
+ 'Revision Requested',
365
+ ];
366
+ if (!validStatuses.includes(inspection.inspection_status))
367
+ return false;
368
+ return true;
369
+ };
370
+ exports.canCopyInspectionDeeplink = canCopyInspectionDeeplink;
371
+ const canManualSync = (inspection, property) => {
372
+ /**
373
+ * If the property is not synced to either provider we don't
374
+ * have anywhere to sync the inspection to.
375
+ */
376
+ if (!property.rentmanager_sync && !property.appfolio_sync)
377
+ return false;
378
+ /**
379
+ * if the inspection has already been synced and we registered
380
+ * no errors, we don't need to show the button. Manual sync is
381
+ * only intended to be shown as an initial sync or a retry.
382
+ */
383
+ if (inspection.sync_data && !inspection.sync_data.error)
384
+ return false;
385
+ /**
386
+ * Only inspections that are Completed or In Review can be synced.
387
+ */
388
+ const validStatuses = [
389
+ 'In Review',
390
+ 'Completed',
391
+ 'Awaiting Review',
392
+ 'Revision Review',
393
+ 'Approved',
394
+ ];
395
+ if (!validStatuses.includes(inspection.inspection_status))
396
+ return false;
397
+ return true;
398
+ };
399
+ exports.canManualSync = canManualSync;
400
+ const canShowSyncStatus = (inspection) => {
401
+ if (!inspection.sync_data)
402
+ return false;
403
+ const validStatuses = [
404
+ 'In Review',
405
+ 'Completed',
406
+ 'Awaiting Review',
407
+ 'Revision Review',
408
+ 'Approved',
409
+ ];
410
+ if (!validStatuses.includes(inspection.inspection_status))
411
+ return false;
412
+ if ((0, inspections_1.userIsInvitedTeammate)(inspection))
413
+ return true;
414
+ const validRoles = ['creator', 'self-perform'];
415
+ if (!validRoles.includes(inspection.role))
416
+ return false;
417
+ return true;
418
+ };
419
+ exports.canShowSyncStatus = canShowSyncStatus;
@@ -7,7 +7,7 @@ const canAccess = (user, subscription) => {
7
7
  return false;
8
8
  if (!user)
9
9
  return false;
10
- return user.organizations.some((org) => org.role === 'admin');
10
+ return true;
11
11
  };
12
12
  exports.canAccess = canAccess;
13
13
  const canEdit = (user, subscription) => {
@@ -1,2 +1,4 @@
1
+ import { Timestamp } from '@rentcheck/types';
1
2
  export type ParseDateDatabaseType = 'firestore';
2
- export declare const parseDate: (fromDatabase: ParseDateDatabaseType, date: any, defaultReturnValue?: any) => any;
3
+ export declare const parse: (fromDatabase: ParseDateDatabaseType, date: any, defaultReturnValue?: any) => any;
4
+ export declare const buildDateFromApiOrFirebase: (a?: Timestamp | string) => Date;
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.parseDate = void 0;
6
+ exports.buildDateFromApiOrFirebase = exports.parse = void 0;
7
7
  const lodash_1 = __importDefault(require("lodash"));
8
- const parseDate = (fromDatabase, date, defaultReturnValue = null) => {
8
+ const parse = (fromDatabase, date, defaultReturnValue = null) => {
9
9
  if (!date || lodash_1.default.isEmpty(date))
10
10
  return defaultReturnValue;
11
11
  if (fromDatabase === 'firestore') {
@@ -19,4 +19,12 @@ const parseDate = (fromDatabase, date, defaultReturnValue = null) => {
19
19
  }
20
20
  throw new Error(`fromDatabase (${fromDatabase}) not suported!`);
21
21
  };
22
- exports.parseDate = parseDate;
22
+ exports.parse = parse;
23
+ const buildDateFromApiOrFirebase = (a) => {
24
+ if (!a)
25
+ return undefined;
26
+ if (typeof a === 'string')
27
+ return new Date(a);
28
+ return a.toDate();
29
+ };
30
+ exports.buildDateFromApiOrFirebase = buildDateFromApiOrFirebase;
@@ -2,6 +2,7 @@ export * as Dates from './dates';
2
2
  export * as Helpers from './helpers';
3
3
  export * as InspectionFeatures from './inspection-features';
4
4
  export * as InspectionTemplates from './inspection-templates';
5
+ export * as PermissionGroups from './permission-groups';
5
6
  export * as Properties from './properties';
6
7
  export * as Subscriptions from './subscriptions';
7
8
  export * as Tenants from './tenants';
@@ -23,11 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.Users = exports.Tenants = exports.Subscriptions = exports.Properties = exports.InspectionTemplates = exports.InspectionFeatures = exports.Helpers = exports.Dates = void 0;
26
+ exports.Users = exports.Tenants = exports.Subscriptions = exports.Properties = exports.PermissionGroups = exports.InspectionTemplates = exports.InspectionFeatures = exports.Helpers = exports.Dates = void 0;
27
27
  exports.Dates = __importStar(require("./dates"));
28
28
  exports.Helpers = __importStar(require("./helpers"));
29
29
  exports.InspectionFeatures = __importStar(require("./inspection-features"));
30
30
  exports.InspectionTemplates = __importStar(require("./inspection-templates"));
31
+ exports.PermissionGroups = __importStar(require("./permission-groups"));
31
32
  exports.Properties = __importStar(require("./properties"));
32
33
  exports.Subscriptions = __importStar(require("./subscriptions"));
33
34
  exports.Tenants = __importStar(require("./tenants"));
@@ -1,6 +1,6 @@
1
1
  import { Feature, InspectionTemplate } from '@rentcheck/types';
2
2
  export declare const sectionCanExistMultipleTimes: (sectionName: string) => boolean;
3
- export declare const sortFeaturesBySection: <T extends Feature>(features: T[], template: InspectionTemplate) => T[];
3
+ export declare const sortFeaturesBySection: <T extends Feature>(features: T[], template: Pick<InspectionTemplate, 'sections'>) => T[];
4
4
  /**
5
5
  * Converts the template room name from plural to singular, this is to
6
6
  * account for legacy functionality where the template section name is
@@ -38,6 +38,7 @@ const createFeaturesFromSection = (inspection, section, sectionName, sectionName
38
38
  reference_photos: [],
39
39
  number_of_photos_required: 1,
40
40
  questions: [],
41
+ is_video_enabled: true,
41
42
  };
42
43
  if (section.type === 'room') {
43
44
  basicFeatureProps.description =
@@ -1,3 +1,4 @@
1
+ import { ApiInspectionTemplateDigest, InspectionTemplate } from '@rentcheck/types';
1
2
  /**
2
3
  * Converts the template room name from plural to singular, this is to
3
4
  * account for legacy functionality where the template section name is
@@ -34,3 +35,17 @@ export declare const parseSelectedSectionName: (name: string) => string;
34
35
  * @returns the updated section name, e.g. "First Floor", "Second Bedroom"
35
36
  */
36
37
  export declare const addOrdinalToSectionName: (sectionName: string, number: number) => string;
38
+ /**
39
+ * Function used to determine the order of 2 inspection templates.
40
+ * Follows this criteria:
41
+ * 1. RentCheck templates should always be at the bottom
42
+ * 2. Custom templates should be sorted alphabetically
43
+ * 3. RentCheck templates should be sorted by created date
44
+ *
45
+ * @param a an inspection template
46
+ * @param b a different inspection template
47
+ * @returns It is expected to return a negative value if the first argument
48
+ * is less than the second argument, zero if they're equal, and a positive
49
+ * value otherwise
50
+ */
51
+ export declare const sortFn: (a: InspectionTemplate | ApiInspectionTemplateDigest, b: InspectionTemplate | ApiInspectionTemplateDigest) => number;
@@ -23,8 +23,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.addOrdinalToSectionName = exports.parseSelectedSectionName = exports.sectionCanExistMultipleTimes = exports.parseTemplateRoomName = void 0;
26
+ exports.sortFn = exports.addOrdinalToSectionName = exports.parseSelectedSectionName = exports.sectionCanExistMultipleTimes = exports.parseTemplateRoomName = void 0;
27
27
  const Constants = __importStar(require("../../constants"));
28
+ const dates_1 = require("../dates");
28
29
  /**
29
30
  * Converts the template room name from plural to singular, this is to
30
31
  * account for legacy functionality where the template section name is
@@ -129,3 +130,43 @@ const addOrdinalToSectionName = (sectionName, number) => {
129
130
  return `${Constants.Rooms.ordinalPrefixes[number]} ${sectionName}`;
130
131
  };
131
132
  exports.addOrdinalToSectionName = addOrdinalToSectionName;
133
+ /**
134
+ * Function used to determine the order of 2 inspection templates.
135
+ * Follows this criteria:
136
+ * 1. RentCheck templates should always be at the bottom
137
+ * 2. Custom templates should be sorted alphabetically
138
+ * 3. RentCheck templates should be sorted by created date
139
+ *
140
+ * @param a an inspection template
141
+ * @param b a different inspection template
142
+ * @returns It is expected to return a negative value if the first argument
143
+ * is less than the second argument, zero if they're equal, and a positive
144
+ * value otherwise
145
+ */
146
+ const sortFn = (a, b) => {
147
+ /**
148
+ * If both templates are rentcheck templates then the order is pre-determined
149
+ * in the requirements for REN-3522. In this case we sort by created date as this
150
+ * order is already taken into account in the script that creates the documents
151
+ */
152
+ if (a.is_rc_template && b.is_rc_template) {
153
+ const aDate = (0, dates_1.buildDateFromApiOrFirebase)(a.created_at);
154
+ const bDate = (0, dates_1.buildDateFromApiOrFirebase)(b.created_at);
155
+ return bDate.getTime() - aDate.getTime();
156
+ }
157
+ /**
158
+ * If both templates are custom templates then the order is alphabetical
159
+ */
160
+ if (!a.is_rc_template && !b.is_rc_template) {
161
+ return a.name.localeCompare(b.name);
162
+ }
163
+ /**
164
+ * All RentCheck Templates should sort at the bottom, leaving custom templates on
165
+ * top
166
+ */
167
+ if (a.is_rc_template) {
168
+ return 1;
169
+ }
170
+ return -1;
171
+ };
172
+ exports.sortFn = sortFn;
@@ -1,3 +1,3 @@
1
1
  import { Feature, InspectionTemplate } from '@rentcheck/types';
2
- export declare const getQuestionIdsAttachedToLogic: (inspectionTemplate: InspectionTemplate) => string[];
3
- export declare const sectionShouldBeVisible: (section: Feature['section'], otherFeatures: Feature[], template: InspectionTemplate) => boolean;
2
+ export declare const getQuestionIdsAttachedToLogic: (inspectionTemplate: Pick<InspectionTemplate, 'sections'>) => string[];
3
+ export declare const sectionShouldBeVisible: (section: Feature['section'], otherFeatures: Feature[], template: Pick<InspectionTemplate, 'sections'>) => boolean;
@@ -0,0 +1,2 @@
1
+ import { ApiInspection } from '@rentcheck/types';
2
+ export declare const userIsInvitedTeammate: (inspection: ApiInspection) => boolean;