Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@ class Meta:
"work_phone",
"birth_date",
"join_date",
"active",
"end_date",
"end_reason",
"notes",
]
widgets = {
"birth_date": DateInput(format=("%Y-%m-%d")),
"join_date": DateInput(format=("%Y-%m-%d")),
"end_date": DateInput(format=("%Y-%m-%d")),
}
120 changes: 120 additions & 0 deletions src/models/management/commands/seed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from django.core.management.base import BaseCommand

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing wrong with this, but I think we do have some sample data, it just doesn't have a nice wrapper around if you were looking for something else!

import random
from address.models import Address, Locality, State, Country

from logging import getLogger

from models.models import (
Customer,
CustomerRecord,
Payment
)


log = getLogger(__name__)

# python manage.py seed --mode=refresh

""" Clear all data and creates cusotmers """
MODE_REFRESH = 'refresh'

""" Clear all data and do not create any object """
MODE_CLEAR = 'clear'

class Command(BaseCommand):
help = "seed database for testing and development."

def add_arguments(self, parser):
parser.add_argument('--mode', type=str, help="Mode")

def handle(self, *args, **options):
self.stdout.write('seeding data...')
run_seed(self, options['mode'])
self.stdout.write('done.')


def clear_data():
"""Deletes all the table data"""
log.info("Deleting customers")
Customer.objects.all().delete()
CustomerRecord.objects.all().delete()


def create_customer(local, payment_types):
"""Creates an customer object combining different elements from the list"""
log.info("Creating customer")

active_options = [True, False]
first_name_options = ["Bob", "Jane", "Joe", "Hank", "Jill", "Tom", "Alice"]
last_name_options = ["Smith", "Adams", "Thompson", "Berry", "Phillips"]


a = Address(
street_number="1",
route="Some Street",
locality=local,
raw="1 Some Street, Charlottesvile, VA"
)
a.save()

c = Customer(
active=random.choice(active_options),
first_name=random.choice(first_name_options),
last_name=random.choice(last_name_options),
address=a
)
c.save()


cr = CustomerRecord(
customer=c,
num_meals=1,
payment_type=random.choice(payment_types)
)
cr.save()

log.info("{} customer created.".format(c))
return c

def run_seed(self, mode):
""" Seed database based on mode

:param mode: refresh / clear
:return:
"""
# Clear data from tables
clear_data()
if mode == MODE_CLEAR:
return

payment_types = []

try:
country = Country(name="US")
country.save()
state = State(name="VA", country=country)
state.save()
local = Locality(name="Charlottesville", postal_code="22911", state=state)
local.save()
except:
local = Locality.objects.first()

try:
p1 = Payment(name="debit")
p1.save()
p2 = Payment(name="credit")
p2.save()
p3 = Payment(name="cash")
p3.save()

payment_types = [p1,p2,p3]
except:
payment_types = Payment.objects.all()


# Creating 30 customers
for i in range(30):
try:
create_customer(local,payment_types)
except:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generated by Django 4.0.4 on 2024-08-11 00:44

from django.db import migrations, models


def set_default_values(apps, schema_editor):
Volunteer = apps.get_model('models', 'volunteer')
db_alias = schema_editor.connection.alias

Volunteer.objects.update(active=True)

class Migration(migrations.Migration):

dependencies = [
('models', '0033_alter_route_bonusroute'),
]

operations = [
migrations.AddField(
model_name='volunteer',
name='end_date',
field=models.DateField(blank=True, null=True),
),
migrations.AddField(
model_name='volunteer',
name='end_reason',
field=models.TextField(blank=True, default=''),
),
migrations.AddField(
model_name='volunteer',
name='active',
field=models.BooleanField(default=True),
),
migrations.RunPython(set_default_values),
]
3 changes: 3 additions & 0 deletions src/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class Volunteer(models.Model):
birth_date = models.DateField(null=True, blank=True)
notes = models.TextField(default="", blank=True)
join_date = models.DateField(default=date.today)
end_date=models.DateField(null=True, blank=True)
end_reason = models.TextField(default="", blank=True)
active = models.BooleanField(default=True)
number_of_people = models.IntegerField(default=1)
dont_email = models.BooleanField(default=False)

Expand Down
14 changes: 9 additions & 5 deletions src/pdfs/templates/pdfs/job-overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@
<h1 style="font-weight: bold;">MOW Job Overview Report</h1>
<h5>Generated: {{today|date:'l, M. d, Y'}} at {{today|time:'h:i a'}}</h5>
<h5>** denotes volunteering via substitution</h5>
{%for d in dates%}
{% for jt in d.job_types %}
<h3 style="font-weight: bold;">{{jt.job_type.name}} ({{d.date|date:'l, M. d, Y'}})</h3>
{%for c in context%}
{% for jt in c.job_types %}
<h3 style="font-weight: bold;">{{jt.job_type_name}} ({{c.date|date:'l, M. d, Y'}})</h3>
<table class="table table-condensed">
<thead>
<th class="col-xs-4"><b>Job Name</b></th>
<th class="col-xs-8"><b>Volunteers</b></th>
<th class="col-xs-8"><b>Clients</b></th>
<th class="col-xs-8"><b>Meals</b></th>
</thead>
<tbody>
{% for j in jt.jobs %}
<tr>
<td class="col-xs-4">{{j.job.name}}</td>
<td class="col-xs-4">{{j.job.job.name}}</td>
<td class="col-xs-8">
{% for person in j.todays_volunteers %}
{% for person in j.job.todays_volunteers %}
{% if person.sub_pk %}
{% if person.name == open_substitution %}
{{open_substitution}}{% if not forloop.last %},{% endif %}
Expand All @@ -30,6 +32,8 @@ <h3 style="font-weight: bold;">{{jt.job_type.name}} ({{d.date|date:'l, M. d, Y'}
{{unassigned_job}}
{% endfor%}
</td>
<td class="col-xs-4">{{j.number_of_customers}}</td>
<td class="col-xs-4">{{j.total_meals}}</td>
</tr>
{% empty %}
<td>Nothing to display.</td><td></td>
Expand Down
4 changes: 2 additions & 2 deletions src/pdfs/templates/pdfs/monthly-billing.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ <h3 style="text-align: center;"> {{ payment_type|getPayment }}:
<th class="col-xs-6">Route</th>
</thead>
<tbody>
{% for reportday in reportday_section %}
{% for reportday in reportday_section|sort_name:"customer__last_name,customer__first_name" %}
<tr>
<td>{{ reportday.customer|getCustomer }}</td>
<td>{{ reportday.customer__first_name }} {{ reportday.customer__last_name }}</td>
<td>{{ reportday.total_meals }}</td>
<td>{{ reportday.payment_type|getPayment }}</td>
<td>{{ reportday.route_assigned|getRoute }}</td>
Expand Down
5 changes: 5 additions & 0 deletions src/pdfs/templatetags/route_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,8 @@ def numMealsOnDay(cust, date):
register.filter("getItem", getItem)
register.filter("numMealsOnDay", numMealsOnDay)
register.filter("getRange", getRange)

@register.filter
def sort_name(val, args):
x, y = args.split(',')
return sorted(val, key=lambda item: (item[x].lower(), item[y].lower()))
66 changes: 51 additions & 15 deletions src/pdfs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,21 @@
"Delivery Status", "Client Status", "Notes", "Volunteer"]


def to_pdf(html, styleSheetPath=None):
def to_pdf(html, styleSheetPath=None, options=None):
global _display
if not _display:
_display = Display(visible=0, size=(320, 240)).start()
options = {
"page-size": "Letter",
"margin-top": "0.74in",
"margin-right": "0.39in",
"margin-bottom": "0.39in",
"margin-left": "0.39in",
"print-media-type": True,
"user-style-sheet": styleSheetPath
}
if not options:
options = {
"page-size": "Letter",
"margin-top": "0.74in",
"margin-right": "0.39in",
"margin-bottom": "0.39in",
"margin-left": "0.39in",
"footer-right": "[page] of [topage]",
"print-media-type": True,
"user-style-sheet": styleSheetPath
}

pdf = pdfkit.from_string(html, False, options)

Expand Down Expand Up @@ -212,13 +214,33 @@ def job_overview_report(request, begin_date, end_date):
begin_date_datetime = datetime.datetime.strptime(begin_date, "%m-%d-%Y")
end_date_datetime = datetime.datetime.strptime(end_date, "%m-%d-%Y")
dates = actuals_to_display(
begin_date_datetime, end_date_datetime + datetime.timedelta(days=1)
begin_date_datetime, end_date_datetime + datetime.timedelta(days=1),
skip_unfilled_end=True
)

context = []
for d in dates:
job_types = []
for jt in d.job_types:
details = {"job_type_name": jt.job_type.name}
jobs = []
for job in jt.jobs:
total_num_meals = 0
customers = Customer.objects.filter(route=job.route_number)
for c in customers:
num_meals = c.num_meals_on_day(d.date)
total_num_meals += num_meals
jobs.append({"job": job, "number_of_customers": len(customers), "total_meals": total_num_meals})
details["jobs"] = jobs

job_types.append(details)
context.append({"date": d.date, "job_types": job_types})

template = get_template("pdfs/job-overview.html")
return to_pdf(
template.render(
{
"dates": dates,
"context": context,
"open_substitution": OPEN_SUBSTITUTION,
"unassigned_job": UNASSIGNED_JOB,
}
Expand Down Expand Up @@ -336,8 +358,10 @@ def monthly_billing_report(request, begin_date, end_date):
CustomerRecord.objects.filter(
num_meals__gte=1,
date__gte=begin_date,
date__lte=end_date) .values(
"customer",
date__lte=end_date).select_related('customer').values(
"customer__id",
"customer__first_name",
"customer__last_name",
"payment_type",
"route_assigned") .annotate(
total_meals=Sum("num_meals")) .order_by("payment_type"))
Expand Down Expand Up @@ -576,11 +600,23 @@ def generate_routes_report(request, date):
for c in custs:
total_meals += c.num_meals_on_day(date)


if total_meals < 1:
continue

# Append to data
data.append({"route": route, "customer_list": custs,
"total_meals": total_meals, "date": date, "vols": vols})

template = get_template("pdfs/generate-routes-report.html")
context = {"data": data}

return to_pdf(template.render(context), '/collected-static/pdfs/route_all_pdf.css')
return to_pdf(template.render(context), options = {
"page-size": "Letter",
"margin-top": "0.74in",
"margin-right": "0.39in",
"margin-bottom": "0.39in",
"margin-left": "0.39in",
"footer-right": "[page] of [topage]",
"user-style-sheet": '/collected-static/pdfs/route_all_pdf.css'
})
1 change: 0 additions & 1 deletion src/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ graphviz==0.20
gunicorn==20.1.0
idna==3.3
inflection==0.5.1
install==1.3.5
isort==5.10.1
itypes==1.2.0
Jinja2==3.1.1
Expand Down
11 changes: 11 additions & 0 deletions src/staff/templates/edit-volunteer.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ <h2>Edit Volunteer</h2>
{{ form.join_date|as_crispy_field }}
</div>
</div>
<div class="row mb-4">
<div class="form-group col-md-6">
{{ form.end_date|as_crispy_field }}
</div>
<div class="form-group col-md-6">
{{ form.active|as_crispy_field }}
</div>
<div class="form-group col-md-6">
{{ form.end_reason|as_crispy_field }}
</div>
</div>
<div class="row mb-4">
<div class="form-group col-md-12">
{{ form.notes|as_crispy_field }}
Expand Down
4 changes: 2 additions & 2 deletions src/staff/views/customer_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def manage_customers(request):
will bring up all custome
"""
# get all the substitutions in the DB from today on
all_customers = Customer.objects.all().order_by("first_name", "last_name")
all_customers = Customer.objects.all().order_by("last_name", "first_name")
return render(request, "manage-customers.html", {"cstmrs": all_customers})


Expand Down Expand Up @@ -152,7 +152,7 @@ def export_customers(request):
writer = csv.writer(response)
writer.writerow(field_names)

customers = Customer.objects.filter(active=1)
customers = Customer.objects.all().order_by("last_name", "first_name")

for obj in customers:
writer.writerow([getattr(obj, field) for field in field_names])
Expand Down
Loading