zet-lib 1.3.39 → 1.3.40
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/LICENSE +21 -21
- package/README.md +15 -15
- package/lib/ErrorWithCode.js +6 -6
- package/lib/Form.js +1019 -1019
- package/lib/Mail.js +68 -68
- package/lib/Modal.js +95 -95
- package/lib/Pool.js +437 -437
- package/lib/UI.js +7 -7
- package/lib/Util.js +1384 -1384
- package/lib/access.js +6 -6
- package/lib/cache.js +3 -3
- package/lib/connection.js +409 -409
- package/lib/debug.js +22 -22
- package/lib/index.js +36 -36
- package/lib/io.js +44 -44
- package/lib/languages/lang_en.js +125 -125
- package/lib/languages/lang_fr.js +125 -125
- package/lib/languages/lang_id.js +126 -126
- package/lib/languages/lang_jp.js +125 -125
- package/lib/moduleLib.js +661 -661
- package/lib/tableForm.js +10 -10
- package/lib/views/generator.ejs +598 -598
- package/lib/views/generator_layout.ejs +224 -224
- package/lib/views/generatorjs.ejs +927 -927
- package/lib/zAppRouter.js +1637 -1637
- package/lib/zCache.js +301 -301
- package/lib/zComponent.js +27 -27
- package/lib/zFn.js +58 -58
- package/lib/zFunction.js +20 -20
- package/lib/zGeneratorRouter.js +1641 -1641
- package/lib/zMenuRouter.js +556 -556
- package/lib/zPage.js +188 -188
- package/lib/zReport.js +982 -982
- package/lib/zRole.js +256 -256
- package/lib/zRoleRouter.js +609 -609
- package/lib/zRoute.js +5025 -5024
- package/lib/zTester.js +93 -93
- package/lib/zapp.js +65 -65
- package/lib/zdataTable.js +330 -330
- package/package.json +56 -56
package/lib/Util.js
CHANGED
|
@@ -1,1384 +1,1384 @@
|
|
|
1
|
-
const moment = require('moment')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const randomstring = require('randomstring')
|
|
4
|
-
const fs = require('fs-extra')
|
|
5
|
-
const { v4: uuidv4 } = require('uuid')
|
|
6
|
-
const sha256 = require('js-sha256')
|
|
7
|
-
|
|
8
|
-
const Util = {}
|
|
9
|
-
|
|
10
|
-
Util.tab = '\t'
|
|
11
|
-
Util.tabs = (n) => {
|
|
12
|
-
let ret = ''
|
|
13
|
-
for (var i = 0; i < n; i++) {
|
|
14
|
-
ret += Util.tab
|
|
15
|
-
}
|
|
16
|
-
return ret
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
Util.NEW_LINE = '\n'
|
|
20
|
-
Util.newLine = '\r\n'
|
|
21
|
-
Util.newLines = (n) => {
|
|
22
|
-
let ret = ''
|
|
23
|
-
for (var i = 0; i < n; i++) {
|
|
24
|
-
ret += Util.newLine
|
|
25
|
-
}
|
|
26
|
-
return ret
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
//sha256
|
|
30
|
-
Util.hash = (string) => {
|
|
31
|
-
return sha256(string)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
Util.hashCompare = (myPlaintextPassword, hash) => {
|
|
35
|
-
return Util.hash(myPlaintextPassword) == hash
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
Util.excelSequence = function () {
|
|
39
|
-
let abjads = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
|
40
|
-
let arr = abjads
|
|
41
|
-
let char = 0
|
|
42
|
-
let num = 26
|
|
43
|
-
for (let x = 2; x < 15; x++) {
|
|
44
|
-
let idx = 0
|
|
45
|
-
for (let i = 1; i <= 26; i++) {
|
|
46
|
-
arr[num] = abjads[char] + abjads[idx]
|
|
47
|
-
idx++
|
|
48
|
-
num++
|
|
49
|
-
}
|
|
50
|
-
char++
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return arr
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
Util.now = function () {
|
|
57
|
-
return moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
Util.nowShort = function () {
|
|
61
|
-
return moment(new Date()).format('YYYY-MM-DD')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
Util.ago = (data) => {
|
|
65
|
-
return moment(data).fromNow()
|
|
66
|
-
}
|
|
67
|
-
/*
|
|
68
|
-
moment get one month ago from current
|
|
69
|
-
var monthago = moment().subtract(1, 'months').format('YYYY-MM-DD');
|
|
70
|
-
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
Util.dateSql = function (date, format) {
|
|
74
|
-
format = format || 'YYYY-MM-DD'
|
|
75
|
-
if (date && date != '0000-00-00') return moment(date).format(format)
|
|
76
|
-
else return ''
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
Util.dateOriginal = function (date) {
|
|
80
|
-
if (date && date != '0000-00-00') {
|
|
81
|
-
let value = moment(date).utc(false)
|
|
82
|
-
return value
|
|
83
|
-
} else {
|
|
84
|
-
return ''
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
Util.dateFormat = function (date, format) {
|
|
89
|
-
format = format || 'YYYY-MM-DD'
|
|
90
|
-
if (date && date != '0000-00-00') return moment(date).format(format)
|
|
91
|
-
else return ''
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
Util.timePublic = function (date) {
|
|
95
|
-
if (date) return moment(date).format('DD MMM YYYY')
|
|
96
|
-
else return ''
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
Util.timeSql = function (date, format) {
|
|
100
|
-
if (date && date != '0000-00-00 00:00:00') {
|
|
101
|
-
format = format || 'YYYY-MM-DD HH:mm:ss'
|
|
102
|
-
return moment(date).format(format)
|
|
103
|
-
} else return ''
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
//moment('2017-11-30T15:00:00-07:00').diff(moment('2017-05-31T15:00:00-07:00'), 'months')
|
|
107
|
-
Util.dateDiff = (start, end, format = 'months') => {
|
|
108
|
-
let count = 0
|
|
109
|
-
if (start && end) {
|
|
110
|
-
count = moment(end).diff(moment(start), format, true)
|
|
111
|
-
}
|
|
112
|
-
return count
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
Util.getDate = function (date) {
|
|
116
|
-
date = date + '' || ''
|
|
117
|
-
if (date != '') {
|
|
118
|
-
let explode = date.split('-')
|
|
119
|
-
return {
|
|
120
|
-
year: parseInt(explode[0]),
|
|
121
|
-
month: parseInt(explode[1]),
|
|
122
|
-
date: parseInt(explode[2]),
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
return {
|
|
126
|
-
year: 0,
|
|
127
|
-
month: 0,
|
|
128
|
-
date: 0,
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
Util.dateIsBetween = (compare, start, end) => {
|
|
134
|
-
if (compare == '' || compare == '0000-00-00') {
|
|
135
|
-
return false
|
|
136
|
-
}
|
|
137
|
-
compare = moment(compare).format('YYYY-MM-DD')
|
|
138
|
-
start = moment(start).format('YYYY-MM-DD')
|
|
139
|
-
end = moment(end).format('YYYY-MM-DD')
|
|
140
|
-
let today = moment(compare)
|
|
141
|
-
let startDate = moment(start)
|
|
142
|
-
let endDate = moment(end)
|
|
143
|
-
|
|
144
|
-
if (compare == start) {
|
|
145
|
-
return true
|
|
146
|
-
} else if (compare == end) {
|
|
147
|
-
return true
|
|
148
|
-
} else {
|
|
149
|
-
return today.isBetween(startDate, endDate)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
Util.getMonth = function (date) {
|
|
154
|
-
if (date.length > 5) {
|
|
155
|
-
let n = new Date(date)
|
|
156
|
-
let m = n.getMonth()
|
|
157
|
-
return parseInt(m) + 1
|
|
158
|
-
}
|
|
159
|
-
return 0
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
Util.getYear = function (date) {
|
|
163
|
-
date = Util.dateSql(date) || ''
|
|
164
|
-
return date.slice(0, 4)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
//first is smaller than second
|
|
168
|
-
Util.calculateDay = function (from, to, holidayInWeek = 0) {
|
|
169
|
-
holidayInWeek = parseInt(holidayInWeek) || 0
|
|
170
|
-
let count = 0
|
|
171
|
-
if (holidayInWeek == 1) {
|
|
172
|
-
let days = Util.enumerateDaysBetweenDates(moment(from).format('YYYY-MM-DD'), moment(to).format('YYYY-MM-DD'))
|
|
173
|
-
let countdays = days.filter((item) => parseInt(moment(item).format('d')) != 0)
|
|
174
|
-
count = countdays.length
|
|
175
|
-
} else if (holidayInWeek == 2) {
|
|
176
|
-
let days = Util.enumerateDaysBetweenDates(moment(from).format('YYYY-MM-DD'), moment(to).format('YYYY-MM-DD'))
|
|
177
|
-
let countdays = days.filter((item) => parseInt(moment(item).format('d')) != 0 && parseInt(moment(item).format('d')) != 6)
|
|
178
|
-
count = countdays.length
|
|
179
|
-
} else {
|
|
180
|
-
let a = moment(from)
|
|
181
|
-
let b = moment(to)
|
|
182
|
-
count = b.diff(a, 'days') + 1
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return count
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
var getDaysBetweenDates = function (startDate, endDate) {
|
|
189
|
-
let now = startDate.clone(),
|
|
190
|
-
dates = []
|
|
191
|
-
while (now.isSameOrBefore(endDate)) {
|
|
192
|
-
dates.push(now.format('MM/DD/YYYY'))
|
|
193
|
-
now.add(1, 'days')
|
|
194
|
-
}
|
|
195
|
-
return dates
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
//itterate days in array
|
|
199
|
-
Util.enumerateDaysBetweenDates = function (startDate, endDate) {
|
|
200
|
-
let now = moment(startDate).clone(),
|
|
201
|
-
dates = []
|
|
202
|
-
while (now.isSameOrBefore(endDate)) {
|
|
203
|
-
dates.push(now.format('MM/DD/YYYY'))
|
|
204
|
-
now.add(1, 'days')
|
|
205
|
-
}
|
|
206
|
-
return dates
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
Util.tableArray = function (arr = []) {
|
|
210
|
-
let r = []
|
|
211
|
-
let tables = arr[0]
|
|
212
|
-
for (let i = 0; i < tables.length; i++) {
|
|
213
|
-
for (let obj in tables[i]) {
|
|
214
|
-
r.push(tables[i][obj])
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return r
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/*
|
|
221
|
-
table array in sql to arr table name
|
|
222
|
-
only for generator
|
|
223
|
-
*/
|
|
224
|
-
Util.tableArrayToObj = (arr = []) => {
|
|
225
|
-
return arr.map((m) => Object.values(m)[0])
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
Util.escapeRegExp = function (str = '') {
|
|
229
|
-
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
Util.validateEmail = function (email) {
|
|
233
|
-
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
234
|
-
return re.test(email)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/*
|
|
238
|
-
Replace All like str_replace in PHP
|
|
239
|
-
example : Util.replaceAll("abd","a","")
|
|
240
|
-
*/
|
|
241
|
-
|
|
242
|
-
Util.replaceAll = function (str = '', find, replace) {
|
|
243
|
-
let t = ''
|
|
244
|
-
if (Array.isArray(find)) {
|
|
245
|
-
t = str
|
|
246
|
-
for (let i = 0; i < find.length; i++) {
|
|
247
|
-
if (str.indexOf(find[i]) > -1) {
|
|
248
|
-
t = str.replace(new RegExp(Util.escapeRegExp(find[i]), 'g'), replace)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
} else {
|
|
252
|
-
if (typeof str == 'string') {
|
|
253
|
-
t = str.replace(new RegExp(Util.escapeRegExp(find), 'g'), replace)
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return t
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
Util.phoneFixed = function (str = '') {
|
|
260
|
-
let ret = ''
|
|
261
|
-
str = Util.replaceAll(str, ' ', '')
|
|
262
|
-
let phone = str.trim()
|
|
263
|
-
phone = Util.replaceAll(phone, '-', '')
|
|
264
|
-
let first = phone.charAt(0)
|
|
265
|
-
if (first == '') {
|
|
266
|
-
ret = ''
|
|
267
|
-
} else if (first == '+') {
|
|
268
|
-
ret = phone
|
|
269
|
-
} else if (first == '0') {
|
|
270
|
-
ret = '+62' + phone.replace('0', '')
|
|
271
|
-
} else {
|
|
272
|
-
ret = '+' + phone
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return ret
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
Util.jsonSuccess = function (message = '') {
|
|
279
|
-
message = message || LANGUAGE.data_saved
|
|
280
|
-
let json = { type: 'success', status: 1, title: LANGUAGE.success, message: message }
|
|
281
|
-
|
|
282
|
-
return json
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
Util.flashError = function (message = '', errors = []) {
|
|
286
|
-
message = message || LANGUAGE.data_not_found
|
|
287
|
-
let json = { type: 'error', status: 0, title: 'Error', message: message, errors: errors }
|
|
288
|
-
|
|
289
|
-
return json
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
Util.jsonError = function (path, message) {
|
|
293
|
-
let json = {}
|
|
294
|
-
json.errorLog = 1
|
|
295
|
-
json.type = 'error'
|
|
296
|
-
json.status = 0
|
|
297
|
-
json.title = path + ' Error!'
|
|
298
|
-
json.message = message
|
|
299
|
-
json.errors = [{ path: path, message: message }]
|
|
300
|
-
|
|
301
|
-
return json
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
Util.arrayToObject = (array = [], keyField, isInteger = false) => {
|
|
305
|
-
let obj = {}
|
|
306
|
-
if (array.length) {
|
|
307
|
-
array.forEach(function (item) {
|
|
308
|
-
var name = item[keyField] == null ? 'xxxxxx' : item[keyField] == 'null' ? 'xxxxxx' : isInteger ? item[keyField] : item[keyField] + ''
|
|
309
|
-
obj[name] = item
|
|
310
|
-
})
|
|
311
|
-
}
|
|
312
|
-
return obj
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
//chase id:1,name:'test' t0 {1:'test'}
|
|
316
|
-
Util.modulesSwitch = (arr = []) => {
|
|
317
|
-
let stores = []
|
|
318
|
-
stores.push({ id: '', name: '' })
|
|
319
|
-
arr.forEach((ar, index) => {
|
|
320
|
-
stores.push({ id: index, name: ar })
|
|
321
|
-
})
|
|
322
|
-
return stores
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
Util.buildArrayObjectPrefix = function (arr = []) {
|
|
326
|
-
return Util.modulesSwitch(arr)
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
Util.arrayWithObject = (array = [], key, field) => {
|
|
330
|
-
if (array.length) {
|
|
331
|
-
return array.reduce((obj, item) => {
|
|
332
|
-
obj[item[key]] = item[field]
|
|
333
|
-
return obj
|
|
334
|
-
}, {})
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/*
|
|
339
|
-
for movedupload file using single file
|
|
340
|
-
*/
|
|
341
|
-
Util.moveFile = function (buffer, filename) {
|
|
342
|
-
return new Promise(function (resolve, reject) {
|
|
343
|
-
buffer.mv(filename, function (err) {
|
|
344
|
-
if (err) {
|
|
345
|
-
reject(err)
|
|
346
|
-
} else {
|
|
347
|
-
resolve(filename)
|
|
348
|
-
}
|
|
349
|
-
})
|
|
350
|
-
})
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
Util.generateUnique = function (length, charset) {
|
|
354
|
-
let random = Util.generate(length, charset)
|
|
355
|
-
let uid = new Date().valueOf().toString(36)
|
|
356
|
-
|
|
357
|
-
return uid + random
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
Util.generate = function (length, charset) {
|
|
361
|
-
length = length || 50
|
|
362
|
-
//alphanumeric - [0-9 a-z A-Z] alphabetic - [a-z A-Z] numeric - [0-9] hex - [0-9 a-f] custom - any given characters
|
|
363
|
-
charset = charset || 'alphanumeric'
|
|
364
|
-
return randomstring.generate({
|
|
365
|
-
length: length,
|
|
366
|
-
charset: charset,
|
|
367
|
-
})
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
Util.uuid = () => {
|
|
371
|
-
return uuidv4()
|
|
372
|
-
}
|
|
373
|
-
/*
|
|
374
|
-
generate random string 8
|
|
375
|
-
*/
|
|
376
|
-
Util.random = function (length) {
|
|
377
|
-
length = length || 5
|
|
378
|
-
let text = ''
|
|
379
|
-
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
380
|
-
for (let i = 0; i < length; i++) text += possible.charAt(Math.floor(Math.random() * possible.length))
|
|
381
|
-
|
|
382
|
-
return text
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
Util.whitelist = function () {
|
|
386
|
-
return ['www', 'app', 'my', 'sintret', 'https', 'https']
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
Util.convertDate = function (d) {
|
|
390
|
-
d = d.trim()
|
|
391
|
-
let myarr = d.split(' ')
|
|
392
|
-
return myarr[2] + '-' + Util.monthConvert(myarr[1]) + '-' + myarr[0]
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// get string start from to
|
|
396
|
-
Util.cut = function (text, start, end) {
|
|
397
|
-
return text.substr(start, end)
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
Util.getFormattedDate = function (date) {
|
|
401
|
-
let year = date.getFullYear()
|
|
402
|
-
let month = (1 + date.getMonth()).toString()
|
|
403
|
-
month = month.length > 1 ? month : '0' + month
|
|
404
|
-
let day = date.getDate().toString()
|
|
405
|
-
day = day.length > 1 ? day : '0' + day
|
|
406
|
-
let time = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()
|
|
407
|
-
return year + '-' + month + '-' + day + ' ' + time
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
Util.uniqueId = function () {
|
|
411
|
-
return (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase()
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
Util.typePaperSize = [
|
|
415
|
-
{ title: 'F4', description: 'FOLIO', width: 215, height: 330 },
|
|
416
|
-
{ title: 'LEGAL', description: 'LEGAL', width: 216, height: 356 },
|
|
417
|
-
{ title: 'LETTER', description: 'LETTER', width: 216, height: 279 },
|
|
418
|
-
{ title: 'A3', description: 'A3', width: 297, height: 420 },
|
|
419
|
-
{ title: 'A4', description: 'A4', width: 210, height: 297 },
|
|
420
|
-
{ title: 'A5', description: 'A5', width: 148, height: 210 },
|
|
421
|
-
{ title: 'A6', description: 'A6', width: 105, height: 148 },
|
|
422
|
-
{ title: 'A7', description: 'A7', width: 74, height: 105 },
|
|
423
|
-
{ title: 'A8', description: 'A8', width: 52, height: 74 },
|
|
424
|
-
{ title: 'A9', description: 'A9', width: 37, height: 52 },
|
|
425
|
-
{ title: 'CUSTOM', description: 'CUSTOM', width: 105, height: 148 },
|
|
426
|
-
]
|
|
427
|
-
|
|
428
|
-
Util.typeFont = [
|
|
429
|
-
'Verdana, Geneva, sans-serif',
|
|
430
|
-
'"Times New Roman", Times, serif',
|
|
431
|
-
'Georgia, serif',
|
|
432
|
-
'"Palatino Linotype", "Book Antiqua", Palatino, serif',
|
|
433
|
-
'Arial, Helvetica, sans-serif',
|
|
434
|
-
'"Arial Black", Gadget, sans-serif',
|
|
435
|
-
'"Comic Sans MS", cursive, sans-serif',
|
|
436
|
-
'Impact, Charcoal, sans-serif',
|
|
437
|
-
'"Lucida Sans Unicode", "Lucida Grande", sans-serif',
|
|
438
|
-
'Tahoma, Geneva, sans-serif',
|
|
439
|
-
'"Trebuchet MS", Helvetica, sans-serif',
|
|
440
|
-
'"Courier New", Courier, monospace',
|
|
441
|
-
'"Lucida Console", Monaco, monospace',
|
|
442
|
-
]
|
|
443
|
-
|
|
444
|
-
Util.objectToGridFormat = function (obj = {}, isInteger = false) {
|
|
445
|
-
isInteger = isInteger || false
|
|
446
|
-
let arr = []
|
|
447
|
-
arr.push({ id: '', name: '' })
|
|
448
|
-
for (let keys in obj) {
|
|
449
|
-
if (isInteger) {
|
|
450
|
-
arr.push({ id: parseInt(keys), name: obj[keys] })
|
|
451
|
-
} else {
|
|
452
|
-
arr.push({ id: keys, name: obj[keys] })
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
return arr
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
Util.random = function (length = 5) {
|
|
459
|
-
let text = ''
|
|
460
|
-
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
461
|
-
for (let i = 0; i < length; i++) text += possible.charAt(Math.floor(Math.random() * possible.length))
|
|
462
|
-
|
|
463
|
-
return text
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
Util.typePrint = {
|
|
467
|
-
register: '{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"10","header":"SURAT PERINTAH KERJA","header_font":"0","header_font_size":"26"}',
|
|
468
|
-
estimation: '{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"ESTIMASI BIAYA PERBAIKAN","header_font":"0","header_font_size":"18"}',
|
|
469
|
-
invoice: '{"paper_size":"A5","paper_size_width":"148","paper_size_height":"210","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"INVOICE","header_font":"0","header_font_size":"18"}',
|
|
470
|
-
currency: '{"symbol":"Rp","name":"Rupiah","thousand":"."}',
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
Util.isJson = function (text) {
|
|
474
|
-
if (text) {
|
|
475
|
-
if (
|
|
476
|
-
/^[\],:{}\s]*$/.test(
|
|
477
|
-
text
|
|
478
|
-
.replace(/\\["\\\/bfnrtu]/g, '@')
|
|
479
|
-
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
|
480
|
-
.replace(/(?:^|:|,)(?:\s*\[)+/g, '')
|
|
481
|
-
)
|
|
482
|
-
) {
|
|
483
|
-
//the json is ok
|
|
484
|
-
return true
|
|
485
|
-
} else {
|
|
486
|
-
return false
|
|
487
|
-
//the json is not ok
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return false
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
Util.isEmptyObject = function (obj = {}) {
|
|
494
|
-
for (let prop in obj) {
|
|
495
|
-
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
496
|
-
return false
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
return JSON.stringify(obj) === JSON.stringify({})
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
Util.serializeTable = function (table = '') {
|
|
504
|
-
return '`' + table + '`'
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
Util.getKey = function (obj = {}, field = '') {
|
|
508
|
-
let t = ''
|
|
509
|
-
for (let item in obj) {
|
|
510
|
-
if (obj[item] == field) {
|
|
511
|
-
return item
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return t
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
Util.camelize = function (text = '') {
|
|
518
|
-
return text.replace(/^([A-Z])|[\s-_]+(\w)/g, function (match, p1, p2, offset) {
|
|
519
|
-
if (p2) return p2.toUpperCase()
|
|
520
|
-
return p1.toLowerCase()
|
|
521
|
-
})
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
Util.decamelize = function (str = '', separator = '_') {
|
|
525
|
-
return str
|
|
526
|
-
.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
|
|
527
|
-
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2')
|
|
528
|
-
.replace('_', separator)
|
|
529
|
-
.toLowerCase()
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/*
|
|
533
|
-
change : Order Step
|
|
534
|
-
to : order_tep
|
|
535
|
-
*/
|
|
536
|
-
|
|
537
|
-
Util.toName = function (str = '', separator = '_') {
|
|
538
|
-
if (str && str.length) {
|
|
539
|
-
str = str.trim()
|
|
540
|
-
//add if first character is number with string character
|
|
541
|
-
if (Util.isInteger(str.charAt(0))) {
|
|
542
|
-
str = 'a' + str
|
|
543
|
-
}
|
|
544
|
-
let string = str.replace(/\s+/g, separator).toLowerCase()
|
|
545
|
-
string = string.replace('/', '')
|
|
546
|
-
string = string.replace('//', '')
|
|
547
|
-
string = string.replace('__', '_')
|
|
548
|
-
return string.replace(/[^A-Za-z0-9/_]/g, '')
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/*
|
|
553
|
-
change : orderStep
|
|
554
|
-
to : Order Step
|
|
555
|
-
*/
|
|
556
|
-
Util.fieldToName = function (str = '') {
|
|
557
|
-
let title = Util.capitalizeFirstLetter(Util.decamelize(str))
|
|
558
|
-
title = Util.replaceAll(title, '_', ' ')
|
|
559
|
-
title = Util.replaceAll(title, ' id', '')
|
|
560
|
-
title = Util.capitalizeAfterSpace(title)
|
|
561
|
-
|
|
562
|
-
const lastWords = Util.lastWord(title)
|
|
563
|
-
if (title.length > 4 && lastWords == 'Id') {
|
|
564
|
-
title = title.replace('Id', '')
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
return title
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
Util.capitalizeWord = (string = '') => {
|
|
571
|
-
return string
|
|
572
|
-
.split(' ')
|
|
573
|
-
.map((m) => m[0].toUpperCase() + m.substr(1))
|
|
574
|
-
.join(' ')
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
Util.capitalizeFirstLetter = (string = '') => {
|
|
578
|
-
return string.charAt(0).toUpperCase() + string.slice(1)
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
Util.asyncWrap = (fn) => {
|
|
582
|
-
return (req, res, next) => {
|
|
583
|
-
fn(req, res, next).catch(next)
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
Util.capitalizeAfterSpace = function (str = '') {
|
|
588
|
-
str = Util.replaceAll(str, '_', ' ')
|
|
589
|
-
return str.replace(/\w\S*/g, function (txt) {
|
|
590
|
-
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
591
|
-
})
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
Util.capitalizeAfterSpaceTitle = function (str = '') {
|
|
595
|
-
str = Util.replaceAll(str, ' ', '_')
|
|
596
|
-
return str.replace(/\w\S*/g, function (txt) {
|
|
597
|
-
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
598
|
-
})
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
Util.lastWord = function (words = '') {
|
|
602
|
-
let n = words.split(' ')
|
|
603
|
-
return n[n.length - 1]
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
Util.arrayUnShift = function (arr = [], val = '') {
|
|
607
|
-
let obj = {}
|
|
608
|
-
obj[arr[0]] = ''
|
|
609
|
-
obj[arr[1]] = ''
|
|
610
|
-
return obj
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
Util.in_array = function (needle = '', haystack = []) {
|
|
614
|
-
if (haystack.length && needle) {
|
|
615
|
-
return haystack.includes(needle)
|
|
616
|
-
} else {
|
|
617
|
-
return false
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
Util.gridSearch = function (visibles, relations, name, value) {
|
|
622
|
-
let index = 0
|
|
623
|
-
let elm = 'input'
|
|
624
|
-
for (let i = 0; i < visibles.length; i++) {
|
|
625
|
-
if (name == visibles[i]) {
|
|
626
|
-
index = i
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
if (!Util.isEmptyObject(relations)) {
|
|
630
|
-
let arr = Object.keys(relations)
|
|
631
|
-
for (let i = 0; i < arr.length; i++) {
|
|
632
|
-
if (name == arr[i]) {
|
|
633
|
-
elm = 'select'
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
return 'searchValue.eq(' + index + ').find("' + elm + '").val("' + value + '");'
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
Util.toNumber = function (num) {
|
|
641
|
-
num = num + ''
|
|
642
|
-
return parseFloat(Util.replaceAll(num, '.', ''))
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
Util.formatNumber = function (num, thousandSeparator = '.') {
|
|
646
|
-
num = num || ''
|
|
647
|
-
let sep = '$1' + thousandSeparator
|
|
648
|
-
let numString = num.toString()
|
|
649
|
-
if (numString.indexOf('.') > -1) {
|
|
650
|
-
let explode = numString.split('.')
|
|
651
|
-
return explode[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, sep) + ',' + explode[1]
|
|
652
|
-
} else {
|
|
653
|
-
return numString.replace(/(\d)(?=(\d{3})+(?!\d))/g, sep)
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
//usage Util.round(12345.6789, 2) // 12345.68
|
|
658
|
-
Util.round = (value, precision = 0) => {
|
|
659
|
-
value = +value || 0
|
|
660
|
-
var multiplier = Math.pow(10, precision)
|
|
661
|
-
return Math.round(value * multiplier) / multiplier
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
Util.fileAttribute = function (filename = '') {
|
|
665
|
-
filename = filename.toLowerCase() || ''
|
|
666
|
-
let ext = filename.split('.').pop()
|
|
667
|
-
let obj = {}
|
|
668
|
-
obj.ext = ext
|
|
669
|
-
if (Util.in_array(ext, Util.fileImage)) {
|
|
670
|
-
obj.type = 'image'
|
|
671
|
-
} else {
|
|
672
|
-
obj.type = 'file'
|
|
673
|
-
}
|
|
674
|
-
return obj
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
Util.fileImage = ['jpg', 'jpeg', 'png', 'webp', 'bmp', 'tif', 'gif', 'png', 'svg', 'avif']
|
|
678
|
-
|
|
679
|
-
Util.fileExtension = (filename = '') => {
|
|
680
|
-
filename = filename.toLowerCase() || ''
|
|
681
|
-
let obj = {}
|
|
682
|
-
let ext = filename.split('.').pop()
|
|
683
|
-
obj.ext = ext
|
|
684
|
-
if (Util.in_array(ext, Util.fileImage)) {
|
|
685
|
-
obj.type = 'image'
|
|
686
|
-
} else {
|
|
687
|
-
obj.type = 'file'
|
|
688
|
-
}
|
|
689
|
-
let file = 'file.png'
|
|
690
|
-
if (ext == 'docx' || ext == 'doc') {
|
|
691
|
-
file = 'word.png'
|
|
692
|
-
} else if (ext == 'xls' || ext == 'xlsx') {
|
|
693
|
-
file = 'excel.png'
|
|
694
|
-
} else if (ext == 'pdf') {
|
|
695
|
-
file = 'pdf.png'
|
|
696
|
-
} else if (ext == 'ppt' || ext == 'pptx') {
|
|
697
|
-
file = 'ppt.png'
|
|
698
|
-
} else if (ext == 'txt') {
|
|
699
|
-
file = 'txt.png'
|
|
700
|
-
} else if (ext == 'zip') {
|
|
701
|
-
file = 'zip.jpg'
|
|
702
|
-
} else if (ext == 'rar') {
|
|
703
|
-
file = 'rar.jpg'
|
|
704
|
-
} else if (ext == 'rar') {
|
|
705
|
-
file = 'file.png'
|
|
706
|
-
}
|
|
707
|
-
obj.file = file
|
|
708
|
-
return obj
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
Util.fileView = function (dir = '', file = '', attributes = {}) {
|
|
712
|
-
let filename = dir + file
|
|
713
|
-
let html = ''
|
|
714
|
-
let width = attributes.hasOwnProperty('width') ? attributes.width : '300'
|
|
715
|
-
let withIcon = attributes.hasOwnProperty('withIcon') ? true : false
|
|
716
|
-
let obj = Util.fileExtension(filename)
|
|
717
|
-
let className = attributes.hasOwnProperty('class') ? ` class="${attributes.class}" ` : ''
|
|
718
|
-
if (filename.includes('https')) {
|
|
719
|
-
html = `<img src="${file}" ${className} class="img-responsive">`
|
|
720
|
-
} else {
|
|
721
|
-
if (obj.type == 'image') {
|
|
722
|
-
html = `<img src="${filename}" ${className} width="${width}px">`
|
|
723
|
-
} else {
|
|
724
|
-
if (file) {
|
|
725
|
-
if (withIcon) {
|
|
726
|
-
html = `<img class="mb-3 boxy-small" src="/img/${obj.file}" height="45px" width="45px"><a class="text-success" target="_blank" href="${filename}"> ${file.substring(13)}</a>`
|
|
727
|
-
} else {
|
|
728
|
-
html = `<a class="text-success" target="_blank" href="${filename}"> ${file.substring(13)}</a>`
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
return html
|
|
735
|
-
}
|
|
736
|
-
/// end files
|
|
737
|
-
|
|
738
|
-
Util.arrayDelete = function (arr, value) {
|
|
739
|
-
return arr.filter((item) => item != value)
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
Util.arrayDeletes = function (arr = [], array = []) {
|
|
743
|
-
return arr.filter((item) => !Util.in_array(item, array))
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
Util.arrayToList = function (arr, array, delimiter, isCount) {
|
|
747
|
-
delimiter = delimiter || '<br>'
|
|
748
|
-
isCount = isCount || 1
|
|
749
|
-
let html = ''
|
|
750
|
-
if (arr) {
|
|
751
|
-
for (var i = 0; i < arr.length; i++) {
|
|
752
|
-
html += isCount == 1 ? i + 1 + '. ' + array[arr[i]] + delimiter : ' ' + array[arr[i]] + delimiter
|
|
753
|
-
}
|
|
754
|
-
html = html.slice(0, delimiter.length * -1)
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
return html
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
Util.menuAccess = function (menu, params) {
|
|
761
|
-
const roles = require('./role')
|
|
762
|
-
const routes = roles.routes
|
|
763
|
-
if (Util.in_array(menu, routes)) {
|
|
764
|
-
if (Util.in_array(menu, params)) return true
|
|
765
|
-
else return false
|
|
766
|
-
} else {
|
|
767
|
-
return true
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
Util.dropdownHelper = function (data, field, model) {
|
|
772
|
-
let fieldsx = field + '[]'
|
|
773
|
-
let name = field + '[]'
|
|
774
|
-
let myvalue = typeof data[fieldsx] == undefined ? ' ' : typeof data[fieldsx] == 'string' ? '["' + data[fieldsx] + '"]' : JSON.stringify(data[name])
|
|
775
|
-
if (myvalue) {
|
|
776
|
-
let unique = myvalue.indexOf('[') > -1 ? myvalue : !myvalue ? '' : '[' + myvalue + ']'
|
|
777
|
-
unique = JSON.parse(unique)
|
|
778
|
-
data[field] = JSON.stringify(unique.filter(Util.arrayUnique))
|
|
779
|
-
delete data[name]
|
|
780
|
-
}
|
|
781
|
-
if (model.fields[field].required) {
|
|
782
|
-
if (!data[field]) {
|
|
783
|
-
return false
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
return data
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
Util.dropdownAdd = function (data, field, model, datas) {
|
|
790
|
-
let name = field + '[]'
|
|
791
|
-
let myvalue = typeof datas == undefined ? ' ' : typeof datas == 'string' ? '["' + datas + '"]' : JSON.stringify(datas)
|
|
792
|
-
if (myvalue) {
|
|
793
|
-
let unique = myvalue.indexOf('[') > -1 ? myvalue : !myvalue ? '' : '[' + myvalue + ']'
|
|
794
|
-
unique = JSON.parse(unique)
|
|
795
|
-
myvalue = JSON.stringify(unique.filter(Util.arrayUnique))
|
|
796
|
-
delete data[name]
|
|
797
|
-
|
|
798
|
-
data[field] = myvalue
|
|
799
|
-
}
|
|
800
|
-
if (model.fields[field].required) {
|
|
801
|
-
if (!myvalue) {
|
|
802
|
-
return false
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
return data
|
|
806
|
-
}
|
|
807
|
-
//array unique
|
|
808
|
-
// array.filter(Util.arrayUnique);
|
|
809
|
-
Util.arrayUnique = (value, index, self) => {
|
|
810
|
-
return self.indexOf(value) == index
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
Util.virtualHelper = function (obj) {
|
|
814
|
-
if (Util.isEmptyObject(obj)) return
|
|
815
|
-
if (obj == undefined) return
|
|
816
|
-
|
|
817
|
-
var str = ''
|
|
818
|
-
for (var key in obj) {
|
|
819
|
-
str += ', `' + obj[key] + '` AS ' + key
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
return str
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
Util.nots = ['id', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy', 'companyId', 'created_at', 'updated_at', 'updated_by', 'created_by', 'modified_by', 'company_id', 'token', 'version', 'signin_method', 'lastLogin', 'last_login', 'forgotPassword', 'forgot_password', 'no', 'actionColumn', 'lock', 'approval_status', 'approval_history']
|
|
826
|
-
|
|
827
|
-
Util.requiredFields = function (obj = {}) {
|
|
828
|
-
var nots = Util.nots
|
|
829
|
-
var arr = []
|
|
830
|
-
for (var key in obj) {
|
|
831
|
-
if (!Util.in_array(key, nots)) {
|
|
832
|
-
if (obj[key].required == true) {
|
|
833
|
-
arr.push(key)
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
return arr
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
Util.extractDetails = function (obj = {}) {
|
|
841
|
-
let arr = []
|
|
842
|
-
for (let key in obj) {
|
|
843
|
-
if (obj[key].length > 0) {
|
|
844
|
-
for (var i = 0; i < obj[key].length; i++) {
|
|
845
|
-
arr.push(obj[key][i])
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
return arr
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
Util.arrayToConcat = function (arr = []) {
|
|
853
|
-
let str = 'CONCAT('
|
|
854
|
-
for (let i = 0; i < arr.length; i++) {
|
|
855
|
-
str += arr[i] + '," - ",'
|
|
856
|
-
}
|
|
857
|
-
str = str.slice(0, -9)
|
|
858
|
-
str += ')'
|
|
859
|
-
|
|
860
|
-
return str
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
//sequence all fields based on drag drop generator
|
|
864
|
-
Util.arraySequence = function (arr = [], left = [], right = []) {
|
|
865
|
-
let obj = Util.arrayToObject(arr, 'Field')
|
|
866
|
-
let temp = [],
|
|
867
|
-
stores = []
|
|
868
|
-
for (let i = 0; i < arr.length; i++) {
|
|
869
|
-
if (arr[i].Field == 'id') {
|
|
870
|
-
stores.push(arr[i].Field)
|
|
871
|
-
temp.push(arr[i])
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
if (Array.isArray(left)) {
|
|
875
|
-
for (let i = 0; i < left.length; i++) {
|
|
876
|
-
if (i % 2 == 0) {
|
|
877
|
-
temp.push(obj[left[i]])
|
|
878
|
-
stores.push(left[i])
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
if (Array.isArray(right)) {
|
|
883
|
-
for (let i = 0; i < right.length; i++) {
|
|
884
|
-
if (i % 2 == 0) {
|
|
885
|
-
temp.push(obj[right[i]])
|
|
886
|
-
stores.push(right[i])
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
if (Array.isArray(left)) {
|
|
891
|
-
for (let i = 0; i < left.length; i++) {
|
|
892
|
-
if (i % 2 == 1) {
|
|
893
|
-
temp.push(obj[left[i]])
|
|
894
|
-
stores.push(left[i])
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
if (Array.isArray(right)) {
|
|
899
|
-
for (let i = 0; i < right.length; i++) {
|
|
900
|
-
if (i % 2 == 1) {
|
|
901
|
-
temp.push(obj[right[i]])
|
|
902
|
-
stores.push(right[i])
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
for (let i = 0; i < arr.length; i++) {
|
|
908
|
-
const field = arr[i].Field
|
|
909
|
-
if (!Util.in_array(field, stores)) {
|
|
910
|
-
temp.push(arr[i])
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
return temp
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
Util.isInteger = (value) => {
|
|
918
|
-
return (
|
|
919
|
-
!isNaN(value) &&
|
|
920
|
-
(function (x) {
|
|
921
|
-
return (x | 0) === x
|
|
922
|
-
})(parseFloat(value))
|
|
923
|
-
)
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
Util.isEmptyArray = (arr = []) => {
|
|
927
|
-
let isArr = false
|
|
928
|
-
if (Array.isArray(arr)) {
|
|
929
|
-
if (arr.length === 0) {
|
|
930
|
-
isArr = true
|
|
931
|
-
} else {
|
|
932
|
-
isArr = arr.reduce((a, b) => (b === null ? a + 0 : a + 1), 0) === 0
|
|
933
|
-
}
|
|
934
|
-
} else {
|
|
935
|
-
isArr = true
|
|
936
|
-
}
|
|
937
|
-
return isArr
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
Util.isNumeric = function (value) {
|
|
941
|
-
return /^-?\d+$/.test(value)
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
Util.tags = function (tags = '') {
|
|
945
|
-
let html = ''
|
|
946
|
-
if (tags.indexOf(',') > -1) {
|
|
947
|
-
let explode = tags.split(',')
|
|
948
|
-
for (var i = 0; i < explode.length; i++) {
|
|
949
|
-
html += `<a href="#" rel="tag">${explode[i]}</a>`
|
|
950
|
-
}
|
|
951
|
-
} else {
|
|
952
|
-
html += `<a href="#" rel="tag">${tags}</a>`
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
return html
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
/*
|
|
959
|
-
get extension of filename
|
|
960
|
-
*/
|
|
961
|
-
|
|
962
|
-
Util.getExtensionFile = (str = '') => {
|
|
963
|
-
str = str || ''
|
|
964
|
-
let extension = str.split('.').pop()
|
|
965
|
-
extension = extension.toLowerCase()
|
|
966
|
-
let ret = extension
|
|
967
|
-
if (extension == 'jpg') {
|
|
968
|
-
ret = 'jpeg'
|
|
969
|
-
}
|
|
970
|
-
return ret
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
Util.badgeError = (msg = '') => {
|
|
974
|
-
return `<span class="badge badge-danger">${msg}</span>`
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
Util.badgeSuccess = (msg = '') => {
|
|
978
|
-
return `<span class="badge badge-success">${msg}</span>`
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
Util.alertError = function (msg = '') {
|
|
982
|
-
return `<div class="alert alert-danger" role="alert">${msg}</div>`
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
Util.alertSuccess = function (msg = '') {
|
|
986
|
-
return `<div class="alert alert-success" role="alert">${msg}</div>`
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
Util.alertInfo = function (msg = '') {
|
|
990
|
-
return `<div class="alert alert-info" role="alert">${msg}</div>`
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
Util.regexPassword = (lengthMin, lengthMax) => {
|
|
994
|
-
//minimum length
|
|
995
|
-
lengthMin = lengthMin || 6
|
|
996
|
-
lengthMax = lengthMax || 20
|
|
997
|
-
|
|
998
|
-
return new RegExp('^[a-zA-Z0-9_-]{' + lengthMin + ',' + lengthMax + '}$', 'i')
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
//huruf dan angka saja
|
|
1002
|
-
Util.regexCode = (lengthMin, lengthMax) => {
|
|
1003
|
-
lengthMin = lengthMin || 2
|
|
1004
|
-
lengthMax = lengthMax || 10
|
|
1005
|
-
|
|
1006
|
-
return new RegExp('^[A-Z0-9]{' + lengthMin + ',' + lengthMax + '}$', 'i')
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
Util.imageProfile = function (image = '') {
|
|
1010
|
-
return image ? (image.indexOf('http') > -1 ? image : '/uploads/zuser/' + image) : '/img/user.png'
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
/*
|
|
1014
|
-
Files
|
|
1015
|
-
*/
|
|
1016
|
-
Util.readFile = function (filename = '') {
|
|
1017
|
-
try {
|
|
1018
|
-
if (Util.fileExist(filename)) {
|
|
1019
|
-
const data = fs.readFileSync(filename, 'utf8')
|
|
1020
|
-
return data
|
|
1021
|
-
}
|
|
1022
|
-
} catch (err) {}
|
|
1023
|
-
return ''
|
|
1024
|
-
}
|
|
1025
|
-
//check directory if not exist create or not return true/false
|
|
1026
|
-
Util.dirExist = (dir = '', create = false) => {
|
|
1027
|
-
try {
|
|
1028
|
-
if (create) {
|
|
1029
|
-
fs.ensureDir(dir, (err) => {})
|
|
1030
|
-
}
|
|
1031
|
-
// check if directory exists
|
|
1032
|
-
if (fs.existsSync(dir)) {
|
|
1033
|
-
return true
|
|
1034
|
-
}
|
|
1035
|
-
} catch (e) {}
|
|
1036
|
-
return false
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
Util.fileExist = (filename = '') => {
|
|
1040
|
-
if (fs.existsSync(filename)) {
|
|
1041
|
-
return true
|
|
1042
|
-
}
|
|
1043
|
-
return false
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
Util.getAllFiles = (dir = '') => {
|
|
1047
|
-
let files = []
|
|
1048
|
-
try {
|
|
1049
|
-
if (Util.dirExist(dir, true)) {
|
|
1050
|
-
files = fs.readdirSync(dir)
|
|
1051
|
-
}
|
|
1052
|
-
} catch (e) {
|
|
1053
|
-
return []
|
|
1054
|
-
}
|
|
1055
|
-
return files
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
Util.writeFile = (filename = '', content = '') => {
|
|
1059
|
-
try {
|
|
1060
|
-
let dir = require('path').dirname(filename)
|
|
1061
|
-
Util.dirExist(dir, true)
|
|
1062
|
-
fs.writeFileSync(filename, content)
|
|
1063
|
-
return true
|
|
1064
|
-
} catch (e) {
|
|
1065
|
-
return false
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
Util.deleteAllFiles = (dir = '') => {
|
|
1070
|
-
try {
|
|
1071
|
-
fs.emptyDirSync(dir)
|
|
1072
|
-
return true
|
|
1073
|
-
} catch (e) {
|
|
1074
|
-
return false
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
Util.findFilesName = (arr = [], filename = '') => {
|
|
1079
|
-
return arr.filter((item) => item.includes(filename))
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
//convert image file to base64
|
|
1083
|
-
Util.imageFiletoBase64 = (imgPath) => {
|
|
1084
|
-
// read image file
|
|
1085
|
-
const base64Image = fs.readFileSync(imgPath, 'base64')
|
|
1086
|
-
const extensionName = path.extname(imgPath)
|
|
1087
|
-
return `data:image/${extensionName.split('.').pop()};base64,${base64Image}`
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
Util.getFiles = function (dir, token = '') {
|
|
1091
|
-
let arr = fs.readdirSync(dir)
|
|
1092
|
-
let folders = ''
|
|
1093
|
-
let files = ''
|
|
1094
|
-
arr.forEach(function (item) {
|
|
1095
|
-
if (item.indexOf('.') > -1) {
|
|
1096
|
-
var explode = dir.split('public/')
|
|
1097
|
-
var path = explode[1]
|
|
1098
|
-
var url = '/' + path + '/' + item
|
|
1099
|
-
var extension = item.split('.').pop()
|
|
1100
|
-
files += ` <div class="folder data-file ui-draggable ui-draggable-handle ui-selectee" data-toggle="tooltip" data-type="file" data-url="${url}" data-extension="${extension}" data-name="${item}" filename="${item}" data-original-title="${item}">
|
|
1101
|
-
<img src="/assets/images/formats/file.png" class="img-responsive ui-selectee">
|
|
1102
|
-
<p class="text-ellipsis ui-selectee">${item}</p>
|
|
1103
|
-
</div>`
|
|
1104
|
-
} else {
|
|
1105
|
-
let explode = dir.split(token)
|
|
1106
|
-
let path = explode[1] || ''
|
|
1107
|
-
let state = ''
|
|
1108
|
-
if (path == '') {
|
|
1109
|
-
state = '/' + item
|
|
1110
|
-
} else {
|
|
1111
|
-
state = path.replace(item, '') + '/' + item
|
|
1112
|
-
}
|
|
1113
|
-
folders += `<div class="folder data-folder ui-draggable ui-draggable-handle ui-droppable ui-selectee" data-toggle="tooltip" data-type="folder" data-state="${state}" data-name="${item}" data-original-title="${item}">
|
|
1114
|
-
<img src="/assets/images/folder.png" class="img-responsive ui-selectee">
|
|
1115
|
-
<p class="text-ellipsis ui-selectee">${item}</p>
|
|
1116
|
-
</div>`
|
|
1117
|
-
}
|
|
1118
|
-
})
|
|
1119
|
-
|
|
1120
|
-
return folders + files
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
Util.ejsOpen = '<%- '
|
|
1124
|
-
Util.ejsStart = '<% '
|
|
1125
|
-
Util.ejsClose = ' %>'
|
|
1126
|
-
Util.ejsFunction = (yourCode, isStatement = false) => {
|
|
1127
|
-
const open = isStatement ? Util.ejsStart : Util.ejsOpen
|
|
1128
|
-
return open + yourCode + Util.ejsClose
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
Util.attributeOptions = (obj = {}, defaultObj = {}) => {
|
|
1132
|
-
let html = ''
|
|
1133
|
-
let arr = Object.keys(defaultObj) || []
|
|
1134
|
-
for (const key in obj) {
|
|
1135
|
-
let value = obj[key]
|
|
1136
|
-
if (defaultObj.hasOwnProperty(key)) {
|
|
1137
|
-
value = defaultObj[key] + obj[key]
|
|
1138
|
-
Util.arrayDelete(arr, key)
|
|
1139
|
-
}
|
|
1140
|
-
html += ` ${key}="${value}" `
|
|
1141
|
-
}
|
|
1142
|
-
if (arr.length) {
|
|
1143
|
-
arr.map((item) => (html += ` ${item}="${defaultObj[item]}" `))
|
|
1144
|
-
}
|
|
1145
|
-
return html
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
/*
|
|
1149
|
-
array to update json array at postgresql
|
|
1150
|
-
*/
|
|
1151
|
-
Util.array_to_jsonb = (arr = []) => {
|
|
1152
|
-
let value = ''
|
|
1153
|
-
let myarr = []
|
|
1154
|
-
if (arr.length > 0) {
|
|
1155
|
-
arr.map((item) => {
|
|
1156
|
-
myarr.push(JSON.stringify(item))
|
|
1157
|
-
})
|
|
1158
|
-
}
|
|
1159
|
-
value = JSON.stringify(myarr).replace('[', '{').replaceAll(']', '}')
|
|
1160
|
-
return value
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
/*
|
|
1164
|
-
array to update array at postgresql
|
|
1165
|
-
*/
|
|
1166
|
-
Util.array_to_arraypg = (arr = []) => {
|
|
1167
|
-
let value = null
|
|
1168
|
-
if (arr.length > 0) {
|
|
1169
|
-
value = JSON.stringify(arr).replace('[', '{').replaceAll(']', '}')
|
|
1170
|
-
}
|
|
1171
|
-
return value
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
|
-
Util.userAvatar = (img = '') => {
|
|
1175
|
-
return img ? (img.includes('http') ? img : `/uploads/user/${img}`) : `/img/user.png`
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
/*
|
|
1179
|
-
SQL HELPER
|
|
1180
|
-
*/
|
|
1181
|
-
Util.selectParser = (fields = [], MYMODEL = {}) => {
|
|
1182
|
-
let table = MYMODEL.table
|
|
1183
|
-
let virtuals = []
|
|
1184
|
-
let select = ''
|
|
1185
|
-
for (var key in MYMODEL.widgets) {
|
|
1186
|
-
if (MYMODEL.widgets[key].name === 'virtual') {
|
|
1187
|
-
virtuals.push(key)
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
let arr = []
|
|
1191
|
-
fields.forEach((item) => {
|
|
1192
|
-
if (virtuals.includes(item)) {
|
|
1193
|
-
select += `${MYMODEL.widgets[item].fields},`
|
|
1194
|
-
} else if (item === 'no') {
|
|
1195
|
-
arr.push(`${table}.id`)
|
|
1196
|
-
} else if (item === 'actionColumn') {
|
|
1197
|
-
arr.push(`${table}.lock`)
|
|
1198
|
-
} else {
|
|
1199
|
-
arr.push(Util.fieldWithTable(item, MYMODEL))
|
|
1200
|
-
}
|
|
1201
|
-
})
|
|
1202
|
-
//select += `"${arr.join('","')}"`
|
|
1203
|
-
select += arr.join(',')
|
|
1204
|
-
return select
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
Util.fieldWithTable = (field, MYMODEL, isWhere = false) => {
|
|
1208
|
-
let name = ''
|
|
1209
|
-
let joinList = MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.list : []
|
|
1210
|
-
if (joinList.length > 0) {
|
|
1211
|
-
if (joinList.includes(field)) {
|
|
1212
|
-
let split = field.split('___')
|
|
1213
|
-
if (isWhere) {
|
|
1214
|
-
name = `${split[0]}.${split[1]}`
|
|
1215
|
-
} else {
|
|
1216
|
-
name = `${split[0]}.${split[1]} as ${field}`
|
|
1217
|
-
}
|
|
1218
|
-
} else {
|
|
1219
|
-
name = `${MYMODEL.table}.${field}`
|
|
1220
|
-
}
|
|
1221
|
-
} else {
|
|
1222
|
-
name = `${MYMODEL.table}.${field}`
|
|
1223
|
-
}
|
|
1224
|
-
return name
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
Util.tableWithJoin = (MYMODEL) => {
|
|
1228
|
-
return MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.sql : []
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
Util.selectMysql = (fields = [], relations = {}) => {
|
|
1232
|
-
let obj = {}
|
|
1233
|
-
let arr = []
|
|
1234
|
-
let virtuals = {}
|
|
1235
|
-
let virtualArray = []
|
|
1236
|
-
if (relations.hasOwnProperty('zvirtuals')) {
|
|
1237
|
-
virtuals = relations.zvirtuals
|
|
1238
|
-
delete relations.zvirtuals
|
|
1239
|
-
virtualArray = Object.keys(virtuals)
|
|
1240
|
-
virtualArray.forEach(function (item) {
|
|
1241
|
-
fields = Util.arrayDelete(fields, item)
|
|
1242
|
-
})
|
|
1243
|
-
}
|
|
1244
|
-
let selects = []
|
|
1245
|
-
fields.forEach(function (item) {
|
|
1246
|
-
if (item != 'actionColumn') {
|
|
1247
|
-
if (item == 'no') {
|
|
1248
|
-
selects.push('id')
|
|
1249
|
-
} else {
|
|
1250
|
-
selects.push(item)
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
})
|
|
1254
|
-
//make sure id
|
|
1255
|
-
selects.push('id')
|
|
1256
|
-
let select = `"${selects.join('","')}"`
|
|
1257
|
-
if (virtualArray.length) {
|
|
1258
|
-
for (let key in virtuals) {
|
|
1259
|
-
select += `, ${virtuals[key]} `
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
return select
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
/*
|
|
1266
|
-
Sorting array object with key name
|
|
1267
|
-
*/
|
|
1268
|
-
Util.sortArray = (arr, key) => {
|
|
1269
|
-
function compare(a, b) {
|
|
1270
|
-
if (a[key] < b[key]) {
|
|
1271
|
-
return -1
|
|
1272
|
-
}
|
|
1273
|
-
if (a[key] > b[key]) {
|
|
1274
|
-
return 1
|
|
1275
|
-
}
|
|
1276
|
-
return 0
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
return arr.sort(compare)
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
Util.cleanString = (str = '') => {
|
|
1283
|
-
return str.replaceAll('(', '').replaceAll(')', '').replaceAll('%', '').replaceAll('-', '')
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
Util.encrypt = (str, key) => {
|
|
1287
|
-
const crypto = require('crypto')
|
|
1288
|
-
var encrypt = crypto.createCipheriv('des-ede3', key, '')
|
|
1289
|
-
var theCipher = encrypt.update(str, 'utf8', 'base64')
|
|
1290
|
-
theCipher += encrypt.final('base64')
|
|
1291
|
-
theCipher = theCipher.replaceAll('/', '55ter55')
|
|
1292
|
-
return theCipher
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
Util.decrypt = (str, key) => {
|
|
1296
|
-
const crypto = require('crypto')
|
|
1297
|
-
str = str.replaceAll('55ter55', '/')
|
|
1298
|
-
var decrypt = crypto.createDecipheriv('des-ede3', key, '')
|
|
1299
|
-
var s = decrypt.update(str, 'base64', 'utf8')
|
|
1300
|
-
return s + decrypt.final('utf8')
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
Util.terbilang = (nilai) => {
|
|
1304
|
-
nilai = Math.floor(Math.abs(nilai))
|
|
1305
|
-
let huruf = ['', 'Satu', 'Dua', 'Tiga', 'Empat', 'Lima', 'Enam', 'Tujuh', 'Delapan', 'Sembilan', 'Sepuluh', 'Sebelas']
|
|
1306
|
-
let bagi = 0
|
|
1307
|
-
let penyimpanan = ''
|
|
1308
|
-
if (nilai < 12) {
|
|
1309
|
-
penyimpanan = ' ' + huruf[nilai]
|
|
1310
|
-
} else if (nilai < 20) {
|
|
1311
|
-
penyimpanan = Util.terbilang(Math.floor(nilai - 10)) + ' Belas'
|
|
1312
|
-
} else if (nilai < 100) {
|
|
1313
|
-
bagi = Math.floor(nilai / 10)
|
|
1314
|
-
penyimpanan = Util.terbilang(bagi) + ' Puluh' + Util.terbilang(nilai % 10)
|
|
1315
|
-
} else if (nilai < 200) {
|
|
1316
|
-
penyimpanan = ' Seratus' + Util.terbilang(nilai - 100)
|
|
1317
|
-
} else if (nilai < 1000) {
|
|
1318
|
-
bagi = Math.floor(nilai / 100)
|
|
1319
|
-
penyimpanan = Util.terbilang(bagi) + ' Ratus' + Util.terbilang(nilai % 100)
|
|
1320
|
-
} else if (nilai < 2000) {
|
|
1321
|
-
penyimpanan = ' Seribu' + Util.terbilang(nilai - 1000)
|
|
1322
|
-
} else if (nilai < 1000000) {
|
|
1323
|
-
bagi = Math.floor(nilai / 1000)
|
|
1324
|
-
penyimpanan = Util.terbilang(bagi) + ' Ribu' + Util.terbilang(nilai % 1000)
|
|
1325
|
-
} else if (nilai < 1000000000) {
|
|
1326
|
-
bagi = Math.floor(nilai / 1000000)
|
|
1327
|
-
penyimpanan = Util.terbilang(bagi) + ' Juta' + Util.terbilang(nilai % 1000000)
|
|
1328
|
-
} else if (nilai < 1000000000000) {
|
|
1329
|
-
bagi = Math.floor(nilai / 1000000000)
|
|
1330
|
-
penyimpanan = Util.terbilang(bagi) + ' Miliar' + Util.terbilang(nilai % 1000000000)
|
|
1331
|
-
} else if (nilai < 1000000000000000) {
|
|
1332
|
-
bagi = Math.floor(nilai / 1000000000000)
|
|
1333
|
-
penyimpanan = Util.terbilang(nilai / 1000000000000) + ' Triliun' + Util.terbilang(nilai % 1000000000000)
|
|
1334
|
-
}
|
|
1335
|
-
return penyimpanan
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
Util.array_id_to_zname = (arr) => {
|
|
1339
|
-
let r = {}
|
|
1340
|
-
arr.map((item) => {
|
|
1341
|
-
r[item.id] = item.zname;
|
|
1342
|
-
})
|
|
1343
|
-
return r;
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
Util.tableShowInGrid = (arr, qey, MYMODEL, myCache, companyId) => {
|
|
1347
|
-
try {
|
|
1348
|
-
if (typeof arr != 'object') {
|
|
1349
|
-
arr = []
|
|
1350
|
-
}
|
|
1351
|
-
arr = arr || []
|
|
1352
|
-
let html = ''
|
|
1353
|
-
let MYMODELS = myCache.get('MYMODELS');
|
|
1354
|
-
let mywidget = MYMODELS[MYMODEL.widgets[qey].table].widgets
|
|
1355
|
-
if (arr.length > 0) {
|
|
1356
|
-
html += `<table class="table table-sm table-striped table-bordered table-hover">`
|
|
1357
|
-
let json = arr[0]
|
|
1358
|
-
arr.map((item) => {
|
|
1359
|
-
html += `<tr>`
|
|
1360
|
-
for (let key in item) {
|
|
1361
|
-
var keyFields = key + 'Fields'
|
|
1362
|
-
var keyObject = key + 'Object'
|
|
1363
|
-
let value = item[key]
|
|
1364
|
-
if(mywidget[key].name == "relation"){
|
|
1365
|
-
value = value ? Util.array_id_to_zname(myCache.get(`${mywidget[key].table}_${MYMODEL.widgets[qey].table}___${key}_${companyId}`))[value] : ''
|
|
1366
|
-
} else {
|
|
1367
|
-
if (Util.isNumeric(value)) {
|
|
1368
|
-
value = Util.formatNumber(value, '.')
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
html += `<td>${value}</td>`
|
|
1373
|
-
}
|
|
1374
|
-
html += `</tr>`
|
|
1375
|
-
})
|
|
1376
|
-
html += `</table>`
|
|
1377
|
-
}
|
|
1378
|
-
return html
|
|
1379
|
-
} catch (e) {
|
|
1380
|
-
return e + ''
|
|
1381
|
-
}
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
module.exports = Util
|
|
1
|
+
const moment = require('moment')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const randomstring = require('randomstring')
|
|
4
|
+
const fs = require('fs-extra')
|
|
5
|
+
const { v4: uuidv4 } = require('uuid')
|
|
6
|
+
const sha256 = require('js-sha256')
|
|
7
|
+
|
|
8
|
+
const Util = {}
|
|
9
|
+
|
|
10
|
+
Util.tab = '\t'
|
|
11
|
+
Util.tabs = (n) => {
|
|
12
|
+
let ret = ''
|
|
13
|
+
for (var i = 0; i < n; i++) {
|
|
14
|
+
ret += Util.tab
|
|
15
|
+
}
|
|
16
|
+
return ret
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Util.NEW_LINE = '\n'
|
|
20
|
+
Util.newLine = '\r\n'
|
|
21
|
+
Util.newLines = (n) => {
|
|
22
|
+
let ret = ''
|
|
23
|
+
for (var i = 0; i < n; i++) {
|
|
24
|
+
ret += Util.newLine
|
|
25
|
+
}
|
|
26
|
+
return ret
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//sha256
|
|
30
|
+
Util.hash = (string) => {
|
|
31
|
+
return sha256(string)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Util.hashCompare = (myPlaintextPassword, hash) => {
|
|
35
|
+
return Util.hash(myPlaintextPassword) == hash
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Util.excelSequence = function () {
|
|
39
|
+
let abjads = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
|
40
|
+
let arr = abjads
|
|
41
|
+
let char = 0
|
|
42
|
+
let num = 26
|
|
43
|
+
for (let x = 2; x < 15; x++) {
|
|
44
|
+
let idx = 0
|
|
45
|
+
for (let i = 1; i <= 26; i++) {
|
|
46
|
+
arr[num] = abjads[char] + abjads[idx]
|
|
47
|
+
idx++
|
|
48
|
+
num++
|
|
49
|
+
}
|
|
50
|
+
char++
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return arr
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Util.now = function () {
|
|
57
|
+
return moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Util.nowShort = function () {
|
|
61
|
+
return moment(new Date()).format('YYYY-MM-DD')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Util.ago = (data) => {
|
|
65
|
+
return moment(data).fromNow()
|
|
66
|
+
}
|
|
67
|
+
/*
|
|
68
|
+
moment get one month ago from current
|
|
69
|
+
var monthago = moment().subtract(1, 'months').format('YYYY-MM-DD');
|
|
70
|
+
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
Util.dateSql = function (date, format) {
|
|
74
|
+
format = format || 'YYYY-MM-DD'
|
|
75
|
+
if (date && date != '0000-00-00') return moment(date).format(format)
|
|
76
|
+
else return ''
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Util.dateOriginal = function (date) {
|
|
80
|
+
if (date && date != '0000-00-00') {
|
|
81
|
+
let value = moment(date).utc(false)
|
|
82
|
+
return value
|
|
83
|
+
} else {
|
|
84
|
+
return ''
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Util.dateFormat = function (date, format) {
|
|
89
|
+
format = format || 'YYYY-MM-DD'
|
|
90
|
+
if (date && date != '0000-00-00') return moment(date).format(format)
|
|
91
|
+
else return ''
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Util.timePublic = function (date) {
|
|
95
|
+
if (date) return moment(date).format('DD MMM YYYY')
|
|
96
|
+
else return ''
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Util.timeSql = function (date, format) {
|
|
100
|
+
if (date && date != '0000-00-00 00:00:00') {
|
|
101
|
+
format = format || 'YYYY-MM-DD HH:mm:ss'
|
|
102
|
+
return moment(date).format(format)
|
|
103
|
+
} else return ''
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//moment('2017-11-30T15:00:00-07:00').diff(moment('2017-05-31T15:00:00-07:00'), 'months')
|
|
107
|
+
Util.dateDiff = (start, end, format = 'months') => {
|
|
108
|
+
let count = 0
|
|
109
|
+
if (start && end) {
|
|
110
|
+
count = moment(end).diff(moment(start), format, true)
|
|
111
|
+
}
|
|
112
|
+
return count
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
Util.getDate = function (date) {
|
|
116
|
+
date = date + '' || ''
|
|
117
|
+
if (date != '') {
|
|
118
|
+
let explode = date.split('-')
|
|
119
|
+
return {
|
|
120
|
+
year: parseInt(explode[0]),
|
|
121
|
+
month: parseInt(explode[1]),
|
|
122
|
+
date: parseInt(explode[2]),
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
return {
|
|
126
|
+
year: 0,
|
|
127
|
+
month: 0,
|
|
128
|
+
date: 0,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Util.dateIsBetween = (compare, start, end) => {
|
|
134
|
+
if (compare == '' || compare == '0000-00-00') {
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
compare = moment(compare).format('YYYY-MM-DD')
|
|
138
|
+
start = moment(start).format('YYYY-MM-DD')
|
|
139
|
+
end = moment(end).format('YYYY-MM-DD')
|
|
140
|
+
let today = moment(compare)
|
|
141
|
+
let startDate = moment(start)
|
|
142
|
+
let endDate = moment(end)
|
|
143
|
+
|
|
144
|
+
if (compare == start) {
|
|
145
|
+
return true
|
|
146
|
+
} else if (compare == end) {
|
|
147
|
+
return true
|
|
148
|
+
} else {
|
|
149
|
+
return today.isBetween(startDate, endDate)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
Util.getMonth = function (date) {
|
|
154
|
+
if (date.length > 5) {
|
|
155
|
+
let n = new Date(date)
|
|
156
|
+
let m = n.getMonth()
|
|
157
|
+
return parseInt(m) + 1
|
|
158
|
+
}
|
|
159
|
+
return 0
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Util.getYear = function (date) {
|
|
163
|
+
date = Util.dateSql(date) || ''
|
|
164
|
+
return date.slice(0, 4)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//first is smaller than second
|
|
168
|
+
Util.calculateDay = function (from, to, holidayInWeek = 0) {
|
|
169
|
+
holidayInWeek = parseInt(holidayInWeek) || 0
|
|
170
|
+
let count = 0
|
|
171
|
+
if (holidayInWeek == 1) {
|
|
172
|
+
let days = Util.enumerateDaysBetweenDates(moment(from).format('YYYY-MM-DD'), moment(to).format('YYYY-MM-DD'))
|
|
173
|
+
let countdays = days.filter((item) => parseInt(moment(item).format('d')) != 0)
|
|
174
|
+
count = countdays.length
|
|
175
|
+
} else if (holidayInWeek == 2) {
|
|
176
|
+
let days = Util.enumerateDaysBetweenDates(moment(from).format('YYYY-MM-DD'), moment(to).format('YYYY-MM-DD'))
|
|
177
|
+
let countdays = days.filter((item) => parseInt(moment(item).format('d')) != 0 && parseInt(moment(item).format('d')) != 6)
|
|
178
|
+
count = countdays.length
|
|
179
|
+
} else {
|
|
180
|
+
let a = moment(from)
|
|
181
|
+
let b = moment(to)
|
|
182
|
+
count = b.diff(a, 'days') + 1
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return count
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var getDaysBetweenDates = function (startDate, endDate) {
|
|
189
|
+
let now = startDate.clone(),
|
|
190
|
+
dates = []
|
|
191
|
+
while (now.isSameOrBefore(endDate)) {
|
|
192
|
+
dates.push(now.format('MM/DD/YYYY'))
|
|
193
|
+
now.add(1, 'days')
|
|
194
|
+
}
|
|
195
|
+
return dates
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//itterate days in array
|
|
199
|
+
Util.enumerateDaysBetweenDates = function (startDate, endDate) {
|
|
200
|
+
let now = moment(startDate).clone(),
|
|
201
|
+
dates = []
|
|
202
|
+
while (now.isSameOrBefore(endDate)) {
|
|
203
|
+
dates.push(now.format('MM/DD/YYYY'))
|
|
204
|
+
now.add(1, 'days')
|
|
205
|
+
}
|
|
206
|
+
return dates
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
Util.tableArray = function (arr = []) {
|
|
210
|
+
let r = []
|
|
211
|
+
let tables = arr[0]
|
|
212
|
+
for (let i = 0; i < tables.length; i++) {
|
|
213
|
+
for (let obj in tables[i]) {
|
|
214
|
+
r.push(tables[i][obj])
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return r
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/*
|
|
221
|
+
table array in sql to arr table name
|
|
222
|
+
only for generator
|
|
223
|
+
*/
|
|
224
|
+
Util.tableArrayToObj = (arr = []) => {
|
|
225
|
+
return arr.map((m) => Object.values(m)[0])
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Util.escapeRegExp = function (str = '') {
|
|
229
|
+
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1')
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
Util.validateEmail = function (email) {
|
|
233
|
+
let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
234
|
+
return re.test(email)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/*
|
|
238
|
+
Replace All like str_replace in PHP
|
|
239
|
+
example : Util.replaceAll("abd","a","")
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
Util.replaceAll = function (str = '', find, replace) {
|
|
243
|
+
let t = ''
|
|
244
|
+
if (Array.isArray(find)) {
|
|
245
|
+
t = str
|
|
246
|
+
for (let i = 0; i < find.length; i++) {
|
|
247
|
+
if (str.indexOf(find[i]) > -1) {
|
|
248
|
+
t = str.replace(new RegExp(Util.escapeRegExp(find[i]), 'g'), replace)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
if (typeof str == 'string') {
|
|
253
|
+
t = str.replace(new RegExp(Util.escapeRegExp(find), 'g'), replace)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return t
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
Util.phoneFixed = function (str = '') {
|
|
260
|
+
let ret = ''
|
|
261
|
+
str = Util.replaceAll(str, ' ', '')
|
|
262
|
+
let phone = str.trim()
|
|
263
|
+
phone = Util.replaceAll(phone, '-', '')
|
|
264
|
+
let first = phone.charAt(0)
|
|
265
|
+
if (first == '') {
|
|
266
|
+
ret = ''
|
|
267
|
+
} else if (first == '+') {
|
|
268
|
+
ret = phone
|
|
269
|
+
} else if (first == '0') {
|
|
270
|
+
ret = '+62' + phone.replace('0', '')
|
|
271
|
+
} else {
|
|
272
|
+
ret = '+' + phone
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return ret
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
Util.jsonSuccess = function (message = '') {
|
|
279
|
+
message = message || LANGUAGE.data_saved
|
|
280
|
+
let json = { type: 'success', status: 1, title: LANGUAGE.success, message: message }
|
|
281
|
+
|
|
282
|
+
return json
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
Util.flashError = function (message = '', errors = []) {
|
|
286
|
+
message = message || LANGUAGE.data_not_found
|
|
287
|
+
let json = { type: 'error', status: 0, title: 'Error', message: message, errors: errors }
|
|
288
|
+
|
|
289
|
+
return json
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
Util.jsonError = function (path, message) {
|
|
293
|
+
let json = {}
|
|
294
|
+
json.errorLog = 1
|
|
295
|
+
json.type = 'error'
|
|
296
|
+
json.status = 0
|
|
297
|
+
json.title = path + ' Error!'
|
|
298
|
+
json.message = message
|
|
299
|
+
json.errors = [{ path: path, message: message }]
|
|
300
|
+
|
|
301
|
+
return json
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
Util.arrayToObject = (array = [], keyField, isInteger = false) => {
|
|
305
|
+
let obj = {}
|
|
306
|
+
if (array.length) {
|
|
307
|
+
array.forEach(function (item) {
|
|
308
|
+
var name = item[keyField] == null ? 'xxxxxx' : item[keyField] == 'null' ? 'xxxxxx' : isInteger ? item[keyField] : item[keyField] + ''
|
|
309
|
+
obj[name] = item
|
|
310
|
+
})
|
|
311
|
+
}
|
|
312
|
+
return obj
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
//chase id:1,name:'test' t0 {1:'test'}
|
|
316
|
+
Util.modulesSwitch = (arr = []) => {
|
|
317
|
+
let stores = []
|
|
318
|
+
stores.push({ id: '', name: '' })
|
|
319
|
+
arr.forEach((ar, index) => {
|
|
320
|
+
stores.push({ id: index, name: ar })
|
|
321
|
+
})
|
|
322
|
+
return stores
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
Util.buildArrayObjectPrefix = function (arr = []) {
|
|
326
|
+
return Util.modulesSwitch(arr)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
Util.arrayWithObject = (array = [], key, field) => {
|
|
330
|
+
if (array.length) {
|
|
331
|
+
return array.reduce((obj, item) => {
|
|
332
|
+
obj[item[key]] = item[field]
|
|
333
|
+
return obj
|
|
334
|
+
}, {})
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/*
|
|
339
|
+
for movedupload file using single file
|
|
340
|
+
*/
|
|
341
|
+
Util.moveFile = function (buffer, filename) {
|
|
342
|
+
return new Promise(function (resolve, reject) {
|
|
343
|
+
buffer.mv(filename, function (err) {
|
|
344
|
+
if (err) {
|
|
345
|
+
reject(err)
|
|
346
|
+
} else {
|
|
347
|
+
resolve(filename)
|
|
348
|
+
}
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
Util.generateUnique = function (length, charset) {
|
|
354
|
+
let random = Util.generate(length, charset)
|
|
355
|
+
let uid = new Date().valueOf().toString(36)
|
|
356
|
+
|
|
357
|
+
return uid + random
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
Util.generate = function (length, charset) {
|
|
361
|
+
length = length || 50
|
|
362
|
+
//alphanumeric - [0-9 a-z A-Z] alphabetic - [a-z A-Z] numeric - [0-9] hex - [0-9 a-f] custom - any given characters
|
|
363
|
+
charset = charset || 'alphanumeric'
|
|
364
|
+
return randomstring.generate({
|
|
365
|
+
length: length,
|
|
366
|
+
charset: charset,
|
|
367
|
+
})
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
Util.uuid = () => {
|
|
371
|
+
return uuidv4()
|
|
372
|
+
}
|
|
373
|
+
/*
|
|
374
|
+
generate random string 8
|
|
375
|
+
*/
|
|
376
|
+
Util.random = function (length) {
|
|
377
|
+
length = length || 5
|
|
378
|
+
let text = ''
|
|
379
|
+
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
380
|
+
for (let i = 0; i < length; i++) text += possible.charAt(Math.floor(Math.random() * possible.length))
|
|
381
|
+
|
|
382
|
+
return text
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
Util.whitelist = function () {
|
|
386
|
+
return ['www', 'app', 'my', 'sintret', 'https', 'https']
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
Util.convertDate = function (d) {
|
|
390
|
+
d = d.trim()
|
|
391
|
+
let myarr = d.split(' ')
|
|
392
|
+
return myarr[2] + '-' + Util.monthConvert(myarr[1]) + '-' + myarr[0]
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// get string start from to
|
|
396
|
+
Util.cut = function (text, start, end) {
|
|
397
|
+
return text.substr(start, end)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
Util.getFormattedDate = function (date) {
|
|
401
|
+
let year = date.getFullYear()
|
|
402
|
+
let month = (1 + date.getMonth()).toString()
|
|
403
|
+
month = month.length > 1 ? month : '0' + month
|
|
404
|
+
let day = date.getDate().toString()
|
|
405
|
+
day = day.length > 1 ? day : '0' + day
|
|
406
|
+
let time = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()
|
|
407
|
+
return year + '-' + month + '-' + day + ' ' + time
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
Util.uniqueId = function () {
|
|
411
|
+
return (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase()
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
Util.typePaperSize = [
|
|
415
|
+
{ title: 'F4', description: 'FOLIO', width: 215, height: 330 },
|
|
416
|
+
{ title: 'LEGAL', description: 'LEGAL', width: 216, height: 356 },
|
|
417
|
+
{ title: 'LETTER', description: 'LETTER', width: 216, height: 279 },
|
|
418
|
+
{ title: 'A3', description: 'A3', width: 297, height: 420 },
|
|
419
|
+
{ title: 'A4', description: 'A4', width: 210, height: 297 },
|
|
420
|
+
{ title: 'A5', description: 'A5', width: 148, height: 210 },
|
|
421
|
+
{ title: 'A6', description: 'A6', width: 105, height: 148 },
|
|
422
|
+
{ title: 'A7', description: 'A7', width: 74, height: 105 },
|
|
423
|
+
{ title: 'A8', description: 'A8', width: 52, height: 74 },
|
|
424
|
+
{ title: 'A9', description: 'A9', width: 37, height: 52 },
|
|
425
|
+
{ title: 'CUSTOM', description: 'CUSTOM', width: 105, height: 148 },
|
|
426
|
+
]
|
|
427
|
+
|
|
428
|
+
Util.typeFont = [
|
|
429
|
+
'Verdana, Geneva, sans-serif',
|
|
430
|
+
'"Times New Roman", Times, serif',
|
|
431
|
+
'Georgia, serif',
|
|
432
|
+
'"Palatino Linotype", "Book Antiqua", Palatino, serif',
|
|
433
|
+
'Arial, Helvetica, sans-serif',
|
|
434
|
+
'"Arial Black", Gadget, sans-serif',
|
|
435
|
+
'"Comic Sans MS", cursive, sans-serif',
|
|
436
|
+
'Impact, Charcoal, sans-serif',
|
|
437
|
+
'"Lucida Sans Unicode", "Lucida Grande", sans-serif',
|
|
438
|
+
'Tahoma, Geneva, sans-serif',
|
|
439
|
+
'"Trebuchet MS", Helvetica, sans-serif',
|
|
440
|
+
'"Courier New", Courier, monospace',
|
|
441
|
+
'"Lucida Console", Monaco, monospace',
|
|
442
|
+
]
|
|
443
|
+
|
|
444
|
+
Util.objectToGridFormat = function (obj = {}, isInteger = false) {
|
|
445
|
+
isInteger = isInteger || false
|
|
446
|
+
let arr = []
|
|
447
|
+
arr.push({ id: '', name: '' })
|
|
448
|
+
for (let keys in obj) {
|
|
449
|
+
if (isInteger) {
|
|
450
|
+
arr.push({ id: parseInt(keys), name: obj[keys] })
|
|
451
|
+
} else {
|
|
452
|
+
arr.push({ id: keys, name: obj[keys] })
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return arr
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
Util.random = function (length = 5) {
|
|
459
|
+
let text = ''
|
|
460
|
+
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
461
|
+
for (let i = 0; i < length; i++) text += possible.charAt(Math.floor(Math.random() * possible.length))
|
|
462
|
+
|
|
463
|
+
return text
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
Util.typePrint = {
|
|
467
|
+
register: '{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"10","header":"SURAT PERINTAH KERJA","header_font":"0","header_font_size":"26"}',
|
|
468
|
+
estimation: '{"paper_size":"F4","paper_size_width":"215","paper_size_height":"330","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"ESTIMASI BIAYA PERBAIKAN","header_font":"0","header_font_size":"18"}',
|
|
469
|
+
invoice: '{"paper_size":"A5","paper_size_width":"148","paper_size_height":"210","padding_top":"8","padding_right":"8","padding_bottom":"8","padding_left":"8","border":"1","font":"0","font_size":"12","header":"INVOICE","header_font":"0","header_font_size":"18"}',
|
|
470
|
+
currency: '{"symbol":"Rp","name":"Rupiah","thousand":"."}',
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
Util.isJson = function (text) {
|
|
474
|
+
if (text) {
|
|
475
|
+
if (
|
|
476
|
+
/^[\],:{}\s]*$/.test(
|
|
477
|
+
text
|
|
478
|
+
.replace(/\\["\\\/bfnrtu]/g, '@')
|
|
479
|
+
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
|
480
|
+
.replace(/(?:^|:|,)(?:\s*\[)+/g, '')
|
|
481
|
+
)
|
|
482
|
+
) {
|
|
483
|
+
//the json is ok
|
|
484
|
+
return true
|
|
485
|
+
} else {
|
|
486
|
+
return false
|
|
487
|
+
//the json is not ok
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return false
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
Util.isEmptyObject = function (obj = {}) {
|
|
494
|
+
for (let prop in obj) {
|
|
495
|
+
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
496
|
+
return false
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return JSON.stringify(obj) === JSON.stringify({})
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
Util.serializeTable = function (table = '') {
|
|
504
|
+
return '`' + table + '`'
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
Util.getKey = function (obj = {}, field = '') {
|
|
508
|
+
let t = ''
|
|
509
|
+
for (let item in obj) {
|
|
510
|
+
if (obj[item] == field) {
|
|
511
|
+
return item
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return t
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
Util.camelize = function (text = '') {
|
|
518
|
+
return text.replace(/^([A-Z])|[\s-_]+(\w)/g, function (match, p1, p2, offset) {
|
|
519
|
+
if (p2) return p2.toUpperCase()
|
|
520
|
+
return p1.toLowerCase()
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
Util.decamelize = function (str = '', separator = '_') {
|
|
525
|
+
return str
|
|
526
|
+
.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
|
|
527
|
+
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2')
|
|
528
|
+
.replace('_', separator)
|
|
529
|
+
.toLowerCase()
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/*
|
|
533
|
+
change : Order Step
|
|
534
|
+
to : order_tep
|
|
535
|
+
*/
|
|
536
|
+
|
|
537
|
+
Util.toName = function (str = '', separator = '_') {
|
|
538
|
+
if (str && str.length) {
|
|
539
|
+
str = str.trim()
|
|
540
|
+
//add if first character is number with string character
|
|
541
|
+
if (Util.isInteger(str.charAt(0))) {
|
|
542
|
+
str = 'a' + str
|
|
543
|
+
}
|
|
544
|
+
let string = str.replace(/\s+/g, separator).toLowerCase()
|
|
545
|
+
string = string.replace('/', '')
|
|
546
|
+
string = string.replace('//', '')
|
|
547
|
+
string = string.replace('__', '_')
|
|
548
|
+
return string.replace(/[^A-Za-z0-9/_]/g, '')
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/*
|
|
553
|
+
change : orderStep
|
|
554
|
+
to : Order Step
|
|
555
|
+
*/
|
|
556
|
+
Util.fieldToName = function (str = '') {
|
|
557
|
+
let title = Util.capitalizeFirstLetter(Util.decamelize(str))
|
|
558
|
+
title = Util.replaceAll(title, '_', ' ')
|
|
559
|
+
title = Util.replaceAll(title, ' id', '')
|
|
560
|
+
title = Util.capitalizeAfterSpace(title)
|
|
561
|
+
|
|
562
|
+
const lastWords = Util.lastWord(title)
|
|
563
|
+
if (title.length > 4 && lastWords == 'Id') {
|
|
564
|
+
title = title.replace('Id', '')
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
return title
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
Util.capitalizeWord = (string = '') => {
|
|
571
|
+
return string
|
|
572
|
+
.split(' ')
|
|
573
|
+
.map((m) => m[0].toUpperCase() + m.substr(1))
|
|
574
|
+
.join(' ')
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
Util.capitalizeFirstLetter = (string = '') => {
|
|
578
|
+
return string.charAt(0).toUpperCase() + string.slice(1)
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
Util.asyncWrap = (fn) => {
|
|
582
|
+
return (req, res, next) => {
|
|
583
|
+
fn(req, res, next).catch(next)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
Util.capitalizeAfterSpace = function (str = '') {
|
|
588
|
+
str = Util.replaceAll(str, '_', ' ')
|
|
589
|
+
return str.replace(/\w\S*/g, function (txt) {
|
|
590
|
+
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
591
|
+
})
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
Util.capitalizeAfterSpaceTitle = function (str = '') {
|
|
595
|
+
str = Util.replaceAll(str, ' ', '_')
|
|
596
|
+
return str.replace(/\w\S*/g, function (txt) {
|
|
597
|
+
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
|
|
598
|
+
})
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
Util.lastWord = function (words = '') {
|
|
602
|
+
let n = words.split(' ')
|
|
603
|
+
return n[n.length - 1]
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
Util.arrayUnShift = function (arr = [], val = '') {
|
|
607
|
+
let obj = {}
|
|
608
|
+
obj[arr[0]] = ''
|
|
609
|
+
obj[arr[1]] = ''
|
|
610
|
+
return obj
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
Util.in_array = function (needle = '', haystack = []) {
|
|
614
|
+
if (haystack.length && needle) {
|
|
615
|
+
return haystack.includes(needle)
|
|
616
|
+
} else {
|
|
617
|
+
return false
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
Util.gridSearch = function (visibles, relations, name, value) {
|
|
622
|
+
let index = 0
|
|
623
|
+
let elm = 'input'
|
|
624
|
+
for (let i = 0; i < visibles.length; i++) {
|
|
625
|
+
if (name == visibles[i]) {
|
|
626
|
+
index = i
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (!Util.isEmptyObject(relations)) {
|
|
630
|
+
let arr = Object.keys(relations)
|
|
631
|
+
for (let i = 0; i < arr.length; i++) {
|
|
632
|
+
if (name == arr[i]) {
|
|
633
|
+
elm = 'select'
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return 'searchValue.eq(' + index + ').find("' + elm + '").val("' + value + '");'
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
Util.toNumber = function (num) {
|
|
641
|
+
num = num + ''
|
|
642
|
+
return parseFloat(Util.replaceAll(num, '.', ''))
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
Util.formatNumber = function (num, thousandSeparator = '.') {
|
|
646
|
+
num = num || ''
|
|
647
|
+
let sep = '$1' + thousandSeparator
|
|
648
|
+
let numString = num.toString()
|
|
649
|
+
if (numString.indexOf('.') > -1) {
|
|
650
|
+
let explode = numString.split('.')
|
|
651
|
+
return explode[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, sep) + ',' + explode[1]
|
|
652
|
+
} else {
|
|
653
|
+
return numString.replace(/(\d)(?=(\d{3})+(?!\d))/g, sep)
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
//usage Util.round(12345.6789, 2) // 12345.68
|
|
658
|
+
Util.round = (value, precision = 0) => {
|
|
659
|
+
value = +value || 0
|
|
660
|
+
var multiplier = Math.pow(10, precision)
|
|
661
|
+
return Math.round(value * multiplier) / multiplier
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
Util.fileAttribute = function (filename = '') {
|
|
665
|
+
filename = filename.toLowerCase() || ''
|
|
666
|
+
let ext = filename.split('.').pop()
|
|
667
|
+
let obj = {}
|
|
668
|
+
obj.ext = ext
|
|
669
|
+
if (Util.in_array(ext, Util.fileImage)) {
|
|
670
|
+
obj.type = 'image'
|
|
671
|
+
} else {
|
|
672
|
+
obj.type = 'file'
|
|
673
|
+
}
|
|
674
|
+
return obj
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
Util.fileImage = ['jpg', 'jpeg', 'png', 'webp', 'bmp', 'tif', 'gif', 'png', 'svg', 'avif']
|
|
678
|
+
|
|
679
|
+
Util.fileExtension = (filename = '') => {
|
|
680
|
+
filename = filename.toLowerCase() || ''
|
|
681
|
+
let obj = {}
|
|
682
|
+
let ext = filename.split('.').pop()
|
|
683
|
+
obj.ext = ext
|
|
684
|
+
if (Util.in_array(ext, Util.fileImage)) {
|
|
685
|
+
obj.type = 'image'
|
|
686
|
+
} else {
|
|
687
|
+
obj.type = 'file'
|
|
688
|
+
}
|
|
689
|
+
let file = 'file.png'
|
|
690
|
+
if (ext == 'docx' || ext == 'doc') {
|
|
691
|
+
file = 'word.png'
|
|
692
|
+
} else if (ext == 'xls' || ext == 'xlsx') {
|
|
693
|
+
file = 'excel.png'
|
|
694
|
+
} else if (ext == 'pdf') {
|
|
695
|
+
file = 'pdf.png'
|
|
696
|
+
} else if (ext == 'ppt' || ext == 'pptx') {
|
|
697
|
+
file = 'ppt.png'
|
|
698
|
+
} else if (ext == 'txt') {
|
|
699
|
+
file = 'txt.png'
|
|
700
|
+
} else if (ext == 'zip') {
|
|
701
|
+
file = 'zip.jpg'
|
|
702
|
+
} else if (ext == 'rar') {
|
|
703
|
+
file = 'rar.jpg'
|
|
704
|
+
} else if (ext == 'rar') {
|
|
705
|
+
file = 'file.png'
|
|
706
|
+
}
|
|
707
|
+
obj.file = file
|
|
708
|
+
return obj
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
Util.fileView = function (dir = '', file = '', attributes = {}) {
|
|
712
|
+
let filename = dir + file
|
|
713
|
+
let html = ''
|
|
714
|
+
let width = attributes.hasOwnProperty('width') ? attributes.width : '300'
|
|
715
|
+
let withIcon = attributes.hasOwnProperty('withIcon') ? true : false
|
|
716
|
+
let obj = Util.fileExtension(filename)
|
|
717
|
+
let className = attributes.hasOwnProperty('class') ? ` class="${attributes.class}" ` : ''
|
|
718
|
+
if (filename.includes('https')) {
|
|
719
|
+
html = `<img src="${file}" ${className} class="img-responsive">`
|
|
720
|
+
} else {
|
|
721
|
+
if (obj.type == 'image') {
|
|
722
|
+
html = `<img src="${filename}" ${className} width="${width}px">`
|
|
723
|
+
} else {
|
|
724
|
+
if (file) {
|
|
725
|
+
if (withIcon) {
|
|
726
|
+
html = `<img class="mb-3 boxy-small" src="/img/${obj.file}" height="45px" width="45px"><a class="text-success" target="_blank" href="${filename}"> ${file.substring(13)}</a>`
|
|
727
|
+
} else {
|
|
728
|
+
html = `<a class="text-success" target="_blank" href="${filename}"> ${file.substring(13)}</a>`
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return html
|
|
735
|
+
}
|
|
736
|
+
/// end files
|
|
737
|
+
|
|
738
|
+
Util.arrayDelete = function (arr, value) {
|
|
739
|
+
return arr.filter((item) => item != value)
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
Util.arrayDeletes = function (arr = [], array = []) {
|
|
743
|
+
return arr.filter((item) => !Util.in_array(item, array))
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
Util.arrayToList = function (arr, array, delimiter, isCount) {
|
|
747
|
+
delimiter = delimiter || '<br>'
|
|
748
|
+
isCount = isCount || 1
|
|
749
|
+
let html = ''
|
|
750
|
+
if (arr) {
|
|
751
|
+
for (var i = 0; i < arr.length; i++) {
|
|
752
|
+
html += isCount == 1 ? i + 1 + '. ' + array[arr[i]] + delimiter : ' ' + array[arr[i]] + delimiter
|
|
753
|
+
}
|
|
754
|
+
html = html.slice(0, delimiter.length * -1)
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return html
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
Util.menuAccess = function (menu, params) {
|
|
761
|
+
const roles = require('./role')
|
|
762
|
+
const routes = roles.routes
|
|
763
|
+
if (Util.in_array(menu, routes)) {
|
|
764
|
+
if (Util.in_array(menu, params)) return true
|
|
765
|
+
else return false
|
|
766
|
+
} else {
|
|
767
|
+
return true
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
Util.dropdownHelper = function (data, field, model) {
|
|
772
|
+
let fieldsx = field + '[]'
|
|
773
|
+
let name = field + '[]'
|
|
774
|
+
let myvalue = typeof data[fieldsx] == undefined ? ' ' : typeof data[fieldsx] == 'string' ? '["' + data[fieldsx] + '"]' : JSON.stringify(data[name])
|
|
775
|
+
if (myvalue) {
|
|
776
|
+
let unique = myvalue.indexOf('[') > -1 ? myvalue : !myvalue ? '' : '[' + myvalue + ']'
|
|
777
|
+
unique = JSON.parse(unique)
|
|
778
|
+
data[field] = JSON.stringify(unique.filter(Util.arrayUnique))
|
|
779
|
+
delete data[name]
|
|
780
|
+
}
|
|
781
|
+
if (model.fields[field].required) {
|
|
782
|
+
if (!data[field]) {
|
|
783
|
+
return false
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return data
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
Util.dropdownAdd = function (data, field, model, datas) {
|
|
790
|
+
let name = field + '[]'
|
|
791
|
+
let myvalue = typeof datas == undefined ? ' ' : typeof datas == 'string' ? '["' + datas + '"]' : JSON.stringify(datas)
|
|
792
|
+
if (myvalue) {
|
|
793
|
+
let unique = myvalue.indexOf('[') > -1 ? myvalue : !myvalue ? '' : '[' + myvalue + ']'
|
|
794
|
+
unique = JSON.parse(unique)
|
|
795
|
+
myvalue = JSON.stringify(unique.filter(Util.arrayUnique))
|
|
796
|
+
delete data[name]
|
|
797
|
+
|
|
798
|
+
data[field] = myvalue
|
|
799
|
+
}
|
|
800
|
+
if (model.fields[field].required) {
|
|
801
|
+
if (!myvalue) {
|
|
802
|
+
return false
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return data
|
|
806
|
+
}
|
|
807
|
+
//array unique
|
|
808
|
+
// array.filter(Util.arrayUnique);
|
|
809
|
+
Util.arrayUnique = (value, index, self) => {
|
|
810
|
+
return self.indexOf(value) == index
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
Util.virtualHelper = function (obj) {
|
|
814
|
+
if (Util.isEmptyObject(obj)) return
|
|
815
|
+
if (obj == undefined) return
|
|
816
|
+
|
|
817
|
+
var str = ''
|
|
818
|
+
for (var key in obj) {
|
|
819
|
+
str += ', `' + obj[key] + '` AS ' + key
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
return str
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
Util.nots = ['id', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy', 'companyId', 'created_at', 'updated_at', 'updated_by', 'created_by', 'modified_by', 'company_id', 'token', 'version', 'signin_method', 'lastLogin', 'last_login', 'forgotPassword', 'forgot_password', 'no', 'actionColumn', 'lock', 'approval_status', 'approval_history']
|
|
826
|
+
|
|
827
|
+
Util.requiredFields = function (obj = {}) {
|
|
828
|
+
var nots = Util.nots
|
|
829
|
+
var arr = []
|
|
830
|
+
for (var key in obj) {
|
|
831
|
+
if (!Util.in_array(key, nots)) {
|
|
832
|
+
if (obj[key].required == true) {
|
|
833
|
+
arr.push(key)
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return arr
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
Util.extractDetails = function (obj = {}) {
|
|
841
|
+
let arr = []
|
|
842
|
+
for (let key in obj) {
|
|
843
|
+
if (obj[key].length > 0) {
|
|
844
|
+
for (var i = 0; i < obj[key].length; i++) {
|
|
845
|
+
arr.push(obj[key][i])
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return arr
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
Util.arrayToConcat = function (arr = []) {
|
|
853
|
+
let str = 'CONCAT('
|
|
854
|
+
for (let i = 0; i < arr.length; i++) {
|
|
855
|
+
str += arr[i] + '," - ",'
|
|
856
|
+
}
|
|
857
|
+
str = str.slice(0, -9)
|
|
858
|
+
str += ')'
|
|
859
|
+
|
|
860
|
+
return str
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
//sequence all fields based on drag drop generator
|
|
864
|
+
Util.arraySequence = function (arr = [], left = [], right = []) {
|
|
865
|
+
let obj = Util.arrayToObject(arr, 'Field')
|
|
866
|
+
let temp = [],
|
|
867
|
+
stores = []
|
|
868
|
+
for (let i = 0; i < arr.length; i++) {
|
|
869
|
+
if (arr[i].Field == 'id') {
|
|
870
|
+
stores.push(arr[i].Field)
|
|
871
|
+
temp.push(arr[i])
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
if (Array.isArray(left)) {
|
|
875
|
+
for (let i = 0; i < left.length; i++) {
|
|
876
|
+
if (i % 2 == 0) {
|
|
877
|
+
temp.push(obj[left[i]])
|
|
878
|
+
stores.push(left[i])
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (Array.isArray(right)) {
|
|
883
|
+
for (let i = 0; i < right.length; i++) {
|
|
884
|
+
if (i % 2 == 0) {
|
|
885
|
+
temp.push(obj[right[i]])
|
|
886
|
+
stores.push(right[i])
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (Array.isArray(left)) {
|
|
891
|
+
for (let i = 0; i < left.length; i++) {
|
|
892
|
+
if (i % 2 == 1) {
|
|
893
|
+
temp.push(obj[left[i]])
|
|
894
|
+
stores.push(left[i])
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
if (Array.isArray(right)) {
|
|
899
|
+
for (let i = 0; i < right.length; i++) {
|
|
900
|
+
if (i % 2 == 1) {
|
|
901
|
+
temp.push(obj[right[i]])
|
|
902
|
+
stores.push(right[i])
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
for (let i = 0; i < arr.length; i++) {
|
|
908
|
+
const field = arr[i].Field
|
|
909
|
+
if (!Util.in_array(field, stores)) {
|
|
910
|
+
temp.push(arr[i])
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
return temp
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
Util.isInteger = (value) => {
|
|
918
|
+
return (
|
|
919
|
+
!isNaN(value) &&
|
|
920
|
+
(function (x) {
|
|
921
|
+
return (x | 0) === x
|
|
922
|
+
})(parseFloat(value))
|
|
923
|
+
)
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
Util.isEmptyArray = (arr = []) => {
|
|
927
|
+
let isArr = false
|
|
928
|
+
if (Array.isArray(arr)) {
|
|
929
|
+
if (arr.length === 0) {
|
|
930
|
+
isArr = true
|
|
931
|
+
} else {
|
|
932
|
+
isArr = arr.reduce((a, b) => (b === null ? a + 0 : a + 1), 0) === 0
|
|
933
|
+
}
|
|
934
|
+
} else {
|
|
935
|
+
isArr = true
|
|
936
|
+
}
|
|
937
|
+
return isArr
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
Util.isNumeric = function (value) {
|
|
941
|
+
return /^-?\d+$/.test(value)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
Util.tags = function (tags = '') {
|
|
945
|
+
let html = ''
|
|
946
|
+
if (tags.indexOf(',') > -1) {
|
|
947
|
+
let explode = tags.split(',')
|
|
948
|
+
for (var i = 0; i < explode.length; i++) {
|
|
949
|
+
html += `<a href="#" rel="tag">${explode[i]}</a>`
|
|
950
|
+
}
|
|
951
|
+
} else {
|
|
952
|
+
html += `<a href="#" rel="tag">${tags}</a>`
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
return html
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/*
|
|
959
|
+
get extension of filename
|
|
960
|
+
*/
|
|
961
|
+
|
|
962
|
+
Util.getExtensionFile = (str = '') => {
|
|
963
|
+
str = str || ''
|
|
964
|
+
let extension = str.split('.').pop()
|
|
965
|
+
extension = extension.toLowerCase()
|
|
966
|
+
let ret = extension
|
|
967
|
+
if (extension == 'jpg') {
|
|
968
|
+
ret = 'jpeg'
|
|
969
|
+
}
|
|
970
|
+
return ret
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
Util.badgeError = (msg = '') => {
|
|
974
|
+
return `<span class="badge badge-danger">${msg}</span>`
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
Util.badgeSuccess = (msg = '') => {
|
|
978
|
+
return `<span class="badge badge-success">${msg}</span>`
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
Util.alertError = function (msg = '') {
|
|
982
|
+
return `<div class="alert alert-danger" role="alert">${msg}</div>`
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
Util.alertSuccess = function (msg = '') {
|
|
986
|
+
return `<div class="alert alert-success" role="alert">${msg}</div>`
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
Util.alertInfo = function (msg = '') {
|
|
990
|
+
return `<div class="alert alert-info" role="alert">${msg}</div>`
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
Util.regexPassword = (lengthMin, lengthMax) => {
|
|
994
|
+
//minimum length
|
|
995
|
+
lengthMin = lengthMin || 6
|
|
996
|
+
lengthMax = lengthMax || 20
|
|
997
|
+
|
|
998
|
+
return new RegExp('^[a-zA-Z0-9_-]{' + lengthMin + ',' + lengthMax + '}$', 'i')
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
//huruf dan angka saja
|
|
1002
|
+
Util.regexCode = (lengthMin, lengthMax) => {
|
|
1003
|
+
lengthMin = lengthMin || 2
|
|
1004
|
+
lengthMax = lengthMax || 10
|
|
1005
|
+
|
|
1006
|
+
return new RegExp('^[A-Z0-9]{' + lengthMin + ',' + lengthMax + '}$', 'i')
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
Util.imageProfile = function (image = '') {
|
|
1010
|
+
return image ? (image.indexOf('http') > -1 ? image : '/uploads/zuser/' + image) : '/img/user.png'
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/*
|
|
1014
|
+
Files
|
|
1015
|
+
*/
|
|
1016
|
+
Util.readFile = function (filename = '') {
|
|
1017
|
+
try {
|
|
1018
|
+
if (Util.fileExist(filename)) {
|
|
1019
|
+
const data = fs.readFileSync(filename, 'utf8')
|
|
1020
|
+
return data
|
|
1021
|
+
}
|
|
1022
|
+
} catch (err) {}
|
|
1023
|
+
return ''
|
|
1024
|
+
}
|
|
1025
|
+
//check directory if not exist create or not return true/false
|
|
1026
|
+
Util.dirExist = (dir = '', create = false) => {
|
|
1027
|
+
try {
|
|
1028
|
+
if (create) {
|
|
1029
|
+
fs.ensureDir(dir, (err) => {})
|
|
1030
|
+
}
|
|
1031
|
+
// check if directory exists
|
|
1032
|
+
if (fs.existsSync(dir)) {
|
|
1033
|
+
return true
|
|
1034
|
+
}
|
|
1035
|
+
} catch (e) {}
|
|
1036
|
+
return false
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
Util.fileExist = (filename = '') => {
|
|
1040
|
+
if (fs.existsSync(filename)) {
|
|
1041
|
+
return true
|
|
1042
|
+
}
|
|
1043
|
+
return false
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
Util.getAllFiles = (dir = '') => {
|
|
1047
|
+
let files = []
|
|
1048
|
+
try {
|
|
1049
|
+
if (Util.dirExist(dir, true)) {
|
|
1050
|
+
files = fs.readdirSync(dir)
|
|
1051
|
+
}
|
|
1052
|
+
} catch (e) {
|
|
1053
|
+
return []
|
|
1054
|
+
}
|
|
1055
|
+
return files
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
Util.writeFile = (filename = '', content = '') => {
|
|
1059
|
+
try {
|
|
1060
|
+
let dir = require('path').dirname(filename)
|
|
1061
|
+
Util.dirExist(dir, true)
|
|
1062
|
+
fs.writeFileSync(filename, content)
|
|
1063
|
+
return true
|
|
1064
|
+
} catch (e) {
|
|
1065
|
+
return false
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
Util.deleteAllFiles = (dir = '') => {
|
|
1070
|
+
try {
|
|
1071
|
+
fs.emptyDirSync(dir)
|
|
1072
|
+
return true
|
|
1073
|
+
} catch (e) {
|
|
1074
|
+
return false
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
Util.findFilesName = (arr = [], filename = '') => {
|
|
1079
|
+
return arr.filter((item) => item.includes(filename))
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
//convert image file to base64
|
|
1083
|
+
Util.imageFiletoBase64 = (imgPath) => {
|
|
1084
|
+
// read image file
|
|
1085
|
+
const base64Image = fs.readFileSync(imgPath, 'base64')
|
|
1086
|
+
const extensionName = path.extname(imgPath)
|
|
1087
|
+
return `data:image/${extensionName.split('.').pop()};base64,${base64Image}`
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
Util.getFiles = function (dir, token = '') {
|
|
1091
|
+
let arr = fs.readdirSync(dir)
|
|
1092
|
+
let folders = ''
|
|
1093
|
+
let files = ''
|
|
1094
|
+
arr.forEach(function (item) {
|
|
1095
|
+
if (item.indexOf('.') > -1) {
|
|
1096
|
+
var explode = dir.split('public/')
|
|
1097
|
+
var path = explode[1]
|
|
1098
|
+
var url = '/' + path + '/' + item
|
|
1099
|
+
var extension = item.split('.').pop()
|
|
1100
|
+
files += ` <div class="folder data-file ui-draggable ui-draggable-handle ui-selectee" data-toggle="tooltip" data-type="file" data-url="${url}" data-extension="${extension}" data-name="${item}" filename="${item}" data-original-title="${item}">
|
|
1101
|
+
<img src="/assets/images/formats/file.png" class="img-responsive ui-selectee">
|
|
1102
|
+
<p class="text-ellipsis ui-selectee">${item}</p>
|
|
1103
|
+
</div>`
|
|
1104
|
+
} else {
|
|
1105
|
+
let explode = dir.split(token)
|
|
1106
|
+
let path = explode[1] || ''
|
|
1107
|
+
let state = ''
|
|
1108
|
+
if (path == '') {
|
|
1109
|
+
state = '/' + item
|
|
1110
|
+
} else {
|
|
1111
|
+
state = path.replace(item, '') + '/' + item
|
|
1112
|
+
}
|
|
1113
|
+
folders += `<div class="folder data-folder ui-draggable ui-draggable-handle ui-droppable ui-selectee" data-toggle="tooltip" data-type="folder" data-state="${state}" data-name="${item}" data-original-title="${item}">
|
|
1114
|
+
<img src="/assets/images/folder.png" class="img-responsive ui-selectee">
|
|
1115
|
+
<p class="text-ellipsis ui-selectee">${item}</p>
|
|
1116
|
+
</div>`
|
|
1117
|
+
}
|
|
1118
|
+
})
|
|
1119
|
+
|
|
1120
|
+
return folders + files
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
Util.ejsOpen = '<%- '
|
|
1124
|
+
Util.ejsStart = '<% '
|
|
1125
|
+
Util.ejsClose = ' %>'
|
|
1126
|
+
Util.ejsFunction = (yourCode, isStatement = false) => {
|
|
1127
|
+
const open = isStatement ? Util.ejsStart : Util.ejsOpen
|
|
1128
|
+
return open + yourCode + Util.ejsClose
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
Util.attributeOptions = (obj = {}, defaultObj = {}) => {
|
|
1132
|
+
let html = ''
|
|
1133
|
+
let arr = Object.keys(defaultObj) || []
|
|
1134
|
+
for (const key in obj) {
|
|
1135
|
+
let value = obj[key]
|
|
1136
|
+
if (defaultObj.hasOwnProperty(key)) {
|
|
1137
|
+
value = defaultObj[key] + obj[key]
|
|
1138
|
+
Util.arrayDelete(arr, key)
|
|
1139
|
+
}
|
|
1140
|
+
html += ` ${key}="${value}" `
|
|
1141
|
+
}
|
|
1142
|
+
if (arr.length) {
|
|
1143
|
+
arr.map((item) => (html += ` ${item}="${defaultObj[item]}" `))
|
|
1144
|
+
}
|
|
1145
|
+
return html
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/*
|
|
1149
|
+
array to update json array at postgresql
|
|
1150
|
+
*/
|
|
1151
|
+
Util.array_to_jsonb = (arr = []) => {
|
|
1152
|
+
let value = ''
|
|
1153
|
+
let myarr = []
|
|
1154
|
+
if (arr.length > 0) {
|
|
1155
|
+
arr.map((item) => {
|
|
1156
|
+
myarr.push(JSON.stringify(item))
|
|
1157
|
+
})
|
|
1158
|
+
}
|
|
1159
|
+
value = JSON.stringify(myarr).replace('[', '{').replaceAll(']', '}')
|
|
1160
|
+
return value
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/*
|
|
1164
|
+
array to update array at postgresql
|
|
1165
|
+
*/
|
|
1166
|
+
Util.array_to_arraypg = (arr = []) => {
|
|
1167
|
+
let value = null
|
|
1168
|
+
if (arr.length > 0) {
|
|
1169
|
+
value = JSON.stringify(arr).replace('[', '{').replaceAll(']', '}')
|
|
1170
|
+
}
|
|
1171
|
+
return value
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
Util.userAvatar = (img = '') => {
|
|
1175
|
+
return img ? (img.includes('http') ? img : `/uploads/user/${img}`) : `/img/user.png`
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/*
|
|
1179
|
+
SQL HELPER
|
|
1180
|
+
*/
|
|
1181
|
+
Util.selectParser = (fields = [], MYMODEL = {}) => {
|
|
1182
|
+
let table = MYMODEL.table
|
|
1183
|
+
let virtuals = []
|
|
1184
|
+
let select = ''
|
|
1185
|
+
for (var key in MYMODEL.widgets) {
|
|
1186
|
+
if (MYMODEL.widgets[key].name === 'virtual') {
|
|
1187
|
+
virtuals.push(key)
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
let arr = []
|
|
1191
|
+
fields.forEach((item) => {
|
|
1192
|
+
if (virtuals.includes(item)) {
|
|
1193
|
+
select += `${MYMODEL.widgets[item].fields},`
|
|
1194
|
+
} else if (item === 'no') {
|
|
1195
|
+
arr.push(`${table}.id`)
|
|
1196
|
+
} else if (item === 'actionColumn') {
|
|
1197
|
+
arr.push(`${table}.lock`)
|
|
1198
|
+
} else {
|
|
1199
|
+
arr.push(Util.fieldWithTable(item, MYMODEL))
|
|
1200
|
+
}
|
|
1201
|
+
})
|
|
1202
|
+
//select += `"${arr.join('","')}"`
|
|
1203
|
+
select += arr.join(',')
|
|
1204
|
+
return select
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
Util.fieldWithTable = (field, MYMODEL, isWhere = false) => {
|
|
1208
|
+
let name = ''
|
|
1209
|
+
let joinList = MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.list : []
|
|
1210
|
+
if (joinList.length > 0) {
|
|
1211
|
+
if (joinList.includes(field)) {
|
|
1212
|
+
let split = field.split('___')
|
|
1213
|
+
if (isWhere) {
|
|
1214
|
+
name = `${split[0]}.${split[1]}`
|
|
1215
|
+
} else {
|
|
1216
|
+
name = `${split[0]}.${split[1]} as ${field}`
|
|
1217
|
+
}
|
|
1218
|
+
} else {
|
|
1219
|
+
name = `${MYMODEL.table}.${field}`
|
|
1220
|
+
}
|
|
1221
|
+
} else {
|
|
1222
|
+
name = `${MYMODEL.table}.${field}`
|
|
1223
|
+
}
|
|
1224
|
+
return name
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
Util.tableWithJoin = (MYMODEL) => {
|
|
1228
|
+
return MYMODEL.joins && MYMODEL.joins.list.length > 0 ? MYMODEL.joins.sql : []
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
Util.selectMysql = (fields = [], relations = {}) => {
|
|
1232
|
+
let obj = {}
|
|
1233
|
+
let arr = []
|
|
1234
|
+
let virtuals = {}
|
|
1235
|
+
let virtualArray = []
|
|
1236
|
+
if (relations.hasOwnProperty('zvirtuals')) {
|
|
1237
|
+
virtuals = relations.zvirtuals
|
|
1238
|
+
delete relations.zvirtuals
|
|
1239
|
+
virtualArray = Object.keys(virtuals)
|
|
1240
|
+
virtualArray.forEach(function (item) {
|
|
1241
|
+
fields = Util.arrayDelete(fields, item)
|
|
1242
|
+
})
|
|
1243
|
+
}
|
|
1244
|
+
let selects = []
|
|
1245
|
+
fields.forEach(function (item) {
|
|
1246
|
+
if (item != 'actionColumn') {
|
|
1247
|
+
if (item == 'no') {
|
|
1248
|
+
selects.push('id')
|
|
1249
|
+
} else {
|
|
1250
|
+
selects.push(item)
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
})
|
|
1254
|
+
//make sure id
|
|
1255
|
+
selects.push('id')
|
|
1256
|
+
let select = `"${selects.join('","')}"`
|
|
1257
|
+
if (virtualArray.length) {
|
|
1258
|
+
for (let key in virtuals) {
|
|
1259
|
+
select += `, ${virtuals[key]} `
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
return select
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/*
|
|
1266
|
+
Sorting array object with key name
|
|
1267
|
+
*/
|
|
1268
|
+
Util.sortArray = (arr, key) => {
|
|
1269
|
+
function compare(a, b) {
|
|
1270
|
+
if (a[key] < b[key]) {
|
|
1271
|
+
return -1
|
|
1272
|
+
}
|
|
1273
|
+
if (a[key] > b[key]) {
|
|
1274
|
+
return 1
|
|
1275
|
+
}
|
|
1276
|
+
return 0
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
return arr.sort(compare)
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
Util.cleanString = (str = '') => {
|
|
1283
|
+
return str.replaceAll('(', '').replaceAll(')', '').replaceAll('%', '').replaceAll('-', '')
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
Util.encrypt = (str, key) => {
|
|
1287
|
+
const crypto = require('crypto')
|
|
1288
|
+
var encrypt = crypto.createCipheriv('des-ede3', key, '')
|
|
1289
|
+
var theCipher = encrypt.update(str, 'utf8', 'base64')
|
|
1290
|
+
theCipher += encrypt.final('base64')
|
|
1291
|
+
theCipher = theCipher.replaceAll('/', '55ter55')
|
|
1292
|
+
return theCipher
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
Util.decrypt = (str, key) => {
|
|
1296
|
+
const crypto = require('crypto')
|
|
1297
|
+
str = str.replaceAll('55ter55', '/')
|
|
1298
|
+
var decrypt = crypto.createDecipheriv('des-ede3', key, '')
|
|
1299
|
+
var s = decrypt.update(str, 'base64', 'utf8')
|
|
1300
|
+
return s + decrypt.final('utf8')
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
Util.terbilang = (nilai) => {
|
|
1304
|
+
nilai = Math.floor(Math.abs(nilai))
|
|
1305
|
+
let huruf = ['', 'Satu', 'Dua', 'Tiga', 'Empat', 'Lima', 'Enam', 'Tujuh', 'Delapan', 'Sembilan', 'Sepuluh', 'Sebelas']
|
|
1306
|
+
let bagi = 0
|
|
1307
|
+
let penyimpanan = ''
|
|
1308
|
+
if (nilai < 12) {
|
|
1309
|
+
penyimpanan = ' ' + huruf[nilai]
|
|
1310
|
+
} else if (nilai < 20) {
|
|
1311
|
+
penyimpanan = Util.terbilang(Math.floor(nilai - 10)) + ' Belas'
|
|
1312
|
+
} else if (nilai < 100) {
|
|
1313
|
+
bagi = Math.floor(nilai / 10)
|
|
1314
|
+
penyimpanan = Util.terbilang(bagi) + ' Puluh' + Util.terbilang(nilai % 10)
|
|
1315
|
+
} else if (nilai < 200) {
|
|
1316
|
+
penyimpanan = ' Seratus' + Util.terbilang(nilai - 100)
|
|
1317
|
+
} else if (nilai < 1000) {
|
|
1318
|
+
bagi = Math.floor(nilai / 100)
|
|
1319
|
+
penyimpanan = Util.terbilang(bagi) + ' Ratus' + Util.terbilang(nilai % 100)
|
|
1320
|
+
} else if (nilai < 2000) {
|
|
1321
|
+
penyimpanan = ' Seribu' + Util.terbilang(nilai - 1000)
|
|
1322
|
+
} else if (nilai < 1000000) {
|
|
1323
|
+
bagi = Math.floor(nilai / 1000)
|
|
1324
|
+
penyimpanan = Util.terbilang(bagi) + ' Ribu' + Util.terbilang(nilai % 1000)
|
|
1325
|
+
} else if (nilai < 1000000000) {
|
|
1326
|
+
bagi = Math.floor(nilai / 1000000)
|
|
1327
|
+
penyimpanan = Util.terbilang(bagi) + ' Juta' + Util.terbilang(nilai % 1000000)
|
|
1328
|
+
} else if (nilai < 1000000000000) {
|
|
1329
|
+
bagi = Math.floor(nilai / 1000000000)
|
|
1330
|
+
penyimpanan = Util.terbilang(bagi) + ' Miliar' + Util.terbilang(nilai % 1000000000)
|
|
1331
|
+
} else if (nilai < 1000000000000000) {
|
|
1332
|
+
bagi = Math.floor(nilai / 1000000000000)
|
|
1333
|
+
penyimpanan = Util.terbilang(nilai / 1000000000000) + ' Triliun' + Util.terbilang(nilai % 1000000000000)
|
|
1334
|
+
}
|
|
1335
|
+
return penyimpanan
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
Util.array_id_to_zname = (arr) => {
|
|
1339
|
+
let r = {}
|
|
1340
|
+
arr.map((item) => {
|
|
1341
|
+
r[item.id] = item.zname;
|
|
1342
|
+
})
|
|
1343
|
+
return r;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
Util.tableShowInGrid = (arr, qey, MYMODEL, myCache, companyId) => {
|
|
1347
|
+
try {
|
|
1348
|
+
if (typeof arr != 'object') {
|
|
1349
|
+
arr = []
|
|
1350
|
+
}
|
|
1351
|
+
arr = arr || []
|
|
1352
|
+
let html = ''
|
|
1353
|
+
let MYMODELS = myCache.get('MYMODELS');
|
|
1354
|
+
let mywidget = MYMODELS[MYMODEL.widgets[qey].table].widgets
|
|
1355
|
+
if (arr.length > 0) {
|
|
1356
|
+
html += `<table class="table table-sm table-striped table-bordered table-hover">`
|
|
1357
|
+
let json = arr[0]
|
|
1358
|
+
arr.map((item) => {
|
|
1359
|
+
html += `<tr>`
|
|
1360
|
+
for (let key in item) {
|
|
1361
|
+
var keyFields = key + 'Fields'
|
|
1362
|
+
var keyObject = key + 'Object'
|
|
1363
|
+
let value = item[key]
|
|
1364
|
+
if(mywidget[key].name == "relation"){
|
|
1365
|
+
value = value ? Util.array_id_to_zname(myCache.get(`${mywidget[key].table}_${MYMODEL.widgets[qey].table}___${key}_${companyId}`))[value] : ''
|
|
1366
|
+
} else {
|
|
1367
|
+
if (Util.isNumeric(value)) {
|
|
1368
|
+
value = Util.formatNumber(value, '.')
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
html += `<td>${value}</td>`
|
|
1373
|
+
}
|
|
1374
|
+
html += `</tr>`
|
|
1375
|
+
})
|
|
1376
|
+
html += `</table>`
|
|
1377
|
+
}
|
|
1378
|
+
return html
|
|
1379
|
+
} catch (e) {
|
|
1380
|
+
return e + ''
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
module.exports = Util
|