Merge branch '434-cmb-uat-issues' into '424-cmb-release'
Resolve "CMB - UAT issues" See merge request jankstudio/resq!501
This commit is contained in:
commit
954ccc5071
16 changed files with 496 additions and 403 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -102,10 +102,17 @@ class AnalyticsController extends Controller
|
|||
*/
|
||||
public function forecastSubmit(EntityManagerInterface $em, Request $req)
|
||||
{
|
||||
$today = new DateTime();
|
||||
|
||||
$hub_list = $req->request->get('hub_ids', []);
|
||||
$distances = $req->request->get('distances', []);
|
||||
$today = DateTime::createFromFormat('d M Y', $req->request->get('date'));
|
||||
$month = $today->format('m');
|
||||
|
||||
$time_start = $req->request->get('time_from');
|
||||
$time_end = $req->request->get('time_to');
|
||||
|
||||
$date_from = DateTime::createFromFormat('d M Y', $req->request->get('date_from'));
|
||||
$date_to = DateTime::createFromFormat('d M Y', $req->request->get('date_to'));
|
||||
|
||||
// error_log(print_r($hub_list, true));
|
||||
|
||||
// $hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
|
||||
|
|
@ -119,7 +126,7 @@ class AnalyticsController extends Controller
|
|||
$hub = $em->getRepository(Hub::class)->find($hub_id);
|
||||
$coords = $hub->getCoordinates();
|
||||
|
||||
$hub_data[$hub_id] = $this->generateHubData($em, $hub, $dist, $today, $overlaps);
|
||||
$hub_data[$hub_id] = $this->generateHubData($em, $hub, $dist, $date_from, $date_to, $time_start, $time_end, $overlaps);
|
||||
|
||||
$hub_coverage[] = [
|
||||
'longitude' => $coords->getLongitude(),
|
||||
|
|
@ -143,8 +150,9 @@ class AnalyticsController extends Controller
|
|||
foreach ($hub_data as $hub_id => $one_hub)
|
||||
{
|
||||
$c_weekday = $one_hub['c_weekday'];
|
||||
|
||||
$chart_weekday = $this->generateWeekdayData($c_weekday, $today, $overlaps);
|
||||
$chart_all_weekdays = $this->generateAllWeekData($c_weekday, $today, $overlaps);
|
||||
$chart_all_weekdays = $this->generateAllWeekData($c_weekday, $overlaps);
|
||||
|
||||
// figure out the rider schedules based on the max hour values
|
||||
$scheduler_data = $chart_all_weekdays['scheduler_data'];
|
||||
|
|
@ -153,18 +161,16 @@ class AnalyticsController extends Controller
|
|||
|
||||
$total_jos = 0;
|
||||
|
||||
// run scheduler
|
||||
// check if 2018 data is available
|
||||
if (isset($scheduler_data['2018'][$month]))
|
||||
{
|
||||
// send 2018 + month data
|
||||
$sched_res = $this->runScheduler($scheduler_data['2018'][$month]);
|
||||
// error_log(print_r($scheduler_data, true));
|
||||
|
||||
// tally total JOs for the month
|
||||
foreach ($scheduler_data['2018'][$month] as $sday_data)
|
||||
foreach ($sday_data as $shour_data)
|
||||
$total_jos += $shour_data;
|
||||
}
|
||||
// run scheduler
|
||||
$sched_res = $this->runScheduler($scheduler_data);
|
||||
|
||||
// tally total JOs for the month
|
||||
foreach ($scheduler_data as $sday_data)
|
||||
foreach ($sday_data as $shour_data)
|
||||
$total_jos += $shour_data;
|
||||
/*
|
||||
else
|
||||
{
|
||||
$sched_res = [
|
||||
|
|
@ -172,6 +178,10 @@ class AnalyticsController extends Controller
|
|||
'total_riders' => 0,
|
||||
];
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// error_log(print_r($chart_all_weekdays, true));
|
||||
|
||||
// agggregate weekday data
|
||||
$i = 0;
|
||||
|
|
@ -244,7 +254,7 @@ class AnalyticsController extends Controller
|
|||
|
||||
// error_log(print_r($args, true));
|
||||
|
||||
// error_log('running...' . $sched_script);
|
||||
error_log('running...' . $sched_script);
|
||||
|
||||
$proc = new Process($args);
|
||||
$proc->run();
|
||||
|
|
@ -253,7 +263,7 @@ class AnalyticsController extends Controller
|
|||
error_log('SCHEDULER DID NOT RUN PROPERLY');
|
||||
|
||||
$res = $proc->getOutput();
|
||||
// error_log($res);
|
||||
error_log($res);
|
||||
|
||||
|
||||
// segregate into weekdays
|
||||
|
|
@ -321,17 +331,14 @@ class AnalyticsController extends Controller
|
|||
return $data;
|
||||
}
|
||||
|
||||
protected function generateHubData($em, $hub, $distance_limit, DateTime $today, &$overlaps)
|
||||
protected function generateHubData($em, $hub, $distance_limit, DateTime $date_start, DateTime $date_end, $time_start, $time_end, &$overlaps)
|
||||
{
|
||||
$date_start = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-01 00:00:00');
|
||||
$date_end = new DateTime();
|
||||
|
||||
// get hub to analyze
|
||||
// $hub = $em->getRepository(Hub::class)->find($hub_id);
|
||||
$conn = $em->getConnection();
|
||||
|
||||
// get job order data (job orders within coverage area)
|
||||
$jos = $this->generateJobOrderData($conn, $hub, $distance_limit);
|
||||
$jos = $this->generateJobOrderData($conn, $hub, $distance_limit, $date_start, $date_end, $time_start, $time_end);
|
||||
|
||||
// initialize counters
|
||||
$c_weekday = [];
|
||||
|
|
@ -360,21 +367,22 @@ class AnalyticsController extends Controller
|
|||
$c_day[$year][$month][$day]++;
|
||||
|
||||
// weekday
|
||||
if (!isset($c_weekday[$year][$month][$weekday][$hour]))
|
||||
if (!isset($c_weekday[$weekday][$hour]))
|
||||
{
|
||||
$c_weekday[$year][$month][$weekday][$hour]['total'] = 0;
|
||||
$c_weekday[$year][$month][$weekday][$hour]['count'] = 0;
|
||||
$c_weekday[$year][$month][$weekday][$hour]['jos'] = [];
|
||||
$c_weekday[$weekday][$hour]['total'] = 0;
|
||||
$c_weekday[$weekday][$hour]['count'] = 0;
|
||||
$c_weekday[$weekday][$hour]['jos'] = [];
|
||||
}
|
||||
|
||||
$c_weekday[$year][$month][$weekday][$hour]['total']++;
|
||||
$c_weekday[$year][$month][$weekday][$hour]['jos'][$jo_id] = $jo_id;
|
||||
$c_weekday[$weekday][$hour]['total']++;
|
||||
$c_weekday[$weekday][$hour]['jos'][$jo_id] = $jo_id;
|
||||
|
||||
if (!isset($c_week_count[$year][$month][$week][$weekday][$hour]))
|
||||
// make a count of number of weeks, so we can take average
|
||||
if (!isset($c_week_count[$week][$weekday][$hour]))
|
||||
{
|
||||
// error_log('week detected - ' . $week);
|
||||
$c_week_count[$year][$month][$week][$weekday][$hour] = 1;
|
||||
$c_weekday[$year][$month][$weekday][$hour]['count']++;
|
||||
$c_week_count[$week][$weekday][$hour] = 1;
|
||||
$c_weekday[$weekday][$hour]['count']++;
|
||||
}
|
||||
|
||||
// track overlaps (jo that can be handled by more than one hub)
|
||||
|
|
@ -404,19 +412,35 @@ class AnalyticsController extends Controller
|
|||
return $params;
|
||||
}
|
||||
|
||||
protected function generateJobOrderData($conn, $hub, $distance_limit)
|
||||
protected function generateJobOrderData($conn, $hub, $distance_limit, DateTime $date_start, DateTime $date_end, $time_start, $time_end)
|
||||
{
|
||||
$hub_coord = $hub->getCoordinates();
|
||||
|
||||
// create query
|
||||
// formula to convert to km is 111195 * st_distance
|
||||
$sql = "select id, round(st_distance(coordinates, Point(:lng, :lat)) * 111195) as dist, date_schedule from job_order where st_distance(coordinates, Point(:lng, :lat)) * 111195 <= :distance_limit and status <> 'cancelled' order by date_schedule asc";
|
||||
$sql = "select id, round(st_distance(coordinates, Point(:lng, :lat)) * 111195) as dist, date_schedule from job_order where st_distance(coordinates, Point(:lng, :lat)) * 111195 <= :distance_limit and status <> 'cancelled' and date_schedule >= :date_start and date_schedule <= :date_end";
|
||||
// check if time is specified
|
||||
if (!empty($time_start))
|
||||
$sql .= ' and time(date_schedule) >= :time_start';
|
||||
if (!empty($time_end))
|
||||
$sql .= ' and time(date_schedule) <= :time_end';
|
||||
$sql .= " order by date_schedule asc";
|
||||
|
||||
|
||||
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindValue('lng', $hub_coord->getLongitude());
|
||||
$stmt->bindValue('lat', $hub_coord->getLatitude());
|
||||
$stmt->bindValue('distance_limit', $distance_limit);
|
||||
// $stmt->bindValue('date_start', $date_start->format('Y-m-d H:i:s'));
|
||||
// $stmt->bindValue('date_end', $date_end->format('Y-m-d H:i:s'));
|
||||
$stmt->bindValue('date_start', $date_start->format('Y-m-d H:i:s'));
|
||||
$stmt->bindValue('date_end', $date_end->format('Y-m-d H:i:s'));
|
||||
|
||||
if (!empty($time_start))
|
||||
$stmt->bindValue('time_start', $time_start);
|
||||
if (!empty($time_end))
|
||||
$stmt->bindValue('time_end', $time_end);
|
||||
|
||||
$stmt->execute();
|
||||
$jos = $stmt->fetchAll();
|
||||
|
||||
|
|
@ -461,7 +485,7 @@ class AnalyticsController extends Controller
|
|||
return $chart_year;
|
||||
}
|
||||
|
||||
protected function generateAllWeekData($all_weekday_data, $today, $overlaps)
|
||||
protected function generateAllWeekData($all_weekday_data, $overlaps)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
|
|
@ -470,53 +494,56 @@ class AnalyticsController extends Controller
|
|||
for ($i = 0; $i < 24; $i++)
|
||||
$hours[] = sprintf('%02d', $i);
|
||||
|
||||
$month = $today->format('m');
|
||||
$year_data = [];
|
||||
// TODO: substitute this
|
||||
$year_data = $all_weekday_data;
|
||||
$scheduler_data = [];
|
||||
|
||||
/*
|
||||
error_log('----------------------------------------------------------------------');
|
||||
error_log(print_r($all_weekday_data, true));
|
||||
error_log('----------------------------------------------------------------------');
|
||||
*/
|
||||
|
||||
// gather maximum for each hour
|
||||
foreach ($this->weekdays as $weekday)
|
||||
{
|
||||
foreach ($all_weekday_data as $year => $year_data)
|
||||
// go through the hours
|
||||
foreach ($hours as $hour)
|
||||
{
|
||||
// go through the hours
|
||||
foreach ($hours as $hour)
|
||||
$id = $hour + 0;
|
||||
if (!isset($data[$id]))
|
||||
$data[$id] = [
|
||||
'hour' => $hour,
|
||||
];
|
||||
|
||||
// get hour data
|
||||
$prefix = $weekday;
|
||||
if (isset($year_data[$weekday][$hour]))
|
||||
{
|
||||
$id = $hour + 0;
|
||||
if (!isset($data[$id]))
|
||||
$data[$id] = [
|
||||
'hour' => $hour,
|
||||
];
|
||||
// calculate the rider value for each JO and use that score as basis
|
||||
$total_rv = $this->calculateTotalRiderValue($year_data[$weekday][$hour]['jos'], $overlaps);
|
||||
$rv_average = ceil($total_rv / $year_data[$weekday][$hour]['count']);
|
||||
|
||||
// get hour data
|
||||
$year_id = 'y' . $year;
|
||||
$prefix = $year_id . '_' . $weekday;
|
||||
if (isset($year_data[$month][$weekday][$hour]))
|
||||
$data[$id][$prefix] = $year_data[$weekday][$hour]['total'];
|
||||
$data[$id][$prefix . '_count'] = $year_data[$weekday][$hour]['count'];
|
||||
$data[$id][$prefix . '_average'] = ceil($year_data[$weekday][$hour]['total'] / $year_data[$weekday][$hour]['count']);
|
||||
$data[$id][$prefix . '_rv_average'] = $rv_average;
|
||||
|
||||
// assign scheduler data
|
||||
$scheduler_data[$weekday][$hour] = $rv_average;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($scheduler_data[$weekday][$hour]))
|
||||
{
|
||||
// calculate the rider value for each JO and use that score as basis
|
||||
$total_rv = $this->calculateTotalRiderValue($year_data[$month][$weekday][$hour]['jos'], $overlaps);
|
||||
$rv_average = ceil($total_rv / $year_data[$month][$weekday][$hour]['count']);
|
||||
|
||||
$data[$id][$prefix] = $year_data[$month][$weekday][$hour]['total'];
|
||||
$data[$id][$prefix . '_count'] = $year_data[$month][$weekday][$hour]['count'];
|
||||
$data[$id][$prefix . '_average'] = ceil($year_data[$month][$weekday][$hour]['total'] / $year_data[$month][$weekday][$hour]['count']);
|
||||
$data[$id][$prefix . '_rv_average'] = $rv_average;
|
||||
|
||||
// assign scheduler data
|
||||
$scheduler_data[$year][$month][$weekday][$hour] = $rv_average;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($scheduler_data[$year][$month][$weekday][$hour]))
|
||||
{
|
||||
$data[$id][$prefix . '_rv_average'] = 0;
|
||||
$scheduler_data[$year][$month][$weekday][$hour] = 0;
|
||||
}
|
||||
$data[$id][$prefix . '_rv_average'] = 0;
|
||||
$scheduler_data[$weekday][$hour] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$data['scheduler_data'] = $scheduler_data;
|
||||
|
||||
// error_log(print_r($data, true));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
25
src/Ramcar/CMBTransactionOrigin.php
Normal file
25
src/Ramcar/CMBTransactionOrigin.php
Normal 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',
|
||||
];
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
|
||||
|
|
@ -443,11 +443,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 +554,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 +600,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)
|
||||
|
|
@ -1447,9 +1443,20 @@ 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['discounts'] = $this->generateDiscountOptions();
|
||||
$params['current_date'] = new DateTime();
|
||||
|
||||
$this->fillDropdownParameters($params);
|
||||
$this->fillFormTags($params);
|
||||
|
|
@ -1470,6 +1477,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$params['mode'] = 'onestep-edit';
|
||||
$params['cvid'] = $obj->getCustomerVehicle()->getID();
|
||||
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
|
||||
$params['discounts'] = $this->generateDiscountOptions();
|
||||
$params['current_date'] = new DateTime();
|
||||
|
||||
// get service charges
|
||||
$sc_array = [];
|
||||
|
|
@ -1487,6 +1496,47 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
|
||||
$params['jo_service_charges'] = $sc_array;
|
||||
|
||||
// get odometer
|
||||
$odometer = $obj->getMeta('odometer');
|
||||
|
||||
$params['odometer'] = $odometer;
|
||||
|
||||
// get customer email used in JO
|
||||
$email = $obj->getMeta('customer_email');
|
||||
|
||||
$params['email'] = $email;
|
||||
|
||||
// get images if any
|
||||
$jo_extra = $obj->getJOExtra();
|
||||
$pic_array = [];
|
||||
$params['signature'] = null;
|
||||
if ($jo_extra != null)
|
||||
{
|
||||
$a_speed_img = $jo_extra->getAfterSpeedImageFilename();
|
||||
$a_plate_img = $jo_extra->getAfterPlateNumImageFilename();
|
||||
$a_batt_img = $jo_extra->getAfterBattImageFilename();
|
||||
|
||||
$a_other_images = $jo_extra->getAfterOtherImages();
|
||||
|
||||
$cust_signature = $jo_extra->getCustomerSignature();
|
||||
|
||||
if ($a_speed_img != null)
|
||||
$pic_array['after_speed_img'] = $a_speed_img;
|
||||
if ($a_plate_img != null)
|
||||
$pic_array['after_plate_img'] = $a_plate_img;
|
||||
if ($a_batt_img != null)
|
||||
$pic_array['after_batt_img'] = $a_batt_img;
|
||||
|
||||
foreach ($a_other_images as $a_img)
|
||||
{
|
||||
$pic_array['a_other_images'][] = $a_img;
|
||||
}
|
||||
|
||||
$params['signature'] = $cust_signature;
|
||||
}
|
||||
|
||||
$params['jo_pictures'] = $pic_array;
|
||||
|
||||
$this->fillDropdownParameters($params);
|
||||
$this->fillFormTags($params);
|
||||
|
||||
|
|
@ -1547,6 +1597,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$params['mode'] = 'open_edit';
|
||||
$params['cvid'] = $jo->getCustomerVehicle()->getID();
|
||||
$params['vid'] = $jo->getCustomerVehicle()->getVehicle()->getID();
|
||||
$params['discounts'] = $this->generateDiscountOptions();
|
||||
|
||||
$this->fillDropdownParameters($params);
|
||||
$this->fillFormTags($params);
|
||||
|
|
@ -1609,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');
|
||||
|
|
@ -2449,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);
|
||||
|
|
@ -2479,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))
|
||||
|
|
@ -2585,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))
|
||||
|
|
@ -2606,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')
|
||||
|
|
@ -2741,6 +2798,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
|||
$params['mode'] = 'walk-in-edit';
|
||||
$params['cvid'] = $obj->getCustomerVehicle()->getID();
|
||||
$params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID();
|
||||
$params['discounts'] = $this->generateDiscountOptions();
|
||||
$params['current_date'] = new DateTime();
|
||||
|
||||
$this->fillDropdownParameters($params);
|
||||
$this->fillFormTags($params);
|
||||
|
|
@ -2778,7 +2837,7 @@ 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();
|
||||
}
|
||||
|
||||
protected function initFormTags(&$params)
|
||||
|
|
@ -3064,9 +3123,15 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -666,13 +666,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,
|
||||
|
|
@ -682,19 +675,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());
|
||||
|
|
@ -764,7 +744,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
|||
'odometer' => $odo,
|
||||
|
||||
// images
|
||||
'arrive_photos' => $before_images,
|
||||
'finish_photos' => $after_images,
|
||||
|
||||
// customer email
|
||||
|
|
@ -1534,6 +1513,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();
|
||||
|
|
@ -1567,169 +1555,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 = [
|
||||
|
|
|
|||
|
|
@ -31,16 +31,42 @@
|
|||
|
||||
<div class="m-portlet__body">
|
||||
<div class="form-group m-form__group row no-border">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="date">Date</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="date" id="date" class="form-control m-input" value="{{ "now"|date('d M Y') }}" readonly placeholder="Select a date" >
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-calendar glyphicon-th"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-control-feedback hide" data-field="date"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="time_from">Restrict Time From</label>
|
||||
<div class="input-group">
|
||||
<input type="time" name="time_from" id="time_from" class="form-control m-input" value="">
|
||||
</div>
|
||||
<div class="form-control-feedback hide" data-field="date_from"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="time_to">Restrict Time To</label>
|
||||
<div class="input-group">
|
||||
<input type="time" name="time_to" id="time_to" class="form-control m-input" value="">
|
||||
</div>
|
||||
<div class="form-control-feedback hide" data-field="date_from"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group m-form__group row no-border">
|
||||
<div class="col-lg-6">
|
||||
<label data-field="date_from">Date From</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="date_from" id="date_from" class="form-control m-input" value="{{ "now"|date('d M Y') }}" readonly placeholder="Select a date" >
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-calendar glyphicon-th"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-control-feedback hide" data-field="date_from"></div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<label data-field="date_to">Date To</label>
|
||||
<div class="input-group date dp">
|
||||
<input type="text" name="date_to" id="date_to" class="form-control m-input" value="{{ "now"|date('d M Y') }}" readonly placeholder="Select a date" >
|
||||
<span class="input-group-addon">
|
||||
<i class="la la-calendar glyphicon-th"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-control-feedback hide" data-field="date_to"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for hub_id in default_hubs %}
|
||||
|
|
|
|||
|
|
@ -330,49 +330,49 @@ var lmon = chart2.series.push(new am4charts.LineSeries());
|
|||
lmon.name = "Monday";
|
||||
lmon.stroke = am4core.color("#003f5c");
|
||||
lmon.strokeWidth = 2;
|
||||
lmon.dataFields.valueY = "y2018_Monday_rv_average";
|
||||
lmon.dataFields.valueY = "Monday_rv_average";
|
||||
lmon.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Tuesday";
|
||||
l.stroke = am4core.color("#374c80");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Tuesday_rv_average";
|
||||
l.dataFields.valueY = "Tuesday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Wednesday";
|
||||
l.stroke = am4core.color("#7a5195");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Wednesday_rv_average";
|
||||
l.dataFields.valueY = "Wednesday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Thursday";
|
||||
l.stroke = am4core.color("#bc5090");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Thursday_rv_average";
|
||||
l.dataFields.valueY = "Thursday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Friday";
|
||||
l.stroke = am4core.color("#ef5675");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Friday_rv_average";
|
||||
l.dataFields.valueY = "Friday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Saturday";
|
||||
l.stroke = am4core.color("#ff764a");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Saturday_rv_average";
|
||||
l.dataFields.valueY = "Saturday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
var l = chart2.series.push(new am4charts.LineSeries());
|
||||
l.name = "Sunday";
|
||||
l.stroke = am4core.color("#ffa600");
|
||||
l.strokeWidth = 2;
|
||||
l.dataFields.valueY = "y2018_Sunday_rv_average";
|
||||
l.dataFields.valueY = "Sunday_rv_average";
|
||||
l.dataFields.categoryX = "hour";
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -278,7 +278,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 +288,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>
|
||||
|
|
@ -492,6 +492,70 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% if mode in ['onestep-edit'] %}
|
||||
<div class="m-form__seperator m-form__seperator--dashed"></div>
|
||||
<div class="m-form__section">
|
||||
<div class="m-form__heading">
|
||||
<h3 class="m-form__heading-title">
|
||||
Other Information
|
||||
</h3>
|
||||
</div>
|
||||
<div class="form-group m-form__group row">
|
||||
<div class="col-lg-3">
|
||||
<label data-field="odometer">Odometer Reading</label>
|
||||
<input type="text" name="odometer" id="odometer" class="form-control m-input other_info_field" value="{{ odometer }}" disabled>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label data-field="email">Email Address</label>
|
||||
<input type="text" name="email" id="email" class="form-control m-input other_info_field" value="{{ email }}" disabled>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<label> Customer Signature </label>
|
||||
<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 After Service</label>
|
||||
</div>
|
||||
{% for key, picture in jo_pictures %}
|
||||
{% if key == 'after_speed_img' %}
|
||||
<div class="col-lg-2">
|
||||
<label> Speedometer after Service </label>
|
||||
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ picture }}');" ></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if key == 'after_plate_img' %}
|
||||
<div class="col-lg-2">
|
||||
<label> Plate Number after Service </label>
|
||||
<div class="portrait-box" style="background-image: url('{{ '/uploads/jo_extra/' ~ picture }}');" ></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if key == 'after_batt_img' %}
|
||||
<div class="col-lg-2">
|
||||
<label> Battery after 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 after Service</label>
|
||||
</div>
|
||||
{% for key, picture in jo_pictures %}
|
||||
{% if key == 'a_other_images' %}
|
||||
{% for pic in jo_pictures['a_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>
|
||||
{% endif %}
|
||||
|
||||
<div class="m-form__seperator m-form__seperator--dashed"></div>
|
||||
<div class="m-form__section" id="sc-section">
|
||||
<div class="m-form__heading">
|
||||
|
|
@ -541,7 +605,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>
|
||||
|
|
@ -551,10 +615,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">
|
||||
|
|
@ -1052,6 +1135,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;
|
||||
|
|
@ -1214,6 +1298,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 %}
|
||||
|
|
@ -1437,7 +1522,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
|
||||
|
|
@ -1781,6 +1867,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 %}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,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 +288,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 +392,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 +402,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 +739,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 +1107,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 %}
|
||||
|
|
|
|||
Loading…
Reference in a new issue