Merge pull request #928 from dod-ccpo/totals-box-wire-up

Wire Up Totals Box Functionality
This commit is contained in:
dandds 2019-06-17 12:43:36 -04:00 committed by GitHub
commit 414e5989f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 3 deletions

View File

@ -16,6 +16,7 @@ def render_task_orders_edit(portfolio_id=None, task_order_id=None, form=None):
portfolio_id = task_order.portfolio_id portfolio_id = task_order.portfolio_id
render_args["form"] = form or TaskOrderForm(**task_order.to_dictionary()) render_args["form"] = form or TaskOrderForm(**task_order.to_dictionary())
render_args["task_order_id"] = task_order_id render_args["task_order_id"] = task_order_id
render_args["task_order"] = task_order
else: else:
render_args["form"] = form or TaskOrderForm() render_args["form"] = form or TaskOrderForm()

View File

@ -1,7 +1,11 @@
import DateSelector from './date_selector' import DateSelector from './date_selector'
import { emitEvent } from '../lib/emitters'
import optionsinput from './options_input' import optionsinput from './options_input'
import textinput from './text_input' import textinput from './text_input'
const JEDI_CLIN_TYPE = 'jedi_clin_type'
const OBLIGATED_AMOUNT = 'obligated_amount'
export default { export default {
name: 'clin-fields', name: 'clin-fields',
@ -17,6 +21,11 @@ export default {
type: Number, type: Number,
default: 0, default: 0,
}, },
initialClinType: String,
initialAmount: {
type: Number,
default: 0,
},
}, },
data: function() { data: function() {
@ -27,9 +36,23 @@ export default {
clinIndex: this.initialClinIndex, clinIndex: this.initialClinIndex,
indexOffset: this.initialLoaCount, indexOffset: this.initialLoaCount,
loas: loas, loas: loas,
clinType: this.initialClinType,
amount: this.initialAmount || 0,
} }
}, },
mounted: function() {
this.$root.$on('field-change', this.handleFieldChange)
},
created: function() {
emitEvent('clin-change', this, {
id: this._uid,
clinType: this.clinType,
amount: this.initialAmount,
})
},
methods: { methods: {
addLoa: function(event) { addLoa: function(event) {
++this.loas ++this.loas
@ -38,5 +61,25 @@ export default {
loaIndex: function(index) { loaIndex: function(index) {
return index + this.indexOffset - 1 return index + this.indexOffset - 1
}, },
clinChangeEvent: function() {
emitEvent('clin-change', this, {
id: this._uid,
clinType: this.clinType,
amount: this.amount,
})
},
handleFieldChange: function(event) {
if (this._uid === event.parent_uid) {
if (event.name.includes(JEDI_CLIN_TYPE)) {
this.clinType = event.value
this.clinChangeEvent()
} else if (event.name.includes(OBLIGATED_AMOUNT)) {
this.amount = parseFloat(event.value)
this.clinChangeEvent()
}
}
},
}, },
} }

View File

@ -6,6 +6,7 @@ import FormMixin from '../../mixins/form'
import optionsinput from '../options_input' import optionsinput from '../options_input'
import SemiCollapsibleText from '../semi_collapsible_text' import SemiCollapsibleText from '../semi_collapsible_text'
import textinput from '../text_input' import textinput from '../text_input'
import TotalsBox from '../totals_box'
import uploadinput from '../upload_input' import uploadinput from '../upload_input'
export default { export default {
@ -19,11 +20,14 @@ export default {
optionsinput, optionsinput,
SemiCollapsibleText, SemiCollapsibleText,
textinput, textinput,
TotalsBox,
uploadinput, uploadinput,
}, },
props: { props: {
initialClinCount: Number, initialClinCount: Number,
initialObligated: Number,
initialTotal: Number,
}, },
data: function() { data: function() {
@ -33,14 +37,39 @@ export default {
return { return {
clins, clins,
clinIndex, clinIndex,
obligated: this.initialObligated || 0,
total: this.initialTotal || 0,
clinChildren: {},
} }
}, },
mounted: function() {
this.$root.$on('clin-change', this.calculateClinAmounts)
},
methods: { methods: {
addClin: function(event) { addClin: function(event) {
++this.clins ++this.clins
++this.clinIndex ++this.clinIndex
}, },
calculateClinAmounts: function(event) {
this.clinChildren[event.id] = {
amount: event.amount,
type: event.clinType,
}
let newTotal = 0
let newObligated = 0
Object.values(this.clinChildren).forEach(function(clin) {
newTotal += clin.amount
if (clin.type.includes('1', '3')) {
newObligated += clin.amount
}
})
this.total = newTotal
this.obligated = newObligated
},
}, },
directives: { directives: {

View File

@ -0,0 +1,20 @@
import { formatDollars } from '../lib/dollars'
export default {
name: 'totalsbox',
props: {
name: String,
obligated: Number,
contractAmount: Number,
},
computed: {
formattedObligated: function() {
return formatDollars(this.obligated)
},
formattedContractAmount: function() {
return formatDollars(this.contractAmount)
},
},
}

View File

@ -41,6 +41,7 @@ import DeleteConfirmation from './components/delete_confirmation'
import NewEnvironment from './components/forms/new_environment' import NewEnvironment from './components/forms/new_environment'
import EnvironmentRole from './components/environment_role' import EnvironmentRole from './components/environment_role'
import SemiCollapsibleText from './components/semi_collapsible_text' import SemiCollapsibleText from './components/semi_collapsible_text'
import TotalsBox from './components/totals_box'
import ToForm from './components/forms/to_form' import ToForm from './components/forms/to_form'
import ClinFields from './components/clin_fields' import ClinFields from './components/clin_fields'
@ -85,6 +86,7 @@ const app = new Vue({
NewEnvironment, NewEnvironment,
EnvironmentRole, EnvironmentRole,
SemiCollapsibleText, SemiCollapsibleText,
TotalsBox,
ToForm, ToForm,
ClinFields, ClinFields,
}, },

View File

@ -59,6 +59,8 @@
<clin-fields <clin-fields
v-bind:initial-clin-index='{{ index }}' v-bind:initial-clin-index='{{ index }}'
v-bind:initial-loa-count="{{ fields.loas.data | length }}" v-bind:initial-loa-count="{{ fields.loas.data | length }}"
v-bind:initial-clin-type="'{{ fields.jedi_clin_type.data }}'"
v-bind:initial-amount='{{ fields.obligated_amount.data }}'
inline-template> inline-template>
<div> <div>
<div class="form-row"> <div class="form-row">
@ -102,7 +104,15 @@
{% endif %} {% endif %}
<form id="new-task-order" action='{{ action }}' method="POST" autocomplete="off" enctype="multipart/form-data"> <form id="new-task-order" action='{{ action }}' method="POST" autocomplete="off" enctype="multipart/form-data">
{{ form.csrf_token }} {{ form.csrf_token }}
<to-form inline-template v-bind:initial-clin-count="{{ form.clins.data | length }}">
{% set obligated = task_order.total_obligated_funds if task_order else 0 %}
{% set total = task_order.total_contract_amount if task_order else 0 %}
<to-form
inline-template
v-bind:initial-obligated='{{ obligated }}'
v-bind:initial-total='{{ total }}'
v-bind:initial-clin-count="{{ form.clins.data | length }}">
<div> <div>
{% call StickyCTA(text="Add Funding") %} {% call StickyCTA(text="Add Funding") %}
<span class="action-group"> <span class="action-group">
@ -150,7 +160,10 @@
<div v-for="clin in clins"> <div v-for="clin in clins">
<hr v-if="clinIndex !== 0"> <hr v-if="clinIndex !== 0">
<clin-fields v-bind:initial-clin-index='clinIndex' inline-template> <clin-fields
v-bind:initial-clin-index='clinIndex'
v-bind:initial-clin-type="'JEDICLINType.JEDI_CLIN_1'"
inline-template>
<div> <div>
<div class="form-row"> <div class="form-row">
<div class="form-col form-col--two-thirds"> <div class="form-col form-col--two-thirds">
@ -205,6 +218,7 @@
</template> </template>
</div> </div>
</textinput> </textinput>
</div> </div>
</div> </div>
@ -382,8 +396,27 @@
</div> </div>
{{ UploadInput(form.pdf, watch=True) }} {{ UploadInput(form.pdf, watch=True) }}
</div> </div>
{{ TotalsBox(task_order=task_order) }}
<totals-box
inline-template
v-bind:obligated='obligated'
v-bind:contract-amount='total'
>
<div class="col totals-box">
<div class="h4">Total obligated funds</div>
<div class="h3" v-html="formattedObligated"></div>
<div>This is the funding allocated to cloud services. It may be 100% or a portion of the total task order budget.</div>
<hr>
<div class="h4">Total contract amount</div>
<div class="h3" v-html="formattedContractAmount"></div>
<div>This is the value of all funds obligated for this contract, including -- but not limited to -- funds obligated for the cloud.</div>
</div>
</totals-box>
</div> </div>
</div> </div>
</div> </div>
</to-form> </to-form>