Implemented policy parsing, applied policy to report creation, added field_name to fields.
This commit is contained in:
parent
fc2d2e9e9d
commit
38a9464870
6 changed files with 87 additions and 98 deletions
18
back/backend/migrations/0005_field_field_name.py
Normal file
18
back/backend/migrations/0005_field_field_name.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.1.5 on 2019-02-07 22:02
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('backend', '0004_auto_20190131_1645'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='field',
|
||||||
|
name='field_name',
|
||||||
|
field=models.CharField(default='field', max_length=512),
|
||||||
|
),
|
||||||
|
]
|
|
@ -26,12 +26,13 @@ class Section(models.Model):
|
||||||
|
|
||||||
class Field(models.Model):
|
class Field(models.Model):
|
||||||
section_id = models.ForeignKey(Section, on_delete=models.CASCADE)
|
section_id = models.ForeignKey(Section, on_delete=models.CASCADE)
|
||||||
|
field_name = models.CharField(max_length=512, default="field")
|
||||||
label = models.CharField(max_length=512)
|
label = models.CharField(max_length=512)
|
||||||
number = models.IntegerField()
|
number = models.IntegerField()
|
||||||
type = models.CharField(max_length=128)
|
type = models.CharField(max_length=128)
|
||||||
completed = models.BooleanField(default=False)
|
completed = models.BooleanField(default=False)
|
||||||
data_bool = 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, null=True, blank=True)
|
||||||
data_date = models.DateField(default=datetime.date.today)
|
data_date = models.DateField(default=datetime.date.today)
|
||||||
data_file = models.FileField(upload_to='uploads/%Y/%m/%d/', max_length=512, 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)
|
data_string = models.TextField(default='', blank=True)
|
||||||
|
|
|
@ -1,10 +1,36 @@
|
||||||
# simple_policy.py
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from policy import Policy, Section
|
|
||||||
|
|
||||||
# - For the rules, should one refer to fields by 'section.fields.x'
|
#### Classes for policy, sections.
|
||||||
# or by the section name eg. 'general_section.fields.x'?
|
|
||||||
|
|
||||||
|
class Policy():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.sections = []
|
||||||
|
|
||||||
|
def add_section(self, section):
|
||||||
|
self.sections.append(section)
|
||||||
|
|
||||||
|
class Section():
|
||||||
|
|
||||||
|
def __init__(self, title="Section", html_description="", required=False, auto_submit=False, fields={}):
|
||||||
|
self.title = title
|
||||||
|
self.html_description = html_description
|
||||||
|
self.required = required
|
||||||
|
self.auto_submit = auto_submit
|
||||||
|
self.fields = fields
|
||||||
|
self.rules = []
|
||||||
|
|
||||||
|
def add_rule(self, title="Rule", rule=None, rule_break_text=""):
|
||||||
|
rule = {
|
||||||
|
"title": title,
|
||||||
|
"rule": rule,
|
||||||
|
"rule_break_text": rule_break_text,
|
||||||
|
}
|
||||||
|
self.rules.append(rule)
|
||||||
|
|
||||||
|
#### Policy configuration begin here
|
||||||
|
|
||||||
|
pol = Policy()
|
||||||
|
|
||||||
#### General
|
#### General
|
||||||
#### Section 0
|
#### Section 0
|
||||||
|
@ -12,7 +38,7 @@ general_section = Section(
|
||||||
title="General Info",
|
title="General Info",
|
||||||
html_description="",
|
html_description="",
|
||||||
fields={
|
fields={
|
||||||
"destination": {"label": "Destination City", "type": "string"}
|
"destination": {"label": "Destination City", "type": "string"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,7 +48,7 @@ general_section.add_rule(
|
||||||
rule_break_text="What did the cowboy say about Tim, his wild horse?"
|
rule_break_text="What did the cowboy say about Tim, his wild horse?"
|
||||||
)
|
)
|
||||||
|
|
||||||
Policy.add_section(general_section)
|
pol.add_section(general_section)
|
||||||
|
|
||||||
#### Flight
|
#### Flight
|
||||||
#### Section 1
|
#### Section 1
|
||||||
|
@ -43,7 +69,7 @@ flight_section.add_rule(
|
||||||
rule_break_text="Fares cannot be more than $500"
|
rule_break_text="Fares cannot be more than $500"
|
||||||
)
|
)
|
||||||
|
|
||||||
Policy.add_section(flight_section)
|
pol.add_section(flight_section)
|
||||||
|
|
||||||
#### Lodging
|
#### Lodging
|
||||||
#### Section 2
|
#### Section 2
|
||||||
|
@ -64,13 +90,13 @@ def nightly_rate_check(report, section):
|
||||||
duration = checkout_date - checkin_date
|
duration = checkout_date - checkin_date
|
||||||
return section.fields.cost <= duration * section.fields.rate
|
return section.fields.cost <= duration * section.fields.rate
|
||||||
|
|
||||||
section.add_rule(
|
lodging_section.add_rule(
|
||||||
title="",
|
title="",
|
||||||
rule=nightly_rate_check,
|
rule=nightly_rate_check,
|
||||||
rule_break_text="The average nightly rate cannot be more than the USGSA rate."
|
rule_break_text="The average nightly rate cannot be more than the USGSA rate."
|
||||||
)
|
)
|
||||||
|
|
||||||
Policy.add_section(lodging_section)
|
pol.add_section(lodging_section)
|
||||||
|
|
||||||
#### Local Transportation
|
#### Local Transportation
|
||||||
#### Section 3
|
#### Section 3
|
||||||
|
@ -89,7 +115,7 @@ transport_section.add_rule(
|
||||||
rule_break_text="Local transportation costs must be less than $10 per day, on average."
|
rule_break_text="Local transportation costs must be less than $10 per day, on average."
|
||||||
)
|
)
|
||||||
|
|
||||||
Policy.add_section(transport_section)
|
pol.add_section(transport_section)
|
||||||
|
|
||||||
#### Per Diem
|
#### Per Diem
|
||||||
#### Section 4
|
#### Section 4
|
||||||
|
@ -109,24 +135,4 @@ per_diem_section.add_rule(
|
||||||
rule_break_text="The average cost per day for per diem expenses cannot be more than the rate specified by the USGSA."
|
rule_break_text="The average cost per day for per diem expenses cannot be more than the rate specified by the USGSA."
|
||||||
)
|
)
|
||||||
|
|
||||||
Policy.add_section(per_diem_section)
|
pol.add_section(per_diem_section)
|
||||||
|
|
||||||
'''
|
|
||||||
Section(
|
|
||||||
title="",
|
|
||||||
html_description="<p></p>",
|
|
||||||
fields={
|
|
||||||
"": {"label": "", "type": ""}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
section.add_rule(
|
|
||||||
title="",
|
|
||||||
rule=lambda report, section: boolean_statement,
|
|
||||||
rule_break_text=""
|
|
||||||
)
|
|
||||||
|
|
||||||
#// or, for a rule which doesn’t apply to a specific section...
|
|
||||||
#//
|
|
||||||
#// add_general_rule(...)
|
|
||||||
'''
|
|
||||||
|
|
3
back/backend/test.py
Normal file
3
back/backend/test.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from policy import pol
|
||||||
|
|
||||||
|
print(pol)
|
|
@ -1,7 +1,8 @@
|
||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from .models import *
|
from .models import *
|
||||||
|
from .policy import pol
|
||||||
|
import json
|
||||||
|
|
||||||
# function that prints all the reports
|
# function that prints all the reports
|
||||||
def get_reports(report_pk):
|
def get_reports(report_pk):
|
||||||
|
@ -47,15 +48,14 @@ def get_sections(r_id):
|
||||||
def get_fields(s_id):
|
def get_fields(s_id):
|
||||||
# create dict of arrays for fields
|
# create dict of arrays for fields
|
||||||
field_set = {"fields": []}
|
field_set = {"fields": []}
|
||||||
queryset = Field.objects.filter(section_id=s_id)
|
queryset = Field.objects.filter(section_id=s_id).order_by('number')
|
||||||
# queryset = Field.objects.all()
|
|
||||||
for i in queryset:
|
for i in queryset:
|
||||||
data = {
|
data = {
|
||||||
"field_name": "TODO",
|
"field_name": i.field_name,
|
||||||
"label": i.label,
|
"label": i.label,
|
||||||
"type": i.type,
|
"type": i.type,
|
||||||
"number": i.number,
|
"number": i.number,
|
||||||
"value": "get_value",
|
"value": "i.to_json()",
|
||||||
}
|
}
|
||||||
# append the fields to array
|
# append the fields to array
|
||||||
# use copy() to avoid overwriting
|
# use copy() to avoid overwriting
|
||||||
|
@ -70,73 +70,34 @@ def report(request):
|
||||||
'''
|
'''
|
||||||
Generate a new empty report and return it
|
Generate a new empty report and return it
|
||||||
'''
|
'''
|
||||||
data = {
|
|
||||||
"title": "2018 Portland trip",
|
# Create the report
|
||||||
"date_created": "2018-05-22T14:56:28.000Z",
|
report = Report.objects.create(user_id=request.user, title=request.data['title'], date_created=datetime.date.today())
|
||||||
"submitted": False,
|
report.save()
|
||||||
"date_submitted": "0000-00-00T00:00:00.000Z",
|
|
||||||
"sections": [
|
# Create the sections
|
||||||
{
|
for i in range(len(pol.sections)):
|
||||||
"id": 1,
|
section = pol.sections[i]
|
||||||
"completed": True,
|
s = Section.objects.create(report_id=report, auto_submit=section.auto_submit, required=section.required, completed=False, title=section.title, html_description=section.html_description, number=i)
|
||||||
"title": "Flight Info",
|
s.save()
|
||||||
"html_description": "<p>Enter flight details here.</p>",
|
|
||||||
"fields": {
|
# Create the fields
|
||||||
"international": {
|
j = 0
|
||||||
"label": "International flight",
|
for key in section.fields:
|
||||||
"type": "boolean",
|
field = section.fields[key]
|
||||||
"value": True
|
f = Field.objects.create(section_id=s, field_name=key, label=field['label'], number=j, type=field['type'], completed=False)
|
||||||
},
|
f.save()
|
||||||
"travel_date": {
|
j = j+1
|
||||||
"label": "Travel start date",
|
|
||||||
"type": "date",
|
# Return the newly created report
|
||||||
"value": "2016-05-22T14:56:28.000Z"
|
data = get_reports(report.id)
|
||||||
},
|
|
||||||
"fare": {
|
|
||||||
"label": "Fare",
|
|
||||||
"type": "decimal",
|
|
||||||
"value": "1024.99"
|
|
||||||
},
|
|
||||||
"lowest_fare_screenshot": {
|
|
||||||
"label": "Lowest fare screenshot",
|
|
||||||
"type": "file",
|
|
||||||
"value": "e92h842jiu49f8..."
|
|
||||||
},
|
|
||||||
"plane_ticket_invoice": {
|
|
||||||
"label": "Plane ticket invoice PDF",
|
|
||||||
"type": "file",
|
|
||||||
"value": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rule_violations": [
|
|
||||||
{
|
|
||||||
"error_text": "Plane ticket invoice must be submitted."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"completed": False,
|
|
||||||
"title": "Hotel info",
|
|
||||||
"html_description": "<p>If you used a hotel, please enter the details.</p>",
|
|
||||||
"fields": {
|
|
||||||
"total": {
|
|
||||||
"label": "Total cost",
|
|
||||||
"type": "decimal"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rule_violations": [
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
# List of reports
|
# List of reports
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def reports(request):
|
def reports(request):
|
||||||
report_set = {"reports": []}
|
report_set = {"reports": []}
|
||||||
queryset = Report.objects.all()
|
queryset = Report.objects.all().order_by('date_created')
|
||||||
for i in queryset:
|
for i in queryset:
|
||||||
data = {
|
data = {
|
||||||
"report_pk": i.id,
|
"report_pk": i.id,
|
||||||
|
|
BIN
back/db.sqlite3
BIN
back/db.sqlite3
Binary file not shown.
Loading…
Reference in a new issue