diff --git a/config/acl.yaml b/config/acl.yaml index f8a5febc..f50b9d33 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -238,3 +238,11 @@ access_keys: label: Update - id: promo.delete label: Delete + + - id: report + label: Reports + acls: + - id: report.menu + label: Menu + - id: report.reject + label: Rejection Report diff --git a/config/routes/report.yaml b/config/routes/report.yaml new file mode 100644 index 00000000..c933d680 --- /dev/null +++ b/config/routes/report.yaml @@ -0,0 +1,9 @@ +rep_reject_form: + path: /report/rejection + controller: App\Controller\ReportController::rejectForm + methods: [GET] + +rep_reject_submit: + path: /report/rejection + controller: App\Controller\ReportController::rejectSubmit + methods: [POST] diff --git a/public/assets/css/style.css b/public/assets/css/style.css index ef00d1b7..96f1f655 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -196,6 +196,81 @@ span.has-danger, top: -0.45rem; } +.input-group .form-control:first-child:not(:last-child):not(:focus):not(.focus) { + border-right: 0; +} + +.input-group .input-group-append + .form-control:not(:focus):not(.focus) { + border-left: 0; +} + +.input-group > .form-control:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group > .form-control:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group .input-group-append > .input-group-text { + border-color: #ebedf2; + background-color: #f4f5f8; + color: #575962; +} + +.input-group > .input-group-append > .input-group-text { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group > .input-group-append:not(:last-child) > .input-group-text { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group-text { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: .85rem 1.15rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.25; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: .25rem; +} + +.input-daterange input:last-child { + border-radius: 0 3px 3px 0; +} + +.input-group { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + width: 100%; +} + +.input-daterange { + width: 100%; +} + @media (min-width: 995px) { .modal-lg { max-width: 1024px; diff --git a/src/Controller/ReportController.php b/src/Controller/ReportController.php new file mode 100644 index 00000000..4363e747 --- /dev/null +++ b/src/Controller/ReportController.php @@ -0,0 +1,150 @@ +denyAccessUnlessGranted('report.reject', null, 'No access.'); + + $params = $this->initParameters('outlet_list'); + + return $this->render('report/rejection/form.html.twig', $params); + } + + public function rejectSubmit(Request $req) + { + $this->denyAccessUnlessGranted('report.reject', null, 'No access.'); + + // get query builder + $qb = $this->getDoctrine() + ->getRepository(JORejection::class) + ->createQueryBuilder('r'); + + // get dates + $raw_date_start = $req->request->get('date_start'); + $raw_date_end = $req->request->get('date_end'); + + $date_start = DateTime::createFromFormat('m/d/Y', $raw_date_start); + $date_end = DateTime::createFromFormat('m/d/Y', $raw_date_end); + + // build query + $query = $qb->where('r.date_create >= :start') + ->andWhere('r.date_create <= :end') + ->setParameter('start', $date_start->format('Y-m-d') . ' 00:00:00') + ->setParameter('end', $date_end->format('Y-m-d') . ' 23:59:59') + ->getQuery(); + + + // run query + $jors = $query->getResult(); + + // initialize counter + $counter = []; + + // get results + $res = []; + foreach ($jors as $jor) + { + $jo = $jor->getJobOrder(); + $hub = $jor->getHub(); + $hub_id = $hub->getID(); + $hub_name = $hub->getName() . ' - ' . $hub->getBranch(); + + $reason = $jor->getReason(); + + if (!isset($counter[$hub_id])) + $counter[$hub_id] = [ + 'reasons' => [], + 'name' => $hub_name, + ]; + + if (!isset($counter[$hub_id][$reason])) + { + $counter[$hub_id]['reasons'][$reason]['name'] = JORejectionReason::getName($reason); + $counter[$hub_id]['reasons'][$reason]['counter'] = 1; + } + else + { + $counter[$hub_id]['reasons'][$reason]['counter'] += 1; + } + + $res[] = [ + 'jo_id' => $jo->getID(), + 'jo_date_time' => $jo->getDateSchedule(), + 'jor_date_create' => $jo->getDateCreate(), + 'hub' => $hub->getName() . ' - ' . $hub->getBranch(), + 'reason' => JORejectionReason::getName($jor->getReason()), + 'contact' => $jor->getContactPerson(), + 'remarks' => $jor->getRemarks(), + ]; + } + + + // response + $resp = new StreamedResponse(); + $resp->setCallback(function() use ($counter) { + // csv output + $csv_handle = fopen('php://output', 'w+'); + fputcsv($csv_handle, ['Enrollee', 'Reason', 'Count']); + foreach ($counter as $centry) + { + $first = true; + foreach ($centry['reasons'] as $creason) + { + // first line has hub name + if ($first) + { + fputcsv($csv_handle, [ + $centry['name'], + $creason['name'], + $creason['counter'], + ]); + $first = false; + } + else + { + fputcsv($csv_handle, [ + '', + $creason['name'], + $creason['counter'], + ]); + } + } + } + + fclose($csv_handle); + }); + + $filename = 'reject_' . $date_start->format('Ymd') . '_' . $date_end->format('Ymd') . '.csv'; + + $resp->setStatusCode(200); + $resp->headers->set('Content-Type', 'text/csv; charset=utf-8'); + $resp->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"'); + + return $resp; + /* + return $this->json([ + 'result' => $res, + 'counter' => $counter, + ]); + */ + } +} diff --git a/src/Ramcar/JORejectionReason.php b/src/Ramcar/JORejectionReason.php index a07042e6..9dee1217 100644 --- a/src/Ramcar/JORejectionReason.php +++ b/src/Ramcar/JORejectionReason.php @@ -12,6 +12,9 @@ class JORejectionReason extends NameValue const NO_RIDER_AVAILABLE = 'no_rider_available'; const NO_RIDER_IN_TRANSIT = 'no_rider_in_transit'; const REFUSAL = 'refusal'; + const STORE_CLOSED = 'store_closed'; + const NO_CREDIT_CARD = 'no_credit_card'; + const DISCOUNT = 'discount'; const COLLECTION = [ 'administrative' => 'ADMINISTRATIVE', @@ -22,5 +25,8 @@ class JORejectionReason extends NameValue 'no_rider_available' => 'NO RIDER - AVAILABLE', 'no_rider_in_transit' => 'NO RIDER - IN TRANSIT', 'refusal' => 'REFUSAL', + 'store_closed' => 'STORE CLOSED', + 'no_credit_card' => 'NO CREDIT CARD PAYMENT / NO TERMINAL', + 'discount' => 'DISCOUNT', ]; } diff --git a/templates/base.html.twig b/templates/base.html.twig index 84dbcbb4..656d5418 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -103,53 +103,24 @@ + diff --git a/templates/report/rejection/form.html.twig b/templates/report/rejection/form.html.twig new file mode 100644 index 00000000..c0676019 --- /dev/null +++ b/templates/report/rejection/form.html.twig @@ -0,0 +1,82 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

Rejection Report

+
+
+
+ +
+ +
+
+
+
+
+
+ + + +

+ Select a date range +

+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %}