@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/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@things-factory/work-shift",
3
- "version": "6.0.75",
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.75",
27
- "@things-factory/env": "^6.0.71",
28
- "@things-factory/shell": "^6.0.75",
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": "f7ca179a7fabfc129a9981a7bd734380a3ac64f0"
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 { WorkDateWorkShiftPair } from '../service/work-shift/work-shift-type'
8
-
9
- function between(
10
- fromDate: WorkShiftDateType,
11
- fromTime: string /* hh:mm */,
12
- toDate: WorkShiftDateType,
13
- toTime: string /* hh:mm */,
14
- theDay: Date,
15
- dateTime: Date
16
- ): boolean {
17
- const convertedFromDate = new Date(theDay.getTime() + fromDate * (24 * 60 * 60 * 1000))
18
- const convertedToDate = new Date(theDay.getTime() + toDate * (24 * 60 * 60 * 1000))
19
- const from = new Date(`${convertedFromDate.toISOString().split('T')[0]}T${fromTime}`)
20
- const to = new Date(`${convertedToDate.toISOString().split('T')[0]}T${toTime}`)
21
-
22
- return dateTime >= from && to > dateTime
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 getWorkDateAndShift(
41
+ export async function getDateRangeForWorkDate(
26
42
  domain: Domain,
27
- dateTime: Date,
28
- options?: any
29
- ): Promise<WorkDateWorkShiftPair> {
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
- if (workShifts && workShifts.length > 0) {
50
- const theDay = new Date(givenDate.format('YYYY-MM-DD'))
51
- const theDayBefore = new Date(theDay.getTime() - 24 * 60 * 60 * 1000)
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 theDay = days[i]
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
- if (between(fromDate, fromTime, toDate, toTime, theDay, localDate)) {
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 'NA' */
244
+ /* 3. in case there are no work-shift, just give date and default shift '' */
75
245
  return {
76
- workDate,
77
- workShift: 'NA'
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
@@ -1,6 +1,2 @@
1
1
  export * from './controllers'
2
- export * from './migrations'
3
- export * from './middlewares'
4
2
  export * from './service'
5
-
6
- import './routes'
@@ -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 { WorkDateWorkShiftPair, WorkShiftList } from './work-shift-type'
8
+ import { WorkShiftInfo, WorkShiftList } from './work-shift-type'
9
9
 
10
10
  @Resolver(Domain)
11
11
  export class DomainWorkShiftQuery {
12
- @Query(returns => WorkDateWorkShiftPair, { description: 'To fetch a work date and work shift for given datetime' })
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 WorkDateWorkShiftPair {
36
- @Field()
37
- workDate: string
35
+ export class WorkShiftInfo {
36
+ @Field({ nullable: true })
37
+ workDate?: string
38
38
 
39
- @Field()
40
- workShift: string
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,3 +0,0 @@
1
- export function initMiddlewares(app) {
2
- /* can add middlewares into app */
3
- }
@@ -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
- })