Commit 9d166ae5 authored by droces's avatar droces

Much more reorganisation of PHP files in Abookings and Booking modules

parent b67de5a6
......@@ -9,9 +9,9 @@
*
* abookings_help()
* abookings_theme()
* abookings_node_form_validate()
* booking_form_validate()
* validate_promo()
* save_promo_line_item()
* create_promo_line_item()
* submission_apply_promotion()
* abookings_node_form_submit()
* abookings_mail()
......@@ -21,11 +21,7 @@
* check_confirmed_bookings()
* complete_booking()
* // abookings_entity_update()
* attach_booking_assets()
* get_seasons_data()
* get_bookings_data()
* abookings_form_node_season_edit_form_alter()
* validate_season()
* attach_booking_data()
*/
use Drupal\Core\Routing\RouteMatchInterface;
......@@ -78,10 +74,10 @@ function abookings_theme() {
/**
* Form validation handler for node forms. Only used for booking nodes.
* Form validation handler for booking node forms. Only used for booking nodes.
*/
function abookings_node_form_validate($form, FormStateInterface &$form_state) {
// kint('abookings_node_form_validate()');
function booking_form_validate($form, FormStateInterface &$form_state) {
// kint('booking_form_validate()');
// kint($form, '$form');
// kint($form_state, '$form_state');
......@@ -127,6 +123,9 @@ function abookings_node_form_validate($form, FormStateInterface &$form_state) {
/**
* Form submission validation for promotion nodes.
*/
function validate_promo($form_state, $promo_code_provided, $checkin_date, $nights) {
$promo;
try {
......@@ -160,12 +159,13 @@ function validate_promo($form_state, $promo_code_provided, $checkin_date, $night
// kint($discount, '$discount');
$booking = $form_state->getFormObject()->getEntity();
// kint($booking, '$booking');
save_promo_line_item($promo_code_provided, $discount, $booking, $checkin_date);
$promo = create_promo_line_item($promo_code_provided, $discount, $booking, $checkin_date);
$promo->save();
}
function save_promo_line_item($code, $amount, $booking, $date) {
function create_promo_line_item($code, $amount, $booking, $date) {
// kint($code, '$code');
// kint($booking, '$booking');
// kint($date, '$date');
......@@ -180,7 +180,7 @@ function save_promo_line_item($code, $amount, $booking, $date) {
'field_date' => $date->format('Y-m-d H:i:s'),
]);
// kint($promo, '$promo');
$promo->save();
return $promo;
}
......@@ -385,16 +385,6 @@ function expire_booking($booking, $bookable) {
// Send expire email to guest
send_expired_booking_email($booking, $bookable);
// Send expire email to owner
// $recipients_string = \Drupal::config('abookings.bookingsettings')
// ->get('notifn_emails_addresses');
// $recipients = explode(',', $recipients_string);
// foreach ($recipients as $email_key => $address) {
// send_owner_email();
// }
// Set booking status to expired
$booking->set('field_booking_status', 'expired');
......@@ -481,16 +471,6 @@ function complete_booking($booking, $bookable) {
send_completed_booking_email($booking, $bookable);
// Send emails to owner
// $recipients_string = \Drupal::config('abookings.bookingsettings')
// ->get('notifn_emails_addresses');
// $recipients = explode(',', $recipients_string);
// foreach ($recipients as $key => $address) {
// send_owner_email();
// }
// Change status to completed
$booking->set('field_booking_status', 'completed');
......@@ -517,7 +497,10 @@ function complete_booking($booking, $bookable) {
// }
function attach_booking_assets(&$renderable) {
/**
* Provides booking-related data needed by JS to any renderable object (such as a form).
*/
function attach_booking_data(&$renderable) {
$renderable['#attached']['drupalSettings'] = [
'seasons' => get_seasons_data(),
'bookings' => get_bookings_data(),
......@@ -539,93 +522,3 @@ function attach_booking_assets(&$renderable) {
'name' => \Drupal::routeMatch()->getRouteName(),
];
}
function get_seasons_data() {
$seasons_renderable = [];
$seasons_data = views_get_view_result('data_seasons');
// kint($seasons_data, '$seasons_data');
foreach ($seasons_data as $season_data) {
$season = $season_data->_entity;
// Get Start date as unix timestamp
$start_iso_8601_date = $season->get('field_start_date')->get(0)
->getValue()['value'];
$start_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $start_iso_8601_date)->format('U'); // 'c'
// Get End date as unix timestamp
$end_iso_8601_date = $season->get('field_end_date')->get(0)
->getValue()['value'];
$end_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $end_iso_8601_date)->format('U'); // 'c'
// Add season data to drupalSettings (for JS to use)
$seasons_renderable[$season->id()] = [
'field_start_date' => $start_timestamp,
'field_end_date' => $end_timestamp,
'field_seasonal_price' => $season->get('field_seasonal_price')->getValue()[0]['value'],
];
}
// kint($content['#attached']['drupalSettings']['seasons'], 'seasons_data settings');
return $seasons_renderable;
}
function get_bookings_data() {
$bookings_renderable = [];
$bookings_data = views_get_view_result('data_bookings');
// kint($seasons_data, '$seasons_data');
foreach ($bookings_data as $booking_data) {
$booking = $booking_data->_entity;
// Get Check-in date as unix timestamp
$checkin_iso_8601_date = $booking->get('field_checkin_date')->get(0)
->getValue()['value'];
$checkin_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $checkin_iso_8601_date)->format('U'); // 'c'
// Get Check-out date as unix timestamp
$checkout_iso_8601_date = $booking->get('field_checkout_date')->get(0)
->getValue()['value'];
$checkout_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $checkout_iso_8601_date)->format('U'); // 'c'
// Add booking data to drupalSettings (for JS to use)
$bookings_renderable[$booking->id()] = [
'field_checkin_date' => $checkin_timestamp,
'field_checkout_date' => $checkout_timestamp,
'field_booking_status' => $booking->get('field_booking_status')->getValue()[0]['value'],
];
}
// kint($content['#attached']['drupalSettings']['seasons'], 'seasons_data settings');
return $bookings_renderable;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function abookings_form_node_season_edit_form_alter(&$form,
\Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
$form['#validate'][] = 'validate_season';
}
function validate_season(array &$form, FormStateInterface $form_state) {
// kint($form, '$form');
// kint($form_state, '$form_state');
// Get dates as unix timestamps
$start_date = $form_state->getValue('field_start_date')[0]['value']->format('U');
$end_date = $form_state->getValue('field_end_date')[0]['value']->format('U');
if ($start_date > $end_date) {
$msg = 'End date must be after start date';
$form_state->setErrorByName('field_start_date');
$form_state->setErrorByName('field_end_date', t($msg));
}
}
......@@ -10,6 +10,8 @@
* get_bookables()
* get_bookings()
* get_promo()
* get_seasons_data()
* get_bookings_data()
**/
......@@ -123,3 +125,77 @@ function get_promo($code_provided, $checkin_date, $nights) {
}
return NULL;
}
/**
* Gets data of all seasons. Uses 'data_seasons' view.
*/
function get_seasons_data() {
$seasons_renderable = [];
$seasons_data = views_get_view_result('data_seasons');
// kint($seasons_data, '$seasons_data');
foreach ($seasons_data as $season_data) {
$season = $season_data->_entity;
// Get Start date as unix timestamp
$start_iso_8601_date = $season->get('field_start_date')->get(0)
->getValue()['value'];
$start_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $start_iso_8601_date)->format('U'); // 'c'
// Get End date as unix timestamp
$end_iso_8601_date = $season->get('field_end_date')->get(0)
->getValue()['value'];
$end_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $end_iso_8601_date)->format('U'); // 'c'
// Add season data to drupalSettings (for JS to use)
$seasons_renderable[$season->id()] = [
'field_start_date' => $start_timestamp,
'field_end_date' => $end_timestamp,
'field_seasonal_price' => $season->get('field_seasonal_price')->getValue()[0]['value'],
];
}
// kint($content['#attached']['drupalSettings']['seasons'], 'seasons_data settings');
return $seasons_renderable;
}
/**
* Gets data of all bookings. Uses 'data_bookings' view.
*/
function get_bookings_data() {
$bookings_renderable = [];
$bookings_data = views_get_view_result('data_bookings');
// kint($seasons_data, '$seasons_data');
foreach ($bookings_data as $booking_data) {
$booking = $booking_data->_entity;
// Get Check-in date as unix timestamp
$checkin_iso_8601_date = $booking->get('field_checkin_date')->get(0)
->getValue()['value'];
$checkin_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $checkin_iso_8601_date)->format('U'); // 'c'
// Get Check-out date as unix timestamp
$checkout_iso_8601_date = $booking->get('field_checkout_date')->get(0)
->getValue()['value'];
$checkout_timestamp = \Drupal\Core\Datetime\DrupalDateTime
::createFromFormat('Y-m-d', $checkout_iso_8601_date)->format('U'); // 'c'
// Add booking data to drupalSettings (for JS to use)
$bookings_renderable[$booking->id()] = [
'field_checkin_date' => $checkin_timestamp,
'field_checkout_date' => $checkout_timestamp,
'field_booking_status' => $booking->get('field_booking_status')->getValue()[0]['value'],
];
}
// kint($content['#attached']['drupalSettings']['seasons'], 'seasons_data settings');
return $bookings_renderable;
}
This diff is collapsed.
<?php
/**
* @file
* Description...
**/
/**
* CONTENTS
*
* get_booking_costs()
* get_booking_total_cost()
* build_costs_markup()
**/
use Drupal\node\Entity\Node;
/**
* Calculates each type of cost and line item, and provides markup for all.
*/
function get_booking_costs(Node $booking) {
$base_cost = $booking->get('field_base_cost')->getValue();
// kint($base_cost, '$base_cost');
if ((! $base_cost) || ($base_cost[0] === [])) {
$base_cost = [['value' => 0]];
}
$base_cost = $base_cost[0]['value'];
$base_cost = floatval($base_cost);
// kint($base_cost, '$base_cost');
$totals = [
'base_cost' => $base_cost,
'total_cost' => get_booking_total_cost($booking->id(), $base_cost),
'total_payable' => NULL,
'amount_due' => NULL,
];
$balance = $base_cost;
// Promos
$promos = get_line_items($booking->id(), 'promotion');
foreach ($promos as $nid => $promo) {
$amount = $promo->get('field_amount')->getValue()[0]['value'];
$balance -= $amount;
}
$totals['total_payable'] = $balance;
// Payments
$payments = get_line_items($booking->id(), 'payment');
foreach ($payments as $nid => $payment) {
$amount = $payment->get('field_amount')->getValue()[0]['value'];
$balance -= $amount;
}
$totals['amount_due'] = $balance;
return $totals;
}
/**
* @param $booking_nid
* @param float $base_cost
*/
function get_booking_total_cost($booking_nid, $base_cost) {
$balance = $base_cost;
// Additions
$additions = get_line_items($booking_nid, 'addition');
foreach ($additions as $nid => $addition) {
$amount = $addition->get('field_amount')->getValue()[0]['value'];
$balance += $amount;
}
// Deductions
$deductions = get_line_items($booking_nid, 'deduction');
foreach ($deductions as $nid => $deduction) {
$amount = $deduction->get('field_amount')->getValue()[0]['value'];
$balance -= $amount;
}
// Addons
$addons = views_get_view_result('data_addons', NULL, $booking_nid);
foreach ($addons as $index => $resultRow) {
$addon = $resultRow->_entity;
$amount = $addon->get('field_amount')->getValue()[0]['value'];
$balance += $amount;
}
return $balance;
}
/**
* Calculates each type of cost and line item, and provides markup for all.
*/
function build_costs_markup(Node $booking) {
$booking_costs = get_booking_costs($booking);
$balance = $booking_costs['base_cost'];
$markup = '<h3 class="entity-meta__title">Costs</h3>'
. '<table>';
// Base cost
$markup .=
' <tr><td>Base cost</td><td>' . $booking_costs['base_cost'] . '</td></tr>';
// Additions
$additions = get_line_items($booking->id(), 'addition');
foreach ($additions as $nid => $addition) {
$amount = $addition->get('field_amount')->getValue()[0]['value'];
$markup .=
' <tr><td>+ <strong class="tag">Addition</strong> ' . $addition->getTitle() . '</td>'
. '<td>' . $amount . '</td></tr>';
}
if (count($additions) == 0) {
$markup .= ' <tr><td><em>No additions</em></td><td></td></tr>';
}
// Deductions
$deductions = get_line_items($booking->id(), 'deduction');
foreach ($deductions as $nid => $deduction) {
$amount = $deduction->get('field_amount')->getValue()[0]['value'];
$markup .=
' <tr><td>- <strong class="tag">Deduction</strong> ' . $deduction->getTitle() . '</td>'
. '<td>(' . $amount . ')</td></tr>';
}
if (count($deductions) == 0) {
$markup .= ' <tr><td><em>No deductions</em></td><td></td></tr>';
}
// Addons
$addons = views_get_view_result('data_addons', NULL, $booking->id());
foreach ($addons as $index => $resultRow) {
$addon = $resultRow->_entity;
$amount = $addon->get('field_amount')->getValue()[0]['value'];
$markup .=
' <tr><td>+ <strong class="tag">Addon</strong> ' . $addon->getTitle() . '</td>'
. '<td>' . $amount . '</td></tr>';
}
if (count($addons) == 0) {
$markup .= ' <tr><td><em>No addons</em></td><td></td></tr>';
}
// Total cost
$markup .=
' <tr class="total"><td>= Total cost</td><td>' . $booking_costs['total_cost'] . '</td></tr>';
// Promos
$promos = get_line_items($booking->id(), 'promotion');
foreach ($promos as $nid => $promo) {
$amount = $promo->get('field_amount')->getValue()[0]['value'];
$markup .=
' <tr><td>- <strong class="tag">Promotion</strong> ' . $promo->getTitle() . '</td>'
. '<td>(' . $amount . ')</td></tr>';
}
if (count($promos) == 0) {
$markup .= ' <tr><td><em>No promotions</em></td><td></td></tr>';
}
// Total payable
$markup .=
' <tr class="total"><td>= Total payable</td><td>' . $booking_costs['total_payable'] . '</td></tr>';
// Payments
$payments = get_line_items($booking->id(), 'payment');
foreach ($payments as $nid => $payment) {
$amount = $payment->get('field_amount')->getValue()[0]['value'];
$markup .=
' <tr><td>- <strong class="tag">Payment</strong> ' . $payment->getTitle() . '</td>'
. '<td>(' . $amount . ')</td></tr>';
}
if (count($payments) == 0) {
$markup .= ' <tr><td><em>No payments</em></td><td></td></tr>';
}
// Balance due
$markup .=
' <tr class="total"><td>= Balance due</td><td>' . $booking_costs['amount_due'] . '</td></tr>'
. '</table>';
return $markup;
}
<?php
/**
* @file
* Functions that modify booking-related node forms.
**/
/**
* CONTENTS
*
* all_booking_form_alter()
* be_booking_form_alter()
* fe_booking_form_alter()
* line_item_form_alter()
**/
use Drupal\Core\Form\FormStateInterface;
/**
* Edits all booking forms.
*/
function all_booking_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// kint($form, '$form');
// kint($form_state, '$form_state');
$build_info_args = $form_state->getBuildInfo()['args'];
$bookable_nid = \Drupal::config('abookings.bookingsettings')->get('bookable');
$form['field_history']['#access'] = FALSE;
// If this site represents just a single bookable
if ($bookable_nid) {
$form['field_bookable_unit']['widget']['#options'] = [$bookable_nid => 'Bookable unit'];
$form['field_bookable_unit']['widget']['#default_value'] = [$bookable_nid];
$form['field_bookable_unit']['#attributes']['class'][] = 'hidden';
// kint($form, '$form');
}
// Unneeded node settings
$form['revision_information']['#access'] = FALSE;
// Add custom validate / submit callback function
$form['actions']['publish']['#submit'][] = 'abookings_node_form_submit';
$form['#validate'][] = 'booking_form_validate';
// Add button for validating the promo
$form['field_promo_code_provided']['widget'][0]['validate_button'] = [
'#type' => 'button',
'#value' => t('Validate'),
'#attributes' => [
'id' => 'validate_promo',
'class' => ['right align-right'],
],
'#weight' => -1,
];
$form['field_promo_code_provided']['widget'][0]['discount'] = [
'#markup' => '<span class="discount"></span>',
'#weight' => 1,
];
$bookable_nid = \Drupal::config('abookings.bookingsettings')->get('bookable');
$bookable = node_load($bookable_nid);
// kint($bookable, '$bookable');
if (! in_array("/book", $build_info_args)) {
be_booking_form_alter($form, $form_state, $form_id);
}
attach_booking_data($form);
// kint($form, '$form');
}
/**
* Edits the booking form for the backend (administration).
*/
function be_booking_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// kint($form, '$form');
$form['costs'] = [
'#type' => 'fieldset',
// '#group' => 'advanced',
// '#title' => t('Costs'),
'title' => ['#markup' => '<h2 class="entity-meta__title">Booking details</h2>'],
'intro' => ['#markup' => '<p>If you change these, <em><a href="#edit-actions">save this booking</a></em> to see updated costs on the right.</p>'],
'#open' => TRUE,
'#weight' => -100,
// '#optional' => FALSE,
];
$form['field_reminder_sent_deposit']['#access'] = FALSE;
$form['field_bookable_unit']['#group'] = 'costs';
$form['field_num_guests']['#group'] = 'costs';
$form['field_num_nights']['#group'] = 'costs';
$form['field_checkin_date']['#group'] = 'costs';
$form['field_checkout_date']['#group'] = 'costs';
$form['field_addons']['#group'] = 'costs';
$form['field_base_cost']['#group'] = 'costs';
$booking = $form_state->getFormObject()->getEntity();
// kint($booking, '$booking');
$form['history'] = [
'#type' => 'container',
'#group' => 'advanced',
'emails' => [
'#markup' => get_history_as_markup($booking),
],
'#attributes' => [
'class' => ['entity-meta__header'],
],
'#weight' => 100,
];
$form['costs_line_items'] = [
'#type' => 'fieldset',
// '#group' => 'costs',
'items_table' => [
'#markup' => build_costs_markup($booking),
],
'#weight' => -95,
];
$form['status_email_send'] = [
'#type' => 'checkbox',
'#return_value' => 'send',
'#title' => t('Send an email if status has been updated'),
'#default_value' => 'send',
'#weight' => 50,
];
$booking_costs = get_booking_costs($booking);
// kint($booking_costs, '$booking_costs');
$form['#attached']['library'][] = 'abookings/booking_form';
// kint($form, '$form');
}
/**
* Edits the booking form for the frontend (Book page).
*/
function fe_booking_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// kint($form, '$form');
$build_info_args = $form_state->getBuildInfo()['args'];
// $form['title']['#access'] = FALSE;
if (in_array('/book', $build_info_args)) {
// kint($form, '$form');
// $form['field_checkin_date']['#attributes']['class'][] = 'hidden';
// $form['field_checkout_date']['#attributes']['class'][] = 'hidden';
$form['field_base_cost']['#attributes']['class'][] = 'hidden';
$form['field_num_nights']['#attributes']['class'][] = 'hidden';
$form['field_checkin_date']['#weight'] = -10;
$form['field_checkout_date']['#weight'] = -9;
$form['calendar'] = [
'#prefix' => '<div class="">',
'#suffix' => '</div>',
'#type' => 'markup',
'calendar' => [
'#markup' => '<div id="calendar"></div>',
],
'#weight' => 1,
];
$form_items_to_deaccess = [
'title',
'field_booking_status',
'field_paid_status',
'field_reminder_sent_deposit',
// 'field_history', // Hidden from form above
'path',
'author',
'advanced',
'options',
];
foreach ($form_items_to_deaccess as $name) {
$form[$name]['#access'] = FALSE;
}
$form_items_to_keep = [
'field_bookable_unit',
'field_num_guests',
'field_num_nights',
'field_checkin_date',
'field_checkout_date',
'field_addons',
'field_promo_code_provided',
'field_last_name',
'field_first_name',
'field_phone_number',
'field_phone_number_alt',
'field_email_address',
'field_country',
'field_notes',
'field_amount_due',
'field_base_cost',
];
foreach (array_keys($form) as $key) {
// kint($key, '$key');
$is_field = (substr($key, 0, 6) === 'field_') ? TRUE : FALSE;
// kint($is_field, '$is_field');
if (! $is_field) {
continue;
}
if (! in_array($key, $form_items_to_keep)) {
// kint($key, 'Removing access to: $key');
$form[$key]['#access'] = FALSE;
}
}
// kint($form, '$form');
$form_items_to_hide = [
'field_amount_due',
'field_base_cost',
];
foreach ($form_items_to_hide as $name) {
$form[$name]['#attributes']['class'][] =
'hidden';
}
// Unneeded actions
$form['actions']['unpublish']['#access'] = FALSE;
$form['actions']['preview']['#access'] = FALSE;
$form['actions']['delete']['#access'] = FALSE;
unset($form['actions']['publish']['#dropbutton']);
}
}
function line_item_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// kint($form, '$form');
// kint($form_state, '$form_state');
$booking = \Drupal::routeMatch()->getParameter('node');
// kint($booking, '$booking');
$form['field_booking']['widget'][0]['target_id']['#default_value'] =
$booking;
$form_state->setRebuild();
$form_state->disableRedirect();
// Unneeded node settings
$form['revision_information']['#access'] = FALSE;
$form['path']['#access'] = FALSE;
$form['author']['#access'] = FALSE;
$form['advanced'