Расчет ставки аренды автомобиля

Попытка расчета бронирования и аренды автомобиля.

  • Календарь должен отключить уже забронированную дату (Готово - используется 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


Форма бронирования и расчет

fig2


Образцы расчетного уравнения

Рис3


Рабочая скрипка


заранее спасибо

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);              
}

объяснение

В этой задаче есть два типа ставок:

  1. Продолжительность курса (ежемесячно, еженедельно и ежедневно)
  2. Специальные цены (выходные)

Чтобы рассчитать коэффициенты продолжительности, вы работаете от самого большого интервала до наименьшего интервала, определяя, сколько из каждого интервала будет "соответствовать" за период времени. Например, за 9 дней вы можете уместить 0 целых месяцев, 1 целую неделю и 2 целых дня.

Сложность проблемы возникает, если учесть ставку на выходные. Вы должны знать соответствующие дни, чтобы иметь возможность определить, целесообразно ли назначать ставку выходного дня или суточную ставку.

Чтобы решить эту проблему, вы можете рассчитать оставшиеся дни после месячных и еженедельных ставок, а, поскольку это меньше недели, и javascripts Date.getDay() Функция работает около понедельника, вы можете проверить, больше ли "день" отслеживаемой даты, чем "день" конечной даты (это означает, что она должна была бы зацикливаться, указывая выходные дни)

Другие вопросы по тегам