@things-factory/work-shift 6.0.75 → 6.0.78
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-server/controllers/index.js +158 -20
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/index.js +0 -3
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-query.js +1 -1
- package/dist-server/service/work-shift/work-shift-query.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-type.js +17 -9
- package/dist-server/service/work-shift/work-shift-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
- package/server/controllers/index.ts +205 -34
- package/server/index.ts +0 -4
- package/server/service/work-shift/work-shift-query.ts +3 -6
- package/server/service/work-shift/work-shift-type.ts +11 -5
- package/server/middlewares/index.ts +0 -3
- package/server/migrations/index.ts +0 -9
- package/server/routes.ts +0 -26
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/work-shift",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.78",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
7
7
|
"author": "heartyoh <heartyoh@hatiolab.com>",
|
|
8
8
|
"description": "Module to handle work shift",
|
|
9
|
+
"license": "MIT",
|
|
9
10
|
"publishConfig": {
|
|
10
11
|
"access": "public",
|
|
11
12
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -23,10 +24,10 @@
|
|
|
23
24
|
"migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
|
-
"@things-factory/auth-base": "^6.0.
|
|
27
|
-
"@things-factory/env": "^6.0.
|
|
28
|
-
"@things-factory/shell": "^6.0.
|
|
27
|
+
"@things-factory/auth-base": "^6.0.78",
|
|
28
|
+
"@things-factory/env": "^6.0.78",
|
|
29
|
+
"@things-factory/shell": "^6.0.78",
|
|
29
30
|
"moment-timezone": "^0.5.40"
|
|
30
31
|
},
|
|
31
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "6d1b076baae617ee1c1df25e176c21d7b1a18e61"
|
|
32
33
|
}
|
|
@@ -4,36 +4,97 @@ import { logger } from '@things-factory/env'
|
|
|
4
4
|
import { Domain, getRepository } from '@things-factory/shell'
|
|
5
5
|
|
|
6
6
|
import { WorkShift, WorkShiftDateType } from '../service/work-shift/work-shift'
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
import { WorkShiftInfo } from '../service/work-shift/work-shift-type'
|
|
8
|
+
|
|
9
|
+
export async function getDateRangeForWorkShift(
|
|
10
|
+
domain: Domain,
|
|
11
|
+
workDate: string,
|
|
12
|
+
workShiftName: string,
|
|
13
|
+
options: { timezone?: string; format?: string }
|
|
14
|
+
): Promise<Date[]> {
|
|
15
|
+
const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }
|
|
16
|
+
const { timezone, format } = dateOptions
|
|
17
|
+
|
|
18
|
+
const workShift = await getRepository(WorkShift).findOne({
|
|
19
|
+
where: {
|
|
20
|
+
domain: { id: domain.id },
|
|
21
|
+
name: workShiftName
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
if (!workShift) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
const theDay = moment.tz(workDate, timezone)
|
|
29
|
+
const { name, fromDate, fromTime, toDate, toTime } = workShift
|
|
30
|
+
|
|
31
|
+
const convertedFromDate = theDay.clone().add(fromDate, 'day')
|
|
32
|
+
const convertedToDate = theDay.clone().add(toDate, 'day')
|
|
33
|
+
const from = moment
|
|
34
|
+
.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
35
|
+
.toDate()
|
|
36
|
+
const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone).toDate()
|
|
37
|
+
|
|
38
|
+
return [from, to]
|
|
23
39
|
}
|
|
24
40
|
|
|
25
|
-
export async function
|
|
41
|
+
export async function getDateRangeForWorkDate(
|
|
26
42
|
domain: Domain,
|
|
27
|
-
|
|
28
|
-
options?:
|
|
29
|
-
)
|
|
43
|
+
workDate: string,
|
|
44
|
+
options: { timezone?: string; format?: string }
|
|
45
|
+
) {
|
|
46
|
+
const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }
|
|
47
|
+
const { timezone, format } = dateOptions
|
|
48
|
+
|
|
49
|
+
var beginDate
|
|
50
|
+
var endDate
|
|
51
|
+
|
|
52
|
+
/* 1. get work-shift list for the domain */
|
|
53
|
+
const workShifts = await getRepository(WorkShift).find({
|
|
54
|
+
where: {
|
|
55
|
+
domain: { id: domain.id }
|
|
56
|
+
},
|
|
57
|
+
order: {
|
|
58
|
+
fromDate: 'ASC',
|
|
59
|
+
fromTime: 'ASC'
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
/* 2. get date-time for every work-shift */
|
|
64
|
+
if (workShifts && workShifts.length > 0) {
|
|
65
|
+
const theDay = moment.tz(workDate, timezone)
|
|
66
|
+
|
|
67
|
+
for (let j = 0; j < workShifts.length; j++) {
|
|
68
|
+
const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]
|
|
69
|
+
|
|
70
|
+
const convertedFromDate = theDay.clone().add(fromDate, 'day')
|
|
71
|
+
const convertedToDate = theDay.clone().add(toDate, 'day')
|
|
72
|
+
const from = moment
|
|
73
|
+
.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
74
|
+
.toDate()
|
|
75
|
+
const to = moment
|
|
76
|
+
.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
77
|
+
.toDate()
|
|
78
|
+
|
|
79
|
+
if (!beginDate) {
|
|
80
|
+
beginDate = from
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
endDate = to
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* 3. in case there are no work-shift, just give date and default shift '' */
|
|
90
|
+
return [beginDate, endDate]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function getWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {
|
|
30
94
|
const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }
|
|
31
95
|
const { timezone, format } = dateOptions
|
|
32
96
|
|
|
33
|
-
// const givenDate = dateTime.toISOString().split('T')[0]
|
|
34
97
|
const givenDate = moment(dateTime).tz(timezone)
|
|
35
|
-
const localDate = new Date(givenDate.format('YYYY-MM-DD HH:mm:ss'))
|
|
36
|
-
const workDate = givenDate.format(format)
|
|
37
98
|
/* 1. get work-shift list for the domain */
|
|
38
99
|
const workShifts = await getRepository(WorkShift).find({
|
|
39
100
|
where: {
|
|
@@ -46,23 +107,132 @@ export async function getWorkDateAndShift(
|
|
|
46
107
|
})
|
|
47
108
|
|
|
48
109
|
/* 2. compare given date-time to every work-shift */
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const theDayAfter = new Date(theDay.getTime() + 24 * 60 * 60 * 1000)
|
|
110
|
+
const theDay = givenDate.clone().startOf('day')
|
|
111
|
+
const theDayBefore = theDay.clone().subtract(1, 'day')
|
|
112
|
+
const theDayAfter = theDay.clone().add(1, 'day')
|
|
53
113
|
|
|
114
|
+
if (workShifts && workShifts.length > 0) {
|
|
54
115
|
const days = [theDayBefore, theDay, theDayAfter]
|
|
116
|
+
let dateBegin, dateEnd
|
|
55
117
|
|
|
56
118
|
for (let i = 0; i < days.length; i++) {
|
|
57
|
-
const
|
|
119
|
+
const day = days[i]
|
|
120
|
+
dateBegin = null
|
|
58
121
|
|
|
59
122
|
for (let j = 0; j < workShifts.length; j++) {
|
|
60
123
|
const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]
|
|
61
124
|
|
|
62
|
-
|
|
125
|
+
const convertedFromDate = day.clone().add(fromDate, 'day')
|
|
126
|
+
const convertedToDate = day.clone().add(toDate, 'day')
|
|
127
|
+
|
|
128
|
+
const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
129
|
+
const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
130
|
+
|
|
131
|
+
dateBegin = dateBegin || from
|
|
132
|
+
dateEnd = from.clone().add(1, 'day')
|
|
133
|
+
|
|
134
|
+
if (dateTime >= from.toDate() && to.toDate() > dateTime) {
|
|
63
135
|
return {
|
|
64
|
-
workDate,
|
|
65
|
-
workShift: name
|
|
136
|
+
workDate: moment(day).format(format),
|
|
137
|
+
workShift: name,
|
|
138
|
+
dateRange: [dateBegin.toDate(), dateEnd.toDate()],
|
|
139
|
+
shiftRange: [from.toDate(), to.toDate()]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
logger.error(new Error('shift not found'))
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* 3. in case there are no work-shift, just give date and default shift '' */
|
|
149
|
+
return {
|
|
150
|
+
workDate: givenDate.format(format),
|
|
151
|
+
workShift: '',
|
|
152
|
+
dateRange: [theDay.toDate(), theDayAfter.toDate()]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export async function getLatestWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {
|
|
157
|
+
const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }
|
|
158
|
+
const { timezone, format } = dateOptions
|
|
159
|
+
|
|
160
|
+
const givenDate = moment(dateTime).tz(timezone)
|
|
161
|
+
|
|
162
|
+
/* 1. get work-shift list for the domain */
|
|
163
|
+
const workShifts = await getRepository(WorkShift).find({
|
|
164
|
+
where: {
|
|
165
|
+
domain: { id: domain.id }
|
|
166
|
+
},
|
|
167
|
+
order: {
|
|
168
|
+
fromDate: 'ASC',
|
|
169
|
+
fromTime: 'ASC'
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
/* 2. compare given date-time to every work-shift */
|
|
174
|
+
const theDay = givenDate.clone().startOf('day')
|
|
175
|
+
const theDayBefore = theDay.clone().subtract(1, 'day')
|
|
176
|
+
const theDayAfter = theDay.clone().add(1, 'day')
|
|
177
|
+
|
|
178
|
+
if (workShifts && workShifts.length > 0) {
|
|
179
|
+
const days = [theDayBefore, theDay, theDayAfter]
|
|
180
|
+
let dateBegin, dateEnd
|
|
181
|
+
|
|
182
|
+
for (let i = 0; i < days.length; i++) {
|
|
183
|
+
const day = days[i]
|
|
184
|
+
dateBegin = null
|
|
185
|
+
|
|
186
|
+
for (let j = 0; j < workShifts.length; j++) {
|
|
187
|
+
const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]
|
|
188
|
+
|
|
189
|
+
const convertedFromDate = day.clone().add(fromDate, 'day')
|
|
190
|
+
const convertedToDate = day.clone().add(toDate, 'day')
|
|
191
|
+
|
|
192
|
+
const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
193
|
+
const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
194
|
+
|
|
195
|
+
dateBegin = dateBegin || from
|
|
196
|
+
dateEnd = from.clone().add(1, 'day')
|
|
197
|
+
|
|
198
|
+
if (dateTime < from.toDate()) {
|
|
199
|
+
if (j > 0) {
|
|
200
|
+
const { name, fromDate, fromTime, toDate, toTime } = workShifts[j - 1]
|
|
201
|
+
|
|
202
|
+
const from = moment.tz(
|
|
203
|
+
`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,
|
|
204
|
+
'YYYY-MM-DD HH:mm:ss',
|
|
205
|
+
timezone
|
|
206
|
+
)
|
|
207
|
+
const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
workDate: moment(day).format(format),
|
|
211
|
+
workShift: name,
|
|
212
|
+
dateRange: [dateBegin.toDate(), dateEnd.toDate()],
|
|
213
|
+
shiftRange: [from.toDate(), to.toDate()]
|
|
214
|
+
}
|
|
215
|
+
} else if (i > 0) {
|
|
216
|
+
const { name, fromDate, fromTime, toDate, toTime } = workShifts[0]
|
|
217
|
+
|
|
218
|
+
const convertedFromDate = days[i - 1].clone().add(fromDate, 'day')
|
|
219
|
+
const convertedToDate = days[i - 1].clone().add(toDate, 'day')
|
|
220
|
+
|
|
221
|
+
const from = moment.tz(
|
|
222
|
+
`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,
|
|
223
|
+
'YYYY-MM-DD HH:mm:ss',
|
|
224
|
+
timezone
|
|
225
|
+
)
|
|
226
|
+
const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
workDate: moment(day).format(format),
|
|
230
|
+
workShift: name,
|
|
231
|
+
dateRange: [dateBegin.clone().subtract(1, 'day').toDate(), dateBegin.toDate()],
|
|
232
|
+
shiftRange: [from.toDate(), to.toDate()]
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
return
|
|
66
236
|
}
|
|
67
237
|
}
|
|
68
238
|
}
|
|
@@ -71,9 +241,10 @@ export async function getWorkDateAndShift(
|
|
|
71
241
|
logger.error(new Error('shift not found'))
|
|
72
242
|
}
|
|
73
243
|
|
|
74
|
-
/* 3. in case there are no work-shift, just give date and default shift '
|
|
244
|
+
/* 3. in case there are no work-shift, just give date and default shift '' */
|
|
75
245
|
return {
|
|
76
|
-
workDate,
|
|
77
|
-
workShift: '
|
|
246
|
+
workDate: givenDate.clone().subtract(1, 'day').format(format),
|
|
247
|
+
workShift: '',
|
|
248
|
+
dateRange: [theDayBefore.toDate(), theDay.toDate()]
|
|
78
249
|
}
|
|
79
250
|
}
|
package/server/index.ts
CHANGED
|
@@ -5,15 +5,12 @@ import { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from
|
|
|
5
5
|
|
|
6
6
|
import { getWorkDateAndShift } from '../../controllers/index'
|
|
7
7
|
import { WorkShift } from './work-shift'
|
|
8
|
-
import {
|
|
8
|
+
import { WorkShiftInfo, WorkShiftList } from './work-shift-type'
|
|
9
9
|
|
|
10
10
|
@Resolver(Domain)
|
|
11
11
|
export class DomainWorkShiftQuery {
|
|
12
|
-
@Query(returns =>
|
|
13
|
-
async getWorkDateAndShift(
|
|
14
|
-
@Arg('dateTime') dateTime: Date,
|
|
15
|
-
@Ctx() context: ResolverContext
|
|
16
|
-
): Promise<WorkDateWorkShiftPair> {
|
|
12
|
+
@Query(returns => WorkShiftInfo, { description: 'To fetch a work date and work shift for given datetime' })
|
|
13
|
+
async getWorkDateAndShift(@Arg('dateTime') dateTime: Date, @Ctx() context: ResolverContext): Promise<WorkShiftInfo> {
|
|
17
14
|
const { domain } = context.state
|
|
18
15
|
|
|
19
16
|
return await getWorkDateAndShift(domain, dateTime)
|
|
@@ -32,10 +32,16 @@ export class WorkShiftList {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
@ObjectType()
|
|
35
|
-
export class
|
|
36
|
-
@Field()
|
|
37
|
-
workDate
|
|
35
|
+
export class WorkShiftInfo {
|
|
36
|
+
@Field({ nullable: true })
|
|
37
|
+
workDate?: string
|
|
38
38
|
|
|
39
|
-
@Field()
|
|
40
|
-
workShift
|
|
39
|
+
@Field({ nullable: true })
|
|
40
|
+
workShift?: string
|
|
41
|
+
|
|
42
|
+
@Field(type => [Date], { nullable: true })
|
|
43
|
+
dateRange?: Date[]
|
|
44
|
+
|
|
45
|
+
@Field(type => [Date], { nullable: true })
|
|
46
|
+
shiftRange?: Date[]
|
|
41
47
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const glob = require('glob')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
|
|
4
|
-
export var migrations = []
|
|
5
|
-
|
|
6
|
-
glob.sync(path.resolve(__dirname, '.', '**', '*.js')).forEach(function(file) {
|
|
7
|
-
if (file.indexOf('index.js') !== -1) return
|
|
8
|
-
migrations = migrations.concat(Object.values(require(path.resolve(file))) || [])
|
|
9
|
-
})
|
package/server/routes.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRouter) => {
|
|
2
|
-
/*
|
|
3
|
-
* can add global public routes to application (auth not required, tenancy not required)
|
|
4
|
-
*
|
|
5
|
-
* ex) routes.get('/path', async(context, next) => {})
|
|
6
|
-
* ex) routes.post('/path', async(context, next) => {})
|
|
7
|
-
*/
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRouter) => {
|
|
11
|
-
/*
|
|
12
|
-
* can add global private routes to application (auth required, tenancy not required)
|
|
13
|
-
*/
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
process.on('bootstrap-module-domain-public-route' as any, (app, domainPublicRouter) => {
|
|
17
|
-
/*
|
|
18
|
-
* can add domain public routes to application (auth not required, tenancy required)
|
|
19
|
-
*/
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
process.on('bootstrap-module-domain-private-route' as any, (app, domainPrivateRouter) => {
|
|
23
|
-
/*
|
|
24
|
-
* can add domain private routes to application (auth required, tenancy required)
|
|
25
|
-
*/
|
|
26
|
-
})
|