forked from kriskbx/gitlab-time-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhasTimes.js
More file actions
executable file
·142 lines (114 loc) · 4.8 KB
/
hasTimes.js
File metadata and controls
executable file
·142 lines (114 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const _ = require('underscore');
const moment = require('moment');
const Base = require('./base');
const Time = require('./time');
const regex = /added (.*) of time spent/i;
const subRegex = /subtracted (.*) of time spent/i;
const removeRegex = /Removed time spent/i;
/**
* base model for models that have times
*/
class hasTimes extends Base {
constructor(config) {
super(config);
this.times = [];
}
/**
* create time
* @param time
* @returns {*}
*/
createTime(time) {
return this.post(`projects/${this.data.project_id}/${this._type}/${this.iid}/add_spent_time`, {
duration: Time.toHumanReadable(time, this.config.get('hoursPerDay'), '[%sign][%days>d ][%hours>h ][%minutes>m ][%seconds>s]')
});
}
/**
* set stats
* @returns {Promise}
*/
getStats() {
let promise = this.get(`projects/${this.data.project_id}/${this._type}/${this.iid}/time_stats`);
promise.then(response => this.stats = response.body);
return promise;
}
/**
* set notes
* @returns {Promise}
*/
getNotes() {
let promise = this.all(`projects/${this.data.project_id}/${this._type}/${this.iid}/notes`);
promise.then(notes => this.notes = notes);
return promise;
}
/**
* set times (call set notes first)
* @returns {Promise}
*/
getTimes() {
let times = [],
timeSpent = 0,
totalTimeSpent = 0,
timeUsers = {},
timeFormat = this.config.get('timeFormat', this._type);
// sort by created at
this.notes.sort((a, b) => {
if (a.created_at === b.created_at) return 0;
return moment(a.created_at).isBefore(b.created_at) ? -1 : 1;
});
let promise = this.parallel(this.notes, (note, done) => {
let created = moment(note.created_at), match, subMatch;
if ( //
// filter out user notes
!note.system ||
// filter out notes that are no time things
!(match = regex.exec(note.body)) && !(subMatch = subRegex.exec(note.body)) && !removeRegex.exec(note.body)
) return done();
// create a time string and a time object
let timeString = match ? match[1] : (subMatch ? `-${subMatch[1]}` : `-${Time.toHumanReadable(timeSpent, this.config.get('hoursPerDay'))}`);
let time = new Time(timeString, note, this, this.config);
// add to total time spent
totalTimeSpent += time.seconds;
if ( //
// only include times by the configured user
(this.config.get('user') && this.config.get('user') !== note.author.username) ||
// filter out times that are not in the given time frame
!(created.isSameOrAfter(moment(this.config.get('from'))) && created.isSameOrBefore(moment(this.config.get('to'))))
) return done();
if (!timeUsers[note.author.username]) timeUsers[note.author.username] = 0;
// add to time spent & add to user specific time spent
timeSpent += time.seconds;
timeUsers[note.author.username] += time.seconds;
time.project_namespace = this.project_namespace;
times.push(time);
done();
});
promise = promise.then(() => new Promise(resolve => {
let created = moment(this.data.created_at);
if ( //
// skip if description parsing is disabled
this.config.get('_skipDescriptionParsing') ||
// or time stats are not available
!this.data.time_stats || !this.data.time_stats.total_time_spent ||
// or the total time matches
!this.data.time_stats ||
totalTimeSpent === this.data.time_stats.total_time_spent ||
// or the user is filtered out
(this.config.get('user') && this.config.get('user') !== this.data.author.username) ||
// or the issue is not within the given time frame
!(created.isSameOrAfter(moment(this.config.get('from'))) && created.isSameOrBefore(moment(this.config.get('to'))))
) return resolve();
let difference = this.data.time_stats.total_time_spent - totalTimeSpent,
note = Object.assign({noteable_type: this._typeSingular}, this.data);
times.unshift(new Time(Time.toHumanReadable(difference, this.config.get('hoursPerDay')), note, this, this.config));
resolve();
}));
promise.then(() => {
_.each(timeUsers, (time, name) => this[`time_${name}`] = Time.toHumanReadable(time, this.config.get('hoursPerDay'), timeFormat));
this.timeSpent = timeSpent;
this.times = times
});
return promise;
}
}
module.exports = hasTimes;