Fix customer crud form saving
This commit is contained in:
parent
cab1af0356
commit
7739b23a7d
6 changed files with 394 additions and 129 deletions
|
|
@ -1,7 +1,9 @@
|
|||
/* template add-ons */
|
||||
|
||||
label.has-danger,
|
||||
.form-control-feedback.has-danger {
|
||||
.form-control-feedback.has-danger,
|
||||
span.has-danger,
|
||||
.nav-link.has-danger {
|
||||
color: #f4516c !important;
|
||||
}
|
||||
|
||||
|
|
@ -44,4 +46,10 @@ label.has-danger,
|
|||
|
||||
.switch-label {
|
||||
margin: 6px 0 0 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 995px) {
|
||||
.modal-lg {
|
||||
max-width: 1024px;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,7 +171,8 @@ class CustomerController extends BaseController
|
|||
foreach ($numbers as $key => $number) {
|
||||
$mobile_number = new MobileNumber();
|
||||
$mobile_number->setID($number->id)
|
||||
->setDateRegistered(DateTime::createFromFormat("d M Y - h:i A", $number->date_registered));
|
||||
->setDateRegistered(DateTime::createFromFormat("d M Y - h:i A", $number->date_registered))
|
||||
->setCustomer($row);
|
||||
|
||||
if (!empty($number->date_confirmed)) {
|
||||
$mobile_number->setDateConfirmed(DateTime::createFromFormat("d M Y - h:i A", $number->date_confirmed))
|
||||
|
|
@ -190,8 +191,7 @@ class CustomerController extends BaseController
|
|||
$nerror_array[$key][$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
// add to entity
|
||||
if (!$nerrors) {
|
||||
if (!isset($nerror_array[$key])) {
|
||||
$row->addMobileNumber($mobile_number);
|
||||
}
|
||||
}
|
||||
|
|
@ -209,16 +209,18 @@ class CustomerController extends BaseController
|
|||
$verror_array[$vehicle->index]['vehicle'] = 'Invalid vehicle specified.';
|
||||
} else {
|
||||
$cust_vehicle = new CustomerVehicle();
|
||||
$cust_vehicle->setVehicle($vobj)
|
||||
$cust_vehicle->setName($vehicle->name)
|
||||
->setVehicle($vobj)
|
||||
->setPlateNumber($vehicle->plate_number)
|
||||
->setModelYear($vehicle->model_year)
|
||||
->setColor($vehicle->color)
|
||||
->setStatusCondition($vehicle->status_condition)
|
||||
->setFuelType($vehicle->fuel_type)
|
||||
->setActive($vehicle->flag_active);
|
||||
->setActive($vehicle->flag_active)
|
||||
->setCustomer($row);
|
||||
|
||||
// if specified, check if battery exists
|
||||
if (isset($vehicle->battery)) {
|
||||
if ($vehicle->battery) {
|
||||
// check if battery exists
|
||||
$bobj = $em->getRepository(Battery::class)->find($vehicle->battery);
|
||||
|
||||
|
|
@ -237,15 +239,15 @@ class CustomerController extends BaseController
|
|||
$verrors = $validator->validate($cust_vehicle);
|
||||
|
||||
// add errors to list
|
||||
foreach ($nerrors as $error) {
|
||||
if (!isset($nerror_array[$key]))
|
||||
foreach ($verrors as $error) {
|
||||
if (!isset($verror_array[$vehicle->index]))
|
||||
$verror_array[$vehicle->index] = [];
|
||||
|
||||
$verror_array[$vehicle->index][$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
// add to entity
|
||||
if (empty($verror_array[$vehicle->index])) {
|
||||
if (!isset($verror_array[$vehicle->index])) {
|
||||
$row->addVehicle($cust_vehicle);
|
||||
}
|
||||
}
|
||||
|
|
@ -319,28 +321,180 @@ class CustomerController extends BaseController
|
|||
throw $this->createNotFoundException('The item does not exist');
|
||||
|
||||
// set and save values
|
||||
$row->setName($req->request->get('name'));
|
||||
$row->setFirstName($req->request->get('first_name'))
|
||||
->setLastName($req->request->get('last_name'));
|
||||
|
||||
// initialize error lists
|
||||
$error_array = [];
|
||||
$nerror_array = [];
|
||||
$verror_array = [];
|
||||
|
||||
// initialize child id lists
|
||||
$number_ids = [];
|
||||
$vehicle_ids = [];
|
||||
|
||||
// custom validation for mobile numbers
|
||||
$numbers = json_decode($req->request->get('mobile_numbers'));
|
||||
|
||||
if (!empty($numbers)) {
|
||||
foreach ($numbers as $key => $number) {
|
||||
// check if number exists
|
||||
$mobile_number = $em->getRepository(MobileNumber::class)->find($number->id);
|
||||
|
||||
// this is a new number
|
||||
if (empty($mobile_number)) {
|
||||
$mobile_number = new MobileNumber();
|
||||
$mobile_number->setID($number->id)
|
||||
->setDateRegistered(DateTime::createFromFormat("d M Y - h:i A", $number->date_registered))
|
||||
->setCustomer($row);
|
||||
|
||||
if (!empty($number->date_confirmed)) {
|
||||
$mobile_number->setDateConfirmed(DateTime::createFromFormat("d M Y - h:i A", $number->date_confirmed))
|
||||
->setConfirmed();
|
||||
} else {
|
||||
$mobile_number->setConfirmed(false);
|
||||
}
|
||||
|
||||
$nerrors = $validator->validate($mobile_number);
|
||||
|
||||
// add errors to list
|
||||
foreach ($nerrors as $error) {
|
||||
if (!isset($nerror_array[$key]))
|
||||
$nerror_array[$key] = [];
|
||||
|
||||
$nerror_array[$key][$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
if (!isset($nerror_array[$key])) {
|
||||
$row->addMobileNumber($mobile_number);
|
||||
}
|
||||
}
|
||||
|
||||
// add to list of numbers to keep
|
||||
$number_ids[] = $mobile_number->getID();
|
||||
}
|
||||
}
|
||||
|
||||
// delete all numbers not in list
|
||||
$qb = $em->createQueryBuilder();
|
||||
$del_numbers = $qb->select('m')
|
||||
->from(MobileNumber::class, 'm')
|
||||
->where($qb->expr()->notIn('m.id', $number_ids))
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
if (!empty($del_numbers)) {
|
||||
foreach ($del_numbers as $dn) {
|
||||
$em->remove($dn);
|
||||
}
|
||||
}
|
||||
|
||||
// custom validation for vehicles
|
||||
$vehicles = json_decode($req->request->get('vehicles'));
|
||||
|
||||
if (!empty($vehicles)) {
|
||||
foreach ($vehicles as $vehicle) {
|
||||
$cust_vehicle = false;
|
||||
$is_new_vehicle = false;
|
||||
|
||||
// check if customer vehicle exists
|
||||
if (!empty($vehicle->id)) {
|
||||
$cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($vehicle->id);
|
||||
}
|
||||
|
||||
// this is a new vehicle
|
||||
if (empty($cust_vehicle)) {
|
||||
$cust_vehicle = new CustomerVehicle();
|
||||
$cust_vehicle->setCustomer($row);
|
||||
$is_new_vehicle = true;
|
||||
}
|
||||
|
||||
// check if vehicle exists
|
||||
$vobj = $em->getRepository(Vehicle::class)->find($vehicle->vehicle);
|
||||
|
||||
if (empty($vobj)) {
|
||||
$verror_array[$vehicle->index]['vehicle'] = 'Invalid vehicle specified.';
|
||||
} else {
|
||||
$cust_vehicle->setName($vehicle->name)
|
||||
->setVehicle($vobj)
|
||||
->setPlateNumber($vehicle->plate_number)
|
||||
->setModelYear($vehicle->model_year)
|
||||
->setColor($vehicle->color)
|
||||
->setStatusCondition($vehicle->status_condition)
|
||||
->setFuelType($vehicle->fuel_type)
|
||||
->setActive($vehicle->flag_active);
|
||||
|
||||
// if specified, check if battery exists
|
||||
if ($vehicle->battery) {
|
||||
// check if battery exists
|
||||
$bobj = $em->getRepository(Battery::class)->find($vehicle->battery);
|
||||
|
||||
if (empty($bobj)) {
|
||||
$verror_array[$vehicle->index]['battery'] = 'Invalid battery specified.';
|
||||
} else {
|
||||
$cust_vehicle->setHasMotoliteBattery(true)
|
||||
->setCurrentBattery($bobj)
|
||||
->setWarrantyCode($vehicle->warranty_code)
|
||||
->setWarrantyExpiration(DateTime::createFromFormat("d M Y", $vehicle->warranty_expiration));
|
||||
}
|
||||
} else {
|
||||
$cust_vehicle->setHasMotoliteBattery(false);
|
||||
}
|
||||
|
||||
$verrors = $validator->validate($cust_vehicle);
|
||||
|
||||
// add errors to list
|
||||
foreach ($verrors as $error) {
|
||||
if (!isset($verror_array[$vehicle->index]))
|
||||
$verror_array[$vehicle->index] = [];
|
||||
|
||||
$verror_array[$vehicle->index][$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
if (!isset($verror_array[$vehicle->index]) && $is_new_vehicle) {
|
||||
$row->addVehicle($cust_vehicle);
|
||||
}
|
||||
|
||||
// add to list of vehicles to keep
|
||||
$vehicle_ids[] = $cust_vehicle->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete all vehicles not in list
|
||||
$qb = $em->createQueryBuilder();
|
||||
$del_vehicles = $qb->select('cv')
|
||||
->from(CustomerVehicle::class, 'cv')
|
||||
->where($qb->expr()->notIn('cv.id', $vehicle_ids))
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
if (!empty($del_vehicles)) {
|
||||
foreach ($del_vehicles as $dv) {
|
||||
$em->remove($dv);
|
||||
}
|
||||
}
|
||||
|
||||
// validate
|
||||
$errors = $validator->validate($row);
|
||||
|
||||
// initialize error list
|
||||
$error_array = [];
|
||||
|
||||
// add errors to list
|
||||
foreach ($errors as $error) {
|
||||
$error_array[$error->getPropertyPath()] = $error->getMessage();
|
||||
}
|
||||
|
||||
// check if any errors were found
|
||||
if (!empty($error_array)) {
|
||||
if (!empty($error_array) || !empty($nerror_array) || !empty($verror_array)) {
|
||||
// return validation failure response
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'errors' => $error_array
|
||||
'errors' => $error_array,
|
||||
'nerrors' => $nerror_array,
|
||||
'verrors' => $verror_array
|
||||
], 422);
|
||||
} else {
|
||||
// validated! save the entity
|
||||
// validated! save the entity. do a persist anyway to save child entities
|
||||
$em->persist($row);
|
||||
$em->flush();
|
||||
|
||||
// return successful response
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class Customer
|
|||
|
||||
// mobile numbers linked to this customer
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="MobileNumber", mappedBy="customer")
|
||||
* @ORM\OneToMany(targetEntity="MobileNumber", mappedBy="customer", cascade={"persist"})
|
||||
*/
|
||||
protected $numbers;
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ class Customer
|
|||
|
||||
// vehicles linked to customer
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="customer")
|
||||
* @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="customer", cascade={"persist"})
|
||||
*/
|
||||
protected $vehicles;
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ class Customer
|
|||
return $this->sessions;
|
||||
}
|
||||
|
||||
public function addVehicle(Vehicle $vehicle)
|
||||
public function addVehicle(CustomerVehicle $vehicle)
|
||||
{
|
||||
$this->vehicles->add($vehicle);
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class CustomerVehicle
|
|||
// user-defined name for vehicle
|
||||
/**
|
||||
* @ORM\Column(type="string", length=80)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ class CustomerVehicle
|
|||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="vehicles")
|
||||
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $customer;
|
||||
|
||||
|
|
@ -80,7 +82,6 @@ class CustomerVehicle
|
|||
// TODO: figure out how to check expiration
|
||||
/**
|
||||
* @ORM\Column(type="string", length=20, nullable=true)
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $warranty_code;
|
||||
|
||||
|
|
@ -120,6 +121,17 @@ class CustomerVehicle
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setCustomer(Customer $customer)
|
||||
{
|
||||
$this->customer = $customer;
|
||||
|
|
@ -241,14 +253,14 @@ class CustomerVehicle
|
|||
return $this->flag_motolite_battery;
|
||||
}
|
||||
|
||||
public function setActive($active = true)
|
||||
public function setActive($flag_active = true)
|
||||
{
|
||||
$this->active = $active;
|
||||
$this->flag_active = $flag_active;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return $this->active;
|
||||
return $this->flag_active;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class MobileNumber
|
|||
/**
|
||||
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="numbers")
|
||||
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
protected $customer;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
</div>
|
||||
<form id="row-form" class="m-form m-form--label-align-right" method="post" action="{{ mode == 'update' ? url('customer_update_submit', {'id': obj.getId()}) : url('customer_create_submit') }}">
|
||||
<div class="m-portlet__body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<ul id="customer-tabs" class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#customer-info">Customer Info</a>
|
||||
</li>
|
||||
|
|
@ -52,14 +52,14 @@
|
|||
First Name:
|
||||
</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" name="first_name" class="form-control m-input" value="{{ obj.getFirstName() }}">
|
||||
<input type="text" name="first_name" class="form-control m-input" value="{{ obj.getFirstName() }}" data-name="first_name">
|
||||
<div class="form-control-feedback hide" data-field="first_name"></div>
|
||||
</div>
|
||||
<label class="col-lg-2 col-form-label" data-field="last_name">
|
||||
Last Name:
|
||||
</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" name="last_name" class="form-control m-input" value="{{ obj.getLastName() }}">
|
||||
<input type="text" name="last_name" class="form-control m-input" value="{{ obj.getLastName() }}" data-name="last_name">
|
||||
<div class="form-control-feedback hide" data-field="last_name"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -140,7 +140,13 @@
|
|||
</h3>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-name" data-field="name">Vehicle Name</label>
|
||||
<input type="text" name="name" id="vehicle-name" class="form-control m-input" data-required="1">
|
||||
<div class="form-control-feedback hide" data-field="name"></div>
|
||||
<span class="m-form__help">Display name for this vehicle</span>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label for="vmfg" data-field="vmfg">Manufacturer</label>
|
||||
<select name="vmfg" class="form-control m-input" id="vmfg" data-required="0">
|
||||
<option value="">Select a manufacturer</option>
|
||||
|
|
@ -150,31 +156,31 @@
|
|||
</select>
|
||||
<div class="form-control-feedback hide" data-field="vmfg"></div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle" data-field="vehicle">Vehicle</label>
|
||||
<select name="vehicle" class="form-control m-input" id="vehicle" data-value="" data-required="1" disabled>
|
||||
<option value="">Select a manufacturer first</option>
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="vehicle"></div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-year" data-field="model_year">Year</label>
|
||||
<input type="text" name="model_year" id="vehicle-year" class="form-control m-input" data-required="1">
|
||||
<div class="form-control-feedback hide" data-field="model_year"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-plate-number" data-field="plate_number">Plate Number</label>
|
||||
<input type="text" name="plate_number" id="vehicle-plate-number" class="form-control m-input" data-required="1">
|
||||
<div class="form-control-feedback hide" data-field="plate_number"></div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-color" data-field="color">Color</label>
|
||||
<input type="text" name="color" id="vehicle-color" class="form-control m-input" data-required="1">
|
||||
<div class="form-control-feedback hide" data-field="color"></div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-status" data-field="status_condition">Status</label>
|
||||
<select name="status_condition" class="form-control m-input" id="vehicle-status" data-required="1">
|
||||
<option value=""></option>
|
||||
|
|
@ -183,9 +189,7 @@
|
|||
</select>
|
||||
<div class="form-control-feedback hide" data-field="status_condition"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-4">
|
||||
<div class="col-lg-3">
|
||||
<label for="vehicle-fuel-type" data-field="fuel_type">Fuel Type</label>
|
||||
<select name="fuel_type" class="form-control m-input" id="vehicle-fuel-type" data-required="1">
|
||||
<option value=""></option>
|
||||
|
|
@ -194,8 +198,9 @@
|
|||
</select>
|
||||
<div class="form-control-feedback hide" data-field="fuel_type"></div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<label> </label>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-12">
|
||||
<span class="m-switch m-switch--icon block-switch">
|
||||
<label>
|
||||
<input type="checkbox" name="flag_active" id="flag-active" value="1" checked>
|
||||
|
|
@ -225,7 +230,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row curr_battery_row hide">
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-3">
|
||||
<label for="bmfg" data-field="bmfg">Manufacturer</label>
|
||||
<select name="bmfg" class="form-control m-input" id="bmfg" data-required="0">
|
||||
<option value="">Select a manufacturer</option>
|
||||
|
|
@ -235,21 +240,19 @@
|
|||
</select>
|
||||
<div class="form-control-feedback hide" data-field="bmfg"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-3">
|
||||
<label for="battery" data-field="battery">Product</label>
|
||||
<select name="battery" class="form-control m-input" id="battery" data-value="" disabled data-required="0">
|
||||
<option value="">Select a manufacturer first</option>
|
||||
</select>
|
||||
<div class="form-control-feedback hide" data-field="battery"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row curr_battery_row hide">
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-3">
|
||||
<label for="battery-warranty-code" data-field="warranty_code">Warranty Code</label>
|
||||
<input type="text" name="warranty_code" id="battery-warranty-code" class="form-control m-input" data-required="0">
|
||||
<div class="form-control-feedback hide" data-field="warranty_code"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-3">
|
||||
<label for="battery-warranty-expiration" data-field="warranty_expiration">Warranty Expiration</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="warranty_expiration" id="battery-warranty-expiration" class="form-control m-input" readonly placeholder="Select a date" data-required="0">
|
||||
|
|
@ -315,7 +318,10 @@
|
|||
}
|
||||
});
|
||||
}).fail(function(response) {
|
||||
var errors = response.responseJSON.errors;
|
||||
var json = response.responseJSON;
|
||||
var errors = json.errors;
|
||||
var nerrors = json.nerrors;
|
||||
var verrors = json.verrors;
|
||||
var firstfield = false;
|
||||
|
||||
// remove all error classes first
|
||||
|
|
@ -323,7 +329,7 @@
|
|||
|
||||
// display errors contextually
|
||||
$.each(errors, function(field, msg) {
|
||||
var formfield = $("[name='" + field + "']");
|
||||
var formfield = $("[data-name='" + field + "']");
|
||||
var label = $("label[data-field='" + field + "']");
|
||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
||||
|
||||
|
|
@ -338,8 +344,66 @@
|
|||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
||||
firstfield = domfield;
|
||||
}
|
||||
|
||||
// add error class to this tab
|
||||
var tabId = $(formfield).closest('.tab-pane').prop('id');
|
||||
$("#customer-tabs").find("a[href='#" + tabId + "']").addClass('has-danger');
|
||||
});
|
||||
|
||||
// loop through mobile number errors
|
||||
$.each(nerrors, function(rowindex, errorlist) {
|
||||
var row = $("#data-mobile-numbers table").find("[name='index'][value='" + rowindex + "']").closest('tr');
|
||||
|
||||
$.each(errorlist, function(field, msg) {
|
||||
var msgbox = row.find(".form-control-feedback[data-field='" + field + "']");
|
||||
var col = msgbox.closest('span');
|
||||
|
||||
// add error classes to bad fields
|
||||
col.addClass('has-danger');
|
||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
||||
|
||||
// check if this field comes first in DOM
|
||||
var domfield = col.get(0);
|
||||
|
||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
||||
firstfield = domfield;
|
||||
}
|
||||
|
||||
// add error class to this tab
|
||||
var tabId = $(col).closest('.tab-pane').prop('id');
|
||||
$("#customer-tabs").find("a[href='#" + tabId + "']").addClass('has-danger');
|
||||
});
|
||||
});
|
||||
|
||||
// loop through vehicle errors
|
||||
$.each(verrors, function(rowindex, errorlist) {
|
||||
var row = $("#data-vehicles table").find("[name='index'][value='" + rowindex + "']").closest('tr');
|
||||
|
||||
$.each(errorlist, function(field, msg) {
|
||||
var msgbox = row.find(".form-control-feedback[data-field='" + field + "']");
|
||||
var col = msgbox.closest('span');
|
||||
|
||||
// add error classes to bad fields
|
||||
col.addClass('has-danger');
|
||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
||||
|
||||
// check if this field comes first in DOM
|
||||
var domfield = col.get(0);
|
||||
|
||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
||||
firstfield = domfield;
|
||||
}
|
||||
|
||||
// add error class to this tab
|
||||
var tabId = $(col).closest('.tab-pane').prop('id');
|
||||
$("#customer-tabs").find("a[href='#" + tabId + "']").addClass('has-danger');
|
||||
});
|
||||
});
|
||||
|
||||
// focus on tab containing first field
|
||||
var firstTabId = $(firstfield).closest('.tab-pane').prop('id');
|
||||
$("#customer-tabs").find("a[href='#" + firstTabId + "']").tab('show');
|
||||
|
||||
// focus on first bad field
|
||||
firstfield.focus();
|
||||
|
||||
|
|
@ -353,7 +417,7 @@
|
|||
// remove all error classes
|
||||
function removeErrors() {
|
||||
$(".form-control-danger").removeClass('form-control-danger');
|
||||
$("[data-field]").removeClass('has-danger');
|
||||
$(".has-danger").removeClass('has-danger');
|
||||
$(".form-control-feedback[data-field]").addClass('hide');
|
||||
}
|
||||
|
||||
|
|
@ -399,8 +463,8 @@
|
|||
{% for number in obj.getMobileNumbers() %}
|
||||
nrow = {
|
||||
id: "{{ number.getID() }}",
|
||||
date_registered: "{{ number.getDateRegistered() }}",
|
||||
date_confirmed: "{{ number.getDateConfirmed() }}"
|
||||
date_registered: "{{ number.getDateRegistered()|date('d M Y - h:i A') }}",
|
||||
date_confirmed: "{{ number.getDateConfirmed()|date('d M Y - h:i A') }}"
|
||||
};
|
||||
|
||||
numberRows.push(nrow);
|
||||
|
|
@ -413,20 +477,21 @@
|
|||
|
||||
vrow = {
|
||||
id: "{{ cv.getID() }}",
|
||||
name: "{{ cv.getName() }}",
|
||||
index: moment().unix(),
|
||||
battery: "{{ battery.getID() }}",
|
||||
bmfg: "{{ battery.getManufacturer().getID() }}",
|
||||
battery: "{{ battery ? battery.getID() }}",
|
||||
battery_label: "{{ battery ? battery.getModel().getName() ~ ' ' ~ battery.getSize().getName() ~ ' (' ~ battery.getProductCode() ~ ')' }}",
|
||||
bmfg: "{{ battery ? battery.getManufacturer().getID() }}",
|
||||
color: "{{ cv.getColor() }}",
|
||||
flag_active: {{ cv.isActive() }},
|
||||
flag_motolite_battery: {{ cv.hasMotoliteBattery() }},
|
||||
flag_active: {{ cv.isActive() ? 'true' : 'false' }},
|
||||
flag_motolite_battery: {{ cv.hasMotoliteBattery() ? 'true' : 'false' }},
|
||||
fuel_type: "{{ cv.getFuelType() }}",
|
||||
mfg_name: "{{ vehicle.getManufacturer().getName() }}",
|
||||
model_year: "{{ cv.getModelYear() }}",
|
||||
plate_number: "{{ cv.getPlateNumber() }}",
|
||||
status_condition: "{{ cv.getStatusCondition() }}",
|
||||
vehicle: "{{ vehicle.getID() }}",
|
||||
vehicle_label: "{{ vehicle.getMake() ~ ' (' ~ vehicle.getModelYearStart() ~ ' ' ~ vehicle.getModelYearEnd() ~ ')' }}",
|
||||
vmfg: "{{ vehicle.getManufacturer().getID() }}",
|
||||
vehicle: "{{ vehicle ? vehicle.getID() }}",
|
||||
vehicle_label: "{{ vehicle ? vehicle.getManufacturer().getName() ~ ' ' ~ vehicle.getMake() ~ ' (' ~ vehicle.getModelYearFrom() ~ ' ' ~ vehicle.getModelYearTo() ~ ')' }}",
|
||||
vmfg: "{{ vehicle ? vehicle.getManufacturer().getID() }}",
|
||||
warranty_code: "{{ cv.getWarrantyCode() }}",
|
||||
warranty_expiration: "{{ cv.getWarrantyExpiration() ? cv.getWarrantyExpiration()|date('d M Y') }}"
|
||||
};
|
||||
|
|
@ -483,61 +548,45 @@
|
|||
numberTable.reload();
|
||||
});
|
||||
|
||||
// add a vehicle to the table
|
||||
$("#btn-add-vehicle").click(function() {
|
||||
var id = $("#vehicle").val();
|
||||
var index = $("#vehicle").find(":selected").data('index');
|
||||
|
||||
if (vehicleIds.indexOf(id) !== -1) {
|
||||
swal({
|
||||
title: 'Whoops',
|
||||
text: 'This vehicle is already on the list.',
|
||||
type: 'warning'
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// add vehicle to arrays
|
||||
vehicleIds.push(id);
|
||||
vehicleRows.push(mfgVehicles[index]);
|
||||
|
||||
// refresh the data table
|
||||
vehicleTable.originalDataSet = vehicleRows;
|
||||
vehicleTable.reload();
|
||||
});
|
||||
|
||||
// remove item from table
|
||||
$(document).on('click', '.btn-delete', function(e) {
|
||||
// remove mobile number from table
|
||||
$(document).on('click', '.btn-delete-number', function(e) {
|
||||
var btn = $(this);
|
||||
var id = $(this).data('id');
|
||||
var table = $(this).closest('table');
|
||||
var rowArray;
|
||||
var rowIds;
|
||||
var dt;
|
||||
|
||||
if (table.parent().prop('id') == 'data-mobile-numbers') {
|
||||
rowArray = numberRows;
|
||||
dt = numberTable;
|
||||
// remove from ids
|
||||
numberIds.splice(numberIds.indexOf(id), 1);
|
||||
|
||||
// remove from ids
|
||||
numberIds.splice(numberIds.indexOf(id), 1);
|
||||
} else {
|
||||
rowArray = vehicleRows;
|
||||
dt = vehicleTable;
|
||||
}
|
||||
|
||||
$.each(rowArray, function(index, row) {
|
||||
$.each(numberRows, function(index, row) {
|
||||
if (row.id == id) {
|
||||
delete rowArray.splice(index, 1);
|
||||
numberRows.splice(index, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// reload table
|
||||
dt.row(btn.parents('tr')).remove();
|
||||
dt.originalDataSet = rowArray;
|
||||
dt.reload();
|
||||
numberTable.row(btn.parents('tr')).remove();
|
||||
numberTable.originalDataSet = numberRows;
|
||||
numberTable.reload();
|
||||
});
|
||||
|
||||
// remove vehicle from table
|
||||
$(document).on('click', '.btn-delete-vehicle', function(e) {
|
||||
var btn = $(this);
|
||||
var id = $(this).data('index');
|
||||
var table = $(this).closest('table');
|
||||
|
||||
$.each(vehicleRows, function(index, row) {
|
||||
if (row.index == id) {
|
||||
vehicleRows.splice(index, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// reload table
|
||||
vehicleTable.row(btn.parents('tr')).remove();
|
||||
vehicleTable.originalDataSet = vehicleRows;
|
||||
vehicleTable.reload();
|
||||
});
|
||||
|
||||
// display create vehicle form
|
||||
|
|
@ -698,7 +747,7 @@
|
|||
var firstfield = false;
|
||||
|
||||
// remove all error classes first
|
||||
removeErrors();
|
||||
removeVehicleErrors();
|
||||
|
||||
// check for required fields
|
||||
$.each(fields, function(field, value) {
|
||||
|
|
@ -739,8 +788,7 @@
|
|||
|
||||
// build table row
|
||||
var row = fields;
|
||||
row.mfg_name = $("#vmfg option:selected").text();
|
||||
row.vehicle_label = $("#vehicle option:selected").text();
|
||||
row.vehicle_label = $("#vmfg option:selected").text() + " " + $("#vehicle option:selected").text();
|
||||
row.flag_active = row.flag_active == 1 ? true : false;
|
||||
|
||||
// add optional field
|
||||
|
|
@ -778,14 +826,15 @@
|
|||
$("#flag-motolite-battery").prop('checked', false).change();
|
||||
$("#flag-active").prop('checked', true);
|
||||
$("#vehicle-form").find("input[type='text'], select").val("").change();
|
||||
removeErrors();
|
||||
removeVehicleErrors();
|
||||
});
|
||||
|
||||
// remove all error classes on vehicle form
|
||||
function removeErrors() {
|
||||
$(".form-control-danger").removeClass('form-control-danger');
|
||||
$("[data-field]").removeClass('has-danger');
|
||||
$(".form-control-feedback[data-field]").addClass('hide');
|
||||
function removeVehicleErrors() {
|
||||
var form = $("#vehicle-form");
|
||||
form.find(".form-control-danger").removeClass('form-control-danger');
|
||||
form.find("[data-field]").removeClass('has-danger');
|
||||
form.find(".form-control-feedback[data-field]").addClass('hide');
|
||||
}
|
||||
|
||||
// mobile numbers data table
|
||||
|
|
@ -804,15 +853,24 @@
|
|||
columns: [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'Mobile Number'
|
||||
title: 'Mobile Number',
|
||||
template: function (row, index, datatable) {
|
||||
return row.id + '<div class="form-control-feedback hide" data-field="id"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'date_registered',
|
||||
title: 'Date Registered'
|
||||
title: 'Date Registered',
|
||||
template: function (row, index, datatable) {
|
||||
return row.date_registered + '<div class="form-control-feedback hide" data-field="date_registered"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'date_confirmed',
|
||||
title: 'Date Confirmed'
|
||||
title: 'Date Confirmed',
|
||||
template: function (row, index, datatable) {
|
||||
return row.date_confirmed + '<div class="form-control-feedback hide" data-field="date_confirmed"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'Actions',
|
||||
|
|
@ -821,7 +879,7 @@
|
|||
sortable: false,
|
||||
overflow: 'visible',
|
||||
template: function (row, index, datatable) {
|
||||
return '<button data-id="' + row.id + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" title="Delete"><i class="la la-trash"></i></button>';
|
||||
return '<button data-id="' + row.id + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete-number" title="Delete"><i class="la la-trash"></i></button>';
|
||||
},
|
||||
}
|
||||
],
|
||||
|
|
@ -845,60 +903,92 @@
|
|||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'mfg_name',
|
||||
title: 'Manufacturer'
|
||||
field: 'name',
|
||||
title: 'Name',
|
||||
template: function (row, index, datatable) {
|
||||
return row.name + '<div class="form-control-feedback hide" data-field="name"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'vehicle_label',
|
||||
title: 'Vehicle',
|
||||
width: 150
|
||||
width: 150,
|
||||
template: function (row, index, datatable) {
|
||||
return row.vehicle_label + '<div class="form-control-feedback hide" data-field="vehicle"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'model_year',
|
||||
title: 'Year'
|
||||
title: 'Year',
|
||||
template: function (row, index, datatable) {
|
||||
return row.model_year + '<div class="form-control-feedback hide" data-field="model_year"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'plate_number',
|
||||
title: 'Plate No.'
|
||||
title: 'Plate No.',
|
||||
template: function (row, index, datatable) {
|
||||
return row.plate_number + '<div class="form-control-feedback hide" data-field="plate_number"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'color',
|
||||
title: 'Color',
|
||||
width: 70
|
||||
width: 70,
|
||||
template: function (row, index, datatable) {
|
||||
return row.color + '<div class="form-control-feedback hide" data-field="color"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'status_condition',
|
||||
title: 'Cond.'
|
||||
title: 'Cond.',
|
||||
template: function (row, index, datatable) {
|
||||
return row.status_condition + '<div class="form-control-feedback hide" data-field="status_condition"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'fuel_type',
|
||||
title: 'Fuel Type'
|
||||
title: 'Fuel Type',
|
||||
template: function (row, index, datatable) {
|
||||
return row.fuel_type + '<div class="form-control-feedback hide" data-field="fuel_type"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'warranty_code',
|
||||
title: 'Wty. Code'
|
||||
title: 'Wty. Code',
|
||||
template: function (row, index, datatable) {
|
||||
return row.warranty_code + '<div class="form-control-feedback hide" data-field="warranty_code"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'warranty_expiration',
|
||||
title: 'Wty. Exp.',
|
||||
width: 80
|
||||
width: 80,
|
||||
template: function (row, index, datatable) {
|
||||
return row.warranty_expiration + '<div class="form-control-feedback hide" data-field="warranty_expiration"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'battery_label',
|
||||
title: 'Battery',
|
||||
width: 150
|
||||
width: 150,
|
||||
template: function (row, index, datatable) {
|
||||
return row.battery_label + '<div class="form-control-feedback hide" data-field="battery"></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'flag_active',
|
||||
title: 'Status',
|
||||
template: function (row, index, datatable) {
|
||||
if (row.flag_active === true) {
|
||||
tag = '<span class="m-badge m-badge--success m-badge--wide">Active</span>';
|
||||
html = '<span class="m-badge m-badge--success m-badge--wide">Active</span>';
|
||||
} else {
|
||||
tag = '<span class="m-badge m-badge--danger m-badge--wide">Inactive</span>';
|
||||
html = '<span class="m-badge m-badge--danger m-badge--wide">Inactive</span>';
|
||||
}
|
||||
|
||||
return tag;
|
||||
html += '<div class="form-control-feedback hide" data-field="flag_active"></div>';
|
||||
|
||||
return html;
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -910,8 +1000,8 @@
|
|||
template: function (row, index, datatable) {
|
||||
html = '<input type="hidden" name="index" value="' + row.index + '">';
|
||||
|
||||
html += '<button data-id="' + row.id + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit-vehicle" data-id="' + row.mfg_name + ' ' + row.make + ' ' + row.year + '" title="Edit"><i class="la la-edit"></i></button>' +
|
||||
'<button data-id="' + row.id + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" title="Delete"><i class="la la-trash"></i></button>';
|
||||
html += '<button type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit-vehicle" title="Edit"><i class="la la-edit"></i></button>' +
|
||||
'<button data-index="' + row.index + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete-vehicle" title="Delete"><i class="la la-trash"></i></button>';
|
||||
|
||||
return html;
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue