steveosoule
11/12/2016 - 2:01 AM

Miva - Shipping Delivery Estimation

Miva - Shipping Delivery Estimation

<mvt:comment>
	| ------------------------------------------------
	| How to use this ReadyTheme - Content Section:
	| ------------------------------------------------
	| If we're on the OSEL page, we want to modify the l.settings:shippingmethods items with all of the estimation variables
	| 	- Just add this item before the regular shippingmethods loop on OSEL. Then in the OSEL loop, use the
	| If we're on any other page (mainly the PROD), then we want to create some dummy l.settings:shippingmethods info that we can use to show the message that looks like this:
	| 	"Want it Tuesday, August 16?
	| 	Order within 4 hours 59 minutes and choose Overnight at checkout."
	| This allows us to use the same ReadyTheme Content Section shipping logic on the PROD page and OSEL page.
</mvt:comment>

<mvt:comment>
	| Account for Daylight Savings time
</mvt:comment>
	<mvt:if expr="s.tm_isdst">
		<mvt:assign name="g.Timezone_Offset" value="'-5'" />
		<mvt:assign name="g.Timezone_Abbreviation" value="'CDT'" />
	<mvt:else>
		<mvt:assign name="g.Timezone_Offset" value="'-6'" />
		<mvt:assign name="g.Timezone_Abbreviation" value="'CST'" />
	</mvt:if>

<mvt:comment>
	| Assign a Days-of-the-week text array for later
</mvt:comment>

	<mvt:assign name="g.delivery_estimator:days_of_week" value="miva_array_deserialize('Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday')" />
	<mvt:assign name="g.delivery_estimator:months_of_year" value="miva_array_deserialize('January,February,March,April,May,June,July,August,September,October,November,December')" />

<mvt:comment>
	| Assign some date-time variables that make it easier to read, write, and compare dates when we apply the estimation logic
</mvt:comment>

	<mvt:assign name="g.delivery_estimator:todays_date:year" value="time_t_year( s.dyn_time_t, g.Timezone_Offset )" />
	<mvt:assign name="g.delivery_estimator:todays_date:month" value="padl(time_t_month( s.time_t, g.Timezone_Offset ), 2, 0)" />
	<mvt:assign name="g.delivery_estimator:todays_date:month_formatted" value="g.delivery_estimator:months_of_year[g.delivery_estimator:todays_date:month]" />
	<mvt:assign name="g.delivery_estimator:todays_date:day" value="padl(time_t_dayofmonth( s.time_t, g.Timezone_Offset ), 2, 0)" />
	<mvt:assign name="g.delivery_estimator:todays_date:dayofweek" value="time_t_dayofweek( s.time_t, g.Timezone_Offset )" />
	<mvt:assign name="g.delivery_estimator:todays_date:dayofweek_formatted" value="g.delivery_estimator:days_of_week[g.delivery_estimator:todays_date:dayofweek]" />
	<mvt:assign name="g.delivery_estimator:todays_date:hour" value="padl(time_t_hour( s.time_t, g.Timezone_Offset ), 2, 0)" />
	<mvt:assign name="g.delivery_estimator:todays_date:min" value="padl(time_t_min( s.time_t, g.Timezone_Offset ), 2, 0)" />
	<mvt:assign name="g.delivery_estimator:todays_date:sec" value="padl(time_t_sec( s.time_t, g.Timezone_Offset ), 2, 0)" />
	<mvt:assign name="g.delivery_estimator:todays_date:formatted" value="g.delivery_estimator:todays_date:year $ '-' $ g.delivery_estimator:todays_date:month $ '-' $ g.delivery_estimator:todays_date:day $ ' ' $ g.delivery_estimator:todays_date:hour $ ':' $ g.delivery_estimator:todays_date:min $ ':' $ g.delivery_estimator:todays_date:sec $ ' ' $ g.Timezone_Offset" />

<mvt:comment>
	| Let's calculate the remaining time before the 9am CT shipping cut-off
</mvt:comment>
<mvt:assign name="g.delivery_estimator:cutoff:hour" value="10" />
<mvt:assign name="g.delivery_estimator:cutoff:remaining:hours" value="g.delivery_estimator:cutoff:hour - g.delivery_estimator:todays_date:hour" />
<mvt:assign name="g.delivery_estimator:cutoff:remaining:minutes" value="60 - g.delivery_estimator:todays_date:min" />
<mvt:if expr="g.delivery_estimator:cutoff:remaining:minutes EQ 60">
	<mvt:assign name="g.delivery_estimator:cutoff:remaining:hours" value="g.delivery_estimator:cutoff:remaining:hours + 1" />
	<mvt:assign name="g.delivery_estimator:cutoff:remaining:minutes" value="0" />
</mvt:if>

<mvt:if expr="g.delivery_estimator:cutoff:remaining:hours GT 0">
	<mvt:if expr="g.delivery_estimator:cutoff:remaining:hours GT 1">
		<mvt:assign name="g.delivery_estimator:cutoff:remaining:hour_unit" value="'hours'" />
	<mvt:else>
		<mvt:assign name="g.delivery_estimator:cutoff:remaining:hour_unit" value="'hour'" />
	</mvt:if>

	<mvt:assign name="g.delivery_estimator:cutoff:remaining:hour_descrip" value="g.delivery_estimator:cutoff:remaining:hours $ ' ' $ g.delivery_estimator:cutoff:remaining:hour_unit" />
</mvt:if>

<mvt:if expr="g.delivery_estimator:cutoff:remaining:minutes GT 0">
	<mvt:if expr="g.delivery_estimator:cutoff:remaining:minutes GT 1">
		<mvt:assign name="g.delivery_estimator:cutoff:remaining:minute_unit" value="'minutes'" />
	<mvt:else>
		<mvt:assign name="g.delivery_estimator:cutoff:remaining:minute_unit" value="'minute'" />
	</mvt:if>

	<mvt:assign name="g.delivery_estimator:cutoff:remaining:minute_descrip" value="g.delivery_estimator:cutoff:remaining:minutes $ ' ' $ g.delivery_estimator:cutoff:remaining:minute_unit" />
</mvt:if>

<mvt:assign name="g.delivery_estimator:cutoff:still_has_time_today" value="(g.delivery_estimator:cutoff:remaining:hours EQ 0 AND g.delivery_estimator:cutoff:remaining:minutes GT 0) OR g.delivery_estimator:cutoff:remaining:hours GT 0" />


<mvt:comment>
	| Global Delivery Estimator Settings ABOVE
	| -------------------------
	| Local l.settings:shippingmethods Settings BELOW
</mvt:comment>

<mvt:comment>
	| Shipping Methods
</mvt:comment>
	<mvt:if expr="ISNULL l.settings:shippingmethods AND l.settings:page:code NE 'OSEL'">
		<mvt:assign name="l.settings:shippingmethods[1]:name" value="'Overnight'" />
		<mvt:assign name="l.settings:shippingmethods[1]:estimate:delivery_days" value="1" />
	</mvt:if>

<mvt:foreach iterator="shippingmethod" array="shippingmethods">

	<mvt:if expr="l.settings:shippingmethod:name EQ 'Economy'">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery_days" value="3" />
	<mvt:elseif expr="l.settings:shippingmethod:name EQ '2 Day Air'">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery_days" value="2" />
	<mvt:elseif expr="l.settings:shippingmethod:name EQ 'Overnight' OR 1 EQ 1">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery_days" value="1" />
	</mvt:if>

	<mvt:if expr="g.delivery_estimator:todays_date:dayofweek_formatted EQ 'Friday'">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="3" />
	<mvt:elseif expr="g.delivery_estimator:todays_date:dayofweek_formatted EQ 'Saturday'">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="2" />
	<mvt:elseif expr="g.delivery_estimator:todays_date:dayofweek_formatted EQ 'Sunday'">
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="1" />
	<mvt:else>
		<mvt:comment>
			| If it is after 10am CT, then we know the shipment will not be sent out today, so lets add an extra day to the elapsed_days
		</mvt:comment>
		<mvt:if expr="g.delivery_estimator:todays_date:hour GE 10">
			<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="1" />
		<mvt:else>
			<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="0" />
		</mvt:if>

	</mvt:if>


	<mvt:comment>
		| Let's initialized the elapsed_days as the time it takes to deliver the current shipping method.
		| We know that this is the soonest it could be delivered to a person
	</mvt:comment>
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="l.settings:shippingmethod:delivery_estimator:elapsed_days + l.settings:shippingmethod:delivery_estimator:delivery_days" />


	<mvt:comment>
		| Now we should have a possible shipping delivery date IF carriers made deliveries on Sat/Sun...
		| But they don't, so we'll account for that in the next step.
	</mvt:comment>
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_seconds" value="l.settings:shippingmethod:delivery_estimator:elapsed_days * 60*60*24" />
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp" value="s.time_t + l.settings:shippingmethod:delivery_estimator:elapsed_seconds" />
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek" value="time_t_dayofweek( l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp, g.Timezone_Offset )" />
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted" value="g.delivery_estimator:days_of_week[l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek]" />

	<mvt:comment>
		| Shipping-cariers don't make deliveries on Saturdays or Sundays,
		| So when the estimated delivery is a Sat/Sun, we need to re-estimate deliveries starting as being shipping from the following Monday
	</mvt:comment>
	<mvt:if expr="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted CIN 'Saturday, Sunday'">

		<mvt:if expr="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted CIN 'Saturday'">
			<mvt:assign name="l.settings:shippingmethod:delivery_estimator:weekend_adjustment" value="2" />
		<mvt:elseif expr="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted CIN 'Sunday'">
			<mvt:assign name="l.settings:shippingmethod:delivery_estimator:weekend_adjustment" value="1" />
		</mvt:if>

		<mvt:comment>
			| Let's elapse elapsed_days to Monday...
		</mvt:comment>
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="l.settings:shippingmethod:delivery_estimator:elapsed_days + l.settings:shippingmethod:delivery_estimator:weekend_adjustment" />

		<mvt:comment>
			| ...and simulate the delivery for the shipment being sent on a Monday
		</mvt:comment>
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_days" value="l.settings:shippingmethod:delivery_estimator:elapsed_days + l.settings:shippingmethod:delivery_estimator:delivery_days" />

		<mvt:comment>
			| Now we have accounted for the weekend properly, and we can over-write the previously set l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek
		</mvt:comment>
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:elapsed_seconds" value="l.settings:shippingmethod:delivery_estimator:elapsed_days * 60*60*24" />
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp" value="s.time_t + l.settings:shippingmethod:delivery_estimator:elapsed_seconds" />
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek" value="time_t_dayofweek( l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp, g.Timezone_Offset )" />
		<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted" value="g.delivery_estimator:days_of_week[l.settings:shippingmethod:delivery_estimator:delivery:date:dayofweek]" />
	</mvt:if>

	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:month" value="time_t_month( l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp, g.Timezone_Offset )" />
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:month_formatted" value="g.delivery_estimator:months_of_year[l.settings:shippingmethod:delivery_estimator:delivery:date:month]" />
	<mvt:assign name="l.settings:shippingmethod:delivery_estimator:delivery:date:day" value="time_t_dayofmonth( l.settings:shippingmethod:delivery_estimator:delivery:date:timestamp, g.Timezone_Offset )" />

	<mvt:assign name="g.delivery_estimator:shippingmethod" value="l.settings:shippingmethod" />

</mvt:foreach>
<mvt:item name="readytheme" param="contentsection( 'delivery_estimator' )" />

<mvt:if expr="g.delivery_estimator:cutoff:still_has_time_today">
	<mvt:comment>
		| It is before 10 am CT, let's show them a countdown
	</mvt:comment>
	<h4>
		<span data-icon="&#xe01c;" class="orange ships-today-icon"></span>
		Want it &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted;, &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:month_formatted; &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:day;?
	</h4>
	<p>Order within <mvt:if expr="g.delivery_estimator:cutoff:remaining:hour_descrip"><b>&mvte:global:delivery_estimator:cutoff:remaining:hour_descrip;</b> </mvt:if><mvt:if expr="g.delivery_estimator:cutoff:remaining:minute_descrip"><b>&mvte:global:delivery_estimator:cutoff:remaining:minute_descrip;</b> </mvt:if> and choose <b>&mvt:global:delivery_estimator:shippingmethod:name;</b> at checkout.</p>
<mvt:else>
	<mvt:comment>
		| It is after 10 am CT, let's just prompt them to order today without a countdown
	</mvt:comment>
	<h4>
		<span data-icon="&#xe01c;" class="orange ships-today-icon"></span>
		Want it &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:dayofweek_formatted;, &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:month_formatted; &mvt:global:delivery_estimator:shippingmethod:delivery_estimator:delivery:date:day;?
	</h4>
	<p>Order today and choose <b>&mvt:global:delivery_estimator:shippingmethod:name;</b> at checkout.</p>
</mvt:if>
<mvt:item name="readytheme" param="contentsection( 'delivery_estimator' )" />
<p>Choose a delivery option:</p>
<mvt:foreach array="shippingmethods" iterator="method">
	<div class="form-row">
		<mvt:if expr="g.ShippingMethod EQ l.settings:method:module $ ':' $ l.settings:method:code OR (ISNULL g.ShippingMethod AND POS1 EQ 1)">
			<mvt:assign name="l.settings:method:checked" value="'checked'" />
		<mvt:else>
			<mvt:assign name="l.settings:method:checked" value="''" />
		</mvt:if>

		<span class="column whole">
			<label>
				<div class="h4 nm">
					<input type="radio" name="ShippingMethod" value="&mvte:method:module;:&mvte:method:code;" &mvt:method:checked; />
					<span class="js-method-delivery-estimation">
						&mvt:method:delivery_estimator:delivery:date:dayofweek_formatted;, &mvt:method:delivery_estimator:delivery:date:month_formatted; &mvt:method:delivery_estimator:delivery:date:day;
					</span>
				</div>
				&emsp;&mvt:method:name; Shipping<mvt:if expr="NOT ISNULL l.settings:method:price"> - <b>&mvt:method:formatted_price;</b></mvt:if>
			</label>
		</span>
	</div>
</mvt:foreach>