{-|
A 'TimeLogEntry' is a clock-in, clock-out, or other directive in a timelog
file (see timeclock.el or the command-line version). These can be
converted to 'Transactions' and queried like a ledger.
-}moduleHledger.Data.TimeLogwhereimportData.MaybeimportData.Time.CalendarimportData.Time.ClockimportData.Time.FormatimportData.Time.LocalTimeimportSystem.Locale(defaultTimeLocale)importTest.HUnitimportText.PrintfimportHledger.UtilsimportHledger.Data.TypesimportHledger.Data.DatesimportHledger.Data.CommodityimportHledger.Data.TransactioninstanceShowTimeLogEntrywhereshowt=printf"%s %s %s"(show$tlcodet)(show$tldatetimet)(tlcommentt)instanceShowTimeLogCodewhereshowSetBalance="b"showSetRequiredHours="h"showIn="i"showOut="o"showFinalOut="O"instanceReadTimeLogCodewherereadsPrec_('b':xs)=[(SetBalance,xs)]readsPrec_('h':xs)=[(SetRequiredHours,xs)]readsPrec_('i':xs)=[(In,xs)]readsPrec_('o':xs)=[(Out,xs)]readsPrec_('O':xs)=[(FinalOut,xs)]readsPrec__=[]-- | Convert time log entries to journal transactions. When there is no-- clockout, add one with the provided current time. Sessions crossing-- midnight are split into days to give accurate per-day totals.timeLogEntriesToTransactions::LocalTime->[TimeLogEntry]->[Transaction]timeLogEntriesToTransactions_[]=[]timeLogEntriesToTransactionsnow[i]|odate>idate=entryFromTimeLogInOutio':timeLogEntriesToTransactionsnow[i',o]|otherwise=[entryFromTimeLogInOutio]whereo=TimeLogEntryOutend""end=ifitime>nowthenitimeelsenow(itime,otime)=(tldatetimei,tldatetimeo)(idate,odate)=(localDayitime,localDayotime)o'=o{tldatetime=itime{localDay=idate,localTimeOfDay=TimeOfDay235959}}i'=i{tldatetime=itime{localDay=addDays1idate,localTimeOfDay=midnight}}timeLogEntriesToTransactionsnow(i:o:rest)|odate>idate=entryFromTimeLogInOutio':timeLogEntriesToTransactionsnow(i':o:rest)|otherwise=entryFromTimeLogInOutio:timeLogEntriesToTransactionsnowrestwhere(itime,otime)=(tldatetimei,tldatetimeo)(idate,odate)=(localDayitime,localDayotime)o'=o{tldatetime=itime{localDay=idate,localTimeOfDay=TimeOfDay235959}}i'=i{tldatetime=itime{localDay=addDays1idate,localTimeOfDay=midnight}}-- | Convert a timelog clockin and clockout entry to an equivalent journal-- transaction, representing the time expenditure. Note this entry is not balanced,-- since we omit the \"assets:time\" transaction for simpler output.entryFromTimeLogInOut::TimeLogEntry->TimeLogEntry->TransactionentryFromTimeLogInOutio|otime>=itime=t|otherwise=error'$"clock-out time less than clock-in time in:\n"++showTransactiontwheret=Transaction{tdate=idate,teffectivedate=Nothing,tstatus=True,tcode="",tdescription=showtimeitod++"-"++showtimeotod,tcomment="",tmetadata=[],tpostings=ps,tpreceding_comment_lines=""}showtime=take5.showacctname=tlcommentiitime=tldatetimeiotime=tldatetimeoitod=localTimeOfDayitimeotod=localTimeOfDayotimeidate=localDayitimehrs=elapsedSeconds(toutcotime)(toutcitime)/3600wheretoutc=localTimeToUTCutcamount=Mixed[hourshrs]ps=[Posting{pstatus=False,paccount=acctname,pamount=amount,pcomment="",ptype=VirtualPosting,pmetadata=[],ptransaction=Justt}]tests_Hledger_Data_TimeLog=TestList["timeLogEntriesToTransactions"~:dotoday<-getCurrentDaynow'<-getCurrentTimetz<-getCurrentTimeZoneletnow=utcToLocalTimetznow'nowstr=showtimenowyesterday=prevdaytodayclockin=TimeLogEntryInmktimed=LocalTimed.fromMaybemidnight.parseTimedefaultTimeLocale"%H:%M:%S"showtime=formatTimedefaultTimeLocale"%H:%M"assertEntriesGiveStringsnameesss=assertEqualnamess(maptdescription$timeLogEntriesToTransactionsnowes)assertEntriesGiveStrings"started yesterday, split session at midnight"[clockin(mktimeyesterday"23:00:00")""]["23:00-23:59","00:00-"++nowstr]assertEntriesGiveStrings"split multi-day sessions at each midnight"[clockin(mktime(addDays(-2)today)"23:00:00")""]["23:00-23:59","00:00-23:59","00:00-"++nowstr]assertEntriesGiveStrings"auto-clock-out if needed"[clockin(mktimetoday"00:00:00")""]["00:00-"++nowstr]letfuture=utcToLocalTimetz$addUTCTime100now'futurestr=showtimefutureassertEntriesGiveStrings"use the clockin time for auto-clockout if it's in the future"[clockinfuture""][printf"%s-%s"futurestrfuturestr]]