Merge pull request #560 from dod-ccpo/ko-dod-id-toggle

Toggle DOD ID Input For Officers
This commit is contained in:
montana-mil 2019-01-21 14:03:45 -05:00 committed by GitHub
commit 4afafe7217
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 70 deletions

View File

@ -10,9 +10,9 @@ from wtforms.fields import (
)
from wtforms.fields.html5 import DateField, TelField
from wtforms.widgets import ListWidget, CheckboxInput
from wtforms.validators import Required, Length
from wtforms.validators import Length
from atst.forms.validators import IsNumber, PhoneNumber, RequiredIfNot
from atst.forms.validators import IsNumber, PhoneNumber, RequiredIf
from .forms import CacheableForm
from .data import (
@ -117,7 +117,11 @@ class OversightForm(CacheableForm):
)
ko_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"),
validators=[Required(), Length(min=10), IsNumber()],
validators=[
RequiredIf(lambda form: form._fields.get("ko_invite").data),
Length(min=10),
IsNumber(),
],
)
am_cor = BooleanField(translate("forms.task_order.oversight_am_cor_label"))
@ -128,11 +132,21 @@ class OversightForm(CacheableForm):
cor_email = StringField(translate("forms.task_order.oversight_email_label"))
cor_phone_number = TelField(
translate("forms.task_order.oversight_phone_label"),
validators=[RequiredIfNot("am_cor"), PhoneNumber()],
validators=[
RequiredIf(lambda form: not form._fields.get("am_cor").data),
PhoneNumber(),
],
)
cor_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"),
validators=[RequiredIfNot("am_cor"), Length(min=10), IsNumber()],
validators=[
RequiredIf(
lambda form: not form._fields.get("am_cor").data
and form._fields.get("cor_invite").data
),
Length(min=10),
IsNumber(),
],
)
so_first_name = StringField(
@ -145,7 +159,11 @@ class OversightForm(CacheableForm):
)
so_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"),
validators=[Required(), Length(min=10), IsNumber()],
validators=[
RequiredIf(lambda form: form._fields.get("so_invite").data),
Length(min=10),
IsNumber(),
],
)
ko_invite = BooleanField(

View File

@ -80,26 +80,22 @@ def ListItemsUnique(message=translate("forms.validators.list_items_unique_messag
return _list_items_unique
def RequiredIfNot(other_field_name, message=translate("forms.validators.is_required")):
def RequiredIf(criteria_function, message=translate("forms.validators.is_required")):
""" A validator which makes a field required only if another field
has a falsy value
has a truthy value
Args:
other_field_name (str): the name of the field we check before
determining if this field is required; if this other field is falsy,
the field will be required
criteria_function (function): calling this function on form results
in a boolean value that we want to check against;
if it's True, we require the field
message (str): an optional message to display if the field is
required but hasNone value
"""
def _required_if_not(form, field):
other_field = form._fields.get(other_field_name)
if other_field is None:
raise Exception('no field named "%s" in form' % self.other_field_name)
if not bool(other_field.data):
def _required_if(form, field):
if criteria_function(form):
if field.data is None:
raise ValidationError(message)
else:
raise StopValidation()
return _required_if_not
return _required_if

View File

@ -81,6 +81,12 @@ class ShowTaskOrderWorkflow:
elif self._section["section"] == "oversight":
if self.user.dod_id == self.task_order.cor_dod_id:
self._form.am_cor.data = True
if self.task_order.contracting_officer:
self._form.ko_invite.data = True
if self.task_order.contracting_officer_representative:
self._form.cor_invite.data = True
if self.task_order.security_officer:
self._form.so_invite.data = True
else:
self._form = self._section[form_type]()

View File

@ -3,7 +3,7 @@ import textinput from '../text_input'
import checkboxinput from '../checkbox_input'
export default {
name: 'cor',
name: 'oversight',
mixins: [FormMixin],
@ -21,11 +21,17 @@ export default {
data: function () {
const {
am_cor = false
am_cor = false,
ko_invite = false,
cor_invite = false,
so_invite = false,
} = this.initialData
return {
am_cor
am_cor,
ko_invite,
cor_invite,
so_invite,
}
}
}

View File

@ -11,7 +11,7 @@ import textinput from './components/text_input'
import checkboxinput from './components/checkbox_input'
import DetailsOfUse from './components/forms/details_of_use'
import poc from './components/forms/poc'
import cor from './components/forms/cor'
import oversight from './components/forms/oversight'
import financial from './components/forms/financial'
import toggler from './components/toggler'
import NewApplication from './components/forms/new_application'
@ -45,7 +45,7 @@ const app = new Vue({
checkboxinput,
DetailsOfUse,
poc,
cor,
oversight,
financial,
NewApplication,
selector,

View File

@ -13,31 +13,37 @@
<!-- Oversight Section -->
<h3 class="subheading">{{ "task_orders.new.oversight.ko_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.ko_info_paragraph" | translate }}</p>
{{ UserInfo(form.ko_first_name, form.ko_last_name, form.ko_email, form.ko_phone_number) }}
{{ CheckboxInput(form.ko_invite) }}
{{ TextInput(form.ko_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
<hr />
<h3 class="subheading">{{ "task_orders.new.oversight.cor_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.cor_info_paragraph" | translate }}</p>
<cor inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<oversight inline-template v-bind:initial-data='{{ form.data|tojson }}'>
<div class='usa-input'>
{{ UserInfo(form.ko_first_name, form.ko_last_name, form.ko_email, form.ko_phone_number) }}
{{ CheckboxInput(form.ko_invite) }}
<template v-if="ko_invite">
{{ TextInput(form.ko_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
</template>
<hr />
<h3 class="subheading">{{ "task_orders.new.oversight.cor_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.cor_info_paragraph" | translate }}</p>
{{ CheckboxInput(form.am_cor) }}
<template v-if="!am_cor">
{{ UserInfo(form.cor_first_name, form.cor_last_name, form.cor_email, form.cor_phone_number) }}
{{ CheckboxInput(form.cor_invite) }}
{{ TextInput(form.cor_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
<template v-if="cor_invite">
{{ TextInput(form.cor_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
</template>
</template>
<hr />
<h3 class="subheading">{{ "task_orders.new.oversight.so_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.so_info_paragraph" | translate }}</p>
{{ UserInfo(form.so_first_name, form.so_last_name, form.so_email, form.so_phone_number) }}
{{ CheckboxInput(form.so_invite) }}
<template v-if="so_invite">
{{ TextInput(form.so_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
</template>
</div>
</cor>
<hr />
<h3 class="subheading">{{ "task_orders.new.oversight.so_info_title" | translate }}</h3>
<p>{{ "task_orders.new.oversight.so_info_paragraph" | translate }}</p>
{{ UserInfo(form.so_first_name, form.so_last_name, form.so_email, form.so_phone_number) }}
{{ CheckboxInput(form.so_invite) }}
{{ TextInput(form.so_dod_id, placeholder="1234567890", tooltip="Why", tooltip_title='Why', validation='dodId')}}
</oversight>
{% endblock %}

View File

@ -103,15 +103,6 @@ def dummy_form():
return DummyForm()
@pytest.fixture
def dummy_form_with_field():
def set_field(name, value):
data = DummyField(data=value, name=name)
return DummyForm(data=OrderedDict({name: data}))
return set_field
@pytest.fixture
def dummy_field():
return DummyField()

View File

@ -6,7 +6,7 @@ from atst.forms.validators import (
IsNumber,
PhoneNumber,
ListItemsUnique,
RequiredIfNot,
RequiredIf,
)
@ -81,30 +81,19 @@ class TestListItemsUnique:
validator(dummy_form, dummy_field)
class TestRequiredIfNot:
def test_RequiredIfNot_requires_field_if_arg_is_falsy(
self, dummy_form_with_field, dummy_field
):
form = dummy_form_with_field("arg", False)
validator = RequiredIfNot("arg")
class TestRequiredIf:
def test_RequiredIf_requires_field_if_arg_is_truthy(self, dummy_form, dummy_field):
validator = RequiredIf(lambda form: True)
dummy_field.data = None
with pytest.raises(ValidationError):
validator(form, dummy_field)
validator(dummy_form, dummy_field)
def test_RequiredIfNot_does_not_require_field_if_arg_is_truthy(
self, dummy_form_with_field, dummy_field
def test_RequiredIf_does_not_require_field_if_arg_is_falsy(
self, dummy_form, dummy_field
):
form = dummy_form_with_field("arg", True)
validator = RequiredIfNot("arg")
validator = RequiredIf(lambda form: False)
dummy_field.data = None
with pytest.raises(StopValidation):
validator(form, dummy_field)
def test_RequiredIfNot_arg_is_None_raises_error(self, dummy_form, dummy_field):
validator = RequiredIfNot("arg")
dummy_field.data = "some data"
with pytest.raises(Exception):
validator(dummy_form, dummy_field)