Расчет ставки аренды автомобиля
Попытка расчета бронирования и аренды автомобиля.
- Календарь должен отключить уже забронированную дату (Готово - используется DatePicker перед ShowDay:)
- В выходные дни пятницу и понедельник следует выбрать для сбора и возврата (готово -)
Теперь идет расчет (выпуск) Тарифы основаны на рис. Из Fig1 я извлек несколько сценариев Fig3 для программирования.
Арендная плата рассчитывается на основе даты начала и окончания.
Если пользователь выбирает
Mon-Fri follows Weekday rate
Fri-Mon follows Weekend Rate
Mon-Mon/Tue-Tue/Wed-Wed/Thu-Thu/Fri-Fri follows weekly rate
1st of a month and 1st of second month follows monthly package
Если пользователь выбирает
Any day to another day of a far week, the rates should mix the packages based on the date's selected
проблема
Я делал расчеты JavaScript и застрял в последнем пункте выше.
Переполнение стека
Найдено несколько сценариев, но не приведенных выше, некоторые представляют собой простой прямой расчет от даты начала до даты окончания.
HTML-Javascript и мои попытки
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Vehicle Rental Booking Calculation</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://jqueryui.com/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<style type="text/css">
td.red span.ui-state-default {
color: #f00;
font-weight:normal;
}
td.green span.ui-state-default {
color: #0f0;
}
</style>
<script type="text/javascript">
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
$(function() {
var array = ["2016-07-26","2016-08-17","2016-08-18","2016-08-19","2016-08-20","2016-08-30","2016-08-31","2016-09-01","2016-09-02","2016-09-15","2016-09-16","2016-09-17","2016-09-20","2016-09-21","2016-09-22","2016-10-05","2016-10-06","2016-10-07","2016-10-12","2016-10-13","2016-10-14","2016-11-17","2016-11-18","2016-11-19","2016-11-20","2016-11-21","2016-11-22"];
$(".datepicker").datepicker({
showOtherMonths: false,
selectOtherMonths: true,
dateFormat : "dd-mm-yy",
minDate: 0,
maxDate: "+12M +10D",
beforeShowDay: function(date){
var string = jQuery.datepicker.formatDate('yy-mm-dd', date);
//alert(date+" "+array.indexOf(string));
var day = date.getDay();
if (array.indexOf(string) != -1)
{
return [ array.indexOf(string) == -1, 'holiday red', jQuery.datepicker.formatDate('dd-mm-yy', date) + ' is booked' ];
}
else
{
if (day == 0 || day == 6)
return [array.indexOf(string) == -1, '', 'For the Saturday or Sunday selection, the start date (Collection) should be before Saturday and end date (Return) should be after Sunday.\n\nFor weekend package: \nWeekend is from Fri to Mon [Total 2 days], Collection is on Friday and Return is on Monday.'];
else
return [ array.indexOf(string) == -1 ];
}
},
onSelect: function(dateText, inst) {
$(this).data('datepicker').inline = false;
var obj_id = $(this).attr("id");
if (obj_id == "start_date" || obj_id == "end_date")
{
// Weekend select STARTS
var pattern = /(\d{2})\-(\d{2})\-(\d{4})/;
var dt = new Date(dateText.replace(pattern,"$3-$2-$1"));
var day = dt.getDay();
if (day == 0 || day == 6)
{
alert("For the Saturday or Sunday selection, the start date (Collection) should be before Saturday and end date (Return) should be after Sunday.\n\nFor weekend package: \nWeekend is from Fri to Mon [Total 2 days], Collection is on Friday and Return is on Monday.");
$(this).val("");
$(this).data('datepicker').inline = true;
}
// Weekend select ENDS
// Calculation STARTS
var calc_flag = 1;
var start_date = $("#start_date").val();
var end_date = $("#end_date").val();
if (start_date == "" || end_date == "")
calc_flag = 0;
// Get the vehicle rates
var hid_daily_rate = $("#hid_daily_rate").val();
var hid_weekend_rate = $("#hid_weekend_rate").val();
var hid_weekly_rate = $("#hid_weekly_rate").val();
var hid_monthly_rate = $("#hid_monthly_rate").val();
var rental_fee = 0;
// Testing STARTS
if (calc_flag)
{
// get the start and end date
var dateStart = $("#start_date").datepicker("getDate");
var dateEnd = $("#end_date").datepicker("getDate");
var totalmonths = monthDiff(dateStart, dateEnd);
var totalmonths1 = dateEnd.getMonth() - dateStart.getMonth() + (12 * (dateEnd.getFullYear() - dateStart.getFullYear()));
var totalDays = (dateEnd - dateStart) / 24 / 60 / 60 / 1000; //get total days
console.log(dateStart+"\n"+dateEnd+"\ntotalmonths="+totalmonths+","+totalmonths1+" totalDays="+totalDays);
}
// Testing ENDS
if (calc_flag)
{
var a = $("#start_date").datepicker("getDate").getTime(),
b = $("#end_date").datepicker("getDate").getTime(),
c = 24*60*60*1000,
diffDays = Math.round(Math.abs((a - b)/(c)));
//console.log(diffDays); //show difference
//alert(diffDays);
rental_fee = hid_daily_rate*diffDays;
$("#rental_fee").html('$'+rental_fee);
}
// Calculation ENDS
}
}
});
});
</script>
</head>
<div class="container">
<div class="col-lg-12 col-xs-offset-1"><h2 style="text-decoration:underline;">Booking Form</h2></div>
<div class="col-lg-12 col-xs-offset-1">
<div class="alert-info" style="width:600px;">
<ul>
<li>Daily Rate (Mon to Fri) <span>: <strong>$75</strong></span> <br/>- Weekday (Mon - Fri), Min 2days is required</li>
<li>Weekend Rate <span>: <strong>$290</strong></span> <br/> - Weekend Package (Fri - Mon)</li>
<li>Weekly Rate <span>: <strong>$490</strong></span> <br/> - Weekly Package</li>
<li>Monthly Rate <span>: <strong>$1860</strong></span> <br/> - Monthly Package</li>
</ul>
</div>
</div>
<form role="form" class="form-horizontal" method="POST" action="booking_action.php" id="frmBookingFormAction" name="frmBookingFormAction">
<input type="hidden" value="17" name="vehicle_id" id="vehicle_id">
<input type="hidden" id="hid_daily_rate" name="hid_daily_rate" value="75" />
<input type="hidden" id="hid_weekend_rate" name="hid_weekend_rate" value="290" />
<input type="hidden" id="hid_weekly_rate" name="hid_weekly_rate" value="490" />
<input type="hidden" id="hid_monthly_rate" name="hid_monthly_rate" value="1860" />
<div class="form-group">
<label for="start_date" class="control-label col-sm-3">Start Date <label class="clr_error">*</label></label>
<div class="col-sm-5">
<input type="text" autocomplete="off" placeholder="dd-mm-yy" value="" name="start_date" id="start_date" class="form-control datepicker">
</div>
</div>
<div class="form-group">
<label for="end_date" class="control-label col-sm-3">End Date <label class="clr_error">*</label></label>
<div class="col-sm-5">
<input type="text" autocomplete="off" placeholder="dd-mm-yy" value="" name="end_date" id="end_date" class="form-control datepicker">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3" for="collection_time">Collection and Return Time </label>
<div class="col-sm-5">
<select id="collection_time" name="collection_time" class="form-control">
<option value="0">[Select]</option>
<option value="10:00">10:00 am</option>
<option value="11:00">11:00 am</option>
<option value="12:00">12:00 pm</option>
<option value="13:00">1:00 pm</option>
<option value="14:00">2:00 pm</option>
<option value="15:00">3:00 pm</option>
<option value="16:00">4:00 pm</option>
<option value="17:00">5:00 pm</option>
<option value="18:00">6:00 pm</option>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">Rental Fee</label>
<div class="col-sm-5">
<p class="form-control-static"><strong>: <span id="rental_fee">$00.00</span></strong></p>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-8">
<input type="button" class="btn btn-primary" value="Continue" name="btnSubmit" id="btnSubmit">
</div>
</div>
</form>
</div>
СКРИНШОТЫ
Авг-сентябрь Календарь тестирования и ставок аренды
Форма бронирования и расчет
Образцы расчетного уравнения
заранее спасибо
1 ответ
JSFiddle
Соответствующий код
if (calc_flag) {
// get the start and end date
var dateStart = $("#start_date").datepicker("getDate");
var dateEnd = $("#end_date").datepicker("getDate");
// Add months to the rental fee, and move the date forward
var months = monthDiff(dateStart, dateEnd);
var currDate = addMonths(dateStart, months);
rates.monthly = months;
// Add weeks to the rental fee, and move the date forward
var days = (dateEnd - dateStart) / 24 / 60 / 60 / 1000;
var weeks = Math.floor(days / 7);
currDate.setTime(currDate.getTime() + weeks * 7 * 24 * 60 * 60 * 1000);
rates.weekly = weeks;
// Calculate the daily rate, noting conflict with
// weekend rate
var dDays = dateEnd.getDay() - currDate.getDay();
if (dDays < 0) dDays += 7;
rates.daily += dDays;
// If it loops around, readjust for weekend rate
if (currDate.getDay() > dateEnd.getDay()) {
rates.daily -= 3;
rates.weekend += 1;
}
console.log(rates);
rental_fee = rates.monthly * hid_monthly_rate +
rates.weekly * hid_weekly_rate +
rates.weekend * hid_weekend_rate +
rates.daily * hid_daily_rate;
// Update the interface
$("#rental_fee").html('$'+rental_fee);
}
объяснение
В этой задаче есть два типа ставок:
- Продолжительность курса (ежемесячно, еженедельно и ежедневно)
- Специальные цены (выходные)
Чтобы рассчитать коэффициенты продолжительности, вы работаете от самого большого интервала до наименьшего интервала, определяя, сколько из каждого интервала будет "соответствовать" за период времени. Например, за 9 дней вы можете уместить 0 целых месяцев, 1 целую неделю и 2 целых дня.
Сложность проблемы возникает, если учесть ставку на выходные. Вы должны знать соответствующие дни, чтобы иметь возможность определить, целесообразно ли назначать ставку выходного дня или суточную ставку.
Чтобы решить эту проблему, вы можете рассчитать оставшиеся дни после месячных и еженедельных ставок, а, поскольку это меньше недели, и javascripts Date.getDay()
Функция работает около понедельника, вы можете проверить, больше ли "день" отслеживаемой даты, чем "день" конечной даты (это означает, что она должна была бы зацикливаться, указывая выходные дни)