diff --git a/atst/domain/task_orders.py b/atst/domain/task_orders.py index 235351a0..fced1a3b 100644 --- a/atst/domain/task_orders.py +++ b/atst/domain/task_orders.py @@ -1,5 +1,4 @@ from sqlalchemy.orm.exc import NoResultFound - from flask import current_app as app from atst.database import db @@ -93,21 +92,33 @@ class TaskOrders(object): return task_order @classmethod - def is_section_complete(cls, task_order, section): - if section in TaskOrders.sections(): + def section_completion_status(cls, task_order, section): + if section in TaskOrders.SECTIONS: + passed = [] + failed = [] + for attr in TaskOrders.SECTIONS[section]: - if getattr(task_order, attr) is None: - return False + if not app.config.get("CLASSIFIED") and attr in ["clin_02", "clin_04"]: + pass + elif not getattr(task_order, attr): + failed.append(attr) + else: + passed.append(attr) - return True - - else: - return False + if not failed: + return "complete" + elif passed and failed: + return "draft" + else: + return "incomplete" @classmethod def all_sections_complete(cls, task_order): for section in TaskOrders.SECTIONS.keys(): - if not TaskOrders.is_section_complete(task_order, section): + if ( + TaskOrders.section_completion_status(task_order, section) + is not "complete" + ): return False return True diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index 2075e834..516e8ce8 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -10,7 +10,7 @@ from wtforms.fields import ( ) from wtforms.fields.html5 import DateField, TelField from wtforms.widgets import ListWidget, CheckboxInput -from wtforms.validators import Length, InputRequired +from wtforms.validators import Length, Required, InputRequired, Optional from flask_wtf.file import FileAllowed from atst.forms.validators import IsNumber, PhoneNumber, RequiredIf @@ -31,6 +31,7 @@ class AppInfoForm(CacheableForm): portfolio_name = StringField( translate("forms.task_order.portfolio_name_label"), description=translate("forms.task_order.portfolio_name_description"), + validators=[Required()], ) scope = TextAreaField( translate("forms.task_order.scope_label"), @@ -100,25 +101,37 @@ class FundingForm(CacheableForm): clin_01 = DecimalField( translate("forms.task_order.clin_01_label"), validators=[ - InputRequired(message=(translate("forms.task_order.clin_validation_error"))) + Optional(), + InputRequired( + message=(translate("forms.task_order.clin_validation_error")) + ), ], ) clin_02 = DecimalField( translate("forms.task_order.clin_02_label"), validators=[ - InputRequired(message=(translate("forms.task_order.clin_validation_error"))) + Optional(), + InputRequired( + message=(translate("forms.task_order.clin_validation_error")) + ), ], ) clin_03 = DecimalField( translate("forms.task_order.clin_03_label"), validators=[ - InputRequired(message=(translate("forms.task_order.clin_validation_error"))) + Optional(), + InputRequired( + message=(translate("forms.task_order.clin_validation_error")) + ), ], ) clin_04 = DecimalField( translate("forms.task_order.clin_04_label"), validators=[ - InputRequired(message=(translate("forms.task_order.clin_validation_error"))) + Optional(), + InputRequired( + message=(translate("forms.task_order.clin_validation_error")) + ), ], ) @@ -141,7 +154,8 @@ class OversightForm(CacheableForm): ko_last_name = StringField(translate("forms.task_order.oversight_last_name_label")) ko_email = StringField(translate("forms.task_order.oversight_email_label")) ko_phone_number = TelField( - translate("forms.task_order.oversight_phone_label"), validators=[PhoneNumber()] + translate("forms.task_order.oversight_phone_label"), + validators=[Optional(), PhoneNumber()], ) ko_dod_id = StringField( translate("forms.task_order.oversight_dod_id_label"), @@ -162,6 +176,7 @@ class OversightForm(CacheableForm): translate("forms.task_order.oversight_phone_label"), validators=[ RequiredIf(lambda form: not form._fields.get("am_cor").data), + Optional(), PhoneNumber(), ], ) @@ -183,7 +198,8 @@ class OversightForm(CacheableForm): so_last_name = StringField(translate("forms.task_order.oversight_last_name_label")) so_email = StringField(translate("forms.task_order.oversight_email_label")) so_phone_number = TelField( - translate("forms.task_order.oversight_phone_label"), validators=[PhoneNumber()] + translate("forms.task_order.oversight_phone_label"), + validators=[Optional(), PhoneNumber()], ) so_dod_id = StringField( translate("forms.task_order.oversight_dod_id_label"), diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 3a860311..c8ff4e14 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -103,8 +103,9 @@ class ShowTaskOrderWorkflow: if self.task_order: for section in screen_info: - if TaskOrders.is_section_complete(self.task_order, section["section"]): - section["complete"] = True + section["completion"] = TaskOrders.section_completion_status( + self.task_order, section["section"] + ) return screen_info diff --git a/styles/components/_progress_menu.scss b/styles/components/_progress_menu.scss index 01e2de26..0da6d34e 100644 --- a/styles/components/_progress_menu.scss +++ b/styles/components/_progress_menu.scss @@ -107,6 +107,13 @@ padding: 1px 2px; } + &--draft:before { + background: $color-gold; + border: none; + font-size: $h6-font-size; + mask-image: url('#{$asset-path}/icons/alert.svg'); + } + &--incomplete:before { border: 2px solid $color-gray-light; } diff --git a/templates/task_orders/_new.html b/templates/task_orders/_new.html index b80bced9..37f1ce74 100644 --- a/templates/task_orders/_new.html +++ b/templates/task_orders/_new.html @@ -40,7 +40,6 @@