Created
July 21, 2017 03:39
-
-
Save barek2k2/c2af7110c9f646d2e9eda690ae12e1ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Payment = React.createClass({ | |
getInitialState(){ | |
return ({ | |
clinicians: this.props.clinicians, | |
currentClinician: this.props.currentClinician, | |
unallocatedCredit: 0.0, | |
patients: [], | |
currencyTypes: [ | |
{name: 'United States Dollar', code: 'usd'}, | |
{name: 'Canadian Dollar', code: 'cad'} | |
], | |
preferredCreditCardOptions: [ | |
{name: 'Visa', label: 'Visa'}, | |
{name: 'Mastercard', label: 'Mastercard'}, | |
{name: 'AmericanExpress', label: 'American Express'}, | |
{name: 'Discover', label: 'Discover'} | |
], | |
creditCardOptions: [], | |
isNewCard: false, | |
hasStripeKey: false, | |
payment: { | |
clinician_id: this.props.currentClinician.id, | |
patient_id: null, | |
payment_type_id: null, | |
payment_date: moment($("#payment_date").val())._d, | |
amount: null, | |
payment_number: null, | |
memo: null, | |
preferred_credit_card: null, | |
stripe_card_token: null, | |
save_patient_payment_method: false, | |
patient_payment_method_id: null, | |
currency: 'usd', | |
print: false, | |
invoice_id: null, | |
payment_class_id: null, | |
payment_invoice_events: [] | |
}, | |
errors: { | |
amount: false, | |
patient_id: false, | |
payment_type_id: false, | |
payment_class_id: false, | |
patient_payment_method_id: false | |
}, | |
selectedPatient: null, | |
isCreditCard: false, | |
isPaymentNumberRequired: false, | |
useCredit: false | |
}) | |
}, | |
componentWillMount() { | |
var that = this; | |
}, | |
componentDidMount() { | |
var that = this; | |
$("select.chosen").chosen(); | |
that.loadPatients(that.state.currentClinician.id); | |
$("body").delegate("#payment_cl1inician_dropdown", "change", function () { | |
that.loadPatients($(this).val()); | |
}); | |
$('#payment_modal').on('shown.bs.modal', function(e) { | |
var target = e.relatedTarget; | |
if(target){ | |
var payment = that.state.payment; | |
var errors = that.state.errors; | |
errors.patient_id = errors.payment_type_id = errors.payment_class_id = errors.amount = false; | |
payment.patient_id = payment.payment_type_id = payment.payment_class_id = payment.amount = payment.memo = null; | |
that.setState({selectedPatient: null, isNewCard: false, payment: payment, errors: errors}, function () { | |
$("#patient_id,#payment_type_id,#payment_class_id").val("").chosen('destroy').chosen(); | |
$("#amount, #memo").val(''); | |
that.refs.unpaid_invoices.fetchUnpaidInvoices(null); | |
}) | |
} | |
}); | |
$("body").delegate("#payment_type_id", "change", function () { | |
var isCreditCard = $(this).find('option:selected').text() == 'Credit Card'; | |
var isPaymentNumberRequired = that.isPaymentNumberRequired(); | |
that.setState({isCreditCard: isCreditCard, isPaymentNumberRequired: isPaymentNumberRequired}, function () { | |
$("select.chosen, #patient_payment_method_id").chosen(); | |
}) | |
}); | |
$("body").delegate("#patient_id", "change", function () { | |
var payment = that.state.payment; | |
var errors = that.state.errors; | |
errors.amount = false; | |
payment.amount = null; | |
var json = {payment: payment, errors: errors}; | |
if($(this).val() == '') json['selectedPatient'] = null; | |
var patientId = $(this).val(); | |
that.setState(json, function () { | |
that.refs.unpaid_invoices.fetchUnpaidInvoices(patientId); | |
$("#amount").val(''); | |
$(".payment-errors").text('') | |
}); | |
if (that.hasStripeKey()) { | |
$.ajax({ | |
method: 'GET', | |
type: 'json', | |
async: true, | |
url: "/api/patient_payment_methods.json?patient_id=" + $(this).val(), | |
success: function (response) { | |
var patientPaymentMethods = response.patient_payment_methods; | |
var payment = that.state.payment; | |
patientPaymentMethods = patientPaymentMethods.concat([{id: 'new_card', name: "New Card"}]); | |
var patientPaymentMethodId = patientPaymentMethods.length == 1 ? 'new_card' : patientPaymentMethods[0].id; | |
$("#patient_payment_method_id").val(patientPaymentMethodId); | |
payment.patient_payment_method_id = patientPaymentMethodId; | |
var isNewCard = payment.patient_payment_method_id == 'new_card'; | |
that.setState({creditCardOptions: patientPaymentMethods, payment: payment, isNewCard: isNewCard}, function () { | |
$("#patient_payment_method_id").chosen('destroy').chosen(); | |
}) | |
} | |
}); | |
} | |
$("#patient_payment_method_id").chosen(); | |
}); | |
$('.date').datepicker({autoclose: true, forceParse: false}).on('changeDate', function (e) { | |
var date = moment(e.date); | |
}); | |
$("body").delegate(".form_field", "change keyup", function (e) { | |
that.handleFieldChanged(e) | |
}); | |
$("body").delegate("#patient_payment_method_id", "change", function () { | |
that.setState({isNewCard: $(this).val() == 'new_card'}) | |
}) | |
$("body").delegate("input#amount", "keyup", function (e) { | |
that.refs.unpaid_invoices.calculateUnallocatedCredit($(this)) | |
}); | |
$("body").delegate("#use_credit", "click", function (e) { | |
var payment = that.state.payment; | |
var errors = that.state.errors; | |
if($(this).is(":checked")){ | |
var paymentTypeId = $('#payment_type_id option').filter(function () { return $(this).html() == "Credit"; }).val(); | |
var paymentClassId = $('#payment_class_id option').filter(function () { return $(this).html() == "Patient Payment"; }).val(); | |
$('#payment_type_id').val(paymentTypeId).chosen('destroy').chosen().trigger("chosen:updated"); | |
$('#payment_class_id').val(paymentClassId).chosen('destroy').chosen().trigger("chosen:updated"); | |
payment.payment_type_id = paymentTypeId; | |
payment.payment_class_id = paymentClassId; | |
} | |
else{ | |
$('#payment_type_id,#payment_class_id').val('').chosen('destroy').chosen().trigger("chosen:updated"); | |
payment.payment_type_id = payment.payment_class_id = null; | |
errors.payment_type_id = errors.payment_class_id = false; | |
} | |
that.setState({payment: payment, errors: errors, useCredit: $(this).is(":checked")}) | |
}); | |
var hasStripeKey = that.hasStripeKey(); | |
var payment = that.state.payment; | |
if(hasStripeKey){ | |
payment.preferred_credit_card = null | |
} | |
else{ | |
payment.preferred_credit_card = 'Visa' | |
} | |
that.setState({hasStripeKey: hasStripeKey, payment: payment}) | |
}, | |
selectedPatientHandler(patient){ | |
var that = this; | |
that.setState({selectedPatient: patient}, function () { | |
$("#currency,#preferred_credit_card").chosen() | |
}) | |
}, | |
loadPatients(clinicianId){ | |
var that = this; | |
$.ajax({ | |
url: "/api/v2/patients?clinician_id=" + clinicianId, | |
type: 'GET', | |
success: function (response) { | |
that.setState({patients: response.patients}, function () { | |
$("#patient_id").chosen('destroy'); | |
$("#patient_id").chosen(); | |
}); | |
} | |
}); | |
}, | |
isPaymentNumberRequired(){ | |
var that = this; | |
var type = $("#payment_type_id").find('option:selected').text(); | |
return type == 'Check' || type == 'Cash' || (type == 'Credit Card' && !that.hasStripeKey()); | |
}, | |
isCreditCard(){ | |
return this.get('payment_type.name') == 'Credit Card'; | |
}, | |
hasStripeKey(){ | |
var that = this; | |
var payment_status = that.state.currentClinician.payment_status; | |
if (payment_status == 'Trial' || payment_status == 'Paid' || payment_status == 'Unpaid' || payment_status == 'Past Due') { | |
if (that.state.currentClinician.stripe_publishable_key != '') { | |
return true; | |
} else { | |
return false; | |
} | |
} else { | |
return false; | |
} | |
}, | |
handleFieldChanged(e){ | |
var that = this; | |
if (that.isMounted()) { | |
var payment = that.state.payment; | |
var field = $(e.target); | |
var value = e.target.value; | |
attrName = field.attr('name'); | |
if (field.is(':checkbox')) { | |
value = field.is(':checked') | |
} | |
var validAttributes = Object.keys(payment); | |
if (validAttributes.indexOf(attrName) > -1) { | |
payment[attrName] = value; | |
var errors = that.state.errors; | |
var errorAttributes = Object.keys(errors); | |
if (errorAttributes.indexOf(attrName) > -1) { | |
errors[attrName] = value == '' | |
} | |
that.setState({payment: payment, errors: errors}) | |
} | |
} | |
}, | |
stripeTokenHandler(token=null){ | |
var that = this; | |
if(token){ | |
var payment = that.state.payment; | |
payment.stripe_card_token = token; | |
that.setState({payment: payment}, function () { | |
that.savePayment() | |
}); | |
} | |
}, | |
preparePayment(){ | |
var that = this; | |
var errors = that.state.errors; | |
var hasError = false; | |
Object.keys(errors).forEach(function (key) { | |
var element = $("#" + key); | |
if (element.length > 0 && (element.val() == '' || element.val() == undefined)) { | |
errors[key] = true; | |
hasError = true; | |
} | |
}); | |
if (hasError) { | |
that.setState({errors: errors}) | |
return false; | |
} | |
var payment = that.state.payment; | |
var paymentInvoiceEvents = []; | |
$(".money-control").each(function () { | |
var amount = $(this).val(); | |
if (amount > 0) { | |
paymentInvoiceEvents.push({ | |
invoice_id: $(this).attr('id').replace('amount_', ''), | |
payment_id: null, | |
amount: amount, | |
id: null | |
}) | |
} | |
}); | |
payment.payment_invoice_events = paymentInvoiceEvents; | |
payment.payment_date = moment(payment.payment_date)._d; | |
if($("#patient_payment_method_id").val() == 'new_card'){ | |
that.refs.stripe_form.createStripeToken(); | |
} | |
else{ | |
payment.stripe_card_token = null; | |
payment.save_patient_payment_method = null; | |
that.savePayment(); | |
} | |
}, | |
savePayment(){ | |
var that = this; | |
var payment = that.state.payment; | |
$.ajax({ | |
type: 'POST', | |
url: "/api/v2/payments", | |
data: {payment: payment}, | |
beforeSend: function () { | |
$("img.saving_payment").show(); | |
$("#payment_modal div.modal-footer").hide(); | |
$('.payment_error_message .payment-errors').text('').show(); | |
}, | |
success: function (response) { | |
$("#payment_modal").modal('hide'); | |
$("img.saving_payment").hide(); | |
$('#payment_modal').scrollTop(0); | |
$("#calendar").fullCalendar('refetchEvents'); | |
$('#success_flash span').text('Payment for ' + that.state.selectedPatient.firstname + ' ' + that.state.selectedPatient.lastname + ' was successfully saved!').show().parent().fadeIn().delay(5000).fadeOut('slow', function(){ | |
$('#success_flash span').text(''); | |
}); | |
}, | |
error: function (xhr,status,error) { | |
var errorMessage = JSON.parse(xhr.responseText).message; | |
$('#payment_modal').scrollTop(0); | |
$('.payment_error_message .payment-errors').text("Error: "+errorMessage).show(); | |
$("img.saving_payment").hide(); | |
$("#payment_modal div.modal-footer").show() | |
} | |
}) | |
}, | |
render: function () { | |
var that = this; | |
clinicianOptions = that.state.clinicians.map(function (clinician) { | |
return (<option key={clinician.id} value={clinician.id}>{clinician.name}</option>) | |
}); | |
patientsOptions = that.state.patients.map(function (patient) { | |
return (<option key={patient.id} value={patient.id}>{patient.name}</option>) | |
}); | |
paymentTypeOptions = that.state.currentClinician.payment_types.map(function (payment_type) { | |
return (<option key={payment_type.id} value={payment_type.id}>{payment_type.name}</option>) | |
}); | |
paymentClassOptions = that.state.currentClinician.payment_classes.map(function (payment_class) { | |
return (<option key={payment_class.id} value={payment_class.id}>{payment_class.name}</option>) | |
}); | |
currencyTypes = that.state.currencyTypes.map(function (currencyType) { | |
return (<option key={currencyType.code} value={currencyType.code}>{currencyType.name}</option>) | |
}); | |
preferredCreditCardOptions = that.state.preferredCreditCardOptions.map(function (creditCardOption) { | |
return (<option key={creditCardOption.name} value={creditCardOption.name}>{creditCardOption.label}</option>) | |
}); | |
creditCardOptions = that.state.creditCardOptions.map(function (creditCardOption) { | |
return (<option key={creditCardOption.id} value={creditCardOption.id}>{creditCardOption.name}</option>) | |
}); | |
return ( | |
<div id="payment_modal" className="modal fade"> | |
<div className="modal-dialog"> | |
<div className="modal-content"> | |
<div className="modal-header"> | |
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button> | |
<h4 className="modal-title">Payment</h4> | |
</div> | |
<div className="modal-body"> | |
<form className="form-horizontal" id="payment_form" role="form"> | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Clinician</label> | |
<div className="form-main"> | |
<select name="clinician_id" defaultValue={that.state.currentClinician.id} | |
className="chosen form_field" id="payment_clinician_dropdown"> | |
<option >Select</option> | |
{clinicianOptions} | |
</select> | |
</div> | |
</div> | |
</div> | |
<div className={that.state.errors.patient_id ? "form-group has-error" : "form-group" }> | |
<div className="form-row"> | |
<label className="form-labels control-label">Patient</label> | |
<div className="form-main"> | |
<select name="patient_id" className="chosen form_field" id="patient_id"> | |
<option value="">Select</option> | |
{patientsOptions} | |
</select> | |
</div> | |
</div> | |
{that.state.errors.patient_id && | |
<div className="form-row"> | |
<div className="form-labels"></div> | |
<div className="help-block form-main">Patient is required</div> | |
</div> | |
} | |
</div> | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Payment Date</label> | |
<div className="form-main-together"> | |
<div className="date input-group"> | |
<input name="payment_date" id="payment_date" className="form-control form_field date" | |
defaultValue={moment(that.props.date).format("MM/DD/YYYY")} type="text"/> | |
<span className="input-group-addon btn"><i className="glyphicon glyphicon-calendar"></i></span> | |
</div> | |
</div> | |
</div> | |
</div> | |
{ that.state.selectedPatient && that.state.selectedPatient.credits > 0 && | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Credit</label> | |
<div className="form-main"> | |
<p className="form-control-static"> | |
{that.state.selectedPatient.credits.formatCurrency()} | |
<span style={{marginLeft: '10px'}}> | |
<input id="use_credit" className="" type="checkbox"/> | |
<label htmlFor="use_credit" style={{fontWeight: 'normal', cursor: 'pointer', marginLeft: '5px'}}> Use Credit</label> | |
</span> | |
</p> | |
</div> | |
</div> | |
</div> | |
} | |
{ that.state.selectedPatient && that.state.useCredit && | |
<div style={{marginLeft: '147px'}}> | |
To add money to the payment, choose a different payment type. | |
</div> | |
} | |
<div className={that.state.errors.payment_type_id ? "form-group has-error" : "form-group" }> | |
<div className="form-row"> | |
<label className="form-labels control-label">Payment Type</label> | |
<div className="form-main"> | |
<select name="payment_type_id" id="payment_type_id" className="chosen form_field"> | |
<option value="">Select Payment Type</option> | |
{paymentTypeOptions} | |
</select> | |
</div> | |
</div> | |
{that.state.errors.payment_type_id && | |
<div className="form-row"> | |
<div className="form-labels"></div> | |
<div className="help-block form-main">Payment type is required</div> | |
</div> | |
} | |
</div> | |
<div className={that.state.errors.payment_class_id ? "form-group has-error" : "form-group" }> | |
<div className="form-row"> | |
<label className="form-labels control-label">Payment Class</label> | |
<div className="form-main"> | |
<select name="payment_class_id" id="payment_class_id" className="chosen form_field"> | |
<option value="">Select Payment Class</option> | |
{paymentClassOptions} | |
</select> | |
</div> | |
</div> | |
{that.state.errors.payment_class_id && | |
<div className="form-row"> | |
<div className="form-labels"></div> | |
<div className="help-block form-main">Payment class is required</div> | |
</div> | |
} | |
</div> | |
{ that.state.selectedPatient && | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Currency</label> | |
<div className="form-main"> | |
<select name="currency" id="currency" className="chosen form_field"> | |
{currencyTypes} | |
</select> | |
</div> | |
</div> | |
</div> | |
} | |
<div className={that.state.errors.amount ? 'form-group has-error' : 'form-group'}> | |
<div className="form-row"> | |
<label className="form-labels control-label">Amount</label> | |
<div className="form-main form-main-left"> | |
<input name="amount" className="form-control form_field" id="amount" placeholder="$" | |
type="number"/> | |
</div> | |
</div> | |
{that.state.errors.amount && | |
<div className="form-row"> | |
<div className="form-labels"></div> | |
<div className="help-block form-main">Amount is required</div> | |
</div> | |
} | |
</div> | |
{ that.state.selectedPatient && that.state.hasStripeKey && that.state.isCreditCard && | |
<div className={that.state.errors.patient_payment_method_id ? 'form-group has-error' : 'form-group'}> | |
<div className="form-row"> | |
<label className="form-labels control-label">Credit Card*</label> | |
<div className="form-main"> | |
<select name="patient_payment_method_id" id="patient_payment_method_id" className="form_field"> | |
{creditCardOptions} | |
</select> | |
</div> | |
</div> | |
{that.state.errors.patient_payment_method_id && | |
<div className="form-row"> | |
<div className="form-labels"></div> | |
<div className="help-block form-main">Credit Card is required</div> | |
</div> | |
} | |
</div> | |
} | |
{ that.state.selectedPatient && !that.state.hasStripeKey && | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Credit Card</label> | |
<div className="form-main"> | |
<select name="preferred_credit_card" id="preferred_credit_card" className="chosen form_field"> | |
{preferredCreditCardOptions} | |
</select> | |
</div> | |
</div> | |
</div> | |
} | |
{ that.state.selectedPatient && that.state.hasStripeKey && | |
<div className="form-group payment_error_message"> | |
<div className="form-row"> | |
<label className="form-labels control-label"></label> | |
<div className="form-main"> | |
<p className="payment-errors"></p> | |
</div> | |
</div> | |
</div> | |
} | |
{that.state.isNewCard && that.state.isCreditCard && | |
<StripeForm ref="stripe_form" stripeTokenHandler={that.stripeTokenHandler} currentClinician={that.state.currentClinician} /> | |
} | |
{ that.state.isPaymentNumberRequired && | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label">Check/Payment #</label> | |
<div className="form-main"> | |
<input name="payment_number" id="check_payment_number" className="form-control form_field" | |
type="text"/> | |
</div> | |
</div> | |
</div> | |
} | |
<div className="form-group"> | |
<div className="form-row"> | |
<label className="form-labels control-label"> | |
Memo | |
</label> | |
<div className="form-main"> | |
<textarea rows="4" id="memo" className="form-control form_field" name="memo"/> | |
</div> | |
</div> | |
</div> | |
{ that.state.selectedPatient && | |
<p className="right" style={{'marginRight': '15px'}}>Total Amount | |
Due: {that.state.selectedPatient.patient_balance.formatCurrency()}</p> | |
} | |
<UnpaidInvoices ref="unpaid_invoices" selectedPatientHandler={that.selectedPatientHandler} /> | |
</form> | |
</div> | |
<p style={{'textAlign': 'center'}}> | |
<img className="saving_payment" style={{'display': 'none'}} | |
src={that.props.loadingImagePath}/> | |
</p> | |
<div className="modal-footer"> | |
<button type="button" className="btn btn-default cancel" data-dismiss="modal">Close</button> | |
<button type="button" className="btn btn-primary save" onClick={that.preparePayment}>Save</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment