ycl

Artifact [79a624b287]
Login

Artifact [79a624b287]

Artifact 79a624b287b322e4629ccd370552c47082db7c1e:


#! /bin/env tclsh

package require {ycl dict}
namespace import [yclprefix]::dict::getdefault
package require {ycl iapi com kforce util}
namespace import [yclprefix]::iapi::com::kforce::util::clean
package require {ycl parser scripted prototype}
namespace import [yclprefix]::parser
package require {ycl proc}
namespace import [yclprefix]::proc::checkargs
package require {ycl shelf shelf}

[yclprefix] shelf shelf spawn [namespace current]

[namespace current] subcmd clean

proc hours {_ value} {
	upvar 0 [$_ namespace]::parsed parsed
	set hours [getdefault $parsed hours {}]
	set row [lindex $hours end]
	lappend row $value
	dict set parsed hours [lreplace $hours end end $row]
	return $row
}
[namespace current] method hours


if 0 {
	proc hours {node pattern} {
		set table [list]
		set rowheaders {Hours {Regular IC} {Daily Total}}
		set node [$node selectNodes {//*[contains(text(),$pattern)]/../..}]
		if {$node eq {} } {
			raise -code error "Hours should not be parsed on a timecard with no hours"
			return
		}
		for {set i 0} {$i<3} {incr i} {
			set row [list]
			foreach child [$node childNodes] {
				set values [list]
				foreach text [$child selectNodes */text()] {
					lappend values [$text asText]
				}
				lappend row $values
			}
			lappend table $row
			$node nextSibling node
		}
		return $table 
	}
}

variable doc::init {
	args {
		_ {
			description {
				This instance .
			}
		}
		meta {
			description {
				metadata for the timecard
			}
		}
	}
}
proc init {_ args} {
	checkargs [set doc::[namespace tail [lindex [info level 0] 0]]] {*}$args
	$_ $ meta $meta
	return $_
}
[namespace current] method init

proc parse _ {
	upvar 0 [$_ namespace]::timecard parsed
	set parsed {}
	[parser scripted prototype spawn [$_ namespace]::parser1] init states [$_ $ states]
	$_ subcmd [$_ namespace]::parser1
	$_ parser1 $ parsed {}
	$_ parser1 subcmd timecard $_
	$_ parser1 method parsed [namespace current]::parsed
	$_ parser1 method hours [namespace current]::hours
	$_ parser1 eval [list namespace import [namespace current]::getdefault]

	dom parse -html [$_ $ data] html
	$html documentElement root
	$root normalize

	set nodes [$root selectNodes {//text()[
		not(ancestor::embed)
		and not(ancestor::script)
		and not(ancestor::style)
		and not(ancestor::noscript)
		and not(ancestor::source)
		and not(ancestor::svg)
		and not(ancestor::track)
		and not(ancestor::video)
	]}]

	foreach node $nodes[set nodes {}] {
		lappend nodes [string trim [$node asText]]
	}

	$_ parser1 parse [coroutine [$_ namespace]::nodescoro ::apply [list nodes {
		yield [info coroutine]
		foreach node $nodes {
			yield $node
		}
	} [namespace current]] $nodes]
	set parsed [$_ parser1 $ parsed]
	set parsed [$_ clean $parsed]
	return $parsed
}
[namespace current] method parse

proc parsed {_ args} {
	upvar 0 [$_ namespace]::parsed parsed
	if {[llength $args] > 1} {
		dict set parsed {*}$args 
	} elseif {[llength $args] == 1} {
		dict get $parsed [lindex $args 0]
	} else {
		return $parsed
	}
}
[namespace current] method parsed


variable states {
	{Consultant Name:} {}

	expr 1 {
		dict set [$_ $.locate parsed] consultant $value
	}

	{Employee ID:} {}

	{
		$_ parsed employee_id $value
	}

	{Week Ending:} {}

	{
		$_ parsed week $value
	}

	{Client:} {}

	{
		$_ parsed client $value
	}

	{Fax Number:} {}

	{
		$_ parsed fax $value
	}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed assignment $value
	}

	{Assignment ID:} {}

	{Client Location:} {}

	{
		upvar 0 [$_ namespace]::parsed parsed
		dict lappend parsed location $value 
	}

	match {Job Title:} {
	} {
		upvar 0 [$_ namespace]::parsed parsed
		dict lappend parsed location $value 
	}

	{
		$_ parsed title $value
	}


	{Cost Center:} {}

	{
		$_ parsed cost_center $value
	}

	{Department:} {}

	{
		$_ parsed department $value
	}

	{Hiring Manager:} {}

	{
		$_ parsed manager $value
	}

	{Project:} {}

	{
		$_ parsed project $value
	}

	{Purchase Order:} {}

	{
		$_ parsed purchase_order $value 
	}

	equal {Hours} {} {
		#Incomplete timecard.  We're finished.
		$_ $ sindex [llength [$_ $ states]]
	}

	{Mon*} {}

	{Tue*} {}

	{Wed*} {}

	{Thu*} {}

	{Fri*} {}

	{Sat*} {}

	{Sun*} {}

	{Total} {}

	{Regular IC} {
		upvar 0 [$_ namespace]::repeat repeat
		set repeat 8

		upvar 0 [$_ namespace]::parsed parsed
		set hours [getdefault $parsed hours {}]
		lappend hours {}
		dict set parsed hours $hours
	}

	expr {[string is double $value] || $value eq {}} {
		upvar 0 [$_ namespace]::repeat repeat
		$_ hours $value
		if {[incr repeat -1]} {
			$_ repeat
		}

	}

	{Daily Total:} {
		upvar 0 [$_ namespace]::repeat repeat
		set repeat 8

		upvar 0 [$_ namespace]::parsed parsed
		set hours [dict get $parsed hours]
		lappend hours {}
		dict set parsed hours $hours
	}
	
	expr {[string is double $value] || $value eq {}} {
		upvar 0 [$_ namespace]::repeat repeat
		$_ hours $value
		if {[incr repeat -1]} {
			$_ repeat
		}
	}

	{Special Timecard Notes} {}

	{
		$_ parsed notes $value
	}

	{Execution or approval of this form by the client constitutes*} {}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed {user role} $value
	}

	equal {User Role:} {} {
		set status [dict get [$_ timecard $ meta] status]
		if {$status eq {Completed}} {
			#return -code error [
				#list {A completed timecard should have a User Role} [$_ timecard $ meta]]

			# A timecard that is completed but that has no user role was
			# rejected.  We're finished
			set meta [$_ timecard $ meta]
			dict set meta status Rejected
			$_ timecard $ meta $meta
			$_ $ sindex [llength [$_ $ states]]
		} else {
			#If there's no User Role, we're finished with this timecard
			$_ $ sindex [llength [$_ $ states]]
		}
	}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed {action type} $value
	}

	{Action Type:} {}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed {action by} $value
	}

	{Action By:} {}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed reference $value
	}

	{Reference:} {}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed {action datetime} $value
	}

	{Action Date/Time:} {}

	{
		#warning: In this case the value comes before the value name 
		$_ parsed {user ip address} $value
	}

	{User IP Address:} {}

	{For Office use only :} {}

	{
		$_ parsed {for office use only} $value
	}

	{
		$_ parsed {form revision} $value
	}

}