PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / inc / modules / delivery-pickup / admin / options.php

options.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 2.3.2, at inc/modules/delivery-pickup/admin/options.php

1,435 lines 50.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Delivery & Pickup — Option group definitions.
4 *
5 * @package Merchant
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 // Choices used by more than one field, built once.
13 $weekday_choices = Merchant_Admin_Options::get_weekday_choices();
14 $zone_choices = Merchant_Admin_Options::get_shipping_zone_select2_choices();
15 $category_choices = Merchant_Admin_Options::get_category_select2_choices();
16 $brand_choices = Merchant_Admin_Options::get_brand_select2_choices();
17
18 // Time-only preset; stored value is always H:i.
19 $time_picker = array(
20 'onlyTimepicker' => true,
21 'timeFormat' => 'HH:mm',
22 'minDate' => '',
23 );
24
25 // Subject: short single-value tags only; rest goes in the body.
26 $subject_merge_tags = array(
27 '{customer_name}' => esc_html__( 'the customer’s first name', 'merchant' ),
28 '{order_number}' => esc_html__( 'the order number', 'merchant' ),
29 '{fulfilment_type}' => esc_html__( 'your Delivery or Pickup label, whichever the order chose', 'merchant' ),
30 '{delivery_date}' => esc_html__( 'the booking date, in the format you set for the checkout', 'merchant' ),
31 '{delivery_slot}' => esc_html__( 'the booking slot, as 09:00–11:00', 'merchant' ),
32 '{location_name}' => esc_html__( 'the pickup location’s name, empty on a delivery', 'merchant' ),
33 );
34
35 // Out of subject: long text and links read as spam.
36 $body_only_tags = array(
37 '{location_address}' => esc_html__( 'the pickup location’s address, empty on a delivery', 'merchant' ),
38 '{collection_notes}' => esc_html__( 'the collection notes you set on the pickup location', 'merchant' ),
39 '{reschedule_link}' => esc_html__( 'the web address the customer changes the booking at, empty while self-service rescheduling is off', 'merchant' ),
40 '{ics_link}' => esc_html__( 'the web address the calendar file downloads from, empty while the calendar download is off', 'merchant' ),
41 );
42
43 $body_merge_tags = array_merge(
44 $subject_merge_tags,
45 $body_only_tags,
46 array(
47 '{booking_details}' => esc_html__( 'a table of every part of the order, in the columns you ticked under Order Emails. Reach for it when orders can arrive in more than one delivery, since the tags above only describe whichever part arrives first', 'merchant' ),
48 '{order_details}' => esc_html__( 'the items, quantities and totals, the way WooCommerce prints them in its own order emails', 'merchant' ),
49 )
50 );
51
52 // Subject may show where it moved; details stay in message.
53 $subject_moved_tags = array(
54 '{previous_delivery}' => esc_html__( 'the date and slot the booking moved from, empty when the order had no booking until now', 'merchant' ),
55 '{new_delivery}' => esc_html__( 'the date and slot it moved to', 'merchant' ),
56 );
57
58 $moved_merge_tags = array_merge(
59 $subject_moved_tags,
60 array(
61 '{moved_booking}' => esc_html__( 'what moved (the items in that part, or the whole order when it arrives in one piece)', 'merchant' ),
62 '{moved_part}' => esc_html__( 'the number of the part that moved, empty unless the order arrives in several', 'merchant' ),
63 )
64 );
65
66 /**
67 * One "Show more" panel listing the tags a single field reads.
68 *
69 * @param array<string, string> $tags Tag to description.
70 *
71 * @return string
72 */
73 $merge_tag_panel = static function ( array $tags ): string {
74 $lines = array();
75
76 foreach ( $tags as $tag => $description ) {
77 $lines[] = '<strong>' . $tag . ':</strong> ' . $description;
78 }
79
80 return implode( '<br>', $lines );
81 };
82
83 return array(
84
85 array(
86 'title' => esc_html__( 'Delivery Schedules', 'merchant' ),
87 'module' => Merchant_Delivery_Pickup::MODULE_ID,
88 'fields' => array(
89 array(
90 'id' => 'schedules',
91 'type' => 'flexible_content',
92 'button_label' => esc_html__( 'Add New Schedule', 'merchant' ),
93 'style' => Merchant_Delivery_Pickup::MODULE_ID . '-style default',
94 'sorting' => true,
95 'duplicate' => true,
96 'accordion' => true,
97 'layouts' => array(
98 'schedule' => array(
99 'title' => esc_html__( 'Schedule', 'merchant' ),
100 'title-field' => 'schedule_title',
101 'status-field' => 'schedule_status',
102 'fields' => array(
103 array(
104 'id' => 'schedule_status',
105 'type' => 'select',
106 'title' => esc_html__( 'Status', 'merchant' ),
107 'options' => array(
108 'active' => esc_html__( 'Active', 'merchant' ),
109 'inactive' => esc_html__( 'Inactive', 'merchant' ),
110 ),
111 'default' => 'active',
112 'ai_meta' => array(
113 'usage_hint' => 'Controls whether this schedule is active or inactive. Set to active to enable, inactive to disable.',
114 ),
115 ),
116 array(
117 'id' => 'schedule_title',
118 'type' => 'text',
119 'title' => esc_html__( 'Schedule name', 'merchant' ),
120 'default' => esc_html__( 'Standard delivery', 'merchant' ),
121 ),
122 array(
123 'id' => 'fulfilment_type',
124 'type' => 'radio',
125 'title' => esc_html__( 'Fulfilment type', 'merchant' ),
126 'options' => array(
127 'delivery' => esc_html__( 'Delivery', 'merchant' ),
128 'pickup' => esc_html__( 'Pickup', 'merchant' ),
129 ),
130 'default' => 'delivery',
131 'ai_meta' => array(
132 'usage_hint' => 'Whether this schedule offers delivery to the customer address or collection from a pickup location.',
133 ),
134 ),
135
136 array(
137 'id' => 'availability_divider',
138 'type' => 'divider',
139 'title' => esc_html__( 'Availability', 'merchant' ),
140 ),
141 array(
142 'id' => 'available_days',
143 'type' => 'checkbox_multiple',
144 'title' => esc_html__( 'Available days', 'merchant' ),
145 'options' => $weekday_choices,
146 'default' => array( 'mon', 'tue', 'wed', 'thu', 'fri' ),
147 'conditions' => array(
148 'relation' => 'AND',
149 'terms' => array(
150 array(
151 'field' => 'slot_mode',
152 'operator' => 'in',
153 'value' => array( 'time_slots', 'date_only' ),
154 ),
155 ),
156 ),
157 ),
158 array(
159 'id' => 'lead_time',
160 'type' => 'number',
161 'title' => esc_html__( 'Lead time', 'merchant' ),
162 'desc' => esc_html__( 'Delay bookings by this much so you have time to prepare. 1 day hides today, 2 days hides today and tomorrow.', 'merchant' ),
163 'default' => 1,
164 'min' => 0,
165 'step' => 1,
166 'conditions' => array(
167 'relation' => 'AND',
168 'terms' => array(
169 array(
170 'field' => 'slot_mode',
171 'operator' => 'in',
172 'value' => array( 'time_slots', 'date_only' ),
173 ),
174 ),
175 ),
176 ),
177 array(
178 'id' => 'lead_time_unit',
179 'type' => 'select',
180 'title' => esc_html__( 'Lead time unit', 'merchant' ),
181 'options' => array(
182 'hours' => esc_html__( 'Hours', 'merchant' ),
183 'days' => esc_html__( 'Days', 'merchant' ),
184 ),
185 'default' => 'days',
186 'conditions' => array(
187 'relation' => 'AND',
188 'terms' => array(
189 array(
190 'field' => 'slot_mode',
191 'operator' => 'in',
192 'value' => array( 'time_slots', 'date_only' ),
193 ),
194 ),
195 ),
196 ),
197 array(
198 'id' => 'max_days_ahead',
199 'type' => 'number',
200 'title' => esc_html__( 'Bookable window (days)', 'merchant' ),
201 'desc' => esc_html__( 'How far into the future customers can book.', 'merchant' ),
202 'default' => 14,
203 'min' => 1,
204 'step' => 1,
205 'conditions' => array(
206 'relation' => 'AND',
207 'terms' => array(
208 array(
209 'field' => 'slot_mode',
210 'operator' => 'in',
211 'value' => array( 'time_slots', 'date_only' ),
212 ),
213 ),
214 ),
215 ),
216 array(
217 'id' => 'cutoff_time',
218 'type' => 'date_time',
219 'title' => esc_html__( 'Daily cut-off time', 'merchant' ),
220 'desc' => esc_html__( 'Orders placed after this time move to the next available day.', 'merchant' ),
221 'placeholder' => '14:00',
222 'default' => '14:00',
223 'options' => $time_picker,
224 'conditions' => array(
225 'relation' => 'AND',
226 'terms' => array(
227 array(
228 'field' => 'slot_mode',
229 'operator' => 'in',
230 'value' => array( 'time_slots', 'date_only' ),
231 ),
232 ),
233 ),
234 ),
235 array(
236 'id' => 'allow_same_day',
237 'type' => 'switcher',
238 'title' => esc_html__( 'Allow same-day', 'merchant' ),
239 'default' => 0,
240 'conditions' => array(
241 'relation' => 'AND',
242 'terms' => array(
243 array(
244 'field' => 'slot_mode',
245 'operator' => 'in',
246 'value' => array( 'time_slots', 'date_only' ),
247 ),
248 ),
249 ),
250 ),
251 array(
252 'id' => 'blackout_dates',
253 'type' => 'sortable_repeater',
254 'title' => esc_html__( 'Blackout dates', 'merchant' ),
255 'desc' => esc_html__( 'Dates you never deliver or open, one per row, in YYYY-MM-DD format.', 'merchant' ),
256 'button_label' => esc_html__( 'Add Date', 'merchant' ),
257 'default' => array(),
258 'conditions' => array(
259 'relation' => 'AND',
260 'terms' => array(
261 array(
262 'field' => 'slot_mode',
263 'operator' => 'in',
264 'value' => array( 'time_slots', 'date_only' ),
265 ),
266 ),
267 ),
268 ),
269 array(
270 'id' => 'repeat_blackouts_yearly',
271 'type' => 'switcher',
272 'title' => esc_html__( 'Repeat blackout dates every year', 'merchant' ),
273 'default' => 0,
274 'conditions' => array(
275 'relation' => 'AND',
276 'terms' => array(
277 array(
278 'field' => 'slot_mode',
279 'operator' => 'in',
280 'value' => array( 'time_slots', 'date_only' ),
281 ),
282 ),
283 ),
284 ),
285
286 array(
287 'id' => 'slots_divider',
288 'type' => 'divider',
289 'title' => esc_html__( 'Time slots & capacity', 'merchant' ),
290 ),
291 array(
292 'id' => 'slot_mode',
293 'type' => 'select',
294 'title' => esc_html__( 'What customers pick', 'merchant' ),
295 'options' => array(
296 'time_slots' => esc_html__( 'Date and time slot', 'merchant' ),
297 'date_only' => esc_html__( 'Date only', 'merchant' ),
298 'fulfilment' => esc_html__( 'Neither (no date to choose)', 'merchant' ),
299 ),
300 'default' => 'time_slots',
301 'desc' => esc_html__( 'Pick the last option when you cannot commit to a day yet. Customers choose delivery or collection and you arrange the timing with them. Capacity limits, reminders and rescheduling all need a date, so they do not apply.', 'merchant' ),
302 ),
303 array(
304 'id' => 'slot_window_start',
305 'type' => 'date_time',
306 'title' => esc_html__( 'Slots start at', 'merchant' ),
307 'placeholder' => '09:00',
308 'default' => '09:00',
309 'options' => $time_picker,
310 'conditions' => array(
311 'relation' => 'AND',
312 'terms' => array(
313 array(
314 'field' => 'slot_mode',
315 'operator' => '===',
316 'value' => 'time_slots',
317 ),
318 ),
319 ),
320 ),
321 array(
322 'id' => 'slot_window_end',
323 'type' => 'date_time',
324 'title' => esc_html__( 'Slots end at', 'merchant' ),
325 'placeholder' => '18:00',
326 'default' => '18:00',
327 'options' => $time_picker,
328 'conditions' => array(
329 'relation' => 'AND',
330 'terms' => array(
331 array(
332 'field' => 'slot_mode',
333 'operator' => '===',
334 'value' => 'time_slots',
335 ),
336 ),
337 ),
338 ),
339 array(
340 'id' => 'slot_duration',
341 'type' => 'select',
342 'title' => esc_html__( 'Slot length', 'merchant' ),
343 'options' => Merchant_Delivery_Pickup_Choices::slot_durations(),
344 'default' => '120',
345 'conditions' => array(
346 'relation' => 'AND',
347 'terms' => array(
348 array(
349 'field' => 'slot_mode',
350 'operator' => '===',
351 'value' => 'time_slots',
352 ),
353 ),
354 ),
355 ),
356 array(
357 'id' => 'capacity_per_day',
358 'type' => 'number',
359 'title' => esc_html__( 'Orders per day', 'merchant' ),
360 'desc' => esc_html__( 'Leave at 0 for unlimited.', 'merchant' ),
361 'default' => 0,
362 'min' => 0,
363 'step' => 1,
364 'conditions' => array(
365 'relation' => 'AND',
366 'terms' => array(
367 array(
368 'field' => 'slot_mode',
369 'operator' => 'in',
370 'value' => array( 'time_slots', 'date_only' ),
371 ),
372 ),
373 ),
374 ),
375 array(
376 'id' => 'capacity_per_slot',
377 'type' => 'number',
378 'title' => esc_html__( 'Orders per slot', 'merchant' ),
379 'desc' => esc_html__( 'Leave at 0 for unlimited.', 'merchant' ),
380 'default' => 0,
381 'min' => 0,
382 'step' => 1,
383 'conditions' => array(
384 'relation' => 'AND',
385 'terms' => array(
386 array(
387 'field' => 'slot_mode',
388 'operator' => '===',
389 'value' => 'time_slots',
390 ),
391 ),
392 ),
393 ),
394 array(
395 'id' => 'show_remaining',
396 'type' => 'switcher',
397 'title' => esc_html__( 'Show how many places are left', 'merchant' ),
398 'desc' => esc_html__( 'Adds a "2 left" badge to slots that are nearly full.', 'merchant' ),
399 'default' => 1,
400 'conditions' => array(
401 'relation' => 'AND',
402 'terms' => array(
403 array(
404 'field' => 'slot_mode',
405 'operator' => 'in',
406 'value' => array( 'time_slots', 'date_only' ),
407 ),
408 ),
409 ),
410 ),
411 array(
412 'id' => 'remaining_threshold',
413 'type' => 'number',
414 'title' => esc_html__( 'Show the badge when places left are this many or fewer', 'merchant' ),
415 'default' => 3,
416 'min' => 1,
417 'step' => 1,
418 'conditions' => array(
419 'relation' => 'AND',
420 'terms' => array(
421 array(
422 'field' => 'show_remaining',
423 'operator' => '===',
424 'value' => true,
425 ),
426 ),
427 ),
428 ),
429
430 array(
431 'id' => 'pricing_divider',
432 'type' => 'divider',
433 'title' => esc_html__( 'Pricing', 'merchant' ),
434 ),
435 array(
436 'id' => 'charge_fee',
437 'type' => 'switcher',
438 'title' => esc_html__( 'Charge for this schedule', 'merchant' ),
439 'default' => 0,
440 ),
441 array(
442 'id' => 'fee_type',
443 'type' => 'select',
444 'title' => esc_html__( 'Charge type', 'merchant' ),
445 'options' => array(
446 'fixed' => esc_html__( 'Fixed amount', 'merchant' ),
447 'percentage' => esc_html__( 'Percentage of the cart subtotal, after discounts', 'merchant' ),
448 'per_item' => esc_html__( 'Amount per item', 'merchant' ),
449 ),
450 'default' => 'fixed',
451 'conditions' => array(
452 'relation' => 'AND',
453 'terms' => array(
454 array(
455 'field' => 'charge_fee',
456 'operator' => '===',
457 'value' => true,
458 ),
459 ),
460 ),
461 ),
462 array(
463 'id' => 'fee_amount',
464 'type' => 'number',
465 'title' => esc_html__( 'Amount', 'merchant' ),
466 'default' => 0,
467 'min' => 0,
468 'step' => 0.01,
469 'conditions' => array(
470 'relation' => 'AND',
471 'terms' => array(
472 array(
473 'field' => 'charge_fee',
474 'operator' => '===',
475 'value' => true,
476 ),
477 ),
478 ),
479 ),
480 array(
481 'id' => 'same_day_fee',
482 'type' => 'number',
483 'title' => esc_html__( 'Same-day surcharge', 'merchant' ),
484 'desc' => esc_html__( 'Added on top when the customer picks today.', 'merchant' ),
485 'default' => 0,
486 'min' => 0,
487 'step' => 0.01,
488 'conditions' => array(
489 'relation' => 'AND',
490 'terms' => array(
491 array(
492 'field' => 'charge_fee',
493 'operator' => '===',
494 'value' => true,
495 ),
496 array(
497 'field' => 'allow_same_day',
498 'operator' => '===',
499 'value' => true,
500 ),
501 ),
502 ),
503 ),
504 array(
505 'id' => 'weekend_fee',
506 'type' => 'number',
507 'title' => esc_html__( 'Weekend surcharge', 'merchant' ),
508 'default' => 0,
509 'min' => 0,
510 'step' => 0.01,
511 'conditions' => array(
512 'relation' => 'AND',
513 'terms' => array(
514 array(
515 'field' => 'charge_fee',
516 'operator' => '===',
517 'value' => true,
518 ),
519 ),
520 ),
521 ),
522 array(
523 'id' => 'free_over_cart_total',
524 'type' => 'number',
525 'title' => esc_html__( 'Free when the cart reaches', 'merchant' ),
526 'desc' => esc_html__( 'Checked against the subtotal of the items going the same way, after discounts and excluding tax, so items being collected do not buy free delivery. Leave at 0 to always charge.', 'merchant' ),
527 'default' => 0,
528 'min' => 0,
529 'step' => 0.01,
530 'conditions' => array(
531 'relation' => 'AND',
532 'terms' => array(
533 array(
534 'field' => 'charge_fee',
535 'operator' => '===',
536 'value' => true,
537 ),
538 ),
539 ),
540 ),
541 array(
542 'id' => 'fee_taxable',
543 'type' => 'switcher',
544 'title' => esc_html__( 'Charge tax on the fee', 'merchant' ),
545 'default' => 1,
546 'conditions' => array(
547 'relation' => 'AND',
548 'terms' => array(
549 array(
550 'field' => 'charge_fee',
551 'operator' => '===',
552 'value' => true,
553 ),
554 ),
555 ),
556 ),
557 array(
558 'id' => 'fee_tax_class',
559 'type' => 'select',
560 'title' => esc_html__( 'Tax class', 'merchant' ),
561 'options' => Merchant_Delivery_Pickup_Choices::tax_classes(),
562 'default' => 'inherit',
563 'conditions' => array(
564 'relation' => 'AND',
565 'terms' => array(
566 array(
567 'field' => 'charge_fee',
568 'operator' => '===',
569 'value' => true,
570 ),
571 array(
572 'field' => 'fee_taxable',
573 'operator' => '===',
574 'value' => true,
575 ),
576 ),
577 ),
578 ),
579
580 array(
581 'id' => 'eligibility_divider',
582 'type' => 'divider',
583 'title' => esc_html__( 'Who gets this schedule', 'merchant' ),
584 ),
585 array(
586 'id' => 'eligibility_info',
587 'type' => 'info',
588 'content' => esc_html__( 'Leave everything untouched to offer it to every cart.', 'merchant' ),
589 ),
590 array(
591 'id' => 'rules_to_display',
592 'type' => 'select',
593 'title' => esc_html__( 'Applies to', 'merchant' ),
594 'options' => array(
595 'all' => esc_html__( 'All Products', 'merchant' ),
596 'products' => esc_html__( 'Specific Products', 'merchant' ),
597 'categories' => esc_html__( 'Specific Categories', 'merchant' ),
598 'tags' => esc_html__( 'Specific Tags', 'merchant' ),
599 'brands' => esc_html__( 'Specific Brands', 'merchant' ),
600 ),
601 'default' => 'all',
602 'ai_meta' => array(
603 'semantic_group' => 'product_targeting',
604 'usage_hint' => 'Controls which products this schedule applies to. Set this BEFORE setting product_ids, category_slugs, tag_slugs or brand_slugs — those fields are conditional on this value.',
605 ),
606 ),
607 array(
608 'id' => 'product_ids',
609 'type' => 'products_selector',
610 'title' => esc_html__( 'Products', 'merchant' ),
611 'multiple' => true,
612 'desc' => esc_html__( 'Only carts containing these products can use the schedule.', 'merchant' ),
613 'conditions' => array(
614 'relation' => 'AND',
615 'terms' => array(
616 array(
617 'field' => 'rules_to_display',
618 'operator' => '===',
619 'value' => 'products',
620 ),
621 ),
622 ),
623 'allowed_types' => array( 'simple', 'variable' ),
624 'ai_meta' => array(
625 'entity' => 'product',
626 'value_format' => 'product_id',
627 'semantic_group' => 'product_targeting',
628 'usage_hint' => 'Use when targeting specific products. Requires rules_to_display=products.',
629 ),
630 ),
631 array(
632 'id' => 'category_slugs',
633 'type' => 'select_ajax',
634 'title' => esc_html__( 'Categories', 'merchant' ),
635 'source' => 'options',
636 'multiple' => true,
637 'options' => $category_choices,
638 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
639 'conditions' => array(
640 'relation' => 'AND',
641 'terms' => array(
642 array(
643 'field' => 'rules_to_display',
644 'operator' => '===',
645 'value' => 'categories',
646 ),
647 ),
648 ),
649 'ai_meta' => array(
650 'entity' => 'category',
651 'taxonomy' => 'product_cat',
652 'value_format' => 'slug',
653 'semantic_group' => 'product_targeting',
654 'usage_hint' => 'Use when targeting products by category. Requires rules_to_display=categories.',
655 ),
656 ),
657 array(
658 'id' => 'tag_slugs',
659 'type' => 'select_ajax',
660 'title' => esc_html__( 'Tags', 'merchant' ),
661 'source' => 'options',
662 'multiple' => true,
663 'options' => Merchant_Admin_Options::get_tag_select2_choices(),
664 'placeholder' => esc_html__( 'Select tags', 'merchant' ),
665 'conditions' => array(
666 'relation' => 'AND',
667 'terms' => array(
668 array(
669 'field' => 'rules_to_display',
670 'operator' => '===',
671 'value' => 'tags',
672 ),
673 ),
674 ),
675 ),
676 array(
677 'id' => 'brand_slugs',
678 'type' => 'select_ajax',
679 'title' => esc_html__( 'Brands', 'merchant' ),
680 'source' => 'options',
681 'multiple' => true,
682 'options' => $brand_choices,
683 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
684 'conditions' => array(
685 'relation' => 'AND',
686 'terms' => array(
687 array(
688 'field' => 'rules_to_display',
689 'operator' => '===',
690 'value' => 'brands',
691 ),
692 ),
693 ),
694 ),
695 array(
696 'id' => 'enable_exclusions',
697 'type' => 'switcher',
698 'title' => esc_html__( 'Exclude some products', 'merchant' ),
699 'desc' => esc_html__( 'Carts containing an excluded product cannot use this schedule.', 'merchant' ),
700 'default' => 0,
701 ),
702 // Excluded axis hides when "Applies to" already targets it.
703 array(
704 'id' => 'excluded_product_ids',
705 'type' => 'products_selector',
706 'title' => esc_html__( 'Excluded products', 'merchant' ),
707 'multiple' => true,
708 'conditions' => array(
709 'relation' => 'AND',
710 'terms' => array(
711 array(
712 'field' => 'enable_exclusions',
713 'operator' => '===',
714 'value' => true,
715 ),
716 array(
717 'field' => 'rules_to_display',
718 'operator' => '!==',
719 'value' => 'products',
720 ),
721 ),
722 ),
723 'allowed_types' => array( 'simple', 'variable' ),
724 ),
725 array(
726 'id' => 'excluded_category_slugs',
727 'type' => 'select_ajax',
728 'title' => esc_html__( 'Excluded categories', 'merchant' ),
729 'source' => 'options',
730 'multiple' => true,
731 'options' => $category_choices,
732 'placeholder' => esc_html__( 'Select categories', 'merchant' ),
733 'conditions' => array(
734 'relation' => 'AND',
735 'terms' => array(
736 array(
737 'field' => 'enable_exclusions',
738 'operator' => '===',
739 'value' => true,
740 ),
741 array(
742 'field' => 'rules_to_display',
743 'operator' => '!==',
744 'value' => 'categories',
745 ),
746 ),
747 ),
748 ),
749 array(
750 'id' => 'excluded_brand_slugs',
751 'type' => 'select_ajax',
752 'title' => esc_html__( 'Excluded brands', 'merchant' ),
753 'source' => 'options',
754 'multiple' => true,
755 'options' => $brand_choices,
756 'placeholder' => esc_html__( 'Select brands', 'merchant' ),
757 'conditions' => array(
758 'relation' => 'AND',
759 'terms' => array(
760 array(
761 'field' => 'enable_exclusions',
762 'operator' => '===',
763 'value' => true,
764 ),
765 array(
766 'field' => 'rules_to_display',
767 'operator' => '!==',
768 'value' => 'brands',
769 ),
770 ),
771 ),
772 ),
773 array(
774 'id' => 'shipping_zone_ids',
775 'type' => 'select_ajax',
776 'title' => esc_html__( 'Shipping zones', 'merchant' ),
777 'source' => 'options',
778 'multiple' => true,
779 'options' => $zone_choices,
780 'placeholder' => esc_html__( 'Any zone', 'merchant' ),
781 'desc' => esc_html__( 'Restrict the schedule to customers in these zones.', 'merchant' ),
782 ),
783 array(
784 'id' => 'shipping_method_ids',
785 'type' => 'select_ajax',
786 'title' => esc_html__( 'Shipping methods', 'merchant' ),
787 'source' => 'options',
788 'multiple' => true,
789 'options' => Merchant_Admin_Options::get_shipping_method_select2_choices(),
790 'placeholder' => esc_html__( 'Any shipping method', 'merchant' ),
791 // A collected order has no shipping rate to restrict.
792 'conditions' => array(
793 'relation' => 'AND',
794 'terms' => array(
795 array(
796 'field' => 'fulfilment_type',
797 'operator' => '===',
798 'value' => 'delivery',
799 ),
800 ),
801 ),
802 ),
803 array(
804 'id' => 'payment_gateway_ids',
805 'type' => 'select_ajax',
806 'title' => esc_html__( 'Payment methods', 'merchant' ),
807 'source' => 'options',
808 'multiple' => true,
809 'options' => Merchant_Admin_Options::get_payment_gateway_select2_choices(),
810 'placeholder' => esc_html__( 'Any payment method', 'merchant' ),
811 'desc' => esc_html__( 'Useful when a courier only accepts prepaid orders.', 'merchant' ),
812 ),
813 array(
814 'id' => 'user_role_slugs',
815 'type' => 'select_ajax',
816 'title' => esc_html__( 'User roles', 'merchant' ),
817 'source' => 'options',
818 'multiple' => true,
819 'options' => Merchant_Admin_Options::get_user_roles_select2_choices(),
820 'placeholder' => esc_html__( 'Any customer', 'merchant' ),
821 'desc' => esc_html__( 'Keep wholesale route days for wholesale accounts only.', 'merchant' ),
822 ),
823 array(
824 'id' => 'min_cart_total',
825 'type' => 'number',
826 'title' => esc_html__( 'Minimum cart total', 'merchant' ),
827 'desc' => esc_html__( 'Checked against the cart subtotal after discounts. Leave at 0 to accept any order value.', 'merchant' ),
828 'default' => 0,
829 'min' => 0,
830 'step' => 0.01,
831 ),
832 ),
833 ),
834 ),
835 ),
836 ),
837 ),
838
839 array(
840 'title' => esc_html__( 'Pickup Locations', 'merchant' ),
841 'module' => Merchant_Delivery_Pickup::MODULE_ID,
842 'fields' => array(
843 array(
844 'id' => 'suppress_core_pickup',
845 'type' => 'switcher',
846 'title' => esc_html__( 'Hide WooCommerce Local Pickup', 'merchant' ),
847 'desc' => esc_html__( 'These locations replace it, so customers are not offered pickup twice at checkout.', 'merchant' ),
848 'default' => 1,
849 ),
850 array(
851 'id' => 'pickup_locations',
852 'type' => 'flexible_content',
853 'button_label' => esc_html__( 'Add New Location', 'merchant' ),
854 'style' => Merchant_Delivery_Pickup::MODULE_ID . '-style default',
855 'sorting' => true,
856 'duplicate' => true,
857 'accordion' => true,
858 'layouts' => array(
859 'location' => array(
860 'title' => esc_html__( 'Location', 'merchant' ),
861 'title-field' => 'location_name',
862 'status-field' => 'location_status',
863 'fields' => array(
864 array(
865 'id' => 'location_status',
866 'type' => 'select',
867 'title' => esc_html__( 'Status', 'merchant' ),
868 'options' => array(
869 'active' => esc_html__( 'Active', 'merchant' ),
870 'inactive' => esc_html__( 'Inactive', 'merchant' ),
871 ),
872 'default' => 'active',
873 ),
874 array(
875 'id' => 'location_name',
876 'type' => 'text',
877 'title' => esc_html__( 'Location name', 'merchant' ),
878 'default' => esc_html__( 'Main store', 'merchant' ),
879 ),
880 array(
881 'id' => 'address',
882 'type' => 'text',
883 'title' => esc_html__( 'Address', 'merchant' ),
884 'placeholder' => esc_html__( '12 High Street', 'merchant' ),
885 ),
886 array(
887 'id' => 'city',
888 'type' => 'text',
889 'title' => esc_html__( 'City', 'merchant' ),
890 ),
891 array(
892 'id' => 'postcode',
893 'type' => 'text',
894 'title' => esc_html__( 'Postcode', 'merchant' ),
895 ),
896 array(
897 'id' => 'collection_notes',
898 'type' => 'textarea',
899 'title' => esc_html__( 'Collection notes', 'merchant' ),
900 'desc' => esc_html__( 'Shown next to the location at checkout and repeated in the order email.', 'merchant' ),
901 ),
902 array(
903 'id' => 'location_hours_divider',
904 'type' => 'divider',
905 'title' => esc_html__( 'Opening hours & capacity', 'merchant' ),
906 ),
907 array(
908 'id' => 'open_days',
909 'type' => 'checkbox_multiple',
910 'title' => esc_html__( 'Open days', 'merchant' ),
911 'options' => $weekday_choices,
912 'default' => array( 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ),
913 ),
914 array(
915 'id' => 'open_from',
916 'type' => 'date_time',
917 'title' => esc_html__( 'Open from', 'merchant' ),
918 'placeholder' => '09:00',
919 'default' => '09:00',
920 'options' => $time_picker,
921 ),
922 array(
923 'id' => 'open_until',
924 'type' => 'date_time',
925 'title' => esc_html__( 'Open until', 'merchant' ),
926 'placeholder' => '17:30',
927 'default' => '17:30',
928 'options' => $time_picker,
929 ),
930 array(
931 'id' => 'preparation_time',
932 'type' => 'number',
933 'title' => esc_html__( 'Preparation time (hours)', 'merchant' ),
934 'desc' => esc_html__( 'The earliest collection time is pushed out by this much.', 'merchant' ),
935 'default' => 2,
936 'min' => 0,
937 'step' => 1,
938 ),
939 array(
940 'id' => 'collections_per_day',
941 'type' => 'number',
942 'title' => esc_html__( 'Collections per day', 'merchant' ),
943 'desc' => esc_html__( 'Leave at 0 for unlimited.', 'merchant' ),
944 'default' => 0,
945 'min' => 0,
946 'step' => 1,
947 ),
948 array(
949 'id' => 'location_blackout_dates',
950 'type' => 'sortable_repeater',
951 'title' => esc_html__( 'Closed dates', 'merchant' ),
952 'desc' => esc_html__( 'One date per row, in YYYY-MM-DD format.', 'merchant' ),
953 'button_label' => esc_html__( 'Add Date', 'merchant' ),
954 'default' => array(),
955 ),
956 array(
957 'id' => 'location_pricing_divider',
958 'type' => 'divider',
959 'title' => esc_html__( 'Pricing & eligibility', 'merchant' ),
960 ),
961 array(
962 'id' => 'location_fee',
963 'type' => 'number',
964 'title' => esc_html__( 'Collection fee', 'merchant' ),
965 'desc' => esc_html__( 'Use a negative amount to discount collection instead.', 'merchant' ),
966 'default' => 0,
967 'step' => 0.01,
968 ),
969 array(
970 'id' => 'location_zone_ids',
971 'type' => 'select_ajax',
972 'title' => esc_html__( 'Offer to these shipping zones', 'merchant' ),
973 'source' => 'options',
974 'multiple' => true,
975 'options' => $zone_choices,
976 'placeholder' => esc_html__( 'Any zone', 'merchant' ),
977 'desc' => esc_html__( 'WooCommerce shows every pickup location to everyone. This keeps distant customers from picking a shop they cannot reach.', 'merchant' ),
978 ),
979 array(
980 'id' => 'location_category_slugs',
981 'type' => 'select_ajax',
982 'title' => esc_html__( 'Only stocks these categories', 'merchant' ),
983 'source' => 'options',
984 'multiple' => true,
985 'options' => $category_choices,
986 'placeholder' => esc_html__( 'Everything', 'merchant' ),
987 ),
988 array(
989 'id' => 'staff_user_ids',
990 'type' => 'select_ajax',
991 'title' => esc_html__( 'Notify these users', 'merchant' ),
992 'source' => 'user',
993 'multiple' => true,
994 'placeholder' => esc_html__( 'Search users', 'merchant' ),
995 'desc' => esc_html__( 'Everyone listed here gets a copy of every collection order for this location. Users are notified at the address on their account.', 'merchant' ),
996 ),
997 array(
998 'id' => 'staff_emails',
999 'type' => 'sortable_repeater',
1000 'title' => esc_html__( 'Notify these addresses', 'merchant' ),
1001 'desc' => esc_html__( 'For anyone without an account on the store. One address per row, for example shop@example.com.', 'merchant' ),
1002 'button_label' => esc_html__( 'Add Email', 'merchant' ),
1003 'default' => array(),
1004 ),
1005 ),
1006 ),
1007 ),
1008 ),
1009 ),
1010 ),
1011
1012 array(
1013 'title' => esc_html__( 'Checkout Display', 'merchant' ),
1014 'module' => Merchant_Delivery_Pickup::MODULE_ID,
1015 'fields' => array(
1016 array(
1017 'id' => 'date_format',
1018 'type' => 'select',
1019 'title' => esc_html__( 'Date format', 'merchant' ),
1020 'options' => array(
1021 'site_default' => esc_html__( 'Site default', 'merchant' ),
1022 'weekday_day_month' => esc_html__( 'Thu 20 Aug', 'merchant' ),
1023 'day_month' => esc_html__( '20 Aug', 'merchant' ),
1024 'weekday_day_month_year' => esc_html__( 'Thu 20 Aug 2026', 'merchant' ),
1025 'day_month_year' => esc_html__( '20 Aug 2026', 'merchant' ),
1026 'weekday_full' => esc_html__( 'Thursday 20 August', 'merchant' ),
1027 'day_month_name_year' => esc_html__( '20 August 2026', 'merchant' ),
1028 'day_first_numeric' => esc_html__( '20/08/2026', 'merchant' ),
1029 'month_first_numeric' => esc_html__( '08/20/2026', 'merchant' ),
1030 'iso' => esc_html__( '2026-08-20', 'merchant' ),
1031 ),
1032 'default' => 'weekday_day_month',
1033 ),
1034 array(
1035 'id' => 'time_format',
1036 'type' => 'select',
1037 'title' => esc_html__( 'Time format', 'merchant' ),
1038 'options' => array(
1039 'site_default' => esc_html__( 'Site default', 'merchant' ),
1040 'twenty_four' => esc_html__( '09:00', 'merchant' ),
1041 'twenty_four_compact' => esc_html__( '9:00', 'merchant' ),
1042 'twenty_four_dot' => esc_html__( '09.00', 'merchant' ),
1043 'twelve' => esc_html__( '2:00 pm', 'merchant' ),
1044 'twelve_caps' => esc_html__( '2:00 PM', 'merchant' ),
1045 'twelve_hour' => esc_html__( '2 pm', 'merchant' ),
1046 'twelve_hour_caps' => esc_html__( '2 PM', 'merchant' ),
1047 ),
1048 'default' => 'site_default',
1049 ),
1050 array(
1051 'id' => 'show_slot_price',
1052 'type' => 'switcher',
1053 'title' => esc_html__( 'Show the price on each slot', 'merchant' ),
1054 'default' => 1,
1055 ),
1056 array(
1057 'id' => 'show_free_delivery_hint',
1058 'type' => 'switcher',
1059 'title' => esc_html__( 'Show how much more buys free delivery', 'merchant' ),
1060 'desc' => esc_html__( 'Counts up to the nearest "Free when the cart reaches" amount among the schedules on offer. Steps aside while the Free Shipping Progress Bar module is active, so customers see one message.', 'merchant' ),
1061 'default' => 1,
1062 ),
1063 array(
1064 'id' => 'is_required',
1065 'type' => 'switcher',
1066 'title' => esc_html__( 'Require a choice before checkout', 'merchant' ),
1067 'desc' => esc_html__( 'Only enforced when the section actually renders, so a layout without it never blocks checkout.', 'merchant' ),
1068 'default' => 1,
1069 ),
1070 array(
1071 'id' => 'required_message',
1072 'type' => 'text',
1073 'title' => esc_html__( 'Message when nothing is chosen', 'merchant' ),
1074 'desc' => esc_html__( 'Use {items} for the products still waiting on a choice, and {count} for how many there are.', 'merchant' ),
1075 'default' => esc_html__( 'Please choose when you would like your order.', 'merchant' ),
1076 'conditions' => array(
1077 'relation' => 'AND',
1078 'terms' => array(
1079 array(
1080 'field' => 'is_required',
1081 'operator' => '===',
1082 'value' => true,
1083 ),
1084 ),
1085 ),
1086 ),
1087 ),
1088 ),
1089
1090 array(
1091 'title' => esc_html__( 'Order Emails', 'merchant' ),
1092 'module' => Merchant_Delivery_Pickup::MODULE_ID,
1093 'fields' => array(
1094 array(
1095 'id' => 'email_to_customer',
1096 'type' => 'switcher',
1097 'title' => esc_html__( 'Add the block to customer emails', 'merchant' ),
1098 'desc' => esc_html__( 'Order confirmation, processing, completed and the customer invoice.', 'merchant' ),
1099 'default' => 1,
1100 ),
1101 array(
1102 'id' => 'email_to_admin',
1103 'type' => 'switcher',
1104 'title' => esc_html__( 'Add the block to admin emails', 'merchant' ),
1105 'desc' => esc_html__( 'The new order email your team receives.', 'merchant' ),
1106 'default' => 1,
1107 ),
1108 array(
1109 'id' => 'email_block_heading',
1110 'type' => 'text',
1111 'title' => esc_html__( 'Block heading', 'merchant' ),
1112 'default' => esc_html__( 'Delivery details', 'merchant' ),
1113 ),
1114 array(
1115 'id' => 'email_details',
1116 'type' => 'checkbox_multiple',
1117 'title' => esc_html__( 'Show in the block', 'merchant' ),
1118 'options' => array(
1119 'fulfilment' => esc_html__( 'Delivery or pickup', 'merchant' ),
1120 'date' => esc_html__( 'Chosen date', 'merchant' ),
1121 'slot' => esc_html__( 'Chosen time slot', 'merchant' ),
1122 'location' => esc_html__( 'Pickup location and address', 'merchant' ),
1123 'notes' => esc_html__( 'Collection notes', 'merchant' ),
1124 'charge' => esc_html__( 'What the slot cost', 'merchant' ),
1125 ),
1126 'default' => array( 'fulfilment', 'date', 'slot', 'location', 'notes' ),
1127 ),
1128 array(
1129 'id' => 'email_position',
1130 'type' => 'select',
1131 'title' => esc_html__( 'Where in the email', 'merchant' ),
1132 'options' => array(
1133 'before_order_table' => esc_html__( 'Before the order table', 'merchant' ),
1134 'after_order_table' => esc_html__( 'After the order table', 'merchant' ),
1135 'after_customer' => esc_html__( 'After the customer details', 'merchant' ),
1136 ),
1137 'default' => 'after_order_table',
1138 ),
1139 ),
1140 ),
1141
1142 array(
1143 'title' => esc_html__( 'Customer Notifications', 'merchant' ),
1144 'module' => Merchant_Delivery_Pickup::MODULE_ID,
1145 'fields' => array(
1146 array(
1147 'type' => 'divider',
1148 'title' => esc_html__( 'Reminder before the slot', 'merchant' ),
1149 ),
1150 array(
1151 'id' => 'reminder_email',
1152 'type' => 'switcher',
1153 'title' => esc_html__( 'Send a reminder', 'merchant' ),
1154 'desc' => esc_html__( 'Fewer missed deliveries, fewer collections left on the shelf.', 'merchant' ),
1155 'default' => 0,
1156 ),
1157 array(
1158 'id' => 'reminder_hours_before',
1159 'type' => 'number',
1160 'title' => esc_html__( 'Hours before the slot', 'merchant' ),
1161 'default' => 24,
1162 'min' => 1,
1163 'step' => 1,
1164 'conditions' => array(
1165 'relation' => 'AND',
1166 'terms' => array(
1167 array(
1168 'field' => 'reminder_email',
1169 'operator' => '===',
1170 'value' => true,
1171 ),
1172 ),
1173 ),
1174 ),
1175 array(
1176 'id' => 'reminder_email_subject',
1177 'type' => 'text',
1178 'title' => esc_html__( 'Subject', 'merchant' ),
1179 'desc' => esc_html__( 'You can use these codes in the subject. The two that print a table only work in the message.', 'merchant' ),
1180 'hidden_desc' => $merge_tag_panel( $subject_merge_tags ),
1181 'default' => esc_html__( 'Your order arrives {delivery_date}', 'merchant' ),
1182 'conditions' => array(
1183 'relation' => 'AND',
1184 'terms' => array(
1185 array(
1186 'field' => 'reminder_email',
1187 'operator' => '===',
1188 'value' => true,
1189 ),
1190 ),
1191 ),
1192 ),
1193 array(
1194 'id' => 'reminder_email_body',
1195 'type' => 'textarea_multiline',
1196 'title' => esc_html__( 'Message', 'merchant' ),
1197 'desc' => esc_html__( 'You can use these codes in the content.', 'merchant' ),
1198 'hidden_desc' => $merge_tag_panel( $body_merge_tags ),
1199 'default' => __( 'Hello {customer_name}, a quick reminder that order {order_number} is on its way {delivery_date} between {delivery_slot}.', 'merchant' ),
1200 'conditions' => array(
1201 'relation' => 'AND',
1202 'terms' => array(
1203 array(
1204 'field' => 'reminder_email',
1205 'operator' => '===',
1206 'value' => true,
1207 ),
1208 ),
1209 ),
1210 ),
1211
1212 array(
1213 'type' => 'divider',
1214 'title' => esc_html__( 'Ready to collect', 'merchant' ),
1215 ),
1216 array(
1217 'id' => 'ready_email',
1218 'type' => 'switcher',
1219 'title' => esc_html__( 'Tell customers when their order is ready', 'merchant' ),
1220 'desc' => esc_html__( 'Sent when you mark a collection order ready.', 'merchant' ),
1221 'default' => 1,
1222 ),
1223 array(
1224 'id' => 'ready_email_subject',
1225 'type' => 'text',
1226 'title' => esc_html__( 'Subject', 'merchant' ),
1227 'desc' => esc_html__( 'You can use these codes in the subject. The two that print a table only work in the message.', 'merchant' ),
1228 'hidden_desc' => $merge_tag_panel( $subject_merge_tags ),
1229 'default' => esc_html__( 'Your order is ready at {location_name}', 'merchant' ),
1230 'conditions' => array(
1231 'relation' => 'AND',
1232 'terms' => array(
1233 array(
1234 'field' => 'ready_email',
1235 'operator' => '===',
1236 'value' => true,
1237 ),
1238 ),
1239 ),
1240 ),
1241 array(
1242 'id' => 'ready_email_body',
1243 'type' => 'textarea_multiline',
1244 'title' => esc_html__( 'Message', 'merchant' ),
1245 'desc' => esc_html__( 'You can use these codes in the content.', 'merchant' ),
1246 'hidden_desc' => $merge_tag_panel( $body_merge_tags ),
1247 'default' => __( 'Hello {customer_name}, order {order_number} is packed and waiting for you at {location_name}, {location_address}. {collection_notes}', 'merchant' ),
1248 'conditions' => array(
1249 'relation' => 'AND',
1250 'terms' => array(
1251 array(
1252 'field' => 'ready_email',
1253 'operator' => '===',
1254 'value' => true,
1255 ),
1256 ),
1257 ),
1258 ),
1259
1260 array(
1261 'type' => 'divider',
1262 'title' => esc_html__( 'Changed slot', 'merchant' ),
1263 ),
1264 array(
1265 'id' => 'reschedule_email',
1266 'type' => 'switcher',
1267 'title' => esc_html__( 'Confirm a changed date or slot', 'merchant' ),
1268 'desc' => esc_html__( 'Sent whether you moved the order or the customer did.', 'merchant' ),
1269 'default' => 1,
1270 ),
1271 array(
1272 'id' => 'reschedule_email_subject',
1273 'type' => 'text',
1274 'title' => esc_html__( 'Subject', 'merchant' ),
1275 'desc' => esc_html__( 'You can use these codes in the subject. The two that print a table only work in the message.', 'merchant' ),
1276 'hidden_desc' => $merge_tag_panel( array_merge( $subject_merge_tags, $subject_moved_tags ) ),
1277 'default' => esc_html__( 'A new time for order {order_number}', 'merchant' ),
1278 'conditions' => array(
1279 'relation' => 'AND',
1280 'terms' => array(
1281 array(
1282 'field' => 'reschedule_email',
1283 'operator' => '===',
1284 'value' => true,
1285 ),
1286 ),
1287 ),
1288 ),
1289 array(
1290 'id' => 'reschedule_email_body',
1291 'type' => 'textarea_multiline',
1292 'title' => esc_html__( 'Message', 'merchant' ),
1293 'desc' => esc_html__( 'You can use these codes in the content.', 'merchant' ),
1294 'hidden_desc' => $merge_tag_panel( array_merge( $body_merge_tags, $moved_merge_tags ) ),
1295 'default' => __( "Hello {customer_name}, {moved_booking} has been rescheduled to {new_delivery}.\n\n{booking_details}\n\n{order_details}", 'merchant' ),
1296 'conditions' => array(
1297 'relation' => 'AND',
1298 'terms' => array(
1299 array(
1300 'field' => 'reschedule_email',
1301 'operator' => '===',
1302 'value' => true,
1303 ),
1304 ),
1305 ),
1306 ),
1307
1308 array(
1309 'type' => 'divider',
1310 'title' => esc_html__( 'Opting out', 'merchant' ),
1311 ),
1312 array(
1313 'id' => 'unsubscribe_link',
1314 'type' => 'switcher',
1315 'title' => esc_html__( 'Let customers unsubscribe', 'merchant' ),
1316 'desc' => esc_html__( 'Adds an unsubscribe link to the reminder, the ready-to-collect and the changed-slot emails, and a matching checkbox on the account details page. It stops all three.', 'merchant' ),
1317 'default' => 1,
1318 ),
1319 array(
1320 'id' => 'unsubscribe_message',
1321 'type' => 'textarea',
1322 'title' => esc_html__( 'Confirmation message', 'merchant' ),
1323 'desc' => esc_html__( 'Shown after the customer follows the unsubscribe link.', 'merchant' ),
1324 'default' => __( 'You will no longer receive delivery and collection emails from us.', 'merchant' ),
1325 'conditions' => array(
1326 'relation' => 'AND',
1327 'terms' => array(
1328 array(
1329 'field' => 'unsubscribe_link',
1330 'operator' => '===',
1331 'value' => true,
1332 ),
1333 ),
1334 ),
1335 ),
1336
1337 array(
1338 'type' => 'divider',
1339 'title' => esc_html__( 'Telling the shop', 'merchant' ),
1340 ),
1341 array(
1342 'id' => 'reschedule_staff_email',
1343 'type' => 'switcher',
1344 'title' => esc_html__( 'A slot was changed', 'merchant' ),
1345 'desc' => esc_html__( 'Goes to the pickup location\'s staff, and to the store admin when the customer moved it.', 'merchant' ),
1346 'default' => 1,
1347 ),
1348 array(
1349 'id' => 'cancellation_staff_email',
1350 'type' => 'switcher',
1351 'title' => esc_html__( 'A booking was cancelled or refunded', 'merchant' ),
1352 'desc' => esc_html__( 'The slot goes back to the pool quietly. This says so, to the pickup location\'s staff and the store admin.', 'merchant' ),
1353 'default' => 1,
1354 ),
1355
1356 array(
1357 'type' => 'divider',
1358 'title' => esc_html__( 'Self-service', 'merchant' ),
1359 ),
1360 array(
1361 'id' => 'allow_reschedule',
1362 'type' => 'switcher',
1363 'title' => esc_html__( 'Let customers reschedule from My Account', 'merchant' ),
1364 'default' => 0,
1365 ),
1366 array(
1367 'id' => 'reschedule_cutoff_hours',
1368 'type' => 'number',
1369 'title' => esc_html__( 'Stop rescheduling this many hours before the slot', 'merchant' ),
1370 'default' => 24,
1371 'min' => 0,
1372 'step' => 1,
1373 'conditions' => array(
1374 'relation' => 'AND',
1375 'terms' => array(
1376 array(
1377 'field' => 'allow_reschedule',
1378 'operator' => '===',
1379 'value' => true,
1380 ),
1381 ),
1382 ),
1383 ),
1384 array(
1385 'id' => 'customer_ics',
1386 'type' => 'switcher',
1387 'title' => esc_html__( 'Let customers add the slot to their calendar', 'merchant' ),
1388 'desc' => esc_html__( 'Adds an "Add to calendar" link to the customer order emails and to the order page, and turns on the {ics_link} merge tag.', 'merchant' ),
1389 'default' => 0,
1390 ),
1391 ),
1392 ),
1393
1394 array(
1395 'title' => esc_html__( 'Orders & Operations', 'merchant' ),
1396 'module' => Merchant_Delivery_Pickup::MODULE_ID,
1397 'fields' => array(
1398 array(
1399 'id' => 'orders_list_column',
1400 'type' => 'switcher',
1401 'title' => esc_html__( 'Add a delivery column to the orders list', 'merchant' ),
1402 'desc' => esc_html__( 'Sortable and filterable, so you can work a single day at a time.', 'merchant' ),
1403 'default' => 1,
1404 ),
1405 array(
1406 'id' => 'delivery_calendar',
1407 'type' => 'switcher',
1408 'title' => esc_html__( 'Show the delivery calendar', 'merchant' ),
1409 'desc' => esc_html__( 'A month, week and day view of everything booked, with CSV export and print.', 'merchant' ),
1410 'default' => 1,
1411 ),
1412 array(
1413 'id' => 'capacity_unit',
1414 'type' => 'select',
1415 'title' => esc_html__( 'Count capacity in', 'merchant' ),
1416 'desc' => esc_html__( 'What fills up a day or a slot. Count orders when every delivery takes the same effort, one drop per address. Count items when the load is what limits you. A van, a bench or an oven fills up on cakes, not on receipts, so a 20-item order uses twenty places rather than one.', 'merchant' ),
1417 'options' => array(
1418 'orders' => esc_html__( 'Orders', 'merchant' ),
1419 'items' => esc_html__( 'Items', 'merchant' ),
1420 ),
1421 'default' => 'orders',
1422 ),
1423 array(
1424 'type' => 'divider',
1425 'title' => esc_html__( 'A note on your timezone', 'merchant' ),
1426 ),
1427 array(
1428 'id' => 'timezone_info',
1429 'type' => 'info',
1430 'content' => esc_html__( 'Dates, cut-offs and capacity all follow the timezone in Settings > General. Pick a city rather than a UTC offset, otherwise daylight saving shifts every cut-off by an hour twice a year.', 'merchant' ),
1431 ),
1432 ),
1433 ),
1434 );
1435