Merge branch 'master' into section_complete_boolean
This commit is contained in:
commit
04a742dec0
5 changed files with 78 additions and 16 deletions
38
back/backend/migrations/0008_auto_20190214_1421.py
Normal file
38
back/backend/migrations/0008_auto_20190214_1421.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Generated by Django 2.1.5 on 2019-02-14 22:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('backend', '0007_merge_20190213_2318'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='field',
|
||||
name='data_decimal',
|
||||
field=models.DecimalField(decimal_places=2, default=0, max_digits=9),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='field',
|
||||
name='number',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='section',
|
||||
name='auto_submit',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='section',
|
||||
name='completed',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='section',
|
||||
name='required',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
|
@ -15,9 +15,9 @@ class Report(models.Model):
|
|||
|
||||
class Section(models.Model):
|
||||
report_id = models.ForeignKey(Report, on_delete=models.CASCADE)
|
||||
auto_submit = models.BooleanField()
|
||||
required = models.BooleanField()
|
||||
completed = models.BooleanField()
|
||||
auto_submit = models.BooleanField(default=False)
|
||||
required = models.BooleanField(default=False)
|
||||
completed = models.BooleanField(default=False)
|
||||
title = models.CharField(max_length=256)
|
||||
html_description = models.TextField()
|
||||
number = models.IntegerField()
|
||||
|
@ -29,11 +29,11 @@ class Field(models.Model):
|
|||
section_id = models.ForeignKey(Section, on_delete=models.CASCADE)
|
||||
field_name = models.CharField(max_length=512, default="field")
|
||||
label = models.CharField(max_length=512)
|
||||
number = models.IntegerField()
|
||||
number = models.IntegerField(default=0)
|
||||
field_type = models.CharField(max_length=128)
|
||||
completed = models.BooleanField(default=False)
|
||||
data_bool = models.BooleanField(default=False)
|
||||
data_decimal = models.DecimalField(max_digits=9, decimal_places=2, null=True, blank=True)
|
||||
data_decimal = models.DecimalField(max_digits=9, decimal_places=2, default=0)
|
||||
data_date = models.DateField(null=True, blank=True)
|
||||
data_file = models.FileField(upload_to='uploads/%Y/%m/%d/', max_length=512, null=True, blank=True)
|
||||
data_string = models.TextField(default='', blank=True)
|
||||
|
|
|
@ -45,7 +45,7 @@ general_section = Section(
|
|||
|
||||
general_section.add_rule(
|
||||
title="Destination city check",
|
||||
rule=lambda report, section: section.field.destination == "Timbuktu",
|
||||
rule=lambda report, fields: fields['destination'] == "Timbuktu",
|
||||
rule_break_text="What did the cowboy say about Tim, his wild horse?"
|
||||
)
|
||||
|
||||
|
@ -68,7 +68,7 @@ flight_section = Section(
|
|||
|
||||
flight_section.add_rule(
|
||||
title="Airline fare pre-approval check",
|
||||
rule=lambda report, section: section.fields.fare < 500,
|
||||
rule=lambda report, fields: fields['fare'] < 500,
|
||||
rule_break_text="Fares cannot be more than $500"
|
||||
)
|
||||
|
||||
|
@ -88,14 +88,14 @@ lodging_section = Section(
|
|||
}
|
||||
)
|
||||
|
||||
def nightly_rate_check(report, section):
|
||||
checkin_date = date(section.fields.checkin_date)
|
||||
checkout_date = date(section.fields.checkout_date)
|
||||
def nightly_rate_check(report, fields):
|
||||
checkin_date = date(fields['checkin_date'])
|
||||
checkout_date = date(fields['checkout_date'])
|
||||
duration = checkout_date - checkin_date
|
||||
return section.fields.cost <= duration * section.fields.rate
|
||||
return fields['cost'] <= duration * fields['rate']
|
||||
|
||||
lodging_section.add_rule(
|
||||
title="",
|
||||
title="Average nightly rate",
|
||||
rule=nightly_rate_check,
|
||||
rule_break_text="The average nightly rate cannot be more than the USGSA rate."
|
||||
)
|
||||
|
@ -108,14 +108,14 @@ transport_section = Section(
|
|||
title="Local Transportation",
|
||||
html_description="<p>How much did you spend on local transportation, in total?</p>",
|
||||
fields={
|
||||
"duration": {"label": "How many days was your trip?", "field_type": "decimal"},
|
||||
"duration": {"label": "How many days was your trip?", "field_type": "integer"},
|
||||
"cost": {"label": "Total cost", "field_type": "decimal"}
|
||||
}
|
||||
)
|
||||
|
||||
transport_section.add_rule(
|
||||
title="Total cost check",
|
||||
rule=lambda report, section: section.fields.cost <= section.fields.duration * 10,
|
||||
rule=lambda report, fields: fields['cost'] <= fields['duration'] * 10,
|
||||
rule_break_text="Local transportation costs must be less than $10 per day, on average."
|
||||
)
|
||||
|
||||
|
@ -136,7 +136,7 @@ per_diem_section = Section(
|
|||
|
||||
per_diem_section.add_rule(
|
||||
title="Per Diem Cost Check",
|
||||
rule=lambda report, section: section.fields.cost <= section.fields.duration * section.fields.rate,
|
||||
rule=lambda report, fields: fields['cost'] <= fields['duration'] * fields['rate'],
|
||||
rule_break_text="The average cost per day for per diem expenses cannot be more than the rate specified by the USGSA."
|
||||
)
|
||||
|
||||
|
|
|
@ -28,15 +28,31 @@ def get_sections(r_id):
|
|||
# create a dict of arrays for section
|
||||
section_set = {"sections": []}
|
||||
queryset = Section.objects.filter(report_id=r_id)
|
||||
for i in queryset:
|
||||
for index in range(len(queryset)):
|
||||
i = queryset[index]
|
||||
data = {
|
||||
"id": i.id,
|
||||
"completed": i.completed,
|
||||
"title": i.title,
|
||||
"html_description": i.html_description,
|
||||
"rule_violations": [],
|
||||
}
|
||||
# append the fields for corresponding section
|
||||
data.update(get_fields(i.id))
|
||||
# process rules from the policy file if the section is completed
|
||||
if i.completed:
|
||||
rules = pol.sections[index].rules
|
||||
for rule in rules:
|
||||
try:
|
||||
named_fields = generate_named_fields_for_section(data['fields'])
|
||||
if not rule['rule'](data, named_fields):
|
||||
info = {
|
||||
"label": rule['title'],
|
||||
"rule_break_text": rule['rule_break_text'],
|
||||
}
|
||||
data['rule_violations'].append(info)
|
||||
except Exception as e:
|
||||
print('Rule "{}" encountered an error. {}'.format(rule['title'], e))
|
||||
# append section to the array
|
||||
section_set["sections"].append(data.copy())
|
||||
|
||||
|
@ -67,6 +83,14 @@ def get_fields(s_id):
|
|||
return field_set
|
||||
|
||||
|
||||
def generate_named_fields_for_section(fields):
|
||||
result = {}
|
||||
for field in fields:
|
||||
key = field['field_name']
|
||||
value = field['value']
|
||||
result[key] = value
|
||||
return result
|
||||
|
||||
# API Endpoints
|
||||
@api_view(['POST'])
|
||||
def report(request):
|
||||
|
|
BIN
back/db.sqlite3
BIN
back/db.sqlite3
Binary file not shown.
Loading…
Reference in a new issue