mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2025-05-02 20:37:08 +01:00
Improve duration calcs, intro base resume class.
This commit is contained in:
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'
|
||||
require('../utils/string')
|
||||
|
||||
###*
|
||||
Create a FluentDate from a string or Moment date object. There are a few date
|
||||
@ -30,6 +31,8 @@ class FluentDate
|
||||
constructor: (dt) ->
|
||||
@rep = this.fmt dt
|
||||
|
||||
@isCurrent: (dt) ->
|
||||
!dt || (String.is(dt) and /^(present|now|current)$/.test(dt))
|
||||
|
||||
months = {}
|
||||
abbr = {}
|
||||
|
@ -17,6 +17,8 @@ XML = require 'xml-escape'
|
||||
MD = require 'marked'
|
||||
CONVERTER = require 'fresh-jrs-converter'
|
||||
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.
|
||||
@constructor
|
||||
###
|
||||
class FreshResume
|
||||
class FreshResume extends AbstractResume
|
||||
|
||||
###* Initialize the FreshResume from file. ###
|
||||
open: ( file, opts ) ->
|
||||
@ -306,28 +308,8 @@ class FreshResume
|
||||
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) ->
|
||||
unit = unit || 'years'
|
||||
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
|
||||
|
||||
super('employment.history', 'start', 'end', unit)
|
||||
|
||||
|
||||
###*
|
||||
@ -337,9 +319,9 @@ class FreshResume
|
||||
sort: () ->
|
||||
|
||||
byDateDesc = (a,b) ->
|
||||
if ( a.safe.start.isBefore(b.safe.start) )
|
||||
if a.safe.start.isBefore(b.safe.start)
|
||||
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 ) ->
|
||||
ar = __.get this, key
|
||||
@ -352,10 +334,6 @@ class FreshResume
|
||||
sortSection 'service.history'
|
||||
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) ->
|
||||
if a.safe.date.isBefore b.safe.date
|
||||
then 1
|
||||
@ -400,6 +378,7 @@ _parseDates = () ->
|
||||
return if !obj
|
||||
if Object.prototype.toString.call( obj ) == '[object Array]'
|
||||
obj.forEach (elem) -> replaceDatesInObject( elem )
|
||||
return
|
||||
else if typeof obj == 'object'
|
||||
if obj._isAMomentObject || obj.safe
|
||||
return
|
||||
@ -410,8 +389,12 @@ _parseDates = () ->
|
||||
obj.safe[ val ] = _fmt obj[val]
|
||||
if obj[val] && (val == 'start') && !obj.end
|
||||
obj.safe.end = _fmt 'current'
|
||||
|
||||
Object.keys( this ).forEach (member) -> replaceDatesInObject(that[member])
|
||||
return
|
||||
return
|
||||
Object.keys( this ).forEach (member) ->
|
||||
replaceDatesInObject(that[member])
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ PATH = require('path')
|
||||
MD = require('marked')
|
||||
CONVERTER = require('fresh-jrs-converter')
|
||||
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.
|
||||
@class JRSResume
|
||||
###
|
||||
class JRSResume
|
||||
class JRSResume extends AbstractResume
|
||||
|
||||
|
||||
|
||||
@ -203,25 +203,8 @@ class JRSResume
|
||||
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 ) ->
|
||||
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, ( w ) -> w.safeEndDate.unix() ).safeEndDate;
|
||||
return careerLast.diff careerStart, unit
|
||||
0
|
||||
|
||||
duration: (unit) ->
|
||||
super('work', 'startDate', 'endDate', unit)
|
||||
|
||||
|
||||
###*
|
||||
|
Reference in New Issue
Block a user