commerce_gc_client-8.x-1.9/src/PluginForm/RecurrenceRulesFormBase.php
src/PluginForm/RecurrenceRulesFormBase.php
<?php
/**
* @file
* Contains \Drupal\commerce_gc_client\PluginForm\RecurrenceRulesFormBase.
*/
namespace Drupal\commerce_gc_client\PluginForm;
use Drupal\Core\Entity\EntityInterface;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines the RecurrenceRulesFormBase abstract class
*/
abstract class RecurrenceRulesFormBase extends FormBase implements RecurrenceRulesFormInterface {
/**
* @var \Drupal\commerce_product\Entity\ProductVariation.
*/
protected $variation;
/**
* {@inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$build_info = $form_state->getBuildInfo();
if ($build_info['args'] && $build_info['args'][0] instanceof ProductVariation) {
$this->variation = $build_info['args'][0];
}
$gc_variation_types = \Drupal::config('commerce_gc_client.settings')->get('product_variation_types');
if (in_array($this->variation->bundle(), $gc_variation_types)) {
$form['#attached']['library'][] = 'commerce_gc_client/gc_settings_form';
$defaults = ['gc_use' => false];
if ($variation_id = $this->variation->id()) {
if ($fields = commerce_gc_client_get_variation_data($variation_id)) {
$defaults = unserialize($fields->data);
$defaults['gc_use'] = $fields->gc_use;
}
}
if ($form_state->getValues()) {
$gcs = $form_state->getValue('gc');
$flat = [];
array_walk_recursive($gcs['gc_use_container'], function ($item, $key) use (&$flat){$flat[$key] = $item;});
$gcs['gc_use_container'] = $flat;
}
foreach ([
'gc_use' => FALSE,
'gc_type' => 'P',
'gc_interval_length' => 1,
'gc_interval_unit' => 'monthly',
'gc_create_payment' => TRUE,
'gc_start_type' => 'none',
'gc_start_number' => 1,
'gc_start_unit' => NULL,
'gc_start_date' => NULL,
'gc_dow' => NULL,
'gc_dom' => NULL,
'gc_month' => NULL,
'gc_end_type' => 'none',
'gc_end_number' => 1,
'gc_end_unit' => NULL,
'gc_count' => 1,
'gc_end_date' => NULL,
'gc_payment_int' => NULL,
'gc_create_order' => FALSE,
'gc_email_invoice' => FALSE,
] as $key => $value) {
// New and existing variations after ajax has been called.
if (isset($gcs)) {
if ($key == 'gc_use') {
$gc_use = $gcs[$key] ? $gcs[$key] : $value;
}
else {
if (isset($gcs['gc_use_container'][$key])) {
$$key = $gcs['gc_use_container'][$key];
}
else {
$$key = $value;
}
}
}
// Existing variations before ajax has been called.
elseif (isset($defaults[$key])) {
$$key = $defaults[$key];
}
// New variations.
else {
$$key = $value;
}
}
$ajax = [
'callback' => [$this, 'ajax'],
'wrapper' => 'gc-client-product-use-settings-ajax',
'method' => 'replace',
];
$dow_options = [
'Monday' => t('Monday'),
'Tuesday' => t('Tuesday'),
'Wednesday' => t('Wednesday'),
'Thursday' => t('Thursday'),
'Friday' => t('Friday'),
'Saturday' => t('Saturday'),
'Sunday' => t('Sunday'),
];
$dom_options = [];
for ($d = -1; $d <= 28; $d++) {
if ($d == -1) {
$dom_options[$d] = t('Last day of month');
}
elseif ($d == 0) {
continue;
}
else {
$dom_options[$d] = $d;
}
}
$month_options = [];
for ($m = 1; $m <= 12; $m++) {
$mon = t('@month', ['@month' => date('F', mktime(0, 0, 0, $m, 1))]);
$month_options[strtolower($mon)] = $mon;
}
$dow_access = FALSE;
$dom_access = FALSE;
$dom_required = FALSE;
$month_access = FALSE;
$month_required = FALSE;
if ($gc_type == 'S') {
if (in_array($gc_interval_unit, ['monthly', 'yearly']) && $gc_start_type == 'time') {
$dom_access = TRUE;
}
if ($gc_interval_unit == 'yearly' && $gc_start_type == 'time') {
$month_access = TRUE;
$dom_required = TRUE;
$month_required = TRUE;
}
if ($gc_interval_unit == 'monthly') {
$dom_required = TRUE;
}
}
if ($gc_type == 'P' && !$gc_create_payment && $gc_start_type == 'time') {
if ($gc_interval_unit == 'weekly') {
$dow_access = TRUE;
}
if (in_array($gc_interval_unit, ['monthly', 'yearly'])) {
$dom_access = TRUE;
}
if ($gc_interval_unit == 'yearly') {
$month_access = TRUE;
}
$dom_required = TRUE;
}
$yearly_sub = $gc_type == 'S' && $gc_interval_unit == 'yearly' ? TRUE : FALSE;
$start_type_options = [
'relative' => t('Relative to the time of purchase'),
'fixed' => t('Fixed date'),
];
if ($gc_type == 'P' || ($gc_type == 'S' && $gc_interval_unit !== 'weekly')) {
$start_type_options['time'] = t('Time of Week / Month / Year');
}
if ($gc_type == 'P') {
$start_type_options['none'] = t('Not set');
}
else {
$start_type_options = array_merge(['none' => t('Starts immediately on completion of checkout')], $start_type_options);
}
if ($gc_type == 'S' && $gc_start_type == 'time' && $gc_interval_unit == 'weekly') {
$gc_start_type = 'none';
}
$form['gc'] = [
'#type' => 'details',
'#title' => t('GoCardless recurrence settings'),
'#open' => $gc_use ? TRUE : FALSE,
'#group' => 'advanced',
'#attributes' => ['id' => ['gc-client-product-use-settings-ajax']],
'#tree' => TRUE,
];
$markup = '<p>' . t("If you do not use GoCardless recurrence rules with this variant, the module will attempt to make a single 'Instant' non-recurring payment with GoCardless during checkout. If this is not possible a debit mandate and a 'One-off' payment will be created instead.") . '</p>';
$markup .= '<p>' . t("Instant non-recurring payments are single payments created upon checkout by GoCardless using Open Banking protocol and do not require a debit mandate. Open banking does not require credit/debit cards but the experience is similar to other online payment services in that the customer is required to provide their bank details, and to verify the bank account.") . '</p>';
$markup .= '<p>' . t("Subscription and One-off payments both require a debit mandate, which is created automatically upon checkout. Subscriptions are recurring payments that are created automatically by GoCardless according to the instructions that you provide here. One-off payments are recurring payments that are created automatically when your website instructs GoCardless to do so, and are more flexible than Subscription payments. Debit payments take several days to complete following an instruction from GoCardless to the bank to create the payment.") . '</p>';
$markup .= '<p>' . t("Instant payments are only created if none of the products in a cart are using recurrence rules, <i>or</i> if they are One-off payments that are configured to 'Create payment immediately' upon checkout. Instant payments are currenly only available in the UK and Germany. If it is not possible to create an Instant payment upon checkout, a debit mandate will be created instead, and the variant will be paid for with a One-off payment.") . '</p>';
$form['gc']['markup'] = [
'#type' => 'markup',
'#markup' => $markup,
];
$form['gc']['gc_use'] = [
'#type' => 'checkbox',
'#title' => t("Use GoCardless recurrence rules with this product?"),
'#default_value' => $gc_use,
'#ajax' => $ajax,
];
$form['gc']['gc_use_container'] = [
'#type' => 'container',
'#collapsible' => FALSE,
'#access' => $gc_use,
];
$form['gc']['gc_use_container']['gc_type'] = [
'#type' => 'radios',
'#title' => t('Payments type'),
'#default_value' => $gc_type,
'#options' => ['P' => t('One-off payments'), 'S' => t('Subscription')],
'#description' => t('Subscription payments created automatically by GoCardless, or one-off payments created by your website. If you choose any of the Start date, Day of week, or Day of month options, these will be the customer charge date for subscriptions, and the payment creation date for one-off payments. The customer charge date is usually 2 or 3 working days after the payment creation.'),
'#ajax' => $ajax,
];
$form['gc']['gc_use_container']['interval_container'] = [
'#type' => 'fieldset',
'#title' => t('Interval between payments'),
];
$form['gc']['gc_use_container']['interval_container']['gc_interval_length'] = [
'#type' => 'number',
'#title' => t('Length'),
'#default_value' => $yearly_sub ? 1 : $gc_interval_length,
'#size' => 1,
'#min' => 1,
'#step' => 1,
'#ajax' => $ajax,
'#required' => true,
'#attributes' => ['class' => ['gc-settings-form-number-length']],
'#disabled' => $yearly_sub ? TRUE : FALSE,
];
$form['gc']['gc_use_container']['interval_container']['gc_interval_unit'] = [
'#type' => 'select',
'#default_value' => $gc_interval_unit,
'#options' => [
'weekly' => t('Week'),
'monthly' => t('Month'),
'yearly' => t('Year'),
],
'#description' => t("The interval for Subscription payments must result be at least one per year. For One-off payments the interval can be greater but depending on the currency there may be rules about the maximum dormancy period allowed for a debit mandate, that will cause the mandate to expire if payments are too infrequent."),
'#ajax' => $ajax,
'#required' => true,
];
$form['gc']['gc_use_container']['start_container'] = [
'#type' => 'fieldset',
'#title' => t('First payment creation'),
];
$form['gc']['gc_use_container']['start_container']['gc_create_payment'] = [
'#type' => 'checkbox',
'#title' => t('First payment is created during checkout'),
'#default_value' => $gc_create_payment,
'#ajax' => $ajax,
'#access' => $gc_type == 'P',
];
$form['gc']['gc_use_container']['start_container']['gc_start_type'] = [
'#type' => 'radios',
'#title' => t('Setting the first payment date'),
'#default_value' => $gc_start_type,
'#options' => $start_type_options,
'#description' => t("If you are setting a Subscription payment type you must set a start date. If you are using One-off payments and do not set a start date there will be no automatic payment creation but you will be able to create payments manually under the mandate that is created, or set a start date for recurring payments whenever you need."),
'#access' => $gc_type == 'S' || ($gc_type == 'P' && !$gc_create_payment),
'#ajax' => $ajax,
];
$form['gc']['gc_use_container']['start_container']['gc_start_number'] = [
'#title' => t('Period before first payment'),
'#type' => 'number',
'#default_value' => $gc_start_number,
'#size' => 1,
'#min' => 1,
'#step' => 1,
'#attributes' => ['class' => ['gc-settings-form-number-length']],
'#required' => $gc_start_type == 'relative',
'#access' => $gc_type == 'S' && $gc_start_type == 'relative' || ($gc_type == 'P' && !$gc_create_payment && $gc_start_type == 'relative'),
];
$form['gc']['gc_use_container']['start_container']['gc_start_unit'] = [
'#type' => 'select',
'#default_value' => $gc_start_unit,
'#options' => [
'hour' => t('Hour'),
'day' => t('Day'),
'week' => t('Week'),
'month' => t('Month'),
'year' => t('Year'),
],
'#empty_option' => t('- Select -'),
'#description' => t("The time period after the customer completes checkout before the first payment can be created. Recommended within one year of creation of the debit mandate to ensure compliance."),
'#access' => $gc_type == 'S' && $gc_start_type == 'relative' || ($gc_type == 'P' && !$gc_create_payment && $gc_start_type == 'relative'),
'#required' => true,
];
$form['gc']['gc_use_container']['start_container']['gc_start_date'] = [
'#title' => t('Start date'),
'#type' => 'date',
'#date_format' => 'd M Y',
'#datepicker_options' => ['minDate' => 0],
'#date_year_range' => '0:+1',
'#default_value' => $gc_start_date,
'#description' => t("The date on which the first payment should be charged. Must be within one year of purchase."),
'#access' => $gc_start_type == 'fixed' || $gc_start_type == 'time' && ($gc_type == 'S' || ($gc_type == 'P' && !$gc_create_payment)),
'#required' => $gc_start_type !== 'time',
];
$form['gc']['gc_use_container']['start_container']['gc_dow'] = [
'#type' => 'select',
'#title' => t('Day of week'),
'#options' => $dow_options,
'#default_value' => $gc_dow,
'#description' => t("The day of the week to charge customers on."),
'#empty_option' => '- ' . t('select') . ' -',
'#access' => $dow_access,
'#required' => true,
];
$form['gc']['gc_use_container']['start_container']['gc_dom'] = [
'#type' => 'select',
'#title' => t('Day of month'),
'#options' => $dom_options,
'#default_value' => $gc_dom,
'#description' => t("The day of the month to charge customers on. (As per RFC 2445.)"),
'#empty_option' => '- ' . t('select') . ' -',
'#access' => $dom_access,
'#ajax' => $ajax,
'#required' => $gc_month || $dom_required,
];
$form['gc']['gc_use_container']['start_container']['gc_month'] = [
'#type' => 'select',
'#title' => t('Month'),
'#options' => $month_options,
'#default_value' => $gc_month,
'#description' => t("Name of the month on which to charge a customer."),
'#empty_option' => '- ' . t('select') . ' -',
'#access' => $month_access,
'#required' => $month_required,
'#ajax' => $ajax,
];
$form['gc']['gc_use_container']['end_container'] = [
'#type' => 'fieldset',
'#title' => t('Final payment creation'),
];
$form['gc']['gc_use_container']['end_container']['gc_end_type'] = [
'#type' => 'radios',
'#title' => t('Setting the final payment creation'),
'#default_value' => $gc_end_type,
'#options' => [
'none' => t('There is no final payment'),
'count' => t('After a specific number of payments'),
'relative' => t('Relative to the time of purchase'),
'fixed' => t('Fixed date'),
],
'#ajax' => $ajax,
];
$form['gc']['gc_use_container']['end_container']['gc_end_date'] = [
'#title' => t('End date'),
'#type' => 'date',
'#date_format' => 'd M Y',
'#datepicker_options' => ['minDate' => 0],
'#default_value' => $gc_end_date,
'#description' => t("Date on or after which no further payments will be created."),
'#ajax' => $ajax,
'#access' => $gc_end_type == 'fixed',
'#required' => true,
];
$form['gc']['gc_use_container']['end_container']['gc_count'] = [
'#title' => t('Number of payments'),
'#type' => 'number',
'#default_value' => $gc_count,
'#size' => 1,
'#min' => 1,
'#step' => 1,
'#attributes' => ['class' => ['gc-settings-form-number-length']],
'#description' => t("The total number of payments that will be created."),
'#access' => $gc_end_type == 'count',
'#required' => true,
];
$form['gc']['gc_use_container']['end_container']['gc_end_number'] = [
'#title' => t('Period before final payment'),
'#type' => 'number',
'#default_value' => $gc_end_number,
'#size' => 1,
'#min' => 1,
'#step' => 1,
'#attributes' => ['class' => ['gc-settings-form-number-length']],
'#required' => true,
'#access' => $gc_end_type == 'relative',
];
$form['gc']['gc_use_container']['end_container']['gc_end_unit'] = [
'#type' => 'select',
'#default_value' => $gc_end_unit,
'#options' => [
'hour' => t('Hour'),
'day' => t('Day'),
'week' => t('Week'),
'month' => t('Month'),
'year' => t('Year'),
],
'#empty_option' => t('- Select -'),
'#description' => t("The period after the customer completes checkout until payments will stop being created."),
'#access' => $gc_end_type == 'relative',
'#required' => true,
];
$form['gc']['gc_use_container']['gc_create_order'] = [
'#type' => 'checkbox',
'#title' => t("Create an order upon creation of recurring payment"),
'#description' => t("The new order will not create the payment but recurring payments will continue to be created by the parent order. The parent and child orders will reference each other in the GoCardless tab."),
'#default_value' => $gc_create_order,
'#access' => $gc_type == 'P',
'#ajax' => $ajax,
];
$form['gc']['gc_use_container']['gc_email_invoice'] = [
'#type' => 'checkbox',
'#title' => t("Email the user an invoice upon creation of a recurring order"),
'#description' => t("The invoice will have the same number as the recurring order."),
'#default_value' => $gc_email_invoice,
'#access' => $gc_type == 'P' && $gc_create_order,
];
}
$form['gc']['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => $this->t('Save'),
'#button_type' => 'primary',
],
];
return $form;
}
/**
* Ajax callback function..
*/
public function ajax(&$form, &$form_state) {
return $form['gc'];
}
}