Merge pull request #1106 from dod-ccpo/clin-errors-contract-dates
PoP Range error message
This commit is contained in:
commit
bb6d656def
@ -38,6 +38,22 @@ def validate_funding(form, field):
|
||||
)
|
||||
|
||||
|
||||
def validate_date_in_range(form, field):
|
||||
contract_start = app.config.get("CONTRACT_START_DATE")
|
||||
contract_end = app.config.get("CONTRACT_END_DATE")
|
||||
|
||||
if field.data and (field.data < contract_start or field.data > contract_end):
|
||||
raise ValidationError(
|
||||
translate(
|
||||
"forms.task_order.pop_errors.range",
|
||||
{
|
||||
"start": contract_start.strftime("%b %d, %Y"),
|
||||
"end": contract_end.strftime("%b %d, %Y"),
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class CLINForm(FlaskForm):
|
||||
jedi_clin_type = SelectField(
|
||||
translate("task_orders.form.clin_type_label"),
|
||||
@ -52,13 +68,13 @@ class CLINForm(FlaskForm):
|
||||
translate("task_orders.form.pop_start"),
|
||||
description=translate("task_orders.form.pop_example"),
|
||||
format="%m/%d/%Y",
|
||||
validators=[Optional()],
|
||||
validators=[validate_date_in_range],
|
||||
)
|
||||
end_date = DateField(
|
||||
translate("task_orders.form.pop_end"),
|
||||
description=translate("task_orders.form.pop_example"),
|
||||
format="%m/%d/%Y",
|
||||
validators=[Optional()],
|
||||
validators=[validate_date_in_range],
|
||||
)
|
||||
total_amount = DecimalField(
|
||||
label=translate("task_orders.form.total_funds_label"),
|
||||
@ -84,8 +100,6 @@ class CLINForm(FlaskForm):
|
||||
|
||||
def validate(self, *args, **kwargs):
|
||||
valid = super().validate(*args, **kwargs)
|
||||
contract_start = app.config.get("CONTRACT_START_DATE")
|
||||
contract_end = app.config.get("CONTRACT_END_DATE")
|
||||
|
||||
if (
|
||||
self.start_date.data
|
||||
@ -97,24 +111,6 @@ class CLINForm(FlaskForm):
|
||||
)
|
||||
valid = False
|
||||
|
||||
if self.start_date.data and self.start_date.data <= contract_start:
|
||||
self.start_date.errors.append(
|
||||
translate(
|
||||
"forms.task_order.pop_errors.start",
|
||||
{"date": contract_start.strftime("%b %d, %Y")},
|
||||
)
|
||||
)
|
||||
valid = False
|
||||
|
||||
if self.end_date.data and self.end_date.data >= contract_end:
|
||||
self.end_date.errors.append(
|
||||
translate(
|
||||
"forms.task_order.pop_errors.end",
|
||||
{"date": contract_end.strftime("%b %d, %Y")},
|
||||
)
|
||||
)
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
|
@ -250,4 +250,33 @@ describe('DateSelector', () => {
|
||||
expect(component.maxError).toEqual(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('outsideRange', () => {
|
||||
it('should return true if the date is before the minrange', () => {
|
||||
component.minrange = '2020-01-01'
|
||||
component.maxrange = '2025-01-01'
|
||||
component.day = 1
|
||||
component.month = 1
|
||||
component.year = 2005
|
||||
expect(component.outsideRange).toEqual(true)
|
||||
})
|
||||
|
||||
it('should return true if the date is after the maxrange', () => {
|
||||
component.minrange = '2020-01-01'
|
||||
component.maxrange = '2025-01-01'
|
||||
component.day = 1
|
||||
component.month = 1
|
||||
component.year = 2030
|
||||
expect(component.outsideRange).toEqual(true)
|
||||
})
|
||||
|
||||
it('should return false if the date is betwen minrange and maxrange', () => {
|
||||
component.minrange = '2020-01-01'
|
||||
component.maxrange = '2025-01-01'
|
||||
component.day = 1
|
||||
component.month = 1
|
||||
component.year = 2022
|
||||
expect(component.outsideRange).toEqual(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -19,6 +19,8 @@ export default {
|
||||
initialyear: { type: String },
|
||||
mindate: { type: String },
|
||||
maxdate: { type: String },
|
||||
minrange: { type: String },
|
||||
maxrange: { type: String },
|
||||
nameTag: { type: String },
|
||||
optional: {
|
||||
type: Boolean,
|
||||
@ -179,6 +181,15 @@ export default {
|
||||
return false
|
||||
},
|
||||
|
||||
outsideRange: function() {
|
||||
if (!!this.maxrange && !!this.minrange && this.isDateComplete) {
|
||||
return (
|
||||
this.dateParsed < this.minRangeParsed ||
|
||||
this.dateParsed > this.maxRangeParsed
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
maxDateParsed: function() {
|
||||
return new Date(this.maxdate)
|
||||
},
|
||||
@ -187,6 +198,14 @@ export default {
|
||||
return new Date(this.mindate)
|
||||
},
|
||||
|
||||
maxRangeParsed: function() {
|
||||
return new Date(this.maxrange)
|
||||
},
|
||||
|
||||
minRangeParsed: function() {
|
||||
return new Date(this.minrange)
|
||||
},
|
||||
|
||||
dateParsed: function() {
|
||||
return new Date(this.formattedDate)
|
||||
},
|
||||
|
@ -332,6 +332,8 @@
|
||||
<date-selector
|
||||
:mindate="initialMinStartDate"
|
||||
:maxdate="maxStartProp"
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
|
||||
name-tag='start_date'
|
||||
initialmonth=""
|
||||
@ -352,10 +354,13 @@
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
<div v-if='outsideRange && !minError' class="usa-input-error-message">
|
||||
PoP start date must be before or on September 14, 2022.
|
||||
</div>
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
PoP start date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
<div v-if='maxError && !outsideRange' class="usa-input-error-message">
|
||||
PoP start date must be before end date.
|
||||
</div>
|
||||
</legend>
|
||||
@ -431,6 +436,8 @@
|
||||
<date-selector
|
||||
:mindate="minEndProp"
|
||||
:maxdate="initialMaxEndDate"
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
|
||||
name-tag='end_date'
|
||||
initialmonth=""
|
||||
@ -473,11 +480,14 @@
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
<div v-if='outsideRange && !maxError' class="usa-input-error-message">
|
||||
PoP end date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div v-if='minError && !outsideRange' class="usa-input-error-message">
|
||||
PoP end date must be after start date.
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
PoP end date must be on or after September 14, 2022.
|
||||
PoP end date must be before or on September 14, 2022.
|
||||
</div>
|
||||
</legend>
|
||||
|
||||
|
@ -2,15 +2,15 @@
|
||||
<pop-date-range
|
||||
initial-min-start-date="2019-09-14"
|
||||
initial-max-end-date="2022-09-14"
|
||||
|
||||
|
||||
v-bind:clin-index="1"
|
||||
|
||||
|
||||
|
||||
|
||||
initial-start-date="None"
|
||||
|
||||
|
||||
|
||||
|
||||
initial-end-date="None"
|
||||
|
||||
|
||||
inline-template>
|
||||
|
||||
<div>
|
||||
@ -19,12 +19,14 @@
|
||||
<date-selector
|
||||
:mindate="initialMinStartDate"
|
||||
:maxdate="maxStartProp"
|
||||
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
|
||||
name-tag='start_date'
|
||||
initialmonth=""
|
||||
initialday=""
|
||||
initialyear=""
|
||||
|
||||
|
||||
:optional='true'
|
||||
v-on:date-change='handleDateChange'
|
||||
inline-template>
|
||||
@ -39,10 +41,14 @@
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
<div v-if='outsideRange && !minError' class="usa-input-error-message">
|
||||
{{ ""}}
|
||||
PoP start date must be before or on September 14, 2022.
|
||||
</div>
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
PoP start date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
<div v-if='maxError && !outsideRange' class="usa-input-error-message">
|
||||
PoP start date must be before end date.
|
||||
</div>
|
||||
</legend>
|
||||
@ -94,17 +100,17 @@
|
||||
|
||||
<div v-if="isDateComplete">
|
||||
<div class="usa-form-group-date-ok" v-if="isDateValid">
|
||||
|
||||
|
||||
<span class="icon icon--ok icon--green" aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="usa-form-group-date-ok" v-else>
|
||||
|
||||
|
||||
<span class="icon icon--alert icon--red" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -118,12 +124,14 @@
|
||||
<date-selector
|
||||
:mindate="minEndProp"
|
||||
:maxdate="initialMaxEndDate"
|
||||
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
|
||||
name-tag='end_date'
|
||||
initialmonth=""
|
||||
initialday=""
|
||||
initialyear=""
|
||||
|
||||
|
||||
:optional='true'
|
||||
v-on:date-change='handleDateChange'
|
||||
inline-template>
|
||||
@ -133,26 +141,26 @@
|
||||
<div class="usa-input__title">
|
||||
End Date
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class='usa-alert usa-alert-info' role='alert' aria-live='polite'>
|
||||
|
||||
<div class='usa-alert-body'>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class='usa-alert-text'>
|
||||
A CLIN's period of performance must end before September 14, 2022.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -160,11 +168,14 @@
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
<div v-if='outsideRange && !maxError' class="usa-input-error-message">
|
||||
PoP end date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div v-if='minError && !outsideRange' class="usa-input-error-message">
|
||||
PoP end date must be after start date.
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
PoP end date must be on or after September 14, 2022.
|
||||
PoP end date must be before or on September 14, 2022.
|
||||
</div>
|
||||
</legend>
|
||||
|
||||
@ -212,17 +223,17 @@
|
||||
|
||||
<div v-if="isDateComplete">
|
||||
<div class="usa-form-group-date-ok" v-if="isDateValid">
|
||||
|
||||
|
||||
<span class="icon icon--ok icon--green" aria-hidden="true"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="svg-inline--fa fa-check-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path></svg></span>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="usa-form-group-date-ok" v-else>
|
||||
|
||||
|
||||
<span class="icon icon--alert icon--red" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#fdb81e">
|
||||
<path d="M8 16c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zM8 2C4.691 2 2 4.691 2 8s2.691 6 6 6 6-2.691 6-6-2.691-6-6-6zm0 8c-.552 0-1-.447-1-1V4c0-.552.448-1 1-1s1 .448 1 1v5c0 .553-.448 1-1 1zm0 3c-.26 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.271.11-.521.29-.71.38-.37 1.05-.37 1.42 0 .18.189.29.45.29.71s-.11.52-.29.71c-.19.18-.45.29-.71.29z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -203,7 +203,7 @@
|
||||
<div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<date-selector :maxdate="maxStartProp" :mindate="initialMinStartDate" :name-tag="'clins-' + clinIndex + '-start_date'" :optional="false" inline-template="" v-on:date-change="handleDateChange">
|
||||
<date-selector :maxdate="maxStartProp" :maxrange="initialMaxEndDate" :mindate="initialMinStartDate" :minrange="initialMinStartDate" :name-tag="'clins-' + clinIndex + '-start_date'" :optional="false" inline-template="" v-on:date-change="handleDateChange">
|
||||
<fieldset :name="name" class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid && isDateComplete, 'usa-input--error': !isDateValid && isDateComplete }">
|
||||
<legend>
|
||||
<div class="usa-input__title">
|
||||
@ -212,10 +212,13 @@
|
||||
<p class="usa-input__help">
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
<div class="usa-input-error-message" v-if="outsideRange && !minError">
|
||||
PoP start date must be before or on September 14, 2022.
|
||||
</div>
|
||||
<div class="usa-input-error-message" v-if="minError">
|
||||
PoP start date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div class="usa-input-error-message" v-if="maxError">
|
||||
<div class="usa-input-error-message" v-if="maxError && !outsideRange">
|
||||
PoP start date must be before end date.
|
||||
</div>
|
||||
</legend>
|
||||
@ -251,7 +254,7 @@
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<date-selector :maxdate="initialMaxEndDate" :mindate="minEndProp" :name-tag="'clins-' + clinIndex + '-end_date'" :optional="false" inline-template="" v-on:date-change="handleDateChange">
|
||||
<date-selector :maxdate="initialMaxEndDate" :maxrange="initialMaxEndDate" :mindate="minEndProp" :minrange="initialMinStartDate" :name-tag="'clins-' + clinIndex + '-end_date'" :optional="false" inline-template="" v-on:date-change="handleDateChange">
|
||||
<fieldset :name="name" class="usa-input date-picker" v-bind:class="{ 'usa-input--success': isDateValid && isDateComplete, 'usa-input--error': !isDateValid && isDateComplete }">
|
||||
<legend>
|
||||
<div class="usa-input__title">
|
||||
@ -267,11 +270,14 @@
|
||||
<p class="usa-input__help">
|
||||
For example: 07 04 1776
|
||||
</p>
|
||||
<div class="usa-input-error-message" v-if="minError">
|
||||
<div class="usa-input-error-message" v-if="outsideRange && !maxError">
|
||||
PoP end date must be on or after September 14, 2019.
|
||||
</div>
|
||||
<div class="usa-input-error-message" v-if="minError && !outsideRange">
|
||||
PoP end date must be after start date.
|
||||
</div>
|
||||
<div class="usa-input-error-message" v-if="maxError">
|
||||
PoP end date must be on or after September 14, 2022.
|
||||
PoP end date must be before or on September 14, 2022.
|
||||
</div>
|
||||
</legend>
|
||||
<div class="date-picker-component">
|
||||
|
@ -2,6 +2,8 @@
|
||||
{% from 'components/icon.html' import Icon %}
|
||||
|
||||
{% macro PopDateRange(start_field=None, end_field=None, mindate=mindate, maxdate=maxdate, optional=True, index=None) %}
|
||||
{% set formatted_end = maxdate | formattedDate(formatter="%B %d, %Y") %}
|
||||
{% set formatted_start = mindate | formattedDate(formatter="%B %d, %Y") %}
|
||||
<pop-date-range
|
||||
initial-min-start-date="{{ mindate }}"
|
||||
initial-max-end-date="{{ maxdate }}"
|
||||
@ -24,6 +26,8 @@
|
||||
<date-selector
|
||||
:mindate="initialMinStartDate"
|
||||
:maxdate="maxStartProp"
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
{% if start_field %}
|
||||
name-tag='{{ start_field.name }}'
|
||||
initialmonth="{{ start_field.data.month }}"
|
||||
@ -46,11 +50,14 @@
|
||||
{{ "task_orders.form.pop_example" | translate | safe }}
|
||||
</p>
|
||||
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
PoP start date must be on or after {{ mindate | formattedDate(formatter="%B %d, %Y") }}.
|
||||
<div v-if='outsideRange && !minError' class="usa-input-error-message">
|
||||
{{ "forms.task_order.pop_errors.start_past_contract" | translate({"date": formatted_end}) }}
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
PoP start date must be before end date.
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
{{ "forms.task_order.pop_errors.start_pre_contract" | translate({"date": formatted_start}) }}
|
||||
</div>
|
||||
<div v-if='maxError && !outsideRange' class="usa-input-error-message">
|
||||
{{ "forms.task_order.pop_errors.date_order" | translate }}
|
||||
</div>
|
||||
</legend>
|
||||
|
||||
@ -118,6 +125,8 @@
|
||||
<date-selector
|
||||
:mindate="minEndProp"
|
||||
:maxdate="initialMaxEndDate"
|
||||
:minrange='initialMinStartDate'
|
||||
:maxrange='initialMaxEndDate'
|
||||
{% if end_field %}
|
||||
name-tag='{{ end_field.name }}'
|
||||
initialmonth="{{ end_field.data.month }}"
|
||||
@ -135,18 +144,20 @@
|
||||
<div class="usa-input__title">
|
||||
{{ 'task_orders.form.pop_end' | translate }}
|
||||
</div>
|
||||
{% set formatted_end_date = maxdate | formattedDate(formatter="%B %d, %Y") %}
|
||||
{{ Alert(message="task_orders.form.pop_end_alert" | translate({'end_date': formatted_end_date })) }}
|
||||
{{ Alert(message="task_orders.form.pop_end_alert" | translate({'end_date': formatted_end })) }}
|
||||
|
||||
<p class='usa-input__help'>
|
||||
{{ 'task_orders.form.pop_example' | translate }}
|
||||
</p>
|
||||
|
||||
<div v-if='minError' class="usa-input-error-message">
|
||||
PoP end date must be after start date.
|
||||
<div v-if='outsideRange && !maxError' class="usa-input-error-message">
|
||||
{{ "forms.task_order.pop_errors.end_pre_contract" | translate({"date": formatted_start}) }}
|
||||
</div>
|
||||
<div v-if='minError && !outsideRange' class="usa-input-error-message">
|
||||
{{ "forms.task_order.pop_errors.date_order" | translate }}
|
||||
</div>
|
||||
<div v-if='maxError' class="usa-input-error-message">
|
||||
PoP end date must be on or after {{ formatted_end_date }}.
|
||||
{{ "forms.task_order.pop_errors.end_past_contract" | translate({"date": formatted_end}) }}
|
||||
</div>
|
||||
</legend>
|
||||
|
||||
|
@ -47,17 +47,24 @@ def test_clin_form_pop_dates_within_contract_dates():
|
||||
start_date=invalid_start, end_date=invalid_end
|
||||
)
|
||||
clin_form = CLINForm(obj=invalid_clin)
|
||||
|
||||
assert not clin_form.validate()
|
||||
assert (
|
||||
translate(
|
||||
"forms.task_order.pop_errors.start",
|
||||
{"date": CONTRACT_START_DATE.strftime("%b %d, %Y")},
|
||||
"forms.task_order.pop_errors.range",
|
||||
{
|
||||
"start": CONTRACT_START_DATE.strftime("%b %d, %Y"),
|
||||
"end": CONTRACT_END_DATE.strftime("%b %d, %Y"),
|
||||
},
|
||||
)
|
||||
) in clin_form.start_date.errors
|
||||
assert (
|
||||
translate(
|
||||
"forms.task_order.pop_errors.end",
|
||||
{"date": CONTRACT_END_DATE.strftime("%b %d, %Y")},
|
||||
"forms.task_order.pop_errors.range",
|
||||
{
|
||||
"start": CONTRACT_START_DATE.strftime("%b %d, %Y"),
|
||||
"end": CONTRACT_END_DATE.strftime("%b %d, %Y"),
|
||||
},
|
||||
)
|
||||
) in clin_form.end_date.errors
|
||||
|
||||
|
@ -211,8 +211,11 @@ forms:
|
||||
number_description: Task order number (13 digits)
|
||||
pop_errors:
|
||||
date_order: PoP start date must be before end date.
|
||||
end: PoP end date must be before or on {date}.
|
||||
start: PoP start date must be on or after {date}.
|
||||
range: Date must be between {start} and {end}.
|
||||
end_past_contract: PoP end date must be before or on {date}.
|
||||
end_pre_contract: PoP end date must be after or on {date}.
|
||||
start_past_contract: PoP start date must be before or on {date}.
|
||||
start_pre_contract: PoP start date must be on or after {date}.
|
||||
scope_description: 'What do you plan to do on the cloud? Some examples might include migrating an existing application or creating a prototype. You don’t need to include a detailed plan of execution, but should list key requirements. This section will be reviewed by your contracting officer, but won’t be sent to the CCPO. <p>Not sure how to describe your scope? <a href="#">Read some examples</a> to get some inspiration.</p>'
|
||||
scope_label: Cloud project scope
|
||||
clin_funding_errors:
|
||||
|
Loading…
x
Reference in New Issue
Block a user