You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

363 lines
15 KiB

<?php
require APPPATH . 'libraries/rest-api/REST_Controller.php';
class Cart_confirmation extends REST_Controller {
protected $USER_ID = NULL;
protected $EVENT_ID = NULL;
protected $EVENT_SCHEDULE_ID = NULL;
protected $REG_TYPE = REG_TYPE['normal_reg']; // 1 = REGISTER
protected $REG_ACTION = "register"; // "REGISTER" || "MODIFY"
protected $NUMBER_OF_SEATS = 0;
protected $RES_ALLOWED = FALSE;
protected $RES_STATUS = "";
protected $RES_EMAIL_TYPE = [
"CONFIRMATION_EMAIL" => 3,
"MODIFY_RESERVATION" => 8
];
protected $ERROR_FIELDS = [];
protected $RESERVATION = NULL;
protected $RESERVATION_OTHER_DETAILS = NULL;
protected $POST_DATA = NULL;
const EVENT_RESPONSE = [
"EVENT_CLOSED" => "Reservation is not allowed. Event is currently closed.",
"EVENT_FULL_RES_TO_WL" => "Cannot reserve, event is already full.",
"EVENT_REG_DISABLED" => "Reservation is not allowed.",
"EVENT_FULL" => "Reservation is not allowed event is full.",
"EVENT_REG_UNAVAILABLE" => "You have reached the maximum reservation allowed per subscriber in this event.",
"EVENT_RES_OK" => "You have successfully registered to an event.",
"EVENT_RES_ADDED_SEAT" => "You have successfully added seat to your reservations.",
"EVENT_404" => "Event not found.",
"EVENT_RESTRICT_MULTIPLE_RES" => "You have reached the maximum reservation allowed per subscriber in this event.",
"EVENT_RES_NULL" => "Reserve seats should not be null.",
"EVENT_WRONG_FORMAT_PAYLOAD" => "Wrong format of JSON data",
// Reservation
"EVENT_RESERVATION_ERR" => "Reservation unsuccessfull. Try again later.",
"EVENT_NO_RESERVATION" => "No current reservation.",
"EVENT_RESERVATION_EMIAL_ERR" => "Unable to queue reservation confirmation email."
];
const PAYLOAD_FIELDS = [
// Optional fields
"mage_id" => ["required" => false, "dtype" => "string"],
"firstname" => ["required" => false, "dtype" => "string"],
"lastname" => ["required" => false, "dtype" => "string"],
"event_date_time" => ["required" => false, "dtype" => "date"],
"update_date_time" => ["required" => false, "dtype" => "date"],
"comment" => ["required" => false, "dtype" => "string"],
// Required fields
"magento_id" => ["required" => true, "dtype" => "int"],
"email" => ["required" => true, "dtype" => "email"],
"cart_id" => ["required" => true, "dtype" => "string"],
// Required to determine which event_schedule to query from
"code_selection" => ["required" => true, "dtype" => "string"],
"item_name" => ["required" => true, "dtype" => "string"],
"number_of_seat" => ["required" => true, "dtype" => "int"],
"unit_price" => ["required" => true, "dtype" => "int"],
"amount_cart" => ["required" => true, "dtype" => "int"],
"procurement_date_time" => ["required" => true, "dtype" => "date"]
];
/**
* Get All Data from this method.
*
* @return Response
*/
public function __construct() {
parent::__construct();
$this->load->database();
$this->load->model('user_model');
$this->load->model("event_schedule_model");
$this->load->model("event_registration_paid_event_model");
$this->load->model('event_wait_list_model');
$this->load->model('event_registration_model');
$this->load->model("user_subscriber_model");
$this->load->model('event_email_template_model');
$this->load->model('event_email_recipient_model');
$this->load->model('user_activity_log_model');
}
/**
* Reserve seat
*
* @return Response
*/
public function action_post()
{
// Validate payload and initialize variables
$this->validate_payload();
// Get event details
$event_sched_details = $this->event_schedule_model->event_schedule_details($this->EVENT_ID, $this->EVENT_SCHEDULE_ID);
// Validate registration information
$this->validate_reservation($event_sched_details);
if ($this->RES_ALLOWED) {
$this->RESERVATION = array(
"event_id" => $this->EVENT_ID,
"seat_feature" => $event_sched_details->seat_feature,
"action" => $this->REG_ACTION,
"reg_type" => $this->REG_TYPE,
"user_id" => $this->USER_ID,
"seats_reserved" => $this->NUMBER_OF_SEATS,
"event_schedule_id" => $this->EVENT_SCHEDULE_ID,
"guest_emails" => "",
"user_agent" => $_SERVER['HTTP_USER_AGENT'] ?? null,
"is_user_moderated" => 0
);
$this->RESERVATION_OTHER_DETAILS = [
"cart_id" => $this->POST_DATA['cart_id'],
"item_code" => $this->POST_DATA['code_selection'],
"item_name" => $this->POST_DATA['item_name'],
"number_of_seats" => $this->NUMBER_OF_SEATS,
"unit_price" => $this->POST_DATA['unit_price'],
"amount_cart" => $this->POST_DATA['amount_cart'],
"comment" => (isset($this->POST_DATA['comment']) && !empty($this->POST_DATA['comment'])) ? $this->POST_DATA['comment'] : NULL,
"procurement_date_time" => $this->POST_DATA['procurement_date_time'] ?? NULL,
"update_date_time" => $this->POST_DATA['update_date_time'] ?? NULL
];
if ($this->REG_ACTION == "register")
return $this->add_reservation();
else
return $this->modify_reservation();
}
$this->responseFormatter("EVENT_RESERVATION_ERR");
}
private function validate_payload() {
$POST_DATA = countVal($this->input->post()) ? $this->input->post() : $this->request->body;
if ( !countVal($POST_DATA) )
$this->responseFormatter("EVENT_WRONG_FORMAT_PAYLOAD");
// Checking Unknown fields
foreach ($POST_DATA as $key => $value) {
// Unknown fields
if ( !array_key_exists($key, self::PAYLOAD_FIELDS) ) {
array_push($this->ERROR_FIELDS , [
"field" => $key,
"description" => "Unkown field"
]);
continue;
}
}
foreach (self::PAYLOAD_FIELDS as $key => $value) {
// Requied fields
if ( self::PAYLOAD_FIELDS[$key]["required"]) {
$msg = (!array_key_exists($key, $POST_DATA))
? "Ce champ est obligatoire."
: (isset($POST_DATA[$key]) && empty($POST_DATA[$key]) )
? "Required field must not be null"
: "";
if ($msg) {
array_push($this->ERROR_FIELDS , ["field" => $key, "description" => $msg]);
continue;
}
}
isset($POST_DATA[$key]) && $this->validate_field($key, $POST_DATA[$key]);
}
if ( countVal($this->ERROR_FIELDS) ) {
$this->responseHandler(["message" => "Field validation error" , "details" => $this->ERROR_FIELDS], REST_Controller::HTTP_BAD_REQUEST);
}
/**
* Required fields are validated so we verify its values
*/
// Verify code selection
$eventInfo = $this->event_registration_paid_event_model->get_event_by_code_selection($POST_DATA['code_selection']);
if (!$eventInfo) {
$this->responseHandler("Invalid code selection", REST_Controller::HTTP_BAD_REQUEST);
}
$this->EVENT_ID = $eventInfo->event_id;
$this->EVENT_SCHEDULE_ID = $eventInfo->event_schedule_id;
// Verify user email, magento_id || mage_id
$user = $this->user_model->get_user_by_email_or_magento_id($POST_DATA['email'], $POST_DATA['magento_id'], $POST_DATA['mage_id'] ?? null);
if (!$user) {
$this->responseHandler([
"message" => "Subscriber with email '".$POST_DATA['email']."' not recognized",
"description" => "Make sure 'magento_id' and 'email' are valid."
], REST_Controller::HTTP_BAD_REQUEST);
}
$this->USER_ID = $user->user_id;
$this->NUMBER_OF_SEATS = $POST_DATA['number_of_seat'];
$this->POST_DATA = $POST_DATA;
}
private function validate_reservation($event_sched_details) {
// Event exists
if ( !countVal($event_sched_details) > 0 )
$this->responseFormatter("EVENT_404", REST_Controller::HTTP_NOT_FOUND);
// Check if subscriber is allowed to book for more than 1 date per event
if ( !$this->event_registration_paid_event_model->can_register_to_event($this->EVENT_ID, $this->USER_ID, $this->REG_TYPE) )
$this->responseFormatter("EVENT_RESTRICT_MULTIPLE_RES");
// Check if there are seats avaiable or if the limit for seat_per_subscriber have not been reached
$event = $this->event_registration_paid_event_model->check_availability($this->EVENT_ID, $this->EVENT_SCHEDULE_ID, $this->NUMBER_OF_SEATS);
$prev_reservation = $this->event_registration_model->seats_reserved($this->USER_ID, $this->EVENT_SCHEDULE_ID);
if ($prev_reservation)
$this->REG_ACTION = "modify";
// Event is Closed
if (countVal($event) <= 0 || $event->back_office_status >= 4)
$this->responseFormatter("EVENT_CLOSED");
// Event FULL
if ($event->back_office_status == 3 || ($event->event_status == 'FULL' && $event->remaining_seat >=0))
$this->responseFormatter("EVENT_FULL");
// Register to regular/normal registration disabled : must register to waiting list
if ($event->remaining_seat <= 0 && $event->quota_waiting_list_seat > 0)
$this->responseFormatter("EVENT_FULL_RES_TO_WL");
// Event FULL
if ($event->remaining_seat <= 0)
$this->responseFormatter("EVENT_FULL");
// Event Registration disabled
if ($event->seats_per_subscriber <=0)
$this->responseFormatter("EVENT_REG_DISABLED");
// Allow Reserver for normal or regular reservation
$currentTotalReservation = $prev_reservation + $this->NUMBER_OF_SEATS;
if ($event->remaining_seat > 0
&& $event->event_status == 'AVAILABLE'
&& $event->remaining_seat >= $this->NUMBER_OF_SEATS
&& $currentTotalReservation <= $event->seats_per_subscriber)
{
return $this->RES_ALLOWED = true;
} else {
//Event registration disabled
$this->responseFormatter("EVENT_REG_UNAVAILABLE");
}
}
private function validate_field($field, $value, $required = false) {
switch(self::PAYLOAD_FIELDS[$field]["dtype"]) {
case 'email':
if ( !filter_var($value, FILTER_VALIDATE_EMAIL) ) {
array_push($this->ERROR_FIELDS , [
"field" => $field,
"description" => "Invalid email"
]);
}
return;
case 'date':
$dFormat = 'Y-m-d H:i:s';
$d = DateTime::createFromFormat($dFormat , $value);
if (!$d || $d->format($dFormat ) != $value) {
array_push($this->ERROR_FIELDS , [
"field" => $field,
"description" => "Invalid date format"
]);
}
return;
case 'int':
if (!is_numeric($value)) {
array_push($this->ERROR_FIELDS , [
"field" => $field,
"description" => "Invalid number"
]);
return;
}
if (is_numeric($value) && (int) $value <= 0 ) {
array_push($this->ERROR_FIELDS , [
"field" => $field,
"description" => "Number must be greater than zero"
]);
return;
}
return;
}
}
private function add_reservation() {
$registration_id = $this->event_registration_model->register($this->RESERVATION);
// Send email when reservation is successfull
if (!$registration_id)
return $this->responseFormatter("EVENT_RESERVATION_ERR");
// Add entry to paid event table
$paidEventId = $this->add_paid_event_entry($registration_id);
// Save logs
$this->add_log("ADD", $paidEventId);
// Queue email
$this->queue_confirmation_email($this->RES_EMAIL_TYPE['CONFIRMATION_EMAIL'], $registration_id);
return $this->responseFormatter("EVENT_RES_OK", REST_Controller::HTTP_OK);
}
private function modify_reservation() {
$registration_id = $this->event_registration_model->register($this->RESERVATION);
// Send email when reservation is successfull
if (!$registration_id)
return $this->responseFormatter("EVENT_RESERVATION_ERR");
// Add entry to paid event table
$paidEventId = $this->add_paid_event_entry($registration_id);
// Save logs
$this->add_log("EDIT", $paidEventId);
$seats_reserved = $this->event_registration_model->seats_reserved($this->USER_ID, $this->EVENT_SCHEDULE_ID);
if (!$seats_reserved)
return $this->responseFormatter("EVENT_NO_RESERVATION");
// Queue email
$this->queue_confirmation_email($this->RES_EMAIL_TYPE['MODIFY_RESERVATION'], $registration_id);
return $this->responseFormatter("EVENT_RES_ADDED_SEAT", REST_Controller::HTTP_OK);
}
private function queue_confirmation_email($email_type_d, $registration_id) {
$emailRefId = $this->event_email_recipient_model->queue_reservation_email([
'event_schedule_id' => $this->EVENT_SCHEDULE_ID,
'reference_id' => $registration_id,
'email_type_id' => $email_type_d,
'email_status' => '0'
]);
if (!$emailRefId)
return $this->responseFormatter("EVENT_RESERVATION_EMIAL_ERR");
}
private function add_log($action, $registration_id) {
$this->user_activity_log_model->add_activity_log([
"description" => $action." Paid Event Reservations",
"user_id" => $this->USER_ID,
"action" => $action,
"table_origin" => "event_registration_paid_event",
"reference_id" => $registration_id
]);
}
private function add_paid_event_entry($registration_id) {
$this->RESERVATION_OTHER_DETAILS['registration_id'] = $registration_id;
return $this->event_registration_paid_event_model->add_paid_event($this->RESERVATION_OTHER_DETAILS);
}
private function responseFormatter($message, $httpStatus = REST_Controller::HTTP_BAD_REQUEST) {
$this->responseHandler(self::EVENT_RESPONSE[$message], $httpStatus);
}
}