Resolve "Ticket changes" #830

Merged
arcticzero merged 5 commits from 21-ticket-changes into master 2018-02-26 09:53:57 +00:00
8 changed files with 261 additions and 43 deletions

View file

@ -10,18 +10,20 @@ ticket_rows:
methods: [POST] methods: [POST]
ticket_create: ticket_create:
path: /tickets/create/{customer_id} path: /tickets/create/{customer_id}/{job_order_id}
controller: App\Controller\TicketController::addForm controller: App\Controller\TicketController::addForm
methods: [GET] methods: [GET]
defaults: defaults:
customer_id: false customer_id: false
job_order_id: false
ticket_create_submit: ticket_create_submit:
path: /tickets/create/{customer_id} path: /tickets/create/{customer_id}/{job_order_id}
controller: App\Controller\TicketController::addSubmit controller: App\Controller\TicketController::addSubmit
methods: [POST] methods: [POST]
defaults: defaults:
customer_id: false customer_id: false
job_order_id: false
ticket_update: ticket_update:
path: /tickets/{id} path: /tickets/{id}

View file

@ -7,6 +7,7 @@ use App\Ramcar\TicketType;
use App\Ramcar\TicketStatus; use App\Ramcar\TicketStatus;
use App\Entity\Ticket; use App\Entity\Ticket;
use App\Entity\Customer; use App\Entity\Customer;
use App\Entity\JobOrder;
use Doctrine\ORM\Query; use Doctrine\ORM\Query;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -99,6 +100,7 @@ class TicketController extends BaseController
$row['contact_num'] = $orow->getContactNumber(); $row['contact_num'] = $orow->getContactNumber();
$row['status'] = $ticket_statuses[$orow->getStatus()]; $row['status'] = $ticket_statuses[$orow->getStatus()];
$row['ticket_type'] = $ticket_types[$orow->getTicketType()]; $row['ticket_type'] = $ticket_types[$orow->getTicketType()];
$row['plate_number'] = $orow->getPlateNumber();
// add row metadata // add row metadata
$row['meta'] = [ $row['meta'] = [
@ -122,7 +124,7 @@ class TicketController extends BaseController
]); ]);
} }
public function addForm(Request $req, $customer_id) public function addForm(Request $req, $customer_id, $job_order_id)
{ {
$this->denyAccessUnlessGranted('ticket.add', null, 'No access.'); $this->denyAccessUnlessGranted('ticket.add', null, 'No access.');
@ -130,6 +132,7 @@ class TicketController extends BaseController
$params['obj'] = new Ticket(); $params['obj'] = new Ticket();
$params['mode'] = 'create'; $params['mode'] = 'create';
$params['customer'] = false; $params['customer'] = false;
$params['job_order'] = false;
$customer = false; $customer = false;
// get customer data // get customer data
@ -143,6 +146,18 @@ class TicketController extends BaseController
// add to view // add to view
$params['customer'] = $customer; $params['customer'] = $customer;
// get job order data
if ($job_order_id) {
$job_order = $em->getRepository(JobOrder::class)->find($job_order_id);
// make sure this row exists
if (empty($job_order))
throw $this->createNotFoundException('This job order does not exist');
// add to view
$params['job_order'] = $job_order;
}
} }
// get parent associations // get parent associations
@ -159,13 +174,21 @@ class TicketController extends BaseController
if ($referer == $cust_update_url) if ($referer == $cust_update_url)
$params['redirect_url'] = $cust_update_url; $params['redirect_url'] = $cust_update_url;
if ($job_order)
{
$job_order_url = $this->generateUrl('jo_proc_form', ['id' => $job_order->getID()], UrlGeneratorInterface::ABSOLUTE_URL);
if ($referer == $job_order_url)
$params['redirect_url'] = $job_order_url;
}
} }
// response // response
return $this->render('ticket/form.html.twig', $params); return $this->render('ticket/form.html.twig', $params);
} }
public function addSubmit(Request $req, ValidatorInterface $validator, $customer_id) public function addSubmit(Request $req, ValidatorInterface $validator, $customer_id, $job_order_id)
{ {
$this->denyAccessUnlessGranted('ticket.add', null, 'No access.'); $this->denyAccessUnlessGranted('ticket.add', null, 'No access.');
@ -189,6 +212,15 @@ class TicketController extends BaseController
if (count($mobile_numbers) > 0) { if (count($mobile_numbers) > 0) {
$contact_num = $mobile_numbers[0]->getID(); $contact_num = $mobile_numbers[0]->getID();
} }
// get job order data
if ($job_order_id) {
$job_order = $em->getRepository(JobOrder::class)->find($job_order_id);
// make sure this row exists
if (empty($job_order))
throw $this->createNotFoundException('This job order does not exist');
}
} else { } else {
// get values directly from form // get values directly from form
$first_name = $req->request->get('first_name'); $first_name = $req->request->get('first_name');
@ -216,6 +248,7 @@ class TicketController extends BaseController
->setOtherTicketType($other_ticket_type) ->setOtherTicketType($other_ticket_type)
->setSubject($req->request->get('subject')) ->setSubject($req->request->get('subject'))
->setDetails($req->request->get('details')) ->setDetails($req->request->get('details'))
->setPlateNumber($req->request->get('plate_number'))
->setDateCreate(new DateTime()) ->setDateCreate(new DateTime())
->setCreatedBy($this->getUser()); ->setCreatedBy($this->getUser());
@ -224,6 +257,11 @@ class TicketController extends BaseController
$obj->setCustomer($customer); $obj->setCustomer($customer);
} }
// if linked to job order, set association
if ($job_order_id) {
$obj->setJobOrder($job_order);
}
// initialize error list // initialize error list
$error_array = []; $error_array = [];
@ -277,9 +315,11 @@ class TicketController extends BaseController
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$customer = $obj->getCustomer(); $customer = $obj->getCustomer();
$job_order = $obj->getJobOrder();
// get parent associations // get parent associations
$params['customer'] = $customer; $params['customer'] = $customer;
$params['job_order'] = $job_order;
$params['ticket_types'] = TicketType::getCollection(); $params['ticket_types'] = TicketType::getCollection();
$params['statuses'] = TicketStatus::getCollection(); $params['statuses'] = TicketStatus::getCollection();
$params['other_ticket_type'] = TicketType::OTHER; $params['other_ticket_type'] = TicketType::OTHER;
@ -348,7 +388,8 @@ class TicketController extends BaseController
->setTicketType($ticket_type) ->setTicketType($ticket_type)
->setOtherTicketType($other_ticket_type) ->setOtherTicketType($other_ticket_type)
->setSubject($req->request->get('subject')) ->setSubject($req->request->get('subject'))
->setDetails($req->request->get('details')); ->setDetails($req->request->get('details'))
->setPlateNumber($req->request->get('plate_number'));
// initialize error list // initialize error list
$error_array = []; $error_array = [];

View file

@ -173,6 +173,12 @@ class JobOrder
*/ */
protected $cancel_reason; protected $cancel_reason;
// tickets associated with job order
/**
* @ORM\OneToMany(targetEntity="Ticket", mappedBy="job_order")
*/
protected $tickets;
public function __construct() public function __construct()
{ {
$this->date_create = new DateTime(); $this->date_create = new DateTime();
@ -435,4 +441,9 @@ class JobOrder
{ {
return $this->cancel_reason; return $this->cancel_reason;
} }
public function getTickets()
{
return $this->tickets;
}
} }

View file

@ -83,6 +83,12 @@ class Ticket
*/ */
protected $details; protected $details;
// plate number
/**
* @ORM\Column(type="string", length=10, nullable=true)
*/
protected $plate_number;
// user that created the ticket // user that created the ticket
/** /**
* @ORM\ManyToOne(targetEntity="User", inversedBy="tickets") * @ORM\ManyToOne(targetEntity="User", inversedBy="tickets")
@ -97,6 +103,13 @@ class Ticket
*/ */
protected $customer; protected $customer;
// job order associated with the ticket (optional)
/**
* @ORM\ManyToOne(targetEntity="JobOrder", inversedBy="tickets")
* @ORM\JoinColumn(name="job_order_id", referencedColumnName="id", nullable=true)
*/
protected $job_order;
public function __construct() public function __construct()
{ {
$this->date_create = new DateTime(); $this->date_create = new DateTime();
@ -222,6 +235,17 @@ class Ticket
return $this->details; return $this->details;
} }
public function setPlateNumber($plate_number)
{
$this->plate_number = $plate_number;
return $this;
}
public function getPlateNumber()
{
return $this->plate_number;
}
public function setCreatedBy(User $created_by) public function setCreatedBy(User $created_by)
{ {
$this->created_by = $created_by; $this->created_by = $created_by;
@ -243,4 +267,15 @@ class Ticket
{ {
return $this->customer; return $this->customer;
} }
public function setJobOrder(JobOrder $job_order)
{
$this->job_order = $job_order;
return $this;
}
public function getJobOrder()
{
return $this->job_order;
}
} }

View file

@ -4,17 +4,20 @@ namespace App\Ramcar;
class TicketType extends NameValue class TicketType extends NameValue
{ {
const COMPLAINT = 'complaint'; const COMPLAINT = 'complaint';
const QUESTION = 'question'; const INQUIRY = 'inquiry';
const ORDERS = 'orders'; const ORDERS = 'orders';
const BILLING = 'billing'; const BILLING = 'billing';
const OTHER = 'other'; const OTHER = 'other';
const FOR_FOLLOW_UP = 'for_follow_up';
const COLLECTION = [ const COLLECTION = [
'complaint' => 'Complaint', 'complaint' => 'Complaint',
'question' => 'Question', 'inquiry' => 'Inquiry',
'orders' => 'Orders', 'orders' => 'Orders',
'billing' => 'Billing', 'billing' => 'Billing',
'other' => 'Other', 'other' => 'Other',
'for_follow_up' => 'For follow-up',
]; ];
} }

View file

@ -376,7 +376,7 @@
{% if mode == 'update-processing' %} {% if mode == 'update-processing' %}
<div class="m-form__seperator m-form__seperator--dashed"></div> <div class="m-form__seperator m-form__seperator--dashed"></div>
<div class="m-form__section m-form__section--last"> <div class="m-form__section">
<div class="m-form__heading"> <div class="m-form__heading">
<h3 class="m-form__heading-title"> <h3 class="m-form__heading-title">
Nearest Hubs Nearest Hubs
@ -421,8 +421,12 @@
</div> </div>
</div> </div>
</div> </div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<div id="hub_map" style="height:600px;"></div>
</div>
</div>
</div> </div>
<div id="hub_map" style="height:600px;"></div>
{% endif %} {% endif %}
{% if mode in ['update-assigning', 'update-fulfillment'] %} {% if mode in ['update-assigning', 'update-fulfillment'] %}
@ -473,7 +477,7 @@
<div class="m-form__seperator m-form__seperator--dashed"></div> <div class="m-form__seperator m-form__seperator--dashed"></div>
{% if mode == 'update-assigning' %} {% if mode == 'update-assigning' %}
<div class="m-form__section m-form__section--last"> <div class="m-form__section">
<div class="m-form__heading"> <div class="m-form__heading">
<h3 class="m-form__heading-title"> <h3 class="m-form__heading-title">
Rider Assignment Rider Assignment
@ -525,7 +529,7 @@
{% endif %} {% endif %}
{% if mode == 'update-fulfillment' %} {% if mode == 'update-fulfillment' %}
<div class="m-form__section m-form__section--last"> <div class="m-form__section">
<div class="m-form__heading"> <div class="m-form__heading">
<h3 class="m-form__heading-title"> <h3 class="m-form__heading-title">
Rider Details Rider Details
@ -565,6 +569,28 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if mode != 'create' %}
<div class="m-form__seperator m-form__seperator--dashed"></div>
<div class="m-form__section m-form__section--last">
<div class="m-form__heading">
<h3 class="m-form__heading-title">
Tickets
</h3>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<div class="m_datatable" id="data-tickets"></div>
</div>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<a href="{{ url('ticket_create', {'customer_id': obj.getCustomer.getID, 'job_order_id': obj.getID}) }}" class="btn btn-primary">Create Ticket</a>
</div>
</div>
</div>
{% endif %}
</div> </div>
<div class="m-portlet__foot m-portlet__foot--fit"> <div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right"> <div class="m-form__actions m-form__actions--solid m-form__actions--right">
@ -1070,7 +1096,7 @@ $(function() {
selectedHub = id; selectedHub = id;
// center the map // center the map
omap.setCenter(lat, lng); hmap.setCenter(lat, lng);
} else { } else {
// unhighlight this row // unhighlight this row
$(this).removeClass('m-table__row--primary'); $(this).removeClass('m-table__row--primary');
@ -1104,6 +1130,76 @@ $(function() {
} }
}); });
{% endif %} {% endif %}
{% if mode != 'create' %}
var ticketRows = [];
{% for ticket in obj.getTickets %}
trow = {
id: "{{ ticket.getID }}",
date_create: "{{ ticket.getDateCreate|date('d M Y - h:i A') }}",
subject: "{{ ticket.getSubject }}",
ticket_type: "{{ ticket.getTicketTypeText }}",
status: "{{ ticket.getStatusText }}",
edit_url: "{{ url('ticket_update', {'id': ticket.getID}) }}"
};
ticketRows.push(trow);
{% endfor %}
// tickets data table
var ticketOptions = {
data: {
type: 'local',
source: ticketRows,
saveState: {
cookie: false,
webstorage: false
}
},
layout: {
scroll: true
},
columns: [
{
field: 'id',
title: 'ID',
width: 30
},
{
field: 'date_create',
title: 'Date Created',
width: 200
},
{
field: 'subject',
title: 'Subject',
width: 300
},
{
field: 'ticket_type',
title: 'Ticket Type'
},
{
field: 'status',
title: 'Status'
},
{
field: 'Actions',
width: 70,
title: 'Actions',
sortable: false,
overflow: 'visible',
template: function (row, index, datatable) {
return '<a href="' + row.edit_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit-ticket" title="Edit"><i class="la la-edit"></i></a>';
},
}
],
pagination: false
};
var ticketTable = $("#data-tickets").mDatatable(ticketOptions);
{% endif %}
}); });
</script> </script>
{% endblock %} {% endblock %}

View file

@ -35,35 +35,9 @@
</div> </div>
</div> </div>
</div> </div>
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('ticket_update_submit', {'id': obj.getId}) : url('ticket_create_submit', {'customer_id': customer ? customer.getID : false}) }}"> <form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('ticket_update_submit', {'id': obj.getId}) : url('ticket_create_submit', {'customer_id': customer ? customer.getID : false, 'job_order_id': job_order ? job_order.getID : false}) }}">
<div class="m-portlet__body"> <div class="m-portlet__body">
<div class="form-group m-form__group row no-border"> <div class="form-group m-form__group row no-border">
<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="{{ customer and mode == 'create' ? customer.getFirstName : obj.getFirstName }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="first_name"></div>
</div>
<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="{{ customer and mode == 'create' ? customer.getLastName : obj.getLastName }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="last_name"></div>
</div>
<div class="col-lg-4">
<label data-field="contact_num">Contact Number</label>
<input type="text" name="contact_num" class="form-control m-input" value="{{ customer and mode == 'create' and customer.getMobileNumbers is not empty ? customer.getMobileNumbers[0].getID : obj.getContactNumber }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="contact_num"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-4">
<label data-field="status">Status</label>
<select class="form-control m-input" id="status" name="status">
{% for key, status in statuses %}
<option value="{{ key }}"{{ key == obj.getStatus ? ' selected' }}>{{ status }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="status"></div>
</div>
<div class="col-lg-4"> <div class="col-lg-4">
<label data-field="status">Ticket Type</label> <label data-field="status">Ticket Type</label>
<select class="form-control m-input" id="ticket-type" name="ticket_type"> <select class="form-control m-input" id="ticket-type" name="ticket_type">
@ -80,6 +54,43 @@
<div class="form-control-feedback hide" data-field="other_ticket_type"></div> <div class="form-control-feedback hide" data-field="other_ticket_type"></div>
</div> </div>
</div> </div>
<div class="form-group m-form__group row no-border">
<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="{{ customer and mode == 'create' ? customer.getFirstName : obj.getFirstName }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="first_name"></div>
</div>
<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="{{ customer and mode == 'create' ? customer.getLastName : obj.getLastName }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="last_name"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-4">
<label data-field="contact_num">Contact Number</label>
<input type="text" name="contact_num" class="form-control m-input" value="{{ customer and mode == 'create' and customer.getMobileNumbers is not empty ? customer.getMobileNumbers[0].getID : obj.getContactNumber }}"{{ customer ? ' disabled' }}>
<div class="form-control-feedback hide" data-field="contact_num"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-4">
<label data-field="plate_number">Vehicle Plate Number</label>
<input type="text" name="plate_number" class="form-control m-input" value="{{ obj.getPlateNumber }}">
<div class="form-control-feedback hide" data-field="plate_number"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-4">
<label data-field="status">Status</label>
<select class="form-control m-input" id="status" name="status">
{% for key, status in statuses %}
<option value="{{ key }}"{{ key == obj.getStatus ? ' selected' }}>{{ status }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="status"></div>
</div>
</div>
<div class="form-group m-form__group row no-border"> <div class="form-group m-form__group row no-border">
<div class="col-lg-12"> <div class="col-lg-12">
<label data-field="subject">Subject</label> <label data-field="subject">Subject</label>
@ -96,6 +107,21 @@
<div class="form-control-feedback hide" data-field="details"></div> <div class="form-control-feedback hide" data-field="details"></div>
</div> </div>
</div> </div>
<div class="form-group m-form__group row no-border">
<div class="col-lg-4">
<label data-field="job_order_id">Linked Job Order</label>
<input type="text" name="job_order_id" class="form-control m-input" value="{{ job_order.getID|default('None') }}" disabled>
<div class="form-control-feedback hide" data-field="job_order_id"></div>
</div>
{% if job_order %}
<div class="col-lg-4">
<label>&nbsp;</label>
<div>
<a href="{{ url('jo_proc_form', {'id': job_order.getID }) }}" class="btn btn-info">View Job Order</a>
</div>
</div>
{% endif %}
</div>
</div> </div>
<div class="m-portlet__foot m-portlet__foot--fit"> <div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right"> <div class="m-form__actions m-form__actions--solid m-form__actions--right">

View file

@ -105,6 +105,10 @@
field: 'contact_num', field: 'contact_num',
title: 'Contact No.' title: 'Contact No.'
}, },
{
field: 'plate_number',
title: 'Plate Number'
},
{ {
field: 'ticket_type', field: 'ticket_type',
title: 'Type' title: 'Type'