commit 8dceaeecd45b24493b6906193dc764e7ac59bf6f
parent fa1a16b584a17e98e524123acb962b317b7c851e
Author: Youth Employment Program Production <youthemployment22@gmail.com>
Date: Fri, 24 May 2024 08:51:04 -0600
various fixes to equipment and meetings pages, admin pages and hoursd
Diffstat:
16 files changed, 139 insertions(+), 38 deletions(-)
diff --git a/app/equipment/__pycache__/equipment.cpython-310.pyc b/app/equipment/__pycache__/equipment.cpython-310.pyc
Binary files differ.
diff --git a/app/equipment/__pycache__/forms.cpython-310.pyc b/app/equipment/__pycache__/forms.cpython-310.pyc
Binary files differ.
diff --git a/app/equipment/__pycache__/routes.cpython-310.pyc b/app/equipment/__pycache__/routes.cpython-310.pyc
Binary files differ.
diff --git a/app/equipment/equipment.py b/app/equipment/equipment.py
@@ -30,6 +30,24 @@ def get_available_equipment():
equipment = mongo.db.equipment_collection.find({'retired':{'$exists':False},'checked_out':{'$exists':False}})
return equipment
+# return available equipment by type
+def get_available_equipment_type(equipment_type,branch=None):
+ matchdoc = {"equipment_type":equipment_type,'checked_out':{'$exists':False},'retired':{'$exists':False}}
+ if branch != None:
+ matchdoc["branch"] = branch
+ equipment = mongo.db.equipment_collection.aggregate( [
+ {
+ "$match": matchdoc
+ },
+ {
+ "$sort": {
+ "equipment_type":1,
+ "purchase_timestamp":1
+ }
+ }
+ ] )
+ return equipment
+
# return document of equipment type (_id) and count(number of occurances)
def get_equipment_types():
types = mongo.db.equipment_collection.aggregate( [
@@ -51,3 +69,16 @@ def count_equipment_types():
counts.append((tool['_id'],label))
return counts
+# update db and returns equipment with checked_out attribute set to True by id
+def checkout_equipment_id(equipment_id):
+ equipment = fetch_equpiment(equipment_id)
+ equipment['checked_out'] = True
+ mongo.db.equipment_collection.update({'_id':equipment_id},{'$set':{'checked_out':True}})
+ return equipment
+
+# update db and returns equipment with popped checked_out attribute by id
+def checkin_equipment_id(equipment_id):
+ equipment = fetch_equipment(equipment_id)
+ equipment.pop('checked_out')
+ mongo.db.equipment_collection.update({'_id':equipment_id},{'$unset':{'checked_out':""}})
+ return equipment
diff --git a/app/equipment/routes.py b/app/equipment/routes.py
@@ -4,9 +4,10 @@ from flask import render_template, redirect, url_for, flash, request
from flask_login import login_required
from bson.objectid import ObjectId
from app.routes import get_available_projects
+from app.branches.routes import get_available_branches
from app.equipment import bp
from app.equipment.forms import NewEquipment, UpdateEquipment
-from app.equipment.equipment import fetch_equipment, EquipmentNotFoundError, get_all_equipment, get_usable_equipment, get_available_equipment, get_equipment_types, count_equipment_types
+from app.equipment.equipment import fetch_equipment, EquipmentNotFoundError, get_all_equipment, get_usable_equipment, get_available_equipment, get_available_equipment_type, get_equipment_types, count_equipment_types
import datetime
mongo = PyMongo(app)
@@ -136,18 +137,7 @@ def equipment(equipment_id):
@bp.route("/equipment/t/<equipmentType>",methods=["GET"])
@login_required
def EquipmentType(equipmentType):
- equipment = mongo.db.equipment_collection.aggregate( [
- {
- "$match": {"equipment_type":equipmentType
- }
- },
- {
- "$sort": {
- "equipment_type":1,
- "purchase_timestamp":1
- }
- }
- ] )
+ equipment = get_available_equipment_type(equipmentType)
return render_template("equipment.html",equipment=equipment)
@bp.route("/newequipment")
@@ -183,6 +173,7 @@ def update_equipment(equipment_id,update):
types.append(('Create New Type','Create New Type'))
form.equipment_type.choices = types
form.purchasing_project.choices = get_available_projects()
+ form.branch.choices = get_available_branches()
try:
equipment = fetch_equipment(equipment_id)
@@ -216,6 +207,10 @@ def update_equipment(equipment_id,update):
mongo.db.equipment_collection.update_one({'_id':equipment['_id']},{'$set':{'purchasing_project':form.purchasing_project.data}})
flash("Updated Purchasing Project to {}".format(form.purchasing_project.data))
return redirect(url_for('equipment.equipment',equipment_id=equipment_id))
+ case "branch":
+ mongo.db.equipment_collection.update_one({'_id':equipment['_id']},{'$set':{'branch':form.branch.data}})
+ flash("Updated Branch to {}".format(form.branch.data))
+ return redirect(url_for('equipment.equipment',equipment_id=equipment_id))
return render_template("form_equipment.html",update=update,form=form,equipment=equipment)
diff --git a/app/meetings/__pycache__/routes.cpython-310.pyc b/app/meetings/__pycache__/routes.cpython-310.pyc
Binary files differ.
diff --git a/app/meetings/routes.py b/app/meetings/routes.py
@@ -6,6 +6,7 @@ from app.meetings import bp
from bson.objectid import ObjectId
import datetime, hashlib
import os
+from gridfs import GridFS
from app.meetings.forms import NewMeeting, UpdateMeeting, NewFileUpload
#from app.meetings.update import
#from app.meetings.meeting import
@@ -107,6 +108,7 @@ def meetings():
'$limit':7
}
])
+
return render_template('meetings.html',ongoingMeetings=ongoingMeetings,upcomingMeetings=upcomingMeetings,pastMeetings=pastMeetings)
@bp.route('/meetings/past',methods=["GET"])
@@ -156,7 +158,7 @@ def new_meeting():
# new_meeting['meeting_name']=form.name.data
return render_template('new_meeting.html',form=form)
-@bp.route('/meeting/<meeting_id>/upload',methods=["GET","POST"])
+@bp.route('/meeting/<meeting_id>/upload',methods=["GET","POST","PUT"])
@login_required
def upload_meeting_document(meeting_id):
try:
@@ -165,12 +167,40 @@ def upload_meeting_document(meeting_id):
return render_template('error.html',error=e)
else:
form = NewFileUpload()
- upload = datetime.datetime.utcnow()
+ #upload.filename = "test"
if form.validate_on_submit():
- flash("submitted")
- mongo.db.meeting_collection.update_one({'_id':meeting['_id']},{'$push':{'documents':'brennen'}})
+ fs = GridFS(mongo.db)
+ upload = request.files['file']
+ if upload.filename != '':
+ fs.put(upload)
+ flash("submitted {}".format(upload.filename))
+ mongo.db.meeting_collection.update_one({'_id':meeting['_id']},{'$push':{'documents':upload.filename}})
return redirect(url_for('meetings.upload_meeting_document',meeting_id=meeting['meeting_id']))
- return render_template('upload_meeting_document.html',meeting=meeting,form=form,upload=upload)
+# app_root = os.path.dirname(os.path.abspath(__file__))
+# target = os.path.join(app_root, 'static/meeting-docs')
+# if not os.path.isdir(target):
+# os.mkdir(target)
+# if request.method == "POST":
+# upload = request.files['file']
+# if upload.filename != '':
+# upload.save(os.path.join('static/meeting-docs',upload.filename))
+# flash("submitted {}".format(upload.filename))
+# mongo.db.meeting_collection.update_one({'_id':meeting['_id']},{'$push':{'documents':upload.filename}})
+# return redirect(url_for('meetings.upload_meeting_document',meeting_id=meeting['meeting_id']))
+ return render_template('upload_meeting_document.html',meeting=meeting,form=form)
+
+@bp.route('/meeting/get-file/<fid>')
+@bp.route('/meeting/get-file')
+def get_meeting_file(fid=None):
+ fs = GridFS(mongo.db)
+ #fs = GridFS(MongoClient().CINEfs_example)
+
+ if fid is not None:
+ file = fs.get(ObjectId(fid))
+ rfile = app.response_class(file, direct_passthrough=True, mimetype='application/octet-stream')
+ rfile.headers.set('Content-Disposition','attachment', filename=fid) #maybe change to actually return real filename instead of file_id
+ return rfile
+ return render_template('get_meeting_file.html', files=fs.list())
@bp.route('/meeting/<meeting_id>/update',methods=["GET","POST"])
@login_required
diff --git a/app/meetings/templates/meetings.html b/app/meetings/templates/meetings.html
@@ -10,8 +10,8 @@
{% endfor %}
{% endif %}
{% endwith %}
- <section>
- {% if ongoingMeetings %}
+ <section class="hours-grid">
+ {% if ongoingMeetings is defined %}
<section class="ongoing">
<h2 style="color:red">Ongoing</h2>
{% for ongoing in ongoingMeetings %}
@@ -33,14 +33,14 @@
</section>
{% endif %}
{% if pastMeetings %}
- <section>
+ <section style="margin-bottom:1em;">
<h2>Past Meetings:</h2>
{%- for meeting in pastMeetings %}
- <div>
+ <div style="padding-bottom:1em;">
<a href="{{ url_for('meetings.meeting',meeting_id=meeting['meeting_id']) }}"><div>{{ meeting.timestamp.date().isoformat() }} @ {{ meeting.timestamp.time().isoformat(timespec='minutes') }}</div>{% if allOldMeetings %}<div>{{meeting['meeting_description']}}</div>{% endif %}</a>
</div>
{%- endfor %}
- {% if not allOldMeetings %}<a href="{{ url_for('meetings.past_meetings') }}"class="action-button">View older meetings</a>{% endif %}
+ {% if not allOldMeetings %}<a href="{{ url_for('meetings.past_meetings') }}" class="action-button">View older meetings</a>{% endif %}
{% if allOldMeetings %}<a href="{{ url_for('meetings.meetings') }}"class="action-button">Back to meetings</a>{% endif %}
</section>
{% endif %}
diff --git a/app/meetings/templates/upload_meeting_document.html b/app/meetings/templates/upload_meeting_document.html
@@ -12,7 +12,7 @@
{% endwith %}
<a href="{{ url_for('meetings.meeting',meeting_id=meeting['meeting_id']) }}">back to meeting</a>
<section class="hours-grid">{#class="meeting">#}
- <h2>{{ upload.date() }} {{ upload.time().isoformat(timespec='minutes') }}</h2>
+ {# <h2>{{ upload.date() }} {{ upload.time().isoformat(timespec='minutes') }}</h2> #}
<p>Upload document to {{ meeting['timestamp'].date() }} Meeting for {{ meeting['meeting_description'] }}</p>
<form action="" method="POST" novalidate enctype="multipart/form-data">
{{ form.hidden_tag() }}
diff --git a/app/templates/admin/agreements/index.html b/app/templates/admin/agreements/index.html
@@ -14,8 +14,8 @@
<dl>
<dt>{{ agreement['agreement_name'] }}<a href="{{url_for('rename_agreement',agreement_id=agreement['_id'])}}" style="color:var(--accent)"> change</a></dt>
<dd>
- {%- for element in agreement['signing_agency'] %}
- {{ agreement[element] }}
+ {%- for element in agreement['agency'] %}
+ {{ agreement['agency'] }}
{%- endfor %}
</dd>
<dd>{{ agreement['start_date'] }} - {{ agreement['end_date'] }}<a href="{{url_for('change_agreement_dates')}}" style="color:var(--accent);"> change</a></dd>
diff --git a/app/templates/admin/agreements/projects/index.html b/app/templates/admin/agreements/projects/index.html
@@ -36,13 +36,13 @@
</tr>
{% for entry in payperiod_times %}
<tr>
- <td>{{entry['date'].date().isoformat()}}</td>
+ <td><a href="{{url_for('updateDate',mod_username=current_user.username,timeid=entry._id)}}">{{entry['date'].date().isoformat()}}</a></td>
<td>{{entry.modified_by.0}}</td>
{% if entry['clock_out'] %}<td>{{(entry['clock_out'][-1]-entry['clock_in'][-1])}}</td>{% else %}<td>Clocked In</td>{% endif %}
- <td>{{entry['clock_in'][-1].time().isoformat(timespec='minutes')}}</td>
- {% if entry['clock_out'] %}<td>{{entry['clock_out'][-1].time().isoformat(timespec='minutes')}}</td>{% else %}<td>Clocked In</td>{% endif %}
- {% if entry['lunch'] %}<td>{{entry['lunch']}}</td>{% else %}<td> </td>{% endif %}<!-- make this an image of checkbox so can link to toggle route... -->
- {% if entry['perdiem'] %}<td>{{entry['perdiem']}}</td>{% else %}<td> </td>{% endif %}<!-- make this an image of checkbox so can link to toggle route... -->
+ <td><a href="{{url_for('updateStartTime',mod_username=current_user.username,timeid=entry._id)}}">{{entry['clock_in'][-1].time().isoformat(timespec='minutes')}}</a></td>
+ {% if entry['clock_out'] %}<td><a href="{{url_for('updateEndTime',mod_username=current_user.username,timeid=entry._id)}}">{{entry['clock_out'][-1].time().isoformat(timespec='minutes')}}</a></td>{% else %}<td><a href="{{url_for('updateEndTime',mod_username=current_user.username,timeid=entry._id)}}">Clocked In</a></td>{% endif %}
+ {% if entry['lunch'] %}<td><a href="{{url_for('toggle_lunch',timeid=entry._id)}}">{{entry['lunch']}}</a></td>{% else %}<td><a href="{{url_for('toggle_lunch',timeid=entry._id)}}"> </a></td>{% endif %}<!-- make this an image of checkbox so can link to toggle route... -->
+ {% if entry['perdiem'] %}<td><a href="{{url_for('toggle_per_diem',timeid=entry._id)}}">{{entry['perdiem']}}</a></td>{% else %}<td><a href="{{url_for('toggle_per_diem',timeid=entry._id)}}"> </a></td>{% endif %}<!-- make this an image of checkbox so can link to toggle route... -->
<td>{{entry['note']}}</td>
</tr>
{% endfor %}
diff --git a/app/templates/admin/agreements/projects/newproject.html b/app/templates/admin/agreements/projects/newproject.html
@@ -13,6 +13,7 @@
{% for ferror in form.form_errors %}
<span style="color:yellow;">[{{ ferror }}]</span>
{% endfor %}
+ {{ form.fenumber.label }}{{ form.fenumber() }}<br>
{{ form.projectName.label }}{{ form.projectName() }}<br>
{{ form.agreement.label }}{{ form.agreement() }}<br>
{{ form.branch.label }}{{ form.branch() }}<br>
diff --git a/app/templates/admin/agreements/projects/update/rename.html b/app/templates/admin/agreements/projects/update/rename.html
@@ -20,6 +20,7 @@
{% endfor %}
{% endif %}
{% endwith %}
+ {{ form.fenumber.label }}{{ form.fenumber() }}<br>
{{ form.newName.label }}{{ form.newName() }}<br>
{{ form.renameProject() }}
</form>
diff --git a/app/templates/admin/bound_timedata_report/widget.html b/app/templates/admin/bound_timedata_report/widget.html
@@ -67,21 +67,36 @@
<th>Time(hrs)</th>
</tr>
{% for time in times['times'] %}
+ <!-- {# <a href="{{url_for('hours',username=time['modified_by'][0])}}#{{time['_id']}}"> #} -->
<tr>
- <td>{{time['date'].date().isoformat()}}</td>
- <td>{{time['project_data'][0]['project_name']}}</td>
- <td>{{time['clock_in'][-1].time().isoformat(timespec="minutes")}}</td>
+ <td><a href="{{url_for('updateDate',mod_username=current_user.username,timeid=time._id)}}">{{time['date'].date().isoformat()}}</a></td>
+ <td><a href="{{url_for('updateProjectTime',mod_username=current_user.username,timeid=time._id)}}">{{time['project_data'][0]['project_name']}}</a></td>
+ <td><a href="{{url_for('updateStartTime',mod_username=current_user.username,timeid=time._id)}}">{{time['clock_in'][-1].time().isoformat(timespec="minutes")}}</a></td>
{% if time['clock_out'] is defined %}
- <td>{{time['clock_out'][-1].time().isoformat(timespec="minutes")}}</td>
+ <td><a href="{{url_for('updateEndTime',mod_username=current_user.username,timeid=time._id)}}">{{time['clock_out'][-1].time().isoformat(timespec="minutes")}}</a></td>
{% else %}
- <td>Clocked In</td>
+ <td><a href="{{url_for('updateEndTime',mod_username=current_user.username,timeid=time._id)}}">Clocked In</a></td>
{% endif %}
- <td>{{time['lunchCount']}}</td>
- <td>{{time['perdiemCount']}}</td>
+ <td><a href="{{url_for('toggle_lunch',timeid=time._id)}}">{{time['lunchCount']}}</a></td>
+ <td><a href="{{url_for('toggle_per_diem',timeid=time._id)}}">{{time['perdiemCount']}}</a></td>
<td><a href="{{url_for('hours',username=time['modified_by'][0])}}">{{ (time['totalHoursWorked']/(1000*60*60))|round(2) }}</a></td>
</tr>
{% endfor %}
</table></div>
+ <table>
+ <tr>
+ <th>Date</th>
+ <th>Note</th>
+ </tr>
+ {% for item in times['times'] %}
+ {% if item['note'] %}
+ <tr>
+ <td>{{item['date'].date().isoformat()}}</td>
+ <td>{{item['note']}}</td>
+ </tr>
+ {% endif %}
+ {% endfor %}
+ </table>
{% endfor %}
<!-- </section>
@@ -129,11 +144,13 @@
<th>Note</th>
</tr>
{% for item in times['times'] %}
+ {% if item['note'] %}
<tr>
<td>{{item['date'].date().isoformat()}}</td>
<td>{{item['modified_by'][0]}}</td>
<td>{{item['note']}}</td>
</tr>
+ {% endif %}
{% endfor %}
</table>
{% endfor %}
diff --git a/app/templates/admin/layout.html b/app/templates/admin/layout.html
@@ -3,6 +3,15 @@
{% block title %}Admin{% endblock %}
{% block content %}
+
+{% with messages = get_flashed_messages() %}
+ {% if messages %}
+ {% for message in messages %}
+ <div id="messagebanner"><p>{{ message }}</p></div>
+ {% endfor %}
+ {% endif %}
+{% endwith %}
+
<section class="admin-grid">
<!-- returned values from admin check is array of permissive ACCESS else return 'missing permissions response' -->
{%- for x in permissions %}
diff --git a/app/templates/dashboard/punchclock/index.dev.html b/app/templates/dashboard/punchclock/index.dev.html
@@ -3,7 +3,20 @@
{% block title %}Hours{% endblock %}
{% block content %}
+{% with messages = get_flashed_messages() %}
+ {% if messages %}
+ {% for message in messages %}
+ <div id='messagebanner'><p>{{message}}</p></div>
+ {% endfor %}
+ {% endif %}
+{% endwith %}
+
<section class="hours-grid">
+ {{ cd[2] }}
+ {{ cd[1] }}
+ {{ bd[2] }}
+ {{ bd[1] }}
+ {{ current_user.birthday }}
<h1 id="clock"></h1>
<div><!-- abstract to payPeriod() -->
<h6>$payperiod range</h6>
@@ -15,7 +28,11 @@
{% 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>
+ {% if entry.project[0] %}
<td><a href="{{url_for('updateProjectTime',mod_username=current_user.username,timeid=entry._id)}}">{{ entry.project[0]['project_name'] }}</a></td>
+ {% else %}
+ <td><a href="{{url_for('updateProjectTime',mod_username=current_user.username,timeid=entry._id)}}">Project not Found</a></td>
+ {% endif %}
<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 %}