mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-22 16:30:11 +00:00
Improve duration calcs, intro base resume class.
This commit is contained in:
parent
8ec6b5ed6a
commit
8e806dc04f
71
dist/core/abstract-resume.js
vendored
Normal file
71
dist/core/abstract-resume.js
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
Definition of the AbstractResume class.
|
||||||
|
@license MIT. See LICENSE.md for details.
|
||||||
|
@module core/abstract-resume
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var AbstractResume, FluentDate, _, __;
|
||||||
|
|
||||||
|
_ = require('underscore');
|
||||||
|
|
||||||
|
__ = require('lodash');
|
||||||
|
|
||||||
|
FluentDate = require('./fluent-date');
|
||||||
|
|
||||||
|
AbstractResume = (function() {
|
||||||
|
function AbstractResume() {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Compute the total duration of the work history.
|
||||||
|
@returns The total duration of the sheet's work history, that is, the number
|
||||||
|
of years between the start date of the earliest job on the resume and the
|
||||||
|
*latest end date of all jobs in the work history*. This last condition is for
|
||||||
|
sheets that have overlapping jobs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractResume.prototype.duration = function(collKey, startKey, endKey, unit) {
|
||||||
|
var firstDate, hist, lastDate, new_e;
|
||||||
|
unit = unit || 'years';
|
||||||
|
hist = hist || __.get(this, collKey);
|
||||||
|
if (!hist || !hist.length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
new_e = hist.map(function(job) {
|
||||||
|
var obj;
|
||||||
|
obj = _.pick(job, [startKey, endKey]);
|
||||||
|
if (!_.has(obj, endKey)) {
|
||||||
|
obj[endKey] = 'current';
|
||||||
|
}
|
||||||
|
if (obj && (obj[startKey] || obj[endKey])) {
|
||||||
|
obj = _.pairs(obj);
|
||||||
|
obj[0][1] = FluentDate.fmt(obj[0][1]);
|
||||||
|
if (obj.length > 1) {
|
||||||
|
obj[1][1] = FluentDate.fmt(obj[1][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
new_e = _.filter(_.flatten(new_e, true), function(v) {
|
||||||
|
return v && v.length && v[0] && v[0].length;
|
||||||
|
});
|
||||||
|
if (!new_e || !new_e.length) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
new_e = _.sortBy(new_e, function(elem) {
|
||||||
|
return elem[1].unix();
|
||||||
|
});
|
||||||
|
firstDate = _.first(new_e)[1];
|
||||||
|
lastDate = _.last(new_e)[1];
|
||||||
|
return lastDate.diff(firstDate, unit);
|
||||||
|
};
|
||||||
|
|
||||||
|
return AbstractResume;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
module.exports = AbstractResume;
|
||||||
|
|
||||||
|
}).call(this);
|
6
dist/core/fluent-date.js
vendored
6
dist/core/fluent-date.js
vendored
@ -10,6 +10,8 @@ The HackMyResume date representation.
|
|||||||
|
|
||||||
moment = require('moment');
|
moment = require('moment');
|
||||||
|
|
||||||
|
require('../utils/string');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a FluentDate from a string or Moment date object. There are a few date
|
Create a FluentDate from a string or Moment date object. There are a few date
|
||||||
@ -33,6 +35,10 @@ The HackMyResume date representation.
|
|||||||
this.rep = this.fmt(dt);
|
this.rep = this.fmt(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FluentDate.isCurrent = function(dt) {
|
||||||
|
return !dt || (String.is(dt) && /^(present|now|current)$/.test(dt));
|
||||||
|
};
|
||||||
|
|
||||||
return FluentDate;
|
return FluentDate;
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
64
dist/core/fresh-resume.js
vendored
64
dist/core/fresh-resume.js
vendored
@ -6,7 +6,9 @@ Definition of the FRESHResume class.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var CONVERTER, FS, FreshResume, JRSResume, MD, PATH, XML, _, __, _parseDates, extend, moment, validator;
|
var AbstractResume, CONVERTER, FS, FluentDate, FreshResume, JRSResume, MD, PATH, XML, _, __, _parseDates, extend, moment, validator,
|
||||||
|
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||||
|
hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
FS = require('fs');
|
FS = require('fs');
|
||||||
|
|
||||||
@ -30,6 +32,10 @@ Definition of the FRESHResume class.
|
|||||||
|
|
||||||
JRSResume = require('./jrs-resume');
|
JRSResume = require('./jrs-resume');
|
||||||
|
|
||||||
|
FluentDate = require('./fluent-date');
|
||||||
|
|
||||||
|
AbstractResume = require('./abstract-resume');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
|
A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
|
||||||
@ -37,8 +43,12 @@ Definition of the FRESHResume class.
|
|||||||
@constructor
|
@constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FreshResume = (function() {
|
FreshResume = (function(superClass) {
|
||||||
function FreshResume() {}
|
extend1(FreshResume, superClass);
|
||||||
|
|
||||||
|
function FreshResume() {
|
||||||
|
return FreshResume.__super__.constructor.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Initialize the FreshResume from file. */
|
/** Initialize the FreshResume from file. */
|
||||||
@ -376,36 +386,8 @@ Definition of the FRESHResume class.
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate the total duration of the sheet. Assumes this.work has been sorted
|
|
||||||
by start date descending, perhaps via a call to Sheet.sort().
|
|
||||||
@returns The total duration of the sheet's work history, that is, the number
|
|
||||||
of years between the start date of the earliest job on the resume and the
|
|
||||||
*latest end date of all jobs in the work history*. This last condition is for
|
|
||||||
sheets that have overlapping jobs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FreshResume.prototype.duration = function(unit) {
|
FreshResume.prototype.duration = function(unit) {
|
||||||
var careerLast, careerStart, empHist, firstJob;
|
return FreshResume.__super__.duration.call(this, 'employment.history', 'start', 'end', unit);
|
||||||
unit = unit || 'years';
|
|
||||||
empHist = __.get(this, 'employment.history');
|
|
||||||
if (empHist && empHist.length) {
|
|
||||||
firstJob = _.last(empHist);
|
|
||||||
careerStart = firstJob.start ? firstJob.safe.start : '';
|
|
||||||
if ((typeof careerStart === 'string' || careerStart instanceof String) && !careerStart.trim()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
careerLast = _.max(empHist, function(w) {
|
|
||||||
if (w.safe && w.safe.end) {
|
|
||||||
return w.safe.end.unix();
|
|
||||||
} else {
|
|
||||||
return moment().unix();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return careerLast.safe.end.diff(careerStart, unit);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -420,7 +402,11 @@ Definition of the FRESHResume class.
|
|||||||
if (a.safe.start.isBefore(b.safe.start)) {
|
if (a.safe.start.isBefore(b.safe.start)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return (a.safe.start.isAfter(b.safe.start) && -1) || 0;
|
if (a.safe.start.isAfter(b.safe.start)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sortSection = function(key) {
|
sortSection = function(key) {
|
||||||
@ -448,7 +434,7 @@ Definition of the FRESHResume class.
|
|||||||
|
|
||||||
return FreshResume;
|
return FreshResume;
|
||||||
|
|
||||||
})();
|
})(AbstractResume);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -499,7 +485,7 @@ Definition of the FRESHResume class.
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
||||||
return obj.forEach(function(elem) {
|
obj.forEach(function(elem) {
|
||||||
return replaceDatesInObject(elem);
|
return replaceDatesInObject(elem);
|
||||||
});
|
});
|
||||||
} else if (typeof obj === 'object') {
|
} else if (typeof obj === 'object') {
|
||||||
@ -509,19 +495,19 @@ Definition of the FRESHResume class.
|
|||||||
Object.keys(obj).forEach(function(key) {
|
Object.keys(obj).forEach(function(key) {
|
||||||
return replaceDatesInObject(obj[key]);
|
return replaceDatesInObject(obj[key]);
|
||||||
});
|
});
|
||||||
return ['start', 'end', 'date'].forEach(function(val) {
|
['start', 'end', 'date'].forEach(function(val) {
|
||||||
if ((obj[val] !== void 0) && (!obj.safe || !obj.safe[val])) {
|
if ((obj[val] !== void 0) && (!obj.safe || !obj.safe[val])) {
|
||||||
obj.safe = obj.safe || {};
|
obj.safe = obj.safe || {};
|
||||||
obj.safe[val] = _fmt(obj[val]);
|
obj.safe[val] = _fmt(obj[val]);
|
||||||
if (obj[val] && (val === 'start') && !obj.end) {
|
if (obj[val] && (val === 'start') && !obj.end) {
|
||||||
return obj.safe.end = _fmt('current');
|
obj.safe.end = _fmt('current');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Object.keys(this).forEach(function(member) {
|
Object.keys(this).forEach(function(member) {
|
||||||
return replaceDatesInObject(that[member]);
|
replaceDatesInObject(that[member]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
40
dist/core/jrs-resume.js
vendored
40
dist/core/jrs-resume.js
vendored
@ -6,7 +6,9 @@ Definition of the JRSResume class.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var CONVERTER, FS, JRSResume, MD, PATH, _, _parseDates, extend, moment, validator;
|
var AbstractResume, CONVERTER, FS, JRSResume, MD, PATH, _, _parseDates, extend, moment, validator,
|
||||||
|
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||||
|
hasProp = {}.hasOwnProperty;
|
||||||
|
|
||||||
FS = require('fs');
|
FS = require('fs');
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ Definition of the JRSResume class.
|
|||||||
|
|
||||||
moment = require('moment');
|
moment = require('moment');
|
||||||
|
|
||||||
|
AbstractResume = require('./abstract-resume');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
|
A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
|
||||||
@ -31,10 +35,14 @@ Definition of the JRSResume class.
|
|||||||
@class JRSResume
|
@class JRSResume
|
||||||
*/
|
*/
|
||||||
|
|
||||||
JRSResume = (function() {
|
JRSResume = (function(superClass) {
|
||||||
var clear, format;
|
var clear, format;
|
||||||
|
|
||||||
function JRSResume() {}
|
extend1(JRSResume, superClass);
|
||||||
|
|
||||||
|
function JRSResume() {
|
||||||
|
return JRSResume.__super__.constructor.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Initialize the JSResume from file. */
|
/** Initialize the JSResume from file. */
|
||||||
@ -249,30 +257,8 @@ Definition of the JRSResume class.
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Calculate the total duration of the sheet. Assumes this.work has been sorted
|
|
||||||
by start date descending, perhaps via a call to Sheet.sort().
|
|
||||||
@returns The total duration of the sheet's work history, that is, the number
|
|
||||||
of years between the start date of the earliest job on the resume and the
|
|
||||||
*latest end date of all jobs in the work history*. This last condition is for
|
|
||||||
sheets that have overlapping jobs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
JRSResume.prototype.duration = function(unit) {
|
JRSResume.prototype.duration = function(unit) {
|
||||||
var careerLast, careerStart;
|
return JRSResume.__super__.duration.call(this, 'work', 'startDate', 'endDate', unit);
|
||||||
unit = unit || 'years';
|
|
||||||
if (this.work && this.work.length) {
|
|
||||||
careerStart = this.work[this.work.length - 1].safeStartDate;
|
|
||||||
if ((typeof careerStart === 'string' || careerStart instanceof String) && !careerStart.trim()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
careerLast = _.max(this.work, function(w) {
|
|
||||||
return w.safeEndDate.unix();
|
|
||||||
}).safeEndDate;
|
|
||||||
return careerLast.diff(careerStart, unit);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -372,7 +358,7 @@ Definition of the JRSResume class.
|
|||||||
|
|
||||||
return JRSResume;
|
return JRSResume;
|
||||||
|
|
||||||
})();
|
})(AbstractResume);
|
||||||
|
|
||||||
|
|
||||||
/** Get the default (empty) sheet. */
|
/** Get the default (empty) sheet. */
|
||||||
|
56
src/core/abstract-resume.coffee
Normal file
56
src/core/abstract-resume.coffee
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
###*
|
||||||
|
Definition of the AbstractResume class.
|
||||||
|
@license MIT. See LICENSE.md for details.
|
||||||
|
@module core/abstract-resume
|
||||||
|
###
|
||||||
|
|
||||||
|
_ = require 'underscore'
|
||||||
|
__ = require 'lodash'
|
||||||
|
FluentDate = require('./fluent-date')
|
||||||
|
|
||||||
|
class AbstractResume
|
||||||
|
|
||||||
|
###*
|
||||||
|
Compute the total duration of the work history.
|
||||||
|
@returns The total duration of the sheet's work history, that is, the number
|
||||||
|
of years between the start date of the earliest job on the resume and the
|
||||||
|
*latest end date of all jobs in the work history*. This last condition is for
|
||||||
|
sheets that have overlapping jobs.
|
||||||
|
###
|
||||||
|
duration: (collKey, startKey, endKey, unit) ->
|
||||||
|
unit = unit || 'years'
|
||||||
|
hist = hist || __.get(this, collKey)
|
||||||
|
return 0 if !hist or !hist.length
|
||||||
|
|
||||||
|
# BEGIN CODE DUPLICATION --> src/inspectors/gap-inspector.coffee (TODO)
|
||||||
|
|
||||||
|
# Convert the candidate's employment history to an array of dates,
|
||||||
|
# where each element in the array is a start date or an end date of a
|
||||||
|
# job -- it doesn't matter which.
|
||||||
|
new_e = hist.map( ( job ) ->
|
||||||
|
obj = _.pick( job, [startKey, endKey] )
|
||||||
|
# Synthesize an end date if this is a "current" gig
|
||||||
|
obj[endKey] = 'current' if !_.has obj, endKey
|
||||||
|
if obj && (obj[startKey] || obj[endKey])
|
||||||
|
obj = _.pairs( obj )
|
||||||
|
obj[0][1] = FluentDate.fmt( obj[0][1] )
|
||||||
|
if obj.length > 1
|
||||||
|
obj[1][1] = FluentDate.fmt( obj[1][1] )
|
||||||
|
return obj
|
||||||
|
)
|
||||||
|
|
||||||
|
# Flatten the array, remove empties, and sort
|
||||||
|
new_e = _.filter _.flatten( new_e, true ), (v) ->
|
||||||
|
return v && v.length && v[0] && v[0].length
|
||||||
|
|
||||||
|
return 0 if !new_e or !new_e.length
|
||||||
|
|
||||||
|
new_e = _.sortBy new_e, ( elem ) -> return elem[1].unix()
|
||||||
|
|
||||||
|
# END CODE DUPLICATION
|
||||||
|
|
||||||
|
firstDate = _.first( new_e )[1];
|
||||||
|
lastDate = _.last( new_e )[1];
|
||||||
|
lastDate.diff firstDate, unit
|
||||||
|
|
||||||
|
module.exports = AbstractResume
|
@ -7,6 +7,7 @@ The HackMyResume date representation.
|
|||||||
|
|
||||||
|
|
||||||
moment = require 'moment'
|
moment = require 'moment'
|
||||||
|
require('../utils/string')
|
||||||
|
|
||||||
###*
|
###*
|
||||||
Create a FluentDate from a string or Moment date object. There are a few date
|
Create a FluentDate from a string or Moment date object. There are a few date
|
||||||
@ -30,6 +31,8 @@ class FluentDate
|
|||||||
constructor: (dt) ->
|
constructor: (dt) ->
|
||||||
@rep = this.fmt dt
|
@rep = this.fmt dt
|
||||||
|
|
||||||
|
@isCurrent: (dt) ->
|
||||||
|
!dt || (String.is(dt) and /^(present|now|current)$/.test(dt))
|
||||||
|
|
||||||
months = {}
|
months = {}
|
||||||
abbr = {}
|
abbr = {}
|
||||||
|
@ -17,6 +17,8 @@ XML = require 'xml-escape'
|
|||||||
MD = require 'marked'
|
MD = require 'marked'
|
||||||
CONVERTER = require 'fresh-jrs-converter'
|
CONVERTER = require 'fresh-jrs-converter'
|
||||||
JRSResume = require './jrs-resume'
|
JRSResume = require './jrs-resume'
|
||||||
|
FluentDate = require './fluent-date'
|
||||||
|
AbstractResume = require './abstract-resume'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
|
|||||||
object is an instantiation of that JSON decorated with utility methods.
|
object is an instantiation of that JSON decorated with utility methods.
|
||||||
@constructor
|
@constructor
|
||||||
###
|
###
|
||||||
class FreshResume
|
class FreshResume extends AbstractResume
|
||||||
|
|
||||||
###* Initialize the FreshResume from file. ###
|
###* Initialize the FreshResume from file. ###
|
||||||
open: ( file, opts ) ->
|
open: ( file, opts ) ->
|
||||||
@ -306,28 +308,8 @@ class FreshResume
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###*
|
|
||||||
Calculate the total duration of the sheet. Assumes this.work has been sorted
|
|
||||||
by start date descending, perhaps via a call to Sheet.sort().
|
|
||||||
@returns The total duration of the sheet's work history, that is, the number
|
|
||||||
of years between the start date of the earliest job on the resume and the
|
|
||||||
*latest end date of all jobs in the work history*. This last condition is for
|
|
||||||
sheets that have overlapping jobs.
|
|
||||||
###
|
|
||||||
duration: (unit) ->
|
duration: (unit) ->
|
||||||
unit = unit || 'years'
|
super('employment.history', 'start', 'end', unit)
|
||||||
empHist = __.get(this, 'employment.history')
|
|
||||||
if empHist && empHist.length
|
|
||||||
firstJob = _.last( empHist )
|
|
||||||
careerStart = if firstJob.start then firstJob.safe.start else ''
|
|
||||||
if ((typeof careerStart == 'string' || careerStart instanceof String) && !careerStart.trim())
|
|
||||||
return 0
|
|
||||||
careerLast = _.max empHist, ( w ) ->
|
|
||||||
return if w.safe && w.safe.end then w.safe.end.unix() else moment().unix()
|
|
||||||
return careerLast.safe.end.diff careerStart, unit
|
|
||||||
0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###*
|
###*
|
||||||
@ -337,9 +319,9 @@ class FreshResume
|
|||||||
sort: () ->
|
sort: () ->
|
||||||
|
|
||||||
byDateDesc = (a,b) ->
|
byDateDesc = (a,b) ->
|
||||||
if ( a.safe.start.isBefore(b.safe.start) )
|
if a.safe.start.isBefore(b.safe.start)
|
||||||
then 1
|
then 1
|
||||||
else ( a.safe.start.isAfter(b.safe.start) && -1 ) || 0
|
else ( if a.safe.start.isAfter(b.safe.start) then -1 else 0 )
|
||||||
|
|
||||||
sortSection = ( key ) ->
|
sortSection = ( key ) ->
|
||||||
ar = __.get this, key
|
ar = __.get this, key
|
||||||
@ -352,10 +334,6 @@ class FreshResume
|
|||||||
sortSection 'service.history'
|
sortSection 'service.history'
|
||||||
sortSection 'projects'
|
sortSection 'projects'
|
||||||
|
|
||||||
# this.awards && this.awards.sort( function(a, b) {
|
|
||||||
# return( a.safeDate.isBefore(b.safeDate) ) ? 1
|
|
||||||
# : ( a.safeDate.isAfter(b.safeDate) && -1 ) || 0;
|
|
||||||
# });
|
|
||||||
@writing && @writing.sort (a, b) ->
|
@writing && @writing.sort (a, b) ->
|
||||||
if a.safe.date.isBefore b.safe.date
|
if a.safe.date.isBefore b.safe.date
|
||||||
then 1
|
then 1
|
||||||
@ -400,6 +378,7 @@ _parseDates = () ->
|
|||||||
return if !obj
|
return if !obj
|
||||||
if Object.prototype.toString.call( obj ) == '[object Array]'
|
if Object.prototype.toString.call( obj ) == '[object Array]'
|
||||||
obj.forEach (elem) -> replaceDatesInObject( elem )
|
obj.forEach (elem) -> replaceDatesInObject( elem )
|
||||||
|
return
|
||||||
else if typeof obj == 'object'
|
else if typeof obj == 'object'
|
||||||
if obj._isAMomentObject || obj.safe
|
if obj._isAMomentObject || obj.safe
|
||||||
return
|
return
|
||||||
@ -410,8 +389,12 @@ _parseDates = () ->
|
|||||||
obj.safe[ val ] = _fmt obj[val]
|
obj.safe[ val ] = _fmt obj[val]
|
||||||
if obj[val] && (val == 'start') && !obj.end
|
if obj[val] && (val == 'start') && !obj.end
|
||||||
obj.safe.end = _fmt 'current'
|
obj.safe.end = _fmt 'current'
|
||||||
|
return
|
||||||
Object.keys( this ).forEach (member) -> replaceDatesInObject(that[member])
|
return
|
||||||
|
Object.keys( this ).forEach (member) ->
|
||||||
|
replaceDatesInObject(that[member])
|
||||||
|
return
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ PATH = require('path')
|
|||||||
MD = require('marked')
|
MD = require('marked')
|
||||||
CONVERTER = require('fresh-jrs-converter')
|
CONVERTER = require('fresh-jrs-converter')
|
||||||
moment = require('moment')
|
moment = require('moment')
|
||||||
|
AbstractResume = require('./abstract-resume')
|
||||||
|
|
||||||
|
|
||||||
###*
|
###*
|
||||||
@ -22,7 +22,7 @@ A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
|
|||||||
is an instantiation of that JSON decorated with utility methods.
|
is an instantiation of that JSON decorated with utility methods.
|
||||||
@class JRSResume
|
@class JRSResume
|
||||||
###
|
###
|
||||||
class JRSResume
|
class JRSResume extends AbstractResume
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -203,25 +203,8 @@ class JRSResume
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###*
|
|
||||||
Calculate the total duration of the sheet. Assumes this.work has been sorted
|
|
||||||
by start date descending, perhaps via a call to Sheet.sort().
|
|
||||||
@returns The total duration of the sheet's work history, that is, the number
|
|
||||||
of years between the start date of the earliest job on the resume and the
|
|
||||||
*latest end date of all jobs in the work history*. This last condition is for
|
|
||||||
sheets that have overlapping jobs.
|
|
||||||
###
|
|
||||||
duration: (unit) ->
|
duration: (unit) ->
|
||||||
unit = unit || 'years';
|
super('work', 'startDate', 'endDate', unit)
|
||||||
if this.work && this.work.length
|
|
||||||
careerStart = this.work[ this.work.length - 1].safeStartDate
|
|
||||||
if (typeof careerStart == 'string' || careerStart instanceof String) && !careerStart.trim()
|
|
||||||
return 0
|
|
||||||
careerLast = _.max( this.work, ( w ) -> w.safeEndDate.unix() ).safeEndDate;
|
|
||||||
return careerLast.diff careerStart, unit
|
|
||||||
0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###*
|
###*
|
||||||
|
Loading…
Reference in New Issue
Block a user