commit f716544bfe79e1d49202dc869c8a220e60d61013
parent 16fb5b74838a12e590a214f057da5eba41e3c691
Author: Youth Employment Program Production <youthemployment22@gmail.com>
Date: Tue, 9 Apr 2024 10:37:44 -0600
add updateProjectTime, fix display projects in index.dev.html, BUGFIX admin route missing project for agreement calculation, hoursd limit output in hours, aggregate project data
Diffstat:
2 files changed, 78 insertions(+), 56 deletions(-)
diff --git a/app/routes.py b/app/routes.py
@@ -313,6 +313,28 @@ def dashboard():
return render_template('dashboard/layout.html',permissions=dashperms,clocked_out=clocked_out,clockoutform=clockoutform,clockinform=clockinform,fleetCheckedOut=fleetCheckedOut,crewform=crewform,vehicle_name=vehicle_name,fleetinform=fleetinform,fleetoutform=fleetoutform,clocked_in_users=clocked_in_users,ORGNAME=OrganizationName)
+@app.route("/update/project/<mod_username>/<timeid>",methods=['GET','POST'])
+@login_required
+def updateProjectTime(mod_username,timeid):
+ timeid = ObjectId(timeid)
+ form = updateProject()
+ if form.validate_on_submit():
+ app.logger.info('update project route')
+ try:
+ entry = mongo.db.time_collection.find_one({'_id':timeid})
+ except:
+ flash("Issue finding/assigning time_id: {}".format(timeid))
+ else:
+ try:
+ mongo.db.time_collection.update_one({'_id':timeid},{'$set':{'project':ObjectId(form.projectSel.data)}})
+ except:
+ flash("unable to set project {}".format(ObjectId(form.projectSel.data)))
+ else:
+ flash("Updated project to {}".format(ObjectId(form.projectSel.data)))
+ finally:
+ return redirect(url_for('dashboard'))#change to hours and mod_username redirect
+ return render_template('dashboard/punchclock/update/project.html',form=form, ORGNAME=OrganizationName)
+
@app.route("/update/start/<mod_username>/<timeid>",methods=['GET','POST']) #TODO MAKE OTHER VALUE FOR LAST PAGE, RETURNS LAST PAGE ELSE DASHBOARD
@login_required
def updateStartTime(mod_username,timeid):
@@ -662,11 +684,28 @@ def admin():
agreement['total_budget']=0
agreement['total_cost']=0
for i in range(len(agreement['projects'])):
- agreement['projects'][i]= mongo.db.projects_collection.find_one({'_id': agreement['projects'][i]})
- agreement['projects'][i]['total_budget'] = sum(agreement['projects'][i]['budget'][0].values())
- agreement['projects'][i]['total_cost'] = sum(agreement['projects'][i]['costs'][0].values())
- agreement['total_budget']=agreement['total_budget']+agreement['projects'][i]['total_budget']
- agreement['total_cost']=agreement['total_cost']+agreement['projects'][i]['total_cost']
+ try:
+ if mongo.db.projects_collection.find_one({'_id': agreement['projects'][i]}) is None:
+ flash("could not find project {} in agreement {}".format(agreement['projects'][i],agreement['_id']))
+ return redirect(url_for('dashboard'))
+ else:
+ agreement['projects'][i]= mongo.db.projects_collection.find_one({'_id': agreement['projects'][i]})
+ except:
+ flash("could not find project {} in agreement {}".format(agreement['projects'][i],agreement['_id']))
+ return redirect(url_for('dashboard'))
+ else:
+ try:
+ if agreement['projects'][i]:#['budget'][0]
+ agreement['projects'][i]['total_budget'] = sum(agreement['projects'][i]['budget'][0].values())
+ else:
+ agreement['projects'][i]['total_budget'] = 1
+ except:
+ flash("could not assign agreement {} total budget")
+ agreement['projects'][i]['total_budget'] = 1
+ finally:
+ agreement['projects'][i]['total_cost'] = sum(agreement['projects'][i]['costs'][0].values())
+ agreement['total_budget']=agreement['total_budget']+agreement['projects'][i]['total_budget']
+ agreement['total_cost']=agreement['total_cost']+agreement['projects'][i]['total_cost']
agreements.append(agreement)
#all_permissions=mongo.db.permissions_collection.find_one({"label":current_user.role})
@@ -719,50 +758,43 @@ def hoursd(username):#userid goes into call to db to get user[] -> then returns
for project in mongo.db.projects_collection.find(): #TODO TO RESOLVE BELOW ISSUE, JUST USE aggregator QUERY, WILL ALLOW SORTING AS WELL AS PROPER SUMMATION OF HOURS
availableProjects.append((project['_id'],project['project_name']))#TODO FIND OUT WHY THIS RETURNS THE OBJECTID VALUE .str THROWS AttributeError: 'ObjectId' object has no attribute 'str'
#'completed':{'$exists':False}
- dbhours = mongo.db.time_collection.find({'modified_by.0':user['username']})
+ aghours = mongo.db.time_collection.find({'modified_by.0':username})
+ dbhours = mongo.db.time_collection.aggregate( [
+ {
+ "$match":{'modified_by.0':username}
+ },
+ {
+ '$lookup': {
+ 'from': 'projects_collection',
+ 'localField': 'project',
+ 'foreignField': '_id',
+ 'as': 'project'
+ }
+ },
+ {
+ "$sort":{'clock_in':-1}
+ },
+ {
+ "$limit":10 #change to ~ 30 days OR to prior 1st or 15th of month
+ }
+
+ ] )
hours = []
deltas=[]
- for hour in dbhours: # Currenty acts wrong with longer than 1 day
- for x, y in availableProjects:
- if x is ObjectId(hour['project']):
- hour['projectName'] = y
- if 'clock_out' not in hour:
- hour['clock_out']=[datetime.datetime.now()]
- time = hour['clock_out'][-1] - hour['clock_in'][-1]
- hour['total_time'] = time
- hours.append(hour)
- deltas.append(time)
+# for hour in dbhours: # Currenty acts wrong with longer than 1 day
+# for x, y in availableProjects:
+# if x is ObjectId(hour['project']):
+# hour['projectName'] = y
+# if 'clock_out' not in hour:
+# hour['clock_out']=[datetime.datetime.now()]
+# time = hour['clock_out'][-1] - hour['clock_in'][-1]
+# hour['total_time'] = time
+# hours.append(hour)
+# deltas.append(time)
- form = NewHoursForm()
- form.dateSel.data = datetime.datetime.today()
- form.projectSel.choices = availableProjects
- form.startTime.data = datetime.datetime.now()
total_hours = sum(deltas,datetime.timedelta())
statement_hours = "{} Hours, {} Minutes".format(total_hours.seconds//3600,(total_hours.seconds//60)%60)
- if form.validate_on_submit(): # Possible bug iff user clocks in between page load and form submit... will create additional time_collection entry
- indt = datetime.combine(form.dateSel.data,form.startTime.data)
- outdt = datetime.combine(form.dateSel.data,form.endTime.data)
- if user['username'] is current_user.username and not form.perDiemSel.data and not form.lunchSel.data:
- mongo.db.time_collection.insert_one({'clock_in' : [indt],
- 'modified_by' : [current_user.username],
- 'date' : datetime.datetime.today(),
- 'project' : ObjectId(form.projectSel.data),
- 'clock_out':[outdt]})
- return redirect(url_for('hours',username=user['username']))
-
- if user['username'] is not current_user.username and not form.perDiemSel.data and not form.lunchSel.data:
- mongo.db.time_collection.insert_one({'clock_in' : [indt],
- 'modified_by' : [user['username'], current_user.username],
- 'date' : datetime.datetime.today(),
- 'project' : ObjectId(form.projectSel.data),
- 'clock_out':[outdt]})
-
- return redirect(url_for('hours',username=user['username']))
-
- #hours = mongo.db.time_collection.find({'modified_by.0':user.username})
-
-
tspp = mongo.db.time_collection.aggregate( [
{
"$lookup":{
@@ -791,7 +823,7 @@ def hoursd(username):#userid goes into call to db to get user[] -> then returns
] )# Time Spent Per Project (filter entries by username, then group and sum hours by project)
- return render_template ('dashboard/punchclock/index.dev.html',form=form,hours=hours,availableProjects=availableProjects,total_hours=total_hours,statement_hours=statement_hours,user=user,tspp=tspp,ORGNAME=OrganizationName)
+ return render_template ('dashboard/punchclock/index.dev.html',hours=dbhours,availableProjects=availableProjects,total_hours=total_hours,statement_hours=statement_hours,tspp=tspp,ORGNAME=OrganizationName)
diff --git a/app/templates/dashboard/punchclock/index.dev.html b/app/templates/dashboard/punchclock/index.dev.html
@@ -4,22 +4,12 @@
{% block content %}
<section class="hours-grid">
- <h3>{{ user.fname }} {{ user.lname }}</h3><!-- IF logged in user has permission allow this username section to be a dropdown for modifying user time sheets. -->
<h1 id="clock"></h1>
<div><!-- abstract to payPeriod() -->
<h6>$payperiod range</h6>
<!--<h5>Total:{# {{ statement_hours }} #}</h5> -->
{{availableProjects}}
</div>
- <a href="{{url_for('new_time',usernm=user.username)}}" style=" border: none;
- background: var(--accent);
- cursor: pointer;
- border-radius: 3px;
- padding: 6px;
- width: 200px;
- color: white;
- margin-left: 25px;
- box-shadow: 0 3px 6px 0 rgba(0,0,0,0.2);">New Time</a>
<form action="" method="POST" novalidate>
<table><tr>
{% for field in form %}{% if field.widget.input_type != 'hidden' and field.widget.input_type != 'submit' %}
@@ -39,7 +29,7 @@
{% for entry in hours %}
<tr>
<td><a href="{{url_for('updateDate',mod_username=current_user.username,timeid=entry._id)}}">{{ entry.date.date().isoformat() }}</a></td>
- <td>{{ entry.projectName }}</td>
+ <td><a href="{{url_for('updateProjectTime',mod_username=current_user.username,timeid=entry._id)}}">{{ entry.project[0]['project_name'] }}</a></td>
<td><a href="{{url_for('updateStartTime',mod_username=current_user.username,timeid=entry._id)}}">{{ entry.clock_in[-1].time().isoformat(timespec='minutes') }}</a></td>
<td><a href="{{url_for('updateEndTime',mod_username=current_user.username,timeid=entry._id)}}">{{ entry.clock_out[-1].time().isoformat(timespec='minutes') }}</a></td>
{% if entry.lunch %}
@@ -60,7 +50,7 @@
<td><a href="{{url_for( 'removetime',timeid=entry._id) }}" class="action-button">Remove</a></td>
{#{{ form.hidden_tag() }}#}
</tr>
- {# {{entry}} #}
+ {{entry}}
{% endfor %}
</table>
</form>