Merge branch 'master' of gitlab.com:jankstudio/resq

This commit is contained in:
Kendrick Chan 2018-02-01 01:36:08 +08:00
commit 83a162b4ab
25 changed files with 520 additions and 408 deletions

View file

@ -635,7 +635,7 @@ class APIController extends Controller
'size_id' => $batt->getSize()->getID(),
'size_name' => $batt->getSize()->getName(),
'price' => $batt->getSellingPrice(),
'wty_personal' => $batt->getWarrantyPersonal(),
'wty_private' => $batt->getWarrantyPrivate(),
'wty_commercial' => $batt->getWarrantyCommercial(),
];
}

View file

@ -116,7 +116,7 @@ class BatteryController extends BaseController
$row['size_name'] = $orow['size_name'];
$row['prod_code'] = $orow[0]->getProductCode();
$row['sell_price'] = $orow[0]->getSellingPrice();
$row['warr_personal'] = $orow[0]->getWarrantyPersonal();
$row['warr_private'] = $orow[0]->getWarrantyPrivate();
$row['warr_commercial'] = $orow[0]->getWarrantyCommercial();
$row['res_capacity'] = $orow[0]->getReserveCapacity();
$row['length'] = $orow[0]->getLength();
@ -176,7 +176,7 @@ class BatteryController extends BaseController
// set and save values
$row->setProductCode($req->request->get('prod_code'))
->setWarrantyPersonal($req->request->get('warr_personal'))
->setWarrantyPrivate($req->request->get('warr_private'))
->setWarrantyCommercial($req->request->get('warr_commercial'))
->setReserveCapacity($req->request->get('res_capacity'))
->setLength($req->request->get('length'))
@ -296,7 +296,7 @@ class BatteryController extends BaseController
// set and save values
$row->setProductCode($req->request->get('prod_code'))
->setWarrantyPersonal($req->request->get('warr_personal'))
->setWarrantyPrivate($req->request->get('warr_private'))
->setWarrantyCommercial($req->request->get('warr_commercial'))
->setReserveCapacity($req->request->get('res_capacity'))
->setLength($req->request->get('length'))

View file

@ -289,7 +289,10 @@ class BatteryManufacturerController extends BaseController
'mfg_name' => $battery->getManufacturer()->getName(),
'model_name' => $battery->getModel()->getName(),
'size_name' => $battery->getSize()->getName(),
'prod_code' => $battery->getProductCode()
'prod_code' => $battery->getProductCode(),
'sell_price' => $battery->getSellingPrice(),
'warr_private' => $battery->getWarrantyPrivate(),
'warr_commercial' => $battery->getWarrantyCommercial(),
];
}

View file

@ -3,6 +3,7 @@
namespace App\Controller;
use App\Ramcar\BaseController;
use App\Ramcar\CustomerClassification;
use App\Ramcar\FuelType;
use App\Ramcar\VehicleStatusCondition;
use App\Entity\Customer;
@ -103,10 +104,19 @@ class CustomerController extends BaseController
// process rows
$rows = [];
foreach ($obj_rows as $orow) {
$classifications = CustomerClassification::getCollection();
// add row data
$row['id'] = $orow->getID();
$row['first_name'] = $orow->getFirstName();
$row['last_name'] = $orow->getLastName();
$row['customer_classification'] = $classifications[$orow->getCustomerClassification()];
$row['flag_mobile_app'] = $orow->hasMobileApp();
$row['app_mobile_number'] = $orow->hasMobileApp() && !empty($orow->getMobileSessions()) ? $orow->getMobileSessions()[0]->getPhoneNumber() : '';
// TODO: properly add mobile numbers and plate numbers as searchable/sortable fields, use doctrine events
$row['mobile_numbers'] = implode("<br>", $orow->getMobileNumberList());
$row['plate_numbers'] = implode("<br>", $orow->getPlateNumberList());
// add row metadata
$row['meta'] = [
@ -143,6 +153,7 @@ class CustomerController extends BaseController
// get parent associations
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
$params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll();
$params['classifications'] = CustomerClassification::getCollection();
$params['fuel_types'] = FuelType::getCollection();
$params['status_conditions'] = VehicleStatusCondition::getCollection();
@ -163,8 +174,8 @@ class CustomerController extends BaseController
// set and save values
$row->setFirstName($req->request->get('first_name'))
->setLastName($req->request->get('last_name'))
->setCustomerNotes($req->request->get('customer_notes'))
->setConfirmed(false);
->setCustomerClassification($req->request->get('customer_classification'))
->setCustomerNotes($req->request->get('customer_notes'));
// initialize error lists
$error_array = [];
@ -317,6 +328,7 @@ class CustomerController extends BaseController
// get parent associations
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
$params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll();
$params['classifications'] = CustomerClassification::getCollection();
$params['fuel_types'] = FuelType::getCollection();
$params['status_conditions'] = VehicleStatusCondition::getCollection();
@ -343,6 +355,7 @@ class CustomerController extends BaseController
// set and save values
$row->setFirstName($req->request->get('first_name'))
->setLastName($req->request->get('last_name'))
->setCustomerClassification($req->request->get('customer_classification'))
->setCustomerNotes($req->request->get('customer_notes'));
// initialize error lists
@ -716,6 +729,7 @@ class CustomerController extends BaseController
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
$query->where('q.first_name LIKE :filter')
->orWhere('q.last_name LIKE :filter')
->orWhere('q.customer_classification LIKE :filter')
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}
}

View file

@ -84,6 +84,7 @@ class HubController extends BaseController
// add row data
$row['id'] = $orow->getID();
$row['name'] = $orow->getName();
$row['branch'] = $orow->getBranch();
$row['address'] = $orow->getAddress();
$row['contact_nums'] = $orow->getContactNumbers();
$row['time_open'] = $orow->getTimeOpen()->format('g:i A');
@ -135,6 +136,7 @@ class HubController extends BaseController
// set and save values
$obj->setName($req->request->get('name'))
->setBranch($req->request->get('branch'))
->setAddress($req->request->get('address'))
->setContactNumbers($req->request->get('contact_nums'))
->setTimeOpen($time_open)

View file

@ -5,6 +5,7 @@ namespace App\Controller;
use App\Ramcar\BaseController;
use App\Ramcar\ServiceType;
use App\Ramcar\JOStatus;
use App\Ramcar\WarrantyClass;
use App\Entity\JobOrder;
use App\Entity\BatteryManufacturer;
use App\Entity\Customer;
@ -43,6 +44,7 @@ class JobOrderController extends BaseController
$params['outlet'] = $em->getRepository(Outlet::class)->findAll();
$params['rider'] = $em->getRepository(Rider::class)->findAll();
$params['service_types'] = ServiceType::getCollection();
$params['warranty_classes'] = WarrantyClass::getCollection();
$params['statuses'] = JOStatus::getCollection();
// response
@ -88,6 +90,7 @@ class JobOrderController extends BaseController
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
->setCreatedBy($this->getUser())
->setServiceType($req->request->get('service_type'))
->setWarrantyClass($req->request->get('warranty_class'))
->setCustomer($cust_vehicle->getCustomer())
->setCustomerVehicle($cust_vehicle)
->setSource('web')
@ -188,9 +191,7 @@ class JobOrderController extends BaseController
$datatable = $req->request->get('datatable');
// count total records
$tquery = $qb->select('COUNT(q)')
->join('q.cus_vehicle', 'cv')
->join('q.customer', 'c');
$tquery = $qb->select('COUNT(q)');
$this->setQueryFilters($datatable, $tquery, $qb, $tier_params['jo_status']);
@ -214,22 +215,14 @@ class JobOrderController extends BaseController
];
// build query
$query = $qb->select('q')
->addSelect('cv.plate_number as plate_number')
->addSelect('c.first_name as customer_name')
->addSelect('c.last_name as cust_last_name');
$query = $qb->select('q');
$this->setQueryFilters($datatable, $query, $qb, $tier_params['jo_status']);
// check if sorting is present, otherwise use default
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
$prefix = '';
if (!in_array($datatable['sort']['field'], ['plate_number', 'customer_name']))
$prefix = 'q.';
$order = $datatable['sort']['sort'] ?? 'asc';
$query->orderBy($prefix . $datatable['sort']['field'], $order);
$query->orderBy('q.' . $datatable['sort']['field'], $order);
} else {
$query->orderBy('q.date_schedule', 'asc');
}
@ -243,26 +236,16 @@ class JobOrderController extends BaseController
// process rows
$rows = [];
foreach ($obj_rows as $orow) {
// get service type name
$service_type = false;
$statuses = JOStatus::getCollection();
$service_types = ServiceType::getCollection();
foreach ($service_types as $key => $service) {
if ($key == $orow[0]->getServiceType()) {
$service_type = $service;
break;
}
}
// add row data
$row['id'] = $orow[0]->getID();
$row['date_schedule'] = $orow[0]->getDateSchedule()->format("d M Y");
$row['date_schedule_time'] = $orow[0]->getDateSchedule()->format("g:i A");
$row['service_type'] = $service_type;
$row['plate_number'] = $orow['plate_number'];
$row['customer_name'] = $orow['customer_name'] . " " . $orow['cust_last_name'];
$row['mobile_numbers'] = implode("<br>", $orow[0]->getCustomer()->getMobileNumberList());
$row['source'] = ucfirst($orow[0]->getSource());
$row['flag_advance'] = $orow[0]->isAdvanceOrder();
$row['id'] = $orow->getID();
$row['delivery_address'] = $orow->getDeliveryAddress();
$row['date_schedule'] = $orow->isAdvanceOrder() ? $orow->getDateSchedule()->format("d M Y g:i A") : 'Immediate';
$row['service_type'] = $service_types[$orow->getServiceType()];
$row['status'] = $statuses[$orow->getStatus()];
$row['flag_advance'] = $orow->isAdvanceOrder();
// add crud urls
$row['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $row['id']]);
@ -296,6 +279,7 @@ class JobOrderController extends BaseController
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
$params['customers'] = $em->getRepository(Customer::class)->findAll();
$params['service_types'] = ServiceType::getCollection();
$params['warranty_classes'] = WarrantyClass::getCollection();
$params['statuses'] = JOStatus::getCollection();
// get closest outlets
@ -378,6 +362,7 @@ class JobOrderController extends BaseController
->setCoordinates($point)
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
->setServiceType($req->request->get('service_type'))
->setWarrantyClass($req->request->get('warranty_class'))
->setSource('web')
->setStatus($req->request->get('status'))
->setDeliveryInstructions($req->request->get('delivery_instructions'))
@ -431,6 +416,7 @@ class JobOrderController extends BaseController
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
$params['customers'] = $em->getRepository(Customer::class)->findAll();
$params['service_types'] = ServiceType::getCollection();
$params['warranty_classes'] = WarrantyClass::getCollection();
$params['statuses'] = JOStatus::getCollection();
// get closest outlets
@ -513,6 +499,7 @@ class JobOrderController extends BaseController
->setCoordinates($point)
->setAdvanceOrder($req->request->get('flag_advance') ?? false)
->setServiceType($req->request->get('service_type'))
->setWarrantyClass($req->request->get('warranty_class'))
->setSource('web')
->setStatus($req->request->get('status'))
->setDeliveryInstructions($req->request->get('delivery_instructions'))

View file

@ -96,6 +96,7 @@ class OutletController extends BaseController
// add row data
$row['id'] = $orow[0]->getID();
$row['name'] = $orow[0]->getName();
$row['branch'] = $orow[0]->getBranch();
$row['address'] = $orow[0]->getAddress();
$row['contact_nums'] = $orow[0]->getContactNumbers();
$row['time_open'] = $orow[0]->getTimeOpen()->format('g:i A');
@ -153,6 +154,7 @@ class OutletController extends BaseController
// set and save values
$obj->setName($req->request->get('name'))
->setBranch($req->request->get('branch'))
->setAddress($req->request->get('address'))
->setContactNumbers($req->request->get('contact_nums'))
->setTimeOpen($time_open)
@ -165,6 +167,7 @@ class OutletController extends BaseController
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
$query->where('hub.name LIKE :filter')
->orWhere('q.name LIKE :filter')
->orWhere('q.branch LIKE :filter')
->orWhere('q.address LIKE :filter')
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}

View file

@ -71,7 +71,7 @@ class Battery
* @ORM\Column(type="smallint")
* @Assert\NotBlank()
*/
protected $warr_personal;
protected $warr_private;
// warranty commercial
/**
@ -118,6 +118,8 @@ class Battery
// selling price (vat inclusive)
/**
* @ORM\Column(type="decimal", precision=7, scale=2, nullable=true)
* @Assert\NotBlank()
* @Assert\Range(min=0, minMessage="This value should be a valid number.")
*/
protected $sell_price;
@ -193,15 +195,15 @@ class Battery
return $this->prod_code;
}
public function setWarrantyPersonal($warr_personal)
public function setWarrantyPrivate($warr_private)
{
$this->warr_personal = $warr_personal;
$this->warr_private = $warr_private;
return $this;
}
public function getWarrantyPersonal()
public function getWarrantyPrivate()
{
return $this->warr_personal;
return $this->warr_private;
}
public function setWarrantyCommercial($warr_commercial)

View file

@ -34,6 +34,13 @@ class Customer
*/
protected $last_name;
// customer classification
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $customer_classification;
/**
* @ORM\Column(type="text", length=80)
*/
@ -75,12 +82,21 @@ class Customer
*/
protected $flag_confirmed;
// if registered on mobile app
/**
* @ORM\Column(type="boolean")
*/
protected $flag_mobile_app;
public function __construct()
{
$this->numbers = new ArrayCollection();
$this->sessions = new ArrayCollection();
$this->vehicles = new ArrayCollection();
$this->job_orders = new ArrayCollection();
$this->flag_confirmed = false;
$this->flag_mobile_app = false;
}
public function getID()
@ -110,6 +126,17 @@ class Customer
return $this->last_name;
}
public function setCustomerClassification($customer_classification)
{
$this->customer_classification = $customer_classification;
return $this;
}
public function getCustomerClassification()
{
return $this->customer_classification;
}
public function setCustomerNotes($customer_notes)
{
$this->customer_notes = $customer_notes;
@ -147,6 +174,15 @@ class Customer
return $numbers;
}
public function getPlateNumberList()
{
$plate_numbers = [];
foreach ($this->vehicles as $vehicle)
$plate_numbers[] = $vehicle->getPlateNumber();
return $plate_numbers;
}
public function addMobileSession(MobileSession $session)
{
$this->sessions->add($session);
@ -192,6 +228,17 @@ class Customer
return $this->flag_confirmed;
}
public function setHasMobileApp($flag_mobile_app = true)
{
$this->flag_mobile_app = $flag_mobile_app;
return $this;
}
public function hasMobileApp()
{
return $this->flag_mobile_app;
}
public function getJobOrders()
{
return $this->job_orders;

View file

@ -2,64 +2,20 @@
namespace App\Entity;
use App\Ramcar\Location;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="hub")
*/
class Hub
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// name of hub
/**
* @ORM\Column(type="string", length=80)
*/
protected $name;
// address
/**
* @ORM\Column(type="string", length=80)
*/
protected $address;
// address coordinates
/**
* @ORM\Column(type="point")
*/
protected $coordinates;
// contact numbers
// this is displayed in a textarea
/**
* @ORM\Column(type="string", length=200)
*/
protected $contact_nums;
// opening time
/**
* @ORM\Column(type="time")
*/
protected $time_open;
// closing time
/**
* @ORM\Column(type="time")
*/
protected $time_close;
use Location;
// riders assigned to this hub
/**
@ -75,81 +31,10 @@ class Hub
public function __construct()
{
$this->riders = new ArrayCollection();
$this->time_open = new DateTime();
$this->time_close = new DateTime();
}
public function getID()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setAddress($address)
{
$this->address = $address;
return $this;
}
public function getAddress()
{
return $this->address;
}
public function setCoordinates(Point $point)
{
$this->coordinates = $point;
return $this;
}
public function getCoordinates()
{
return $this->coordinates;
}
public function setContactNumbers($nums)
{
$this->contact_nums = $nums;
return $this;
}
public function getContactNumbers()
{
return $this->contact_nums;
}
public function setTimeOpen(DateTime $time_open)
{
$this->time_open = $time_open;
return $this;
}
public function getTimeOpen()
{
return $this->time_open;
}
public function setTimeClose(DateTime $time_close)
{
$this->time_close = $time_close;
return $this;
}
public function getTimeClose()
{
return $this->time_close;
$this->riders = new ArrayCollection();
$this->outlets = new ArrayCollection();
}
public function getRiders()

View file

@ -86,6 +86,12 @@ class JobOrder
*/
protected $service_type;
// warranty class
/**
* @ORM\Column(type="string", length=25)
*/
protected $warranty_class;
// customer that requested job order
/**
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="job_orders")
@ -142,7 +148,8 @@ class JobOrder
// delivery address
/**
* @ORM\Column(type="text", nullable=true)
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
protected $delivery_address;
@ -259,6 +266,17 @@ class JobOrder
return $this->service_type;
}
public function setWarrantyClass($warranty_class)
{
$this->warranty_class = $warranty_class;
return $this;
}
public function getWarrantyClass()
{
return $this->warranty_class;
}
public function setCustomer(Customer $customer)
{
$this->customer = $customer;

View file

@ -2,11 +2,11 @@
namespace App\Entity;
use App\Ramcar\Location;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use DateTime;
/**
@ -15,55 +15,7 @@ use DateTime;
*/
class Outlet
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// name of enrollee
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $name;
// address
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $address;
// address coordinates
/**
* @ORM\Column(type="point")
*/
protected $coordinates;
// contact numbers
// this is displayed in a textarea
/**
* @ORM\Column(type="string", length=200)
* @Assert\NotBlank()
*/
protected $contact_nums;
// opening time
/**
* @ORM\Column(type="time")
* @Assert\NotBlank()
*/
protected $time_open;
// closing time
/**
* @ORM\Column(type="time")
* @Assert\NotBlank()
*/
protected $time_close;
use Location;
// job orders assigned to outlet
/**
@ -81,78 +33,12 @@ class Outlet
{
$this->time_open = new DateTime();
$this->time_close = new DateTime();
$this->job_orders = new ArrayCollection();
}
public function getID()
public function getJobOrders()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setAddress($address)
{
$this->address = $address;
return $this;
}
public function getAddress()
{
return $this->address;
}
public function setCoordinates(Point $point)
{
$this->coordinates = $point;
return $this;
}
public function getCoordinates()
{
return $this->coordinates;
}
public function setContactNumbers($nums)
{
$this->contact_nums = $nums;
return $this;
}
public function getContactNumbers()
{
return $this->contact_nums;
}
public function setTimeOpen(DateTime $time_open)
{
$this->time_open = $time_open;
return $this;
}
public function getTimeOpen()
{
return $this->time_open;
}
public function setTimeClose(DateTime $time_close)
{
$this->time_close = $time_close;
return $this;
}
public function getTimeClose()
{
return $this->time_close;
return $this->job_orders;
}
public function setHub(Hub $hub)

View file

@ -0,0 +1,20 @@
<?php
namespace App\Ramcar;
class CustomerClassification extends NameValue
{
const REGULAR = 'regular';
const MEDIA = 'media';
const VIP = 'vip';
const BLACKLISTED = 'blacklisted';
const OTHER = 'other';
const COLLECTION = [
'regular' => 'Regular',
'media' => 'Media',
'vip' => 'VIP',
'blacklisted' => 'Blacklisted',
'other' => 'Other',
];
}

151
src/Ramcar/Location.php Normal file
View file

@ -0,0 +1,151 @@
<?php
namespace App\Ramcar;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use DateTime;
trait Location
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// name of location
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $name;
// branch name
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $branch;
// address
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $address;
// address coordinates
/**
* @ORM\Column(type="point")
*/
protected $coordinates;
// contact numbers
// this is displayed in a textarea
/**
* @ORM\Column(type="string", length=200)
* @Assert\NotBlank()
*/
protected $contact_nums;
// opening time
/**
* @ORM\Column(type="time")
* @Assert\NotBlank()
*/
protected $time_open;
// closing time
/**
* @ORM\Column(type="time")
* @Assert\NotBlank()
*/
protected $time_close;
public function getID()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setBranch($branch)
{
$this->branch = $branch;
return $this;
}
public function getBranch()
{
return $this->branch;
}
public function setAddress($address)
{
$this->address = $address;
return $this;
}
public function getAddress()
{
return $this->address;
}
public function setCoordinates(Point $point)
{
$this->coordinates = $point;
return $this;
}
public function getCoordinates()
{
return $this->coordinates;
}
public function setContactNumbers($nums)
{
$this->contact_nums = $nums;
return $this;
}
public function getContactNumbers()
{
return $this->contact_nums;
}
public function setTimeOpen(DateTime $time_open)
{
$this->time_open = $time_open;
return $this;
}
public function getTimeOpen()
{
return $this->time_open;
}
public function setTimeClose(DateTime $time_close)
{
$this->time_close = $time_close;
return $this;
}
public function getTimeClose()
{
return $this->time_close;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Ramcar;
class WarrantyClass extends NameValue
{
const WTY_PRIVATE = 'private';
const WTY_COMMERCIAL = 'commercial';
const COLLECTION = [
'private' => 'Private',
'commercial' => 'Commercial',
];
}

View file

@ -114,11 +114,11 @@
</div>
<div class="form-group m-form__group row">
<div class="col-lg-4">
<label data-field="warr_personal">
<label data-field="warr_private">
Personal
</label>
<input type="number" name="warr_personal" class="form-control m-input" value="{{ obj.getWarrantyPersonal() }}">
<div class="form-control-feedback hide" data-field="warr_personal"></div>
<input type="number" name="warr_private" class="form-control m-input" value="{{ obj.getWarrantyPrivate() }}">
<div class="form-control-feedback hide" data-field="warr_private"></div>
<span class="m-form__help">In months</span>
</div>
<div class="col-lg-4">

View file

@ -83,14 +83,16 @@
title: 'ID',
width: 30
},
/*
{
field: 'mfg_name',
title: 'Manufacturer',
width: 150
},
*/
{
field: 'model_name',
title: 'Model',
title: 'Brand',
width: 150
},
{
@ -98,14 +100,16 @@
title: 'Size',
width: 100
},
/*
{
field: 'prod_code',
title: 'Product Code',
width: 150
},
*/
{
field: 'warr_personal',
title: 'Personal Wty.',
field: 'warr_private',
title: 'Private Wty.',
width: 170
},
{
@ -115,7 +119,7 @@
},
{
field: 'sell_price',
title: 'SRP'
title: 'Price'
},
{
field: 'Actions',

View file

@ -53,23 +53,34 @@
<div class="tab-content">
<div class="tab-pane active" id="customer-info" role="tabpanel">
<div class="form-group m-form__group row">
<div class="col-lg-6">
<div class="col-lg-4">
<label data-field="first_name">
First Name
</label>
<input type="text" name="first_name" class="form-control m-input" value="{{ obj.getFirstName() }}" data-name="first_name">
<div class="form-control-feedback hide" data-field="first_name"></div>
</div>
<div class="col-lg-6">
<div class="col-lg-4">
<label data-field="last_name">
Last Name
</label>
<input type="text" name="last_name" class="form-control m-input" value="{{ obj.getLastName() }}" data-name="last_name">
<div class="form-control-feedback hide" data-field="last_name"></div>
</div>
<div class="col-lg-4">
<label data-field="customer_classification">
Customer Classification
</label>
<select name="customer_classification" class="form-control m-input">
{% for key, classification in classifications %}
<option value="{{ key }}"{{ obj.getCustomerClassification == key ? ' selected' }}>{{ classification }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="customer_classification"></div>
</div>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-6">
<div class="col-lg-4">
<label data-field="customer_notes">
Customer Notes
</label>

View file

@ -91,6 +91,20 @@
field: 'last_name',
title: 'Last Name'
},
{
field: 'customer_classification',
title: 'Classification'
},
{
field: 'mobile_numbers',
title: 'Mobile Numbers',
sortable: false
},
{
field: 'plate_numbers',
title: 'Plate Numbers',
sortable: false
},
{
field: 'flag_confirmed',
title: 'Status',
@ -106,6 +120,25 @@
return tag;
}
},
{
field: 'flag_mobile_app',
title: 'Has Mobile App?',
template: function (row, index, datatable) {
var tag = '';
if (row.flag_mobile_app === true) {
tag = '<span class="m-badge m-badge--success m-badge--wide">Yes</span>';
} else {
tag = '<span class="m-badge m-badge--danger m-badge--wide">No</span>';
}
return tag;
}
},
{
field: 'app_mobile_number',
title: 'Registered Number'
},
{
field: 'Actions',
width: 110,

View file

@ -58,6 +58,31 @@
<input type="text" name="name" class="form-control m-input" value="{{ obj.getName() }}">
<div class="form-control-feedback hide" data-field="name"></div>
</div>
<div class="col-lg-6">
<label for="name" data-field="branch">
Branch
</label>
<input type="text" name="branch" class="form-control m-input" value="{{ obj.getBranch() }}">
<div class="form-control-feedback hide" data-field="branch"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label for="address" data-field="address">
Address
</label>
<textarea class="form-control m-input" id="address" rows="4" name="address">{{ obj.getAddress }}</textarea>
<div class="form-control-feedback hide" data-field="address"></div>
</div>
<div class="col-lg-6">
<label for="contact_nums" data-field="contact_nums">
Contact Numbers
</label>
<textarea class="form-control m-input" id="contact_nums" rows="4" name="contact_nums">{{ obj.getContactNumbers }}</textarea>
<div class="form-control-feedback hide" data-field="contact_nums"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-3">
<label for="time_open">
Time Open
@ -83,22 +108,6 @@
<div class="form-control-feedback hide" data-field="time_close"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label for="address" data-field="address">
Address
</label>
<textarea class="form-control m-input" id="address" rows="4" name="address">{{ obj.getAddress }}</textarea>
<div class="form-control-feedback hide" data-field="address"></div>
</div>
<div class="col-lg-6">
<label for="contact_nums" data-field="contact_nums">
Contact Numbers
</label>
<textarea class="form-control m-input" id="contact_nums" rows="4" name="contact_nums">{{ obj.getContactNumbers }}</textarea>
<div class="form-control-feedback hide" data-field="contact_nums"></div>
</div>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<label>
@ -309,6 +318,7 @@ $(function() {
{% for outlet in obj.getOutlets() %}
orow = {
name: "{{ outlet.getName() }}",
branch: "{{ outlet.getBranch() }}",
address: "{{ outlet.getAddress() }}",
contact_nums: '{{ outlet.getContactNumbers()|replace({"\r\n": "<br>"})|raw }}',
time_open: "{{ outlet.getTimeOpen()|date('g:i A') }}",
@ -342,7 +352,11 @@ $(function() {
columns: [
{
field: 'name',
title: 'Name'
title: 'Outlet'
},
{
field: 'branch',
title: 'Branch'
},
{
field: 'address',

View file

@ -82,7 +82,11 @@
},
{
field: 'name',
title: 'Name'
title: 'Hub'
},
{
field: 'branch',
title: 'Branch'
},
{
field: 'address',

View file

@ -154,11 +154,21 @@
<select class="form-control m-input" name="service_type">
<!--<option value=""></option>-->
{% for key, service in service_types %}
<option value="{{ key }}"{{ obj.getServiceType == service ? ' selected' }}>{{ service }}</option>
<option value="{{ key }}"{{ obj.getServiceType == key ? ' selected' }}>{{ service }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="service_type"></div>
</div>
<div class="col-lg-6">
<label data-field="warranty_class">Warranty Class</label>
<select class="form-control m-input" id="warranty-class" name="warranty_class">
<!--<option value=""></option>-->
{% for key, class in warranty_classes %}
<option value="{{ key }}"{{ obj.getWarrantyClass == key ? ' selected' }}>{{ class }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="warranty_class"></div>
</div>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-6">
@ -252,21 +262,29 @@
</h3>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-3">
<label>Amount</label>
<input type="text" id="invoice-amount" class="form-control m-input text-right" value="0.00" disabled>
<div class="col-lg-2">
<label>Price</label>
<input type="text" id="invoice-price" class="form-control m-input text-right" value="0.00" disabled>
</div>
<div class="col-lg-3">
<label>Tax</label>
<input type="text" id="invoice-tax" class="form-control m-input text-right" value="0.00" disabled>
<div class="col-lg-2">
<label>VAT</label>
<input type="text" id="invoice-vat" class="form-control m-input text-right" value="0.00" disabled>
</div>
<div class="col-lg-3">
<label>Discount</label>
<input type="text" id="invoice-discount" class="form-control m-input text-right" value="0.00" disabled>
<div class="col-lg-2">
<label>Promo Discount</label>
<input type="text" id="invoice-promo-discount" class="form-control m-input text-right" value="0.00" disabled>
</div>
<div class="col-lg-3">
<label>Final Amount</label>
<input type="text" id="invoice-final-amount" class="form-control m-input text-right" value="0.00" disabled>
<div class="col-lg-2">
<label>Discount Type</label>
<input type="text" id="invoice-discount-type" class="form-control m-input" value="PVC" disabled>
</div>
<div class="col-lg-2">
<label>Trade In</label>
<input type="text" id="invoice-trade-in" class="form-control m-input text-right" value="0.00" disabled>
</div>
<div class="col-lg-2">
<label>Total Amount</label>
<input type="text" id="invoice-total-amount" class="form-control m-input text-right" value="0.00" disabled>
</div>
</div>
<div class="form-group m-form__group row">
@ -276,23 +294,16 @@
<tr>
<th>Item</th>
<th class="text-right">Quantity</th>
<th>Price Level</th>
<th class="text-right">Res Price<br>(w/ Tax)</th>
<th class="text-right">Total Price Adj.</th>
<th>Final Amount</th>
<th>No Trade-in Item?</th>
<th>Battery Class</th>
<th>Discount Item</th>
<th>Percentage</th>
<th>Converted Rate<br>(in Decimal)</th>
<th class="text-right">Discount Amount</th>
<th>Warranty Class</th>
<th>Warranty</th>
<th>Date of Purchase</th>
<th>Warranty Until</th>
<th style="width: 50px;"></th>
</tr>
</thead>
<tbody>
<tr class="placeholder-row">
<td colspan="14">
<td colspan="7">
No items to display.
</td>
</tr>
@ -339,21 +350,17 @@
<table id="outlets-table" class="table table-compact table-hover table-clickable m-table">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Numbers</th>
<th>Opening</th>
<th>Closing</th>
<th class="text-right">Sales Count</th>
<th class="text-right">Sales Amount</th>
<th class="text-right">Service Count</th>
<th>Outlet</th>
<th>Branch</th>
<th class="text-right">Distance</th>
<th class="text-right">Travel Time</th>
</tr>
<th class="text-right">Sales (Day)</th>
<th class="text-right">Services (Day)</th>
<th>Contact Numbers</th> </tr>
</thead>
<tbody>
<tr class="placeholder-row{{ outlets|length > 0 ? ' hide' }}">
<td colspan="10">
<td colspan="7">
No items to display.
</td>
</tr>
@ -361,15 +368,12 @@
{% for outlet in outlets %}
<tr data-lat="{{ outlet.outlet.getCoordinates.getLatitude }}" data-lng="{{ outlet.outlet.getCoordinates.getLongitude }}" data-id="{{ outlet.outlet.getID }}"{{ obj.getOutlet and obj.getOutlet.getID == outlet.outlet.getID ? ' class="m-table__row--primary"' }}>
<td>{{ outlet.outlet.getName }}</td>
<td>{{ outlet.outlet.getAddress }}</td>
<td>{{ outlet.outlet.getContactNumbers }}</td>
<td>{{ outlet.outlet.getTimeOpen|date("g:i A") }}</td>
<td>{{ outlet.outlet.getTimeClose|date("g:i A") }}</td>
<td class="text-right">0.00</td>
<td class="text-right">0.00</td>
<td class="text-right">0</td>
<td>{{ outlet.outlet.getBranch }}</td>
<td class="text-right">{{ outlet.distance ? outlet.distance : '-' }}</td>
<td class="text-right">{{ outlet.duration ? outlet.duration : '-' }}</td>
<td class="text-right">0</td>
<td class="text-right">0</td>
<td>{{ outlet.outlet.getContactNumbers }}</td>
</tr>
{% endfor %}
</tbody>
@ -835,7 +839,8 @@ $(function() {
var unitPrice = 1000;
$.each(response.data, function(index, battery) {
html += '<option value="' + battery.id + '" data-index="' + index + '" data-unit-price="' + unitPrice + '">' + battery.model_name + ' ' + battery.size_name + ' (' + battery.prod_code + ')</option>';
console.log(battery);
html += '<option value="' + battery.id + '" data-index="' + index + '" data-unit-price="' + battery.sell_price + '" data-warr-private="' + battery.warr_private + '" data-warr-commercial="' + battery.warr_commercial + '">' + battery.model_name + ' ' + battery.size_name + '</option>';
});
field.html(html).prop('disabled', false);
@ -863,6 +868,8 @@ $(function() {
var qty = $("#invoice-quantity");
var tbody = $("#invoice-table tbody");
var unitPrice = parseFloat(battery.find('option:selected').data('unit-price'));
var warrPrivate = parseInt(battery.find('option:selected').data('warr-private'));
var warrCommercial = parseInt(battery.find('option:selected').data('warr-commercial'));
if (!bmfg.val() || !battery.val() || !qty.val()) {
swal({
@ -896,22 +903,24 @@ $(function() {
'subtotal': subtotal
});
var warrantyClasses = {
{% for key, class in warranty_classes %}
"{{ key }}": "{{ class }}",
{% endfor %}
};
var warrantyClass = $("#warranty-class").val();
var warrantyLength = warrantyClass == warrantyClasses["private"] ? warrPrivate : warrCommercial;
// build row html
// TODO: Fill with actual data for the rest of the columns
var html = '<tr>' +
'<td>' + battery.find('option:selected').text() + '</td>' +
'<td class="text-right col-quantity">' + qty.val() + '</td>' +
'<td>Base Price</td>' + // TODO: static for now
'<td class="col-unit-price">' + (Math.round(unitPrice * 100) / 100).toFixed(2) + '</td>' + // TODO: not sure if this is correct since it says w/ tax
'<td>0.00</td>' + // TODO: static for now
'<td>' + (Math.round(subtotal * 100) / 100).toFixed(2) + '</td>' + // TODO: I assumed this is unit price * qty
'<td><span class="m-badge m-badge--success m-badge--wide">Yes</span></td>' + // TODO: static for now
'<td>Regular</td>' +
'<td></td>' +
'<td></td>' +
'<td></td>' +
'<td class="col-discount"></td>' +
'<td></td>' +
'<td>' + warrantyClasses[warrantyClass] + '</td>' +
'<td>' + warrantyLength + ' month' + (warrantyLength > 1 ? 's' : '') + '</td>' +
'<td></td>' + // TODO: Date of Purchase, blank for now
'<td></td>' + // TODO: Warranty until, blank for now
'<td><button type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-invoice-delete" title="Delete"><i class="la la-trash"></i></button></td>' +
'</tr>';
@ -925,10 +934,10 @@ $(function() {
});
function updateInvoiceFigures() {
var amountField = $("#invoice-amount");
var taxField = $("#invoice-tax");
var amountField = $("#invoice-price");
var taxField = $("#invoice-vat");
var discountField = $("#invoice-discount");
var finalAmountField = $("#invoice-final-amount");
var finalAmountField = $("#invoice-total-amount");
var finalAmount = invoiceTotal + invoiceTax - invoiceDiscount;
amountField.val(parseFloat(Math.round(invoiceTotal * 100) / 100).toFixed(2));

View file

@ -75,32 +75,27 @@
columns: [
{
field: 'id',
title: 'ID'
title: 'JO Number'
},
{
field: 'delivery_address',
title: 'Customer Area'
},
{
field: 'service_type',
title: 'Type of Transaction'
},
{
field: 'date_schedule',
title: 'Scheduled Date'
},
{
field: 'date_schedule_time',
title: 'Scheduled Time',
sortable: false
field: 'status',
title: 'Status'
},
{
field: 'service_type',
title: 'Service Type'
},
{
field: 'plate_number',
title: 'Plate No.'
},
{
field: 'customer_name',
title: 'Customer'
},
{
field: 'mobile_numbers',
title: 'Mobile Numbers'
field: 'owner',
title: 'Owner'
},
{
field: 'Actions',

View file

@ -43,18 +43,32 @@
<input type="text" name="name" class="form-control m-input" value="{{ obj.getName() }}">
<div class="form-control-feedback hide" data-field="name"></div>
</div>
<div class="col-lg-6">
<label for="name" data-field="branch">
Branch
</label>
<input type="text" name="branch" class="form-control m-input" value="{{ obj.getBranch() }}">
<div class="form-control-feedback hide" data-field="branch"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label data-field="hub">Hub</label>
<select class="form-control m-input" id="hub" name="hub">
<option value=""></option>
{% for hub in hubs %}
<option value="{{ hub.getID() }}"{{ obj.getHub() and hub.getID() == obj.getHub().getID() ? ' selected' }}>{{ hub.getName() }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="hub"></div>
<label for="address" data-field="address">
Address
</label>
<textarea class="form-control m-input" id="address" rows="4" name="address">{{ obj.getAddress }}</textarea>
<div class="form-control-feedback hide" data-field="address"></div>
</div>
<div class="col-lg-6">
<label for="contact_nums" data-field="contact_nums">
Contact Numbers
</label>
<textarea class="form-control m-input" id="contact_nums" rows="4" name="contact_nums">{{ obj.getContactNumbers }}</textarea>
<div class="form-control-feedback hide" data-field="contact_nums"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-3">
<label for="time_open">
Time Open
@ -79,21 +93,15 @@
</div>
<div class="form-control-feedback hide" data-field="time_close"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label for="address" data-field="address">
Address
</label>
<textarea class="form-control m-input" id="address" rows="4" name="address">{{ obj.getAddress }}</textarea>
<div class="form-control-feedback hide" data-field="address"></div>
</div>
<div class="col-lg-6">
<label for="contact_nums" data-field="contact_nums">
Contact Numbers
</label>
<textarea class="form-control m-input" id="contact_nums" rows="4" name="contact_nums">{{ obj.getContactNumbers }}</textarea>
<div class="form-control-feedback hide" data-field="contact_nums"></div>
<label data-field="hub">Hub</label>
<select class="form-control m-input" id="hub" name="hub">
<option value=""></option>
{% for hub in hubs %}
<option value="{{ hub.getID() }}"{{ obj.getHub() and hub.getID() == obj.getHub().getID() ? ' selected' }}>{{ hub.getName() }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="hub"></div>
</div>
</div>
<div class="form-group m-form__group row">
@ -115,8 +123,6 @@
<div class="form-control-feedback hide" data-field="coordinates"></div>
</div>
</div>
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right">

View file

@ -82,7 +82,11 @@
},
{
field: 'name',
title: 'Name'
title: 'Outlet'
},
{
field: 'branch',
title: 'Branch'
},
{
field: 'address',