Commit 706a7690 authored by richardARPANET's avatar richardARPANET

initial commit

parents
#pycharm
.idea
.cache
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
.vscode
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
.idea
htmlcov/
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
# virtual env
venv
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store
*.sqlite
# Timesheet generator
```
python main.py --company=ACME --month=january --year=2018 --work-bank-hols=false
# if working bank holiday dates
python main.py --company=ACME --month=january --year=2018 --work-bank-hols=true
```
from datetime import date
import calendar
import requests
from dateutil.parser import parse
import click
import pandas as pd
template = pd.read_csv('template.csv')
def _get_bank_holidays():
resp = requests.get('https://www.gov.uk/bank-holidays.json')
resp.json()
return [
parse(d['date']).date()
for d in resp.json()['england-and-wales']['events']
]
def _get_working_dates(*, month_number, year, bank_hol_dates):
cal = calendar.Calendar()
working_days = [
x[0] for x in cal.itermonthdays2(year, month_number)
if x[0] != 0 and x[1] < 5
]
dates = [
date(year, month_number, day_number) for day_number in working_days
]
if not bank_hol_dates:
return dates
return [d for d in dates if d not in bank_hol_dates]
def month_string_to_number(string):
months = {
'jan': 1,
'feb': 2,
'mar': 3,
'apr': 4,
'may': 5,
'jun': 6,
'jul': 7,
'aug': 8,
'sep': 9,
'oct': 10,
'nov': 11,
'dec': 12
}
short_month_str = string.strip()[:3].lower()
try:
return months[short_month_str]
except KeyError:
raise ValueError('Invalid month input')
@click.command()
@click.option('--company', type=str, required=True)
@click.option('--year', type=int, required=True)
@click.option('--month', type=str, required=True)
@click.option('--work-bank-hols', type=bool, required=True)
def main(company, year, month, work_bank_hols):
if work_bank_hols is False:
bank_hol_dates = _get_bank_holidays()
else:
bank_hol_dates = []
month_number = month_string_to_number(month)
dept = 'Data Science Team'
approver = 'Vincent Tuk'
HOURS_WORKED = str(8)
working_dates_in_month = _get_working_dates(
month_number=month_number, year=year, bank_hol_dates=bank_hol_dates)
total_hours = int(HOURS_WORKED) * len(working_dates_in_month)
inserting_data = False
for idx, values in enumerate(template.values):
if 'Name/Role:' in values:
template.values[idx] = [
values[0], f'{company} / Software Development Services'
]
if 'Department:' in values:
template.values[idx] = [values[0]] + [dept]
if 'Approver:' in values:
template.values[idx] = [values[0]] + [approver]
if 'Period:' in values:
template.values[idx] = [values[0]] + [f'{month} {year}']
if 'Total hours:' in values:
template.values[idx] = [values[0]] + [total_hours]
# Fill out date, hours worked
target_values = ['Date', 'Hours worked*']
previous_values = template.values[idx - 1]
if target_values in previous_values:
inserting_data = True
if working_dates_in_month and inserting_data:
value = working_dates_in_month.pop(0)
template.values[idx] = [value, HOURS_WORKED]
out_filename = f'{month}-{year}-timesheet-{company}.csv'
template.to_csv(out_filename, index=False)
print('Output to', out_filename)
if __name__ == '__main__':
main()
Timesheet for USIO Contractors,
,
,
,
Name/Role:,
Department:,
Approver:,
Period:,
,
,
Date,Hours worked*
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
Total hours:,
,
"*If your contract is on a per diem basis, indicate this as 8 hours for a full day and 4 hours for half a day",
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment