diff --git a/public/assets/css/style.css b/public/assets/css/style.css index a67f0745..db831654 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -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; + } } \ No newline at end of file diff --git a/src/Controller/CustomerController.php b/src/Controller/CustomerController.php index bc2d9ffc..1be54743 100644 --- a/src/Controller/CustomerController.php +++ b/src/Controller/CustomerController.php @@ -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 diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index d968691f..c1cd86cd 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -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; diff --git a/src/Entity/CustomerVehicle.php b/src/Entity/CustomerVehicle.php index ab29b26c..60271608 100644 --- a/src/Entity/CustomerVehicle.php +++ b/src/Entity/CustomerVehicle.php @@ -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; } } diff --git a/src/Entity/MobileNumber.php b/src/Entity/MobileNumber.php index ea402acc..586a5392 100644 --- a/src/Entity/MobileNumber.php +++ b/src/Entity/MobileNumber.php @@ -28,6 +28,7 @@ class MobileNumber /** * @ORM\ManyToOne(targetEntity="Customer", inversedBy="numbers") * @ORM\JoinColumn(name="customer_id", referencedColumnName="id") + * @Assert\NotBlank() */ protected $customer; diff --git a/templates/customer/form.html.twig b/templates/customer/form.html.twig index 31d18576..6f76c35b 100644 --- a/templates/customer/form.html.twig +++ b/templates/customer/form.html.twig @@ -34,7 +34,7 @@