diff --git a/js/components/__tests__/clin_fields.test.js b/js/components/__tests__/clin_fields.test.js
new file mode 100644
index 00000000..70a19e50
--- /dev/null
+++ b/js/components/__tests__/clin_fields.test.js
@@ -0,0 +1,48 @@
+import { mount } from '@vue/test-utils'
+
+import clinFields from '../clin_fields'
+
+import { makeTestWrapper } from '../../test_utils/component_test_helpers'
+
+const ClinFieldsWrapper = makeTestWrapper({
+ components: { clinFields },
+ templatePath: 'clin_fields.html',
+})
+
+describe('ClinFields Test', () => {
+ it('should calculate the percentage of obligated funds', () => {
+ const wrapper = mount(ClinFieldsWrapper, {
+ propsData: {
+ initialData: {},
+ },
+ })
+ const percentObligatedElement = wrapper.find('#percent-obligated')
+ // test starts at zero
+ expect(percentObligatedElement.text()).toBe('0%')
+
+ // test greater than 100%
+ wrapper.find('input#obligated_amount').setValue('2')
+ wrapper.find('input#total_amount').setValue('1')
+ expect(percentObligatedElement.text()).toBe('>100%')
+
+ // test greater than 99% but less than 100%
+ wrapper.find('input#obligated_amount').setValue('999')
+ wrapper.find('input#total_amount').setValue('1000')
+ expect(percentObligatedElement.text()).toBe('>99%')
+
+ // test a normal percentage
+ wrapper.find('input#obligated_amount').setValue('1')
+ wrapper.find('input#total_amount').setValue('2')
+ expect(percentObligatedElement.text()).toBe('50%')
+
+ // test less than 1%
+ wrapper.find('input#obligated_amount').setValue('1')
+ wrapper.find('input#total_amount').setValue('1000')
+ expect(percentObligatedElement.text()).toBe('<1%')
+
+ // test resets to zero
+ wrapper.find('input#obligated_amount').setValue('0')
+ wrapper.find('input#total_amount').setValue('0')
+ expect(percentObligatedElement.text()).toBe('0%')
+ })
+})
diff --git a/js/test_templates/clin_fields.html b/js/test_templates/clin_fields.html
new file mode 100644
index 00000000..c8e4bc0a
--- /dev/null
+++ b/js/test_templates/clin_fields.html
@@ -0,0 +1,571 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Percent Obligated
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/components/clin_fields.html b/templates/components/clin_fields.html
new file mode 100644
index 00000000..82e54a8e
--- /dev/null
+++ b/templates/components/clin_fields.html
@@ -0,0 +1,319 @@
+{% from "components/clin_dollar_amount.html" import CLINDollarAmount %}
+{% from 'components/alert.html' import Alert %}
+{% from 'components/date_picker.html' import DatePicker %}
+{% from 'components/icon.html' import Icon %}
+{% from 'components/options_input.html' import OptionsInput %}
+{% from 'components/text_input.html' import TextInput %}
+
+{% macro CLINFields(contract_start, contract_end, fields=None, index=None) %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if fields %}
+ {{ CLINDollarAmount("total", field=fields.total_amount) }}
+ {{ CLINDollarAmount("obligated", field=fields.obligated_amount, funding_validation=True) }}
+ {% else %}
+ {{ CLINDollarAmount("total") }}
+ {{ CLINDollarAmount("obligated", funding_validation=True) }}
+ {% endif %}
+
+
Percent Obligated
+
+
+
+
+ {% set contract_end_formatted = contract_end | dateFromString(formatter="%Y-%m-%d") | formattedDate(formatter="%B %d, %Y") %}
+ {% if fields %}
+
+
+ {% else %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endmacro %}
diff --git a/templates/task_orders/step_3.html b/templates/task_orders/step_3.html
index c52d3f96..aa3fff3a 100644
--- a/templates/task_orders/step_3.html
+++ b/templates/task_orders/step_3.html
@@ -1,11 +1,7 @@
{% extends "task_orders/builder_base.html" %}
-{% from 'components/alert.html' import Alert %}
-{% from 'components/date_picker.html' import DatePicker %}
{% from 'components/icon.html' import Icon %}
-{% from 'components/options_input.html' import OptionsInput %}
-{% from 'components/text_input.html' import TextInput %}
-{% from "components/clin_dollar_amount.html" import CLINDollarAmount %}
+{% from "components/clin_fields.html" import CLINFields %}
{% from 'task_orders/form_header.html' import TOFormStepHeader %}
{% set action = url_for("task_orders.submit_form_step_three_add_clins", task_order_id=task_order_id) %}
@@ -13,330 +9,17 @@
{% set previous_button_link = url_for("task_orders.form_step_two_add_number", task_order_id=task_order_id) %}
{% set step = "3" %}
-{% macro CLINFields(fields=None, index=None) %}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {% if fields %}
- {{ CLINDollarAmount("total", field=fields.total_amount) }}
- {{ CLINDollarAmount("obligated", field=fields.obligated_amount, funding_validation=True) }}
- {% else %}
- {{ CLINDollarAmount("total") }}
- {{ CLINDollarAmount("obligated", funding_validation=True) }}
- {% endif %}
-
-
Percent Obligated
-
-
-
-
- {% set contract_end_formatted = contract_end | dateFromString(formatter="%Y-%m-%d") | formattedDate(formatter="%B %d, %Y") %}
- {% if fields %}
-
-
- {% else %}
-
-
- {% endif %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{% endmacro %}
-
{% block to_builder_form_field %}
{{ TOFormStepHeader('task_orders.form.clin_title' | translate, 'task_orders.form.clin_description' | translate, task_order.number) }}
{% for clin in form.clins %}
- {{ CLINFields(clin, index=loop.index - 1) }}
+ {{ CLINFields(contract_start, contract_end, clin, index=loop.index - 1) }}
{% endfor %}
- {{ CLINFields() }}
+ {{ CLINFields(contract_start, contract_end) }}