Changeset 3729359
- Timestamp:
- 10/05/2026 05:21:01 PM (3 weeks ago)
- Location:
- sales-igniter-rentals-bookings-lite/trunk
- Files:
-
- 1 added
- 38 edited
-
Admin/DataRemovalSettings.php (modified) (2 diffs)
-
Admin/Upgrade.php (modified) (1 diff)
-
Ajax/Calendar.php (modified) (3 diffs)
-
Ajax/Price.php (modified) (2 diffs)
-
Api.php (modified) (2 diffs)
-
Assets/public/js/sibookingCalendarRules.js (modified) (1 diff)
-
Assets/public/js/sibookingCalendarRules.min.js (modified) (1 diff)
-
Assets/public/js/sibookingCalendarUi.js (modified) (1 diff)
-
Assets/public/js/sibookingCalendarUi.min.js (modified) (1 diff)
-
Includes/AdminOrderDates.php (modified) (6 diffs)
-
Includes/BookedBy.php (added)
-
Includes/CartAvailability.php (modified) (1 diff)
-
Includes/Diagnostics.php (modified) (1 diff)
-
Includes/Order.php (modified) (5 diffs)
-
Includes/PendingHold.php (modified) (2 diffs)
-
Includes/Price.php (modified) (2 diffs)
-
Includes/Stays.php (modified) (3 diffs)
-
Includes/StaysSwitch.php (modified) (1 diff)
-
Includes/Validation.php (modified) (1 diff)
-
Languages/acf-strings.php (modified) (4 diffs)
-
Languages/sales-igniter-rentals-bookings-lite.pot (modified) (72 diffs)
-
Model/ACF/group_61d28753aedd5.json (modified) (6 diffs)
-
Model/ACF/group_61d2ba5188b94.json (modified) (5 diffs)
-
Model/Availability.php (modified) (2 diffs)
-
Model/Buffer.php (modified) (6 diffs)
-
Model/DataRemoval.php (modified) (1 diff)
-
Model/DisabledDates.php (modified) (1 diff)
-
Model/FieldSlots.php (modified) (1 diff)
-
Model/Pricing/ConfigFactory.php (modified) (4 diffs)
-
Model/RateLimit.php (modified) (1 diff)
-
Model/ResponseCache.php (modified) (1 diff)
-
Model/Services.php (modified) (1 diff)
-
Model/Stay.php (modified) (5 diffs)
-
bootstrap.php (modified) (2 diffs)
-
composer.json (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
sales-igniter-rentals-bookings-lite.php (modified) (1 diff)
-
vendor/composer/autoload_classmap.php (modified) (3 diffs)
-
vendor/composer/autoload_static.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sales-igniter-rentals-bookings-lite/trunk/Admin/DataRemovalSettings.php
r3728745 r3729359 7 7 /** 8 8 * Rentals > Settings > Advanced > "Delete rental data on uninstall": the double opt-in 9 * (review finding BOOT-05, Kevin's answer to §7 Q8). See Model\DataRemoval.9 * (review finding BOOT-05, the owner's answer to §7 Q8). See Model\DataRemoval. 10 10 * 11 11 * The block is an ACF `message` field whose message is empty; its text and its inputs … … 13 13 * `.acf-input`), NOT put into the field's message: SCF prints a message through 14 14 * acf_esc_html() / wp_kses(), which strips every <input>, so the box and the phrase 15 * never reached the page (found by Kevinon a real install, 2026-09-28).15 * never reached the page (found by the owner on a real install, 2026-09-28). 16 16 * 17 17 * The inputs are this block's own (not ACF's), so nothing about it is stored by ACF: the -
sales-igniter-rentals-bookings-lite/trunk/Admin/Upgrade.php
r3728745 r3729359 90 90 [ __( 'Date and date-and-time rentals with turnover buffers, store hours and closed days', 'sales-igniter-rentals-bookings-lite' ), true, true, true ], 91 91 [ __( 'Stays by the night: check-in and check-out days, prices and turnover in nights', 'sales-igniter-rentals-bookings-lite' ), true, true, true ], 92 [ __( 'Extras for nightly stays: half-day cells for partly booked days, a Stay typebulk action, room-nights in the Usage Report', 'sales-igniter-rentals-bookings-lite' ), false, true, true ],92 [ __( 'Extras for nightly stays: half-day cells for partly booked days, a "Booked by" bulk action, room-nights in the Usage Report', 'sales-igniter-rentals-bookings-lite' ), false, true, true ], 93 93 [ __( 'Guests and party size: a single count, or adults, children, infants and pets with age notes and limits', 'sales-igniter-rentals-bookings-lite' ), true, true, true ], 94 94 [ __( 'Popup Range Picker with the Calendar Styler (four looks, your colours)', 'sales-igniter-rentals-bookings-lite' ), true, true, true ], -
sales-igniter-rentals-bookings-lite/trunk/Ajax/Calendar.php
r3728745 r3729359 96 96 */ 97 97 public function sibooking_calendar(){ 98 // Kevin's answer to review Q10: the shopper calls stay open to visitors, but carry98 // The owner's answer to review Q10: the shopper calls stay open to visitors, but carry 99 99 // the calendar's nonce (sibooking.data.nonce; the scripts renew it on a cached page 100 100 // through sibooking_calendar_fresh) and are rate limited per client … … 452 452 // last day's 00:00, so that day is free to start on and a booked day can be an end 453 453 'returnDayFree' => $dated && \Sibooking\Model\Buffer::startOnReturnDay((int) $settingsId), 454 // "Also charge the return day" (Model\Pricing\ConfigFactory::countsReturnDay()): a 455 // date-only rental's length counts its return day too ("1st to 3rd: 3 days") 456 'chargeReturnDay' => $productid && !$nightly && !\Sibooking\Model\RentalTypes::usesTime(\Sibooking\Model\RentalTypes::of((int) $settingsId)) && \Sibooking\Model\Pricing\ConfigFactory::countsReturnDay((int) $settingsId), 454 457 // date picker selection + styler settings (Model\CalendarStyle); read by 455 458 // sibookingCalendarUi.js, ignored by the previous picker … … 529 532 'dated' => false, 530 533 'returnDayFree' => false, 534 'chargeReturnDay' => false, 531 535 'turnoverBeforeMinutes' => 0, 532 536 'turnoverAfterMinutes' => 0, -
sales-igniter-rentals-bookings-lite/trunk/Ajax/Price.php
r3728745 r3729359 33 33 public function rental_price() { 34 34 check_ajax_referer( 'sibooking-calendar', 'nonce' ); 35 // Kevin's answer to review Q10: open to visitors, rate limited per client35 // The owner's answer to review Q10: open to visitors, rate limited per client 36 36 if ( ! \Sibooking\Model\RateLimit::hit( 'quote' ) ) { 37 37 \Sibooking\Model\RateLimit::refuse(); … … 222 222 $total = (float) $line['total']; 223 223 $breakdown = self::breakdown( $product, $dates['start'], $dates['end'], $unit, $line['engine'] ?? null ); 224 // "Also charge the return day" (Model\Pricing\ConfigFactory): a date-only rental from the 225 // 1st to the 3rd is charged, and so counted, as 3 days 226 if ( ! $nightly && '' === $totime && $to > $from && \Sibooking\Model\Pricing\ConfigFactory::countsReturnDay( $product->get_id() ) ) { 227 $breakdown['days'] = max( 1, \Sibooking\Model\Stay::nights( $from, $to ) ) + 1; 228 } 224 229 $extra = []; 225 230 foreach ( $line['lines'] as $l ) { -
sales-igniter-rentals-bookings-lite/trunk/Api.php
r3728745 r3729359 405 405 } 406 406 407 /** 408 * A product's "Booked by" as the shop set it (its own choice, else the store's "Date-only 409 * rentals are booked by"): days (the return day held), days_free (can go out again on the 410 * return day) or nights. Without a product: the store's. Not filtered (nightly() and 411 * startOnReturnDay() are). 412 * 413 * @since api 1 (Lite 1.0.15) 414 * @param int|null $productId 415 * @return string days | days_free | nights 416 */ 417 public static function bookedBy( $productId = null ) { 418 return $productId ? Stay::rule( (int) $productId ) : Stay::storeRule(); 419 } 420 421 /** 422 * "Also charge the return day" for a product (its own Yes / No, else the store's): a 423 * date-only rental booked by the day from the 1st to the 3rd is then 3 days, not 2. 424 * Stays of nights are priced per night whatever this says. 425 * 426 * @since api 1 (Lite 1.0.15) 427 * @param int $productId 428 * @return bool 429 */ 430 public static function chargesReturnDay( $productId ) { 431 return Model\Pricing\ConfigFactory::chargesReturnDay( $productId ); 432 } 433 407 434 /** @since api 1 @return string a date as the reminder emails print it (Rentals > Settings > Date Formatting) */ 408 435 public static function emailDate( $datetime ) { … … 639 666 640 667 /** 641 * Whether a date-only rental's return day is free for another rental to start on (the 642 * store setting "Allow rentals to start on the same day as they are returned", filter 643 * sibooking_start_on_return_day). Stays of nights and timed rentals never ask. 668 * Whether a date-only rental's return day is free for another rental to start on: the 669 * product is "Booked by" "Days: can go out again on the return day" (bookedBy() is 670 * days_free; until Lite 1.0.15 the store yes/no "Allow rentals to start on the same day as 671 * they are returned"), filter sibooking_start_on_return_day. Stays of nights and timed 672 * rentals never ask. 644 673 * 645 674 * @since api 1 (Lite 1.0.13) -
sales-igniter-rentals-bookings-lite/trunk/Assets/public/js/sibookingCalendarRules.js
r3728745 r3729359 827 827 828 828 /** Whole days between two dates, at least 1 (same day = 1); for a stay of nights, the nights. */ 829 function dayCount(start, end, nightly ) {829 function dayCount(start, end, nightly, chargeReturnDay) { 830 830 var s = toMoment(start).startOf('day'), e = toMoment(end).startOf('day'); 831 return nightly ? Math.max(0, e.diff(s, 'days')) : Math.max(1, e.diff(s, 'days')); 831 if (nightly) return Math.max(0, e.diff(s, 'days')); 832 // "Also charge the return day" (data.chargeReturnDay): the 1st to the 3rd is 3 days 833 if (chargeReturnDay && e.diff(s, 'days') > 0) return e.diff(s, 'days') + 1; 834 return Math.max(1, e.diff(s, 'days')); 832 835 } 833 836 -
sales-igniter-rentals-bookings-lite/trunk/Assets/public/js/sibookingCalendarRules.min.js
r3728745 r3729359 1 (function(c,s){typeof module=="object"&&module.exports?module.exports=s(typeof globalThis!="undefined"&&globalThis.moment?globalThis.moment:require("moment")):c.SibookingCalendarRules=s(c.moment)})(typeof self!="undefined"?self:this,function(c){"use strict";var s="YYYY-MM-DD",Y="23:59",H="00:00";function d(r){return c.isMoment(r)?r.clone():c(r)}function S(r){var e=parseInt(r,10);return isNaN(e)||e<1?1:e}function Q(r,e){var n=S(e),t=[];return(r.fullybooked_dates||[]).forEach(function(i){(r.isComposite&&!r.compositeUnits||n>r.inventoryQuantity-i.quantity)&&t.push(i.date)}),t}function ur(r,e){if(r.isComposite&&!r.compositeUnits||!r.inventoryQuantity||r.inventoryQuantity>=99999)return null;var n=0;return(r.fullybooked_dates||[]).some(function(t){return t.date===e?(n=t.quantity,!0):!1}),Math.max(0,r.inventoryQuantity-n)}function fr(r,e,n){if(r.isComposite&&!r.compositeUnits||r.inventoryQuantity===void 0||r.inventoryQuantity===null||r.inventoryQuantity>=99999)return null;var t=Math.max(0,parseInt(r.inventoryQuantity,10)||0);if(!e||!t)return t;var i=d(e).startOf("day"),o=d(n||e).startOf("day");o.isBefore(i)&&(o=i.clone());var u={};(r.fullybooked_dates||[]).forEach(function(l){u[l.date]=Math.min(u[l.date]===void 0?1/0:u[l.date],t-(parseInt(l.quantity,10)||0))});for(var f=0;!i.isAfter(o,"day")&&f<3660;f++){var a=i.format(s);u[a]!==void 0&&(t=Math.min(t,Math.max(0,u[a]))),i.add(1,"d")}return t}function _(r,e){var n=d(r);if(!e||e.quantity===void 0||e.quantity==="")return n;var t=parseFloat(e.quantity);switch(e.type){case"hours":case"h":n.add(t,"h");break;case"days":case"d":n.add(t,"d");break;case"w":n.add(t,"w");break;case"m":n.add(t,"M");break;case"y":n.add(t,"y");break}return n}function N(r){return r&&typeof r=="object"&&r.quantity!==void 0&&r.quantity!==""&&r.quantity!==null}function ar(r,e){var n=d(r);return n.isSameOrAfter(c(e.from))&&n.isSameOrBefore(c(e.to))}var F=typeof WeakMap=="function"?new WeakMap:null;function P(r){if(r=r||[],F&&F.has(r))return F.get(r);for(var e={},n=[],t=0;t<r.length;t++){var i=r[t];if(typeof i=="string")e[i]=!0;else if(i&&i.from!==void 0){var o=c(i.from),u=c(i.to);o.isValid()&&u.isValid()&&n.push({from:o.valueOf(),to:u.valueOf(),item:i})}}var f={days:e,ranges:n};return F&&F.set(r,f),f}function sr(r){var e=r.split("-"),n=new Date(+e[0],+e[1]-1,+e[2],0,0,0,0).getTime(),t=new Date(+e[0],+e[1]-1,+e[2],23,59,59,999).getTime();return[n,t]}function U(r,e){return W(r,e).length>0}function W(r,e){var n=P(e),t=[];if(n.days[r]&&t.push(r),n.ranges.length)for(var i=sr(r),o=0;o<n.ranges.length;o++){var u=n.ranges[o];u.from<=i[1]&&u.to>=i[0]&&t.push(u.item)}return t}function T(r,e){var n=[];if(!r||!N(e))return n;var t=d(r).startOf("day").add(1,"d"),i=_(d(r).startOf("day"),e);i.isAfter(t,"day")&&n.push(d(r).format(s));for(var o=t.clone();o.isBefore(i,"day");)n.push(o.format(s)),o.add(1,"d");return n}function z(r,e,n){var t=d(r).startOf("day");if(n){var i=t.clone().add(1,"d");if(N(e)){var o=_(t.clone(),e);o.isAfter(i)&&(i=o)}return i.format(s)}if(N(e)){var u=_(t.clone(),e);if(u.isAfter(t))return u.format(s)}return t.format(s)}function V(r,e){if(r){var n={};(e||[]).forEach(function(u){n[u]=!0});for(var t=d(r).startOf("day"),i=0;i<730;i++){var o=t.format(s);if(n[o])return o;t.add(1,"d")}}}function lr(r,e,n,t,i){var o=[];if(r.maxFutureDaysDate&&o.push(c(r.maxFutureDaysDate)),e&&N(r.maxLength)&&o.push(_(d(e),r.maxLength)),e&&r.dated){var u=ir(r,d(e).format(s),i);u&&o.push(c(u,s))}if(e&&t&&r.timed){var f=X(r,d(e).format(s)+" "+t,i);f&&o.push(c(f,s))}if(e){var a=V(e,n);if(a&&r.nightly)o.push(c(a,s).subtract(R(r.bufferAfterDays),"d"));else if(a&&r.dated&&r.returnDayFree){var l=Number(r.bufferAfterMinutes)||0;o.push(c(a,s).subtract(l>0?Math.ceil(l/1440):0,"d"))}else if(a){var v=Number(r.bufferAfterMinutes)||0,h=r.calendarType==="datetime",p=v>0?h?Math.floor(v/1440):Math.ceil(v/1440):0;o.push(p>0?c(a,s).subtract(1+p,"d"):c(a,s))}}if(!o.length)return null;var b=o.reduce(function(D,k){return D.isBefore(k)?D:k});return b.format(s)}function cr(r,e,n,t){if(r.nightly)return vr(r,e,n,t);var i=Q(r,e),o=i.concat(r.disabled_dates||[]),u=o.concat(t||[]).concat(r.disabled_dates_start||[]).concat(r.timed?G(r,e):[]).concat(r.dated?tr(r,e):[]),f=r.dated&&r.returnDayFree?r.disabled_dates||[]:o,a=f.concat(n?T(n,r.minLength):[]).concat(r.disabled_dates_end||[]);return{booked:i,both:o,start:u,end:a}}function R(r){var e=Math.ceil(Number(r)||0);return e>0?e:0}function w(r,e){return d(e).startOf("day").diff(d(r).startOf("day"),"days")}function q(r,e){var n={};return Q(r,e).forEach(function(t){n[t]=!0}),n}function vr(r,e,n,t){var i=q(r,e),o=Object.keys(i).sort(),u=R(r.bufferBeforeDays),f=R(r.bufferAfterDays),a=N(r.minLength)?Math.max(1,w(c("2000-01-01",s),_(c("2000-01-01",s),r.minLength))):1,l={};o.forEach(function(k){for(var M=c(k,s),A=-(a+f-1);A<=u;A++)l[M.clone().add(A,"d").format(s)]=!0});var v=Object.keys(l).sort().concat(r.disabled_dates||[]).concat(t||[]).concat(r.disabled_dates_start||[]);typeof r.inventoryQuantity=="number"&&S(e)>r.inventoryQuantity&&(v=v.concat([{from:"1900-01-01",to:"2999-12-31"}]));var h=[];if(n)for(var p=c(z(n,r.minLength,!0),s),b=d(n).startOf("day");b.isBefore(p,"day");b.add(1,"d"))h.push(b.format(s));var D=(r.disabled_dates||[]).concat(h).concat(r.disabled_dates_end||[]);return{booked:o,both:o.concat(r.disabled_dates||[]),start:v,end:D}}function dr(r,e,n){var t=q(r,e),i=!!t[c(n,s).subtract(1,"d").format(s)],o=!!t[n];return!i&&!o?"free":i&&!o?"checkin-only":!i&&o?"checkout-only":(r.turnover_dates||[]).indexOf(n)!==-1?"turnover":"booked"}var y=1440;function g(r){var e=/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{1,2}):(\d{2}))?/.exec(String(r));return e?Math.round(Date.UTC(+e[1],+e[2]-1,+e[3])/6e4)+(e[4]?+e[4]*60+ +e[5]:0):NaN}function E(r){return new Date(Math.floor(r/y)*864e5).toISOString().slice(0,10)}function yr(r){var e=Math.floor(r/60),n=r%60;return(e<10?"0":"")+e+":"+(n<10?"0":"")+n}function O(r){var e=parseInt(r&&r.turnoverBeforeMinutes,10),n=parseInt(r&&r.turnoverAfterMinutes,10);return{before:e>0?e:0,after:n>0?n:0}}var I=typeof WeakMap=="function"?new WeakMap:null;function C(r){if(!I||!r||typeof r!="object")return null;var e=I.get(r);return(!e||e.list!==r.inventoryArray||e.before!==r.turnoverBeforeMinutes||e.after!==r.turnoverAfterMinutes||e.qty!==r.inventoryQuantity)&&(e={list:r.inventoryArray,before:r.turnoverBeforeMinutes,after:r.turnoverAfterMinutes,qty:r.inventoryQuantity},I.set(r,e)),e}function B(r,e){var n=S(e),t=C(r);if(t&&t["full"+n])return t["full"+n];var i=[];return(r.inventoryArray||[]).forEach(function(o){if(!(!o||!(n>r.inventoryQuantity-o.q))){var u=g(o.s),f=g(o.e);!isNaN(u)&&!isNaN(f)&&f>u&&i.push({s:u,e:f})}}),t&&(t["full"+n]=i),i}function hr(r,e,n){var t=S(n),i=d(e).startOf("day"),o=[];return(r.inventoryArray||[]).forEach(function(u){if(t>r.inventoryQuantity-u.q){var f=c(u.s),a=c(u.e),l=i.isSame(f,"day"),v=i.isSame(a,"day");l&&v?o.push([f.format("HH:mm"),a.format("HH:mm")]):l&&a.isAfter(i,"day")?o.push([f.format("HH:mm"),Y]):v&&f.isBefore(a,"day")?o.push([H,a.format("HH:mm")]):f.isBefore(i,"day")&&a.isAfter(i,"day")&&o.push([H,Y])}}),o}function x(r,e,n,t){for(var i=0;i<r.length;i++)if(n-e.before<r[i].e&&t+e.after>r[i].s)return!0;return!1}function J(r,e){if(!r.minDate||String(r.minDate).slice(0,10)!==e)return null;var n=/[ T](\d{1,2}):(\d{2})(?::(\d{2}))?/.exec(String(r.minDate));if(!n)return null;var t=+n[1]*60+ +n[2]+(n[3]&&+n[3]>0?1:0);return t>0?yr(Math.min(t,y)):null}function j(r,e,n,t,i){i=i||{};var o=d(e).format(s),u=g(o),f=Z(r.storeopen,r.storeclose,r.ui&&r.ui.slotInterval||r.timeIncrement),a={};if(t==="to"&&i.pickup&&String(i.pickup).slice(0,10)===o&&(a.notBefore=String(i.pickup).slice(11,16)),t!=="to"){var l=J(r,o);l&&(a.notEarlierThan=l)}var v=$(f,[],a);if(!f.length)return v;var h=O(r),p=B(r,n),b=m(f[0]),D=m(f[f.length-1]),k=g(t==="to"?i.pickup:i.ret);return v.forEach(function(M,A){if(!M.disabled){var or=u+m(M.time),L=k;isNaN(L)&&(t==="to"?L=A>0?u+m(f[A-1]):u-y+D:L=A<f.length-1?u+m(f[A+1]):u+y+b);var gr=t==="to"?x(p,h,L,or):x(p,h,or,L);gr&&(M.disabled=!0,M.reason="booked")}}),v}function G(r,e){var n=S(e),t=C(r);if(t&&t["np"+n]&&t.minDate===r.minDate&&t.hours===r.storeopen+"-"+r.storeclose)return t["np"+n];var i=O(r),o={},u={};if(B(r,n).forEach(function(l){var v=Math.floor((l.s-i.after)/y),h=Math.floor((l.e+i.before-1)/y);o[v-1]=o[v]=o[h]=o[h+1]=!0;for(var p=v+1,b=0;p<h&&b<3660;p++,b++)u[p]=!0}),r.minDate){var f=g(String(r.minDate).slice(0,10));isNaN(f)||(o[Math.floor(f/y)]=!0)}var a=[];return Object.keys(u).forEach(function(l){o[l]||a.push(E(l*y))}),Object.keys(o).forEach(function(l){var v=E(l*y),h=j(r,v,n,"from").some(function(p){return!p.disabled});h||a.push(v)}),a.sort(),t&&(t["np"+n]=a,t.minDate=r.minDate,t.hours=r.storeopen+"-"+r.storeclose),a}function K(r,e,n){var t=g(e);if(isNaN(t))return null;var i=O(r),o=null;return B(r,n).forEach(function(u){if(u.e>t-i.before){var f=u.s-i.after;(o===null||f<o)&&(o=f)}}),o}function X(r,e,n){var t=K(r,e,n);if(t===null)return null;var i=String(e).slice(0,10),o=E(t);if(o<i)return i;if(j(r,o,n,"to",{pickup:e}).some(function(f){return!f.disabled}))return o;var u=E(Math.floor(t/y)*y-y);return u<i?i:u}function m(r){var e=String(r).split(":");return parseInt(e[0],10)*60+parseInt(e[1]||"0",10)}function Z(r,e,n){var t=parseInt(n,10);(isNaN(t)||t<5)&&(t=30);for(var i=m(r||"08:00"),o=m(e||"18:00"),u=[],f=i;f<=o;f+=t){var a=Math.floor(f/60),l=f%60;u.push((a<10?"0":"")+a+":"+(l<10?"0":"")+l)}return u}function $(r,e,n){return n=n||{},(r||[]).map(function(t){var i=m(t),o=null;return n.notBefore&&i<=m(n.notBefore)?o="before-pickup":n.notAfter&&i>=m(n.notAfter)?o="after-return":n.notEarlierThan&&i<m(n.notEarlierThan)?o="too-early":(e||[]).some(function(u){return i>=m(u[0])&&i<m(u[1])?(o="booked",!0):!1}),{time:t,disabled:o!==null,reason:o}})}function pr(r){for(var e=0;e<r.length;e++)if(!r[e].disabled)return r[e].time;return null}function rr(r,e,n,t){var i=g(d(n).format(s)),o=g(d(t).format(s));return isNaN(i)||isNaN(o)?!1:x(B(r,e),O(r),i,er(r,i,o))}function er(r,e,n){return r.returnDayFree&&n>e?n:n+y-1}function nr(r,e){var n=(r.disabled_dates||[]).concat(r.disabled_dates_end||[]),t={};T(e,r.minLength).forEach(function(f){t[f]=!0});for(var i=c(d(e).format(s),s),o=0;o<400;o++,i.add(1,"d")){var u=i.format(s);if(!t[u]&&!(n.length&&U(u,n)))return u}return d(e).format(s)}function tr(r,e){var n=S(e),t=C(r),i="ns"+n+"|"+JSON.stringify([r.minLength||"",r.disabled_dates_end||[],(r.disabled_dates||[]).length]);if(t&&t[i])return t[i];var o=O(r),u=0;N(r.minLength)&&(u=Math.max(0,w(c("2000-01-01",s),_(c("2000-01-01",s),r.minLength))));var f=(r.disabled_dates||[]).length+(r.disabled_dates_end||[]).length?62:0,a={},l={};B(r,n).forEach(function(h){for(var p=Math.floor((h.s-o.after-(y-1))/y)+1,b=Math.floor((h.e+o.before-1)/y),D=p,k=0;D<=b&&k<3660;D++,k++)a[D]=!0;for(var M=p-u-f-1;M<p;M++)l[M]=!0});var v=Object.keys(a).map(function(h){return E(h*y)});return Object.keys(l).forEach(function(h){if(!a[h]){var p=E(h*y);rr(r,n,p,nr(r,p))&&v.push(p)}}),v.sort(),t&&(t[i]=v),v}function ir(r,e,n){var t=g(e);if(isNaN(t))return null;var i=O(r),o=null;if(B(r,n).forEach(function(a){a.e>t-i.before&&(o===null||a.s<o)&&(o=a.s)}),o===null)return null;var u=r.returnDayFree?0:y-1,f=E(Math.floor((o-i.after-u)/y)*y);return f<e?e:f}function mr(r){return r==="datetime"?["start","starttime","end","endtime"]:["start","end"]}function br(r,e,n){var t=d(r).startOf("day"),i=d(e).startOf("day");return Math.max(n?0:1,i.diff(t,"days"))}return{DAY:s,normalizeQuantity:S,bookedDatesForQuantity:Q,unitsLeft:ur,unitsCap:fr,addLength:_,hasLength:N,inRange:ar,isDayDisabled:U,disabledBy:W,compileDisabled:P,daysFromStartUntilMinDate:T,minEndDate:z,firstFullyBookedFrom:V,maxDate:lr,disabledLists:cr,disabledTimeRangesForDay:hr,turnoverMinutes:O,slotsFor:j,noPickupDays:G,returnCap:K,lastReturnDay:X,dateRentalRefused:rr,dateRentalEnd:er,firstEndDay:nr,noStartDays:tr,lastEndDay:ir,earliestPickupTime:J,absMinutes:g,timeSlots:Z,slotAvailability:$,firstAvailableSlot:pr,toMinutes:m,buildSteps:mr,dayCount:br,nightsBetween:w,dayState:dr,soldNights:q}});1 (function(c,s){typeof module=="object"&&module.exports?module.exports=s(typeof globalThis!="undefined"&&globalThis.moment?globalThis.moment:require("moment")):c.SibookingCalendarRules=s(c.moment)})(typeof self!="undefined"?self:this,function(c){"use strict";var s="YYYY-MM-DD",Y="23:59",H="00:00";function d(r){return c.isMoment(r)?r.clone():c(r)}function S(r){var e=parseInt(r,10);return isNaN(e)||e<1?1:e}function Q(r,e){var n=S(e),t=[];return(r.fullybooked_dates||[]).forEach(function(i){(r.isComposite&&!r.compositeUnits||n>r.inventoryQuantity-i.quantity)&&t.push(i.date)}),t}function fr(r,e){if(r.isComposite&&!r.compositeUnits||!r.inventoryQuantity||r.inventoryQuantity>=99999)return null;var n=0;return(r.fullybooked_dates||[]).some(function(t){return t.date===e?(n=t.quantity,!0):!1}),Math.max(0,r.inventoryQuantity-n)}function ur(r,e,n){if(r.isComposite&&!r.compositeUnits||r.inventoryQuantity===void 0||r.inventoryQuantity===null||r.inventoryQuantity>=99999)return null;var t=Math.max(0,parseInt(r.inventoryQuantity,10)||0);if(!e||!t)return t;var i=d(e).startOf("day"),o=d(n||e).startOf("day");o.isBefore(i)&&(o=i.clone());var f={};(r.fullybooked_dates||[]).forEach(function(l){f[l.date]=Math.min(f[l.date]===void 0?1/0:f[l.date],t-(parseInt(l.quantity,10)||0))});for(var u=0;!i.isAfter(o,"day")&&u<3660;u++){var a=i.format(s);f[a]!==void 0&&(t=Math.min(t,Math.max(0,f[a]))),i.add(1,"d")}return t}function _(r,e){var n=d(r);if(!e||e.quantity===void 0||e.quantity==="")return n;var t=parseFloat(e.quantity);switch(e.type){case"hours":case"h":n.add(t,"h");break;case"days":case"d":n.add(t,"d");break;case"w":n.add(t,"w");break;case"m":n.add(t,"M");break;case"y":n.add(t,"y");break}return n}function N(r){return r&&typeof r=="object"&&r.quantity!==void 0&&r.quantity!==""&&r.quantity!==null}function ar(r,e){var n=d(r);return n.isSameOrAfter(c(e.from))&&n.isSameOrBefore(c(e.to))}var F=typeof WeakMap=="function"?new WeakMap:null;function P(r){if(r=r||[],F&&F.has(r))return F.get(r);for(var e={},n=[],t=0;t<r.length;t++){var i=r[t];if(typeof i=="string")e[i]=!0;else if(i&&i.from!==void 0){var o=c(i.from),f=c(i.to);o.isValid()&&f.isValid()&&n.push({from:o.valueOf(),to:f.valueOf(),item:i})}}var u={days:e,ranges:n};return F&&F.set(r,u),u}function sr(r){var e=r.split("-"),n=new Date(+e[0],+e[1]-1,+e[2],0,0,0,0).getTime(),t=new Date(+e[0],+e[1]-1,+e[2],23,59,59,999).getTime();return[n,t]}function U(r,e){return W(r,e).length>0}function W(r,e){var n=P(e),t=[];if(n.days[r]&&t.push(r),n.ranges.length)for(var i=sr(r),o=0;o<n.ranges.length;o++){var f=n.ranges[o];f.from<=i[1]&&f.to>=i[0]&&t.push(f.item)}return t}function T(r,e){var n=[];if(!r||!N(e))return n;var t=d(r).startOf("day").add(1,"d"),i=_(d(r).startOf("day"),e);i.isAfter(t,"day")&&n.push(d(r).format(s));for(var o=t.clone();o.isBefore(i,"day");)n.push(o.format(s)),o.add(1,"d");return n}function z(r,e,n){var t=d(r).startOf("day");if(n){var i=t.clone().add(1,"d");if(N(e)){var o=_(t.clone(),e);o.isAfter(i)&&(i=o)}return i.format(s)}if(N(e)){var f=_(t.clone(),e);if(f.isAfter(t))return f.format(s)}return t.format(s)}function V(r,e){if(r){var n={};(e||[]).forEach(function(f){n[f]=!0});for(var t=d(r).startOf("day"),i=0;i<730;i++){var o=t.format(s);if(n[o])return o;t.add(1,"d")}}}function lr(r,e,n,t,i){var o=[];if(r.maxFutureDaysDate&&o.push(c(r.maxFutureDaysDate)),e&&N(r.maxLength)&&o.push(_(d(e),r.maxLength)),e&&r.dated){var f=ir(r,d(e).format(s),i);f&&o.push(c(f,s))}if(e&&t&&r.timed){var u=X(r,d(e).format(s)+" "+t,i);u&&o.push(c(u,s))}if(e){var a=V(e,n);if(a&&r.nightly)o.push(c(a,s).subtract(R(r.bufferAfterDays),"d"));else if(a&&r.dated&&r.returnDayFree){var l=Number(r.bufferAfterMinutes)||0;o.push(c(a,s).subtract(l>0?Math.ceil(l/1440):0,"d"))}else if(a){var v=Number(r.bufferAfterMinutes)||0,h=r.calendarType==="datetime",p=v>0?h?Math.floor(v/1440):Math.ceil(v/1440):0;o.push(p>0?c(a,s).subtract(1+p,"d"):c(a,s))}}if(!o.length)return null;var b=o.reduce(function(D,k){return D.isBefore(k)?D:k});return b.format(s)}function cr(r,e,n,t){if(r.nightly)return vr(r,e,n,t);var i=Q(r,e),o=i.concat(r.disabled_dates||[]),f=o.concat(t||[]).concat(r.disabled_dates_start||[]).concat(r.timed?G(r,e):[]).concat(r.dated?tr(r,e):[]),u=r.dated&&r.returnDayFree?r.disabled_dates||[]:o,a=u.concat(n?T(n,r.minLength):[]).concat(r.disabled_dates_end||[]);return{booked:i,both:o,start:f,end:a}}function R(r){var e=Math.ceil(Number(r)||0);return e>0?e:0}function w(r,e){return d(e).startOf("day").diff(d(r).startOf("day"),"days")}function q(r,e){var n={};return Q(r,e).forEach(function(t){n[t]=!0}),n}function vr(r,e,n,t){var i=q(r,e),o=Object.keys(i).sort(),f=R(r.bufferBeforeDays),u=R(r.bufferAfterDays),a=N(r.minLength)?Math.max(1,w(c("2000-01-01",s),_(c("2000-01-01",s),r.minLength))):1,l={};o.forEach(function(k){for(var M=c(k,s),A=-(a+u-1);A<=f;A++)l[M.clone().add(A,"d").format(s)]=!0});var v=Object.keys(l).sort().concat(r.disabled_dates||[]).concat(t||[]).concat(r.disabled_dates_start||[]);typeof r.inventoryQuantity=="number"&&S(e)>r.inventoryQuantity&&(v=v.concat([{from:"1900-01-01",to:"2999-12-31"}]));var h=[];if(n)for(var p=c(z(n,r.minLength,!0),s),b=d(n).startOf("day");b.isBefore(p,"day");b.add(1,"d"))h.push(b.format(s));var D=(r.disabled_dates||[]).concat(h).concat(r.disabled_dates_end||[]);return{booked:o,both:o.concat(r.disabled_dates||[]),start:v,end:D}}function dr(r,e,n){var t=q(r,e),i=!!t[c(n,s).subtract(1,"d").format(s)],o=!!t[n];return!i&&!o?"free":i&&!o?"checkin-only":!i&&o?"checkout-only":(r.turnover_dates||[]).indexOf(n)!==-1?"turnover":"booked"}var y=1440;function g(r){var e=/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{1,2}):(\d{2}))?/.exec(String(r));return e?Math.round(Date.UTC(+e[1],+e[2]-1,+e[3])/6e4)+(e[4]?+e[4]*60+ +e[5]:0):NaN}function E(r){return new Date(Math.floor(r/y)*864e5).toISOString().slice(0,10)}function yr(r){var e=Math.floor(r/60),n=r%60;return(e<10?"0":"")+e+":"+(n<10?"0":"")+n}function O(r){var e=parseInt(r&&r.turnoverBeforeMinutes,10),n=parseInt(r&&r.turnoverAfterMinutes,10);return{before:e>0?e:0,after:n>0?n:0}}var I=typeof WeakMap=="function"?new WeakMap:null;function C(r){if(!I||!r||typeof r!="object")return null;var e=I.get(r);return(!e||e.list!==r.inventoryArray||e.before!==r.turnoverBeforeMinutes||e.after!==r.turnoverAfterMinutes||e.qty!==r.inventoryQuantity)&&(e={list:r.inventoryArray,before:r.turnoverBeforeMinutes,after:r.turnoverAfterMinutes,qty:r.inventoryQuantity},I.set(r,e)),e}function B(r,e){var n=S(e),t=C(r);if(t&&t["full"+n])return t["full"+n];var i=[];return(r.inventoryArray||[]).forEach(function(o){if(!(!o||!(n>r.inventoryQuantity-o.q))){var f=g(o.s),u=g(o.e);!isNaN(f)&&!isNaN(u)&&u>f&&i.push({s:f,e:u})}}),t&&(t["full"+n]=i),i}function hr(r,e,n){var t=S(n),i=d(e).startOf("day"),o=[];return(r.inventoryArray||[]).forEach(function(f){if(t>r.inventoryQuantity-f.q){var u=c(f.s),a=c(f.e),l=i.isSame(u,"day"),v=i.isSame(a,"day");l&&v?o.push([u.format("HH:mm"),a.format("HH:mm")]):l&&a.isAfter(i,"day")?o.push([u.format("HH:mm"),Y]):v&&u.isBefore(a,"day")?o.push([H,a.format("HH:mm")]):u.isBefore(i,"day")&&a.isAfter(i,"day")&&o.push([H,Y])}}),o}function x(r,e,n,t){for(var i=0;i<r.length;i++)if(n-e.before<r[i].e&&t+e.after>r[i].s)return!0;return!1}function J(r,e){if(!r.minDate||String(r.minDate).slice(0,10)!==e)return null;var n=/[ T](\d{1,2}):(\d{2})(?::(\d{2}))?/.exec(String(r.minDate));if(!n)return null;var t=+n[1]*60+ +n[2]+(n[3]&&+n[3]>0?1:0);return t>0?yr(Math.min(t,y)):null}function j(r,e,n,t,i){i=i||{};var o=d(e).format(s),f=g(o),u=Z(r.storeopen,r.storeclose,r.ui&&r.ui.slotInterval||r.timeIncrement),a={};if(t==="to"&&i.pickup&&String(i.pickup).slice(0,10)===o&&(a.notBefore=String(i.pickup).slice(11,16)),t!=="to"){var l=J(r,o);l&&(a.notEarlierThan=l)}var v=$(u,[],a);if(!u.length)return v;var h=O(r),p=B(r,n),b=m(u[0]),D=m(u[u.length-1]),k=g(t==="to"?i.pickup:i.ret);return v.forEach(function(M,A){if(!M.disabled){var or=f+m(M.time),L=k;isNaN(L)&&(t==="to"?L=A>0?f+m(u[A-1]):f-y+D:L=A<u.length-1?f+m(u[A+1]):f+y+b);var gr=t==="to"?x(p,h,L,or):x(p,h,or,L);gr&&(M.disabled=!0,M.reason="booked")}}),v}function G(r,e){var n=S(e),t=C(r);if(t&&t["np"+n]&&t.minDate===r.minDate&&t.hours===r.storeopen+"-"+r.storeclose)return t["np"+n];var i=O(r),o={},f={};if(B(r,n).forEach(function(l){var v=Math.floor((l.s-i.after)/y),h=Math.floor((l.e+i.before-1)/y);o[v-1]=o[v]=o[h]=o[h+1]=!0;for(var p=v+1,b=0;p<h&&b<3660;p++,b++)f[p]=!0}),r.minDate){var u=g(String(r.minDate).slice(0,10));isNaN(u)||(o[Math.floor(u/y)]=!0)}var a=[];return Object.keys(f).forEach(function(l){o[l]||a.push(E(l*y))}),Object.keys(o).forEach(function(l){var v=E(l*y),h=j(r,v,n,"from").some(function(p){return!p.disabled});h||a.push(v)}),a.sort(),t&&(t["np"+n]=a,t.minDate=r.minDate,t.hours=r.storeopen+"-"+r.storeclose),a}function K(r,e,n){var t=g(e);if(isNaN(t))return null;var i=O(r),o=null;return B(r,n).forEach(function(f){if(f.e>t-i.before){var u=f.s-i.after;(o===null||u<o)&&(o=u)}}),o}function X(r,e,n){var t=K(r,e,n);if(t===null)return null;var i=String(e).slice(0,10),o=E(t);if(o<i)return i;if(j(r,o,n,"to",{pickup:e}).some(function(u){return!u.disabled}))return o;var f=E(Math.floor(t/y)*y-y);return f<i?i:f}function m(r){var e=String(r).split(":");return parseInt(e[0],10)*60+parseInt(e[1]||"0",10)}function Z(r,e,n){var t=parseInt(n,10);(isNaN(t)||t<5)&&(t=30);for(var i=m(r||"08:00"),o=m(e||"18:00"),f=[],u=i;u<=o;u+=t){var a=Math.floor(u/60),l=u%60;f.push((a<10?"0":"")+a+":"+(l<10?"0":"")+l)}return f}function $(r,e,n){return n=n||{},(r||[]).map(function(t){var i=m(t),o=null;return n.notBefore&&i<=m(n.notBefore)?o="before-pickup":n.notAfter&&i>=m(n.notAfter)?o="after-return":n.notEarlierThan&&i<m(n.notEarlierThan)?o="too-early":(e||[]).some(function(f){return i>=m(f[0])&&i<m(f[1])?(o="booked",!0):!1}),{time:t,disabled:o!==null,reason:o}})}function pr(r){for(var e=0;e<r.length;e++)if(!r[e].disabled)return r[e].time;return null}function rr(r,e,n,t){var i=g(d(n).format(s)),o=g(d(t).format(s));return isNaN(i)||isNaN(o)?!1:x(B(r,e),O(r),i,er(r,i,o))}function er(r,e,n){return r.returnDayFree&&n>e?n:n+y-1}function nr(r,e){var n=(r.disabled_dates||[]).concat(r.disabled_dates_end||[]),t={};T(e,r.minLength).forEach(function(u){t[u]=!0});for(var i=c(d(e).format(s),s),o=0;o<400;o++,i.add(1,"d")){var f=i.format(s);if(!t[f]&&!(n.length&&U(f,n)))return f}return d(e).format(s)}function tr(r,e){var n=S(e),t=C(r),i="ns"+n+"|"+JSON.stringify([r.minLength||"",r.disabled_dates_end||[],(r.disabled_dates||[]).length]);if(t&&t[i])return t[i];var o=O(r),f=0;N(r.minLength)&&(f=Math.max(0,w(c("2000-01-01",s),_(c("2000-01-01",s),r.minLength))));var u=(r.disabled_dates||[]).length+(r.disabled_dates_end||[]).length?62:0,a={},l={};B(r,n).forEach(function(h){for(var p=Math.floor((h.s-o.after-(y-1))/y)+1,b=Math.floor((h.e+o.before-1)/y),D=p,k=0;D<=b&&k<3660;D++,k++)a[D]=!0;for(var M=p-f-u-1;M<p;M++)l[M]=!0});var v=Object.keys(a).map(function(h){return E(h*y)});return Object.keys(l).forEach(function(h){if(!a[h]){var p=E(h*y);rr(r,n,p,nr(r,p))&&v.push(p)}}),v.sort(),t&&(t[i]=v),v}function ir(r,e,n){var t=g(e);if(isNaN(t))return null;var i=O(r),o=null;if(B(r,n).forEach(function(a){a.e>t-i.before&&(o===null||a.s<o)&&(o=a.s)}),o===null)return null;var f=r.returnDayFree?0:y-1,u=E(Math.floor((o-i.after-f)/y)*y);return u<e?e:u}function mr(r){return r==="datetime"?["start","starttime","end","endtime"]:["start","end"]}function br(r,e,n,t){var i=d(r).startOf("day"),o=d(e).startOf("day");return n?Math.max(0,o.diff(i,"days")):t&&o.diff(i,"days")>0?o.diff(i,"days")+1:Math.max(1,o.diff(i,"days"))}return{DAY:s,normalizeQuantity:S,bookedDatesForQuantity:Q,unitsLeft:fr,unitsCap:ur,addLength:_,hasLength:N,inRange:ar,isDayDisabled:U,disabledBy:W,compileDisabled:P,daysFromStartUntilMinDate:T,minEndDate:z,firstFullyBookedFrom:V,maxDate:lr,disabledLists:cr,disabledTimeRangesForDay:hr,turnoverMinutes:O,slotsFor:j,noPickupDays:G,returnCap:K,lastReturnDay:X,dateRentalRefused:rr,dateRentalEnd:er,firstEndDay:nr,noStartDays:tr,lastEndDay:ir,earliestPickupTime:J,absMinutes:g,timeSlots:Z,slotAvailability:$,firstAvailableSlot:pr,toMinutes:m,buildSteps:mr,dayCount:br,nightsBetween:w,dayState:dr,soldNights:q}}); -
sales-igniter-rentals-bookings-lite/trunk/Assets/public/js/sibookingCalendarUi.js
r3728745 r3729359 1271 1271 var from = start.format(fmt) + (useTime && this.times.getTime('from') ? ' ' + this.times.label(this.times.getTime('from')) : ''); 1272 1272 var to = end.format(fmt) + (useTime && this.times.getTime('to') ? ' ' + this.times.label(this.times.getTime('to')) : ''); 1273 var days = R.dayCount(start, end, !!data().nightly );1273 var days = R.dayCount(start, end, !!data().nightly, !!data().chargeReturnDay); 1274 1274 var length; 1275 1275 var fromT = useTime ? this.times.getTime('from') : '', toT = useTime ? this.times.getTime('to') : ''; -
sales-igniter-rentals-bookings-lite/trunk/Assets/public/js/sibookingCalendarUi.min.js
r3728745 r3729359 1 (function(r){"use strict";var A=null;function _(){if(A===null){var n="ltr";try{n=window.getComputedStyle(document.body||document.documentElement).direction}catch(c){}A=n==="rtl"}return A}function M(){return _()?"←":"→"}function O(n){return n=String(n==null?"":n),n===""||!_()?n:""+n+""}r(window).on("load",function(){if(typeof sibooking=="undefined"||!sibooking.data||typeof flatpickr=="undefined")return;var n=window.SibookingCalendarRules,c=window.wp&&window.wp.i18n?window.wp.i18n:{__:function(k){return k},_n:function(k,t,e){return e===1?k:t},sprintf:function(k){return k}},l=c.__,T=r.extend({start:l("Start Date","sales-igniter-rentals-bookings-lite"),starttime:l("Start Time","sales-igniter-rentals-bookings-lite"),end:l("End Date","sales-igniter-rentals-bookings-lite"),endtime:l("End Time","sales-igniter-rentals-bookings-lite")},sibooking.data.ui&&sibooking.data.ui.labels||{}),E='<svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="3"></rect><path d="M3 10h18M8 3v4M16 3v4"></path></svg>',P='<svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 2"></path></svg>';function d(){return window.sibooking.data}function S(){return d().ui||{}}function I(){var k=parseInt(S().lowStock,10);return k>0?k:2}function m(k){return r("<div>").text(k==null?"":String(k)).html()}class j{constructor(t){this.calendar=t,this.timepickerfrom=r("#timepicker"),this.timepickerto=r("#timepicker2"),this.side="from",this.$grid=r(".sib-cal .sib-slots"),this.$head=r(".sib-cal .sib-pane--time .sib-pane-head"),this.onChange=null}enabled(){return this.timepickerfrom.length>0}getTime(t){var e=t==="to"?this.timepickerto:this.timepickerfrom;return e.length&&e.val()||""}setTime(t,e,i){var a=t==="to"?this.timepickerto:this.timepickerfrom;a.length&&(a.val(e||""),this.calendar.updateVisibleTime(t),i||a.trigger("change"))}dayFor(t){var e=t==="to"?this.calendar.siflatpickrend:this.calendar.siflatpickrstart;return!e||!e.selectedDates.length?null:moment(e.selectedDates[0])}momentFor(t){var e=this.dayFor(t),i=this.getTime(t);return e&&i?e.format(n.DAY)+" "+i:null}availability(t){var e=this.dayFor(t);return e?n.slotsFor(d(),e,this.calendar.inputQuantity,t,{pickup:t==="to"?this.momentFor("from"):null,ret:t==="from"?this.momentFor("to"):null}):[]}updateFromDisabledTimes(){this.ensureValid("from"),this.side==="from"&&this.render("from")}updateToDisabledTimes(){this.ensureValid("to"),this.side==="to"&&this.render("to")}ensureValid(t){var e=this.getTime(t);if(e){var i=this.availability(t);if(i.length){var a=i.some(function(s){return s.time===e&&!s.disabled});a||this.setTime(t,"",!0)}}}groupOf(t){var e=parseInt(t.split(":")[0],10);return e<12?l("Morning","sales-igniter-rentals-bookings-lite"):e<17?l("Afternoon","sales-igniter-rentals-bookings-lite"):l("Evening","sales-igniter-rentals-bookings-lite")}label(t){var e=d().inputTimeFormat||"HH:mm";return O(moment(t,"HH:mm").format(e))}render(t){this.side=t;var e=this.dayFor(t),i=this.$grid;i.empty();var a=this.$head,s=d();if(!e){a.html('<span class="sib-h">'+m(t==="to"?T.endtime:T.starttime)+"</span>"),i.append('<div class="sib-placeholder">'+m(l("Pick a date first","sales-igniter-rentals-bookings-lite"))+"</div>");return}var o=e.format(s.inputDateFormatMoment||"ddd D MMM");a.html('<span class="sib-h">'+m((t==="to"?T.endtime:T.starttime)+" · "+o)+'</span><span class="sib-hours">'+m(c.sprintf(l("Open %1$s – %2$s","sales-igniter-rentals-bookings-lite"),(_()?"":"")+this.label(s.storeopen),this.label(s.storeclose)+(_()?"":"")))+"</span>");var h=this.availability(t),u=this.getTime(t),p=t==="to"&&!u?this.getTime("from"):null,g={},y=[];h.forEach(function(b){var v=this.groupOf(b.time);g[v]||(g[v]=[],y.push(v)),g[v].push(b)}.bind(this));var f=this;y.forEach(function(b){var v=r('<div class="sib-slot-group"><span class="sib-h">'+m(b)+"</span></div>"),w=r('<div class="sib-slot-row"></div>');g[b].forEach(function(D){var x="sib-slot";D.disabled&&(x+=" is-off is-"+D.reason),D.time===u&&(x+=" is-sel"),!D.disabled&&D.time===p&&(x+=" is-suggested");var C=r('<button type="button" class="'+x+'"></button>').text(f.label(D.time)).attr("data-time",D.time);D.disabled&&C.attr("disabled","disabled").attr("aria-disabled","true"),D.reason==="before-pickup"&&C.append('<span class="sib-slot-sub">'+m(l("before pick-up","sales-igniter-rentals-bookings-lite"))+"</span>"),!D.disabled&&D.time===p&&C.append('<span class="sib-slot-sub">'+m(l("same as pick-up","sales-igniter-rentals-bookings-lite"))+"</span>"),w.append(C)}),v.append(w),i.append(v)}),h.some(function(b){return!b.disabled})||i.append('<div class="sib-placeholder">'+m(l("No times left on this day","sales-igniter-rentals-bookings-lite"))+"</div>"),i.append('<div class="sib-hint">'+m(l("Greyed times are booked or inside the turnover buffer.","sales-igniter-rentals-bookings-lite"))+"</div>"),i.off("click.sib").on("click.sib",".sib-slot:not([disabled])",function(){var b=r(this).attr("data-time");f.setTime(f.side,b),i.find(".sib-slot").removeClass("is-sel"),r(this).addClass("is-sel"),f.onChange&&f.onChange(f.side,b)})}setInitialTimes(){var t=d();if(this.enabled()&&t.sessionFromDate&&t.sessionToDate){var e=moment(t.sessionFromDate),i=moment(t.sessionToDate),a=function(h){return moment(h,"HH:mm:ss").format("HH:mm")},s=this.withinStoreHours(e)?e.format("HH:mm"):a(t.storeopen),o=this.withinStoreHours(i)?i.format("HH:mm"):a(t.storeclose);this.setTime("from",s,!0),this.setTime("to",o,!0)}}withinStoreHours(t){var e=d(),i=t.hours()*60+t.minutes();return i>=n.toMinutes(e.storeopen)&&i<=n.toMinutes(e.storeclose)}}class L{constructor(){this.$root=r(".sib-cal"),this.sibookingDateContainer=r(".sibooking-datecontainer"),this.inputQuantity=n.normalizeQuantity(r('input[name="quantity"]').val()),this.lists={booked:[],both:[],start:[],end:[]},this.steps=[],this.stepIndex=0,this.hoverEnd=null}get calendarType(){return d().calendarType}get dateFormat(){return d().inputDateFormat}get dateFormatMoment(){return d().inputDateFormatMoment}get timeFormat(){return d().inputTimeFormat}isdatepicker(){return r("#flatpickr").length>0||r("#flatpickr2").length>0}init(){!this.isdatepicker()||!this.$root.length||(this.times=new j(this),this.times.onChange=this.onTimePicked.bind(this),this.buildSteps(),this.updateDisabledDatesAll(),this.loadCalendar(),this.addEventHandlers(),this.render(),this.goTo(0))}$summary(){return this.$root.find(".sib-summary").first()}stepsFor(){return n.buildSteps(this.calendarType)}buildSteps(){var t=this.times&&this.times.enabled();this.steps=this.stepsFor().filter(function(e){return t||e!=="starttime"&&e!=="endtime"}),this.$root.toggleClass("has-time",this.steps.indexOf("starttime")!==-1)}startDate(){return this.siflatpickrstart&&this.siflatpickrstart.selectedDates.length?moment(this.siflatpickrstart.selectedDates[0]):null}endDate(){return this.siflatpickrend&&this.siflatpickrend.selectedDates.length?moment(this.siflatpickrend.selectedDates[0]):null}calendarOptions(){return{disableMobile:!0,mode:"single",dateFormat:"Y-m-d",allowInput:!1,monthSelectorType:"static",showMonths:1,locale:r.extend({firstDayOfWeek:parseInt(S().firstDay||0,10)},S().locale||{}),inline:!0,appendTo:this.$root.find(".sib-cal-mount")[0]}}loadCalendar(){var t=this,e=this.calendarOptions();this.siflatpickrstart=flatpickr("#flatpickr",r.extend({},e,{onDayCreate:this.onDayCreate.bind(this,"start"),onOpen:this.onStartOpen.bind(this),onChange:this.onChangeStart.bind(this),minDate:d().minDate,maxDate:this.getMaxDate()})),this.siflatpickrend=flatpickr("#flatpickr2",r.extend({},e,{allowInvalidPreload:!0,onDayCreate:this.onDayCreate.bind(this,"end"),onOpen:this.onOpenEnd.bind(this),onChange:this.onChangeEnd.bind(this),onClose:this.onCloseEnd.bind(this)})),this.siflatpickrstart.calendarContainer.classList.add("sib-fp","sib-fp--start"),this.siflatpickrend.calendarContainer.classList.add("sib-fp","sib-fp--end"),r(document).trigger("sibooking:calendars",[this.siflatpickrstart,this.siflatpickrend]),r(this.siflatpickrend.calendarContainer).on("mouseover",".flatpickr-day",function(){t.hoverEnd&&t.hoverEnd.getTime()===this.dateObj.getTime()||(t.hoverEnd=this.dateObj,t.paintRange())}).on("mouseleave",function(){t.hoverEnd=null,t.paintRange()}),this.applyDisable()}addEventHandlers(){var t=this;r('input[name="quantity"]').on("change",function(){n.normalizeQuantity(r(this).val())!==t.inputQuantity&&t.onQuantityChanged()}),r(document).on("sib:guests:change",function(e,i,a){a&&!r(a).closest("form").is(t.$root.closest("form"))||t.refreshPrice()}),r(".single_add_to_cart_button").not("#sibookingpurchase").on("click",function(e){var i=t.missingSelection();i?(e.preventDefault(),t._missingSaid=i,t.tell(i)):t._missingSaid&&(t.$root.find(".sib-note").text()===t._missingSaid&&t.say(""),t._missingSaid="")}),r("#sibookingpurchase").on("click",function(){r('input[name="isbookingpurchase"]').val(!0)}),r("#siwidget-update").on("click",function(e){e.preventDefault(),t.widgetUpdate()}),this.$root.find(".sib-panel").length&&(this.$root.on("click",".sib-trigger",function(){t.togglePanel()}),this.$root.on("click",".sib-panel-close, .sib-backdrop",function(){t.closePanel()}),r(document).on("keydown.sibpanel",function(e){e.key==="Escape"&&t.closePanel()}),r(document).on("mousedown.sibpanel touchstart.sibpanel",function(e){t.$root.hasClass("is-open")&&!r(e.target).closest("#sib-cal").length&&t.closePanel()})),this.$root.on("click keydown",".sib-step[data-index]",function(e){if(!(e.type==="keydown"&&e.key!=="Enter"&&e.key!==" ")){e.preventDefault();var i=parseInt(r(this).attr("data-index"),10);!isNaN(i)&&i<=t.furthestStep()&&t.changeStep(i)}}),this.$root.on("click",".sib-reset",function(e){e.preventDefault(),t.clearStartEndDate()})}missingSelection(){return!this.startDate()||!this.endDate()?l("Please first select your booking dates","sales-igniter-rentals-bookings-lite"):this.steps.indexOf("endtime")!==-1&&(!this.times.getTime("from")||!this.times.getTime("to"))?l("Please select your pick-up and return times","sales-igniter-rentals-bookings-lite"):""}onQuantityChanged(){var t=this.startDate(),e=this.endDate();if(this.updateDisabledDatesAll(),this.say(""),!t){this.render();return}if(this.rangeStillFree(t,e||t)){this.render();return}this.clearStartEndDate(),this.say(c.sprintf(c._n("There is not %d free on those dates. Please pick your dates again.","There are not %d free on those dates. Please pick your dates again.",this.inputQuantity,"sales-igniter-rentals-bookings-lite"),this.inputQuantity))}rangeStillFree(t,e){var i={};(this.lists.booked||[]).forEach(function(o){i[o]=!0});var a=t.clone().startOf("day"),s=e.clone().startOf("day");if(i[a.format(n.DAY)])return!1;for(a.add(1,"d");a.isBefore(s,"day");){if(i[a.format(n.DAY)])return!1;a.add(1,"d")}return!0}say(t){var e=this.$root.find(".sib-note");if(!e.length){if(!t)return;e=r('<p class="sib-note" aria-live="polite"></p>');var i=this.$summary();i.length?i.before(e):this.$root.append(e)}e.text(t||"").prop("hidden",!t)}tell(t){this.say(t);var e=this.$root.find(".sib-note").get(0);e&&e.scrollIntoView&&e.scrollIntoView({block:"nearest"})}guestsText(){var t=this.$root.closest("form").find(".sib-guests").get(0);return t&&t.sibGuests?t.sibGuests.summary():""}guestFields(){var t={};return this.$root.closest("form").find(".sib-guests-input[name], .sib-guests-total[name]").each(function(){this.value!==""&&(t[this.name]=this.value)}),t}blockedStarts(){return[]}updateDisabledDatesAll(){this.inputQuantity=n.normalizeQuantity(r('input[name="quantity"]').val()),this.lists=n.disabledLists(d(),this.inputQuantity,this.startDate(),this.blockedStarts()),this.applyDisable(),this.times&&(this.times.ensureValid("from"),this.times.ensureValid("to"))}applyDisable(){var t=d();this._closedFor!==t&&(this._closedFor=t,this._closedStart=(t.disabled_dates||[]).concat(t.disabled_dates_start||[]),this._closedEnd=(t.disabled_dates||[]).concat(t.disabled_dates_end||[]));var e=this.startDate(),i=this.getMaxDate();this.siflatpickrstart&&this.siflatpickrstart.set({disable:this.lists.start,maxDate:e?null:i}),this.siflatpickrend&&this.siflatpickrend.set({disable:this.lists.end,minDate:e?e.format(n.DAY):null,maxDate:i})}updateDisabledDatesEnd(){this.updateDisabledDatesAll()}getMaxDate(){var t=this.times&&this.times.enabled()?this.times.getTime("from"):"";return n.maxDate(d(),this.startDate(),this.lists.booked,t,this.inputQuantity)}getMinDateForEndDate(){return this.startDate()?n.minEndDate(this.startDate(),d().minLength,!!d().nightly):null}onDayCreate(t,e,i,a,s){var o=d(),h=moment(s.dateObj).format(n.DAY),u=null;if(o.nightly&&(u=n.dayState(o,this.inputQuantity,h),s.setAttribute("data-sib-day-state",u)),o.nightly?u==="booked"||u==="turnover":this.lists.booked.indexOf(h)!==-1)s.classList.add("sib-booked"),s.title=l("Fully booked","sales-igniter-rentals-bookings-lite");else{var p=n.disabledBy(h,t==="start"?this._closedStart||[]:this._closedEnd||[]);if(p.length){s.classList.add("sib-closed");var g=p.map(function(v){return v.reason}).filter(function(v,w,D){return v&&D.indexOf(v)===w});s.title=g.length?g.join(" · "):l("Disabled","sales-igniter-rentals-bookings-lite"),s.setAttribute("data-sib-reason",s.title)}}if(S().showPrices&&o.dayPrices&&o.dayPrices[h]&&!s.classList.contains("flatpickr-disabled")){var y=document.createElement("span");y.className="sib-price",y.textContent=o.dayPrices[h],s.appendChild(y)}if(S().showUnitsLeft&&!s.classList.contains("flatpickr-disabled")){var f=n.unitsLeft(o,h);if(f!==null){var b=document.createElement("span");b.className="sib-left"+(f<=I()?" is-low":""),b.textContent=c.sprintf(l("%d left","sales-igniter-rentals-bookings-lite"),f),s.appendChild(b)}}this.paintDay(s,t==="end"),r(document).trigger("sibooking:daycreate",[s,h,t,u])}paintDay(t,e){var i=this.startDate(),a=this.endDate()||(e&&this.hoverEnd?moment(this.hoverEnd):null);if(t.classList.remove("sib-range-start","sib-inrange","sib-range-end"),!!i){var s=moment(t.dateObj);s.isSame(i,"day")&&t.classList.add("sib-range-start"),a&&a.isAfter(i,"day")&&s.isAfter(i,"day")&&s.isBefore(a,"day")&&t.classList.add("sib-inrange"),a&&s.isSame(a,"day")&&!s.isSame(i,"day")&&t.classList.add("sib-range-end")}}paintRange(){var t=this;[[this.siflatpickrend,!0],[this.siflatpickrstart,!1]].forEach(function(e){var i=e[0];if(!(!i||!i.days))for(var a=i.days.querySelectorAll(".flatpickr-day"),s=0;s<a.length;s++)t.paintDay(a[s],e[1])})}onStartOpen(){this.updateDisabledDatesAll()}onChangeStart(){this.say("");var t=this.startDate(),e=t?t.format(n.DAY):"";if(e&&this._lastStart&&e!==this._lastStart&&(this.siflatpickrend&&this.siflatpickrend.clear(),this.times&&(this.times.setTime("from","",!0),this.times.setTime("to","",!0)),this.hoverEnd=null),this._lastStart=e,this.updateDisabledDatesAll(),this.startDate()){var i=this.endDate(),a=this.getMaxDate();i&&(i.isBefore(this.startDate(),"day")||a&&i.isAfter(moment(a,n.DAY),"day"))&&this.siflatpickrend.clear()}this.times&&this.times.updateFromDisabledTimes(),this.completeStep("start")}onOpenEnd(){if(!this.startDate()){this.siflatpickrend.close();return}this.applyDisable(),this.siflatpickrend.jumpToDate(this.startDate().toDate())}onChangeEnd(){this.updateInputValues(),this.paintRange(),this.times&&this.times.updateToDisabledTimes(),this.completeStep("end")}onCloseEnd(){this.updateInputValues(),this.render()}updateInputValues(){var t=r("#flatpickr2"),e=this.endDate();t.val(e?e.format(n.DAY):""),this.siflatpickrend&&this.siflatpickrend.altInput&&(this.siflatpickrend.altInput.value=e?this.siflatpickrend.formatDate(e.toDate(),this.dateFormat):"")}clearStartEndDate(){this._lastStart="",this.siflatpickrstart&&this.siflatpickrstart.clear(),this.siflatpickrend&&this.siflatpickrend.clear(),this.times&&(this.times.setTime("from","",!0),this.times.setTime("to","",!0)),this.hoverEnd=null,this.render(),this.goTo(0)}setInitialDates(){var t=d();if(!(!t.sessionFromDate||!t.sessionToDate||t.sessionFromDate==="Invalid Date"||t.sessionToDate==="Invalid Date")){var e=moment(t.sessionFromDate),i=moment(t.sessionToDate);!e.isValid()||!i.isValid()||t.minDate&&e.isBefore(moment(t.minDate),"day")||(this.siflatpickrstart.setDate(e.format(n.DAY),!1),this.updateDisabledDatesAll(),this.siflatpickrend.setDate(i.format(n.DAY),!1),this.updateInputValues(),this.times&&this.times.setInitialTimes(),this.afterInitialDates(e,i),this._lastStart=e.format(n.DAY),this._rememberedKey=this.startDate()&&this.endDate()?this.startDate().format(n.DAY)+" "+(this.times&&this.times.getTime("from")||"")+"|"+this.endDate().format(n.DAY)+" "+(this.times&&this.times.getTime("to")||""):"",this.siflatpickrstart.jumpToDate(e.toDate()),this.siflatpickrend.jumpToDate(e.toDate()),this.render(),this.goTo(this.steps.length),this.paintRange())}}afterInitialDates(t,e){}widgetUpdate(){if(!this.startDate()||!this.endDate()){this.tell(l("Please first select your booking dates","sales-igniter-rentals-bookings-lite"));return}var t=this,e=r("#sibooking-calendar");e.LoadingOverlay&&e.LoadingOverlay("show");var i={fromDate:this.startDate().format(n.DAY),toDate:this.endDate().format(n.DAY),fromTime:this.times?this.times.getTime("from"):"",toTime:this.times?this.times.getTime("to"):"",action:"sibooking_calendar_global",nonce:d().nonce},a=function(){e.LoadingOverlay&&e.LoadingOverlay("hide"),t.tell(l("Booking dates updated","sales-igniter-rentals-bookings-lite"))},s=function(o){o&&o.statusText==="abort"||(e.LoadingOverlay&&e.LoadingOverlay("hide"),t.tell(l("Your dates could not be saved. Check your connection and try again.","sales-igniter-rentals-bookings-lite")))};r.ajaxq&&r.ajaxq.isRunning("sibookingGlobalCalendar")&&r.ajaxq.abort("sibookingGlobalCalendar"),this.postDates(i,"sibookingGlobalCalendar").done(a).fail(s)}postDates(t,e){var i=d().ajaxurl,a=function(){return t.nonce=d().nonce,e&&r.ajaxq?r.ajaxq(e,{url:i,type:"POST",data:t}):r.post(i,t)},s=r.Deferred();return a().done(s.resolve).fail(function(o){if(o&&o.statusText!=="abort"&&window.sibAjax&&window.sibAjax.isNonceFailure(o)){window.sibAjax.renewNonce().then(function(){a().done(s.resolve).fail(s.reject)},function(){s.reject(o)});return}s.reject(o)}),s.promise()}furthestStep(){for(var t=0;t<this.steps.length&&this.isStepDone(this.steps[t]);t++);return Math.min(t,this.steps.length-1)}isStepDone(t){switch(t){case"start":return!!this.startDate();case"starttime":return!!(this.times&&this.times.getTime("from"));case"end":return!!this.endDate();case"endtime":return!!(this.times&&this.times.getTime("to"))}return!1}allDone(){var t=this;return this.steps.every(function(e){return t.isStepDone(e)})}stepValue(t){var e="ddd D MMM";switch(t){case"start":return this.startDate()?this.startDate().format(e):"";case"end":return this.endDate()?this.endDate().format(e):"";case"starttime":return this.times&&this.times.getTime("from")?this.times.label(this.times.getTime("from")):"";case"endtime":return this.times&&this.times.getTime("to")?this.times.label(this.times.getTime("to")):""}return""}completeStep(t){var e=this.steps.indexOf(t);if(this.render(),e!==-1){for(var i=e+1;i<this.steps.length&&this.isStepDone(this.steps[i]);)i++;if(this.goTo(i),this.allDone()&&this.$root.hasClass("is-open")){var a=this;setTimeout(function(){a.closePanel()},350)}}}onTimePicked(t){if(t==="from"&&this.times){this.updateDisabledDatesAll();var e=this.endDate(),i=this.getMaxDate();e&&i&&e.isAfter(moment(i,n.DAY),"day")&&(this.siflatpickrend.clear(),this.times.setTime("to","",!0),this.updateInputValues()),this.times.ensureValid("to")}this.completeStep(t==="to"?"endtime":"starttime")}changeStep(t){var e=this.steps[t],i=this.times;e==="start"?(this.siflatpickrend&&this.steps.indexOf("end")!==-1&&this.siflatpickrend.clear(),i&&(i.setTime("from","",!0),i.setTime("to","",!0)),this.hoverEnd=null,this.updateInputValues()):e==="starttime"?i&&i.setTime("to","",!0):e==="end"&&(i&&i.setTime("to","",!0),this.hoverEnd=null),this.render(),this.goTo(t)}goTo(t){this.stepIndex=Math.max(0,Math.min(t,this.steps.length));var e=this.steps[this.stepIndex],i=this.$root.find(".sib-stage"),a=e==="start"||!e&&!this.steps.length,s=e==="end"||e==="endtime"?"end":"start";a&&(s="start"),r(this.siflatpickrstart.calendarContainer).toggle(s==="start"),r(this.siflatpickrend.calendarContainer).toggle(s==="end"),s==="end"&&this.startDate()&&this.siflatpickrend.jumpToDate((this.endDate()||this.startDate()).toDate());var o=e==="endtime"?"to":"from";this.times&&this.times.enabled()&&this.times.render(o);var h=e==="starttime"||e==="endtime"?"time":"date";e===void 0&&(h="done"),i.attr("data-active",h);var u=e?T[e]:l("Your booking","sales-igniter-rentals-bookings-lite"),p="";if(s==="end"&&this.startDate()){var g=this.startDate().format("ddd D MMM")+(this.times&&this.times.getTime("from")?" · "+this.times.label(this.times.getTime("from")):"");p='<span class="sib-pane-ctx">'+m(d().nightly?T.start+" "+g:c.sprintf(l("Pick-up %s","sales-igniter-rentals-bookings-lite"),g))+"</span>"}this.$root.find(".sib-pane--date .sib-pane-head").html('<span class="sib-h">'+m(s==="end"?T.end:T.start)+"</span>"+p),this.$root.attr("data-step",e||"done"),this.renderSteps();var y=this.$root.find(".sib-stage-hint");if(y.text(e&&this.stepHints()[e]||""),e==="end"&&this.startDate()&&!this.endDate()){var f=n.minEndDate(this.startDate(),d().minLength,!!d().nightly);n.isDayDisabled(f,this.lists.end)||(this.hoverEnd=moment(f,n.DAY).toDate(),this.paintRange())}this.renderSummary(),r(document).trigger("sibooking:step",[e||"done",this.$root])}stepHints(){return{start:l("Tap a day to continue. Greyed days are booked, closed, or too close to the next booking.","sales-igniter-rentals-bookings-lite"),end:l("Days before pick-up and past the next booking cannot be picked.","sales-igniter-rentals-bookings-lite"),starttime:l("Choosing a time moves straight to the return date.","sales-igniter-rentals-bookings-lite"),endtime:""}}render(){this.renderSteps(),this.renderTrigger(),this.renderSummary(),this.rememberDates(),this.announceDates()}announceDates(){var t=this.startDate(),e=this.endDate(),i=(t?t.format(n.DAY):"")+"|"+(e?e.format(n.DAY):"");i!==this._datesKey&&(this._datesKey=i,r(document.body).trigger("sibooking:dates",[t,e]))}rememberDates(){var t=d();if(!(!t.ajaxurl||t.isComposite)&&!(this.steps.indexOf("end")===-1||!this.allDone())){var e=this.startDate(),i=this.endDate();if(!(!e||!i||i.isBefore(e,"day"))){var a=this.times&&this.times.getTime("from")||"",s=this.times&&this.times.getTime("to")||"",o=e.format(n.DAY)+" "+a+"|"+i.format(n.DAY)+" "+s;o!==this._rememberedKey&&(this._rememberedKey=o,this.postDates({action:"sibooking_calendar_global",fromDate:e.format(n.DAY),toDate:i.format(n.DAY),fromTime:a,toTime:s}))}}}renderSteps(){var t=this.$root.find(".sib-steps");if(this.$root.toggleClass("sib-cal--steps",t.length>0&&S().showSteps!==!1&&this.steps.length>0),!!t.length){if(S().showSteps===!1){t.empty().hide();return}t.show();var e=this,i=this.furthestStep();t.empty(),this.steps.forEach(function(a,s){var o=e.isStepDone(a),h="sib-step"+(o?" is-done":"")+(s===e.stepIndex?" is-on":"")+(s<=i?" is-reachable":""),u=o?e.stepValue(a):s===e.stepIndex?l("Choose","sales-igniter-rentals-bookings-lite"):"",p=o&&s!==e.stepIndex?' title="'+m(l("Change","sales-igniter-rentals-bookings-lite"))+'"':"";t.append('<div class="'+h+'" data-index="'+s+'" role="button" tabindex="0"'+p+' aria-label="'+m(T[a]+(o?": "+u:""))+'"><div class="sib-step-bar"></div><span class="sib-step-t">'+m(T[a])+'</span><span class="sib-step-v">'+m(u)+"</span></div>")})}}updateVisibleTime(t){}quotable(){var t=d();return!!(this.startDate()&&this.endDate()&&this.allDone()&&!t.isComposite&&t.ajaxurl)}totalBox(){var t=r(".sib-rental-total");if(!t.length){t=r('<div class="sib-rental-total" aria-live="polite"></div>');var e=this.$root.closest(".summary, .product"),i=".products, .related, .upsells, .up-sells, .cross-sells, .wc-block-product-template, .wp-block-woocommerce-product-collection, .wp-block-woocommerce-related-products",a=function(o){return o.filter(function(){return!r(this).closest(i).length})},s=a(e.find(".sib-pricing").not(".sib-pricing--loop")).first();s.length||(s=a(e.find("p.price")).first()),s.length||(s=a(e.find(".price")).first()),s.length||(s=r(".single-product .summary p.price").first()),s.length?s.after(t):this.$root.find(".sib-summary").append(t)}return t}showQuote(t){var e=this.totalBox(),i=t.quantity>1?' <span class="sib-rental-total-qty">× '+t.quantity+"</span>":"";e.html('<span class="sib-rental-total-label">'+m(l("Total for your dates","sales-igniter-rentals-bookings-lite"))+i+'</span><span class="sib-rental-total-amount">'+t.total_html+"</span>"),e.removeClass("is-in"),e[0].offsetWidth,e.addClass("is-in")}hideQuote(){this.totalBox().removeClass("is-in")}notesBox(){var t=r(".sib-quote-notes");return t.length||(t=r('<div class="sib-quote-notes" aria-live="polite"></div>'),this.totalBox().after(t)),t}showNotes(t){var e=Array.isArray(t)?t.filter(function(s){return s&&s.text}):[],i=r(".sib-quote-notes");if(!(!e.length&&!i.length)){i=this.notesBox();var a=e.map(function(s){var o=String(s.key||"").replace(/[^A-Za-z0-9_-]/g,"");return'<p class="sib-quote-note'+(o?" sib-quote-note--"+o:"")+'">'+m(s.text)+"</p>"}).join("");i.html()!==a&&i.html(a)}}quoteFields(){return this.guestFields()}showQuoteError(t){this.totalBox().html(t).addClass("is-in")}quoteAgain(t){}refreshPrice(){var t=this,e=d(),i=this.startDate(),a=this.endDate(),s=function(){t._priceKey="",t.showCardTotal(null),t.hideQuote(),t.showNotes(null)};if(!this.quotable()){s();return}var o=r('input[name="variation_id"]').val()||r('button[name="add-to-cart"]').val()||r('input[name="add-to-cart"]').val()||r(".single_add_to_cart_button").val()||"";if(!o){s();return}var h={action:"sibooking_rental_price",nonce:e.nonce,productid:o,variationid:r('input[name="variation_id"]').val()||0,from:i.format(n.DAY),to:a.format(n.DAY),fromtime:this.times?this.times.getTime("from"):"",totime:this.times?this.times.getTime("to"):"",quantity:this.inputQuantity};r.extend(h,this.quoteFields());var u=JSON.stringify(h);if(u===this._priceKey){this._lastQuote&&this._lastQuoteKey===u&&this.quoteAgain(this._lastQuote);return}this._priceKey=u,clearTimeout(this._priceTimer),this.notesBox();var p=function(){t._priceKey===u&&(s(),t.showQuoteError('<span class="sib-ajax-error" role="alert">'+m(l("The price for these dates could not be loaded.","sales-igniter-rentals-bookings-lite"))+' <a href="#" class="sib-ajax-retry">'+m(l("Try again","sales-igniter-rentals-bookings-lite"))+"</a></span>"))};this._retryBound||(this._retryBound=!0,r(document).on("click",".sib-ajax-retry",function(f){f.preventDefault(),t._priceKey="",t.refreshPrice()}));var g=function(f){if(t._priceKey===u){if(!f||!f.success){s();return}t._lastQuote=f.data,t._lastQuoteKey=u,t.showCardTotal(f.data),t.showQuote(f.data),t.showNotes(f.data.notes)}},y=function(f){h.nonce=d().nonce;var b=r.ajaxq?r.ajaxq("sibookingPrice",{url:e.ajaxurl,type:"POST",data:h}):r.post(e.ajaxurl,h);b.done(g).fail(function(v){if(!(t._priceKey!==u||v&&v.statusText==="abort")){if(f<1){p();return}var w=function(){y(f-1)};window.sibAjax&&window.sibAjax.isNonceFailure(v)?window.sibAjax.renewNonce().then(w,p):setTimeout(w,800)}})};this._priceTimer=setTimeout(function(){y(1)},120)}showCardTotal(t){var e=this.$root.closest(".product, .type-product, body").find(".sib-pricing").not(".sib-pricing--loop, .sib-pricing--custom").first();if(e.length){var i=e.find(".sib-pricing-head");if(i.find(".sib-pricing-total--live").remove(),!t||!t.total_html){e.removeClass("has-total has-live-total");return}var a=parseFloat(t.hours||0),s=parseInt(t.days||0,10),o,h=this.times&&this.times.enabled()&&this.times.getTime("from")&&this.times.getTime("to"),u=Math.floor(a/24),p=Math.ceil(Math.round((a-u*24)*100)/100);if(h&&a>0&&a<24){var g=Math.ceil(a);o=c.sprintf(c._n("for %d hour","for %d hours",g,"sales-igniter-rentals-bookings-lite"),g)}else h&&u>0&&p>0&&(t.length_unit||d().lengthUnit)!=="night"?o=c.sprintf(l("for %1$s %2$s","sales-igniter-rentals-bookings-lite"),c.sprintf(c._n("%d day","%d days",u,"sales-igniter-rentals-bookings-lite"),u),c.sprintf(c._n("%d hour","%d hours",p,"sales-igniter-rentals-bookings-lite"),p)):(t.length_unit||d().lengthUnit)==="night"?o=c.sprintf(c._n("for %d night","for %d nights",Math.max(1,s),"sales-igniter-rentals-bookings-lite"),Math.max(1,s)):o=c.sprintf(c._n("for %d day","for %d days",Math.max(1,s),"sales-igniter-rentals-bookings-lite"),Math.max(1,s));r('<span class="sib-pricing-total sib-pricing-total--live"><b class="sib-pricing-amt"></b> <span class="sib-pricing-total-label"></span></span>').find("b").html(t.total_html).end().find(".sib-pricing-total-label").text(o).end().insertAfter(i.find(".sib-pricing-from")),e.addClass("has-total has-live-total")}}lengthText(t){return d().lengthUnit==="night"?c.sprintf(c._n("%d night","%d nights",t,"sales-igniter-rentals-bookings-lite"),t):t===1?l("1 day","sales-igniter-rentals-bookings-lite"):c.sprintf(l("%d days","sales-igniter-rentals-bookings-lite"),t)}summaryDateFormat(){return this.dateFormatMoment||"ddd D MMM"}summaryParts(){var t=this.startDate(),e=this.endDate();if(!t||!e||!this.allDone())return null;var i=this.summaryDateFormat(),a=this.times&&this.times.enabled(),s=t.format(i)+(a&&this.times.getTime("from")?" "+this.times.label(this.times.getTime("from")):""),o=e.format(i)+(a&&this.times.getTime("to")?" "+this.times.label(this.times.getTime("to")):""),h=n.dayCount(t,e,!!d().nightly ),u,p=a?this.times.getTime("from"):"",g=a?this.times.getTime("to"):"",y=!a||!p||!g||p==="00:00"&&(g==="00:00"||g==="23:59"),f=this,b=function(C){return f.lengthText(C)};if(y)u=b(h),s=t.format(i),o=e.format(i);else{var v=t.clone().set({hour:parseInt(p.split(":")[0],10),minute:parseInt(p.split(":")[1],10)}),w=e.clone().set({hour:parseInt(g.split(":")[0],10),minute:parseInt(g.split(":")[1],10)}),D=w.diff(v,"hours",!0);if(D<24){var x=Math.round(D*10)/10;u=x===1?l("1 hour","sales-igniter-rentals-bookings-lite"):c.sprintf(l("%s hours","sales-igniter-rentals-bookings-lite"),x)}else u=b(Math.ceil(D/24))}return{main:u,sub:s+" "+M()+" "+o}}resetButton(t){var e=this.$root.find(".sib-reset");return e.length||(e=r('<button type="button" class="sib-reset" title="'+m(l("Start over","sales-igniter-rentals-bookings-lite"))+'"><svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.7"></path><path d="M3 4v5h5"></path></svg><span>'+m(l("Start over","sales-igniter-rentals-bookings-lite"))+"</span></button>"),t.after(e)),e}renderSummary(){this.refreshPrice();var t=this.$root.find(".sib-summary-text");if(t.length){this.resetButton(t).toggle(!!this.startDate());var e=this.summaryParts();if(!e){t.html('<span class="sib-summary-muted">'+m(l("Select your dates to see the booking summary","sales-igniter-rentals-bookings-lite"))+"</span>"),this.$root.removeClass("is-complete");return}t.html("<b>"+m(e.main)+"</b><small>"+m(e.sub)+"</small>"),this.$root.addClass("is-complete")}}togglePanel(){this.$root.hasClass("is-open")?this.closePanel():this.openPanel()}openPanel(){this.$root.addClass("is-open").find(".sib-trigger").attr("aria-expanded","true"),this.goTo(this.allDone()?0:this.furthestStep()),r("body").addClass("sib-panel-open")}closePanel(){this.$root.removeClass("is-open").find(".sib-trigger").attr("aria-expanded","false"),r("body").removeClass("sib-panel-open"),this.renderTrigger()}renderTrigger(){var t=this.$root.find(".sib-trigger-text");if(t.length){var e=this.startDate(),i=this.endDate(),a=this.dateFormatMoment||"ddd D MMM";if(!e){t.text(l("Select your dates","sales-igniter-rentals-bookings-lite")),this.$root.removeClass("has-dates");return}var s=this.times&&this.times.enabled(),o=e.format(a)+(s&&this.times.getTime("from")?" "+this.times.label(this.times.getTime("from")):""),h='<span class="sib-trigger-part">'+m(o)+"</span>";i&&this.steps.indexOf("end")!==-1&&(h+=' <span class="sib-trigger-part">'+M()+" "+m(i.format(a)+(s&&this.times.getTime("to")?" "+this.times.label(this.times.getTime("to")):""))+"</span>"),t.html(h),this.$root.addClass("has-dates")}}}var F={Calendar:L,TimeSlots:j,R:n,i18n:c,__:l,esc:m,data:d,ui:S,lowStock:I,onward:M,bidiLtr:O,STEP_LABELS:T,ICON_CAL:E,ICON_CLOCK:P};(window.sibookingCalendarExtensions||[]).forEach(function(k){if(typeof k=="function"){var t=k(F);typeof t=="function"&&(F.Calendar=t)}}),window.SibookingCalendar=new F.Calendar,window.SibookingCalendar.init(),window.SibookingTimepicker=window.SibookingCalendar.times||{timepickerfrom:r("#timepicker"),timepickerto:r("#timepicker2"),setInitialTimes:function(){},updateFromDisabledTimes:function(){},updateToDisabledTimes:function(){}},window.SibookingCalendar.isdatepicker()&&window.SibookingCalendar.$root.length&&window.SibookingCalendar.setInitialDates()})})(jQuery);1 (function(r){"use strict";var A=null;function _(){if(A===null){var n="ltr";try{n=window.getComputedStyle(document.body||document.documentElement).direction}catch(c){}A=n==="rtl"}return A}function M(){return _()?"←":"→"}function O(n){return n=String(n==null?"":n),n===""||!_()?n:""+n+""}r(window).on("load",function(){if(typeof sibooking=="undefined"||!sibooking.data||typeof flatpickr=="undefined")return;var n=window.SibookingCalendarRules,c=window.wp&&window.wp.i18n?window.wp.i18n:{__:function(k){return k},_n:function(k,t,e){return e===1?k:t},sprintf:function(k){return k}},l=c.__,T=r.extend({start:l("Start Date","sales-igniter-rentals-bookings-lite"),starttime:l("Start Time","sales-igniter-rentals-bookings-lite"),end:l("End Date","sales-igniter-rentals-bookings-lite"),endtime:l("End Time","sales-igniter-rentals-bookings-lite")},sibooking.data.ui&&sibooking.data.ui.labels||{}),E='<svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="5" width="18" height="16" rx="3"></rect><path d="M3 10h18M8 3v4M16 3v4"></path></svg>',P='<svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 2"></path></svg>';function d(){return window.sibooking.data}function S(){return d().ui||{}}function I(){var k=parseInt(S().lowStock,10);return k>0?k:2}function m(k){return r("<div>").text(k==null?"":String(k)).html()}class j{constructor(t){this.calendar=t,this.timepickerfrom=r("#timepicker"),this.timepickerto=r("#timepicker2"),this.side="from",this.$grid=r(".sib-cal .sib-slots"),this.$head=r(".sib-cal .sib-pane--time .sib-pane-head"),this.onChange=null}enabled(){return this.timepickerfrom.length>0}getTime(t){var e=t==="to"?this.timepickerto:this.timepickerfrom;return e.length&&e.val()||""}setTime(t,e,i){var a=t==="to"?this.timepickerto:this.timepickerfrom;a.length&&(a.val(e||""),this.calendar.updateVisibleTime(t),i||a.trigger("change"))}dayFor(t){var e=t==="to"?this.calendar.siflatpickrend:this.calendar.siflatpickrstart;return!e||!e.selectedDates.length?null:moment(e.selectedDates[0])}momentFor(t){var e=this.dayFor(t),i=this.getTime(t);return e&&i?e.format(n.DAY)+" "+i:null}availability(t){var e=this.dayFor(t);return e?n.slotsFor(d(),e,this.calendar.inputQuantity,t,{pickup:t==="to"?this.momentFor("from"):null,ret:t==="from"?this.momentFor("to"):null}):[]}updateFromDisabledTimes(){this.ensureValid("from"),this.side==="from"&&this.render("from")}updateToDisabledTimes(){this.ensureValid("to"),this.side==="to"&&this.render("to")}ensureValid(t){var e=this.getTime(t);if(e){var i=this.availability(t);if(i.length){var a=i.some(function(s){return s.time===e&&!s.disabled});a||this.setTime(t,"",!0)}}}groupOf(t){var e=parseInt(t.split(":")[0],10);return e<12?l("Morning","sales-igniter-rentals-bookings-lite"):e<17?l("Afternoon","sales-igniter-rentals-bookings-lite"):l("Evening","sales-igniter-rentals-bookings-lite")}label(t){var e=d().inputTimeFormat||"HH:mm";return O(moment(t,"HH:mm").format(e))}render(t){this.side=t;var e=this.dayFor(t),i=this.$grid;i.empty();var a=this.$head,s=d();if(!e){a.html('<span class="sib-h">'+m(t==="to"?T.endtime:T.starttime)+"</span>"),i.append('<div class="sib-placeholder">'+m(l("Pick a date first","sales-igniter-rentals-bookings-lite"))+"</div>");return}var o=e.format(s.inputDateFormatMoment||"ddd D MMM");a.html('<span class="sib-h">'+m((t==="to"?T.endtime:T.starttime)+" · "+o)+'</span><span class="sib-hours">'+m(c.sprintf(l("Open %1$s – %2$s","sales-igniter-rentals-bookings-lite"),(_()?"":"")+this.label(s.storeopen),this.label(s.storeclose)+(_()?"":"")))+"</span>");var h=this.availability(t),u=this.getTime(t),p=t==="to"&&!u?this.getTime("from"):null,g={},y=[];h.forEach(function(b){var v=this.groupOf(b.time);g[v]||(g[v]=[],y.push(v)),g[v].push(b)}.bind(this));var f=this;y.forEach(function(b){var v=r('<div class="sib-slot-group"><span class="sib-h">'+m(b)+"</span></div>"),w=r('<div class="sib-slot-row"></div>');g[b].forEach(function(D){var x="sib-slot";D.disabled&&(x+=" is-off is-"+D.reason),D.time===u&&(x+=" is-sel"),!D.disabled&&D.time===p&&(x+=" is-suggested");var C=r('<button type="button" class="'+x+'"></button>').text(f.label(D.time)).attr("data-time",D.time);D.disabled&&C.attr("disabled","disabled").attr("aria-disabled","true"),D.reason==="before-pickup"&&C.append('<span class="sib-slot-sub">'+m(l("before pick-up","sales-igniter-rentals-bookings-lite"))+"</span>"),!D.disabled&&D.time===p&&C.append('<span class="sib-slot-sub">'+m(l("same as pick-up","sales-igniter-rentals-bookings-lite"))+"</span>"),w.append(C)}),v.append(w),i.append(v)}),h.some(function(b){return!b.disabled})||i.append('<div class="sib-placeholder">'+m(l("No times left on this day","sales-igniter-rentals-bookings-lite"))+"</div>"),i.append('<div class="sib-hint">'+m(l("Greyed times are booked or inside the turnover buffer.","sales-igniter-rentals-bookings-lite"))+"</div>"),i.off("click.sib").on("click.sib",".sib-slot:not([disabled])",function(){var b=r(this).attr("data-time");f.setTime(f.side,b),i.find(".sib-slot").removeClass("is-sel"),r(this).addClass("is-sel"),f.onChange&&f.onChange(f.side,b)})}setInitialTimes(){var t=d();if(this.enabled()&&t.sessionFromDate&&t.sessionToDate){var e=moment(t.sessionFromDate),i=moment(t.sessionToDate),a=function(h){return moment(h,"HH:mm:ss").format("HH:mm")},s=this.withinStoreHours(e)?e.format("HH:mm"):a(t.storeopen),o=this.withinStoreHours(i)?i.format("HH:mm"):a(t.storeclose);this.setTime("from",s,!0),this.setTime("to",o,!0)}}withinStoreHours(t){var e=d(),i=t.hours()*60+t.minutes();return i>=n.toMinutes(e.storeopen)&&i<=n.toMinutes(e.storeclose)}}class L{constructor(){this.$root=r(".sib-cal"),this.sibookingDateContainer=r(".sibooking-datecontainer"),this.inputQuantity=n.normalizeQuantity(r('input[name="quantity"]').val()),this.lists={booked:[],both:[],start:[],end:[]},this.steps=[],this.stepIndex=0,this.hoverEnd=null}get calendarType(){return d().calendarType}get dateFormat(){return d().inputDateFormat}get dateFormatMoment(){return d().inputDateFormatMoment}get timeFormat(){return d().inputTimeFormat}isdatepicker(){return r("#flatpickr").length>0||r("#flatpickr2").length>0}init(){!this.isdatepicker()||!this.$root.length||(this.times=new j(this),this.times.onChange=this.onTimePicked.bind(this),this.buildSteps(),this.updateDisabledDatesAll(),this.loadCalendar(),this.addEventHandlers(),this.render(),this.goTo(0))}$summary(){return this.$root.find(".sib-summary").first()}stepsFor(){return n.buildSteps(this.calendarType)}buildSteps(){var t=this.times&&this.times.enabled();this.steps=this.stepsFor().filter(function(e){return t||e!=="starttime"&&e!=="endtime"}),this.$root.toggleClass("has-time",this.steps.indexOf("starttime")!==-1)}startDate(){return this.siflatpickrstart&&this.siflatpickrstart.selectedDates.length?moment(this.siflatpickrstart.selectedDates[0]):null}endDate(){return this.siflatpickrend&&this.siflatpickrend.selectedDates.length?moment(this.siflatpickrend.selectedDates[0]):null}calendarOptions(){return{disableMobile:!0,mode:"single",dateFormat:"Y-m-d",allowInput:!1,monthSelectorType:"static",showMonths:1,locale:r.extend({firstDayOfWeek:parseInt(S().firstDay||0,10)},S().locale||{}),inline:!0,appendTo:this.$root.find(".sib-cal-mount")[0]}}loadCalendar(){var t=this,e=this.calendarOptions();this.siflatpickrstart=flatpickr("#flatpickr",r.extend({},e,{onDayCreate:this.onDayCreate.bind(this,"start"),onOpen:this.onStartOpen.bind(this),onChange:this.onChangeStart.bind(this),minDate:d().minDate,maxDate:this.getMaxDate()})),this.siflatpickrend=flatpickr("#flatpickr2",r.extend({},e,{allowInvalidPreload:!0,onDayCreate:this.onDayCreate.bind(this,"end"),onOpen:this.onOpenEnd.bind(this),onChange:this.onChangeEnd.bind(this),onClose:this.onCloseEnd.bind(this)})),this.siflatpickrstart.calendarContainer.classList.add("sib-fp","sib-fp--start"),this.siflatpickrend.calendarContainer.classList.add("sib-fp","sib-fp--end"),r(document).trigger("sibooking:calendars",[this.siflatpickrstart,this.siflatpickrend]),r(this.siflatpickrend.calendarContainer).on("mouseover",".flatpickr-day",function(){t.hoverEnd&&t.hoverEnd.getTime()===this.dateObj.getTime()||(t.hoverEnd=this.dateObj,t.paintRange())}).on("mouseleave",function(){t.hoverEnd=null,t.paintRange()}),this.applyDisable()}addEventHandlers(){var t=this;r('input[name="quantity"]').on("change",function(){n.normalizeQuantity(r(this).val())!==t.inputQuantity&&t.onQuantityChanged()}),r(document).on("sib:guests:change",function(e,i,a){a&&!r(a).closest("form").is(t.$root.closest("form"))||t.refreshPrice()}),r(".single_add_to_cart_button").not("#sibookingpurchase").on("click",function(e){var i=t.missingSelection();i?(e.preventDefault(),t._missingSaid=i,t.tell(i)):t._missingSaid&&(t.$root.find(".sib-note").text()===t._missingSaid&&t.say(""),t._missingSaid="")}),r("#sibookingpurchase").on("click",function(){r('input[name="isbookingpurchase"]').val(!0)}),r("#siwidget-update").on("click",function(e){e.preventDefault(),t.widgetUpdate()}),this.$root.find(".sib-panel").length&&(this.$root.on("click",".sib-trigger",function(){t.togglePanel()}),this.$root.on("click",".sib-panel-close, .sib-backdrop",function(){t.closePanel()}),r(document).on("keydown.sibpanel",function(e){e.key==="Escape"&&t.closePanel()}),r(document).on("mousedown.sibpanel touchstart.sibpanel",function(e){t.$root.hasClass("is-open")&&!r(e.target).closest("#sib-cal").length&&t.closePanel()})),this.$root.on("click keydown",".sib-step[data-index]",function(e){if(!(e.type==="keydown"&&e.key!=="Enter"&&e.key!==" ")){e.preventDefault();var i=parseInt(r(this).attr("data-index"),10);!isNaN(i)&&i<=t.furthestStep()&&t.changeStep(i)}}),this.$root.on("click",".sib-reset",function(e){e.preventDefault(),t.clearStartEndDate()})}missingSelection(){return!this.startDate()||!this.endDate()?l("Please first select your booking dates","sales-igniter-rentals-bookings-lite"):this.steps.indexOf("endtime")!==-1&&(!this.times.getTime("from")||!this.times.getTime("to"))?l("Please select your pick-up and return times","sales-igniter-rentals-bookings-lite"):""}onQuantityChanged(){var t=this.startDate(),e=this.endDate();if(this.updateDisabledDatesAll(),this.say(""),!t){this.render();return}if(this.rangeStillFree(t,e||t)){this.render();return}this.clearStartEndDate(),this.say(c.sprintf(c._n("There is not %d free on those dates. Please pick your dates again.","There are not %d free on those dates. Please pick your dates again.",this.inputQuantity,"sales-igniter-rentals-bookings-lite"),this.inputQuantity))}rangeStillFree(t,e){var i={};(this.lists.booked||[]).forEach(function(o){i[o]=!0});var a=t.clone().startOf("day"),s=e.clone().startOf("day");if(i[a.format(n.DAY)])return!1;for(a.add(1,"d");a.isBefore(s,"day");){if(i[a.format(n.DAY)])return!1;a.add(1,"d")}return!0}say(t){var e=this.$root.find(".sib-note");if(!e.length){if(!t)return;e=r('<p class="sib-note" aria-live="polite"></p>');var i=this.$summary();i.length?i.before(e):this.$root.append(e)}e.text(t||"").prop("hidden",!t)}tell(t){this.say(t);var e=this.$root.find(".sib-note").get(0);e&&e.scrollIntoView&&e.scrollIntoView({block:"nearest"})}guestsText(){var t=this.$root.closest("form").find(".sib-guests").get(0);return t&&t.sibGuests?t.sibGuests.summary():""}guestFields(){var t={};return this.$root.closest("form").find(".sib-guests-input[name], .sib-guests-total[name]").each(function(){this.value!==""&&(t[this.name]=this.value)}),t}blockedStarts(){return[]}updateDisabledDatesAll(){this.inputQuantity=n.normalizeQuantity(r('input[name="quantity"]').val()),this.lists=n.disabledLists(d(),this.inputQuantity,this.startDate(),this.blockedStarts()),this.applyDisable(),this.times&&(this.times.ensureValid("from"),this.times.ensureValid("to"))}applyDisable(){var t=d();this._closedFor!==t&&(this._closedFor=t,this._closedStart=(t.disabled_dates||[]).concat(t.disabled_dates_start||[]),this._closedEnd=(t.disabled_dates||[]).concat(t.disabled_dates_end||[]));var e=this.startDate(),i=this.getMaxDate();this.siflatpickrstart&&this.siflatpickrstart.set({disable:this.lists.start,maxDate:e?null:i}),this.siflatpickrend&&this.siflatpickrend.set({disable:this.lists.end,minDate:e?e.format(n.DAY):null,maxDate:i})}updateDisabledDatesEnd(){this.updateDisabledDatesAll()}getMaxDate(){var t=this.times&&this.times.enabled()?this.times.getTime("from"):"";return n.maxDate(d(),this.startDate(),this.lists.booked,t,this.inputQuantity)}getMinDateForEndDate(){return this.startDate()?n.minEndDate(this.startDate(),d().minLength,!!d().nightly):null}onDayCreate(t,e,i,a,s){var o=d(),h=moment(s.dateObj).format(n.DAY),u=null;if(o.nightly&&(u=n.dayState(o,this.inputQuantity,h),s.setAttribute("data-sib-day-state",u)),o.nightly?u==="booked"||u==="turnover":this.lists.booked.indexOf(h)!==-1)s.classList.add("sib-booked"),s.title=l("Fully booked","sales-igniter-rentals-bookings-lite");else{var p=n.disabledBy(h,t==="start"?this._closedStart||[]:this._closedEnd||[]);if(p.length){s.classList.add("sib-closed");var g=p.map(function(v){return v.reason}).filter(function(v,w,D){return v&&D.indexOf(v)===w});s.title=g.length?g.join(" · "):l("Disabled","sales-igniter-rentals-bookings-lite"),s.setAttribute("data-sib-reason",s.title)}}if(S().showPrices&&o.dayPrices&&o.dayPrices[h]&&!s.classList.contains("flatpickr-disabled")){var y=document.createElement("span");y.className="sib-price",y.textContent=o.dayPrices[h],s.appendChild(y)}if(S().showUnitsLeft&&!s.classList.contains("flatpickr-disabled")){var f=n.unitsLeft(o,h);if(f!==null){var b=document.createElement("span");b.className="sib-left"+(f<=I()?" is-low":""),b.textContent=c.sprintf(l("%d left","sales-igniter-rentals-bookings-lite"),f),s.appendChild(b)}}this.paintDay(s,t==="end"),r(document).trigger("sibooking:daycreate",[s,h,t,u])}paintDay(t,e){var i=this.startDate(),a=this.endDate()||(e&&this.hoverEnd?moment(this.hoverEnd):null);if(t.classList.remove("sib-range-start","sib-inrange","sib-range-end"),!!i){var s=moment(t.dateObj);s.isSame(i,"day")&&t.classList.add("sib-range-start"),a&&a.isAfter(i,"day")&&s.isAfter(i,"day")&&s.isBefore(a,"day")&&t.classList.add("sib-inrange"),a&&s.isSame(a,"day")&&!s.isSame(i,"day")&&t.classList.add("sib-range-end")}}paintRange(){var t=this;[[this.siflatpickrend,!0],[this.siflatpickrstart,!1]].forEach(function(e){var i=e[0];if(!(!i||!i.days))for(var a=i.days.querySelectorAll(".flatpickr-day"),s=0;s<a.length;s++)t.paintDay(a[s],e[1])})}onStartOpen(){this.updateDisabledDatesAll()}onChangeStart(){this.say("");var t=this.startDate(),e=t?t.format(n.DAY):"";if(e&&this._lastStart&&e!==this._lastStart&&(this.siflatpickrend&&this.siflatpickrend.clear(),this.times&&(this.times.setTime("from","",!0),this.times.setTime("to","",!0)),this.hoverEnd=null),this._lastStart=e,this.updateDisabledDatesAll(),this.startDate()){var i=this.endDate(),a=this.getMaxDate();i&&(i.isBefore(this.startDate(),"day")||a&&i.isAfter(moment(a,n.DAY),"day"))&&this.siflatpickrend.clear()}this.times&&this.times.updateFromDisabledTimes(),this.completeStep("start")}onOpenEnd(){if(!this.startDate()){this.siflatpickrend.close();return}this.applyDisable(),this.siflatpickrend.jumpToDate(this.startDate().toDate())}onChangeEnd(){this.updateInputValues(),this.paintRange(),this.times&&this.times.updateToDisabledTimes(),this.completeStep("end")}onCloseEnd(){this.updateInputValues(),this.render()}updateInputValues(){var t=r("#flatpickr2"),e=this.endDate();t.val(e?e.format(n.DAY):""),this.siflatpickrend&&this.siflatpickrend.altInput&&(this.siflatpickrend.altInput.value=e?this.siflatpickrend.formatDate(e.toDate(),this.dateFormat):"")}clearStartEndDate(){this._lastStart="",this.siflatpickrstart&&this.siflatpickrstart.clear(),this.siflatpickrend&&this.siflatpickrend.clear(),this.times&&(this.times.setTime("from","",!0),this.times.setTime("to","",!0)),this.hoverEnd=null,this.render(),this.goTo(0)}setInitialDates(){var t=d();if(!(!t.sessionFromDate||!t.sessionToDate||t.sessionFromDate==="Invalid Date"||t.sessionToDate==="Invalid Date")){var e=moment(t.sessionFromDate),i=moment(t.sessionToDate);!e.isValid()||!i.isValid()||t.minDate&&e.isBefore(moment(t.minDate),"day")||(this.siflatpickrstart.setDate(e.format(n.DAY),!1),this.updateDisabledDatesAll(),this.siflatpickrend.setDate(i.format(n.DAY),!1),this.updateInputValues(),this.times&&this.times.setInitialTimes(),this.afterInitialDates(e,i),this._lastStart=e.format(n.DAY),this._rememberedKey=this.startDate()&&this.endDate()?this.startDate().format(n.DAY)+" "+(this.times&&this.times.getTime("from")||"")+"|"+this.endDate().format(n.DAY)+" "+(this.times&&this.times.getTime("to")||""):"",this.siflatpickrstart.jumpToDate(e.toDate()),this.siflatpickrend.jumpToDate(e.toDate()),this.render(),this.goTo(this.steps.length),this.paintRange())}}afterInitialDates(t,e){}widgetUpdate(){if(!this.startDate()||!this.endDate()){this.tell(l("Please first select your booking dates","sales-igniter-rentals-bookings-lite"));return}var t=this,e=r("#sibooking-calendar");e.LoadingOverlay&&e.LoadingOverlay("show");var i={fromDate:this.startDate().format(n.DAY),toDate:this.endDate().format(n.DAY),fromTime:this.times?this.times.getTime("from"):"",toTime:this.times?this.times.getTime("to"):"",action:"sibooking_calendar_global",nonce:d().nonce},a=function(){e.LoadingOverlay&&e.LoadingOverlay("hide"),t.tell(l("Booking dates updated","sales-igniter-rentals-bookings-lite"))},s=function(o){o&&o.statusText==="abort"||(e.LoadingOverlay&&e.LoadingOverlay("hide"),t.tell(l("Your dates could not be saved. Check your connection and try again.","sales-igniter-rentals-bookings-lite")))};r.ajaxq&&r.ajaxq.isRunning("sibookingGlobalCalendar")&&r.ajaxq.abort("sibookingGlobalCalendar"),this.postDates(i,"sibookingGlobalCalendar").done(a).fail(s)}postDates(t,e){var i=d().ajaxurl,a=function(){return t.nonce=d().nonce,e&&r.ajaxq?r.ajaxq(e,{url:i,type:"POST",data:t}):r.post(i,t)},s=r.Deferred();return a().done(s.resolve).fail(function(o){if(o&&o.statusText!=="abort"&&window.sibAjax&&window.sibAjax.isNonceFailure(o)){window.sibAjax.renewNonce().then(function(){a().done(s.resolve).fail(s.reject)},function(){s.reject(o)});return}s.reject(o)}),s.promise()}furthestStep(){for(var t=0;t<this.steps.length&&this.isStepDone(this.steps[t]);t++);return Math.min(t,this.steps.length-1)}isStepDone(t){switch(t){case"start":return!!this.startDate();case"starttime":return!!(this.times&&this.times.getTime("from"));case"end":return!!this.endDate();case"endtime":return!!(this.times&&this.times.getTime("to"))}return!1}allDone(){var t=this;return this.steps.every(function(e){return t.isStepDone(e)})}stepValue(t){var e="ddd D MMM";switch(t){case"start":return this.startDate()?this.startDate().format(e):"";case"end":return this.endDate()?this.endDate().format(e):"";case"starttime":return this.times&&this.times.getTime("from")?this.times.label(this.times.getTime("from")):"";case"endtime":return this.times&&this.times.getTime("to")?this.times.label(this.times.getTime("to")):""}return""}completeStep(t){var e=this.steps.indexOf(t);if(this.render(),e!==-1){for(var i=e+1;i<this.steps.length&&this.isStepDone(this.steps[i]);)i++;if(this.goTo(i),this.allDone()&&this.$root.hasClass("is-open")){var a=this;setTimeout(function(){a.closePanel()},350)}}}onTimePicked(t){if(t==="from"&&this.times){this.updateDisabledDatesAll();var e=this.endDate(),i=this.getMaxDate();e&&i&&e.isAfter(moment(i,n.DAY),"day")&&(this.siflatpickrend.clear(),this.times.setTime("to","",!0),this.updateInputValues()),this.times.ensureValid("to")}this.completeStep(t==="to"?"endtime":"starttime")}changeStep(t){var e=this.steps[t],i=this.times;e==="start"?(this.siflatpickrend&&this.steps.indexOf("end")!==-1&&this.siflatpickrend.clear(),i&&(i.setTime("from","",!0),i.setTime("to","",!0)),this.hoverEnd=null,this.updateInputValues()):e==="starttime"?i&&i.setTime("to","",!0):e==="end"&&(i&&i.setTime("to","",!0),this.hoverEnd=null),this.render(),this.goTo(t)}goTo(t){this.stepIndex=Math.max(0,Math.min(t,this.steps.length));var e=this.steps[this.stepIndex],i=this.$root.find(".sib-stage"),a=e==="start"||!e&&!this.steps.length,s=e==="end"||e==="endtime"?"end":"start";a&&(s="start"),r(this.siflatpickrstart.calendarContainer).toggle(s==="start"),r(this.siflatpickrend.calendarContainer).toggle(s==="end"),s==="end"&&this.startDate()&&this.siflatpickrend.jumpToDate((this.endDate()||this.startDate()).toDate());var o=e==="endtime"?"to":"from";this.times&&this.times.enabled()&&this.times.render(o);var h=e==="starttime"||e==="endtime"?"time":"date";e===void 0&&(h="done"),i.attr("data-active",h);var u=e?T[e]:l("Your booking","sales-igniter-rentals-bookings-lite"),p="";if(s==="end"&&this.startDate()){var g=this.startDate().format("ddd D MMM")+(this.times&&this.times.getTime("from")?" · "+this.times.label(this.times.getTime("from")):"");p='<span class="sib-pane-ctx">'+m(d().nightly?T.start+" "+g:c.sprintf(l("Pick-up %s","sales-igniter-rentals-bookings-lite"),g))+"</span>"}this.$root.find(".sib-pane--date .sib-pane-head").html('<span class="sib-h">'+m(s==="end"?T.end:T.start)+"</span>"+p),this.$root.attr("data-step",e||"done"),this.renderSteps();var y=this.$root.find(".sib-stage-hint");if(y.text(e&&this.stepHints()[e]||""),e==="end"&&this.startDate()&&!this.endDate()){var f=n.minEndDate(this.startDate(),d().minLength,!!d().nightly);n.isDayDisabled(f,this.lists.end)||(this.hoverEnd=moment(f,n.DAY).toDate(),this.paintRange())}this.renderSummary(),r(document).trigger("sibooking:step",[e||"done",this.$root])}stepHints(){return{start:l("Tap a day to continue. Greyed days are booked, closed, or too close to the next booking.","sales-igniter-rentals-bookings-lite"),end:l("Days before pick-up and past the next booking cannot be picked.","sales-igniter-rentals-bookings-lite"),starttime:l("Choosing a time moves straight to the return date.","sales-igniter-rentals-bookings-lite"),endtime:""}}render(){this.renderSteps(),this.renderTrigger(),this.renderSummary(),this.rememberDates(),this.announceDates()}announceDates(){var t=this.startDate(),e=this.endDate(),i=(t?t.format(n.DAY):"")+"|"+(e?e.format(n.DAY):"");i!==this._datesKey&&(this._datesKey=i,r(document.body).trigger("sibooking:dates",[t,e]))}rememberDates(){var t=d();if(!(!t.ajaxurl||t.isComposite)&&!(this.steps.indexOf("end")===-1||!this.allDone())){var e=this.startDate(),i=this.endDate();if(!(!e||!i||i.isBefore(e,"day"))){var a=this.times&&this.times.getTime("from")||"",s=this.times&&this.times.getTime("to")||"",o=e.format(n.DAY)+" "+a+"|"+i.format(n.DAY)+" "+s;o!==this._rememberedKey&&(this._rememberedKey=o,this.postDates({action:"sibooking_calendar_global",fromDate:e.format(n.DAY),toDate:i.format(n.DAY),fromTime:a,toTime:s}))}}}renderSteps(){var t=this.$root.find(".sib-steps");if(this.$root.toggleClass("sib-cal--steps",t.length>0&&S().showSteps!==!1&&this.steps.length>0),!!t.length){if(S().showSteps===!1){t.empty().hide();return}t.show();var e=this,i=this.furthestStep();t.empty(),this.steps.forEach(function(a,s){var o=e.isStepDone(a),h="sib-step"+(o?" is-done":"")+(s===e.stepIndex?" is-on":"")+(s<=i?" is-reachable":""),u=o?e.stepValue(a):s===e.stepIndex?l("Choose","sales-igniter-rentals-bookings-lite"):"",p=o&&s!==e.stepIndex?' title="'+m(l("Change","sales-igniter-rentals-bookings-lite"))+'"':"";t.append('<div class="'+h+'" data-index="'+s+'" role="button" tabindex="0"'+p+' aria-label="'+m(T[a]+(o?": "+u:""))+'"><div class="sib-step-bar"></div><span class="sib-step-t">'+m(T[a])+'</span><span class="sib-step-v">'+m(u)+"</span></div>")})}}updateVisibleTime(t){}quotable(){var t=d();return!!(this.startDate()&&this.endDate()&&this.allDone()&&!t.isComposite&&t.ajaxurl)}totalBox(){var t=r(".sib-rental-total");if(!t.length){t=r('<div class="sib-rental-total" aria-live="polite"></div>');var e=this.$root.closest(".summary, .product"),i=".products, .related, .upsells, .up-sells, .cross-sells, .wc-block-product-template, .wp-block-woocommerce-product-collection, .wp-block-woocommerce-related-products",a=function(o){return o.filter(function(){return!r(this).closest(i).length})},s=a(e.find(".sib-pricing").not(".sib-pricing--loop")).first();s.length||(s=a(e.find("p.price")).first()),s.length||(s=a(e.find(".price")).first()),s.length||(s=r(".single-product .summary p.price").first()),s.length?s.after(t):this.$root.find(".sib-summary").append(t)}return t}showQuote(t){var e=this.totalBox(),i=t.quantity>1?' <span class="sib-rental-total-qty">× '+t.quantity+"</span>":"";e.html('<span class="sib-rental-total-label">'+m(l("Total for your dates","sales-igniter-rentals-bookings-lite"))+i+'</span><span class="sib-rental-total-amount">'+t.total_html+"</span>"),e.removeClass("is-in"),e[0].offsetWidth,e.addClass("is-in")}hideQuote(){this.totalBox().removeClass("is-in")}notesBox(){var t=r(".sib-quote-notes");return t.length||(t=r('<div class="sib-quote-notes" aria-live="polite"></div>'),this.totalBox().after(t)),t}showNotes(t){var e=Array.isArray(t)?t.filter(function(s){return s&&s.text}):[],i=r(".sib-quote-notes");if(!(!e.length&&!i.length)){i=this.notesBox();var a=e.map(function(s){var o=String(s.key||"").replace(/[^A-Za-z0-9_-]/g,"");return'<p class="sib-quote-note'+(o?" sib-quote-note--"+o:"")+'">'+m(s.text)+"</p>"}).join("");i.html()!==a&&i.html(a)}}quoteFields(){return this.guestFields()}showQuoteError(t){this.totalBox().html(t).addClass("is-in")}quoteAgain(t){}refreshPrice(){var t=this,e=d(),i=this.startDate(),a=this.endDate(),s=function(){t._priceKey="",t.showCardTotal(null),t.hideQuote(),t.showNotes(null)};if(!this.quotable()){s();return}var o=r('input[name="variation_id"]').val()||r('button[name="add-to-cart"]').val()||r('input[name="add-to-cart"]').val()||r(".single_add_to_cart_button").val()||"";if(!o){s();return}var h={action:"sibooking_rental_price",nonce:e.nonce,productid:o,variationid:r('input[name="variation_id"]').val()||0,from:i.format(n.DAY),to:a.format(n.DAY),fromtime:this.times?this.times.getTime("from"):"",totime:this.times?this.times.getTime("to"):"",quantity:this.inputQuantity};r.extend(h,this.quoteFields());var u=JSON.stringify(h);if(u===this._priceKey){this._lastQuote&&this._lastQuoteKey===u&&this.quoteAgain(this._lastQuote);return}this._priceKey=u,clearTimeout(this._priceTimer),this.notesBox();var p=function(){t._priceKey===u&&(s(),t.showQuoteError('<span class="sib-ajax-error" role="alert">'+m(l("The price for these dates could not be loaded.","sales-igniter-rentals-bookings-lite"))+' <a href="#" class="sib-ajax-retry">'+m(l("Try again","sales-igniter-rentals-bookings-lite"))+"</a></span>"))};this._retryBound||(this._retryBound=!0,r(document).on("click",".sib-ajax-retry",function(f){f.preventDefault(),t._priceKey="",t.refreshPrice()}));var g=function(f){if(t._priceKey===u){if(!f||!f.success){s();return}t._lastQuote=f.data,t._lastQuoteKey=u,t.showCardTotal(f.data),t.showQuote(f.data),t.showNotes(f.data.notes)}},y=function(f){h.nonce=d().nonce;var b=r.ajaxq?r.ajaxq("sibookingPrice",{url:e.ajaxurl,type:"POST",data:h}):r.post(e.ajaxurl,h);b.done(g).fail(function(v){if(!(t._priceKey!==u||v&&v.statusText==="abort")){if(f<1){p();return}var w=function(){y(f-1)};window.sibAjax&&window.sibAjax.isNonceFailure(v)?window.sibAjax.renewNonce().then(w,p):setTimeout(w,800)}})};this._priceTimer=setTimeout(function(){y(1)},120)}showCardTotal(t){var e=this.$root.closest(".product, .type-product, body").find(".sib-pricing").not(".sib-pricing--loop, .sib-pricing--custom").first();if(e.length){var i=e.find(".sib-pricing-head");if(i.find(".sib-pricing-total--live").remove(),!t||!t.total_html){e.removeClass("has-total has-live-total");return}var a=parseFloat(t.hours||0),s=parseInt(t.days||0,10),o,h=this.times&&this.times.enabled()&&this.times.getTime("from")&&this.times.getTime("to"),u=Math.floor(a/24),p=Math.ceil(Math.round((a-u*24)*100)/100);if(h&&a>0&&a<24){var g=Math.ceil(a);o=c.sprintf(c._n("for %d hour","for %d hours",g,"sales-igniter-rentals-bookings-lite"),g)}else h&&u>0&&p>0&&(t.length_unit||d().lengthUnit)!=="night"?o=c.sprintf(l("for %1$s %2$s","sales-igniter-rentals-bookings-lite"),c.sprintf(c._n("%d day","%d days",u,"sales-igniter-rentals-bookings-lite"),u),c.sprintf(c._n("%d hour","%d hours",p,"sales-igniter-rentals-bookings-lite"),p)):(t.length_unit||d().lengthUnit)==="night"?o=c.sprintf(c._n("for %d night","for %d nights",Math.max(1,s),"sales-igniter-rentals-bookings-lite"),Math.max(1,s)):o=c.sprintf(c._n("for %d day","for %d days",Math.max(1,s),"sales-igniter-rentals-bookings-lite"),Math.max(1,s));r('<span class="sib-pricing-total sib-pricing-total--live"><b class="sib-pricing-amt"></b> <span class="sib-pricing-total-label"></span></span>').find("b").html(t.total_html).end().find(".sib-pricing-total-label").text(o).end().insertAfter(i.find(".sib-pricing-from")),e.addClass("has-total has-live-total")}}lengthText(t){return d().lengthUnit==="night"?c.sprintf(c._n("%d night","%d nights",t,"sales-igniter-rentals-bookings-lite"),t):t===1?l("1 day","sales-igniter-rentals-bookings-lite"):c.sprintf(l("%d days","sales-igniter-rentals-bookings-lite"),t)}summaryDateFormat(){return this.dateFormatMoment||"ddd D MMM"}summaryParts(){var t=this.startDate(),e=this.endDate();if(!t||!e||!this.allDone())return null;var i=this.summaryDateFormat(),a=this.times&&this.times.enabled(),s=t.format(i)+(a&&this.times.getTime("from")?" "+this.times.label(this.times.getTime("from")):""),o=e.format(i)+(a&&this.times.getTime("to")?" "+this.times.label(this.times.getTime("to")):""),h=n.dayCount(t,e,!!d().nightly,!!d().chargeReturnDay),u,p=a?this.times.getTime("from"):"",g=a?this.times.getTime("to"):"",y=!a||!p||!g||p==="00:00"&&(g==="00:00"||g==="23:59"),f=this,b=function(C){return f.lengthText(C)};if(y)u=b(h),s=t.format(i),o=e.format(i);else{var v=t.clone().set({hour:parseInt(p.split(":")[0],10),minute:parseInt(p.split(":")[1],10)}),w=e.clone().set({hour:parseInt(g.split(":")[0],10),minute:parseInt(g.split(":")[1],10)}),D=w.diff(v,"hours",!0);if(D<24){var x=Math.round(D*10)/10;u=x===1?l("1 hour","sales-igniter-rentals-bookings-lite"):c.sprintf(l("%s hours","sales-igniter-rentals-bookings-lite"),x)}else u=b(Math.ceil(D/24))}return{main:u,sub:s+" "+M()+" "+o}}resetButton(t){var e=this.$root.find(".sib-reset");return e.length||(e=r('<button type="button" class="sib-reset" title="'+m(l("Start over","sales-igniter-rentals-bookings-lite"))+'"><svg class="sib-ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M3 12a9 9 0 1 0 3-6.7"></path><path d="M3 4v5h5"></path></svg><span>'+m(l("Start over","sales-igniter-rentals-bookings-lite"))+"</span></button>"),t.after(e)),e}renderSummary(){this.refreshPrice();var t=this.$root.find(".sib-summary-text");if(t.length){this.resetButton(t).toggle(!!this.startDate());var e=this.summaryParts();if(!e){t.html('<span class="sib-summary-muted">'+m(l("Select your dates to see the booking summary","sales-igniter-rentals-bookings-lite"))+"</span>"),this.$root.removeClass("is-complete");return}t.html("<b>"+m(e.main)+"</b><small>"+m(e.sub)+"</small>"),this.$root.addClass("is-complete")}}togglePanel(){this.$root.hasClass("is-open")?this.closePanel():this.openPanel()}openPanel(){this.$root.addClass("is-open").find(".sib-trigger").attr("aria-expanded","true"),this.goTo(this.allDone()?0:this.furthestStep()),r("body").addClass("sib-panel-open")}closePanel(){this.$root.removeClass("is-open").find(".sib-trigger").attr("aria-expanded","false"),r("body").removeClass("sib-panel-open"),this.renderTrigger()}renderTrigger(){var t=this.$root.find(".sib-trigger-text");if(t.length){var e=this.startDate(),i=this.endDate(),a=this.dateFormatMoment||"ddd D MMM";if(!e){t.text(l("Select your dates","sales-igniter-rentals-bookings-lite")),this.$root.removeClass("has-dates");return}var s=this.times&&this.times.enabled(),o=e.format(a)+(s&&this.times.getTime("from")?" "+this.times.label(this.times.getTime("from")):""),h='<span class="sib-trigger-part">'+m(o)+"</span>";i&&this.steps.indexOf("end")!==-1&&(h+=' <span class="sib-trigger-part">'+M()+" "+m(i.format(a)+(s&&this.times.getTime("to")?" "+this.times.label(this.times.getTime("to")):""))+"</span>"),t.html(h),this.$root.addClass("has-dates")}}}var F={Calendar:L,TimeSlots:j,R:n,i18n:c,__:l,esc:m,data:d,ui:S,lowStock:I,onward:M,bidiLtr:O,STEP_LABELS:T,ICON_CAL:E,ICON_CLOCK:P};(window.sibookingCalendarExtensions||[]).forEach(function(k){if(typeof k=="function"){var t=k(F);typeof t=="function"&&(F.Calendar=t)}}),window.SibookingCalendar=new F.Calendar,window.SibookingCalendar.init(),window.SibookingTimepicker=window.SibookingCalendar.times||{timepickerfrom:r("#timepicker"),timepickerto:r("#timepicker2"),setInitialTimes:function(){},updateFromDisabledTimes:function(){},updateToDisabledTimes:function(){}},window.SibookingCalendar.isdatepicker()&&window.SibookingCalendar.$root.length&&window.SibookingCalendar.setInitialDates()})})(jQuery); -
sales-igniter-rentals-bookings-lite/trunk/Includes/AdminOrderDates.php
r3728745 r3729359 328 328 } 329 329 $days = max( 1, (int) ceil( $seconds / DAY_IN_SECONDS ) ); 330 // "Also charge the return day": a date-only rental from the 1st to the 3rd is 3 days 331 if ( ! $useTime && $productId && substr( (string) $to, 0, 10 ) > substr( (string) $from, 0, 10 ) && \Sibooking\Model\Pricing\ConfigFactory::countsReturnDay( $productId ) ) { 332 $days = max( 1, \Sibooking\Model\Stay::nights( $from, $to ) ) + 1; 333 } 330 334 return Price::lengthText( $days, $unit ); 331 335 } … … 557 561 $nightly = \Sibooking\Includes\Order::lineNightly( $item ); 558 562 foreach ( \Sibooking\Model\Availability::check( $pid, $from, $to, $qty, [ 559 'source' => 'admin', 560 'skip' => [ \Sibooking\Model\Availability::TOO_EARLY, \Sibooking\Model\Availability::STOCK ], 561 'nightly' => $nightly, 562 'line' => $item, 563 'source' => 'admin', 564 'skip' => [ \Sibooking\Model\Availability::TOO_EARLY, \Sibooking\Model\Availability::STOCK ], 565 'nightly' => $nightly, 566 'returnDayFree' => \Sibooking\Includes\Order::lineReturnDayFree( $item ), 567 'line' => $item, 563 568 ] ) as $reason => $message ) { 564 569 $errors[] = \Sibooking\Model\Availability::CLOSED === $reason ? __( 'The start or end date falls on a closed day', 'sales-igniter-rentals-bookings-lite' ) : $message; … … 572 577 // units free for the buffered range, this order's own rows left out 573 578 $endForBuffer = apply_filters( 'sibooking_end_datetime_for_buffer', $to, $item ); 574 // the line's own rule (a stay of nights frees its check-out day, Model\Stay) 575 $stay = [ 'nightly' => \Sibooking\Includes\Order::lineNightly( $item ) ]; 579 // the line's own rule (a stay of nights frees its check-out day, Model\Stay; "Days: can go 580 // out again on the return day" frees its return day, Model\Buffer) 581 $stay = [ 'nightly' => \Sibooking\Includes\Order::lineNightly( $item ), 'returnDayFree' => \Sibooking\Includes\Order::lineReturnDayFree( $item ) ]; 576 582 $sb = $this->buffer->calculateBufferBeforeStartDate( $pid, $from, $stay ); 577 583 $eb = $this->buffer->calculateBufferAfterEndDate( $pid, $endForBuffer, $stay + [ 'start' => $from ] ); … … 686 692 // 2. booking row -- in place, so the booking id and its send / return progress survive 687 693 $endForBuffer = apply_filters( 'sibooking_end_datetime_for_buffer', $to, $item ); 688 $stay = [ 'nightly' => \Sibooking\Includes\Order::lineNightly( $item ) ];694 $stay = [ 'nightly' => \Sibooking\Includes\Order::lineNightly( $item ), 'returnDayFree' => \Sibooking\Includes\Order::lineReturnDayFree( $item ) ]; 689 695 $sb = $this->buffer->calculateBufferBeforeStartDate( $pid, $from, $stay ); 690 696 $eb = $this->buffer->calculateBufferAfterEndDate( $pid, $endForBuffer, $stay + [ 'start' => $from ] ); … … 1358 1364 $pid = $part->get_product_id(); 1359 1365 $endForBuffer = apply_filters( 'sibooking_end_datetime_for_buffer', $to, $part ); 1360 $stay = [ 'line' => $part, 'parent' => Order::kitParentId( $part ), 'nightly' => Order::lineNightly( $part ) ];1366 $stay = [ 'line' => $part, 'parent' => Order::kitParentId( $part ), 'nightly' => Order::lineNightly( $part ), 'returnDayFree' => Order::lineReturnDayFree( $part ) ]; 1361 1367 return [ 1362 1368 $this->buffer->calculateBufferBeforeStartDate( $pid, $from, $stay ), … … 1374 1380 $errors = []; 1375 1381 foreach ( \Sibooking\Model\Availability::check( $line->get_product_id(), $from, $to, max( 1, (int) $line->get_quantity() ), [ 1376 'source' => 'admin', 1377 'skip' => [ \Sibooking\Model\Availability::TOO_EARLY, \Sibooking\Model\Availability::STOCK ], 1378 'nightly' => Order::lineNightly( $line ), 1379 'line' => $line, 1382 'source' => 'admin', 1383 'skip' => [ \Sibooking\Model\Availability::TOO_EARLY, \Sibooking\Model\Availability::STOCK ], 1384 'nightly' => Order::lineNightly( $line ), 1385 'returnDayFree' => Order::lineReturnDayFree( $line ), 1386 'line' => $line, 1380 1387 ] ) as $reason => $message ) { 1381 1388 $errors[] = \Sibooking\Model\Availability::CLOSED === $reason ? __( 'The start or end date falls on a closed day', 'sales-igniter-rentals-bookings-lite' ) : $message; -
sales-igniter-rentals-bookings-lite/trunk/Includes/CartAvailability.php
r3728745 r3729359 32 32 * Deliberately not counted against the customer: 33 33 * - their own order still waiting for payment (Validation::ownPendingOrderIds()); 34 * pending orders hold their units indefinitely ( Kevin, §7 Q2), so a retried34 * pending orders hold their units indefinitely (the owner, §7 Q2), so a retried 35 35 * payment would otherwise be refused by its own reservation; 36 36 * - "buy" lines of a rentable product (`_sibooking-isbookingpurchase`), which carry no dates; -
sales-igniter-rentals-bookings-lite/trunk/Includes/Diagnostics.php
r3728745 r3729359 211 211 } 212 212 213 /** The double opt-in that deletes everything ( Kevin's answer to review Q8). */213 /** The double opt-in that deletes everything (the owner's answer to review Q8). */ 214 214 private static function dataRemovalRow() { 215 215 $warning = DataRemoval::warning(); -
sales-igniter-rentals-bookings-lite/trunk/Includes/Order.php
r3728745 r3729359 49 49 50 50 /** 51 * Line meta: 1 = sold under "Booked by" "Days: can go out again on the return day" (its 52 * return day free for the next rental), 0 = not (see lineReturnDayFree()). 53 */ 54 const RETURN_DAY_META = '_sibooking_return_day_free'; 55 56 /** 51 57 * Line meta this class writes for its own use, never for a person to read or edit. 52 58 * The admin order screen shows a line's meta keys raw unless they are hidden here, and … … 55 61 * its price (`_sibooking_price`, Model\Pricing\Unified::SNAPSHOT_META). 56 62 */ 57 const HIDDEN_LINE_META = [ self::NIGHTLY_META, \Sibooking\Model\Pricing\Unified::SNAPSHOT_META ];63 const HIDDEN_LINE_META = [ self::NIGHTLY_META, self::RETURN_DAY_META, \Sibooking\Model\Pricing\Unified::SNAPSHOT_META ]; 58 64 59 65 /** … … 235 241 // a kit's children follow the parent's rule (a stay of nights frees the kayak 236 242 // on the cabin's check-out day too, Model\Stay) 237 $stayContext = [ 'line' => $order_item, 'parent' => self::kitParentId( $order_item ), 'nightly' => self::lineNightly( $order_item ) ];243 $stayContext = [ 'line' => $order_item, 'parent' => self::kitParentId( $order_item ), 'nightly' => self::lineNightly( $order_item ), 'returnDayFree' => self::lineReturnDayFree( $order_item ) ]; 238 244 $startDateWithBuffer = $this->buffer->calculateBufferBeforeStartDate($order_item->get_product_id(),$order_item->get_meta('sibooking-from'), $stayContext); 239 245 // the start tells a date-only rental's end whether its return day is held (Model\Buffer) … … 300 306 } 301 307 return $nightly; 308 } 309 310 /** 311 * Was this line sold with its return day free for the next rental ("Booked by" "Days: can 312 * go out again on the return day", Model\Buffer::startOnReturnDay())? Recorded on the line 313 * (`_sibooking_return_day_free`) the first time it is booked, like lineNightly(), so an 314 * order edit after the product or the store changed "Booked by" keeps what was sold. 315 * 316 * A line booked before 1.0.15 has no record: its booking row tells (a row held to its return 317 * day's 00:00 plus the turnover was written under the rule), else the current rule answers, 318 * which is what such a line was always edited under. 319 * 320 * @param \WC_Order_Item_Product $item 321 * @return bool 322 */ 323 public static function lineReturnDayFree( $item ) { 324 $stored = $item->get_meta( self::RETURN_DAY_META, true ); 325 if ( '' !== $stored && null !== $stored ) { 326 return (bool) (int) $stored; 327 } 328 $parent = self::kitParentId( $item ); 329 $free = self::returnDayFreeFromRow( $item, $parent ); 330 if ( null === $free ) { 331 $ruleId = $parent ? $parent : (int) $item->get_product_id(); 332 $free = \Sibooking\Model\Buffer::startOnReturnDay( \Sibooking\Model\PricingSubject::of( $ruleId ) ); 333 } 334 if ( $item->get_id() ) { 335 $item->update_meta_data( self::RETURN_DAY_META, $free ? '1' : '0' ); 336 $item->save_meta_data(); 337 } 338 return $free; 339 } 340 341 /** 342 * The rule an older line's booking row was written under, from its buffered end: the end 343 * worked out with the return day free, or held. Null when the row cannot tell (no row, a 344 * stay of nights, a same-day rental, or a buffer changed since). 345 * 346 * @return bool|null 347 */ 348 private static function returnDayFreeFromRow( $item, $parent ) { 349 if ( ! $item->get_id() || ! $item->get_order_id() ) { 350 return null; 351 } 352 $row = ( new \Sibooking\Model\Bookings() )->getBookingByOrderItemId( $item->get_order_id(), $item->get_id() ); 353 if ( ! $row || ! empty( $row->nightly ) || empty( $row->start_datetime ) || empty( $row->end_datetime ) || empty( $row->end_with_buffer_datetime ) ) { 354 return null; 355 } 356 $buffer = new \Sibooking\Model\Buffer(); 357 $context = [ 'nightly' => false, 'parent' => $parent, 'start' => (string) $row->start_datetime ]; 358 $free = $buffer->calculateBufferAfterEndDate( $item->get_product_id(), (string) $row->end_datetime, $context + [ 'returnDayFree' => true ] ); 359 $held = $buffer->calculateBufferAfterEndDate( $item->get_product_id(), (string) $row->end_datetime, $context + [ 'returnDayFree' => false ] ); 360 if ( $free === $held ) { 361 return null; 362 } 363 $stored = substr( (string) $row->end_with_buffer_datetime, 0, 19 ); 364 if ( $stored === $free ) { 365 return true; 366 } 367 return $stored === $held ? false : null; 302 368 } 303 369 … … 360 426 * before payment), so the order is kept -- the customer may already have paid -- and 361 427 * flagged: an order note, an admin email, and on-hold instead of processing when the 362 * payment completes ( Kevin's default for §7 Q1).428 * payment completes (the owner's default for §7 Q1). 363 429 * 364 430 * @param \WC_Order $order -
sales-igniter-rentals-bookings-lite/trunk/Includes/PendingHold.php
r3728745 r3729359 9 9 * How long an unpaid order holds its rental units (review finding DATA-08). 10 10 * 11 * Kevin's answer to the review's Q2: "this is manual payments. It should hold stock11 * The owner's answer to the review's Q2: "this is manual payments. It should hold stock 12 12 * indefinitely for now." So by default nothing here ever runs: a pending or on-hold 13 13 * order keeps its units until it is cancelled, fails, is refunded, trashed or deleted, … … 41 41 /** 42 42 * Minutes an unpaid (pending) order holds its rental units after checkout. 0, the 43 * default, holds them until the order is cancelled, fails or is refunded ( Kevin's43 * default, holds them until the order is cancelled, fails or is refunded (the owner's 44 44 * answer to the stability review's Q2: manual payments). 45 45 * -
sales-igniter-rentals-bookings-lite/trunk/Includes/Price.php
r3728745 r3729359 85 85 86 86 /** 87 * day | night: how the store words a daily rate (Rentals > Settings > Date 88 * Formatting, "Daily rates are priced per"). The arithmetic never changes: a 89 * stay from the 7th to the 10th is charged as 3 days and worded as 3 nights. 87 * day | night: how the store words a daily rate of a product that is not booked by 88 * Nights. Since 1.0.15 the word follows "Booked by" (Model\Stay: Nights says night, both 89 * Days choices say day) and the store setting "Daily rates are priced per" (Settings > 90 * Date Formatting) is gone from the page; a store that saved Night keeps it, hidden but 91 * honoured, and is told once (Includes\BookedBy). The arithmetic never changes: a day 92 * rental worded per night is still charged by the day. 90 93 */ 91 94 public static function defaultPeriod() { … … 133 136 * week | month | event | person. 134 137 * 135 * 1. the product's own choice (Pricing > Price shown per), when not Automatic; 138 * 1. the product's own choice (Pricing > Price shown per), when not Automatic (Day and 139 * Night are no longer offered, 1.0.15; a product saved with one keeps it); 136 140 * 2. person, for a product whose guests each take a place (Guests tab); 137 141 * 3. hour, when the product's shortest rate is an hourly one; 138 * 4. the store's day or night. 142 * 4. night for a product booked by Nights ("Booked by", Model\Stay); 143 * 5. else day (or the old store wording, defaultPeriod()). 139 144 * 140 145 * @param int|string $productId -
sales-igniter-rentals-bookings-lite/trunk/Includes/Stays.php
r3728745 r3729359 13 13 * and cleaning time counts in whole days. The rule is Model\Stay; this class is the rest: 14 14 * 15 * - the settings, in this plugin's field groups (Model/ACF): "Stay type" on the store 16 * (Rentals > Settings > Calendar: Days | Nights) and on each date-only product (store 17 * default | Days | Nights), and the check-in / check-out times as text; a subscription 18 * product is never offered Nights; 15 * - the settings, in this plugin's field groups (Model/ACF): "Date-only rentals are booked by" 16 * on the store (Rentals > Settings > Calendar: Days, return day booked | Days, out again on 17 * the return day | Nights) and "Booked by" on each date-only product (its Calendar Rules 18 * tab: store setting | the same three), and the check-in / check-out times as text, shown 19 * for Nights only (Includes\BookedBy has the rest of the screens); a subscription product 20 * is never offered Nights; 19 21 * - what the calendar is told: nights as the length unit, "Check-in" / "Check-out" as the 20 22 * step labels unless the shop named them, the times; the day states are explained to … … 137 139 138 140 /** 139 * The Stay typeshows for every date-only rental type (`sibooking_rental_types` entries141 * "Booked by" shows for every date-only rental type (`sibooking_rental_types` entries 140 142 * with no time of day), not only the plain Date type the field group names. 141 143 * … … 148 150 } 149 151 $rows = []; 152 foreach ( self::dateOnlyTypes() as $type ) { 153 $rows[] = [ [ 'field' => 'field_61d28a385f491', 'operator' => '==', 'value' => $type ] ]; 154 } 155 if ( $rows ) { 156 $field['conditional_logic'] = $rows; 157 } 158 return $field; 159 } 160 161 /** @return string[] the registered rental types with no time of day (`sibooking_rental_types`) */ 162 public static function dateOnlyTypes() { 163 $types = []; 150 164 foreach ( \Sibooking\Model\RentalTypes::all() as $type => $def ) { 151 165 if ( empty( $def['time'] ) ) { 152 $rows[] = [ [ 'field' => 'field_61d28a385f491', 'operator' => '==', 'value' => $type ] ]; 153 } 154 } 155 if ( $rows ) { 156 $field['conditional_logic'] = $rows; 157 } 158 return $field; 159 } 160 161 /** A product that may not be a stay (a subscription rental, `sibooking_product_allows_stay`): its Stay type offers no Nights. */ 166 $types[] = (string) $type; 167 } 168 } 169 return $types; 170 } 171 172 /** A product that may not be a stay (a subscription rental, `sibooking_product_allows_stay`): its Booked by offers no Nights. */ 162 173 public function no_nights_for_subscriptions( $field ) { 163 174 $post = get_post(); // the product being edited -
sales-igniter-rentals-bookings-lite/trunk/Includes/StaysSwitch.php
r3728745 r3729359 165 165 $n = (int) $result['done']; 166 166 /* translators: %d: number of bookings */ 167 echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( sprintf( _n( '%d booking moved to the new stay type.', '%d bookings moved to the new stay type.', $n, 'sales-igniter-rentals-bookings-lite' ), $n ) ) . '</p></div>';167 echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( sprintf( _n( '%d booking now follows the new "Booked by".', '%d bookings now follow the new "Booked by".', $n, 'sales-igniter-rentals-bookings-lite' ), $n ) ) . '</p></div>'; 168 168 } 169 169 $conflictDays = isset( $result['conflicts'] ) ? implode( ', ', array_map( 'sanitize_text_field', (array) $result['conflicts'] ) ) : ''; -
sales-igniter-rentals-bookings-lite/trunk/Includes/Validation.php
r3728745 r3729359 163 163 * The customer's own order still waiting for payment: its booking rows are already 164 164 * written, and they must not count against the same customer's retry (review §6, 165 * and Kevin's answer to §7 Q2: pending orders hold their units indefinitely, so a165 * and the owner's answer to §7 Q2: pending orders hold their units indefinitely, so a 166 166 * retried payment days later would otherwise be refused by its own reservation). 167 167 * -
sales-igniter-rentals-bookings-lite/trunk/Languages/acf-strings.php
r3728745 r3729359 28 28 __( "Date", 'sales-igniter-rentals-bookings-lite' ); 29 29 __( "Date and Time", 'sales-igniter-rentals-bookings-lite' ); 30 __( "Stay type", 'sales-igniter-rentals-bookings-lite' );31 __( "Nights: check-in and check-out, the check-out day can be booked again the same day, and the length is counted in nights. Days: the item comes back on the last day, which stays booked.", 'sales-igniter-rentals-bookings-lite' );32 __( "Use the store default", 'sales-igniter-rentals-bookings-lite' );33 __( "Days (the item comes back on the last day)", 'sales-igniter-rentals-bookings-lite' );34 __( "Nights (check-in and check-out)", 'sales-igniter-rentals-bookings-lite' );35 __( "Check-in from", 'sales-igniter-rentals-bookings-lite' );36 __( "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for stays of nights.", 'sales-igniter-rentals-bookings-lite' );37 __( "Check-out by", 'sales-igniter-rentals-bookings-lite' );38 __( "Shown to the guest, for example \"11:00 am\". Empty: the store's.", 'sales-igniter-rentals-bookings-lite' );39 30 __( "Pricing", 'sales-igniter-rentals-bookings-lite' ); 40 31 __( "Fixed Price", 'sales-igniter-rentals-bookings-lite' ); 41 32 __( "Hourly Price", 'sales-igniter-rentals-bookings-lite' ); 42 33 __( "Daily Price", 'sales-igniter-rentals-bookings-lite' ); 34 __( "Also charge the return day", 'sales-igniter-rentals-bookings-lite' ); 35 __( "For rentals booked by the day. No: the 1st to the 3rd is 2 days (the return day is free). Yes: 3 days. Nights are charged per night.", 'sales-igniter-rentals-bookings-lite' ); 36 __( "Store setting", 'sales-igniter-rentals-bookings-lite' ); 37 __( "No", 'sales-igniter-rentals-bookings-lite' ); 38 __( "Yes", 'sales-igniter-rentals-bookings-lite' ); 43 39 __( "Headline price", 'sales-igniter-rentals-bookings-lite' ); 44 40 __( "What the product page and the shop show as this product's price.", 'sales-igniter-rentals-bookings-lite' ); … … 46 42 __( "Your own text", 'sales-igniter-rentals-bookings-lite' ); 47 43 __( "Price shown per", 'sales-igniter-rentals-bookings-lite' ); 48 __( "The headline reads \"From \$145 / night\". Week and month show what a whole week or month costs at your rates (\$449 / week). Night and event change only the word: a stay from the 7th to the 10th is 3 nights, charged as 3 days.", 'sales-igniter-rentals-bookings-lite' );49 __( "Automatic: the store's day or night(an hourly-only rate shows per hour)", 'sales-igniter-rentals-bookings-lite' );44 __( "The headline reads \"From \$145 / day\", or \"/ night\" for a product booked by Nights. Week and month show what a whole week or month costs at your rates (\$449 / week). Event changes only the word.", 'sales-igniter-rentals-bookings-lite' ); 45 __( "Automatic: follows \"Booked by\" (an hourly-only rate shows per hour)", 'sales-igniter-rentals-bookings-lite' ); 50 46 __( "Hour", 'sales-igniter-rentals-bookings-lite' ); 51 __( "Day", 'sales-igniter-rentals-bookings-lite' );52 __( "Night", 'sales-igniter-rentals-bookings-lite' );53 47 __( "Week", 'sales-igniter-rentals-bookings-lite' ); 54 48 __( "Month", 'sales-igniter-rentals-bookings-lite' ); … … 79 73 __( "Per unit booked, or per booking when each guest takes a place. On top of the maximum guests. Empty: no limit. 0: no pets.", 'sales-igniter-rentals-bookings-lite' ); 80 74 __( "Calendar Rules", 'sales-igniter-rentals-bookings-lite' ); 75 __( "Booked by", 'sales-igniter-rentals-bookings-lite' ); 76 __( "Which days a rental with dates (no times) holds. Bookings you already have keep their rule.", 'sales-igniter-rentals-bookings-lite' ); 77 __( "Days: returned on the last day, entire return day is booked", 'sales-igniter-rentals-bookings-lite' ); 78 __( "Days: can go out again on the return day", 'sales-igniter-rentals-bookings-lite' ); 79 __( "Nights: same-day check-out and check-in", 'sales-igniter-rentals-bookings-lite' ); 80 __( "Check-in from", 'sales-igniter-rentals-bookings-lite' ); 81 __( "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for products booked by Nights.", 'sales-igniter-rentals-bookings-lite' ); 82 __( "Check-out by", 'sales-igniter-rentals-bookings-lite' ); 83 __( "Shown to the guest, for example \"11:00 am\". Empty: the store's.", 'sales-igniter-rentals-bookings-lite' ); 81 84 __( "Use Default Store Closed Days / Holidays", 'sales-igniter-rentals-bookings-lite' ); 82 85 __( "Store Closed Days / Holidays", 'sales-igniter-rentals-bookings-lite' ); … … 118 121 __( "Store Open Time", 'sales-igniter-rentals-bookings-lite' ); 119 122 __( "Store Close Time", 'sales-igniter-rentals-bookings-lite' ); 120 __( " Stay type for date-only products", 'sales-igniter-rentals-bookings-lite' );121 __( " Nights: check-in and check-out; the check-out day can be booked by the next guest and lengths are counted in nights. Days: the item comes back on the last day. Each product can choose for itself.", 'sales-igniter-rentals-bookings-lite' );122 __( " Shown to guests of stays of nights, for example \"3:00 pm\". Text only: it does not change availability.", 'sales-igniter-rentals-bookings-lite' );123 __( "For example \"11:00 am\".", 'sales-igniter-rentals-bookings-lite' );123 __( "Date-only rentals are booked by", 'sales-igniter-rentals-bookings-lite' ); 124 __( "Which days a rental with dates (no times) holds.", 'sales-igniter-rentals-bookings-lite' ); 125 __( "For Nights. Shown to guests, for example \"3:00 pm\". Text only: it does not change availability.", 'sales-igniter-rentals-bookings-lite' ); 126 __( "For Nights. Shown to guests, for example \"11:00 am\". Text only: it does not change availability.", 'sales-igniter-rentals-bookings-lite' ); 124 127 __( "Allow rentals to start on the same day as they are returned", 'sales-igniter-rentals-bookings-lite' ); 125 128 __( "For date-only products rented by the day. On: a unit returned on a day can go out again that day, so another rental may start on the return day. Off: the return day stays with the rental that ends on it. Turnover time still applies, and rentals booked before a change keep the days they were booked with. Products rented by the night always free the check-out day; rentals with a time of day are held to the minute.", 'sales-igniter-rentals-bookings-lite' ); -
sales-igniter-rentals-bookings-lite/trunk/Languages/sales-igniter-rentals-bookings-lite.pot
r3728745 r3729359 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Sales Igniter Rentals & Bookings Lite 1.0.1 3\n"5 "Project-Id-Version: Sales Igniter Rentals & Bookings Lite 1.0.14\n" 6 6 "Report-Msgid-Bugs-To: https://rentalbookingsoftware.com/support/\n" 7 7 "Last-Translator: Sales Igniter <support@rentalbookingsoftware.com>\n" … … 10 10 "Content-Type: text/plain; charset=UTF-8\n" 11 11 "Content-Transfer-Encoding: 8bit\n" 12 "POT-Creation-Date: 2026-10-05T 08:35:41+00:00\n"12 "POT-Creation-Date: 2026-10-05T21:48:27+08:00\n" 13 13 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 14 "X-Generator: WP-CLI 2.12.0\n" … … 46 46 #: Includes/DatesCart.php:573 47 47 #: Includes/DatesCart.php:639 48 #: Languages/acf-strings.php:9 248 #: Languages/acf-strings.php:95 49 49 #: Model/CalendarStyle.php:212 50 50 #: Assets/public/js/sibookingCalendarUi.js:99 … … 57 57 #: Includes/DatesCart.php:578 58 58 #: Includes/DatesCart.php:642 59 #: Languages/acf-strings.php:9 359 #: Languages/acf-strings.php:96 60 60 #: Model/CalendarStyle.php:214 61 61 #: Assets/public/js/sibookingCalendarUi.js:101 … … 73 73 #: Admin/InventoryReport/InventoryReport.php:14 74 74 #: Admin/InventoryReport/InventoryReport.php:21 75 #: Languages/acf-strings.php:2 1775 #: Languages/acf-strings.php:220 76 76 msgid "Inventory Report" 77 77 msgstr "" … … 151 151 #: Ajax/InventoryReport.php:172 152 152 #: Ajax/InventoryReport.php:213 153 #: Languages/acf-strings.php:21 0153 #: Languages/acf-strings.php:213 154 154 msgid "Product" 155 155 msgstr "" … … 244 244 #: Admin/Ui/Format.php:41 245 245 #: Admin/Ui/Format.php:45 246 #: Includes/AdminOrderDates.php:48 3246 #: Includes/AdminOrderDates.php:487 247 247 #: Includes/DatesCart.php:556 248 #: Languages/acf-strings.php:5 8248 #: Languages/acf-strings.php:52 249 249 #: Model/Guests.php:113 250 250 msgid "Guests" … … 374 374 #: Admin/CalendarReport/CalendarReport.php:80 375 375 #: Admin/InventoryReport/InventoryReport.php:34 376 #: Languages/acf-strings.php:2 09376 #: Languages/acf-strings.php:212 377 377 msgid "Filters" 378 378 msgstr "" … … 419 419 420 420 #: Admin/CalendarStyler.php:109 421 #: Languages/acf-strings.php:1 17421 #: Languages/acf-strings.php:120 422 422 msgid "Calendar" 423 423 msgstr "" … … 657 657 #: Admin/DataRemovalSettings.php:87 658 658 #: Ajax/InventoryReport.php:232 659 #: Includes/BookedBy.php:200 660 #: Languages/acf-strings.php:38 659 661 msgid "Yes" 660 662 msgstr "" … … 662 664 #: Admin/DataRemovalSettings.php:87 663 665 #: Ajax/InventoryReport.php:234 666 #: Includes/BookedBy.php:201 667 #: Languages/acf-strings.php:37 664 668 msgid "No" 665 669 msgstr "" … … 835 839 836 840 #: Admin/Kits/KitsPage.php:202 837 #: Languages/acf-strings.php:21 1841 #: Languages/acf-strings.php:214 838 842 msgid "Category" 839 843 msgstr "" … … 1162 1166 1163 1167 #: Admin/Kits/KitsPage.php:475 1164 #: Languages/acf-strings.php: 871168 #: Languages/acf-strings.php:90 1165 1169 msgid "None" 1166 1170 msgstr "" … … 1254 1258 #: Admin/Ui/ListShell.php:105 1255 1259 #: Admin/Ui/ListShell.php:175 1256 #: Languages/acf-strings.php:2 181260 #: Languages/acf-strings.php:221 1257 1261 msgid "Search" 1258 1262 msgstr "" … … 1295 1299 1296 1300 #: Admin/Upgrade.php:92 1297 msgid "Extras for nightly stays: half-day cells for partly booked days, a Stay typebulk action, room-nights in the Usage Report"1301 msgid "Extras for nightly stays: half-day cells for partly booked days, a \"Booked by\" bulk action, room-nights in the Usage Report" 1298 1302 msgstr "" 1299 1303 … … 1335 1339 1336 1340 #: Admin/Upgrade.php:103 1337 #: Languages/acf-strings.php:3 91341 #: Languages/acf-strings.php:30 1338 1342 msgid "Pricing" 1339 1343 msgstr "" … … 1555 1559 msgstr "" 1556 1560 1557 #: Ajax/Calendar.php:7 771561 #: Ajax/Calendar.php:781 1558 1562 msgid "Closed for stocktake" 1559 1563 msgstr "" … … 1710 1714 #. translators: %d: a number of days 1711 1715 #: Ajax/InventoryReport.php:257 1712 #: Includes/Price.php: 1991716 #: Includes/Price.php:204 1713 1717 #: Model/Reminders/Rule.php:140 1714 1718 #: Assets/public/js/sibookingCalendarUi.js:1234 … … 1728 1732 1729 1733 #. translators: %s: hours 1730 #: Ajax/Price.php:27 01734 #: Ajax/Price.php:275 1731 1735 #, php-format 1732 1736 msgid "%s hour" … … 1735 1739 msgstr[1] "" 1736 1740 1737 #: Ajax/Price.php:34 31741 #: Ajax/Price.php:348 1738 1742 #: Model/Pricing/Unified.php:264 1739 1743 msgid "Rental" 1740 1744 msgstr "" 1741 1745 1742 #: Ajax/Price.php:3 451746 #: Ajax/Price.php:350 1743 1747 msgid "Discount" 1744 1748 msgstr "" 1745 1749 1746 #: Ajax/Price.php:3 451750 #: Ajax/Price.php:350 1747 1751 msgid "Rate adjustment" 1748 1752 msgstr "" … … 1814 1818 1815 1819 #: Includes/AdminOrderDates.php:131 1816 #: Includes/AdminOrderDates.php:3 681820 #: Includes/AdminOrderDates.php:372 1817 1821 msgid "Set the start and end times" 1818 1822 msgstr "" … … 1939 1943 msgstr[1] "" 1940 1944 1941 #: Includes/AdminOrderDates.php:36 31945 #: Includes/AdminOrderDates.php:367 1942 1946 msgid "Pick a start and an end date" 1943 1947 msgstr "" 1944 1948 1945 #: Includes/AdminOrderDates.php:3 771949 #: Includes/AdminOrderDates.php:381 1946 1950 msgid "The end must be after the start" 1947 1951 msgstr "" 1948 1952 1949 #: Includes/AdminOrderDates.php:38 01953 #: Includes/AdminOrderDates.php:384 1950 1954 #: Includes/CartAvailability.php:198 1951 1955 msgid "Those dates could not be read" 1952 1956 msgstr "" 1953 1957 1954 #: Includes/AdminOrderDates.php:56 41955 #: Includes/AdminOrderDates.php:138 11958 #: Includes/AdminOrderDates.php:569 1959 #: Includes/AdminOrderDates.php:1388 1956 1960 msgid "The start or end date falls on a closed day" 1957 1961 msgstr "" 1958 1962 1959 1963 #. translators: 1: units available, 2: units needed 1960 #: Includes/AdminOrderDates.php:5 841961 #: Includes/AdminOrderDates.php:9 351964 #: Includes/AdminOrderDates.php:590 1965 #: Includes/AdminOrderDates.php:941 1962 1966 #, php-format 1963 1967 msgid "Only %1$d of the %2$d units needed is free for these dates" … … 1966 1970 msgstr[1] "" 1967 1971 1968 #: Includes/AdminOrderDates.php:7 281969 #: Includes/AdminOrderDates.php:10 351972 #: Includes/AdminOrderDates.php:734 1973 #: Includes/AdminOrderDates.php:1041 1970 1974 msgid "the system" 1971 1975 msgstr "" 1972 1976 1973 1977 #. translators: 1: line item name, 2: old party, 3: new party, 4: user 1974 #: Includes/AdminOrderDates.php:7 341978 #: Includes/AdminOrderDates.php:740 1975 1979 #, php-format 1976 1980 msgid "Guests for %1$s changed from %2$s to %3$s by %4$s." 1977 1981 msgstr "" 1978 1982 1979 #: Includes/AdminOrderDates.php:7 361983 #: Includes/AdminOrderDates.php:742 1980 1984 msgid "(none)" 1981 1985 msgstr "" 1982 1986 1983 1987 #. translators: 1 item name, 2 old dates, 3 new dates, 4 user 1984 #: Includes/AdminOrderDates.php:7 441988 #: Includes/AdminOrderDates.php:750 1985 1989 #, php-format 1986 1990 msgid "Rental dates for %1$s changed from %2$s to %3$s by %4$s." 1987 1991 msgstr "" 1988 1992 1989 #: Includes/AdminOrderDates.php:7 461990 #: Includes/AdminOrderDates.php:10 471993 #: Includes/AdminOrderDates.php:752 1994 #: Includes/AdminOrderDates.php:1053 1991 1995 msgid "(no dates)" 1992 1996 msgstr "" 1993 1997 1994 1998 #. translators: 1: line item name, 2: user name 1995 #: Includes/AdminOrderDates.php:7 541996 #: Includes/AdminOrderDates.php:10 641999 #: Includes/AdminOrderDates.php:760 2000 #: Includes/AdminOrderDates.php:1070 1997 2001 #, php-format 1998 2002 msgid "Rental line %1$s re-priced by %2$s." … … 2000 2004 2001 2005 #. translators: 1: old total, 2: new total 2002 #: Includes/AdminOrderDates.php:76 02003 #: Includes/AdminOrderDates.php:10 692006 #: Includes/AdminOrderDates.php:766 2007 #: Includes/AdminOrderDates.php:1075 2004 2008 #, php-format 2005 2009 msgid "Line total %1$s → %2$s." … … 2007 2011 2008 2012 #. translators: 1: current total, 2: price for the new dates 2009 #: Includes/AdminOrderDates.php:76 22010 #: Includes/AdminOrderDates.php:107 12013 #: Includes/AdminOrderDates.php:768 2014 #: Includes/AdminOrderDates.php:1077 2011 2015 #, php-format 2012 2016 msgid "Line total left at %1$s (price for the new dates would be %2$s)." … … 2016 2020 #. translators: 1: a product name, 2: why it could not be added to the cart 2017 2021 #. translators: 1: a product name, 2: why it cannot be booked ("Only 2 left on your dates") 2018 #: Includes/AdminOrderDates.php:9 062019 #: Includes/AdminOrderDates.php:9 292022 #: Includes/AdminOrderDates.php:912 2023 #: Includes/AdminOrderDates.php:935 2020 2024 #: Includes/GroupedRentals.php:512 2021 2025 #: Assets/public/js/sibooking-grouped.js:116 … … 2025 2029 msgstr "" 2026 2030 2027 #: Includes/AdminOrderDates.php:10 262031 #: Includes/AdminOrderDates.php:1032 2028 2032 msgid "The new dates could not be saved, so nothing was changed. Try again." 2029 2033 msgstr "" 2030 2034 2031 2035 #. translators: 1: the composite's or bundle's line name, 2: its parts, e.g. "Kayak × 2, Paddle set × 2", 3: old dates, 4: new dates, 5: user 2032 #: Includes/AdminOrderDates.php:10 442036 #: Includes/AdminOrderDates.php:1050 2033 2037 #, php-format 2034 2038 msgid "Rental dates for %1$s and its parts (%2$s) changed from %3$s to %4$s by %5$s." 2035 2039 msgstr "" 2036 2040 2037 #: Includes/AdminOrderDates.php:105 22041 #: Includes/AdminOrderDates.php:1058 2038 2042 msgid "Parts that were on other dates now follow it." 2039 2043 msgstr "" 2040 2044 2041 2045 #. translators: 1: the parts that were on other dates, 2: the composite's or bundle's line name, 3: its dates, 4: user 2042 #: Includes/AdminOrderDates.php:10 572046 #: Includes/AdminOrderDates.php:1063 2043 2047 #, php-format 2044 2048 msgid "Rental dates for %1$s put back on the dates of %2$s (%3$s) by %4$s." … … 2046 2050 2047 2051 #. translators: %d: number of order lines 2048 #: Includes/AdminOrderDates.php:14 632052 #: Includes/AdminOrderDates.php:1470 2049 2053 #, php-format 2050 2054 msgid "Rental dates updated on %d line." … … 2053 2057 msgstr[1] "" 2054 2058 2055 #: Includes/AdminOrderDates.php:14 662059 #: Includes/AdminOrderDates.php:1473 2056 2060 msgid "Rental dates not changed —" 2057 2061 msgstr "" … … 2090 2094 msgstr "" 2091 2095 2096 #: Includes/BookedBy.php:74 2097 #: Languages/acf-strings.php:77 2098 msgid "Days: returned on the last day, entire return day is booked" 2099 msgstr "" 2100 2101 #: Includes/BookedBy.php:75 2102 #: Languages/acf-strings.php:78 2103 msgid "Days: can go out again on the return day" 2104 msgstr "" 2105 2106 #: Includes/BookedBy.php:76 2107 #: Languages/acf-strings.php:79 2108 msgid "Nights: same-day check-out and check-in" 2109 msgstr "" 2110 2111 #: Includes/BookedBy.php:83 2112 msgid "The next rental can start the day after." 2113 msgstr "" 2114 2115 #: Includes/BookedBy.php:84 2116 msgid "A rental can start on the day the last one comes back." 2117 msgstr "" 2118 2119 #: Includes/BookedBy.php:85 2120 msgid "Like a hotel: the check-out day can be the next guest's check-in day. Prices and lengths read \"per night\"." 2121 msgstr "" 2122 2123 #: Includes/BookedBy.php:93 2124 #: Includes/Stays.php:206 2125 #: Includes/Stays.php:245 2126 msgid "Nights" 2127 msgstr "" 2128 2129 #: Includes/BookedBy.php:95 2130 msgid "Days, out again on the return day" 2131 msgstr "" 2132 2133 #: Includes/BookedBy.php:97 2134 msgid "Days, return day booked" 2135 msgstr "" 2136 2137 #. translators: %s: the store's "Booked by" choice, e.g. "Nights" 2138 #. translators: %s: the store's answer, Yes or No 2139 #: Includes/BookedBy.php:104 2140 #: Includes/BookedBy.php:203 2141 #, php-format 2142 msgid "Store setting (%s)" 2143 msgstr "" 2144 2145 #: Includes/BookedBy.php:109 2146 msgid "Products can choose their own. What the return day costs is set under Pricing › \"Also charge the return day\". Bookings you already have keep their rule." 2147 msgstr "" 2148 2149 #. translators: an old "Price shown per" choice kept on a product 2150 #: Includes/BookedBy.php:223 2151 msgid "Day (old setting)" 2152 msgstr "" 2153 2154 #. translators: an old "Price shown per" choice kept on a product 2155 #: Includes/BookedBy.php:225 2156 msgid "Night (old setting)" 2157 msgstr "" 2158 2159 #: Includes/BookedBy.php:229 2160 msgid "Day and Night are no longer choices: Automatic follows \"Booked by\". This product keeps its old setting until you change it." 2161 msgstr "" 2162 2163 #: Includes/BookedBy.php:257 2164 msgid "Your prices say \"per night\"" 2165 msgstr "" 2166 2167 #: Includes/BookedBy.php:258 2168 msgid "The setting \"Daily rates are priced per: Night\" is gone: \"night\" or \"day\" now follows \"Booked by\", and your prices keep saying \"per night\" for now. If you rent by the night, set \"Date-only rentals are booked by\" to Nights: the check-out day can then be the next guest's check-in day." 2169 msgstr "" 2170 2171 #: Includes/BookedBy.php:259 2172 msgid "Open \"Booked by\"" 2173 msgstr "" 2174 2175 #: Includes/BookedBy.php:260 2176 msgid "Say \"per day\" instead" 2177 msgstr "" 2178 2179 #: Includes/BookedBy.php:261 2180 #: Model/AdminAlerts.php:78 2181 msgid "Dismiss" 2182 msgstr "" 2183 2184 #: Includes/BookedBy.php:268 2185 #: Model/AdminAlerts.php:85 2186 msgid "Sorry, you are not allowed to do that." 2187 msgstr "" 2188 2092 2189 #: Includes/Calendar.php:84 2093 2190 msgid "First choose product options to load the booking calendar" … … 2280 2377 2281 2378 #: Includes/Diagnostics.php:179 2282 #: Languages/acf-strings.php:1 672379 #: Languages/acf-strings.php:170 2283 2380 msgid "Debug logging" 2284 2381 msgstr "" … … 2333 2430 2334 2431 #: Includes/Diagnostics.php:216 2335 #: Languages/acf-strings.php:17 12432 #: Languages/acf-strings.php:174 2336 2433 msgid "Delete rental data on uninstall" 2337 2434 msgstr "" … … 2418 2515 2419 2516 #: Includes/Emails/Pickup.php:44 2420 #: Languages/acf-strings.php:17 52517 #: Languages/acf-strings.php:178 2421 2518 #: Model/Emails/Defaults.php:177 2422 2519 msgid "Pickup Reminder" … … 2456 2553 #: Includes/Emails/Pickup.php:150 2457 2554 #: Includes/Emails/Reminder.php:131 2458 #: Languages/acf-strings.php:19 02555 #: Languages/acf-strings.php:193 2459 2556 msgid "Subject" 2460 2557 msgstr "" … … 2462 2559 #: Includes/Emails/Pickup.php:158 2463 2560 #: Includes/Emails/Reminder.php:139 2464 #: Languages/acf-strings.php:19 22561 #: Languages/acf-strings.php:195 2465 2562 msgid "Email heading" 2466 2563 msgstr "" … … 2468 2565 #: Includes/Emails/Pickup.php:167 2469 2566 #: Includes/Emails/Reminder.php:148 2470 #: Languages/acf-strings.php: 1992567 #: Languages/acf-strings.php:202 2471 2568 msgid "Additional content" 2472 2569 msgstr "" … … 2484 2581 #: Includes/Emails/Pickup.php:176 2485 2582 #: Includes/Emails/Reminder.php:157 2486 #: Languages/acf-strings.php:20 32583 #: Languages/acf-strings.php:206 2487 2584 msgid "Email type" 2488 2585 msgstr "" … … 2494 2591 2495 2592 #: Includes/Emails/Reminder.php:41 2496 #: Languages/acf-strings.php:18 42593 #: Languages/acf-strings.php:187 2497 2594 #: Model/Emails/Defaults.php:168 2498 2595 #: Model/Emails/Defaults.php:179 … … 2505 2602 2506 2603 #: Includes/Emails/ReminderBody.php:124 2507 #: Languages/acf-strings.php:19 42604 #: Languages/acf-strings.php:197 2508 2605 msgid "Email body" 2509 2606 msgstr "" … … 2586 2683 2587 2684 #. translators: %s: products and dates 2588 #: Includes/Order.php:4 212685 #: Includes/Order.php:487 2589 2686 #, php-format 2590 2687 msgid "Another order booked the same units at the same moment: %s is now booked beyond its stock. The order will be put on hold when it is paid. Contact the customer to change the dates, or free a unit." … … 2592 2689 2593 2690 #. translators: %d: order number 2594 #: Includes/Order.php:4 252691 #: Includes/Order.php:491 2595 2692 #, php-format 2596 2693 msgid "Order #%d was booked at the same moment as another order and some of its rentals are over the stock. It will be on hold; see the order note." … … 2598 2695 2599 2696 #. translators: %d: order number 2600 #: Includes/Order.php:4 312697 #: Includes/Order.php:497 2601 2698 #, php-format 2602 2699 msgid "Rental double booking on order #%d" … … 2604 2701 2605 2702 #. translators: 1: order number, 2: products and dates, 3: link to the order 2606 #: Includes/Order.php:4 332703 #: Includes/Order.php:499 2607 2704 #, php-format 2608 2705 msgid "" … … 2615 2712 2616 2713 #. translators: 1: product name, 2: the rental dates 2617 #: Includes/Order.php: 6352714 #: Includes/Order.php:701 2618 2715 #, php-format 2619 2716 msgid "The rental booking for %1$s (%2$s) could not be saved, so these dates are not reserved. Add the booking by hand under Rentals > Bookings, or edit the dates on this order to try again." … … 2621 2718 2622 2719 #. translators: %d: order number 2623 #: Includes/Order.php: 6392720 #: Includes/Order.php:705 2624 2721 #, php-format 2625 2722 msgid "A rental booking could not be saved for order #%d, so its dates are not reserved. The order has a note with the details." … … 2632 2729 msgstr "" 2633 2730 2634 #: Includes/Price.php:17 02635 #: Includes/Price.php: 3952636 #: Includes/Price.php:10 172731 #: Includes/Price.php:175 2732 #: Includes/Price.php:400 2733 #: Includes/Price.php:1022 2637 2734 msgid "hour" 2638 2735 msgstr "" 2639 2736 2640 #: Includes/Price.php:17 12737 #: Includes/Price.php:176 2641 2738 msgid "night" 2642 2739 msgstr "" 2643 2740 2644 #: Includes/Price.php:17 22741 #: Includes/Price.php:177 2645 2742 msgid "week" 2646 2743 msgstr "" 2647 2744 2648 #: Includes/Price.php:17 32745 #: Includes/Price.php:178 2649 2746 msgid "month" 2650 2747 msgstr "" 2651 2748 2652 2749 #. translators: the price covers one event (a party, a wedding) 2653 #: Includes/Price.php:1 752750 #: Includes/Price.php:180 2654 2751 msgid "event" 2655 2752 msgstr "" 2656 2753 2657 2754 #. translators: the price is per guest 2658 #: Includes/Price.php:1 772755 #: Includes/Price.php:182 2659 2756 msgid "person" 2660 2757 msgstr "" 2661 2758 2662 #: Includes/Price.php:1 792663 #: Includes/Price.php: 3952664 #: Includes/Price.php:10 172759 #: Includes/Price.php:184 2760 #: Includes/Price.php:400 2761 #: Includes/Price.php:1022 2665 2762 msgid "day" 2666 2763 msgstr "" 2667 2764 2668 2765 #. translators: %d: number of nights 2669 #: Includes/Price.php: 1972766 #: Includes/Price.php:202 2670 2767 #: Assets/public/js/sibookingCalendarUi.js:1252 2671 2768 #, php-format,js-format … … 2676 2773 2677 2774 #. translators: 1: price, 2: "day" or "hour" 2678 #: Includes/Price.php: 3992775 #: Includes/Price.php:404 2679 2776 #, php-format 2680 2777 msgctxt "admin product list price" … … 2683 2780 2684 2781 #. translators: 1: price, 2: "day" or "hour" 2685 #: Includes/Price.php:40 32782 #: Includes/Price.php:408 2686 2783 #, php-format 2687 2784 msgctxt "admin product list price" … … 2690 2787 2691 2788 #. translators: %d: number of rental rate tiers 2692 #: Includes/Price.php:4 082789 #: Includes/Price.php:413 2693 2790 #, php-format 2694 2791 msgid "(%d rate)" … … 2697 2794 msgstr[1] "" 2698 2795 2699 #: Includes/Price.php:47 12700 #: Languages/acf-strings.php: 502796 #: Includes/Price.php:476 2797 #: Languages/acf-strings.php:46 2701 2798 msgid "Hour" 2702 2799 msgid_plural "Hours" … … 2704 2801 msgstr[1] "" 2705 2802 2706 #: Includes/Price.php:473 2707 #: Languages/acf-strings.php:51 2803 #: Includes/Price.php:478 2708 2804 msgid "Day" 2709 2805 msgid_plural "Days" … … 2711 2807 msgstr[1] "" 2712 2808 2713 #: Includes/Price.php:476 2714 #: Languages/acf-strings.php:52 2809 #: Includes/Price.php:481 2715 2810 msgid "Night" 2716 2811 msgid_plural "Nights" … … 2718 2813 msgstr[1] "" 2719 2814 2720 #: Includes/Price.php:4 782721 #: Languages/acf-strings.php: 532815 #: Includes/Price.php:483 2816 #: Languages/acf-strings.php:47 2722 2817 msgid "Week" 2723 2818 msgid_plural "Weeks" … … 2725 2820 msgstr[1] "" 2726 2821 2727 #: Includes/Price.php:48 02728 #: Languages/acf-strings.php: 542822 #: Includes/Price.php:485 2823 #: Languages/acf-strings.php:48 2729 2824 msgid "Month" 2730 2825 msgid_plural "Months" … … 2732 2827 msgstr[1] "" 2733 2828 2734 #: Includes/Price.php:48 22829 #: Includes/Price.php:487 2735 2830 msgid "Year" 2736 2831 msgid_plural "Years" … … 2739 2834 2740 2835 #. translators: %s: product name 2741 #: Includes/Price.php:71 32836 #: Includes/Price.php:718 2742 2837 #, php-format 2743 2838 msgid "%s was removed from your cart because its price could not be worked out for those dates. Please add it again with other dates, or contact us." … … 2745 2840 2746 2841 #. translators: %s: product name 2747 #: Includes/Price.php:71 32842 #: Includes/Price.php:718 2748 2843 msgid "A rental was removed from your cart because its price could not be worked out for those dates. Please add it again with other dates, or contact us." 2749 2844 msgstr "" 2750 2845 2751 #: Includes/Price.php:8 672752 #: Includes/Price.php:97 12846 #: Includes/Price.php:872 2847 #: Includes/Price.php:976 2753 2848 msgid "Per hour" 2754 2849 msgstr "" 2755 2850 2756 #: Includes/Price.php:87 02757 #: Includes/Price.php:105 32851 #: Includes/Price.php:875 2852 #: Includes/Price.php:1058 2758 2853 msgid "Per night" 2759 2854 msgstr "" 2760 2855 2761 #: Includes/Price.php:87 02762 #: Includes/Price.php:97 22763 #: Includes/Price.php:10 552856 #: Includes/Price.php:875 2857 #: Includes/Price.php:977 2858 #: Includes/Price.php:1060 2764 2859 msgid "Per day" 2765 2860 msgstr "" 2766 2861 2767 2862 #. translators: 1: price per night, 2: period label 2768 #: Includes/Price.php:9 052863 #: Includes/Price.php:910 2769 2864 #, php-format 2770 2865 msgid "As low as %1$s / night on %2$s" … … 2772 2867 2773 2868 #. translators: 1: price per day, 2: period label 2774 #: Includes/Price.php:9 062869 #: Includes/Price.php:911 2775 2870 #, php-format 2776 2871 msgid "As low as %1$s / day on %2$s" 2777 2872 msgstr "" 2778 2873 2779 #: Includes/Price.php:102 12874 #: Includes/Price.php:1026 2780 2875 #: Includes/RentBuy.php:233 2781 #: Languages/acf-strings.php:8 42876 #: Languages/acf-strings.php:87 2782 2877 msgid "From" 2783 2878 msgstr "" 2784 2879 2785 #: Includes/Price.php:103 12880 #: Includes/Price.php:1036 2786 2881 msgid "Booked out" 2787 2882 msgstr "" 2788 2883 2789 2884 #. translators: %d: units available 2790 #: Includes/Price.php:103 12885 #: Includes/Price.php:1036 2791 2886 #, php-format 2792 2887 msgid "%d unit available" … … 2795 2890 msgstr[1] "" 2796 2891 2797 #: Includes/Price.php:104 42892 #: Includes/Price.php:1049 2798 2893 msgid "Rates" 2799 2894 msgstr "" 2800 2895 2801 #: Includes/Price.php:105 32896 #: Includes/Price.php:1058 2802 2897 msgid "Per night / extra" 2803 2898 msgstr "" 2804 2899 2805 #: Includes/Price.php:10 552900 #: Includes/Price.php:1060 2806 2901 msgid "Per day / extra" 2807 2902 msgstr "" 2808 2903 2809 2904 #. translators: 1: add-on price, 2: add-on period 2810 #: Includes/Price.php:10 652905 #: Includes/Price.php:1070 2811 2906 #, php-format 2812 2907 msgid "then %1$s / extra %2$s" … … 2814 2909 2815 2910 #. translators: %s: price 2816 #: Includes/Price.php:10 672911 #: Includes/Price.php:1072 2817 2912 #, php-format 2818 2913 msgid "%s / hour" … … 2820 2915 2821 2916 #. translators: %s: price 2822 #: Includes/Price.php:107 02917 #: Includes/Price.php:1075 2823 2918 #, php-format 2824 2919 msgid "%s / night" … … 2826 2921 2827 2922 #. translators: %s: price 2828 #: Includes/Price.php:107 12923 #: Includes/Price.php:1076 2829 2924 #, php-format 2830 2925 msgid "%s / day" 2831 2926 msgstr "" 2832 2927 2833 #: Includes/Price.php:10 762928 #: Includes/Price.php:1081 2834 2929 msgid "Period" 2835 2930 msgstr "" 2836 2931 2837 #: Includes/Price.php:10 762932 #: Includes/Price.php:1081 2838 2933 msgid "Price" 2839 2934 msgstr "" … … 2878 2973 msgstr "" 2879 2974 2880 #: Includes/Stays.php:10 52881 #: Includes/Stays.php: 1922882 #: Includes/Stays.php:2 252975 #: Includes/Stays.php:107 2976 #: Includes/Stays.php:203 2977 #: Includes/Stays.php:236 2883 2978 msgid "Check-in" 2884 2979 msgstr "" 2885 2980 2886 #: Includes/Stays.php:1 082887 #: Includes/Stays.php: 1932888 #: Includes/Stays.php:2 292981 #: Includes/Stays.php:110 2982 #: Includes/Stays.php:204 2983 #: Includes/Stays.php:240 2889 2984 msgid "Check-out" 2890 2985 msgstr "" 2891 2986 2892 #: Includes/Stays.php:1 662987 #: Includes/Stays.php:177 2893 2988 msgid "Subscription rentals always count in days." 2894 2989 msgstr "" 2895 2990 2896 #: Includes/Stays.php:195 2897 #: Includes/Stays.php:234 2898 msgid "Nights" 2899 msgstr "" 2900 2901 #: Includes/Stays.php:284 2991 #: Includes/Stays.php:295 2902 2992 msgid "Whether the line is a stay of nights." 2903 2993 msgstr "" 2904 2994 2905 #: Includes/Stays.php:2 852995 #: Includes/Stays.php:296 2906 2996 msgid "Check-in date (Y-m-d)." 2907 2997 msgstr "" 2908 2998 2909 #: Includes/Stays.php:2 862999 #: Includes/Stays.php:297 2910 3000 msgid "Check-out date (Y-m-d), the morning the stay ends." 2911 3001 msgstr "" 2912 3002 2913 #: Includes/Stays.php:2 873003 #: Includes/Stays.php:298 2914 3004 msgid "Number of nights." 2915 3005 msgstr "" 2916 3006 2917 #: Includes/Stays.php:3 453007 #: Includes/Stays.php:356 2918 3008 msgid "For a stay of nights: how many nights; empty otherwise" 2919 3009 msgstr "" 2920 3010 2921 #: Includes/Stays.php:3 463011 #: Includes/Stays.php:357 2922 3012 msgid "For a stay of nights: the check-in date" 2923 3013 msgstr "" 2924 3014 2925 #: Includes/Stays.php:3 473015 #: Includes/Stays.php:358 2926 3016 msgid "For a stay of nights: the check-out date" 2927 3017 msgstr "" 2928 3018 2929 #: Includes/Stays.php:3 483019 #: Includes/Stays.php:359 2930 3020 msgid "The check-in time you set (Rentals > Settings), e.g. 3:00 pm" 2931 3021 msgstr "" 2932 3022 2933 #: Includes/Stays.php:3 493023 #: Includes/Stays.php:360 2934 3024 msgid "The check-out time you set, e.g. 11:00 am" 2935 3025 msgstr "" 2936 3026 2937 3027 #. translators: %s: the check-in date 2938 #: Includes/Stays.php:3 733028 #: Includes/Stays.php:384 2939 3029 #, php-format 2940 3030 msgid "Check-in: %s" … … 2942 3032 2943 3033 #. translators: %s: the check-out date 2944 #: Includes/Stays.php:3 753034 #: Includes/Stays.php:386 2945 3035 #, php-format 2946 3036 msgid "Check-out: %s" … … 2950 3040 #: Includes/StaysSwitch.php:167 2951 3041 #, php-format 2952 msgid "%d booking moved to the new stay type."2953 msgid_plural "%d bookings moved to the new stay type."3042 msgid "%d booking now follows the new \"Booked by\"." 3043 msgid_plural "%d bookings now follow the new \"Booked by\"." 2954 3044 msgstr[0] "" 2955 3045 msgstr[1] "" … … 3025 3115 3026 3116 #: Includes/Validation.php:103 3027 #: Model/Availability.php:7 63117 #: Model/Availability.php:78 3028 3118 msgid "Not enough inventory for the dates selected" 3029 3119 msgstr "" … … 3077 3167 msgstr "" 3078 3168 3079 #: Languages/acf-strings.php:303080 msgid "Stay type"3081 msgstr ""3082 3083 3169 #: Languages/acf-strings.php:31 3084 msgid " Nights: check-in and check-out, the check-out day can be booked again the same day, and the length is counted in nights. Days: the item comes back on the last day, which stays booked."3170 msgid "Fixed Price" 3085 3171 msgstr "" 3086 3172 3087 3173 #: Languages/acf-strings.php:32 3088 msgid " Use the store default"3174 msgid "Hourly Price" 3089 3175 msgstr "" 3090 3176 3091 3177 #: Languages/acf-strings.php:33 3092 msgid "Da ys (the item comes back on the last day)"3178 msgid "Daily Price" 3093 3179 msgstr "" 3094 3180 3095 3181 #: Languages/acf-strings.php:34 3096 msgid " Nights (check-in and check-out)"3182 msgid "Also charge the return day" 3097 3183 msgstr "" 3098 3184 3099 3185 #: Languages/acf-strings.php:35 3100 msgid " Check-in from"3186 msgid "For rentals booked by the day. No: the 1st to the 3rd is 2 days (the return day is free). Yes: 3 days. Nights are charged per night." 3101 3187 msgstr "" 3102 3188 3103 3189 #: Languages/acf-strings.php:36 3104 msgid "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for stays of nights." 3105 msgstr "" 3106 3107 #: Languages/acf-strings.php:37 3108 msgid "Check-out by" 3109 msgstr "" 3110 3111 #: Languages/acf-strings.php:38 3112 msgid "Shown to the guest, for example \"11:00 am\". Empty: the store's." 3190 msgid "Store setting" 3191 msgstr "" 3192 3193 #: Languages/acf-strings.php:39 3194 msgid "Headline price" 3113 3195 msgstr "" 3114 3196 3115 3197 #: Languages/acf-strings.php:40 3116 msgid " Fixed Price"3198 msgid "What the product page and the shop show as this product's price." 3117 3199 msgstr "" 3118 3200 3119 3201 #: Languages/acf-strings.php:41 3120 msgid " Hourly Price"3202 msgid "From the rates (From $50 / day)" 3121 3203 msgstr "" 3122 3204 3123 3205 #: Languages/acf-strings.php:42 3124 msgid " Daily Price"3206 msgid "Your own text" 3125 3207 msgstr "" 3126 3208 3127 3209 #: Languages/acf-strings.php:43 3128 msgid " Headline price"3210 msgid "Price shown per" 3129 3211 msgstr "" 3130 3212 3131 3213 #: Languages/acf-strings.php:44 3132 msgid " What the product page and the shop show as this product's price."3214 msgid "The headline reads \"From $145 / day\", or \"/ night\" for a product booked by Nights. Week and month show what a whole week or month costs at your rates ($449 / week). Event changes only the word." 3133 3215 msgstr "" 3134 3216 3135 3217 #: Languages/acf-strings.php:45 3136 msgid "From the rates (From $50 / day)" 3137 msgstr "" 3138 3139 #: Languages/acf-strings.php:46 3140 msgid "Your own text" 3141 msgstr "" 3142 3143 #: Languages/acf-strings.php:47 3144 msgid "Price shown per" 3145 msgstr "" 3146 3147 #: Languages/acf-strings.php:48 3148 msgid "The headline reads \"From $145 / night\". Week and month show what a whole week or month costs at your rates ($449 / week). Night and event change only the word: a stay from the 7th to the 10th is 3 nights, charged as 3 days." 3218 msgid "Automatic: follows \"Booked by\" (an hourly-only rate shows per hour)" 3149 3219 msgstr "" 3150 3220 3151 3221 #: Languages/acf-strings.php:49 3152 msgid "Automatic: the store's day or night (an hourly-only rate shows per hour)" 3222 msgid "Event" 3223 msgstr "" 3224 3225 #: Languages/acf-strings.php:50 3226 msgid "Your own price text" 3227 msgstr "" 3228 3229 #: Languages/acf-strings.php:51 3230 msgid "Replaces the price wherever a customer sees it. HTML is allowed. {price} is the headline amount and {period} its period, for example: <strong>{price}</strong> per {period}, cleaning included." 3231 msgstr "" 3232 3233 #: Languages/acf-strings.php:53 3234 msgid "Off leaves the product as it is: the quantity is the number of units. \"Each unit holds guests\" checks the party against the maximum per unit: a cottage that sleeps 4, or a room type for 2 with 5 in stock, where 5 guests need 3 rooms. \"Each guest takes one place\" makes the quantity the number of guests: seats on a cruise or a tour." 3235 msgstr "" 3236 3237 #: Languages/acf-strings.php:54 3238 msgid "Off: the quantity is all that is asked" 3153 3239 msgstr "" 3154 3240 3155 3241 #: Languages/acf-strings.php:55 3156 msgid "E vent"3242 msgid "Each unit holds up to a number of guests" 3157 3243 msgstr "" 3158 3244 3159 3245 #: Languages/acf-strings.php:56 3160 msgid " Your own price text"3246 msgid "Each guest takes one place (seats)" 3161 3247 msgstr "" 3162 3248 3163 3249 #: Languages/acf-strings.php:57 3164 msgid "Replaces the price wherever a customer sees it. HTML is allowed. {price} is the headline amount and {period} its period, for example: <strong>{price}</strong> per {period}, cleaning included." 3250 msgid "Maximum guests" 3251 msgstr "" 3252 3253 #: Languages/acf-strings.php:58 3254 msgid "Per unit when each unit holds guests (a cottage that sleeps 4: 4). Per booking when each guest takes a place; leave empty to allow up to the stock." 3165 3255 msgstr "" 3166 3256 3167 3257 #: Languages/acf-strings.php:59 3168 msgid " Off leaves the product as it is: the quantity is the number of units. \"Each unit holds guests\" checks the party against the maximum per unit: a cottage that sleeps 4, or a room type for 2 with 5 in stock, where 5 guests need 3 rooms. \"Each guest takes one place\" makes the quantity the number of guests: seats on a cruise or a tour."3258 msgid "Minimum guests per booking" 3169 3259 msgstr "" 3170 3260 3171 3261 #: Languages/acf-strings.php:60 3172 msgid " Off: the quantity is all that is asked"3262 msgid "The fewest guests one booking may have (a private tour for at least 2)." 3173 3263 msgstr "" 3174 3264 3175 3265 #: Languages/acf-strings.php:61 3176 msgid " Each unit holds up to a number of guests"3266 msgid "What guests are called" 3177 3267 msgstr "" 3178 3268 3179 3269 #: Languages/acf-strings.php:62 3180 msgid " Each guest takes one place (seats)"3270 msgid "Shown beside the guest count on the product page, for example Riders or Passengers. Leave empty for Guests." 3181 3271 msgstr "" 3182 3272 3183 3273 #: Languages/acf-strings.php:63 3184 msgid " Maximum guests"3274 msgid "Use the store's guest types" 3185 3275 msgstr "" 3186 3276 3187 3277 #: Languages/acf-strings.php:64 3188 msgid " Per unit when each unit holds guests (a cottage that sleeps 4: 4). Per booking when each guest takes a place; leave empty to allow up to the stock."3278 msgid "Rentals > Settings > Guests sets which guests are asked for: a single count, or adults with children, infants and pets." 3189 3279 msgstr "" 3190 3280 3191 3281 #: Languages/acf-strings.php:65 3192 msgid " Minimum guests per booking"3282 msgid "Guest types" 3193 3283 msgstr "" 3194 3284 3195 3285 #: Languages/acf-strings.php:66 3196 msgid " The fewest guests one booking may have (a private tour for at least 2)."3286 msgid "Adults are always asked for. Tick none for a single guest count." 3197 3287 msgstr "" 3198 3288 3199 3289 #: Languages/acf-strings.php:67 3200 msgid "What guests are called"3201 msgstr ""3202 3203 #: Languages/acf-strings.php:683204 msgid "Shown beside the guest count on the product page, for example Riders or Passengers. Leave empty for Guests."3205 msgstr ""3206 3207 #: Languages/acf-strings.php:693208 msgid "Use the store's guest types"3209 msgstr ""3210 3211 #: Languages/acf-strings.php:703212 msgid "Rentals > Settings > Guests sets which guests are asked for: a single count, or adults with children, infants and pets."3213 msgstr ""3214 3215 #: Languages/acf-strings.php:713216 msgid "Guest types"3217 msgstr ""3218 3219 #: Languages/acf-strings.php:723220 msgid "Adults are always asked for. Tick none for a single guest count."3221 msgstr ""3222 3223 #: Languages/acf-strings.php:733224 3290 #: Model/Guests.php:202 3225 3291 #: Model/Pricing/Unified.php:343 … … 3227 3293 msgstr "" 3228 3294 3229 #: Languages/acf-strings.php: 743295 #: Languages/acf-strings.php:68 3230 3296 #: Model/Guests.php:210 3231 3297 msgid "Infants" 3232 3298 msgstr "" 3233 3299 3234 #: Languages/acf-strings.php: 753300 #: Languages/acf-strings.php:69 3235 3301 #: Model/Guests.php:210 3236 3302 msgid "Pets" 3237 3303 msgstr "" 3238 3304 3305 #: Languages/acf-strings.php:70 3306 msgid "Most infants" 3307 msgstr "" 3308 3309 #: Languages/acf-strings.php:71 3310 msgid "Per unit booked, or per booking when each guest takes a place. On top of the maximum guests. Empty: no limit. 0: this rental does not take infants (steep stairs, a boat)." 3311 msgstr "" 3312 3313 #: Languages/acf-strings.php:72 3314 msgid "Most pets" 3315 msgstr "" 3316 3317 #: Languages/acf-strings.php:73 3318 msgid "Per unit booked, or per booking when each guest takes a place. On top of the maximum guests. Empty: no limit. 0: no pets." 3319 msgstr "" 3320 3321 #: Languages/acf-strings.php:74 3322 msgid "Calendar Rules" 3323 msgstr "" 3324 3325 #: Languages/acf-strings.php:75 3326 msgid "Booked by" 3327 msgstr "" 3328 3239 3329 #: Languages/acf-strings.php:76 3240 msgid "Most infants" 3241 msgstr "" 3242 3243 #: Languages/acf-strings.php:77 3244 msgid "Per unit booked, or per booking when each guest takes a place. On top of the maximum guests. Empty: no limit. 0: this rental does not take infants (steep stairs, a boat)." 3245 msgstr "" 3246 3247 #: Languages/acf-strings.php:78 3248 msgid "Most pets" 3249 msgstr "" 3250 3251 #: Languages/acf-strings.php:79 3252 msgid "Per unit booked, or per booking when each guest takes a place. On top of the maximum guests. Empty: no limit. 0: no pets." 3330 msgid "Which days a rental with dates (no times) holds. Bookings you already have keep their rule." 3253 3331 msgstr "" 3254 3332 3255 3333 #: Languages/acf-strings.php:80 3256 msgid "C alendar Rules"3334 msgid "Check-in from" 3257 3335 msgstr "" 3258 3336 3259 3337 #: Languages/acf-strings.php:81 3338 msgid "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for products booked by Nights." 3339 msgstr "" 3340 3341 #: Languages/acf-strings.php:82 3342 msgid "Check-out by" 3343 msgstr "" 3344 3345 #: Languages/acf-strings.php:83 3346 msgid "Shown to the guest, for example \"11:00 am\". Empty: the store's." 3347 msgstr "" 3348 3349 #: Languages/acf-strings.php:84 3260 3350 msgid "Use Default Store Closed Days / Holidays" 3261 3351 msgstr "" 3262 3352 3263 #: Languages/acf-strings.php:8 23353 #: Languages/acf-strings.php:85 3264 3354 msgid "Store Closed Days / Holidays" 3265 3355 msgstr "" 3266 3356 3267 #: Languages/acf-strings.php:8 33357 #: Languages/acf-strings.php:86 3268 3358 msgid "Add Row" 3269 3359 msgstr "" 3270 3360 3271 #: Languages/acf-strings.php:8 53361 #: Languages/acf-strings.php:88 3272 3362 msgid "To" 3273 3363 msgstr "" 3274 3364 3275 #: Languages/acf-strings.php:8 63365 #: Languages/acf-strings.php:89 3276 3366 msgid "Repeats" 3277 3367 msgstr "" 3278 3368 3279 #: Languages/acf-strings.php: 883369 #: Languages/acf-strings.php:91 3280 3370 msgid "Weekly" 3281 3371 msgstr "" 3282 3372 3283 #: Languages/acf-strings.php: 893373 #: Languages/acf-strings.php:92 3284 3374 msgid "Monthly" 3285 3375 msgstr "" 3286 3376 3287 #: Languages/acf-strings.php:9 03377 #: Languages/acf-strings.php:93 3288 3378 msgid "Yearly" 3289 3379 msgstr "" 3290 3380 3291 #: Languages/acf-strings.php:9 13381 #: Languages/acf-strings.php:94 3292 3382 msgid "Applies To" 3293 3383 msgstr "" 3294 3384 3295 #: Languages/acf-strings.php:9 43385 #: Languages/acf-strings.php:97 3296 3386 msgid "Both" 3297 3387 msgstr "" 3298 3388 3299 #: Languages/acf-strings.php:9 53389 #: Languages/acf-strings.php:98 3300 3390 msgid "Every day in the range: nothing may be rented across it" 3301 3391 msgstr "" 3302 3392 3303 #: Languages/acf-strings.php:9 63393 #: Languages/acf-strings.php:99 3304 3394 msgid "Reason" 3305 3395 msgstr "" 3306 3396 3307 #: Languages/acf-strings.php: 973397 #: Languages/acf-strings.php:100 3308 3398 msgid "Block out reason is optional. If you add it, it will show to the customer when they hover over those days that are disabled; otherwise the reason will just be \"Disabled\"." 3309 3399 msgstr "" 3310 3400 3311 #: Languages/acf-strings.php: 983401 #: Languages/acf-strings.php:101 3312 3402 msgid "e.g. Closed for stocktake" 3313 3403 msgstr "" 3314 3404 3315 #: Languages/acf-strings.php: 993405 #: Languages/acf-strings.php:102 3316 3406 msgid "Use Default Start Date Padding" 3317 3407 msgstr "" 3318 3408 3319 #: Languages/acf-strings.php:10 03409 #: Languages/acf-strings.php:103 3320 3410 msgid "This is the padding starting from now that you don't want to accept bookings for. For example if you set this to 2 days and today is January 1, the customer would not be able to select a start date until January 3. This is different than buffer before start date below in that it is not actually blocked out before the booked dates for future orders." 3321 3411 msgstr "" 3322 3412 3323 #: Languages/acf-strings.php:10 13413 #: Languages/acf-strings.php:104 3324 3414 msgid "Start Date Padding" 3325 3415 msgstr "" 3326 3416 3327 #: Languages/acf-strings.php:10 23417 #: Languages/acf-strings.php:105 3328 3418 msgid "Type" 3329 3419 msgstr "" 3330 3420 3331 #: Languages/acf-strings.php:10 33421 #: Languages/acf-strings.php:106 3332 3422 msgid "Hours" 3333 3423 msgstr "" 3334 3424 3335 #: Languages/acf-strings.php:10 43425 #: Languages/acf-strings.php:107 3336 3426 msgid "Days" 3337 3427 msgstr "" 3338 3428 3339 #: Languages/acf-strings.php:10 53429 #: Languages/acf-strings.php:108 3340 3430 msgid "Use Default Buffer Before Booking" 3341 3431 msgstr "" 3342 3432 3343 #: Languages/acf-strings.php:10 63433 #: Languages/acf-strings.php:109 3344 3434 msgid "Buffer Before Booking" 3345 3435 msgstr "" 3346 3436 3347 #: Languages/acf-strings.php:1 073437 #: Languages/acf-strings.php:110 3348 3438 msgid "Minutes" 3349 3439 msgstr "" 3350 3440 3351 #: Languages/acf-strings.php:1 083441 #: Languages/acf-strings.php:111 3352 3442 msgid "Use Default Buffer After Booking" 3353 3443 msgstr "" 3354 3444 3355 #: Languages/acf-strings.php:1 093445 #: Languages/acf-strings.php:112 3356 3446 msgid "Buffer After Booking" 3357 3447 msgstr "" 3358 3448 3359 #: Languages/acf-strings.php:11 03449 #: Languages/acf-strings.php:113 3360 3450 msgid "Use Default Minimum Booking Length" 3361 3451 msgstr "" 3362 3452 3363 #: Languages/acf-strings.php:11 13453 #: Languages/acf-strings.php:114 3364 3454 msgid "Minimum Booking Length" 3365 3455 msgstr "" 3366 3456 3367 #: Languages/acf-strings.php:11 23457 #: Languages/acf-strings.php:115 3368 3458 msgid "Use Default Maximum Booking Length" 3369 3459 msgstr "" 3370 3460 3371 #: Languages/acf-strings.php:11 33461 #: Languages/acf-strings.php:116 3372 3462 msgid "Maximum Booking Length" 3373 3463 msgstr "" 3374 3464 3375 #: Languages/acf-strings.php:11 43465 #: Languages/acf-strings.php:117 3376 3466 msgid "Maximum Days In The Future A Booking Is Allowed" 3377 3467 msgstr "" 3378 3468 3379 #: Languages/acf-strings.php:11 53469 #: Languages/acf-strings.php:118 3380 3470 msgid "Use Default Maximum Days In The Future A Booking Is Allowed" 3381 3471 msgstr "" 3382 3472 3383 #: Languages/acf-strings.php:11 63473 #: Languages/acf-strings.php:119 3384 3474 msgid "Rentals & Bookings Settings" 3385 3475 msgstr "" 3386 3476 3387 #: Languages/acf-strings.php:1 183477 #: Languages/acf-strings.php:121 3388 3478 msgid "Store Open Time" 3389 3479 msgstr "" 3390 3480 3391 #: Languages/acf-strings.php:1 193481 #: Languages/acf-strings.php:122 3392 3482 msgid "Store Close Time" 3393 3483 msgstr "" 3394 3484 3395 #: Languages/acf-strings.php:1203396 msgid "Stay type for date-only products"3397 msgstr ""3398 3399 #: Languages/acf-strings.php:1213400 msgid "Nights: check-in and check-out; the check-out day can be booked by the next guest and lengths are counted in nights. Days: the item comes back on the last day. Each product can choose for itself."3401 msgstr ""3402 3403 #: Languages/acf-strings.php:1223404 msgid "Shown to guests of stays of nights, for example \"3:00 pm\". Text only: it does not change availability."3405 msgstr ""3406 3407 3485 #: Languages/acf-strings.php:123 3408 msgid " For example \"11:00 am\"."3486 msgid "Date-only rentals are booked by" 3409 3487 msgstr "" 3410 3488 3411 3489 #: Languages/acf-strings.php:124 3490 msgid "Which days a rental with dates (no times) holds." 3491 msgstr "" 3492 3493 #: Languages/acf-strings.php:125 3494 msgid "For Nights. Shown to guests, for example \"3:00 pm\". Text only: it does not change availability." 3495 msgstr "" 3496 3497 #: Languages/acf-strings.php:126 3498 msgid "For Nights. Shown to guests, for example \"11:00 am\". Text only: it does not change availability." 3499 msgstr "" 3500 3501 #: Languages/acf-strings.php:127 3412 3502 msgid "Allow rentals to start on the same day as they are returned" 3413 3503 msgstr "" 3414 3504 3415 #: Languages/acf-strings.php:12 53505 #: Languages/acf-strings.php:128 3416 3506 msgid "For date-only products rented by the day. On: a unit returned on a day can go out again that day, so another rental may start on the return day. Off: the return day stays with the rental that ends on it. Turnover time still applies, and rentals booked before a change keep the days they were booked with. Products rented by the night always free the check-out day; rentals with a time of day are held to the minute." 3417 3507 msgstr "" 3418 3508 3419 #: Languages/acf-strings.php:12 63509 #: Languages/acf-strings.php:129 3420 3510 msgid "Date Formatting" 3421 3511 msgstr "" 3422 3512 3423 #: Languages/acf-strings.php:1 273513 #: Languages/acf-strings.php:130 3424 3514 msgid "Customer Side Date Field Input" 3425 3515 msgstr "" 3426 3516 3427 #: Languages/acf-strings.php:1 283517 #: Languages/acf-strings.php:131 3428 3518 msgid "Year-Month-Day (i.e. 2022-01-10)" 3429 3519 msgstr "" 3430 3520 3431 #: Languages/acf-strings.php:1 293521 #: Languages/acf-strings.php:132 3432 3522 msgid "Month day, Year (i.e. January 10, 2022)" 3433 3523 msgstr "" 3434 3524 3435 #: Languages/acf-strings.php:13 03525 #: Languages/acf-strings.php:133 3436 3526 msgid "month/day/year (i.e. 01/10/2022)" 3437 3527 msgstr "" 3438 3528 3439 #: Languages/acf-strings.php:13 13529 #: Languages/acf-strings.php:134 3440 3530 msgid "day/month/year (i.e. 10/01/2022)" 3441 3531 msgstr "" 3442 3532 3443 #: Languages/acf-strings.php:13 23533 #: Languages/acf-strings.php:135 3444 3534 msgid "month/day/year, no leading zeros (i.e. 1/10/2022)" 3445 3535 msgstr "" 3446 3536 3447 #: Languages/acf-strings.php:13 33537 #: Languages/acf-strings.php:136 3448 3538 msgid "day/month/year, no leading zeros (i.e. 10/1/2022)" 3449 3539 msgstr "" 3450 3540 3451 #: Languages/acf-strings.php:13 43541 #: Languages/acf-strings.php:137 3452 3542 msgid "day.month.year (i.e. 10.01.2022)" 3453 3543 msgstr "" 3454 3544 3455 #: Languages/acf-strings.php:13 53545 #: Languages/acf-strings.php:138 3456 3546 msgid "day-month-year (i.e. 10-01-2022)" 3457 3547 msgstr "" 3458 3548 3459 #: Languages/acf-strings.php:13 63549 #: Languages/acf-strings.php:139 3460 3550 msgid "Year/Month/Day (i.e. 2022/01/10)" 3461 3551 msgstr "" 3462 3552 3463 #: Languages/acf-strings.php:1 373553 #: Languages/acf-strings.php:140 3464 3554 msgid "Mon day, Year (i.e. Jan 10, 2022)" 3465 3555 msgstr "" 3466 3556 3467 #: Languages/acf-strings.php:1 383557 #: Languages/acf-strings.php:141 3468 3558 msgid "day Mon Year (i.e. 10 Jan 2022)" 3469 3559 msgstr "" 3470 3560 3471 #: Languages/acf-strings.php:1 393561 #: Languages/acf-strings.php:142 3472 3562 msgid "day Month Year (i.e. 10 January 2022)" 3473 3563 msgstr "" 3474 3564 3475 #: Languages/acf-strings.php:14 03565 #: Languages/acf-strings.php:143 3476 3566 msgid "Weekday, Mon day, Year (i.e. Mon, Jan 10, 2022)" 3477 3567 msgstr "" 3478 3568 3479 #: Languages/acf-strings.php:14 13569 #: Languages/acf-strings.php:144 3480 3570 msgid "Weekday day Mon Year (i.e. Mon 10 Jan 2022)" 3481 3571 msgstr "" 3482 3572 3483 #: Languages/acf-strings.php:14 23573 #: Languages/acf-strings.php:145 3484 3574 msgid "Weekday, Month day, Year (i.e. Monday, January 10, 2022)" 3485 3575 msgstr "" 3486 3576 3487 #: Languages/acf-strings.php:14 33577 #: Languages/acf-strings.php:146 3488 3578 msgid "Customer Side Time Field" 3489 3579 msgstr "" 3490 3580 3491 #: Languages/acf-strings.php:14 43581 #: Languages/acf-strings.php:147 3492 3582 msgid "4:33 am (am / pm)" 3493 3583 msgstr "" 3494 3584 3495 #: Languages/acf-strings.php:14 53585 #: Languages/acf-strings.php:148 3496 3586 msgid "4:33 AM (AM / PM)" 3497 3587 msgstr "" 3498 3588 3499 #: Languages/acf-strings.php:14 63589 #: Languages/acf-strings.php:149 3500 3590 msgid "04:33 (24 hour time format)" 3501 3591 msgstr "" 3502 3592 3503 #: Languages/acf-strings.php:1 473593 #: Languages/acf-strings.php:150 3504 3594 msgid "Daily rates are priced per" 3505 3595 msgstr "" 3506 3596 3507 #: Languages/acf-strings.php:1 483597 #: Languages/acf-strings.php:151 3508 3598 msgid "How a daily rate is worded on product pages and in the booking bar. A holiday let is priced per night and a kayak per day; the arithmetic is the same (the 7th to the 10th is 3 nights or 3 days). A product can choose its own under Pricing." 3509 3599 msgstr "" 3510 3600 3511 #: Languages/acf-strings.php:1 493601 #: Languages/acf-strings.php:152 3512 3602 msgid "Day ($50 / day, 3 days)" 3513 3603 msgstr "" 3514 3604 3515 #: Languages/acf-strings.php:15 03605 #: Languages/acf-strings.php:153 3516 3606 msgid "Night ($50 / night, 3 nights)" 3517 3607 msgstr "" 3518 3608 3519 #: Languages/acf-strings.php:15 13609 #: Languages/acf-strings.php:154 3520 3610 msgid "Which products ask for guests" 3521 3611 msgstr "" 3522 3612 3523 #: Languages/acf-strings.php:15 23613 #: Languages/acf-strings.php:155 3524 3614 msgid "A product asks for guests once its Guests tab is not Off. These are the store's defaults for those products; a product can choose its own guest types." 3525 3615 msgstr "" 3526 3616 3527 #: Languages/acf-strings.php:15 33617 #: Languages/acf-strings.php:156 3528 3618 msgid "Age note for adults" 3529 3619 msgstr "" 3530 3620 3531 #: Languages/acf-strings.php:15 43621 #: Languages/acf-strings.php:157 3532 3622 #: Model/Guests.php:298 3533 3623 msgid "Ages 13 or above" 3534 3624 msgstr "" 3535 3625 3536 #: Languages/acf-strings.php:15 53626 #: Languages/acf-strings.php:158 3537 3627 msgid "Age note for children" 3538 3628 msgstr "" 3539 3629 3540 #: Languages/acf-strings.php:15 63630 #: Languages/acf-strings.php:159 3541 3631 #: Model/Guests.php:300 3542 3632 msgid "Ages 2–12" 3543 3633 msgstr "" 3544 3634 3545 #: Languages/acf-strings.php:1 573635 #: Languages/acf-strings.php:160 3546 3636 msgid "Age note for infants" 3547 3637 msgstr "" 3548 3638 3549 #: Languages/acf-strings.php:1 583639 #: Languages/acf-strings.php:161 3550 3640 #: Model/Guests.php:302 3551 3641 msgid "Under 2" 3552 3642 msgstr "" 3553 3643 3554 #: Languages/acf-strings.php:1 593644 #: Languages/acf-strings.php:162 3555 3645 msgid "Note for pets" 3556 3646 msgstr "" 3557 3647 3558 #: Languages/acf-strings.php:16 03648 #: Languages/acf-strings.php:163 3559 3649 msgid "Bringing a service animal?" 3560 3650 msgstr "" 3561 3651 3562 #: Languages/acf-strings.php:16 13652 #: Languages/acf-strings.php:164 3563 3653 msgid "Infants take a seat" 3564 3654 msgstr "" 3565 3655 3566 #: Languages/acf-strings.php:16 23656 #: Languages/acf-strings.php:165 3567 3657 msgid "For products whose guests each take a place (seats on a tour): an infant then takes a seat of their own, free of charge. Off: infants ride on a lap and take no seat." 3568 3658 msgstr "" 3569 3659 3570 #: Languages/acf-strings.php:16 33660 #: Languages/acf-strings.php:166 3571 3661 msgid "Advanced" 3572 3662 msgstr "" 3573 3663 3574 #: Languages/acf-strings.php:16 43664 #: Languages/acf-strings.php:167 3575 3665 msgid "Mode" 3576 3666 msgstr "" 3577 3667 3578 #: Languages/acf-strings.php:16 53668 #: Languages/acf-strings.php:168 3579 3669 msgid "Production" 3580 3670 msgstr "" 3581 3671 3582 #: Languages/acf-strings.php:16 63672 #: Languages/acf-strings.php:169 3583 3673 msgid "Developer" 3584 3674 msgstr "" 3585 3675 3586 #: Languages/acf-strings.php:1 683676 #: Languages/acf-strings.php:171 3587 3677 msgid "Also write the routine rental events (booking saves, checkout checks, upgrade steps) to WooCommerce > Status > Logs, source \"sibooking\". Errors and warnings are always logged; turn this on while you investigate a problem, then off again." 3588 3678 msgstr "" 3589 3679 3590 #: Languages/acf-strings.php:1 693680 #: Languages/acf-strings.php:172 3591 3681 msgid "Use legacy pricing (deprecated)" 3592 3682 msgstr "" 3593 3683 3594 #: Languages/acf-strings.php:17 03684 #: Languages/acf-strings.php:173 3595 3685 msgid "Off (recommended): rentals are priced by the unified pricing engine, the same rules as our Magento and Shopify apps. On: the pricing code from before unified pricing prices every rental exactly as it used to. Kept for checking a price a customer asks about. Orders already placed keep their price either way." 3596 3686 msgstr "" 3597 3687 3598 #: Languages/acf-strings.php:17 23688 #: Languages/acf-strings.php:175 3599 3689 msgid "ICS Export Security Keys" 3600 3690 msgstr "" 3601 3691 3602 #: Languages/acf-strings.php:17 33692 #: Languages/acf-strings.php:176 3603 3693 msgid "Key" 3604 3694 msgstr "" 3605 3695 3606 #: Languages/acf-strings.php:17 43696 #: Languages/acf-strings.php:177 3607 3697 msgid "Emails" 3608 3698 msgstr "" 3609 3699 3610 #: Languages/acf-strings.php:17 63700 #: Languages/acf-strings.php:179 3611 3701 msgid "Remind the customer before their rental starts. How many reminders, and how far ahead, is set here; what the email says is set further down this section." 3612 3702 msgstr "" 3613 3703 3614 #: Languages/acf-strings.php:1 773704 #: Languages/acf-strings.php:180 3615 3705 msgid "Active" 3616 3706 msgstr "" 3617 3707 3618 #: Languages/acf-strings.php:1 783708 #: Languages/acf-strings.php:181 3619 3709 msgid "Name" 3620 3710 msgstr "" 3621 3711 3622 #: Languages/acf-strings.php:1 793712 #: Languages/acf-strings.php:182 3623 3713 msgid "Optional. A name for this reminder, shown on the settings summary and in the order note." 3624 3714 msgstr "" 3625 3715 3626 #: Languages/acf-strings.php:18 03716 #: Languages/acf-strings.php:183 3627 3717 msgid "Time before pickup" 3628 3718 msgstr "" 3629 3719 3630 #: Languages/acf-strings.php:18 13720 #: Languages/acf-strings.php:184 3631 3721 msgid "Unit" 3632 3722 msgstr "" 3633 3723 3634 #: Languages/acf-strings.php:18 23724 #: Languages/acf-strings.php:185 3635 3725 msgid "Send at (time of day)" 3636 3726 msgstr "" 3637 3727 3638 #: Languages/acf-strings.php:18 33728 #: Languages/acf-strings.php:186 3639 3729 msgid "Optional, and only for days: send at this time of day instead of exactly at the offset." 3640 3730 msgstr "" 3641 3731 3642 #: Languages/acf-strings.php:18 53732 #: Languages/acf-strings.php:188 3643 3733 msgid "Remind the customer before the rental is due back. How many reminders, and how far ahead, is set here; what the email says is set further down this section." 3644 3734 msgstr "" 3645 3735 3646 #: Languages/acf-strings.php:18 63736 #: Languages/acf-strings.php:189 3647 3737 msgid "Time before the rental is due back" 3648 3738 msgstr "" 3649 3739 3650 #: Languages/acf-strings.php:1 873740 #: Languages/acf-strings.php:190 3651 3741 msgid "Reminder status" 3652 3742 msgstr "" 3653 3743 3654 #: Languages/acf-strings.php:1 883744 #: Languages/acf-strings.php:191 3655 3745 msgid "No rental reminders are configured yet." 3656 3746 msgstr "" 3657 3747 3658 #: Languages/acf-strings.php:1 893748 #: Languages/acf-strings.php:192 3659 3749 msgid "Send this email" 3660 3750 msgstr "" 3661 3751 3662 #: Languages/acf-strings.php:19 13752 #: Languages/acf-strings.php:194 3663 3753 msgid "{site_title}, {order_date} and {order_number} work here." 3664 3754 msgstr "" 3665 3755 3666 #: Languages/acf-strings.php:19 33756 #: Languages/acf-strings.php:196 3667 3757 msgid "The line printed at the top of the email, inside the header." 3668 3758 msgstr "" 3669 3759 3670 #: Languages/acf-strings.php:19 53760 #: Languages/acf-strings.php:198 3671 3761 msgid "Other languages" 3672 3762 msgstr "" 3673 3763 3674 #: Languages/acf-strings.php:19 63764 #: Languages/acf-strings.php:199 3675 3765 msgid "A customer is emailed in the language they booked in, in the wording we ship for that language — add a row only to change it." 3676 3766 msgstr "" 3677 3767 3678 #: Languages/acf-strings.php: 1973768 #: Languages/acf-strings.php:200 3679 3769 msgid "Add a language" 3680 3770 msgstr "" 3681 3771 3682 #: Languages/acf-strings.php: 1983772 #: Languages/acf-strings.php:201 3683 3773 msgid "Language" 3684 3774 msgstr "" 3685 3775 3686 #: Languages/acf-strings.php:20 03776 #: Languages/acf-strings.php:203 3687 3777 msgid "Printed under the products, above the footer. Merge tags work here too." 3688 3778 msgstr "" 3689 3779 3690 #: Languages/acf-strings.php:20 13780 #: Languages/acf-strings.php:204 3691 3781 msgid "BCC admin recipient(s)" 3692 3782 msgstr "" 3693 3783 3694 #: Languages/acf-strings.php:20 23784 #: Languages/acf-strings.php:205 3695 3785 msgid "Comma separated. Leave empty to send only to the customer." 3696 3786 msgstr "" 3697 3787 3698 #: Languages/acf-strings.php:20 43788 #: Languages/acf-strings.php:207 3699 3789 msgid "Which format to send. Multipart sends both and lets the mail client choose." 3700 3790 msgstr "" 3701 3791 3702 #: Languages/acf-strings.php:20 53792 #: Languages/acf-strings.php:208 3703 3793 msgid "Plain text" 3704 3794 msgstr "" 3705 3795 3706 #: Languages/acf-strings.php:20 63796 #: Languages/acf-strings.php:209 3707 3797 msgid "HTML" 3708 3798 msgstr "" 3709 3799 3710 #: Languages/acf-strings.php:2 073800 #: Languages/acf-strings.php:210 3711 3801 msgid "Multipart" 3712 3802 msgstr "" 3713 3803 3714 #: Languages/acf-strings.php:2 083804 #: Languages/acf-strings.php:211 3715 3805 msgid "Calendar Report" 3716 3806 msgstr "" 3717 3807 3718 #: Languages/acf-strings.php:21 23808 #: Languages/acf-strings.php:215 3719 3809 msgid "Calendar Format" 3720 3810 msgstr "" 3721 3811 3722 #: Languages/acf-strings.php:21 33812 #: Languages/acf-strings.php:216 3723 3813 msgid "Start & End Date" 3724 3814 msgstr "" 3725 3815 3726 #: Languages/acf-strings.php:21 43816 #: Languages/acf-strings.php:217 3727 3817 msgid "Start through End Date" 3728 3818 msgstr "" 3729 3819 3730 #: Languages/acf-strings.php:21 53820 #: Languages/acf-strings.php:218 3731 3821 msgid "Start & End Date With Buffer" 3732 3822 msgstr "" 3733 3823 3734 #: Languages/acf-strings.php:21 63824 #: Languages/acf-strings.php:219 3735 3825 msgid "Start through End Date With Buffer" 3736 3826 msgstr "" 3737 3827 3738 #: Languages/acf-strings.php:2 193828 #: Languages/acf-strings.php:222 3739 3829 msgid "Search product name or sku" 3740 3830 msgstr "" … … 3756 3846 msgstr "" 3757 3847 3758 #: Model/AdminAlerts.php:78 3759 msgid "Dismiss" 3760 msgstr "" 3761 3762 #: Model/AdminAlerts.php:85 3763 msgid "Sorry, you are not allowed to do that." 3764 msgstr "" 3765 3766 #: Model/Availability.php:64 3848 #: Model/Availability.php:66 3767 3849 msgid "The start date is too early" 3768 3850 msgstr "" 3769 3851 3770 #: Model/Availability.php:6 73852 #: Model/Availability.php:69 3771 3853 msgid "The start or end date is disabled" 3772 3854 msgstr "" 3773 3855 3774 #: Model/Availability.php:15 23856 #: Model/Availability.php:157 3775 3857 msgid "Choose at least one night: the check-out day must be after the check-in day." 3776 3858 msgstr "" 3777 3859 3778 3860 #. translators: %d: nights 3779 #: Model/Availability.php:1 583861 #: Model/Availability.php:163 3780 3862 #, php-format 3781 3863 msgid "The minimum stay is %d night." … … 3785 3867 3786 3868 #. translators: %d: nights 3787 #: Model/Availability.php:16 23869 #: Model/Availability.php:167 3788 3870 #, php-format 3789 3871 msgid "The maximum stay is %d night." … … 3793 3875 3794 3876 #. translators: 1: number, 2: unit (hours or days) 3795 #: Model/Availability.php:19 33796 #: Model/Availability.php:22 23877 #: Model/Availability.php:198 3878 #: Model/Availability.php:227 3797 3879 #, php-format 3798 3880 msgid "The minimum rental length is %1$s %2$s" … … 3800 3882 3801 3883 #. translators: 1: number, 2: unit (hours or days) 3802 #: Model/Availability.php:20 03803 #: Model/Availability.php:2 293884 #: Model/Availability.php:205 3885 #: Model/Availability.php:234 3804 3886 #, php-format 3805 3887 msgid "The maximum rental length is %1$s %2$s" -
sales-igniter-rentals-bookings-lite/trunk/Model/ACF/group_61d28753aedd5.json
r3728745 r3729359 94 94 "ajax": 0, 95 95 "placeholder": "" 96 },97 {98 "key": "field_68f6a00000001",99 "label": "Stay type",100 "name": "sibooking_stay_type",101 "aria-label": "",102 "type": "select",103 "instructions": "Nights: check-in and check-out, the check-out day can be booked again the same day, and the length is counted in nights. Days: the item comes back on the last day, which stays booked.",104 "required": 0,105 "conditional_logic": [106 [107 {108 "field": "field_61d28a385f491",109 "operator": "==",110 "value": "date"111 }112 ]113 ],114 "wrapper": {115 "width": "",116 "class": "",117 "id": ""118 },119 "choices": {120 "default": "Use the store default",121 "days": "Days (the item comes back on the last day)",122 "nights": "Nights (check-in and check-out)"123 },124 "default_value": "default",125 "return_format": "value",126 "multiple": 0,127 "allow_null": 0,128 "ui": 0,129 "ajax": 0,130 "placeholder": ""131 },132 {133 "key": "field_68f6a00000002",134 "label": "Check-in from",135 "name": "sibooking_check_in_time",136 "aria-label": "",137 "type": "text",138 "instructions": "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for stays of nights.",139 "required": 0,140 "conditional_logic": [141 [142 {143 "field": "field_68f6a00000001",144 "operator": "!=",145 "value": "days"146 }147 ]148 ],149 "wrapper": {150 "width": "",151 "class": "",152 "id": ""153 },154 "default_value": "",155 "maxlength": 40,156 "placeholder": "",157 "prepend": "",158 "append": ""159 },160 {161 "key": "field_68f6a00000003",162 "label": "Check-out by",163 "name": "sibooking_check_out_time",164 "aria-label": "",165 "type": "text",166 "instructions": "Shown to the guest, for example \"11:00 am\". Empty: the store's.",167 "required": 0,168 "conditional_logic": [169 [170 {171 "field": "field_68f6a00000001",172 "operator": "!=",173 "value": "days"174 }175 ]176 ],177 "wrapper": {178 "width": "",179 "class": "",180 "id": ""181 },182 "default_value": "",183 "maxlength": 40,184 "placeholder": "",185 "prepend": "",186 "append": ""187 96 }, 188 97 { … … 271 180 }, 272 181 { 182 "key": "field_68f6a00000033", 183 "label": "Also charge the return day", 184 "name": "sibooking_charge_return_day", 185 "aria-label": "", 186 "type": "select", 187 "instructions": "For rentals booked by the day. No: the 1st to the 3rd is 2 days (the return day is free). Yes: 3 days. Nights are charged per night.", 188 "required": 0, 189 "conditional_logic": [ 190 [ 191 { 192 "field": "field_61d28a385f491", 193 "operator": "==", 194 "value": "date" 195 } 196 ] 197 ], 198 "wrapper": { 199 "width": "", 200 "class": "", 201 "id": "" 202 }, 203 "choices": { 204 "default": "Store setting", 205 "no": "No", 206 "yes": "Yes" 207 }, 208 "default_value": "default", 209 "return_format": "value", 210 "multiple": 0, 211 "allow_null": 0, 212 "ui": 0, 213 "ajax": 0, 214 "placeholder": "" 215 }, 216 { 273 217 "key": "field_68d3c1a0b0010", 274 218 "label": "Headline price", … … 302 246 "aria-label": "", 303 247 "type": "select", 304 "instructions": "The headline reads \"From $145 / night\". Week and month show what a whole week or month costs at your rates ($449 / week). Night and event change only the word: a stay from the 7th to the 10th is 3 nights, charged as 3 days.",248 "instructions": "The headline reads \"From $145 / day\", or \"/ night\" for a product booked by Nights. Week and month show what a whole week or month costs at your rates ($449 / week). Event changes only the word.", 305 249 "required": 0, 306 250 "conditional_logic": [ … … 319 263 }, 320 264 "choices": { 321 "auto": "Automatic: the store's day or night(an hourly-only rate shows per hour)",265 "auto": "Automatic: follows \"Booked by\" (an hourly-only rate shows per hour)", 322 266 "hour": "Hour", 323 "day": "Day",324 "night": "Night",325 267 "week": "Week", 326 268 "month": "Month", … … 641 583 "endpoint": 0, 642 584 "selected": 0 585 }, 586 { 587 "key": "field_68f6a00000001", 588 "label": "Booked by", 589 "name": "sibooking_stay_type", 590 "aria-label": "", 591 "type": "select", 592 "instructions": "Which days a rental with dates (no times) holds. Bookings you already have keep their rule.", 593 "required": 0, 594 "conditional_logic": [ 595 [ 596 { 597 "field": "field_61d28a385f491", 598 "operator": "==", 599 "value": "date" 600 } 601 ] 602 ], 603 "wrapper": { 604 "width": "", 605 "class": "", 606 "id": "" 607 }, 608 "choices": { 609 "default": "Store setting", 610 "days": "Days: returned on the last day, entire return day is booked", 611 "days_free": "Days: can go out again on the return day", 612 "nights": "Nights: same-day check-out and check-in" 613 }, 614 "default_value": "default", 615 "return_format": "value", 616 "multiple": 0, 617 "allow_null": 0, 618 "ui": 0, 619 "ajax": 0, 620 "placeholder": "" 621 }, 622 { 623 "key": "field_68f6a00000002", 624 "label": "Check-in from", 625 "name": "sibooking_check_in_time", 626 "aria-label": "", 627 "type": "text", 628 "instructions": "Shown to the guest, for example \"3:00 pm\". Empty: the store's. Only for products booked by Nights.", 629 "required": 0, 630 "conditional_logic": [ 631 [ 632 { 633 "field": "field_68f6a00000001", 634 "operator": "==", 635 "value": "nights" 636 } 637 ] 638 ], 639 "wrapper": { 640 "width": "", 641 "class": "", 642 "id": "" 643 }, 644 "default_value": "", 645 "maxlength": 40, 646 "placeholder": "", 647 "prepend": "", 648 "append": "" 649 }, 650 { 651 "key": "field_68f6a00000003", 652 "label": "Check-out by", 653 "name": "sibooking_check_out_time", 654 "aria-label": "", 655 "type": "text", 656 "instructions": "Shown to the guest, for example \"11:00 am\". Empty: the store's.", 657 "required": 0, 658 "conditional_logic": [ 659 [ 660 { 661 "field": "field_68f6a00000001", 662 "operator": "==", 663 "value": "nights" 664 } 665 ] 666 ], 667 "wrapper": { 668 "width": "", 669 "class": "", 670 "id": "" 671 }, 672 "default_value": "", 673 "maxlength": 40, 674 "placeholder": "", 675 "prepend": "", 676 "append": "" 643 677 }, 644 678 { … … 1353 1387 "show_in_rest": 0, 1354 1388 "private": true, 1355 "modified": 179 06651951389 "modified": 1791205690 1356 1390 } -
sales-igniter-rentals-bookings-lite/trunk/Model/ACF/group_61d2ba5188b94.json
r3728745 r3729359 4 4 "fields": [ 5 5 { 6 "key": "field_6 1d2bea09d8f6",7 "label": " Calendar",6 "key": "field_68f6a00000031", 7 "label": "Pricing", 8 8 "name": "", 9 9 "aria-label": "", … … 22 22 }, 23 23 { 24 "key": "field_61d2bfd4998a1", 25 "label": "Store Open Time", 26 "name": "sibooking_store_open_time", 27 "aria-label": "", 28 "type": "time_picker", 29 "instructions": "", 30 "required": 0, 31 "conditional_logic": 0, 32 "wrapper": { 33 "width": "", 34 "class": "", 35 "id": "" 36 }, 37 "display_format": "g:i a", 38 "return_format": "H:i:s" 39 }, 40 { 41 "key": "field_61d2bffe998a2", 42 "label": "Store Close Time", 43 "name": "sibooking_store_close_time", 44 "aria-label": "", 45 "type": "time_picker", 46 "instructions": "", 47 "required": 0, 48 "conditional_logic": 0, 49 "wrapper": { 50 "width": "", 51 "class": "", 52 "id": "" 53 }, 54 "display_format": "g:i a", 55 "return_format": "H:i:s" 56 }, 57 { 58 "key": "field_68f6a00000011", 59 "label": "Stay type for date-only products", 60 "name": "sibooking_stay_type_default", 61 "aria-label": "", 62 "type": "select", 63 "instructions": "Nights: check-in and check-out; the check-out day can be booked by the next guest and lengths are counted in nights. Days: the item comes back on the last day. Each product can choose for itself.", 64 "required": 0, 65 "conditional_logic": 0, 66 "wrapper": { 67 "width": "", 68 "class": "", 69 "id": "" 70 }, 71 "choices": { 72 "days": "Days (the item comes back on the last day)", 73 "nights": "Nights (check-in and check-out)" 74 }, 75 "default_value": "days", 76 "return_format": "value", 77 "multiple": 0, 78 "allow_null": 0, 79 "ui": 0, 80 "ajax": 0, 81 "placeholder": "" 82 }, 83 { 84 "key": "field_68f6a00000012", 85 "label": "Check-in from", 86 "name": "sibooking_check_in_time_default", 87 "aria-label": "", 88 "type": "text", 89 "instructions": "Shown to guests of stays of nights, for example \"3:00 pm\". Text only: it does not change availability.", 90 "required": 0, 91 "conditional_logic": 0, 92 "wrapper": { 93 "width": "", 94 "class": "", 95 "id": "" 96 }, 97 "default_value": "", 98 "maxlength": 40, 99 "placeholder": "", 100 "prepend": "", 101 "append": "" 102 }, 103 { 104 "key": "field_68f6a00000013", 105 "label": "Check-out by", 106 "name": "sibooking_check_out_time_default", 107 "aria-label": "", 108 "type": "text", 109 "instructions": "For example \"11:00 am\".", 110 "required": 0, 111 "conditional_logic": 0, 112 "wrapper": { 113 "width": "", 114 "class": "", 115 "id": "" 116 }, 117 "default_value": "", 118 "maxlength": 40, 119 "placeholder": "", 120 "prepend": "", 121 "append": "" 122 }, 123 { 124 "key": "field_68f6a00000014", 125 "label": "Allow rentals to start on the same day as they are returned", 126 "name": "sibooking_start_on_return_day", 24 "key": "field_68f6a00000032", 25 "label": "Also charge the return day", 26 "name": "sibooking_charge_return_day_default", 127 27 "aria-label": "", 128 28 "type": "true_false", 129 "instructions": "For date-only products rented by the day. On: a unit returned on a day can go out again that day, so another rental may start on the return day. Off: the return day stays with the rental that ends on it. Turnover time still applies, and rentals booked before a change keep the days they were booked with. Products rented by the night always free the check-out day; rentals with a time of day are held to the minute.",29 "instructions": "For rentals booked by the day. No: the 1st to the 3rd is 2 days (the return day is free). Yes: 3 days. Nights are charged per night.", 130 30 "required": 0, 131 31 "conditional_logic": 0, … … 140 40 "ui_on_text": "", 141 41 "ui_off_text": "" 42 }, 43 { 44 "key": "field_61d2bea09d8f6", 45 "label": "Calendar", 46 "name": "", 47 "aria-label": "", 48 "type": "accordion", 49 "instructions": "", 50 "required": 0, 51 "conditional_logic": 0, 52 "wrapper": { 53 "width": "", 54 "class": "", 55 "id": "" 56 }, 57 "open": 0, 58 "multi_expand": 1, 59 "endpoint": 0 60 }, 61 { 62 "key": "field_61d2bfd4998a1", 63 "label": "Store Open Time", 64 "name": "sibooking_store_open_time", 65 "aria-label": "", 66 "type": "time_picker", 67 "instructions": "", 68 "required": 0, 69 "conditional_logic": 0, 70 "wrapper": { 71 "width": "", 72 "class": "", 73 "id": "" 74 }, 75 "display_format": "g:i a", 76 "return_format": "H:i:s" 77 }, 78 { 79 "key": "field_61d2bffe998a2", 80 "label": "Store Close Time", 81 "name": "sibooking_store_close_time", 82 "aria-label": "", 83 "type": "time_picker", 84 "instructions": "", 85 "required": 0, 86 "conditional_logic": 0, 87 "wrapper": { 88 "width": "", 89 "class": "", 90 "id": "" 91 }, 92 "display_format": "g:i a", 93 "return_format": "H:i:s" 142 94 }, 143 95 { … … 347 299 } 348 300 ] 301 }, 302 { 303 "key": "field_68f6a00000011", 304 "label": "Date-only rentals are booked by", 305 "name": "sibooking_stay_type_default", 306 "aria-label": "", 307 "type": "select", 308 "instructions": "Which days a rental with dates (no times) holds.", 309 "required": 0, 310 "conditional_logic": 0, 311 "wrapper": { 312 "width": "", 313 "class": "", 314 "id": "" 315 }, 316 "choices": { 317 "days": "Days: returned on the last day, entire return day is booked", 318 "days_free": "Days: can go out again on the return day", 319 "nights": "Nights: same-day check-out and check-in" 320 }, 321 "default_value": "days", 322 "return_format": "value", 323 "multiple": 0, 324 "allow_null": 0, 325 "ui": 0, 326 "ajax": 0, 327 "placeholder": "" 328 }, 329 { 330 "key": "field_68f6a00000012", 331 "label": "Check-in from", 332 "name": "sibooking_check_in_time_default", 333 "aria-label": "", 334 "type": "text", 335 "instructions": "For Nights. Shown to guests, for example \"3:00 pm\". Text only: it does not change availability.", 336 "required": 0, 337 "conditional_logic": [ 338 [ 339 { 340 "field": "field_68f6a00000011", 341 "operator": "==", 342 "value": "nights" 343 } 344 ] 345 ], 346 "wrapper": { 347 "width": "", 348 "class": "", 349 "id": "" 350 }, 351 "default_value": "", 352 "maxlength": 40, 353 "placeholder": "", 354 "prepend": "", 355 "append": "" 356 }, 357 { 358 "key": "field_68f6a00000013", 359 "label": "Check-out by", 360 "name": "sibooking_check_out_time_default", 361 "aria-label": "", 362 "type": "text", 363 "instructions": "For Nights. Shown to guests, for example \"11:00 am\". Text only: it does not change availability.", 364 "required": 0, 365 "conditional_logic": [ 366 [ 367 { 368 "field": "field_68f6a00000011", 369 "operator": "==", 370 "value": "nights" 371 } 372 ] 373 ], 374 "wrapper": { 375 "width": "", 376 "class": "", 377 "id": "" 378 }, 379 "default_value": "", 380 "maxlength": 40, 381 "placeholder": "", 382 "prepend": "", 383 "append": "" 384 }, 385 { 386 "key": "field_68f6a00000014", 387 "label": "Allow rentals to start on the same day as they are returned", 388 "name": "sibooking_start_on_return_day", 389 "aria-label": "", 390 "type": "true_false", 391 "instructions": "For date-only products rented by the day. On: a unit returned on a day can go out again that day, so another rental may start on the return day. Off: the return day stays with the rental that ends on it. Turnover time still applies, and rentals booked before a change keep the days they were booked with. Products rented by the night always free the check-out day; rentals with a time of day are held to the minute.", 392 "required": 0, 393 "conditional_logic": 0, 394 "wrapper": { 395 "width": "", 396 "class": "", 397 "id": "" 398 }, 399 "message": "", 400 "default_value": 0, 401 "ui": 1, 402 "ui_on_text": "", 403 "ui_off_text": "" 349 404 }, 350 405 { … … 1949 2004 "show_in_rest": 0, 1950 2005 "private": true, 1951 "modified": 179 08670002006 "modified": 1791205690 1952 2007 } -
sales-igniter-rentals-bookings-lite/trunk/Model/Availability.php
r3728745 r3729359 43 43 * the whole-cart check counts stock across lines itself) 44 44 * @type bool|null $nightly the rule the line runs under (Model\Stay); default the product's 45 * @type bool|null $returnDayFree whether the line runs under "Days: can go out again on the return 46 * day" (Includes\Order::lineReturnDayFree()); default the product's 45 47 * @type int $stock_id the pool: a variation with its own stock (default the product) 46 48 * @type int[] $exclude_orders orders whose rows do not count (the order being edited...) … … 97 99 public static function available( $productId, $start, $end, array $context = [] ) { 98 100 $stay = array_key_exists( 'nightly', $context ) && null !== $context['nightly'] ? [ 'nightly' => (bool) $context['nightly'] ] : []; 101 if ( array_key_exists( 'returnDayFree', $context ) && null !== $context['returnDayFree'] ) { 102 $stay['returnDayFree'] = (bool) $context['returnDayFree']; 103 } 99 104 [ $from, $to ] = Validation::bufferedWindow( $productId, $start, $end, $context['line'] ?? null, $stay ); 100 105 $stockId = (int) ( $context['stock_id'] ?? 0 ) > 0 ? (int) $context['stock_id'] : (int) $productId; -
sales-igniter-rentals-bookings-lite/trunk/Model/Buffer.php
r3728745 r3729359 9 9 10 10 /** 11 * The store setting "Allow rentals to start on the same day as they are returned" 12 * (true/false, default off; K5): a date-only rental sold by the day then holds its 13 * days up to its return day's 00:00, so another rental may start on the return day. 11 * The old store yes/no "Allow rentals to start on the same day as they are returned" 12 * (K5, 1.0.13 to 1.0.14). Since 1.0.15 it is the middle "Booked by" choice, "Days: can go 13 * out again on the return day" (Model\Stay::DAYS_FREE): a store that had it on was switched 14 * over once (Model\Stay::switchOver()); the option is kept and no longer read. Also the 15 * name of the filter startOnReturnDay() runs. 14 16 */ 15 17 const START_ON_RETURN_DAY = 'sibooking_start_on_return_day'; … … 54 56 * 55 57 * The return day of a date-only rental is held by that rental (it runs to 23:59 of 56 * its last day) unless the store turns this on. A stay of nights frees the check-out 57 * day anyway (Model\Stay), and a rental with a time of day is held to the minute, so 58 * the answer only changes date-only rentals sold by the day. 58 * its last day) unless the product is "Booked by" "Days: can go out again on the return 59 * day" (Model\Stay::DAYS_FREE, its own choice or the store's). A stay of nights frees the 60 * check-out day anyway (Model\Stay), and a rental with a time of day is held to the 61 * minute, so the answer only changes date-only rentals sold by the day. 59 62 * 60 * @param int|null $productId the product whose rental is asked about (a variation's parent) 63 * @param int|null $productId the product whose rental is asked about (a variation's parent); 64 * null: the store's "Date-only rentals are booked by" 61 65 * @return bool 62 66 */ 63 67 public static function startOnReturnDay( $productId = null ) { 68 $rule = $productId ? Stay::rule( (int) $productId ) : Stay::storeRule(); 64 69 /** 65 * Whether a date-only rental's return day is free for another rental to start on. 66 * The value passed in is the store setting "Allow rentals to start on the same day 67 * as they are returned" (default off). Stays of nights and rentals with a time of 68 * day do not ask. 70 * Whether a date-only rental's return day is free for another rental to start on: the 71 * "Booked by" choice "Days: can go out again on the return day". The value passed in 72 * is true when the product's "Booked by" (its own, else the store's "Date-only rentals 73 * are booked by") is that choice. Return true to give a product that rule, false to 74 * hold its return day. Until 1.0.15 the value was the store yes/no "Allow rentals to 75 * start on the same day as they are returned", which is now that choice. Stays of nights 76 * and rentals with a time of day do not ask. 69 77 * 70 78 * @since 1.0.13 … … 73 81 * @param int|null $productId 74 82 */ 75 return (bool) apply_filters( 'sibooking_start_on_return_day', (bool) Config::option( self::START_ON_RETURN_DAY ), $productId ? (int) $productId : null );83 return (bool) apply_filters( 'sibooking_start_on_return_day', Stay::DAYS_FREE === $rule, $productId ? (int) $productId : null ); 76 84 } 77 85 … … 155 163 * on a later day than it starts is held to its end day's 00:00. 156 164 * Without 'start' the end day is held (the safe answer). 165 * 'returnDayFree' (the rule an order line was sold under, 166 * Includes\Order::lineReturnDayFree()) wins over the product's 167 * current "Booked by"; 'parent' (a kit's parent) rules its children. 157 168 */ 158 169 public function calculateBufferAfterEndDate($productid,$endDateTime, array $context = []) { … … 198 209 199 210 /** 200 * Is a date-only rental's return day left free for the next rental? Only with the 201 * store setting on (startOnReturnDay()) and the start known and on an earlier day. 211 * Is a date-only rental's return day left free for the next rental? Only when it is 212 * "Booked by" "Days: can go out again on the return day" (startOnReturnDay(), or the rule 213 * the line was sold under) and the start is known and on an earlier day. 202 214 */ 203 215 private static function returnDayIsFree($productid, Carbon $end, array $context) { … … 213 225 return false; 214 226 } 215 $settingsId = $productid ? PricingSubject::of((int) $productid) : null; 227 if (isset($context['returnDayFree']) && null !== $context['returnDayFree']) { 228 // the rule an order line was sold under (Includes\Order::lineReturnDayFree()) wins 229 return (bool) $context['returnDayFree']; 230 } 231 // a kit's children follow the parent's rule, as for a stay of nights 232 $ruleId = !empty($context['parent']) ? (int) $context['parent'] : (int) $productid; 233 $settingsId = $ruleId ? PricingSubject::of($ruleId) : null; 216 234 return self::startOnReturnDay($settingsId); 217 235 } -
sales-igniter-rentals-bookings-lite/trunk/Model/DataRemoval.php
r3722835 r3729359 5 5 /** 6 6 * "Delete all rental data when the plugin is deleted" (review finding BOOT-05, and 7 * Kevin's answer to §7 Q8: keep everything by default; deleting is a DOUBLE opt-in that7 * The owner's answer to §7 Q8: keep everything by default; deleting is a DOUBLE opt-in that 8 8 * needs the confirmation typed). 9 9 * -
sales-igniter-rentals-bookings-lite/trunk/Model/DisabledDates.php
r3728745 r3729359 130 130 /** 131 131 * A monthly rule: its days of the month, every month. "The 25th to the 3rd" (the end's day 132 * comes before the start's) runs from its start day into the next month ( Kevin's decision,132 * comes before the start's) runs from its start day into the next month (the owner's decision, 133 133 * PRC-02 / the unified spec's R13); each occurrence used to end on the 3rd of its OWN month, 134 134 * before it began. A start on a day the month lacks (the 31st) overflows into the next -
sales-igniter-rentals-bookings-lite/trunk/Model/FieldSlots.php
r3722835 r3729359 40 40 // Rentals > Settings, Calendar section: after the store's opening hours 41 41 'settings.store_hours' => 'field_61d2bffe998a2', 42 // Rentals > Settings, Pricing section (the first): after its last field, "Also charge 43 // the return day" (1.0.15; an add-on's store pricing settings follow it) 44 'settings.pricing' => 'field_68f6a00000032', 42 45 ]; 43 46 -
sales-igniter-rentals-bookings-lite/trunk/Model/Pricing/ConfigFactory.php
r3728745 r3729359 17 17 * price) -> points with add-ons, priced by cheapest cover even when the add-on that registers 18 18 * the type is off (PRC-15: the classic fallback derived a per-day rate from the shortest point); 19 * - guests: a per-person product books seats; whether infants take a seat (store setting). 19 * - guests: a per-person product books seats; whether infants take a seat (store setting); 20 * - "Also charge the return day" (the product's Pricing tab: store setting | no | yes, else the 21 * store's Settings > Pricing yes/no, default no) -> chargeReturnDay: a day window from the 1st 22 * to the 3rd is then 3 days instead of 2. Only day windows read it: a stay of nights is priced 23 * per night (the engine never charges the check-out day) and a timed rental per minute. 20 24 * 21 25 * Add-ons add their own inputs on `sibooking_pricing_config` (the Regular add-on: date rules as … … 33 37 'sibooking_advanced_price', 34 38 'sibooking_guests_mode', 39 self::CHARGE_RETURN_DAY, 35 40 ]; 41 42 /** The product's "Also charge the return day": default (the store's) | no | yes. */ 43 const CHARGE_RETURN_DAY = 'sibooking_charge_return_day'; 44 45 /** The store's "Also charge the return day" (Settings > Pricing, yes/no, default no). */ 46 const CHARGE_RETURN_DAY_DEFAULT = 'sibooking_charge_return_day_default'; 47 48 /** @return bool the store's "Also charge the return day" */ 49 public static function storeChargesReturnDay() { 50 return self::flag( Config::option( self::CHARGE_RETURN_DAY_DEFAULT ) ); 51 } 52 53 /** 54 * Does a rental of this product booked by the day pay for its return day too? The product's 55 * own Yes / No, else the store's. Stays of nights are priced per night whatever this says. 56 * 57 * @param int|string $productId a product or variation (the pricing subject answers) 58 * @return bool 59 */ 60 public static function chargesReturnDay( $productId ) { 61 $id = PricingSubject::of( $productId ); 62 return self::returnDayFlag( $id ? Config::field( self::CHARGE_RETURN_DAY, $id ) : null, self::storeChargesReturnDay() ); 63 } 64 65 /** 66 * Does the length shown to the customer ("3 days") count the return day of a date-only 67 * rental of this product? Only where the engine charges it: unified pricing on (the 68 * deprecated legacy pricing never charges the return day), not a stay of nights. 69 * 70 * @param int|string $productId 71 * @return bool 72 */ 73 public static function countsReturnDay( $productId ) { 74 return Unified::enabled( $productId ) && ! \Sibooking\Model\Stay::nightly( $productId ) && self::chargesReturnDay( $productId ); 75 } 76 77 /** 78 * @param mixed $own the product's choice: 'yes' | 'no' | 'default' / empty (the store's) 79 * @param bool $store the store's answer 80 */ 81 public static function returnDayFlag( $own, $store ) { 82 if ( 'yes' === $own ) { 83 return true; 84 } 85 if ( 'no' === $own ) { 86 return false; 87 } 88 return (bool) $store; 89 } 36 90 37 91 /** … … 53 107 $fields['sibooking_advanced_price'] = PriceTypes::storedPoints( $id ); 54 108 } 55 $config = self::fromFields( $fields, [ 'sibooking_infants_take_seat' => Config::option( 'sibooking_infants_take_seat' ) ] ); 109 $config = self::fromFields( $fields, [ 110 'sibooking_infants_take_seat' => Config::option( 'sibooking_infants_take_seat' ), 111 self::CHARGE_RETURN_DAY_DEFAULT => Config::option( self::CHARGE_RETURN_DAY_DEFAULT ), 112 ] ); 56 113 57 114 /** … … 71 128 /** 72 129 * @param array $p the product's fields (ACF names) 73 * @param array $store store options: sibooking_infants_take_seat 130 * @param array $store store options: sibooking_infants_take_seat, sibooking_charge_return_day_default 74 131 * @return array<string,mixed> 75 132 */ 76 133 public static function fromFields( array $p, array $store = [] ) { 77 134 $c = [ 'rates' => [] ]; 135 if ( self::returnDayFlag( $p[ self::CHARGE_RETURN_DAY ] ?? null, self::flag( $store[ self::CHARGE_RETURN_DAY_DEFAULT ] ?? false ) ) ) { 136 // "Also charge the return day": a day window 1st -> 3rd is 3 days (nights ignore it) 137 $c['chargeReturnDay'] = true; 138 } 78 139 if ( 'advanced' === ( $p['sibooking_price_type'] ?? 'simple' ) ) { 79 140 foreach ( self::rows( $p['sibooking_advanced_price'] ?? [] ) as $r ) { -
sales-igniter-rentals-bookings-lite/trunk/Model/RateLimit.php
r3728745 r3729359 4 4 5 5 /** 6 * One rate limiter for the public shopper calls (review finding SEC-05, Kevin's answer6 * One rate limiter for the public shopper calls (review finding SEC-05, the owner's answer 7 7 * to §7 Q10): the calendar data, the price quote, the global widget, the map data and 8 8 * the "Where" search. They must stay open to visitors -- a shopper sees availability and -
sales-igniter-rentals-bookings-lite/trunk/Model/ResponseCache.php
r3728745 r3729359 4 4 5 5 /** 6 * A short-lived cache for the public shopper calls (review finding SEC-05, Kevin's6 * A short-lived cache for the public shopper calls (review finding SEC-05, the owner's 7 7 * answer to §7 Q10): the same question -- a product's availability, the price of a 8 8 * rental, the map for an area -- answered from storage while nothing it depends on has -
sales-igniter-rentals-bookings-lite/trunk/Model/Services.php
r3728745 r3729359 40 40 'Sibooking\\Ajax\\InventoryReport' => self::ADMIN, 41 41 'Sibooking\\Ajax\\OrderDates' => self::ADMIN, 42 'Sibooking\\Includes\\BookedBy' => self::ADMIN, // "Booked by" / "Also charge the return day" on the screens, the night-wording notice 42 43 'Sibooking\\Includes\\BookingEditAssets' => self::ADMIN, 43 44 'Sibooking\\Includes\\Diagnostics' => self::ADMIN, -
sales-igniter-rentals-bookings-lite/trunk/Model/Stay.php
r3728745 r3729359 12 12 * nights = check-out - check-in, at least 1. No clock times anywhere. 13 13 * 14 * Which products are sold by the night is this plugin's own setting: the product's "Stay 15 * type" (store default | days | nights) and the store's "Stay type for date-only products" 16 * (Includes\Stays registers both; days unless a shop picks nights). `sibooking_nightly` then 17 * lets another plugin adjust the answer. The answer is recorded on each booking row 18 * (`nightly`) when the order is written, so a product switched between the two rules never 19 * changes what was already sold. 14 * Which products are sold by the night is this plugin's own setting, "Booked by" (the owner, 15 * 2026-10-05): the product's own (Calendar Rules tab: store setting | days | days_free | 16 * nights) and the store's "Date-only rentals are booked by" (Settings > Calendar), stored in 17 * the names the older "Stay type" fields used: 18 * 19 * - `days` Days: returned on the last day, entire return day is booked; 20 * - `days_free` Days: can go out again on the return day (Model\Buffer::startOnReturnDay(), 21 * what the store yes/no "Allow rentals to start on the same day as they are 22 * returned" did until 1.0.15; a store that had it on is switched over once, 23 * switchOver()); 24 * - `nights` Nights: same-day check-out and check-in (a stay, this class). 25 * 26 * Includes\Stays registers the fields. `sibooking_nightly` lets another plugin adjust the 27 * Nights answer. The answer is recorded on each booking row (`nightly`) and order line when the 28 * order is written, so a product switched between the rules never changes what was already sold. 20 29 * 21 30 * No init(): InitLoader skips it. … … 23 32 final class Stay { 24 33 25 /** The product's Stay type: default (the store's) | days| nights. */34 /** The product's "Booked by": default (the store's) | days | days_free | nights. */ 26 35 const TYPE = 'sibooking_stay_type'; 27 36 28 /** The store's Stay type for date-only products: days| nights. */37 /** The store's "Date-only rentals are booked by": days | days_free | nights. */ 29 38 const TYPE_DEFAULT = 'sibooking_stay_type_default'; 39 40 /** Days: returned on the last day, entire return day is booked. */ 41 const DAYS = 'days'; 42 43 /** Days: can go out again on the return day. */ 44 const DAYS_FREE = 'days_free'; 45 46 /** Nights: same-day check-out and check-in. */ 47 const NIGHTS = 'nights'; 48 49 /** The three "Booked by" rules, in the order the settings offer them. */ 50 const RULES = [ self::DAYS, self::DAYS_FREE, self::NIGHTS ]; 51 52 /** 53 * Set once the store's old yes/no "Allow rentals to start on the same day as they are 54 * returned" has been carried over into "Booked by" (switchOver()). 55 */ 56 const SWITCHED_OPTION = 'sibooking_booked_by_switched'; 57 58 /** The old store yes/no (kept, no longer read; Model\Buffer::START_ON_RETURN_DAY). */ 59 const OLD_RETURN_DAY_OPTION = 'sibooking_start_on_return_day'; 30 60 31 61 /** … … 73 103 74 104 /** 75 * The shop's setting for a product: its own Stay type,else the store's. A product105 * The shop's setting for a product: booked by Nights, its own "Booked by" else the store's. A product 76 106 * another plugin rules out (`sibooking_product_allows_stay`) is never a stay. 77 107 * … … 81 111 public static function configured( $productId ) { 82 112 $productId = (int) $productId; 83 if ( ! $productId || ! self::allowed( $productId ) ) { 84 return false; 85 } 86 $type = (string) Config::field( self::TYPE, $productId ); 87 if ( 'nights' === $type ) { 88 return true; 89 } 90 if ( 'days' === $type ) { 91 return false; 92 } 93 return 'nights' === (string) Config::option( self::TYPE_DEFAULT ); 113 if ( ! $productId ) { 114 return false; 115 } 116 return self::NIGHTS === self::rule( $productId ); 117 } 118 119 /** 120 * The store's "Date-only rentals are booked by". 121 * 122 * @return string days | days_free | nights (days when nothing valid is stored) 123 */ 124 public static function storeRule() { 125 $rule = (string) Config::option( self::TYPE_DEFAULT ); 126 return in_array( $rule, self::RULES, true ) ? $rule : self::DAYS; 127 } 128 129 /** 130 * A product's "Booked by" as the shop set it: its own choice, else the store's. A product 131 * that may not be a stay (allowed()) is never Nights: it is held by the day. Not filtered: 132 * Model\Stay::nightly() and Model\Buffer::startOnReturnDay() put their filters on top. 133 * 134 * @param int $productId a product or variation (a variation answers for its parent) 135 * @return string days | days_free | nights 136 */ 137 public static function rule( $productId ) { 138 $id = (int) $productId > 0 ? (int) Guests::fieldsId( (int) $productId ) : 0; 139 $own = $id ? (string) Config::field( self::TYPE, $id ) : ''; 140 $rule = in_array( $own, self::RULES, true ) ? $own : self::storeRule(); 141 if ( self::NIGHTS === $rule && $id && ! self::allowed( $id ) ) { 142 return self::DAYS; 143 } 144 return $rule; 145 } 146 147 /** 148 * Once per site: a store that had the old yes/no "Allow rentals to start on the same day 149 * as they are returned" ON while its date-only rentals were booked by the day now has 150 * "Booked by" set to the middle choice, "Days: can go out again on the return day" -- the 151 * same behaviour, now one of the three choices. A store booked by the night keeps Nights 152 * (it already frees the check-out day). The old option is left as it is and no longer read. 153 * 154 * Runs at plugins_loaded (bootstrap.php) and costs one autoloaded option read once done. 155 * 156 * @return bool|null true when the store was switched, false when there was nothing to switch, 157 * null when it had already run 158 */ 159 public static function switchOver() { 160 if ( get_option( self::SWITCHED_OPTION ) ) { 161 return null; 162 } 163 $old = get_option( 'options_' . self::OLD_RETURN_DAY_OPTION, null ); 164 $on = in_array( $old, [ 1, '1', true, 'yes' ], true ); 165 $current = get_option( 'options_' . self::TYPE_DEFAULT, null ); 166 $days = null === $current || '' === $current || false === $current || self::DAYS === $current; 167 $switch = $on && $days; 168 if ( $switch ) { 169 update_option( 'options_' . self::TYPE_DEFAULT, self::DAYS_FREE ); 170 update_option( '_options_' . self::TYPE_DEFAULT, \Sibooking\Includes\Stays::KEY_TYPE_DEFAULT ); 171 } 172 update_option( self::SWITCHED_OPTION, [ 173 'time' => time(), 174 'version' => defined( 'SIBOOKING_VERSION' ) ? SIBOOKING_VERSION : '', 175 'switched' => $switch, 176 ], true ); 177 return $switch; 94 178 } 95 179 … … 119 203 */ 120 204 public static function storeUsesNights() { 121 if ( 'nights' === (string) Config::option( self::TYPE_DEFAULT) ) {205 if ( self::NIGHTS === self::storeRule() ) { 122 206 return true; 123 207 } -
sales-igniter-rentals-bookings-lite/trunk/bootstrap.php
r3728890 r3729359 23 23 */ 24 24 define( 'SIBOOKING_URL', plugin_dir_url( __FILE__ ) ); 25 define( 'SIBOOKING_VERSION', '1.0.1 4' );25 define( 'SIBOOKING_VERSION', '1.0.15' ); 26 26 /** 27 27 * The add-on contract's version (Sibooking\Api, review ARCH-01). Raised only when a method … … 145 145 } 146 146 new \Sibooking\Model\InitLoader( $sibookinglite_libraries ); 147 // once per site (1.0.15): the old yes/no "Allow rentals to start on the same day as they are 148 // returned" becomes the "Booked by" choice "Days: can go out again on the return day" 149 \Sibooking\Model\Stay::switchOver(); 147 150 // table upgrades: here on an admin page / WP-Cron / WP-CLI, queued to the background 148 151 // run otherwise (Model\Schema, review BOOT-03), which does them before its steps -
sales-igniter-rentals-bookings-lite/trunk/composer.json
r3728890 r3729359 9 9 "spatie/icalendar-generator": "^2.5" 10 10 }, 11 "version": "1.0.1 4",11 "version": "1.0.15", 12 12 "autoload": { 13 13 "psr-4": { -
sales-igniter-rentals-bookings-lite/trunk/readme.txt
r3728890 r3729359 5 5 Tested up to: 7.1 6 6 Requires PHP: 8.1 7 Stable tag: 1.0.1 47 Stable tag: 1.0.15 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 179 179 == Changelog == 180 180 181 = 1.0.1 4=182 * Fixed: variable, composite and bundle rentals: the booking calendar loads again on sites with script debugging off (1.0.13). [Full changelog](https://rentalbookingsoftware.com/docs/lite-changelog/)181 = 1.0.15 = 182 * "Booked by" (days with the return day booked, days that can go out again on the return day, or nights; for the store and per product) and "Also charge the return day"; the unified pricing engine (some rental prices change; Settings > Advanced has a legacy pricing switch), one date picker for grouped rentals, Shop Managers can run rentals, faster product pages, and calendar, cart and order-editor fixes. [Full changelog](https://rentalbookingsoftware.com/docs/lite-changelog/) 183 183 184 184 == Upgrade Notice == -
sales-igniter-rentals-bookings-lite/trunk/sales-igniter-rentals-bookings-lite.php
r3728890 r3729359 10 10 * Plugin URI: https://rentalbookingsoftware.com/free-woocommerce-rental-booking-plugin/ 11 11 * Description: Rent out products by date or by date and time from your WooCommerce store: availability calendar, quantity-based inventory, daily and hourly pricing, store rules and a bookings admin. 12 * Version: 1.0.1 412 * Version: 1.0.15 13 13 * Author: Sales Igniter 14 14 * Author URI: https://rentalbookingsoftware.com -
sales-igniter-rentals-bookings-lite/trunk/vendor/composer/autoload_classmap.php
r3728745 r3729359 8 8 return array( 9 9 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 10 'Sibooking\\ActivateDeactivate' => $baseDir . '/ActivateDeactivate.php', 10 11 'Sibooking\\Admin\\AddOrderColumns' => $baseDir . '/Admin/AddOrderColumns.php', 11 12 'Sibooking\\Admin\\AdminMenu' => $baseDir . '/Admin/AdminMenu.php', … … 26 27 'Sibooking\\Ajax\\OrderDates' => $baseDir . '/Ajax/OrderDates.php', 27 28 'Sibooking\\Ajax\\Price' => $baseDir . '/Ajax/Price.php', 29 'Sibooking\\Api' => $baseDir . '/Api.php', 28 30 'Sibooking\\Includes\\AcfTooltips' => $baseDir . '/Includes/AcfTooltips.php', 29 31 'Sibooking\\Includes\\AcfTranslations' => $baseDir . '/Includes/AcfTranslations.php', … … 32 34 'Sibooking\\Includes\\AdminUi' => $baseDir . '/Includes/AdminUi.php', 33 35 'Sibooking\\Includes\\BidiText' => $baseDir . '/Includes/BidiText.php', 36 'Sibooking\\Includes\\BookedBy' => $baseDir . '/Includes/BookedBy.php', 34 37 'Sibooking\\Includes\\BookingEditAssets' => $baseDir . '/Includes/BookingEditAssets.php', 35 38 'Sibooking\\Includes\\Calendar' => $baseDir . '/Includes/Calendar.php', -
sales-igniter-rentals-bookings-lite/trunk/vendor/composer/autoload_static.php
r3728745 r3729359 23 23 public static $classMap = array ( 24 24 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 25 'Sibooking\\ActivateDeactivate' => __DIR__ . '/../..' . '/ActivateDeactivate.php', 25 26 'Sibooking\\Admin\\AddOrderColumns' => __DIR__ . '/../..' . '/Admin/AddOrderColumns.php', 26 27 'Sibooking\\Admin\\AdminMenu' => __DIR__ . '/../..' . '/Admin/AdminMenu.php', … … 41 42 'Sibooking\\Ajax\\OrderDates' => __DIR__ . '/../..' . '/Ajax/OrderDates.php', 42 43 'Sibooking\\Ajax\\Price' => __DIR__ . '/../..' . '/Ajax/Price.php', 44 'Sibooking\\Api' => __DIR__ . '/../..' . '/Api.php', 43 45 'Sibooking\\Includes\\AcfTooltips' => __DIR__ . '/../..' . '/Includes/AcfTooltips.php', 44 46 'Sibooking\\Includes\\AcfTranslations' => __DIR__ . '/../..' . '/Includes/AcfTranslations.php', … … 47 49 'Sibooking\\Includes\\AdminUi' => __DIR__ . '/../..' . '/Includes/AdminUi.php', 48 50 'Sibooking\\Includes\\BidiText' => __DIR__ . '/../..' . '/Includes/BidiText.php', 51 'Sibooking\\Includes\\BookedBy' => __DIR__ . '/../..' . '/Includes/BookedBy.php', 49 52 'Sibooking\\Includes\\BookingEditAssets' => __DIR__ . '/../..' . '/Includes/BookingEditAssets.php', 50 53 'Sibooking\\Includes\\Calendar' => __DIR__ . '/../..' . '/Includes/Calendar.php',
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)