commit fa1a16b584a17e98e524123acb962b317b7c851e
parent 3d5aeaa83b9332a6435a7ef357b72ea21b2636d1
Author: Youth Employment Program Production <youthemployment22@gmail.com>
Date: Fri, 24 May 2024 08:48:10 -0600
push for offline work
Diffstat:
5 files changed, 95 insertions(+), 63 deletions(-)
diff --git a/TODO.md b/TODO.md
@@ -42,7 +42,9 @@
## OPTIONAL
-- [ ] rework admin page flow to show agency for projects?... wanted to sort and display by agency, but is many to one relationship...
+- [X] rework admin page flow to show agency for projects?... wanted to sort and display by agency, but is many to one relationship...
+### Unclear on how to do the below, doesn't appear to be able to remove session from client or make invalid session...
+### Will likely have to overload the @login_required fn to check for user is_active... will have to on route check for updates, not sure if user object is refreshing every page... likely just being set on login.
- [ ] When users are set to inactive or active (probably just inactive) should remove all current/existing sessions
#TODO TODAY!!!
- [X] Change username to firstname lastname for today
diff --git a/app/forms.py b/app/forms.py
@@ -131,6 +131,7 @@ class ConfirmRemove(FlaskForm):
confirm = SubmitField('YES REMOVE')
class NewProjectForm(BudgetForm):
+ fenumber = IntegerField('FE #', validators=[DataRequired()])
projectName = StringField('Project Name', validators=[DataRequired()])
agreement = SelectField('Part of Agreement', validators=[DataRequired()])
branch = SelectField('Organization Branch', validators=[DataRequired()])
@@ -141,6 +142,7 @@ class MoveProjectForm(FlaskForm):
moveProject = SubmitField('Update Project')
class RenameProjectForm(FlaskForm):
+ fenumber = IntegerField('FE #', validators=[DataRequired()])
newName = StringField('Project Name', validators=[DataRequired()])
renameProject = SubmitField('Update Project')
diff --git a/app/meetings/templates/get_meeting_file.html b/app/meetings/templates/get_meeting_file.html
@@ -0,0 +1,18 @@
+{% extends 'base.html' %}
+
+{% block title %}Get File{% 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">{#class="meeting">#}
+ <ul>{% for file in files %}
+ <li><a href="{{ url_for('meetings.get_meeting_file', fid=file) }}">{{ file }}</a></li>
+ {% endfor %}</ul>
+ </section>
+{% endblock %}
diff --git a/app/routes.py b/app/routes.py
@@ -10,6 +10,7 @@ from werkzeug.urls import url_parse
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import current_user, login_user, logout_user, login_required
from app.branches.routes import get_available_branches
+from app.equipment.equipment import get_available_equipment_type
from app.models import User, Time, Fleet, Agreement, Projects
from bson.objectid import ObjectId
import bson.json_util as json_util
@@ -43,12 +44,25 @@ def fetch_user_from_username(username):
else:
return user
+# Add ability to get users by role type... case match statement inside if for default no arguments?
+# TODO currently doesn't care about active state. FIX
+def get_available_users(active=True,role=None,branch=None):
+ availableUsers = [("","Select User")]
+ for user in mongo.db.users_collection.find():
+ if branch:
+ if 'branch' in user:
+ if user['branch'] == 'Global' or user['branch'] == branch:
+ availableUsers.append((user['_id'],user['username']))
+ else:
+ availableUsers.append((user['_id'],user['username']))
+ return availableUsers
+
def get_available_projects(branch=None):
availableProjects = [("","Select Project")]
for project in mongo.db.projects_collection.find():
if branch:
if 'branch' in project:
- if project['branch'] == 'Global' or project['branch'] == branch:
+ if project['branch'] == 'Global' or project['branch'] == ObjectId(branch):
availableProjects.append((project['_id'],project['project_name']))
else:
availableProjects.append((project['_id'],project['project_name']))
@@ -209,17 +223,11 @@ def chgpass_by_uid(uid):
#### ####
@app.route('/index')
-#def hello():
-# return redirect(url_for('dashboard'))
@app.route("/dashboard", methods=['GET', 'POST'])
@login_required
def dashboard():
currentdate = datetime.datetime.now()
- #Banner, TODO create a MOTD framework, for admin messages
- if currentdate.strftime('%Y-%m-%d') == current_user.birthday:
- flash("Happy Birthday {}!".format(current_user.fname))
- ## END Banner
dashperms=mongo.db.permissions_collection.find_one({'label': current_user.role},{'dashboard':1,'_id':0})
dashperms=dashperms['dashboard']
@@ -287,14 +295,14 @@ def dashboard():
flash('Unable to check out vehicle')
return redirect(url_for('dashboard'))
-# Temp values, change to db dependent values
- #availableVehicles = ['Vehicle 1', 'Vehicle 2', 'Vehicle 3', 'Vehicle 4']
- availableVehicles = mongo.db.fleet_collection.find_one({'_id':'Fleet Pool'},{'available':1})['available']
- lastMileage = 103483
+ #def newfleet_check_out(vehicle_id,start_milage,additional_notes=None,safety_checks=None)
+ #availableVehicles = mongo.db.fleet_collection.find_one({'_id':'Fleet Pool'},{'available':1})['available']
+ availableVehicles = [("","Select Vehicle")]
+ for vehicle in get_available_equipment_type('vehicle',branch=current_user.branch):
+ availableVehicles.append((vehicle['_id'],"Vehicle {}".format(vehicle['vehicle_id'])))
+
#currently gets ALL projects TODO make filter by available agreements/projects
- availableProjects = get_available_projects()
- #for project in mongo.db.projects_collection.find():
- # availableProjects.append((project['_id'],project['project_name']))
+ availableProjects = get_available_projects(current_user.branch)
# GET_CLOCKED out users
clocked_out_active_users=[]
clocked_in_active_users=[]
@@ -369,11 +377,11 @@ def dashboard():
@login_required
def updateProjectTime(mod_username,timeid):
timeid = ObjectId(timeid)
- availableProjects = [] #change to get_available_projects() -> projects where user branch == project['branch']
+ availableProjects = get_available_projects(current_user.branch)#[] #change to get_available_projects() -> projects where user branch == project['branch']
form = updateProject()
- for project in mongo.db.projects_collection.find():
- availableProjects.append((project['_id'],project['project_name']))
+# for project in mongo.db.projects_collection.find():
+# availableProjects.append((project['_id'],project['project_name']))
form.projectSel.choices = availableProjects
@@ -568,9 +576,10 @@ def toggle_per_diem(timeid):
@login_required
def clockin_new_user():
clocked_in_users = mongo.db.time_collection.find({'clock_out': {'$exists':False}})
- availableProjects = []
- for project in mongo.db.projects_collection.find():
- availableProjects.append((project['_id'],project['project_name']))
+ availableProjects = get_available_projects(current_user.branch)#[]
+ #TODO Might be helpful to make available projects search for projects available to the selected user...
+# for project in mongo.db.projects_collection.find():
+# availableProjects.append((project['_id'],project['project_name']))
# GET_CLOCKED out users
clocked_out_active_users=[]
clocked_in_active_users=[]
@@ -604,9 +613,9 @@ def clockin_new_user():
@login_required
def new_time(usernm):
user = mongo.db.user_collection.find_one({"username": usernm})
- availableProjects = []
- for project in mongo.db.projects_collection.find():
- availableProjects.append((project['_id'],project['project_name']))
+ availableProjects = get_available_projects(current_user.branch) #[]
+# for project in mongo.db.projects_collection.find():
+# availableProjects.append((project['_id'],project['project_name']))
# availableProjects = [("","Select Project")]
# for project in mongo.db.projects_collection.find():
# if 'branch' in project:
@@ -647,9 +656,9 @@ def new_time(usernm):
@login_required
def new_user_time():
clocked_in_users = mongo.db.time_collection.find({'clock_out': {'$exists':False}})
- availableProjects = []
- for project in mongo.db.projects_collection.find():
- availableProjects.append((project['_id'],project['project_name']))
+ availableProjects = get_available_projects(current_user.branch)
+# for project in mongo.db.projects_collection.find():
+# availableProjects.append((project['_id'],project['project_name']))
# GET_CLOCKED out users
clocked_out_active_users=[]
clocked_in_active_users=[]
@@ -674,26 +683,6 @@ def new_user_time():
dateentry = datetime.datetime.combine(form.dateSel.data,datetime.time())
starttime = datetime.datetime.combine(form.dateSel.data,form.startTime.data)
endtime = datetime.datetime.combine(form.dateSel.data,form.endTime.data)
-# if form.userSel.data is current_user.username:
-# mongo.db.time_collection.insert_one({
-# 'modified_by' : [form.userSel.data],
-# 'date' : dateentry,
-# 'clock_in' : [starttime],
-# 'clock_out' : [endtime],
-# 'project' : ObjectId(form.projectSel.data),
-# 'lunch': form.lunchSel.data,
-# 'per_diem':form.perDiemSel.data})
-# else:
-# mongo.db.time_collection.insert_one({
-# 'modified_by' : [form.userSel.data, current_user.username],
-# 'date' : dateentry,
-# 'clock_in' : [starttime],
-# 'clock_out' : [endtime],
-# 'project' : ObjectId(form.projectSel.data),
-# 'lunch': form.lunchSel.data,
-# 'per_diem':form.perDiemSel.data})
-
- #New
entryevent = {
'date' : dateentry,
'clock_in' : [starttime],
@@ -708,9 +697,14 @@ def new_user_time():
entryevent['modified_by'] = [form.userSel.data,current_user.username]
if form.note.data != '' and form.note.data != None:
entryevent['note'] = form.note.data
- mongo.db.time_collection.insert_one(entryevent)
-
- return redirect(url_for('new_user_time'))
+ try:
+ mongo.db.time_collection.insert_one(entryevent)
+ except:
+ flash("Unhandled error occured")
+ else:
+ flash("Created time entry for {}".format(userSel.data))
+ finally:
+ return redirect(url_for('new_user_time'))
return render_template('dashboard/punchclock/otheruser.html',form=form,ORGNAME=OrganizationName)
@@ -881,8 +875,16 @@ 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)
+ #Banner, TODO create a MOTD framework, for admin messages
+ currentdate = datetime.datetime.now()
+ currentdate = currentdate.strftime('%Y-%m-%d')
+ currentdate = currentdate.split('-')
+ birthday = current_user.birthday.split("-")
+ if currentdate[1] == birthday[1] and currentdate[2] == birthday[2]:
+ flash("Happy Birthday {}!".format(current_user.fname))
+ ## END Banner
- return render_template ('dashboard/punchclock/index.dev.html',hours=dbhours,tspp=tspp,ORGNAME=OrganizationName)
+ return render_template ('dashboard/punchclock/index.dev.html',cd=currentdate, bd=birthday,hours=dbhours,tspp=tspp,ORGNAME=OrganizationName)
@@ -905,9 +907,9 @@ def hours(username):
#dashperms=dashperms['dashboard']
#total_hours=0
user = mongo.db.user_collection.find_one({"username": username})
- availableProjects = []
- 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'
+ availableProjects = get_available_projects(current_user.branch)
+# 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.aggregate( [
{
@@ -1094,8 +1096,14 @@ def activate_user(userid):
@login_required
def removetime(timeid):
timeid = ObjectId(timeid)
- mongo.db.time_collection.delete_one({'_id':timeid})
- return redirect(url_for('dashboard'))
+ try:
+ mongo.db.time_collection.delete_one({'_id':timeid})
+ except:
+ flash("An unhandled error occured removing time")
+ else:
+ flash("Removed Time")
+ finally:
+ return redirect(url_for('dashboard'))
#@app.route("/clockoutuser/<modusernm>/<timeid>", methods=['GET','POST'])
#@login_required
#def clockout_by_id(modusernm,timeid):
@@ -1127,7 +1135,6 @@ def moduser(uid):
dashperms=dashperms['dashboard']
for perm in dashperms:
- #availableProjects.append((project['_id'],project['project_name']))
availableRoles.append((perm['_id'],perm['label']))
defaultBranch = 'Dillon'
@@ -1311,8 +1318,10 @@ def newproject():
if form.otherBudget.data is None:
form.otherBudget.data = 0.0
+ pjname = "FE " + str(form.fenumber.data) + ": " + form.projectName.data
+
mongo.db.projects_collection.insert_one({
- 'project_name':form.projectName.data,
+ 'project_name':pjname,
'agreement':ObjectId(form.agreement.data),
'branch':form.branch.data,
#'branch':ObjectId(form.branch.data),
@@ -1339,7 +1348,7 @@ def newproject():
'other':0
}]
})
- pj_id = mongo.db.projects_collection.find_one({'project_name':form.projectName.data})['_id']
+ pj_id = mongo.db.projects_collection.find_one({'project_name':pjname})['_id']
mongo.db.agreements_collection.update_one({ '_id':ObjectId(form.agreement.data) },{ '$push':{ 'projects':pj_id }})
flash("{} part of {} added".format(form.projectName.data, form.agreement.data )) #Will need to sendmail password to form.email.data later
@@ -1377,15 +1386,16 @@ def project(project_id):
def rename_project(project_id):
form = RenameProjectForm()
if form.validate_on_submit():
+ pjname = "FE " + str(form.fenumber.data) + ": " + form.newName.data
try:
project = mongo.db.projects_collection.find_one({'_id':project_id})
except:
flash("Issue finding Project with id {}".format(project_id))
else:
try:
- mongo.db.projects_collection.update_one({'_id':ObjectId(project_id)},{'$set':{'project_name':form.newName.data}})
+ mongo.db.projects_collection.update_one({'_id':ObjectId(project_id)},{'$set':{'project_name':pjname}})
except:
- flash("Issue setting {} as project name for {}".format(form.newName.data,project_id))
+ flash("Issue setting {} as project name for {}".format(pjname,project_id))
finally:
return redirect(url_for('project', project_id=project_id))
return render_template('admin/agreements/projects/update/rename.html',form=form,ORGNAME=OrganizationName)
diff --git a/app/static/css/main.css b/app/static/css/main.css
@@ -57,7 +57,7 @@ button, input[type="submit"], input[type="checkbox"] {
/*margin-left: 25px;*/
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.2);
&:hover {
- transform: translateY(-10px);
+ transform: translateY(-2px);
box-shadow: 0 6px 6px 0 rgba(0,0,0,0.2);
}
}
@@ -138,7 +138,7 @@ dl {
color: white;
margin-left: 25px;
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.2);
-/* &:hover { transform: translateY(-10px); box-shadow: 0 6px 6px 0 rgba(0,0,0,0.2); };*/
+/* &:hover { transform: translateY(-5px); box-shadow: 0 6px 6px 0 rgba(0,0,0,0.2); };*/
}
.action-button {
border: none;