{% extends 'base.html.twig' %} {% block body %}

Job Order

{% if mode == 'update-processing' %} Dispatch {{ obj.getID() }} {% elseif mode == 'update-assigning' %} Rider Assignment {{ obj.getID() }} {% elseif mode == 'update-reassign-hub' %} Re-assign Hub {{ obj.getID() }} {% elseif mode == 'update-reassign-rider' %} Re-assign Rider {{ obj.getID() }} {% elseif mode == 'update-all' %} Viewing {{ obj.getID() }} {% else %} Incoming {% endif %}

{% if ftags.vehicle_dropdown %}
{% else %} {% endif %} {% if obj.getReferenceJO %}
{% endif %}

Customer Details

+63
+63
+63
+63

Vehicle Details

Battery Details

Transaction Details




Location

Invoice

{% if ftags.invoice_edit %} {% else %} {% endif %}
{% if not obj.getInvoice or (obj.getInvoice and obj.getInvoice.getItems|length == 0) %} {% else %} {% for item in obj.getInvoice.getItems %} {% endfor %} {% endif %}
Item Quantity Unit Price Amount
No items to display.
{{ item.getTitle }} {{ item.getQuantity|number_format }} {{ item.getPrice|number_format(2) }} {{ (item.getPrice * item.getQuantity)|number_format(2) }}
{% if ftags.invoice_edit %}
{% endif %}
{% if mode in ['update-processing', 'update-reassign-hub'] %}

Nearest Hubs

{% for hub in hubs %} {% endfor %}
Hub Branch Available Riders Jobs For Assignment Contact Numbers Action
No items to display.
{{ hub.hub.getName }} {{ hub.hub.getBranch }} {{ hub.rider_count }} {{ hub.jo_count }} {{ hub.hub.getContactNumbers|replace({"\n": ', '}) }} {% if hub.flag_rejected %} {% else %} {% endif %}
{% endif %} {% if mode in ['update-assigning', 'update-fulfillment', 'update-reassign-rider', 'update-all'] %}
{% if obj.getHub %}

Hub Details

{% endif %}
{% if mode in ['update-assigning', 'update-reassign-rider'] %}

Rider Assignment

{% set avail_riders = obj.getHub.getAvailableRiders|default([]) %} {% if obj.getHub %} {% for rider in avail_riders %} {% endfor %} {% endif %}
First Name Last Name Contact No. Plate Number Status
No riders available.
{{ rider.getFirstName }} {{ rider.getLastName }} {{ rider.getContactNumber }} {{ rider.getPlateNumber }}
{% endif %} {% if mode in ['update-fulfillment', 'update-all'] %} {% if obj.getRider %}

Rider Details

{% endif %} {% endif %} {% endif %} {% if mode == 'update-all' %}

Timeline

{% for event in obj.getEvents %}
{{ event.getDateHappen|date("M j, Y") }}
{{ event.getDateHappen|date("h:i:s a") }}
{{ event.getTypeName }} by {{ event.getUser.getFullName|default('Application') }} {% if event.getRider %} - Rider - {{ event.getRider.getFullName }}{% endif %}
{% endfor %}
{% endif %} {% if ftags.ticket_table %}

Tickets

{% endif %}
{% if mode != 'update-all' %} {% endif %} {% if ftags.set_map_coordinate and is_granted('joborder.cancel') and not obj.isCancelled %} Cancel Job Order {% endif %} {% if mode != 'create' %} Back {% endif %}
{% if mode in ['update-processing', 'update-reassign-hub'] %} {% endif %} {% endblock %} {% block scripts %} {% if map_manager == 'bing' %} {{ include ('job-order/bingmaps.js.twig')}} {% else %} {{ include ('job-order/googlemaps.js.twig')}} {% endif %} $("#row-form").submit(function(e) { if (form_in_process) { alert("Cannot submit form twice. First submission still in progress."); return false; } form_in_process = true; var form = $(this); // get all fields, including disabled ones var disabled = form.find(":input:disabled").prop('disabled', false); var fields = form.serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]; disabled.prop('disabled', true); // add invoice items to data fields['invoice_items'] = invoiceItems; {% if mode in ['update-processing', 'update-reassign-hub'] %} // add selected hub to data fields['hub'] = selectedHub; {% endif %} {% if mode in ['update-assigning', 'update-reassign-rider'] %} // add selected rider to data fields['rider'] = selectedRider; {% endif %} e.preventDefault(); $.ajax({ method: "POST", url: form.prop('action'), data: fields }).done(function(response) { // remove all error classes removeErrors(); swal({ title: 'Done!', text: 'Your changes have been saved!', type: 'success', onClose: function() { window.location.href = "{{ return_url }}"; } }); }).fail(function(response) { if (response.status == 422) { form_in_process = false; var errors = response.responseJSON.errors; var firstfield = false; // remove all error classes first removeErrors(); // display errors contextually $.each(errors, function(field, msg) { var formfield = $("[name='" + field + "'], [data-name='" + field + "']"); var label = $("label[data-field='" + field + "']"); var msgbox = $(".form-control-feedback[data-field='" + field + "']"); // add error classes to bad fields formfield.addClass('form-control-danger'); label.addClass('has-danger'); msgbox.html(msg).addClass('has-danger').removeClass('hide'); // check if this field comes first in DOM var domfield = formfield.get(0); if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) { firstfield = domfield; } }); // focus on first bad field firstfield.focus(); // scroll to above that field to make it visible $('html, body').animate({ scrollTop: $(firstfield).offset().top - 200 }, 100); } }); }); // remove all error classes function removeErrors(formSelector = '') { $(formSelector + " .form-control-danger").removeClass('form-control-danger'); $(formSelector + " [data-field]").removeClass('has-danger'); $(formSelector + " .form-control-feedback[data-field]").addClass('hide'); } // store selected vehicle data var vdata = false; {% if ftags.vehicle_dropdown %} // vehicle selector $('#customer-vehicle').select2({ ajax: { url: "{{ url('customer_vehicle_search') }}", dataType: 'json', delay: 200, data: function (params) { var query = { search: params.term, page: params.page || 1 } return query; } }, placeholder: "Select a vehicle" }).on('select2:select', function(e) { var data = e.params.data; // get info for this customer vehicle $.ajax({ method: "GET", url: "{{ url('customer_vehicle_info') }}", data: { id: data.id } }).done(function(response) { vdata = response.data; // reset vehicle fields resetVehicleFields(); // reset invoice fields $("#btn-reset-invoice").click(); // get compatible batteries $("#invoice-bmfg").change(); // set form fields $("[data-vehicle-field='1']").prop('placeholder', ''); $("#customer-first-name").val(vdata.customer.first_name); $("#customer-last-name").val(vdata.customer.last_name); $("#customer-phone-mobile").val(vdata.customer.phone_mobile); $("#customer-phone-landline").val(vdata.customer.phone_landline); $("#customer-phone-office").val(vdata.customer.phone_office); $("#customer-phone-fax").val(vdata.customer.phone_fax); $("#customer-customer-notes").val(vdata.customer.customer_notes); $("#vmfg").val(vdata.vehicle.mfg_name); $("#vehicle-make").val(vdata.vehicle.make); $("#vehicle-year").val(vdata.vehicle.model_year); $("#vehicle-color").val(vdata.vehicle.color); $("#vehicle-plate").val(vdata.vehicle.plate_number); if (typeof vdata.battery !== 'undefined') { $("#current-battery").val(vdata.battery.mfg_name + " " + vdata.battery.model_name + " " + vdata.battery.size_name + " (" + vdata.battery.prod_code + ")"); $("#warranty-code").val(vdata.battery.warranty_code); $("#warranty-expiration").val(vdata.battery.warranty_expiration); } else { $("#current-battery, #warranty-code, #warranty-expiration").val("No current battery").css('color', '#f4516c'); } }) }).focus(); {% endif %} {% if ftags.vehicle_dropdown %} // reference job order selector $('#ref-jo').select2({ ajax: { url: "{{ url('jo_search') }}", dataType: 'json', delay: 200, data: function (params) { var query = { search: params.term, page: params.page || 1 } return query; } }, placeholder: "Select a job order", allowClear: true }); {% endif %} // reset all vehicle info form fields function resetVehicleFields() { $("[data-vehicle-field='1']").val("").css('color', '').prop('placeholder', 'Select a vehicle first'); } // datepicker $(".dp").datepicker({ format: "dd M yyyy", todayHighlight: true, autoclose: true, pickerPosition: 'bottom-left', bootcssVer: 3, clearBtn: true }); // timepicker $('.tp').timepicker({ format: "HH:ii P", minuteStep: 1, showMeridian: true, snapToStep: true, bootcssVer: 3, clearBtn: true, todayHighlight: true, autoclose: true, pickerPosition: 'bottom-left' }); // toggle advance order fields $("#flag-advance").change(function() { var dp = $("[name='date_schedule_date']"); var tp = $("[name='date_schedule_time']"); var checked = $(this).prop('checked'); if (checked) { dp.prop('disabled', false); tp.prop('disabled', false); } else { // reset to default values if disabled var dateObj = moment(dp.data('default-value'), "YYYY-MM-DD"); dp.prop('disabled', true).parent().datepicker('setDate', dateObj.toDate()); tp.prop('disabled', true).timepicker('setTime', tp.data('default-value')); } }).change(); // update battery list when changing manufacturer $("#invoice-bmfg").change(function() { {% if ftags.preset_vehicle %} vdata = { 'vehicle': { 'id': {{ vid }} } }; {% endif %} // must have a selected vehicle if (!vdata) return; var id = $(this).val(); var field = $("#invoice-battery"); // no id specified if (!id) { field.html('').prop('disabled', true); return true; } // get vehicles for this manufacturer $.ajax({ method: "POST", url: "{{ url('vehicle_batteries') }}", data: { id: id, vehicle_id: vdata.vehicle.id } }).done(function(response) { if (response.data.length > 0) { var html = ''; // TODO: Battery unit price is static for now var unitPrice = 1000; $.each(response.data, function(index, battery) { html += ''; }); field.html(html).prop('disabled', false); } else { field.html('').prop('disabled', true); } }); }); // populate battery dropdown for create from vehicle mode {% if ftags.preset_vehicle %} $("#invoice-bmfg").change(); {% endif %} // mask quantity field $("#invoice-quantity").inputmask("mask", { mask: "9999999", placeholder: "" }); var invoiceItems = []; // add to invoice $("#btn-add-to-invoice").click(function() { var bmfg = $("#invoice-bmfg").val(); var battery = $("#invoice-battery").val(); var tradeIn = $("#invoice-trade-in-type").val(); var qty = $("#invoice-quantity").val(); if (!bmfg || !battery || !qty) { swal({ title: 'Whoops!', text: 'Please fill in all the invoice fields.', type: 'warning' }); return false; } if (isNaN(qty)) { swal({ title: 'Whoops!', text: 'Invalid quantity specified.', type: 'warning' }); return false; } // add to invoice array invoiceItems.push({ battery: battery, quantity: qty, trade_in: tradeIn, }); // regenerate the invoice generateInvoice(); }); // update invoice when promo is changed $("#invoice-promo").change(function() { generateInvoice(); }); // trigger update when service type is changed $("#service_type").change(function() { generateInvoice(); }); // reset the invoice table $("#btn-reset-invoice").click(function() { $("#invoice-promo").prop('selectedIndex', 0); invoiceItems = []; generateInvoice(); }); // recompute $("#btn-recompute-invoice").click(function() { generateInvoice(); }); function generateInvoice() { var promo = $("#invoice-promo").val(); var table = $("#invoice-table tbody"); var stype = $("#service_type").val(); var cvid = $("#customer-vehicle").val(); // generate invoice values $.ajax({ method: "POST", url: "{{ url('jo_gen_invoice') }}", data: { 'stype': stype, 'items': invoiceItems, 'promo': promo, 'cvid': cvid } }).done(function(response) { // mark as invoice changed $("#invoice-change").val(1); var invoice = response.invoice; // populate totals $("#invoice-promo-discount").val(invoice.discount); $("#invoice-price").val(invoice.price); $("#invoice-trade-in").val(invoice.trade_in); $("#invoice-vat").val(invoice.vat); $("#invoice-total-amount").val(invoice.total_price); // populate rows var html = ''; if (invoice.items.length > 0) { $.each(invoice.items, function(key, item) { html += '' + '' + item.title + '' + '' + item.quantity + '' + '' + item.unit_price + '' + '' + item.amount + '' + /* '' + */ ''; }); } else { html = '' + '' + 'No items to display.' + '' + ''; } table.html(html); }); } // remove from invoice table // TODO: figure out a way to delete rows, and should deleting trade ins be allowed since they count as items on the table? /* $(document).on("click", ".btn-invoice-delete", function() { var tbody = $("#invoice-table tbody"); var row = $(this).closest('tr'); var qty = row.find('.col-quantity').html(); var unitPrice = row.find('.col-unit-price').html(); // recreate the local invoice items object var newItems = []; // subtract from totals var subtotal = parseFloat(unitPrice) * parseInt(qty); invoiceTotal -= subtotal; updateInvoiceFigures(); // remove from table row.remove(); // get total item rows and show placeholder if needed var visibleRows = tbody.find('tr:not(.placeholder-row)').length; if (visibleRows === 0) { tbody.find('.placeholder-row').removeClass('hide'); } }); */ {% if mode in ['update-processing', 'update-reassign-hub'] %} var selectedHub = '{{ obj.getHub ? obj.getHub.getID : "" }}'; $("#hubs-table tbody tr").click(function() { var id = $(this).data('id'); var lat = $(this).data('lat'); var lng = $(this).data('lng'); if (id != selectedHub) { // highlight this row, set hub value $("#hubs-table").find('.m-table__row--primary').removeClass('m-table__row--primary'); $(this).addClass('m-table__row--primary'); // set value selectedHub = id; // center the map hmap.setCenter(lat, lng); } else { // unhighlight this row $(this).removeClass('m-table__row--primary'); // remove id value selectedHub = ''; } }); {% endif %} {% if mode in ['update-assigning', 'update-reassign-rider'] %} var selectedRider = '{{ obj.getRider ? obj.getRider.getID : "" }}'; $("#riders-table tbody tr").click(function() { var id = $(this).data('id'); if (id != selectedRider) { // highlight this row, set hub value $("#riders-table").find('.m-table__row--primary').removeClass('m-table__row--primary'); $(this).addClass('m-table__row--primary'); // set value selectedRider = id; } else { // unhighlight this row $(this).removeClass('m-table__row--primary'); // remove id value selectedRider = ''; } }); {% endif %} {% if ftags.ticket_table %} var ticketRows = []; {% for ticket in obj.getTickets %} trow = { id: "{{ ticket.getID }}", date_create: "{{ ticket.getDateCreate|date('d M Y - h:i A') }}", ticket_type: "{{ ticket.getTicketTypeText }}", status: "{{ ticket.getStatusText }}", edit_url: "{{ url('ticket_update', {'id': ticket.getID}) }}" }; ticketRows.push(trow); {% endfor %} // tickets data table var ticketOptions = { data: { type: 'local', source: ticketRows, saveState: { cookie: false, webstorage: false } }, layout: { scroll: true }, columns: [ { field: 'id', title: 'ID', width: 30 }, { field: 'date_create', title: 'Date Created', width: 200 }, { field: 'ticket_type', title: 'Ticket Type' }, { field: 'status', title: 'Status' }, { field: 'Actions', width: 70, title: 'Actions', sortable: false, overflow: 'visible', template: function (row, index, datatable) { return ''; }, } ], pagination: false }; var ticketTable = $("#data-tickets").mDatatable(ticketOptions); {% endif %} {% if mode in ['update-processing', 'update-reassign-hub'] %} // reject hub $(".btn-reject").click(function(e) { var hubID = $(this).data('hub-id'); var hubName = $(this).data('hub-name'); var hubBranch = $(this).data('hub-branch'); $("#hub-reject-id").val(hubID); $("#hub-reject-name").val(hubName); $("#hub-reject-branch").val(hubBranch); $("#modal-rejection").modal('show'); return false; }); // focus on reason field $("#modal-rejection").on('shown.bs.modal', function() { $("#hub-reject-reason").focus(); }); // reset reject form on close modal $("#modal-rejection").on('hidden.bs.modal', function() { $("#hub-reject-contact-person, #hub-reject-remarks").val(""); $("#hub-reject-reason").prop('selectedIndex', 0); }); // submit hub rejection $("#hub-reject-form").submit(function(e) { var form = $(this); var btnSubmit = form.find('[type="submit"]'); // disable the button btnSubmit.prop('disabled', true).html(' Please wait'); e.preventDefault(); $.ajax({ method: "POST", url: form.prop('action'), data: form.serialize() }).done(function(response) { // set button state var btnReject = $("#hubs-table").find("tr[data-id='" + $("#hub-reject-id").val() + "']").find('.btn-reject'); btnReject.removeClass('btn-reject btn-info').addClass('btn-danger btn-disabled').prop('disabled', true).html('Rejected'); // remove all error classes removeErrors("#hub-reject-form"); btnSubmit.prop('disabled', false).html('Reject'); // hide modal $("#modal-rejection").modal('hide'); }).fail(function(response) { if (response.status == 422) { form_in_process = false; var errors = response.responseJSON.errors; var firstfield = false; // remove all error classes first removeErrors("#hub-reject-form"); btnSubmit.prop('disabled', false).html('Reject'); // display errors contextually $.each(errors, function(field, msg) { var formfield = form.find("[name='" + field + "'], [data-name='" + field + "']"); var label = form.find("label[data-field='" + field + "']"); var msgbox = form.find(".form-control-feedback[data-field='" + field + "']"); // add error classes to bad fields formfield.addClass('form-control-danger'); label.addClass('has-danger'); msgbox.html(msg).addClass('has-danger').removeClass('hide'); // check if this field comes first in DOM var domfield = formfield.get(0); if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) { firstfield = domfield; } }); // focus on first bad field firstfield.focus(); } }); }); {% endif %} // cancel job order $(".btn-cancel-job-order").click(function(e) { var url = $(this).prop('href'); e.preventDefault(); swal({ title: 'Cancel Job Order', html: 'Please enter the reason for cancellation of this job order:', input: 'textarea', inputClass: 'form-control', type: 'warning', showCancelButton: true, width: '40rem', preConfirm: (reason) => { if (!reason) { swal.showValidationError( 'Reason for cancellation is required.' ) } } }).then((reason) => { $.ajax({ method: "DELETE", url: url, data: { 'cancel_reason': reason.value } }).done(function(response) { swal({ title: 'Done!', text: response.success, type: 'success', onClose: function() { window.location.href = "{{ return_url }}"; } }); }); }); }); }); {% endblock %}