Merge branch '424-cmb-release' of gitlab.com:jankstudio/resq into 433-cmb-notifications-when-jo-is-cancelled-or-rejected

This commit is contained in:
Korina Cordero 2020-07-10 04:14:13 +00:00
commit 00ae620878
13 changed files with 284 additions and 378 deletions

View file

@ -125,11 +125,6 @@ cmb_rapi_jo_odometer:
controller: App\Controller\CMBRAPIController::setOdometer
methods: [POST]
cmb_rapi_jo_arrive_photos_upload:
path: /cmbrapi/uploadarrivephotos
controller: App\Controller\CMBRAPIController::uploadArrivePhotos
methods: [POST]
cmb_rapi_jo_finish_photos_upload:
path: /cmbrapi/uploadfinishphotos
controller: App\Controller\CMBRAPIController::uploadFinishPhotos

View file

@ -239,15 +239,6 @@ class CMBRAPIController extends Controller
return $res->getReturnResponse();
}
public function uploadArrivePhotos(Request $req, RiderAPIHandlerInterface $rapi_handler)
{
$data = $rapi_handler->uploadArrivePhotos($req);
$res = $this->generateResultFromHandler($data);
return $res->getReturnResponse();
}
public function uploadFinishPhotos(Request $req, RiderAPIHandlerInterface $rapi_handler)
{
$data = $rapi_handler->uploadFinishPhotos($req);

View file

@ -764,7 +764,10 @@ class JobOrderController extends Controller
// use invoice object values in a json friendly array
$invoice = [
'discount' => number_format($iobj->getDiscount(), 2),
// TODO: CMB needs to have no decimal places for discount.
// Resq requires the two decimal places since discount is computed.
//'discount' => number_format($iobj->getDiscount(), 2),
'discount' => number_format($iobj->getDiscount(), 0),
'trade_in' => number_format($iobj->getTradeIn(), 2), // TODO: computations not done yet for this on invoice creator
'price' => number_format($iobj->getVATExclusivePrice(), 2),
'vat' => number_format($iobj->getVAT(), 2),

View file

@ -19,21 +19,6 @@ class JOExtra
*/
protected $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $before_speed_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $before_plate_num_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $before_batt_image_filename;
/**
* @ORM\Column(type="string", nullable=true)
*/
@ -49,11 +34,6 @@ class JOExtra
*/
protected $after_batt_image_filename;
/**
* @ORM\Column(type="array", nullable=true)
*/
protected $before_other_images;
/**
* @ORM\Column(type="array", nullable=true)
*/
@ -67,7 +47,6 @@ class JOExtra
public function __construct()
{
$this->before_other_images = new ArrayCollection();
$this->after_other_images = new ArrayCollection();
}
@ -76,38 +55,6 @@ class JOExtra
return $this->id;
}
public function setBeforeSpeedImageFilename($image_filename)
{
$this->before_speed_image_filename = $image_filename;
return $this;
}
public function getBeforeSpeedImageFilename()
{
return $this->before_speed_image_filename;
}
public function setBeforePlateNumImageFilename($image_filename)
{
$this->before_plate_num_image_filename = $image_filename;
return $this;
}
public function getBeforePlateNumImageFilename()
{
return $this->before_plate_num_image_filename;
}
public function setBeforeBattImageFilename($image_filename)
{
$this->before_batt_image_filename = $image_filename;
return $this;
}
public function getBeforeBattImageFilename()
{
return $this->before_batt_image_filename;
}
public function setAfterSpeedImageFilename($image_filename)
{
$this->after_speed_image_filename = $image_filename;
@ -141,29 +88,6 @@ class JOExtra
return $this->after_batt_image_filename;
}
public function getBeforeOtherImages()
{
return $this->before_other_images;
}
public function setBeforeOtherImages(array $images)
{
$this->before_other_images = new ArrayCollection();
foreach ($images as $image_filename)
{
$this->before_other_images->add($image_filename);
}
return $this;
}
public function clearBeforeOtherImages()
{
$this->before_other_images = new ArrayCollection();
return $this;
}
public function getAfterOtherImages()
{
return $this->after_other_images;

View file

@ -9,6 +9,7 @@ class CMBModeOfPayment extends NameValue
const LAZADA = 'lazada';
const CREDIT_CARD = 'credit_card';
const ONLINE_TRANSFER = 'online_transfer';
const E_WALLET = 'e_wallet';
const COLLECTION = [
'cash' => 'Cash',
@ -16,5 +17,6 @@ class CMBModeOfPayment extends NameValue
'lazada' => 'Lazada',
'credit_card' => 'Credit Card',
'online_transfer' => 'Online Transfer',
'e_wallet' => 'E-Wallet',
];
}

View file

@ -0,0 +1,25 @@
<?php
namespace App\Ramcar;
class CMBTransactionOrigin extends NameValue
{
const CALL = 'call';
const ONLINE = 'online';
const FACEBOOK = 'facebook';
const VIP = 'vip';
const MOBILE_APP = 'mobile_app';
const WALK_IN = 'walk_in';
const WHATSAPP = 'whatsapp';
// TODO: for now, resq also gets the walk-in option
const COLLECTION = [
'call' => 'Hotline',
'online' => 'Online',
'facebook' => 'Facebook',
'vip' => 'VIP',
'mobile_app' => 'Mobile App',
'walk_in' => 'Walk-in',
'whatsapp' => 'Whatsapp',
];
}

View file

@ -594,7 +594,7 @@ class CMBCustomerHandler implements CustomerHandlerInterface
protected function generateYearOptions()
{
$start_year = 1950;
return range($start_year, date("Y") + 1);
return range($start_year, date("Y"));
}

View file

@ -270,7 +270,7 @@ class CMBInvoiceGenerator implements InvoiceGeneratorInterface
}
// check if discount is greater than 50 or negative number
if (($discount > 50) || ($discount < 0))
if (($discount > 60) || ($discount < 0))
return 'Invalid discount specified';
$criteria->setDiscount($discount);

View file

@ -36,7 +36,7 @@ use App\Ramcar\JOStatus;
use App\Ramcar\CMBWarrantyClass;
use App\Ramcar\DiscountApply;
use App\Ramcar\CMBModeOfPayment;
use App\Ramcar\TransactionOrigin;
use App\Ramcar\CMBTransactionOrigin;
use App\Ramcar\FacilitatedType;
use App\Ramcar\JORejectionReason;
@ -194,7 +194,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$row['status'] = $statuses[$orow->getStatus()];
$row['flag_advance'] = $orow->isAdvanceOrder();
$row['plate_number'] = $orow->getCustomerVehicle()->getPlateNumber();
$row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP;
$row['is_mobile'] = $orow->getSource() == CMBTransactionOrigin::MOBILE_APP;
$row['car_model'] = $car_model;
$row['rider_name'] = $rider_name;
$row['rider_plate_number'] = $rider_plate_number;
@ -350,7 +350,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
->setTier2Notes($req->request->get('tier2_notes'))
->setDeliveryAddress($req->request->get('delivery_address'))
->setORName($req->request->get('or_name'))
->setPromoDetail($req->request->get('promo_detail'))
->setPromoDetail($req->request->get('promo_detail', ''))
->setModeOfPayment($req->request->get('mode_of_payment'))
->setLandmark($req->request->get('landmark'));
@ -424,7 +424,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$em = $this->em;
$jo = $em->getRepository(JobOrder::class)->find($id);
$old_rider = null;
$old_jo_status = null;
if (empty($jo))
{
// new job order
@ -432,7 +432,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
}
else
{
$old_rider = $jo->getRider();
//$old_rider = $jo->getRider();
$old_jo_status = $jo->getStatus();
}
// check if lat and lng are provided
@ -443,11 +444,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// check if new customer
if ($req->request->get('new_customer', false))
{
if (empty($req->request->get('customer_notes')))
{
$error_array['customer_notes'] = 'Customer notes cannot be null.';
}
// validate mobile phone
$valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile'));
if (!($valid_mobile))
@ -559,11 +555,12 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
}
// get discount and set to meta
$discount = $req->request->get('invoice_discount', []);
// check if discount is greater than 50 or negative number
if (($discount > 50) || ($discount < 0))
$discount = $req->request->get('invoice_discount');
if (($discount > 60) || ($discount < 0))
{
$error_array['invoice_discount'] = 'Invalid discount specified';
}
// get list of service charges
$service_charges = $req->request->get('service_charges', []);
@ -604,7 +601,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
->setTier2Notes($req->request->get('tier2_notes'))
->setDeliveryAddress($req->request->get('delivery_address'))
->setORName($req->request->get('or_name'))
->setPromoDetail($req->request->get('promo_detail'))
->setPromoDetail($req->request->get('promo_detail', ''))
->setModeOfPayment($req->request->get('mode_of_payment'))
->setLandmark($req->request->get('landmark'))
->setHub($hub)
@ -672,8 +669,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$em->flush();
// check if JO has been reassigned
if ($old_rider != $rider)
//if ($old_rider != $rider)
if ($old_jo_status != $jo->getStatus())
{
error_log('JO has been reassigned');
// TODO: refactor later
$channel = 'rider/' . $rider->getID() . '/events';
$payload = [
@ -1447,9 +1446,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
public function initializeOneStepForm()
{
$params['obj'] = new JobOrder();
$new_jo = new JobOrder();
// set time schedule
$date_schedule = new DateTime();
// add 45 minutes to time
$date_schedule->add(new DateInterval('PT45M'));
$new_jo->setDateSchedule($date_schedule);
$params['obj'] = $new_jo;
$params['mode'] = 'onestep';
$params['jo_service_charges'] = [];
$params['current_date'] = new DateTime();
$this->fillDropdownParameters($params);
$this->fillFormTags($params);
@ -1470,6 +1479,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$params['mode'] = 'onestep-edit';
$params['cvid'] = $obj->getCustomerVehicle()->getID();
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
$params['current_date'] = new DateTime();
// get service charges
$sc_array = [];
@ -1503,35 +1513,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$params['signature'] = null;
if ($jo_extra != null)
{
$b_speed_img = $jo_extra->getBeforeSpeedImageFilename();
$a_speed_img = $jo_extra->getAfterSpeedImageFilename();
$b_plate_img = $jo_extra->getBeforePlateNumImageFilename();
$a_plate_img = $jo_extra->getAfterPlateNumImageFilename();
$b_batt_img = $jo_extra->getBeforeBattImageFilename();
$a_batt_img = $jo_extra->getAfterBattImageFilename();
$b_other_images = $jo_extra->getBeforeOtherImages();
$a_other_images = $jo_extra->getAfterOtherImages();
$cust_signature = $jo_extra->getCustomerSignature();
if ($b_speed_img != null)
$pic_array['before_speed_img'] = $b_speed_img;
if ($a_speed_img != null)
$pic_array['after_speed_img'] = $a_speed_img;
if ($b_plate_img != null)
$pic_array['before_plate_img'] = $b_plate_img;
if ($a_plate_img != null)
$pic_array['after_plate_img'] = $a_plate_img;
if ($b_batt_img != null)
$pic_array['before_batt_img'] = $b_batt_img;
if ($a_batt_img != null)
$pic_array['after_batt_img'] = $a_batt_img;
foreach($b_other_images as $b_img)
{
$pic_array['b_other_images'][] = $b_img;
}
foreach ($a_other_images as $a_img)
{
$pic_array['a_other_images'][] = $a_img;
@ -1664,7 +1660,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// get template to display
// check transaction origin if walkin
if ($obj->getSource() == TransactionOrigin::WALK_IN)
if ($obj->getSource() == CMBTransactionOrigin::WALK_IN)
$params['template'] = $this->getTwigTemplate('jo_walkin_form');
else
$params['template'] = $this->getTwigTemplate('jo_onestep_form');
@ -2504,8 +2500,19 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
public function initializeWalkinForm()
{
$params['obj'] = new JobOrder();
$new_jo = new JobOrder();
// set time schedule
$date_schedule = new DateTime();
// add 45 minutes to time
$date_schedule->add(new DateInterval('PT45M'));
$new_jo->setDateSchedule($date_schedule);
$params['obj'] = $new_jo;
$params['mode'] = 'walk-in';
$params['discounts'] = $this->generateDiscountOptions();
$params['current_date'] = new DateTime();
$this->fillDropdownParameters($params);
$this->fillFormTags($params);
@ -2534,11 +2541,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// check if new customer
if ($req->request->get('new_customer', false))
{
if (empty($req->request->get('customer_notes')))
{
$error_array['customer_notes'] = 'Customer notes cannot be null.';
}
// validate mobile phone
$valid_mobile = $this->cust_handler->validateMobileNumber($req->request->get('phone_mobile'));
if (!($valid_mobile))
@ -2640,8 +2642,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
// get discount and set to meta
$discount = $req->request->get('invoice_discount');
// check if discount is greater than 50 or negative number
if (($discount > 50) || ($discount < 0))
// check if discount is greater than 60 or negative number
if (($discount > 60) || ($discount < 0))
$error_array['invoice_discount'] = 'Invalid discount specified';
if (empty($error_array))
@ -2661,7 +2663,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
->setTier1Notes($req->request->get('tier1_notes'))
->setTier2Notes($req->request->get('tier2_notes'))
->setORName($req->request->get('or_name'))
->setPromoDetail($req->request->get('promo_detail'))
->setPromoDetail($req->request->get('promo_detail', ''))
->setModeOfPayment($req->request->get('mode_of_payment'))
->setLandmark($req->request->get('landmark'))
->setDeliveryAddress('Walk-in')
@ -2796,6 +2798,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$params['mode'] = 'walk-in-edit';
$params['cvid'] = $obj->getCustomerVehicle()->getID();
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
$params['current_date'] = new DateTime();
$this->fillDropdownParameters($params);
$this->fillFormTags($params);
@ -2833,7 +2836,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
$params['trade_in_types'] = CMBTradeInType::getCollection();
$params['facilitated_types'] = FacilitatedType::getCollection();
$params['facilitated_hubs'] = $fac_hubs;
$params['sources'] = TransactionOrigin::getCollection();
$params['sources'] = CMBTransactionOrigin::getCollection();
$params['model_years'] = $this->generateYearOptions();
$params['discounts'] = $this->generateDiscountOptions();
}
protected function initFormTags(&$params)
@ -3119,9 +3125,21 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
throw new NotFoundHttpException('The item does not exist');
// check transaction origin
if ($jo->getSource() == TransactionOrigin::WALK_IN)
if ($jo->getSource() == CMBTransactionOrigin::WALK_IN)
return 'jo_walkin_edit_form';
else
return 'jo_onestep_edit_form';
}
protected function generateDiscountOptions()
{
$discount_start = 0;
return range($discount_start, 60);
}
protected function generateYearOptions()
{
$start_year = 1950;
return range($start_year, date("Y"));
}
}

View file

@ -669,13 +669,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
if ($odo <= 0)
$odo = 0;
// get before images
$before_images = [
'speedometer' => null,
'plate_number' => null,
'battery' => null,
'others' => [],
];
$after_images = [
'speedometer' => null,
'plate_number' => null,
@ -685,19 +678,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
$jo_extra = $jo->getJOExtra();
if ($jo_extra != null)
{
// before images
$before_images['speedometer'] = $this->getURLExtraImage($req, $jo_extra->getBeforeSpeedImageFilename());
$before_images['plate_number'] = $this->getURLExtraImage($req, $jo_extra->getBeforePlateNumImageFilename());
$before_images['battery'] = $this->getURLExtraImage($req, $jo_extra->getBeforeBattImageFilename());
// other images
$other_images = [];
foreach ($jo_extra->getBeforeOtherImages() as $others)
{
$other_images[] = $this->getURLExtraImage($req, $others);
}
$before_images['others'] = $other_images;
// after images
$after_images['speedometer'] = $this->getURLExtraImage($req, $jo_extra->getAfterSpeedImageFilename());
$after_images['plate_number'] = $this->getURLExtraImage($req, $jo_extra->getAfterPlateNumImageFilename());
@ -767,7 +747,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
'odometer' => $odo,
// images
'arrive_photos' => $before_images,
'finish_photos' => $after_images,
// customer email
@ -1553,6 +1532,15 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
$odometer_reading = $req->request->get('odometer');
if ($odometer_reading > 999999)
{
$data = [
'title' => 'Failed Set Odometer',
'error' => 'Odometer cannot be more than 6 figures.',
];
return $data;
}
$jo->addMeta('odometer', $odometer_reading);
$this->em->flush();
@ -1586,169 +1574,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
return $new_filename;
}
public function uploadArrivePhotos(Request $req)
{
$required_params = [
'jo_id',
];
$data = $this->checkActiveJO($req, $required_params, $jo);
if (isset($data['error']))
{
$data['title'] = 'Failed Upload Arrive Photos';
return $data;
}
$dest = $this->upload_dir;
$speed_img_file = $req->files->get('speedometer_img');
$batt_img_file = $req->files->get('battery_img');
$plate_num_img_file = $req->files->get('plate_number_img');
$other_img_files[]= $req->files->get('other_images');
if ((empty($speed_img_file)) &&
(empty($batt_img_file)) &&
(empty($plate_num_img_file)))
{
$data = [
'title' => 'Failed Upload Arrive Photos',
'error' => 'No image files received.'
];
return $data;
}
else
{
$new_speed_filename = '';
$new_batt_filename = '';
$new_plate_num_filename = '';
$other_filenames = [];
if (!empty($speed_img_file))
{
// save speedometer file
$orig_speed_filename = pathinfo($speed_img_file->getClientOriginalName(), PATHINFO_FILENAME);
$new_speed_filename = uniqid() . '-'. $orig_speed_filename . '.' . $speed_img_file->guessClientExtension();
try
{
$speed_img_file->move($dest, $new_speed_filename);
}
catch (FileException $e)
{
$data = [
'error' => 'Error saving image files.'
];
return $data;
}
}
if (!empty($batt_img_file))
{
// save battery file
$orig_batt_filename = pathinfo($batt_img_file->getClientOriginalName(), PATHINFO_FILENAME);
$new_batt_filename = uniqid() . '-' . $orig_batt_filename . '.' . $batt_img_file->guessClientExtension();
try
{
$batt_img_file->move($dest, $new_batt_filename);
}
catch (FileException $e)
{
$data = [
'error' => 'Error saving image files.'
];
return $data;
}
}
if (!empty($plate_num_img_file))
{
// save plate number file
$orig_plate_num_filename = pathinfo($plate_num_img_file->getClientOriginalName(), PATHINFO_FILENAME);
$new_plate_num_filename = uniqid() . '-' . $orig_plate_num_filename . '.' . $plate_num_img_file->guessClientExtension();
try
{
$plate_num_img_file->move($dest, $new_plate_num_filename);
}
catch (FileException $e)
{
$data = [
'error' => 'Error saving image files.'
];
return $data;
}
}
foreach ($other_img_files as $other_img_file)
{
if (!(empty($other_img_file)))
{
foreach($other_img_file as $other_img)
{
$orig_other_filename = pathinfo($other_img->getClientOriginalName(), PATHINFO_FILENAME);
$new_other_filename = uniqid() . '-'. $orig_other_filename . '.' . $other_img->guessClientExtension();
$other_filenames[] = $new_other_filename;
try
{
$other_img->move($dest, $new_other_filename);
}
catch (FileException $e)
{
$data = [
'error' => 'Error saving image files.'
];
return $data;
}
}
}
}
$jo_extra = $jo->getJOExtra();
if ($jo_extra == null)
{
// create JOExtra entity
$jo_extra = new JOExtra();
$jo_extra->setBeforeSpeedImageFilename($new_speed_filename);
$jo_extra->setBeforeBattImageFilename($new_batt_filename);
$jo_extra->setBeforePlateNumImageFilename($new_plate_num_filename);
if (empty($other_filenames))
{
$jo_extra->clearBeforeOtherImages();
}
else
{
$jo_extra->setBeforeOtherImages($other_filenames);
}
$jo->setJOExtra($jo_extra);
$this->em->persist($jo_extra);
}
else
{
$jo_extra->setBeforeSpeedImageFilename($new_speed_filename);
$jo_extra->setBeforeBattImageFilename($new_batt_filename);
$jo_extra->setBeforePlateNumImageFilename($new_plate_num_filename);
if (empty($other_filenames))
{
$jo_extra->clearBeforeOtherImages();
}
else
{
$jo_extra->setBeforeOtherImages($other_filenames);
}
}
$this->em->flush();
}
return $data;
}
public function uploadFinishPhotos(Request $req)
{
$required_params = [

View file

@ -663,9 +663,18 @@
// display create vehicle form
$("#add-vehicle").click(function() {
$("#vehicle-form").data('mode', 'create');
$("#vehicle-form-title").html("Add Vehicle");
$("#vehicle-form-modal").modal('show');
// check if there are already 2 vehicles in list
if (vehicleRows.length == 2)
{
swal({
text: 'Customer is limited to only 2 vehicles..',
type: 'info',
});
} else {
$("#vehicle-form").data('mode', 'create');
$("#vehicle-form-title").html("Add Vehicle");
$("#vehicle-form-modal").modal('show');
}
});
// find vehicle row by index

View file

@ -178,7 +178,16 @@
</div>
<div class="col-lg-3">
<label data-field="cv_year">Model Year</label>
<input type="text" name="cv_year" id="cv-year" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle ? obj.getCustomerVehicle.getModelYear }}" data-vehicle-field="1" disabled>
<select name="cv_year" class="form-control m-input cv_field" id="cv-year" data-required="0" disabled>
<option value="">Select a year</option>
{% for year in model_years %}
{% if obj.getCustomerVehicle %}
<option value="{{ year }}"{{ obj.getCustomerVehicle.getModelYear == year ? ' selected' }}>{{ year }}</option>
{% else %}
<option value="{{ year }}">{{ year }}</option>
{% endif %}
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="cv_year"></div>
</div>
</div>
@ -278,7 +287,7 @@
<div class="col-lg-3">
<label data-field="date_schedule">Scheduled Date</label>
<div class="input-group date dp">
<input type="text" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
<input type="text" id="date-schedule-date" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
<span class="input-group-addon">
<i class="la la-calendar glyphicon-th"></i>
</span>
@ -288,7 +297,7 @@
<div class="col-lg-3">
<label data-field="date_schedule">Scheduled Time</label>
<div class="input-group">
<input type="text" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
<input type="text" id="date-schedule-time" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
<span class="input-group-addon">
<i class="la la-clock-o glyphicon-th"></i>
</span>
@ -511,50 +520,9 @@
</div>
<div class="col-lg-3">
<label> Customer Signature </label>
{% if signature %}
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ signature }}');" ></div>
{% endif %}
<div class="portrait-box" style="background-image: url('{{ signature ? '/uploads/jo_extra/' ~ signature : '/assets/images/user.gif' }}');" ></div>
</div>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<label> Pictures Before Service</label>
</div>
{% for key, picture in jo_pictures %}
{% if key == 'before_speed_img' %}
<div class="col-lg-2">
<label> Speedometer before Service </label>
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ picture }}');" ></div>
</div>
{% endif %}
{% if key == 'before_plate_img' %}
<div class="col-lg-2">
<label> Plate Number before Service </label>
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ picture }}');" ></div>
</div>
{% endif %}
{% if key == 'before_batt_img' %}
<div class="col-lg-2">
<label> Battery before Service </label>
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ picture }}');" ></div>
</div>
{% endif %}
{% endfor %}
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<label> Other Images before Service</label>
</div>
{% for key, picture in jo_pictures %}
{% if key == 'b_other_images' %}
{% for pic in jo_pictures['b_other_images'] %}
<div class="col-lg-2">
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ pic }}');" ></div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<label> Pictures After Service</label>
@ -646,7 +614,7 @@
<input type="text" name="or_name" id="or_name" class="form-control m-input" value="{{ obj.getORName|default('') }}">
<div class="form-control-feedback hide" data-field="or_name"></div>
</div>
<div class="col-lg-6">
<div style="display:none" class="col-lg-6">
<label data-field="promo_detail">Employee ID / Card Number / Referred By</label>
<input type="text" name="promo_detail" id="promo_detail" class="form-control m-input" value="{{ obj.getPromoDetail|default('') }}">
<div class="form-control-feedback hide" data-field="promo_detail"></div>
@ -656,10 +624,29 @@
<div class="col-lg-6">
<label>Discount</label>
{% if ftags.invoice_edit %}
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
<option value=""></option>
{% for discount in discounts %}
{% if obj.getInvoice %}
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(2) == discount ? ' selected' }}>{{ discount }}</option>
{% else %}
<option value="{{ discount }}">{{ discount }}</option>
{% endif %}
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
{% else %}
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
<option value=""></option>
{% for discount in discounts %}
{% if obj.getInvoice %}
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(2) == discount ? ' selected' }} disabled>{{ discount }}</option>
{% else %}
<option value="{{ discount }}" disabled>{{ discount }}</option>
{% endif %}
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
{% endif %}
</div>
<div class="col-lg-6">
@ -1157,6 +1144,7 @@ $(function() {
{% endif %}
$("#row-form").submit(function(e) {
e.preventDefault();
if (form_in_process) {
alert("Cannot submit form twice. First submission still in progress.");
return false;
@ -1319,6 +1307,7 @@ $(function() {
} else {
$("#current-battery, #warranty-expiration").val("No current battery").css('color', '#f4516c');
}
$("#or_name").val(vdata.customer.first_name + ' ' + vdata.customer.last_name);
})
}).focus();
{% endif %}
@ -1542,7 +1531,8 @@ $(function() {
// update invoice when promo is changed
$("#invoice-discount").change(function() {
generateInvoice();
console.log('discount ' + $("#invoice-discount").val());
generateInvoice();
});
// trigger update when service type is changed
@ -1886,6 +1876,53 @@ $(function() {
generateInvoice();
});
$("#customer-first-name, #customer-last-name").change(function() {
// autopopulate OR name with customer name
var cust_name = $("#customer-first-name").val() + ' ' + $("#customer-last-name").val();
$("#or_name").val(cust_name);
});
$('.dp').on('changeDate', function() {
// check date schedule if it's earlier
// if so, show an alert to let user know
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
var date_schedule = new Date(date_time);
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
// check if date is earlier than current
if (date_schedule < current_date)
{
swal({
title: 'Warning!',
text: 'Schedule date and time is before today\'s date and time.',
type: 'warning',
});
}
});
$('.tp').on('changeTime.timepicker', function(e) {
// set the schedule time what the user selects
$('#date-schedule-time').val(e.time.value);
});
$('.tp').on('hide.timepicker', function(e) {
// check time schedule along with date if it's earlier than current date
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
var date_schedule = new Date(date_time);
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
// check if date is earlier than current
if (date_schedule < current_date)
{
swal({
title: 'Warning!',
text: 'Schedule date and time is before today\'s date and time.',
type: 'warning',
});
}
});
});
</script>
{% endblock %}

View file

@ -178,7 +178,16 @@
</div>
<div class="col-lg-3">
<label data-field="cv_year">Model Year</label>
<input type="text" name="cv_year" id="cv-year" class="form-control m-input cv_field" value="{{ obj.getCustomerVehicle ? obj.getCustomerVehicle.getModelYear }}" data-vehicle-field="1" disabled>
<select name="cv_year" class="form-control m-input cv_field" id="cv-year" data-required="0" disabled>
<option value="">Select a year</option>
{% for year in model_years %}
{% if obj.getCustomerVehicle %}
<option value="{{ year }}"{{ obj.getCustomerVehicle.getModelYear == year ? ' selected' }}>{{ year }}</option>
{% else %}
<option value="{{ year }}">{{ year }}</option>
{% endif %}
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="cv_year"></div>
</div>
</div>
@ -278,7 +287,7 @@
<div class="col-lg-3">
<label data-field="date_schedule">Scheduled Date</label>
<div class="input-group date dp">
<input type="text" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
<input type="text" id="date-schedule-date" name="date_schedule_date" class="form-control m-input" data-default-value="{{ obj.getDateSchedule|default("now")|date('Y-m-d') }}" value="{{ obj.getDateSchedule|default("now")|date('d M Y') }}" readonly placeholder="Select a date" disabled>
<span class="input-group-addon">
<i class="la la-calendar glyphicon-th"></i>
</span>
@ -288,7 +297,7 @@
<div class="col-lg-3">
<label data-field="date_schedule">Scheduled Time</label>
<div class="input-group">
<input type="text" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
<input type="text" id="date-schedule-time" name="date_schedule_time" class="form-control m-input tp" data-default-value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" value="{{ obj.getDateSchedule|default("now")|date('g:i A') }}" readonly placeholder="Select a time" disabled>
<span class="input-group-addon">
<i class="la la-clock-o glyphicon-th"></i>
</span>
@ -392,7 +401,7 @@
<input type="text" name="or_name" id="or_name" class="form-control m-input" value="{{ obj.getORName|default('') }}">
<div class="form-control-feedback hide" data-field="or_name"></div>
</div>
<div class="col-lg-6">
<div style="display:none" class="col-lg-6">
<label data-field="promo_detail">Employee ID / Card Number / Referred By</label>
<input type="text" name="promo_detail" id="promo_detail" class="form-control m-input" value="{{ obj.getPromoDetail|default('') }}">
<div class="form-control-feedback hide" data-field="promo_detail"></div>
@ -402,10 +411,28 @@
<div class="col-lg-6">
<label>Discount</label>
{% if ftags.invoice_edit %}
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min = "0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}">
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
<option value=""></option>
{% for discount in discounts %}
{% if obj.getInvoice %}
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount|number_format(0) == discount ? ' selected' }}>{{ discount }}</option>
{% else %}
<option value="{{ discount }}">{{ discount }}</option>
{% endif %}
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="invoice_discount"></div>
{% else %}
<input type="number" id="invoice-discount" name="invoice_discount" class="form-control m-input min="0" max="50" value="{{ obj.getInvoice ? obj.getInvoice.getDiscount }}" disabled>
<select class="form-control m-input" id="invoice-discount" name="invoice_discount">
<option value=""></option>
{% for discount in discounts %}
{% if obj.getInvoice %}
<option value="{{ discount }}"{{ obj.getInvoice.getDiscount == discount ? ' selected' }} disabled>{{ discount }}</option>
{% else %}
<option value="{{ discount }}" disabled>{{ discount }}</option>
{% endif %}
{% endfor %}
</select>
{% endif %}
</div>
<div class="col-lg-6">
@ -721,6 +748,8 @@ var vdata = false;
} else {
$("#current-battery, #warranty-expiration").val("No current battery").css('color', '#f4516c');
}
$("#or_name").val(vdata.customer.first_name + ' ' + vdata.customer.last_name);
})
}).focus();
{% endif %}
@ -1087,6 +1116,54 @@ var vdata = false;
});
});
});
$("#customer-first-name, #customer-last-name").change(function() {
// autopopulate OR name with customer name
var cust_name = $("#customer-first-name").val() + ' ' + $("#customer-last-name").val();
$("#or_name").val(cust_name);
});
$('.dp').on('changeDate', function() {
// check date schedule if it's earlier
// if so, show an alert to let user know
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
var date_schedule = new Date(date_time);
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
// check if date is earlier than current
if (date_schedule < current_date)
{
swal({
title: 'Warning!',
text: 'Schedule date and time is before today\'s date and time.',
type: 'warning',
});
}
});
$('.tp').on('changeTime.timepicker', function(e) {
// set the schedule time what the user selects
$('#date-schedule-time').val(e.time.value);
});
$('.tp').on('hide.timepicker', function(e) {
// check time schedule along with date if it's earlier than current date
var date_time = $('#date-schedule-date').val() + ' ' + $('#date-schedule-time').val()
var date_schedule = new Date(date_time);
var current_date = new Date('{{ current_date|date('Y-m-d g:i A') }}');
// check if date is earlier than current
if (date_schedule < current_date)
{
swal({
title: 'Warning!',
text: 'Schedule date and time is before today\'s date and time.',
type: 'warning',
});
}
});
});
</script>
{% endblock %}