Тариф, учитывающий время проезда по маршруту и километраж
В тарифе существуют параметры, которые позволяют учитывать не только километраж маршрута, но и предварительно рассчитанное время проезда по этому маршруту, которое может зависеть от загруженности дорог.
Текст тарифа (Развернуть/Свернуть) →
//<?xml version="1.0" encoding="UTF-8"?>
//<xml_consts>
// <param>
// <code>PRIOR_ORDER_COST</code>
// <type>currency</type>
// <name>Наценка за предварительный заказ</name>
// </param>
// <group>
// <name>Ожидание</name>
// <items>
// <param>
// <code>WAITING_INCLUDED</code>
// <type>boolean</type>
// <name>Ожидание включено в минимальную стоимость</name>
// </param>
// <param>
// <code>WAIT_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты ожидания</name>
// </param>
// <param>
// <code>FREE_WAITING_TIME</code>
// <type>integer</type>
// <name>Бесплатное время ожидания, мин</name>
// </param>
// <param>
// <code>PRIOR_FREE_WAITING_TIME</code>
// <type>integer</type>
// <name>Бесплатное время ожидания для предварительного заказа, мин</name>
// </param>
// <param>
// <code>CLIENT_ABSENT_VISIBLE</code>
// <type>boolean</type>
// <name>Отображать кнопку "Не выходят"</name>
// </param>
// <param>
// <code>CLIENT_ABSENT_ENABLED_TIME</code>
// <type>integer</type>
// <name>За сколько минут до начала платного ожидания делать доступной кнопку "Не выходят"</name>
// <visible>
// <code>CLIENT_ABSENT_VISIBLE</code>
// <condition>equal</condition>
// <value>true</value>
// </visible>
// </param>
// </items>
// </group>
// <group>
// <name>Обычный заказ (не почасовой)</name>
// <items>
// <group>
// <name>По городу</name>
// <items>
// <param>
// <code>MIN_CITY</code>
// <type>currency</type>
// <name>Минимальная стоимость</name>
// </param>
// <param>
// <code>BOARDING_CITY</code>
// <type>currency</type>
// <name>Посадка</name>
// </param>
// <param>
// <code>CITY_KM_INCLUDED</code>
// <type>float</type>
// <name>Сколько км включено в посадку</name>
// </param>
// <param>
// <code>CITY_KM_COST</code>
// <type>currency</type>
// <name>Цена км далее</name>
// </param>
// <param>
// <type>integer</type>
// <name>На сколько % увеличивать сумму по городу при обратном пути в карте заказа</name>
// <code>CITY_BACK_WAY_PERCENT</code>
// </param>
// <param>
// <code>CITY_MINUTES_INCLUDED</code>
// <type>float</type>
// <name>Сколько минут включено в посадку</name>
// </param>
// <param>
// <code>CITY_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты далее</name>
// </param>
// </items>
// </group>
// <group>
// <name>За городом</name>
// <items>
// <param>
// <code>MIN_COUNTRY</code>
// <type>currency</type>
// <name>Минимальная стоимость</name>
// </param>
// <param>
// <code>BOARDING_COUNTRY</code>
// <type>currency</type>
// <name>Посадка</name>
// </param>
// <param>
// <code>COUNTRY_KM_INCLUDED</code>
// <type>float</type>
// <name>Сколько км включено в посадку</name>
// </param>
// <param>
// <code>COUNTRY_KM_COST</code>
// <type>currency</type>
// <name>Цена км далее</name>
// </param>
// <param>
// <code>SOURCE_COUNTRY_KM_COST</code>
// <type>currency</type>
// <name>Цена км до адреса подачи за город</name>
// </param>
// <param>
// <code>COUNTRY_BACK_WAY_PERCENT</code>
// <type>integer</type>
// <name>На сколько % увеличивать сумму за городом при обратном пути в карте заказа</name>
// </param>
// <param>
// <code>COUNTRY_MINUTES_INCLUDED</code>
// <type>float</type>
// <name>Сколько минут включено в посадку</name>
// </param>
// <param>
// <code>COUNTRY_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты далее</name>
// </param>
// </items>
// </group>
// <group>
// <name>Простой</name>
// <items>
// <param>
// <code>IDLE_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты простоя</name>
// </param>
// <param>
// <code>FREE_IDLE_TIME</code>
// <type>integer</type>
// <name>Период между потерей скорости и началом простоя, сек</name>
// </param>
// <param>
// <code>SPEED_LIMIT</code>
// <type>integer</type>
// <name>Скорость, ниже которой считается простой, км/ч</name>
// </param>
// </items>
// </group>
// <group>
// <name>Остановки</name>
// <items>
// <param>
// <code>MIN_STOP_COST</code>
// <type>currency</type>
// <name>Минимальная стоимость остановки</name>
// </param>
// <param>
// <code>STOP_MINUTES_INCLUDED</code>
// <type>integer</type>
// <name>Сколько минут включено в минимальную стоимость остановки</name>
// </param>
// <param>
// <code>STOP_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты остановки далее</name>
// </param>
// </items>
// </group>
// <group>
// <name>Расчет километража для таксометра через ТМ</name>
// <items>
// <param>
// <code>USE_CALC_TM_ROUTE</code>
// <type>boolean</type>
// <name>Использовать расчет километража для таксометра через ТМ</name>
// </param>
// <param>
// <code>CALC_TM_ROUTE_PERIOD</code>
// <type>integer</type>
// <name>Через сколько секунд делать пересчет километража для таксометра через ТМ</name>
// </param>
// </items>
// </group>
// </items>
// </group>
// <group>
// <name>Почасовой заказ</name>
// <items>
// <param>
// <code>MIN_HOURLY</code>
// <type>currency</type>
// <name>Минимальная стоимость</name>
// </param>
// <param>
// <code>BOARDING_HOURLY</code>
// <type>currency</type>
// <name>Посадка</name>
// </param>
// <param>
// <code>HOURLY_MINUTES_INCLUDED</code>
// <type>integer</type>
// <name>Сколько минут включено в посадку</name>
// </param>
// <param>
// <code>HOURLY_MINUTE_COST</code>
// <type>currency</type>
// <name>Цена минуты далее</name>
// </param>
// <param>
// <code>HOURLY_PERIOD</code>
// <type>integer</type>
// <name>За сколько минут разом увеличивать сумму</name>
// </param>
// <param>
// <code>HOURLY_TRIP_KM_INCLUDED</code>
// <type>float</type>
// <name>Количество км, включенных в поездку</name>
// <visible>
// <code>HOURLY_HOUR_KM_INCLUDED</code>
// <condition>equal</condition>
// <value>0</value>
// </visible>
// </param>
// <param>
// <code>HOURLY_HOUR_KM_INCLUDED</code>
// <type>float</type>
// <name>Количество км, включенных в час</name>
// <visible>
// <code>HOURLY_TRIP_KM_INCLUDED</code>
// <condition>equal</condition>
// <value>0</value>
// </visible>
// </param>
// <param>
// <code>HOURLY_KM_COST</code>
// <type>currency</type>
// <name>Цена км</name>
// </param>
// </items>
// </group>
// <group>
// <name>Районы</name>
// <items>
// <param>
// <code>USE_ZONE_COST</code>
// <type>boolean</type>
// <name>Учитывать посадку/высадку в районах</name>
// </param>
// <param>
// <code>USE_ZONE_PATH</code>
// <type>boolean</type>
// <name>Учитывать проезды между районами</name>
// </param>
// <param>
// <code>ZONES_PATH_GROUP_ID</code>
// <type>zones_path_group</type>
// <name>Группа проездов между районами</name>
// <visible>
// <code>USE_ZONE_PATH</code>
// <condition>equal</condition>
// <value>true</value>
// </visible>
// </param>
// <param>
// <code>ZONES_BACK_WAY_PERCENT</code>
// <type>integer</type>
// <name>На сколько % увеличивать сумму за проезды между районами при обратном пути в карте заказа</name>
// <visible>
// <code>USE_ZONE_PATH</code>
// <condition>equal</condition>
// <value>true</value>
// </visible>
// </param>
// <param>
// <code>USE_REAL_ZONES_IN_TAXM</code>
// <type>boolean</type>
// <name>Определять районы в таксометре по фактическому маршруту</name>
// </param>
// </items>
// </group>
// <group>
// <name>Дополнительные параметры минимальной стоимости</name>
// <items>
// <param>
// <code>DISCOUNT_AFTER_MIN</code>
// <type>boolean</type>
// <name>Считать скидки после минимальной стоимости</name>
// </param>
// <param>
// <code>SERVICES_AFTER_MIN</code>
// <type>boolean</type>
// <name>Считать услуги после минимальной стоимости</name>
// </param>
// <param>
// <code>MIN_SUM_AFTER_CALC</code>
// <type>boolean</type>
// <name>Применять минимальную стоимость после завершения расчета в таксометре</name>
// </param>
// </items>
// </group>
// <group>
// <name>Округление</name>
// <items>
// <param>
// <code>ROUNDING</code>
// <type>currency</type>
// <name>Округление</name>
// <min>0</min>
// </param>
// <param>
// <code>ROUND_UP</code>
// <type>boolean</type>
// <name>Округлять в большую сторону</name>
// </param>
// </items>
// </group>
// <group>
// <name>Таксофон</name>
// <items>
// <param>
// <code>TAXOPHONE_FIRST_DISCOUNT_SUM</code>
// <type>currency</type>
// <name>Скидка за первый заказ из TaxoPhone, руб</name>
// </param>
// <param>
// <code>TAXOPHONE_FIRST_DISCOUNT_PERCENT</code>
// <type>integer</type>
// <name>Скидка за первый заказ из TaxoPhone, %</name>
// </param>
// <param>
// <code>TAXOPHONE_CONSTANT_DISCOUNT_SUM</code>
// <type>currency</type>
// <name>Постоянная скидка для заказов из TaxoPhone, руб</name>
// </param>
// <param>
// <code>TAXOPHONE_CONSTANT_DISCOUNT_PERCENT</code>
// <type>integer</type>
// <name>Постоянная скидка для заказов из TaxoPhone, %</name>
// </param>
// <param>
// <code>TAXOPHONE_REGULAR_DISCOUNT_COUNT</code>
// <type>integer</type>
// <name>Через сколько заказов должна срабатывать регулярная скидка для заказов из TaxoPhone</name>
// </param>
// <param>
// <code>TAXOPHONE_REGULAR_DISCOUNT_SUM</code>
// <type>currency</type>
// <name>Регулярная скидка для заказов из TaxoPhone, руб</name>
// </param>
// <param>
// <code>TAXOPHONE_REGULAR_DISCOUNT_PERCENT</code>
// <type>integer</type>
// <name>Регулярная скидка для заказов из TaxoPhone, %</name>
// </param>
// </items>
// </group>
// <group>
// <name>Услуги, доступные водителю в таксометре</name>
// <items>
// <param>
// <code>SERVICES_BUTTON_COUNT</code>
// <type>integer</type>
// <name>Количество услуг</name>
// <min>0</min>
// <max>10</max>
// </param>
// <param>
// <code>SERVICE_1</code>
// <type>order_param</type>
// <name>Услуга 1</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>1</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_1</code>
// <type>boolean</type>
// <name>Услугу 1 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>1</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_2</code>
// <type>order_param</type>
// <name>Услуга 2</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>2</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_2</code>
// <type>boolean</type>
// <name>Услугу 2 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>2</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_3</code>
// <type>order_param</type>
// <name>Услуга 3</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>3</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_3</code>
// <type>boolean</type>
// <name>Услугу 3 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>3</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_4</code>
// <type>order_param</type>
// <name>Услуга 4</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>4</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_4</code>
// <type>boolean</type>
// <name>Услугу 4 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>4</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_5</code>
// <type>order_param</type>
// <name>Услуга 5</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>5</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_5</code>
// <type>boolean</type>
// <name>Услугу 5 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>5</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_6</code>
// <type>order_param</type>
// <name>Услуга 6</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>6</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_6</code>
// <type>boolean</type>
// <name>Услугу 6 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>6</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_7</code>
// <type>order_param</type>
// <name>Услуга 7</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>7</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_7</code>
// <type>boolean</type>
// <name>Услугу 7 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>7</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_8</code>
// <type>order_param</type>
// <name>Услуга 8</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>8</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_8</code>
// <type>boolean</type>
// <name>Услугу 8 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>8</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_9</code>
// <type>order_param</type>
// <name>Услуга 9</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>9</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_9</code>
// <type>boolean</type>
// <name>Услугу 9 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>9</value>
// </visible>
// </param>
// <param>
// <code>SERVICE_10</code>
// <type>order_param</type>
// <name>Услуга 10</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>greater_or_equal</condition>
// <value>10</value>
// </visible>
// </param>
// <param>
// <code>CAN_REPEAT_SERVICE_10</code>
// <type>boolean</type>
// <name>Услугу 10 можно использовать повторно</name>
// <visible>
// <code>SERVICES_BUTTON_COUNT</code>
// <condition>equal</condition>
// <value>10</value>
// </visible>
// </param>
// </items>
// </group>
// <param>
// <code>CALC_SUM_BY_TAXIMETER</code>
// <type>boolean</type>
// <name>Считать сумму по таксометру</name>
// </param>
// <param>
// <code>USE_STOPS_WAITING_IDLE</code>
// <type>boolean</type>
// <name>Считать простой, ожидание и остановки независимо от настройки "Считать сумму по таксометру"</name>
// <visible>
// <code>CALC_SUM_BY_TAXIMETER</code>
// <condition>equal</condition>
// <value>false</value>
// </visible>
// </param>
// <param>
// <code>USE_GPS_MISSED_DISTANCE_RECOVERY</code>
// <type>boolean</type>
// <name>Использовать восстановление километража по прямой при потере координат</name>
// <visible>
// <code>CALC_SUM_BY_TAXIMETER</code>
// <condition>equal</condition>
// <value>true</value>
// </visible>
// </param>
// <param>
// <code>VALUTA</code>
// <type>string</type>
// <name>Валюта</name>
// </param>
// <group>
// <name>Параметры для печати чека</name>
// <items>
// <param>
// <code>NEED_DETAILS_IN_CHECK</code>
// <type>boolean</type>
// <name>Печатать детализацию поездки</name>
// </param>
// <param>
// <code>TAXI_NAME</code>
// <type>string</type>
// <name>Название такси</name>
// </param>
// <param>
// <code>TAXI_PHONE</code>
// <type>string</type>
// <name>Телефон такси</name>
// </param>
// <param>
// <code>TAXI_INN</code>
// <type>string</type>
// <name>ИНН</name>
// </param>
// </items>
// </group>
//</xml_consts>
const
MIN_CITY = 0;
MIN_COUNTRY = 0;
MIN_HOURLY = 0;
BOARDING_CITY = 0;
CITY_KM_INCLUDED = 0;
CITY_KM_COST = 0;
CITY_MINUTES_INCLUDED = 0;
CITY_MINUTE_COST = 0;
BOARDING_COUNTRY = 0;
COUNTRY_KM_INCLUDED = 0;
COUNTRY_KM_COST = 0;
COUNTRY_MINUTES_INCLUDED = 0;
COUNTRY_MINUTE_COST = 0;
SOURCE_COUNTRY_KM_COST = 0;
BOARDING_HOURLY = 0;
HOURLY_MINUTES_INCLUDED = 0;
HOURLY_MINUTE_COST = 0;
HOURLY_PERIOD = 0;
HOURLY_TRIP_KM_INCLUDED = 0;
HOURLY_HOUR_KM_INCLUDED = 0;
HOURLY_KM_COST = 0;
WAITING_INCLUDED = True;
WAIT_MINUTE_COST = 0;
FREE_WAITING_TIME = 0;
PRIOR_FREE_WAITING_TIME = 0;
CLIENT_ABSENT_VISIBLE = True;
CLIENT_ABSENT_ENABLED_TIME = 0;
IDLE_MINUTE_COST = 0;
FREE_IDLE_TIME = 0;
SPEED_LIMIT = 5;
USE_ZONE_PATH = False;
USE_ZONE_COST = False;
ZONES_PATH_GROUP_ID = 0;
USE_REAL_ZONES_IN_TAXM = False;
MIN_STOP_COST = 0;
STOP_MINUTES_INCLUDED = 0;
STOP_MINUTE_COST = 0;
PRIOR_ORDER_COST = 0;
CITY_BACK_WAY_PERCENT = 0;
COUNTRY_BACK_WAY_PERCENT = 0;
ZONES_BACK_WAY_PERCENT = 0;
ROUNDING = 1;
ROUND_UP = False;
MIN_SUM_AFTER_CALC = False;
DISCOUNT_AFTER_MIN = False;
SERVICES_AFTER_MIN = False;
TAXOPHONE_FIRST_DISCOUNT_SUM = 0;
TAXOPHONE_FIRST_DISCOUNT_PERCENT = 0;
TAXOPHONE_CONSTANT_DISCOUNT_SUM = 0;
TAXOPHONE_CONSTANT_DISCOUNT_PERCENT = 0;
TAXOPHONE_REGULAR_DISCOUNT_COUNT = 0;
TAXOPHONE_REGULAR_DISCOUNT_SUM = 0;
TAXOPHONE_REGULAR_DISCOUNT_PERCENT = 0;
CALC_SUM_BY_TAXIMETER = True;
USE_STOPS_WAITING_IDLE = False;
USE_GPS_MISSED_DISTANCE_RECOVERY = False;
USE_CALC_TM_ROUTE = False;
CALC_TM_ROUTE_PERIOD = 0;
CALC_TM_ROUTE_FINISH_TIMEOUT = 15;
VALUTA = 'р';
NEED_DETAILS_IN_CHECK = False;
TAXI_NAME = 'ООО "Название Такси"';
TAXI_PHONE = '(495) 123-45-67';
TAXI_INN = '123456789012';
SERVICES_BUTTON_COUNT = 0;
SERVICE_1 = 0;
CAN_REPEAT_SERVICE_1 = False;
SERVICE_2 = 0;
CAN_REPEAT_SERVICE_2 = False;
SERVICE_3 = 0;
CAN_REPEAT_SERVICE_3 = False;
SERVICE_4 = 0;
CAN_REPEAT_SERVICE_4 = False;
SERVICE_5 = 0;
CAN_REPEAT_SERVICE_5 = False;
SERVICE_6 = 0;
CAN_REPEAT_SERVICE_6 = False;
SERVICE_7 = 0;
CAN_REPEAT_SERVICE_7 = False;
SERVICE_8 = 0;
CAN_REPEAT_SERVICE_8 = False;
SERVICE_9 = 0;
CAN_REPEAT_SERVICE_9 = False;
SERVICE_10 = 0;
CAN_REPEAT_SERVICE_10 = False;
// Округлить сумму.
function RoundSum(Sum: Single): Single;
var
F, R: Single;
begin
if ROUNDING = 0 then
Result := Sum
else
begin
R := 1 / ROUNDING;
if ROUND_UP then
Result := Ceil(Sum * R) / R
else
begin
F := Trunc(Sum * R) / R;
if Sum - F >= ROUNDING / 2 then
F := F + ROUNDING;
Result := F;
end;
end;
end;
function FloatToStrFixed(Value: Single): String;
var
R, SymbolCount: Integer;
begin
R := Floor(ROUNDING * 100);
if R mod 100 = 0 then
SymbolCount := 0
else
if R mod 10 = 0 then
SymbolCount := 1
else
SymbolCount := 2;
Result := FloatToStr(Round(Value, SymbolCount));
end;
procedure TM_AddZonesSum(var TaxmZonesSum: Single; var ZonePathSum: Single;
NeedPrintToBill: Boolean);
var
F: Single;
s: String;
NeedZoneOutCost: Boolean;
StopCount, i: Integer;
begin
// == Районы.
if USE_ZONE_COST then
begin
// Посадка.
F := ReadFloat('ZoneInCost', -1);
if F <> 0 then
begin
s := ReadStr('ZoneName', -1);
TaxmZonesSum := TaxmZonesSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Посадка в ''' + s + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
// Высадка.
if ReadStr('ZoneName', -1) <> ReadStr('ZoneName', -2) then
NeedZoneOutCost := True
else
if ReadInt('StopCount') > 0 then
begin
NeedZoneOutCost := False;
for i := 0 to ReadInt('StopCount') - 1 do
if ReadStr('ZoneName', i) <> ReadStr('ZoneName', -1) then
NeedZoneOutCost := True;
end
else
NeedZoneOutCost := False;
if NeedZoneOutCost then
begin
F := ReadFloat('ZoneOutCost', -2);
if F <> 0 then
begin
s := ReadStr('ZoneName', -2);
TaxmZonesSum := TaxmZonesSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Высадка в ''' + s + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
// Остановки.
for i := 0 to ReadInt('StopCount') - 1 do
begin
F := ReadFloat('ZoneStopCost', i);
if F <> 0 then
begin
s := ReadStr('ZoneName', i);
TaxmZonesSum := TaxmZonesSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Остановка в ''' + s + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
end;
// Проезды.
if USE_ZONE_PATH then
begin
StopCount := ReadInt('StopCount');
if StopCount > 0 then
begin
F := ReadFloat('ZonePathCost', -1, 0);
if F <> 0 then
begin
ZonePathSum := F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Проезд ''' +
ReadStr('ZoneName', -1) + ''' -> ''' +
ReadStr('ZoneName', 0) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
for i := 0 to StopCount - 2 do
begin
F := ReadFloat('ZonePathCost', i, i + 1);
if F <> 0 then
begin
ZonePathSum := ZonePathSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Проезд ''' +
ReadStr('ZoneName', i) + ''' -> ''' +
ReadStr('ZoneName', i + 1) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
F := ReadFloat('ZonePathCost', StopCount - 1, -2);
if F <> 0 then
begin
ZonePathSum := ZonePathSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Проезд ''' +
ReadStr('ZoneName', StopCount - 1) + ''' -> ''' +
ReadStr('ZoneName', -2) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end
else
begin
F := ReadFloat('ZonePathCost', -1, -2);
if F <> 0 then
begin
ZonePathSum := F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Проезд ''' +
ReadStr('ZoneName', -1) + ''' -> ''' +
ReadStr('ZoneName', -2) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
if ReadBool('BackFree') and (ZonePathSum <> 0) and
(ZONES_BACK_WAY_PERCENT <> 0) then
begin
F := ZonePathSum * ZONES_BACK_WAY_PERCENT / 100;
ZonePathSum := ZonePathSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Обратный проезд между районами');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
end;
// Заказ пришёл из TaxoPhone.
function TM_IsFromTaxophone: Boolean;
begin
Result := (ReadInt('CreationWay') = 6) or
(ReadInt('CreationWay') = 9) or
(ReadInt('CreationWay') = 11);
end;
// Рассчитать стоимость за ожидание.
function TM_GetWaitingCost: Single;
var
FreeWaitingTime: Integer;
begin
if not ReadBool('IsPrior') then
FreeWaitingTime := FREE_WAITING_TIME
else
FreeWaitingTime := PRIOR_FREE_WAITING_TIME;
if ReadInt('WaitTime') div 60 > FreeWaitingTime then
Result := WAIT_MINUTE_COST *
(ReadInt('WaitTime') div 60 - FreeWaitingTime)
else
Result := 0;
end;
// Получить минималку.
function TM_GetMinSum: Single;
begin
if ReadBool('IsHourly') then
Result := MIN_HOURLY
else
if ReadBool('IsCountry') then
Result := MIN_COUNTRY
else
Result := MIN_CITY;
end;
// Добавить услуги (атрибуты/параметры) к сумме.
procedure TM_AddServices(var Sum: Single; NeedPrintToBill: Boolean);
var
F, ServicePercentSum, ServicesSum: Single;
i: Integer;
begin
// Услуги.
ServicesSum := 0;
for i := 0 to ReadInt('ServiceCount') - 1 do
begin
F := ReadFloat('ServiceSum', i);
if F <> 0 then
begin
ServicesSum := ServicesSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text',
'Услуга ''' + ReadStr('ServiceName', i) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
ServicePercentSum := 0;
for i := 0 to ReadInt('ServiceCount') - 1 do
begin
F := ReadFloat('ServicePercent', i);
if F <> 0 then
begin
ServicePercentSum := ServicePercentSum + F;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text',
'Услуга ''' + ReadStr('ServiceName', i) + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 0) + '%');
end;
end;
end;
Sum := Sum + Sum * ServicePercentSum / 100 + ServicesSum;
end;
// Рассчитать сумму со скидкой.
procedure TM_AddDiscounts(var Sum: Single;
var TotalDiscSum: Single;
var TotalDiscPercent: Single;
NeedPrintToBill: Boolean);
var
F: Single;
i: Integer;
S: String;
begin
// == Скидки.
TotalDiscSum := 0;
TotalDiscPercent := 0;
// Скидка/наценка.
for i := 0 to ReadInt('DiscMarkupCount') - 1 do
begin
F := ReadFloat('DiscMarkupSum', i);
if F <> 0 then
begin
if NeedPrintToBill then
begin
if F > 0 then
S := 'Наценка'
else
S := 'Скидка';
WriteStr('Bill', 'Text', S + ' ''' +
ReadStr('DiscMarkupName', i) + '''');
WriteStr('Bill', 'Sum', FloatToStr(Abs(F), 2));
end;
// + это наценка, - это скидка.
TotalDiscSum := TotalDiscSum - F;
end;
F := ReadFloat('DiscMarkupPercent', i);
if F <> 0 then
begin
if NeedPrintToBill then
begin
if F > 0 then
S := 'Наценка'
else
S := 'Скидка';
WriteStr('Bill', 'Text', S + ' ''' +
ReadStr('DiscMarkupName', i) + '''');
WriteStr('Bill', 'Sum', FloatToStr(Abs(F), 0) + '%');
end;
// + это наценка, - это скидка.
TotalDiscPercent := TotalDiscPercent - F;
end;
end;
if TM_IsFromTaxophone then
begin
// Постоянная скидка для заказов из TaxoPhone.
TotalDiscSum := TotalDiscSum + TAXOPHONE_CONSTANT_DISCOUNT_SUM;
TotalDiscPercent := TotalDiscPercent + TAXOPHONE_CONSTANT_DISCOUNT_PERCENT;
if NeedPrintToBill then
begin
if TAXOPHONE_CONSTANT_DISCOUNT_SUM > 0 then
begin
WriteStr('Bill', 'Text', 'Постоянная скидка за заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_CONSTANT_DISCOUNT_SUM, 2));
end;
if TAXOPHONE_CONSTANT_DISCOUNT_PERCENT > 0 then
begin
WriteStr('Bill', 'Text', 'Постоянная скидка за заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_CONSTANT_DISCOUNT_PERCENT, 0) + '%');
end;
end;
// Скидка за первый заказ из TaxoPhone.
if ReadInt('ClientTaxoPhoneOrdersCount') = 0 then
begin
TotalDiscSum := TotalDiscSum + TAXOPHONE_FIRST_DISCOUNT_SUM;
TotalDiscPercent := TotalDiscPercent + TAXOPHONE_FIRST_DISCOUNT_PERCENT;
if NeedPrintToBill then
begin
if TAXOPHONE_FIRST_DISCOUNT_SUM > 0 then
begin
WriteStr('Bill', 'Text', 'Скидка за первый заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_FIRST_DISCOUNT_SUM, 2));
end;
if TAXOPHONE_FIRST_DISCOUNT_PERCENT > 0 then
begin
WriteStr('Bill', 'Text', 'Скидка за первый заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_FIRST_DISCOUNT_PERCENT, 0) + '%');
end;
end;
end;
// Регулярная скидка за заказ из TaxoPhone.
if TAXOPHONE_REGULAR_DISCOUNT_COUNT > 0 then
if (ReadInt('ClientTaxoPhoneOrdersCount') + 1) mod TAXOPHONE_REGULAR_DISCOUNT_COUNT = 0 then
begin
TotalDiscSum := TotalDiscSum + TAXOPHONE_REGULAR_DISCOUNT_SUM;
TotalDiscPercent := TotalDiscPercent + TAXOPHONE_REGULAR_DISCOUNT_PERCENT;
if NeedPrintToBill then
begin
if TAXOPHONE_REGULAR_DISCOUNT_SUM > 0 then
begin
WriteStr('Bill', 'Text', 'Регулярная скидка за каждый ' +
IntToStr(TAXOPHONE_REGULAR_DISCOUNT_COUNT) + '-й заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_REGULAR_DISCOUNT_SUM, 2));
end;
if TAXOPHONE_FIRST_DISCOUNT_PERCENT > 0 then
begin
WriteStr('Bill', 'Text', 'Регулярная скидка за каждый ' +
IntToStr(TAXOPHONE_REGULAR_DISCOUNT_COUNT) + '-й заказ из TaxoPhone');
WriteStr('Bill', 'Sum', FloatToStr(TAXOPHONE_REGULAR_DISCOUNT_PERCENT, 0) + '%');
end;
end;
end;
end;
// Скидка.
S := ReadStr('DiscountName');
F := ReadFloat('DiscountSum');
if F <> 0 then
begin
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Скидка ''' + S + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
TotalDiscSum := TotalDiscSum + F;
end;
F := ReadFloat('DiscountPercent');
if F <> 0 then
begin
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Скидка ''' + S + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 0) + '%');
end;
TotalDiscPercent := TotalDiscPercent + F;
end;
// Скидка по диск. карте.
S := ReadStr('DiscCardName');
F := ReadFloat('DiscCardSum');
if F <> 0 then
begin
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Скидка по ДК ''' + S + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
TotalDiscSum := TotalDiscSum + F;
end;
F := ReadFloat('DiscCardPercent');
if F <> 0 then
begin
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Скидка по ДК ''' + S + '''');
WriteStr('Bill', 'Sum', FloatToStr(F, 0) + '%');
end;
TotalDiscPercent := TotalDiscPercent + F;
end;
Sum := Sum - Sum * TotalDiscPercent / 100 - TotalDiscSum;
if NeedPrintToBill then
begin
WriteStr('Bill', 'Text', 'Сумма со скидкой');
WriteStr('Bill', 'Sum', FloatToStr(Sum, 2));
end;
end;
// *****************
// Вычисление суммы.
// *****************
procedure CalcSum;
var
Sum, F, CityDist, CountryDist, TotalDist, HourlyPayDist,
ZonePathSum, TaxmZonesSum: Single;
CityCost, CountryCost: Single;
i, StopCount, TripTime: Integer;
NeedZoneOutCost: Boolean;
CityTripTime, CountryTripTime: Integer;
begin
Sum := 0;
WriteInt('UseZonesPathGroupId', ZONES_PATH_GROUP_ID);
if ReadBool('IsPrior') and (PRIOR_ORDER_COST <> 0) then
begin
Sum := Sum + PRIOR_ORDER_COST;
WriteStr('Bill', 'Text', 'Предварительный заказ');
WriteStr('Bill', 'Sum', FloatToStr(PRIOR_ORDER_COST, 2));
end;
F := TM_GetWaitingCost;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text',
'Ожидание ' + FloatToStr(WAIT_MINUTE_COST, 2) + ' ' + VALUTA + '/мин');
WriteStr('Bill', 'Value',
IntToStr(ReadInt('WaitTime') div 60) + ' мин');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
F := SOURCE_COUNTRY_KM_COST * ReadFloat('SourceDistCountry');
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text',
'До подачи за город ' + FloatToStr(SOURCE_COUNTRY_KM_COST, 2) + ' ' + VALUTA + '/км');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('SourceDistCountry'), 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
CityDist := ReadFloat('Distance');
if ReadBool('IsCountry') then
CountryDist := ReadFloat('DistCountry')
else
CountryDist := 0;
TotalDist := CityDist + CountryDist;
TripTime := ReadInt('TripTime');
// Почасовой заказ.
if ReadBool('IsHourly') then
begin
F := BOARDING_HOURLY;
if TripTime div 60 > HOURLY_MINUTES_INCLUDED then
if HOURLY_PERIOD = 0 then
F := F + (TripTime div 60 - HOURLY_MINUTES_INCLUDED) *
HOURLY_MINUTE_COST
else
F := F + Ceil((TripTime div 60 - HOURLY_MINUTES_INCLUDED) /
HOURLY_PERIOD) * HOURLY_PERIOD * HOURLY_MINUTE_COST;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Продолжительность');
WriteStr('Bill', 'Value',
IntToStr(TripTime div 60) + ' мин');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
if HOURLY_KM_COST > 0 then
begin
F := 0;
HourlyPayDist := 0;
if HOURLY_HOUR_KM_INCLUDED > 0 then
begin
HourlyPayDist := (TotalDist - HOURLY_HOUR_KM_INCLUDED *
Ceil(TripTime / 60 / 60));
F := HourlyPayDist * HOURLY_KM_COST;
end
else
if HOURLY_TRIP_KM_INCLUDED > 0 then
begin
HourlyPayDist := TotalDist - HOURLY_TRIP_KM_INCLUDED;
F := HourlyPayDist * HOURLY_KM_COST;
end
else
begin
HourlyPayDist := TotalDist;
F := TotalDist * HOURLY_KM_COST;
end;
if F > 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Платный километраж');
WriteStr('Bill', 'Value',
FloatToStr(HourlyPayDist, 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end
else
begin
// Загородный заказ.
if ReadBool('IsCountry') then
begin
F := BOARDING_COUNTRY;
if TotalDist > COUNTRY_KM_INCLUDED then
if CityDist <= COUNTRY_KM_INCLUDED then
F := F + (TotalDist - COUNTRY_KM_INCLUDED) * COUNTRY_KM_COST
else
F := F + (CityDist - COUNTRY_KM_INCLUDED) * CITY_KM_COST +
CountryDist * COUNTRY_KM_COST;
CityCost := 0;
if CityDist > COUNTRY_KM_INCLUDED then
CityCost := BOARDING_COUNTRY + (CityDist - COUNTRY_KM_INCLUDED) * CITY_KM_COST
else
if (TotalDist > COUNTRY_KM_INCLUDED) and (COUNTRY_KM_INCLUDED > 0) then
CityCost := BOARDING_COUNTRY * CityDist / COUNTRY_KM_INCLUDED
else
if TotalDist > 0 then
CityCost := BOARDING_COUNTRY * CityDist / TotalDist;
CountryCost := F - CityCost;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Путь');
WriteStr('Bill', 'Value',
FloatToStr(TotalDist, 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
if ReadBool('BackFree') then
begin
if (CityCost <> 0) and (CITY_BACK_WAY_PERCENT <> 0) then
begin
F := CityCost * CITY_BACK_WAY_PERCENT / 100;
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Обратно по городу');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
if (CountryCost <> 0) and (COUNTRY_BACK_WAY_PERCENT <> 0) then
begin
F := CountryCost * COUNTRY_BACK_WAY_PERCENT / 100;
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Обратно за городом');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
if ((COUNTRY_MINUTE_COST > 0) or (CITY_MINUTE_COST > 0)) and
(TripTime > COUNTRY_MINUTES_INCLUDED * 60) and
(TotalDist > 0) then
begin
CountryTripTime := Floor(TripTime * (CountryDist / TotalDist));
CityTripTime := Floor(TripTime - CountryTripTime);
if CityTripTime <= COUNTRY_MINUTES_INCLUDED * 60 then
begin
CityCost := 0;
CountryCost := (TripTime / 60 - COUNTRY_MINUTES_INCLUDED) * COUNTRY_MINUTE_COST
end
else
begin
CityCost := (CityTripTime / 60 - COUNTRY_MINUTES_INCLUDED) * CITY_MINUTE_COST;
CountryCost := CountryTripTime / 60 * COUNTRY_MINUTE_COST;
end;
F := CityCost + CountryCost;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Длительность по городу');
WriteStr('Bill', 'Value', TimeLenToStr(CityTripTime));
WriteStr('Bill', 'Sum', FloatToStr(CityCost, 2));
WriteStr('Bill', 'Text', 'Длительность за городом');
WriteStr('Bill', 'Value', TimeLenToStr(CountryTripTime));
WriteStr('Bill', 'Sum', FloatToStr(CountryCost, 2));
end;
end;
end
else
// Городской заказ.
begin
F := BOARDING_CITY;
if TotalDist > CITY_KM_INCLUDED then
F := F + (TotalDist - CITY_KM_INCLUDED) * CITY_KM_COST;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Путь');
WriteStr('Bill', 'Value',
FloatToStr(TotalDist, 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
if ReadBool('BackFree') then
if (CITY_BACK_WAY_PERCENT <> 0) then
begin
F := F * CITY_BACK_WAY_PERCENT / 100;
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Обратно по городу');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
if (CITY_MINUTE_COST > 0) and
(TripTime > CITY_MINUTES_INCLUDED * 60) then
begin
F := (TripTime / 60 - CITY_MINUTES_INCLUDED) * CITY_MINUTE_COST;
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Длительность по городу');
WriteStr('Bill', 'Value', TimeLenToStr(TripTime));
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
end;
end;
// Остановки.
if not ReadBool('IsHourly') then
begin
F := MIN_STOP_COST * ReadInt('StopCount');
if F <> 0 then
begin
Sum := Sum + F;
WriteStr('Bill', 'Text', 'Остановки');
WriteStr('Bill', 'Value',
IntToStr(ReadInt('StopCount')) + ' шт');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end;
TaxmZonesSum := 0;
ZonePathSum := 0;
TM_AddZonesSum(TaxmZonesSum, ZonePathSum, True);
Sum := Sum + ZonePathSum + TaxmZonesSum;
if not SERVICES_AFTER_MIN then
TM_AddServices(Sum, True);
WriteFloat('Sum', Sum);
end;
// ***********************************************
// Заполение полей райнов и скидок для таксометра.
// ***********************************************
procedure CalcTaxmSums;
var
i, StopCount: Integer;
TaxmZonesSum, TotalDiscPercent,
TotalDiscSum, ZonePathSum, Sum: Single;
begin
// == Районы.
WriteInt('UseZonesPathGroupId', ZONES_PATH_GROUP_ID);
TaxmZonesSum := 0;
ZonePathSum := 0;
TM_AddZonesSum(TaxmZonesSum, ZonePathSum, False);
// Запись.
WriteFloat('TaxmZonesSum', TaxmZonesSum + ZonePathSum);
TotalDiscSum := 0;
TotalDiscPercent := 0;
TM_AddDiscounts(Sum, TotalDiscSum, TotalDiscPercent, False);
// Запись.
WriteFloat('TaxmTotalDiscSum', TotalDiscSum);
WriteFloat('TaxmTotalDiscPercent', TotalDiscPercent);
end;
// ****************************
// Вычисление суммы со скидкой.
// ****************************
procedure CalcTotalSum;
var
WaitingCost, F, MinSum, Sum: Single;
i: Integer;
TotalDiscSum, TotalDiscPercent: Single;
begin
// Сумма без скидок.
Sum := ReadFloat('Sum');
TotalDiscSum := 0;
TotalDiscPercent := 0;
if not DISCOUNT_AFTER_MIN then
TM_AddDiscounts(Sum, TotalDiscSum, TotalDiscPercent, True);
MinSum := TM_GetMinSum;
WriteStr('Bill', 'Text', 'Минимум');
WriteStr('Bill', 'Sum', FloatToStr(MinSum, 2));
WaitingCost := TM_GetWaitingCost;
if WAITING_INCLUDED then
Sum := Max(MinSum, Sum)
else
Sum := Max(MinSum + WaitingCost, Sum);
if SERVICES_AFTER_MIN then
TM_AddServices(Sum, True);
if DISCOUNT_AFTER_MIN then
TM_AddDiscounts(Sum, TotalDiscSum, TotalDiscPercent, True);
Sum := RoundSum(Sum);
WriteStr('Bill', 'Text', 'Итого');
WriteStr('Bill', 'Sum', FloatToStr(Sum, 2) + ' ' + VALUTA);
// Записать итоговую сумму.
WriteFloat('TotalSum', Sum);
end;
// Использовать простой и остановки.
function TMD_UseCalcStopsIdle: Boolean;
begin
Result := not ReadBool('IsHourly') and
(CALC_SUM_BY_TAXIMETER or USE_STOPS_WAITING_IDLE)
end;
// **************
// Инициализация.
// **************
procedure ResetCalc;
begin
if CLIENT_ABSENT_VISIBLE then
WriteInt('ClientAbsentVisible', 1)
else
WriteInt('ClientAbsentVisible', 0);
end;
// *****************
// Ожидание клиента.
// *****************
procedure WaitCalc;
var
Sum: Single;
FreeWaitingTime, WaitTime: Integer;
begin
if not ReadBool('IsPrior') then
FreeWaitingTime := FREE_WAITING_TIME
else
FreeWaitingTime := PRIOR_FREE_WAITING_TIME;
WaitTime := ReadInt('WaitTime');
WriteInt('FreeWaitingTime', (FreeWaitingTime * 60 - WaitTime));
if CALC_SUM_BY_TAXIMETER or USE_STOPS_WAITING_IDLE then
if WaitTime > FreeWaitingTime * 60 then
begin
Sum := ReadFloat('Sum') + WAIT_MINUTE_COST / 60;
WriteFloat('Temp', 'PayWaitTimeSum', Sum);
WriteFloat('Sum', Sum);
WriteStr('SumStr', FloatToStrFixed(RoundSum(Sum)));
WriteFloat('CurrentSum', Sum);
end;
if CLIENT_ABSENT_VISIBLE and
(WaitTime > (FreeWaitingTime - CLIENT_ABSENT_ENABLED_TIME) * 60) then
WriteInt('ClientAbsentEnabled', 1)
else
WriteInt('ClientAbsentEnabled', 0);
end;
// Получить параметры услуги по ИД.
procedure TMD_GetServiceParams(ServiceId: Integer;
var ServiceCost: Single;
var ServicePercent: Integer;
var ServiceName: String);
begin
ServiceCost := ReadFloat('OrderParamSum', ServiceId);
ServiceName := ReadStr('OrderParamName', ServiceId);
ServicePercent := Trunc(ReadFloat('OrderParamPercent', ServiceId));
end;
// Получить параметры услуги по индексу.
procedure TMD_GetServiceParamsByIndex(Index: Integer;
var ServiceCost: Single;
var ServicePercent: Integer;
var ServiceName: String;
var ServiceId: Integer;
var CanRepeatService: Boolean);
begin
if Index = 1 then
begin
TMD_GetServiceParams(SERVICE_1, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_1;
CanRepeatService := CAN_REPEAT_SERVICE_1;
end
else
if Index = 2 then
begin
TMD_GetServiceParams(SERVICE_2, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_2;
CanRepeatService := CAN_REPEAT_SERVICE_2;
end
else
if Index = 3 then
begin
TMD_GetServiceParams(SERVICE_3, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_3;
CanRepeatService := CAN_REPEAT_SERVICE_3;
end
else
if Index = 4 then
begin
TMD_GetServiceParams(SERVICE_4, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_4;
CanRepeatService := CAN_REPEAT_SERVICE_4;
end
else
if Index = 5 then
begin
TMD_GetServiceParams(SERVICE_5, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_5;
CanRepeatService := CAN_REPEAT_SERVICE_5;
end
else
if Index = 6 then
begin
TMD_GetServiceParams(SERVICE_6, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_6;
CanRepeatService := CAN_REPEAT_SERVICE_6;
end
else
if Index = 7 then
begin
TMD_GetServiceParams(SERVICE_7, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_7;
CanRepeatService := CAN_REPEAT_SERVICE_7;
end
else
if Index = 8 then
begin
TMD_GetServiceParams(SERVICE_8, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_8;
CanRepeatService := CAN_REPEAT_SERVICE_8;
end
else
if Index = 9 then
begin
TMD_GetServiceParams(SERVICE_9, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_9;
CanRepeatService := CAN_REPEAT_SERVICE_9;
end
else
if Index = 10 then
begin
TMD_GetServiceParams(SERVICE_10, ServiceCost, ServicePercent, ServiceName);
ServiceId := SERVICE_10;
CanRepeatService := CAN_REPEAT_SERVICE_10;
end;
end;
// Создать кнопку с услугой.
procedure TMD_CreateDriverServiceButton(Index: Integer; ButtonName: String);
var
I, ServicePercent, ServiceId: Integer;
ServiceCost: Single;
ServiceName: String;
CanRepeatService: Boolean;
begin
TMD_GetServiceParamsByIndex(Index, ServiceCost, ServicePercent, ServiceName,
ServiceId, CanRepeatService);
if (ServiceId > 0) and
((ServiceCost <> 0) or (ServicePercent <> 0)) then
begin
WriteStr('Button', 'New', ButtonName);
WriteStr('Button', 'Select', ButtonName);
WriteInt('Button', 'Visible', 1);
WriteInt('Button', 'Enabled', 1);
WriteInt('Button', 'LongClick', 1);
WriteStr('Button', 'Text', ServiceName);
end;
end;
// Получить количество услуг, доступных водителю.
function TMD_GetDriverServicesCount: Integer;
begin
if SERVICES_BUTTON_COUNT > 10 then
Result := 10
else
if SERVICES_BUTTON_COUNT < 0 then
Result := 0
else
Result := SERVICES_BUTTON_COUNT;
end;
// Инициализация доп. кнопок для водительских услуг.
procedure TMD_InitDriverServiceButtons;
var
I: Integer;
S: String;
begin
for I := 1 to TMD_GetDriverServicesCount do
TMD_CreateDriverServiceButton(I, 'DriverServiceButton' + IntToStr(I));
end;
// Перепроверить видимость услуг.
procedure TMD_RecheckDriverServiceButtons;
var
I, J: Integer;
ServicePercent, ServiceId: Integer;
ServiceCost: Single;
ServiceName: String;
FoundService, CanRepeatService: Boolean;
IsPressedUnrepeatableButton: Boolean;
begin
for I := 1 to TMD_GetDriverServicesCount do
begin
TMD_GetServiceParamsByIndex(I, ServiceCost, ServicePercent, ServiceName,
ServiceId, CanRepeatService);
if ServiceId > 0 then
begin
WriteStr('Button', 'Select', 'DriverServiceButton' + IntToStr(I));
// Кнопку нажали один раз, запрещено нажимать повторно.
IsPressedUnrepeatableButton := not CanRepeatService and
(ReadInt('Temp', 'DriverServiceButton' + IntToStr(I)) = 1);
FoundService := False;
for J := 0 to ReadInt('OrderParamsCount') - 1 do
if ServiceId = ReadInt('OrderParamId', J) then
FoundService := True;
// В ТМ был добавлен атрибут с таким же ИД.
// Нужно сделать соответствующую кнопку невидимой.
if FoundService and
((ReadInt('Button', 'Visible') = 1) or IsPressedUnrepeatableButton) then
begin
WriteInt('Temp', 'DriverServiceButton' + IntToStr(I), 0);
WriteInt('Button', 'Visible', 0);
end
else
// В ТМ убрали атрибут.
// Нужно вновь сделать кнопку видимой.
if not FoundService and (ReadInt('Button', 'Visible') = 0) and
not IsPressedUnrepeatableButton then
WriteInt('Button', 'Visible', 1);
end;
end;
end;
// Взять сумму всех водительских услуг.
procedure TMD_GetDriverServicesSum(var DriverServicesSum: Single;
var DriverServicesPercent: Integer);
var
ServiceCost: Single;
ServicePercent: Integer;
ServiceName: String;
ServiceId, I, ServicesCount: Integer;
CanRepeatService: Boolean;
begin
DriverServicesSum := 0;
DriverServicesPercent := 0;
for I := 1 to TMD_GetDriverServicesCount do
begin
ServicesCount := ReadInt('Temp', 'DriverServiceButton' + IntToStr(I));
if ServicesCount > 0 then
begin
TMD_GetServiceParamsByIndex(I, ServiceCost, ServicePercent, ServiceName,
ServiceId, CanRepeatService);
DriverServicesSum := DriverServicesSum + ServicesCount * ServiceCost;
DriverServicesPercent := DriverServicesPercent + ServicesCount * ServicePercent;
end;
end;
end;
// Добавить в чек стоимость за водительские услуги.
procedure TMD_AddDriverServices;
var
ServiceName: String;
ServiceCost: Single;
I, ServicePercent, ServiceId, ServicesCount: Integer;
CanRepeatService: Boolean;
begin
for I := 1 to TMD_GetDriverServicesCount do
begin
ServicesCount := ReadInt('Temp', 'DriverServiceButton' + IntToStr(I));
if ServicesCount > 0 then
begin
TMD_GetServiceParamsByIndex(I, ServiceCost, ServicePercent, ServiceName,
ServiceId, CanRepeatService);
if ServicePercent <> 0 then
begin
WriteStr('Bill', 'Code', 'DRIVER_SERVICE_PERCENT_' + IntToStr(I));
WriteStr('Bill', 'Text', ServiceName);
WriteStr('Bill', 'Value', IntToStr(ServicesCount));
WriteStr('Bill', 'Sum', FloatToStr(ServicePercent * ServicesCount, 0) + '%');
end;
if ServiceCost <> 0 then
begin
WriteStr('Bill', 'Code', 'DRIVER_SERVICE_SUM_' + IntToStr(I));
WriteStr('Bill', 'Text', ServiceName);
WriteStr('Bill', 'Value', IntToStr(ServicesCount));
WriteStr('Bill', 'Sum', FloatToStr(ServiceCost * ServicesCount, 2));
end;
end;
end;
end;
// Добавить в чек стоимость за услуги (атрибуты/параметры).
procedure TMD_AddServices;
var
F: Single;
begin
F := ReadFloat('ServicesSum');
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'SERVICE_SUM');
WriteStr('Bill', 'Text', 'Услуги');
WriteStr('Bill', 'Value', ReadStr('ServicesName'));
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
F := ReadFloat('ServicesPercent');
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'SERVICE_PERCENT');
WriteStr('Bill', 'Text', 'Услуги');
WriteStr('Bill', 'Value', ReadStr('ServicesName'));
WriteStr('Bill', 'Sum', FloatToStr(F, 0) + '%');
end;
TMD_AddDriverServices;
end;
// Добавить в чек стоимость за скидки.
procedure TMD_AddDiscounts;
var
Sum, DiscountSum, DiscountPercent: Single;
begin
Sum := ReadFloat('Temp', 'SumBeforeDiscount');
WriteStr('Bill', 'Code', 'BEFORE_DISC');
WriteStr('Bill', 'Text', 'Сумма без скидки');
WriteStr('Bill', 'Sum', FloatToStr(Sum, 2));
DiscountSum := ReadFloat('TaxmTotalDiscSum');
if DiscountSum <> 0 then
begin
WriteStr('Bill', 'Code', 'DISC_SUM');
if DiscountSum < 0 then
WriteStr('Bill', 'Text', 'Наценка')
else
WriteStr('Bill', 'Text', 'Скидка');
WriteStr('Bill', 'Sum', FloatToStr(Abs(DiscountSum), 2));
end;
DiscountPercent := ReadFloat('TaxmTotalDiscPercent');
if DiscountPercent <> 0 then
begin
WriteStr('Bill', 'Code', 'DISC_PERCENT');
if DiscountPercent < 0 then
WriteStr('Bill', 'Text', 'Наценка')
else
WriteStr('Bill', 'Text', 'Скидка');
WriteStr('Bill', 'Sum', FloatToStr(Abs(DiscountPercent), 0) + '%');
end;
Sum := Sum - Sum * DiscountPercent / 100 - DiscountSum;
WriteStr('Bill', 'Code', 'AFTER_DISC');
WriteStr('Bill', 'Text', 'Сумма со скидкой');
WriteStr('Bill', 'Sum', FloatToStr(Sum, 2));
end;
function TMD_UseCalcTMRoute: Boolean;
begin
Result := USE_CALC_TM_ROUTE and (ReadInt('SupportedScriptVersion') >= 3);
end;
// Рассчитать стоимость за километраж с учётом маршрута из ТМ.
procedure TMD_RecalcDistSum;
var
DistanceSum: Single;
begin
if ReadInt('TMRouteReceiveTime') <> ReadInt('Temp', 'TMRouteReceiveTime') then
begin
WriteInt('Temp', 'TMRouteReceiveTime', ReadInt('TMRouteReceiveTime'));
if (ReadInt('Now') - ReadInt('TMRouteSendTime') <= CALC_TM_ROUTE_FINISH_TIMEOUT) and
(ReadFloat('TMRouteDistance') > 0) then
begin
if ReadFloat('TMRouteDistance') > ReadFloat('Temp', 'KmIncluded') then
begin
if ReadFloat('TMRouteCountryDistance') = 0 then
DistanceSum := (ReadFloat('TMRouteDistance') - ReadFloat('Temp', 'KmIncluded')) * CITY_KM_COST
else
if ReadFloat('TMRouteCityDistance') > ReadFloat('Temp', 'KmIncluded') then
DistanceSum := (ReadFloat('TMRouteCityDistance') - ReadFloat('Temp', 'KmIncluded')) * CITY_KM_COST +
ReadFloat('TMRouteCountryDistance') * COUNTRY_KM_COST
else
DistanceSum := (ReadFloat('TMRouteDistance') - ReadFloat('Temp', 'KmIncluded')) * COUNTRY_KM_COST;
end
else
DistanceSum := 0;
// Перезаписать сумму и километраж.
WriteFloat('Temp', 'DistanceSum', DistanceSum);
WriteFloat('Temp', 'TotalDist', ReadFloat('TMRouteDistance'));
WriteFloat('Temp', 'DistCity', ReadFloat('TMRouteCityDistance'));
WriteFloat('Temp', 'DistCountry', ReadFloat('TMRouteCountryDistance'));
WriteFloat('Temp', 'GPSLostDistSum', 0);
WriteFloat('Temp', 'GpsLostDistCountry', 0);
WriteFloat('Temp', 'GpsLostDistCity', 0);
WriteFloat('Temp', 'GpsLostKmDist', 0);
end;
end;
end;
// Заполнить дополнительную информацию по тарифу в таксометре.
procedure TMD_FillMoreInfo;
var
BoardingMoreInfo, CityMoreInfo, CountryMoreInfo: String;
HasKmCost, HasMinutesCost: Boolean;
begin
WriteStr('MoreInfo', 0, 'Тариф: ' + ReadStr('TariffName'));
if CALC_SUM_BY_TAXIMETER then
begin
if not ReadBool('IsHourly') then
begin
// Если задан хоть один параметр города или загорода, нужно будет выводить оба,
// даже если цена будет 0.
HasKmCost := (CITY_KM_COST <> 0) or (COUNTRY_KM_COST <> 0);
HasMinutesCost := (CITY_MINUTE_COST <> 0) or (COUNTRY_MINUTE_COST <> 0);
// Выводим подробный текст в поле посадки, если есть включенные км или минуты,
// с учетом того, что есть соответствующие цены.
if ((ReadFloat('Temp', 'KmIncluded') <> 0) and HasKmCost) or
((ReadFloat('Temp', 'MinutesIncluded') <> 0) and HasMinutesCost) then
begin
BoardingMoreInfo := 'Первые';
if HasKmCost then
BoardingMoreInfo := BoardingMoreInfo +
' ' + FloatToStr(ReadFloat('Temp', 'KmIncluded')) + ' км';
if HasMinutesCost then
BoardingMoreInfo := BoardingMoreInfo +
' ' + FloatToStr(ReadFloat('Temp', 'MinutesIncluded')) + ' мин';
CityMoreInfo := 'Далее город:';
CountryMoreInfo := 'Далее загород:';
end
else
// Иначе выводим обычный текст.
begin
BoardingMoreInfo := 'Посадка';
CityMoreInfo := 'Город:';
CountryMoreInfo := 'Загород:';
end;
// В конце строки посадки всегда пишем сумму посадки.
BoardingMoreInfo := BoardingMoreInfo +
': ' + FloatToStrFixed(ReadFloat('Temp', 'BoardingSum')) + ' ' + VALUTA;
// Если есть цена за км, либо вообще нет ни одной цены, то выводим цену за км.
if HasKmCost or not HasMinutesCost then
begin
CityMoreInfo := CityMoreInfo +
' ' + FloatToStrFixed(CITY_KM_COST) + ' ' + VALUTA + '/км';
CountryMoreInfo := CountryMoreInfo +
' ' + FloatToStrFixed(COUNTRY_KM_COST) + ' ' + VALUTA + '/км';
end;
// Если есть цена за минуты, то выводим ее.
// Если при этом была цена за км, то цена за минуты выводится дополнительно.
if HasMinutesCost then
begin
CityMoreInfo := CityMoreInfo +
' ' + FloatToStrFixed(CITY_MINUTE_COST) + ' ' + VALUTA + '/мин';
CountryMoreInfo := CountryMoreInfo +
' ' + FloatToStrFixed(COUNTRY_MINUTE_COST) + ' ' + VALUTA + '/мин';
end;
if IDLE_MINUTE_COST <> 0 then
WriteStr('MoreInfo', 1, 'Простой: ' +
FloatToStrFixed(IDLE_MINUTE_COST) + ' ' + VALUTA + '/мин');
if ReadFloat('Temp', 'MinSum') <> 0 then
WriteStr('MoreInfo', 2, 'Минимум: ' +
FloatToStrFixed(ReadFloat('Temp', 'MinSum')) + ' ' + VALUTA);
WriteStr('MoreInfo', 3, BoardingMoreInfo);
WriteStr('MoreInfo', 4, CityMoreInfo);
WriteStr('MoreInfo', 5, CountryMoreInfo);
end
else
begin
if MIN_HOURLY <> 0 then
WriteStr('MoreInfo', 1, 'Минимум: ' +
FloatToStrFixed(MIN_HOURLY) + ' ' + VALUTA);
if HOURLY_MINUTES_INCLUDED = 0 then
begin
WriteStr('MoreInfo', 3, 'Посадка: ' +
FloatToStrFixed(BOARDING_HOURLY) + ' ' + VALUTA);
if HOURLY_PERIOD > 0 then
WriteStr('MoreInfo', 4, IntToStr(HOURLY_PERIOD) + ' мин: ' +
FloatToStrFixed(HOURLY_MINUTE_COST * HOURLY_PERIOD) + ' ' + VALUTA)
else
WriteStr('MoreInfo', 4, '1 час: ' +
FloatToStrFixed(HOURLY_MINUTE_COST * 60) + ' ' + VALUTA);
end
else
begin
WriteStr('MoreInfo', 3, 'Первые ' + IntToStr(HOURLY_MINUTES_INCLUDED) + ' мин: ' +
FloatToStrFixed(BOARDING_HOURLY) + ' ' + VALUTA);
if HOURLY_PERIOD > 0 then
WriteStr('MoreInfo', 4, 'Далее ' + IntToStr(HOURLY_PERIOD) + ' мин: ' +
FloatToStrFixed(HOURLY_MINUTE_COST * HOURLY_PERIOD) + ' ' + VALUTA)
else
WriteStr('MoreInfo', 4, 'Далее 1 час: ' +
FloatToStrFixed(HOURLY_MINUTE_COST * 60) + ' ' + VALUTA);
end;
end;
end;
end;
// Рассчитать полную стоимость поездки.
procedure TMD_CalcTaximeterSum;
var
Sum, DriverServicesSum: Single;
DriverServicesPercent: Integer;
IsTripFinished: Boolean;
begin
Sum := 0;
TMD_RecheckDriverServiceButtons;
// Стоимость всех водительских услуг.
TMD_GetDriverServicesSum(DriverServicesSum, DriverServicesPercent);
if CALC_SUM_BY_TAXIMETER then
begin
IsTripFinished := ReadInt('Temp', 'TripFinished') = 1;
Sum := Sum + ReadFloat('Temp', 'PayWaitTimeSum') +
ReadFloat('Temp', 'PriorOrderCost') +
ReadFloat('Temp', 'SourceDistCountrySum') +
ReadFloat('Temp', 'BoardingSum');
if ReadBool('IsHourly') then
Sum := Sum + ReadFloat('Temp', 'TripTimeSum') +
ReadFloat('Temp', 'HourlyDistSum')
else
begin
if not IsTripFinished and TMD_UseCalcTMRoute then
TMD_RecalcDistSum;
Sum := Sum + ReadFloat('Temp', 'DistanceSum') +
ReadFloat('Temp', 'CityTripTimeSum') +
ReadFloat('Temp', 'CountryTripTimeSum') +
ReadFloat('Temp', 'GPSLostDistSum') +
ReadFloat('Temp', 'IdleTimeSum') +
ReadFloat('Temp', 'StopsSum') +
ReadFloat('Temp', 'StopTimeSum');
end;
if not USE_REAL_ZONES_IN_TAXM then
Sum := Sum + ReadFloat('TaxmZonesSum')
else
Sum := Sum + ReadFloat('Temp', 'ZoneStopSum') +
ReadFloat('Temp', 'ZonePathSum') +
ReadFloat('Temp', 'ZoneInCost') +
ReadFloat('Temp', 'ZoneOutCost');
if not SERVICES_AFTER_MIN then
begin
if IsTripFinished then
TMD_AddServices;
Sum := Sum + ReadFloat('ServicesSum') + DriverServicesSum +
Sum * (DriverServicesPercent + ReadFloat('ServicesPercent')) / 100;
end;
// Сумма без скидки.
// Работает только для Android.
if ReadStr('Platform') = 'Android' then
WriteFloat('Sum', RoundSum(Sum));
if not DISCOUNT_AFTER_MIN then
begin
WriteFloat('Temp', 'SumBeforeDiscount', Sum);
if IsTripFinished then
TMD_AddDiscounts;
Sum := Sum - Sum * ReadFloat('TaxmTotalDiscPercent') / 100 -
ReadFloat('TaxmTotalDiscSum');
end;
if not ReadBool('IsHourly') and not ReadBool('IsCountry') then
if (ReadInt('Temp', 'WasOutCity') = 0) and not ReadBool('InCity') then
begin
WriteInt('Temp', 'WasOutCity', 1);
WriteFloat('Temp', 'MinSum', MIN_COUNTRY);
WriteStr('MoreInfo', 2, 'Минимум: ' +
FloatToStrFixed(MIN_COUNTRY) + ' ' + VALUTA);
end;
if IsTripFinished then
begin
WriteStr('Bill', 'Code', 'MINIMUM');
WriteStr('Bill', 'Text', 'Минимум');
WriteStr('Bill', 'Sum', FloatToStr(ReadFloat('Temp', 'MinSum'), 2));
end;
if (not MIN_SUM_AFTER_CALC) or (ReadInt('Temp', 'TripFinished') = 1) then
if WAITING_INCLUDED then
Sum := Max(ReadFloat('Temp', 'MinSum'), Sum)
else
Sum := Max(ReadFloat('Temp', 'MinSum') + ReadFloat('Temp', 'PayWaitTimeSum'), Sum);
if SERVICES_AFTER_MIN then
begin
if IsTripFinished then
TMD_AddServices;
Sum := Sum + ReadFloat('ServicesSum') + DriverServicesSum +
Sum * (DriverServicesPercent + ReadFloat('ServicesPercent')) / 100;
end;
if DISCOUNT_AFTER_MIN then
begin
WriteFloat('Temp', 'SumBeforeDiscount', Sum);
if IsTripFinished then
TMD_AddDiscounts;
Sum := Sum - Sum * ReadFloat('TaxmTotalDiscPercent') / 100 -
ReadFloat('TaxmTotalDiscSum');
end;
end
else
begin
WriteStr('Caption', '');
Sum := ReadFloat('OperSum');
Sum := Sum + DriverServicesSum + Sum * DriverServicesPercent / 100;
if USE_STOPS_WAITING_IDLE then
Sum := Sum + ReadFloat('Temp', 'PayWaitTimeSum') +
ReadFloat('Temp', 'IdleTimeSum') +
ReadFloat('Temp', 'StopsSum') +
ReadFloat('Temp', 'StopTimeSum');
WriteFloat('Sum', RoundSum(Sum));
end;
Sum := RoundSum(Sum);
// Итоговая сумма со скидкой.
WriteFloat('TotalSum', Sum);
// Для ios надо заполнить параметр Sum.
if (ReadStr('Platform') <> 'Android') and CALC_SUM_BY_TAXIMETER then
WriteFloat('Sum', Sum);
WriteStr('SumStr', FloatToStrFixed(Sum));
WriteFloat('CurrentSum', Sum);
end;
// ***************
// Начало расчета.
// ***************
procedure InitCalc;
var
F, MinSum, Boarding, KmIncluded, MinutesIncluded: Single;
begin
TMD_InitDriverServiceButtons;
F := ReadFloat('Temp', 'PayWaitTimeSum');
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'WAITING_TIME');
WriteStr('Bill', 'Text', 'Ожидание');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('WaitTime')));
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
if CALC_SUM_BY_TAXIMETER then
begin
if ReadBool('IsPrior') and (PRIOR_ORDER_COST <> 0) then
begin
WriteStr('Bill', 'Code', 'PRIOR_ORDER');
WriteStr('Bill', 'Text', 'Предварительный');
WriteStr('Bill', 'Sum', FloatToStr(PRIOR_ORDER_COST, 2));
WriteFloat('Temp', 'PriorOrderCost', PRIOR_ORDER_COST);
end;
F := ReadFloat('SourceDistCountry') * SOURCE_COUNTRY_KM_COST;
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'SOURCE_COUNTRY_DIST');
WriteStr('Bill', 'Text', 'До подачи загород');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('SourceDistCountry'), 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'SourceDistCountrySum', F);
end;
if not ReadBool('IsHourly') then
begin
if TMD_UseCalcTMRoute then
begin
WriteInt('UseCalcTMRoute', 1);
WriteInt('CalcTMRoutePeriodSec', CALC_TM_ROUTE_PERIOD);
ReadInt('Temp', 'TMRouteReceiveTime', 0);
end;
if ReadBool('IsCountry') or not ReadBool('InCity') then
begin
Boarding := BOARDING_COUNTRY;
KmIncluded := COUNTRY_KM_INCLUDED;
MinutesIncluded := COUNTRY_MINUTES_INCLUDED;
MinSum := MIN_COUNTRY;
WriteInt('Temp', 'WasOutCity', 1);
end
else
begin
Boarding := BOARDING_CITY;
KmIncluded := CITY_KM_INCLUDED;
MinutesIncluded := CITY_MINUTES_INCLUDED;
MinSum := MIN_CITY;
WriteInt('Temp', 'WasOutCity', 0);
end;
WriteFloat('Temp', 'KmIncluded', KmIncluded);
WriteFloat('Temp', 'MinutesIncluded', MinutesIncluded);
end
else
begin
Boarding := BOARDING_HOURLY;
MinSum := MIN_HOURLY;
end;
WriteFloat('Temp', 'BoardingSum', Boarding);
WriteFloat('Temp', 'MinSum', MinSum);
// Определяем район по фактическим координатам.
if USE_REAL_ZONES_IN_TAXM then
begin
// Посадка в районе.
if USE_ZONE_COST then
begin
F := ReadFloat('ZoneInCost', ReadInt('ZoneId'));
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONE_IN');
WriteStr('Bill', 'Text', 'Посадка ' +
'"' + ReadStr('ZoneName') + '"');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'ZoneInCost', F);
end;
end;
// Сохраняем текущий район.
WriteInt('Temp', 'LastZoneId', ReadInt('ZoneId'));
end;
end;
TMD_CalcTaximeterSum;
TMD_FillMoreInfo;
WriteInt('Temp', 'AllStopTime', 0);
WriteFloat('Temp', 'StopTimeSum', 0);
end;
// Использовать восстановление километража при потере GPS.
function TMD_UseGPSMissedDistanceRecovery: Boolean;
begin
Result := USE_GPS_MISSED_DISTANCE_RECOVERY and
(ReadInt('SupportedScriptVersion') > 0);
end;
// Пересчитать параметры, связанные с координатами.
procedure TMD_RecalcLostGPSParams;
var
Lat, Lon, CurTotalDistance, KmCost, DistDelta: Single;
begin
Lon := ReadFloat('Lon');
Lat := ReadFloat('Lat');
// Посчитать километраж по прямой, если появились координаты.
if (ReadInt('Temp', 'IsLostGPS') = 1) and
((ReadFloat('Temp', 'OldLat') > 0) or
(ReadFloat('Temp', 'OldLon') > 0)) and
((Lat > 0) or (Lon > 0)) then
begin
DistDelta := SegmentLength(ReadFloat('Temp', 'OldLon'),
ReadFloat('Temp', 'OldLat'), Lon, Lat);
WriteFloat('Temp', 'GpsLostKmDist',
ReadFloat('Temp', 'GpsLostKmDist') + DistDelta);
CurTotalDistance := ReadFloat('Temp', 'TotalDist') + DistDelta;
// При восстанавлении координат не успевает правильно
// определиться флаг ReadBool('InCity').
if ReadInt('Temp', 'OldInCity') > 0 then
begin
WriteFloat('Temp', 'GpsLostDistCity',
ReadFloat('Temp', 'GpsLostDistCity') + DistDelta);
KmCost := CITY_KM_COST;
end
else
begin
WriteFloat('Temp', 'GpsLostDistCountry',
ReadFloat('Temp', 'GpsLostDistCountry') + DistDelta);
KmCost := COUNTRY_KM_COST;
end;
if CurTotalDistance > ReadFloat('Temp', 'KmIncluded') then
begin
// Если при восстановлении координат сразу закончился
// включенный киломтраж.
if ReadFloat('Temp', 'TotalDist') < ReadFloat('Temp', 'KmIncluded') then
// Платный километраж.
DistDelta := CurTotalDistance - ReadFloat('Temp', 'KmIncluded');
WriteFloat('Temp', 'GPSLostDistSum',
ReadFloat('Temp', 'GPSLostDistSum') + KmCost * DistDelta);
end;
end;
// Пропал сигнал GPS.
if (Lat = 0) and (Lon = 0) then
WriteInt('Temp', 'IsLostGPS', 1)
else
// Есть сигнал GPS.
begin
WriteFloat('Temp', 'OldLat', Lat);
WriteFloat('Temp', 'OldLon', Lon);
if ReadBool('InCity') then
WriteInt('Temp', 'OldInCity', 1)
else
WriteInt('Temp', 'OldInCity', 0);
WriteInt('Temp', 'IsLostGPS', 0);
end;
end;
// *******
// Расчёт.
// *******
procedure StepCalc;
var
F, DistDelta, TripDistance: Single;
City: String;
Seconds: Integer;
begin
if CALC_SUM_BY_TAXIMETER then
begin
if ReadBool('HasCities') then
begin
if ReadBool('InCity') then
City := ' [' + ReadStr('CityName') + ']'
else
City := ' [загород]';
end;
DistDelta := ReadFloat('DistDelta');
if ReadBool('IsHourly') then
begin
WriteStr('Caption', 'ЧАС' + City);
if ReadInt('TripTime') > HOURLY_MINUTES_INCLUDED * 60 then
begin
if HOURLY_PERIOD = 0 then
F := HOURLY_MINUTE_COST / 60
else
if Floor((ReadInt('TripTime') - HOURLY_MINUTES_INCLUDED * 60 - 1) /
60 / HOURLY_PERIOD) * HOURLY_PERIOD * 60 =
ReadInt('TripTime') - HOURLY_MINUTES_INCLUDED * 60 - 1 then
F := HOURLY_PERIOD * HOURLY_MINUTE_COST
else
F := 0;
if F <> 0 then
begin
WriteFloat('Temp', 'TripTimeSum',
ReadFloat('Temp', 'TripTimeSum') + F);
end;
end;
if HOURLY_KM_COST > 0 then
begin
F := 0;
if HOURLY_HOUR_KM_INCLUDED > 0 then
begin
// Ещё один час закончился.
if ReadInt('TripTime') mod (60 * 60) = 0 then
WriteFloat('Temp', 'DistHour', 0);
WriteFloat('Temp', 'DistHour',
ReadFloat('Temp', 'DistHour') + DistDelta);
if ReadFloat('Temp', 'DistHour') > HOURLY_HOUR_KM_INCLUDED then
F := DistDelta * HOURLY_KM_COST;
end
else
if HOURLY_TRIP_KM_INCLUDED > 0 then
begin
if ReadFloat('TripDistance') > HOURLY_TRIP_KM_INCLUDED then
F := DistDelta * HOURLY_KM_COST;
end
else
F := DistDelta * HOURLY_KM_COST;
if F <> 0 then
begin
WriteFloat('Temp', 'HourlyDist',
ReadFloat('Temp', 'HourlyDist') + DistDelta);
WriteFloat('Temp', 'HourlyDistSum',
ReadFloat('Temp', 'HourlyDistSum') + F);
end;
end;
end
else
begin
WriteFloat('Temp', 'TotalDist',
ReadFloat('Temp', 'TotalDist') + DistDelta);
// Если скорость достаточная, считать по километражу.
if ReadFloat('Speed') > SPEED_LIMIT then
begin
WriteStr('Caption', 'КМ' + City);
TripDistance := ReadFloat('Temp', 'TotalDist') + ReadFloat('Temp', 'GpsLostDistCountry') +
ReadFloat('Temp', 'GpsLostDistCity');
if not ReadBool('InCity') then
begin
WriteFloat('Temp', 'DistCountry',
ReadFloat('Temp', 'DistCountry') + DistDelta);
if TripDistance > ReadFloat('Temp', 'KmIncluded') then
begin
WriteFloat('Temp', 'DistanceSum',
ReadFloat('Temp', 'DistanceSum') + COUNTRY_KM_COST * DistDelta);
end;
end
else
begin
WriteFloat('Temp', 'DistCity',
ReadFloat('Temp', 'DistCity') + DistDelta);
if TripDistance > ReadFloat('Temp', 'KmIncluded') then
begin
WriteFloat('Temp', 'DistanceSum',
ReadFloat('Temp', 'DistanceSum') + CITY_KM_COST * DistDelta);
end;
end;
end;
if (COUNTRY_MINUTE_COST <> 0) or (CITY_MINUTE_COST <> 0) then
if not ReadBool('InCity') then
begin
WriteInt('Temp', 'CountryTripTime',
ReadInt('Temp', 'CountryTripTime') + 1);
if ReadInt('TripTime') > ReadFloat('Temp', 'MinutesIncluded') * 60 then
WriteFloat('Temp', 'CountryTripTimeSum',
ReadFloat('Temp', 'CountryTripTimeSum') + COUNTRY_MINUTE_COST / 60);
end
else
begin
WriteInt('Temp', 'CityTripTime',
ReadInt('Temp', 'CityTripTime') + 1);
if ReadInt('TripTime') > ReadFloat('Temp', 'MinutesIncluded') * 60 then
WriteFloat('Temp', 'CityTripTimeSum',
ReadFloat('Temp', 'CityTripTimeSum') + CITY_MINUTE_COST / 60);
end;
if TMD_UseGPSMissedDistanceRecovery then
TMD_RecalcLostGPSParams;
end;
end;
if TMD_UseCalcStopsIdle then
begin
if ReadFloat('Speed') > SPEED_LIMIT then
WriteInt('Temp', 'LastKMTime', ReadInt('TripTime'))
else
if ReadInt('TripTime') - ReadInt('Temp', 'LastKMTime') > FREE_IDLE_TIME then
begin
WriteStr('Caption', 'Простой');
WriteInt('Temp', 'IdleTime',
ReadInt('Temp', 'IdleTime') + 1);
WriteFloat('Temp', 'IdleTimeSum',
ReadFloat('Temp', 'IdleTimeSum') + IDLE_MINUTE_COST / 60);
end
else
begin
Seconds := FREE_IDLE_TIME -
(ReadInt('TripTime') - ReadInt('Temp', 'LastKMTime'));
WriteStr('Caption', 'Ожидание (' + IntToStr(Seconds) + ')' + City);
end;
end;
TMD_CalcTaximeterSum;
end;
// *****************
// Начало остановки.
// *****************
procedure StartStop;
var
F: Single;
begin
if CALC_SUM_BY_TAXIMETER then
begin
WriteStr('Caption', 'Остановка');
WriteInt('UseZonesPathGroupId', ZONES_PATH_GROUP_ID);
// Определяем район по фактическим координатам.
if USE_REAL_ZONES_IN_TAXM then
begin
if ReadInt('ZoneId') <> ReadInt('Temp', 'LastZoneId') then
// Сохраняем признак, что покидали район посадки.
WriteInt('Temp', 'NeedZoneOutCost', 1);
// Проезды между районами
if (USE_ZONE_PATH) and (ReadInt('ZoneId') > 0) then
begin
F := ReadFloat('ZonePathCost',
ReadInt('Temp', 'LastZoneId'), ReadInt('ZoneId'));
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONES_PATH');
WriteStr('Bill', 'Text', 'Проезд ' + '"' +
ReadStr('ZoneName', ReadInt('Temp', 'LastZoneId')) +
'"-"' + ReadStr('ZoneName') + '"');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'ZonePathSum',
ReadFloat('Temp', 'ZonePathSum') + F);
end;
end;
// Сохраняем текущий район.
WriteInt('Temp', 'LastZoneId', ReadInt('ZoneId'));
// Остановка в районе.
if USE_ZONE_COST then
begin
F := ReadFloat('ZoneStopCost', ReadInt('ZoneId'));
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONES_STOP');
WriteStr('Bill', 'Text', 'Остановка ' +
'"' + ReadStr('ZoneName') + '"');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'ZoneStopSum',
ReadFloat('Temp', 'ZoneStopSum') + F);
end;
end;
end;
end;
if TMD_UseCalcStopsIdle then
begin
WriteInt('Temp', 'StopTime', 0);
WriteInt('Temp', 'StopsCount',
ReadInt('Temp', 'StopsCount') + 1);
WriteFloat('Temp', 'StopsSum',
ReadFloat('Temp', 'StopsSum') + MIN_STOP_COST);
end;
TMD_CalcTaximeterSum;
end;
// **********
// Остановка.
// **********
procedure StepCalcStop;
var
StopTime: Integer;
Sum: Single;
begin
if not TMD_UseCalcStopsIdle then
StepCalc
else
begin
WriteFloat('Temp', 'TotalDist',
ReadFloat('Temp', 'TotalDist') + ReadFloat('DistDelta'));
if TMD_UseGPSMissedDistanceRecovery then
TMD_RecalcLostGPSParams;
if STOP_MINUTE_COST <> 0 then
begin
StopTime := ReadInt('Temp', 'StopTime') + 1;
if StopTime > (STOP_MINUTES_INCLUDED * 60) then
begin
WriteFloat('Temp', 'StopTimeSum',
ReadFloat('Temp', 'StopTimeSum') + STOP_MINUTE_COST / 60);
TMD_CalcTaximeterSum;
end;
WriteInt('Temp', 'StopTime', StopTime);
WriteInt('Temp', 'AllStopTime',
ReadInt('Temp', 'AllStopTime') + 1);
end;
end;
end;
// ****************
// Конец остановки.
// ****************
procedure EndStop;
begin
WriteStr('Caption', '');
end;
// ****************
// Обработка дополнительных функциональных кнопок.
// ****************
procedure ButtonClick;
var
ButtonName, ServiceName: String;
Sum, ServiceSum, PercentSum: Single;
I, ServicePercent, ServiceId: Integer;
CanRepeatService: Boolean;
begin
ButtonName := ReadStr('Button', 'Clicked');
for I := 1 to TMD_GetDriverServicesCount do
if ButtonName = 'DriverServiceButton' + IntToStr(I) then
begin
TMD_GetServiceParamsByIndex(I, ServiceSum, ServicePercent, ServiceName,
ServiceId, CanRepeatService);
if CanRepeatService then
WriteInt('Temp', 'DriverServiceButton' + IntToStr(I),
ReadInt('Temp', 'DriverServiceButton' + IntToStr(I)) + 1)
else
begin
WriteInt('Temp', 'DriverServiceButton' + IntToStr(I), 1);
WriteStr('Button', 'Select', ButtonName);
WriteInt('Button', 'Visible', 0);
end;
end;
TMD_CalcTaximeterSum;
end;
// Добавить в чек стоимость за восстановленный километраж.
procedure TMD_AddGPSParams;
begin
if TMD_UseGPSMissedDistanceRecovery and
(ReadFloat('Temp', 'GpsLostKmDist') > 0) then
begin
if ReadFloat('Temp', 'GPSLostDistCity') > 0 then
begin
WriteStr('Bill', 'Code', 'CITY_LOST_GPS_DIST');
WriteStr('Bill', 'Text', 'По городу при отсутствии GPS');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'GPSLostDistCity'), 2) + ' км');
end;
if ReadFloat('Temp', 'GPSLostDistCountry') > 0 then
begin
WriteStr('Bill', 'Code', 'COUNTRY_LOST_GPS_DIST');
WriteStr('Bill', 'Text', 'За городом при отсутствии GPS');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'GPSLostDistCountry'), 2) + ' км');
end;
end;
end;
// Добавить в чек стоимость за простой, ожидание, остановки.
procedure TMD_AddTimeParams;
begin
WriteStr('Bill', 'Code', 'IDLE_TIME');
WriteStr('Bill', 'Text', 'Простой');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('Temp', 'IdleTime')));
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'IdleTimeSum'), 2));
if ReadInt('Temp', 'StopsCount') > 0 then
begin
WriteStr('Bill', 'Code', 'STOPS');
WriteStr('Bill', 'Text', 'Остановки');
WriteStr('Bill', 'Value',
IntToStr(ReadInt('Temp', 'StopsCount')) + ' шт');
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'StopsSum'), 2));
if (STOP_MINUTE_COST <> 0) and (ReadFloat('Temp', 'StopTimeSum') <> 0) then
begin
WriteStr('Bill', 'Code', 'STOPS_TIME');
WriteStr('Bill', 'Text', 'Длит. остановок');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('Temp', 'AllStopTime')));
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'StopTimeSum'), 2));
end;
end;
end;
// *******************
// Завершение расчета.
// *******************
procedure TermCalc;
var
F: Single;
begin
WriteInt('Temp', 'TripFinished', 1);
if CALC_SUM_BY_TAXIMETER then
begin
WriteInt('UseZonesPathGroupId', ZONES_PATH_GROUP_ID);
if not USE_REAL_ZONES_IN_TAXM then
begin
F := ReadFloat('TaxmZonesSum');
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONES');
WriteStr('Bill', 'Text', 'Районы');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end
else
begin
// Перед высадкой проверяем проезды между районами
if (USE_ZONE_PATH) and (ReadInt('ZoneId') > 0) then
begin
F := ReadFloat('ZonePathCost',
ReadInt('Temp', 'LastZoneId'), ReadInt('ZoneId'));
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONES_PATH');
WriteStr('Bill', 'Text', 'Проезд ' + '"' +
ReadStr('ZoneName', ReadInt('Temp', 'LastZoneId')) +
'"-"' + ReadStr('ZoneName') + '"');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'ZonePathSum',
ReadFloat('Temp', 'ZonePathSum') + F);
end;
end;
// Высадка в районе.
if USE_ZONE_COST and (ReadInt('ZoneId') > 0) and
((ReadInt('ZoneId') <> ReadInt('Temp', 'LastZoneId')) or
(ReadInt('Temp', 'NeedZoneOutCost') = 1)) then
begin
F := ReadFloat('ZoneOutCost', ReadInt('ZoneId'));
if F <> 0 then
begin
WriteStr('Bill', 'Code', 'ZONES_OUT');
WriteStr('Bill', 'Text', 'Высадка ' +
'"' + ReadStr('ZoneName') + '"');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
WriteFloat('Temp', 'ZoneOutCost', F);
end;
end;
end;
if ReadBool('IsHourly') then
begin
WriteStr('Bill', 'Code', 'TRIP_TIME');
WriteStr('Bill', 'Text', 'Общее время');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('TripTime')));
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'TripTimeSum') + ReadFloat('Temp', 'BoardingSum'), 2));
WriteStr('Bill', 'Code', 'TRIP_DIST');
WriteStr('Bill', 'Text', 'Общее расстояние');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('TripDistance'), 2) + ' км');
F := ReadFloat('Temp', 'HourlyDistSum');
if F > 0 then
begin
WriteStr('Bill', 'Code', 'HOURLY_PAY_DIST');
WriteStr('Bill', 'Text', 'Платный километраж');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'HourlyDist'), 2) + ' км');
WriteStr('Bill', 'Sum', FloatToStr(F, 2));
end;
end
else
begin
if TMD_UseCalcTMRoute then
TMD_RecalcDistSum;
WriteStr('Bill', 'Code', 'TRIP_TIME');
WriteStr('Bill', 'Text', 'Общее время');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('TripTime')));
if CITY_MINUTE_COST <> 0 then
begin
WriteStr('Bill', 'Code', 'CITY_TRIP_TIME');
WriteStr('Bill', 'Text', 'Время по городу');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('Temp', 'CityTripTime')));
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'CityTripTimeSum'), 2));
end;
if COUNTRY_MINUTE_COST <> 0 then
begin
WriteStr('Bill', 'Code', 'COUNTRY_TRIP_TIME');
WriteStr('Bill', 'Text', 'Время за городом');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('Temp', 'CountryTripTime')));
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'CountryTripTimeSum'), 2));
end;
WriteStr('Bill', 'Code', 'TRIP_DIST');
WriteStr('Bill', 'Text', 'Общее расстояние');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'TotalDist'), 2) + ' км');
WriteStr('Bill', 'Sum',
FloatToStr(ReadFloat('Temp', 'BoardingSum') +
ReadFloat('Temp', 'DistanceSum') +
ReadFloat('Temp', 'GPSLostDistSum'), 2));
WriteStr('Bill', 'Code', 'CITY_DIST');
WriteStr('Bill', 'Text', 'По городу');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'DistCity'), 2) + ' км');
WriteStr('Bill', 'Code', 'COUNTRY_DIST');
WriteStr('Bill', 'Text', 'За городом');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('Temp', 'DistCountry'), 2) + ' км');
TMD_AddGPSParams;
TMD_AddTimeParams;
end;
TMD_CalcTaximeterSum;
end
else
begin
WriteStr('Bill', 'Code', 'TRIP_TIME');
WriteStr('Bill', 'Text', 'Общее время');
WriteStr('Bill', 'Value',
TimeLenToStr(ReadInt('TripTime')));
WriteStr('Bill', 'Code', 'TRIP_DIST');
WriteStr('Bill', 'Text', 'Общее расстояние');
WriteStr('Bill', 'Value',
FloatToStr(ReadFloat('TripDistance'), 2) + ' км');
WriteStr('Bill', 'Code', 'OPER_SUM');
WriteStr('Bill', 'Text', 'Сумма оператора');
WriteStr('Bill', 'Sum', FloatToStr(ReadFloat('OperSum'), 2));
if USE_STOPS_WAITING_IDLE then
TMD_AddTimeParams;
TMD_AddDriverServices;
TMD_CalcTaximeterSum;
WriteStr('Bill', 'Code', 'AFTER_DISC');
WriteStr('Bill', 'Text', 'Сумма');
if ReadStr('Platform') = 'Android' then
WriteStr('Bill', 'Sum', FloatToStr(ReadFloat('TotalSum'), 2))
else
WriteStr('Bill', 'Sum', FloatToStr(ReadFloat('Sum'), 2));
end;
end;
// *****************************************************************
// Добавить строку в чек. В конец строки вставляется перенос строки.
// *****************************************************************
procedure AddLine(Line: String);
begin
WriteStr('PrintCheck', 'Text', Line);
end;
// ******************************************
// Добавить в чек строку типа текст/значение.
// ******************************************
procedure AddLineTextValue(Line: String; Value: String);
begin
WriteStr('PrintCheck', 'Text', Line);
WriteStr('PrintCheck', 'Value', Value);
end;
// ******************************************
// Добавить в чек строку типа текст/значение для стоимости.
// ******************************************
procedure AddTextCostValue(Line: String; Value: Single);
begin
WriteStr('PrintCheck', 'Text', Line);
WriteStr('PrintCheck', 'Value', '=' + FloatToStr(Value, 2));
end;
// ******************************************
// Добавить в чек строку типа текст/значение с проверкой на 0.
// ******************************************
procedure AddTextNotNullValue(Line: String; Value: Single);
begin
if Value <> 0 then
AddTextCostValue(Line, Value);
end;
// ******************************
// Добавить перенос строки в чек.
// ******************************
procedure AddLineBreak;
begin
WriteStr('PrintCheck', 'BreakLine');
end;
// ******************************
// Получить текущую дату и время в виде строки.
// ******************************
function GetDateTimeStr(DT: Integer): String;
var
TmpStr: String;
D, M, Y, DW, H, S, I: Integer;
begin
TmpStr := '';
ExtractDate(DT, D, M, Y, DW);
if D < 10 then
TmpStr := TmpStr + '0';
TmpStr := TmpStr + IntToStr(D) + '.';
if M < 10 then
TmpStr := TmpStr + '0';
TmpStr := TmpStr + IntToStr(M) + '.';
Y := Y mod 100;
if Y < 10 then
TmpStr := TmpStr + '0';
TmpStr := TmpStr + IntToStr(y) + ' ';
ExtractTime(ReadInt('Now'), H, M, S);
if H < 10 then
TmpStr := TmpStr + '0';
TmpStr := TmpStr + IntToStr(H) + ':';
if M < 10 then
TmpStr := TmpStr + '0';
TmpStr := TmpStr + IntToStr(M);
Result := TmpStr;
end;
// ******************************
// Сформировать QR-код.
// ******************************
function GetQrCode: String;
var
D, M, Y, DW, H, MM, S, I: Integer;
QR: String;
begin
ExtractDate(ReadInt('FiscalInfo', 'CompleteTime'), D, M, Y, DW);
ExtractTime(ReadInt('FiscalInfo', 'CompleteTime'), H, MM, S);
QR := 't=' +IntToStr(Y) + IntToStr(M) + IntToStr(D) + 'T' + IntToStr(H) +
IntToStr(MM);
QR := QR + '&s=' + FloatToStr(ReadFloat('BankCardSum') + ReadFloat('CashSum'), 2);
QR := QR + '&fn=' + ReadStr('FiscalInfo', 'FiscalNumber');
QR := QR + '&i=' + IntToStr(ReadInt('FiscalInfo', 'FiscalDocumentNumber'));
QR := QR + '&fp=' + ReadStr('FiscalInfo', 'FiscalDocumentSign');
QR := QR + '&n=1';
Result := QR;
end;
// ************
// Печать чека.
// ************
procedure PrintCheck;
var
I: Integer;
TmpStr, PrinterModel, Encoding: String;
ServicePercent, SumServicePercent, NdsSum, FiscalSum, DiscountSum: Single;
begin
WriteStr('PrintCheck', 'Align', '0');
AddLine(TAXI_NAME);
AddLine('т. ' + TAXI_PHONE);
AddLineBreak;
AddLine('БЛАГОДАРИМ ВАС');
AddLine('ЗА ОБРАЩЕНИЕ В НАШУ КОМПАНИЮ!');
AddLineBreak;
// Детализация поездки
if NEED_DETAILS_IN_CHECK then
begin
if not ReadBool('IsBorder') then
AddLine('Заказ #' + IntToStr(ReadInt('OrderId')))
else
AddLine('Бордюрный заказ');
AddLine('Тариф: ' + ReadStr('TariffName'));
if not ReadBool('IsBorder') then
AddLine('Адрес: ' + ReadStr('SourceAddress'));
AddLine('Водитель: ' + ReadStr('DriverName'));
AddLine('Машина: ' + ReadStr('CarColor') + ' ' +
ReadStr('CarMark') + ' ' + ReadStr('CarModel') + ' ' + ReadStr('CarGosnumber'));
AddLineBreak;
AddLine('Километраж: ' + FloatToStr(ReadFloat('TripDistance'), 2) + ' км');
AddLine('Длительность: ' + TimeLenToStr(ReadInt('TripTime')));
AddLineBreak;
if CALC_SUM_BY_TAXIMETER then
begin
AddLine('Услуга Сумма');
AddLine('--------------------------------');
AddTextNotNullValue('Доезд до адреса подачи',
ReadFloat('Temp', 'SourceDistCountrySum'));
AddTextNotNullValue('Ожидание', ReadFloat('Temp', 'PayWaitTimeSum'));
AddTextNotNullValue('Посадка', ReadFloat('Temp', 'BoardingSum'));
AddTextNotNullValue('Районы', ReadFloat('TaxmZonesSum'));
if ReadBool('IsHourly') then
begin
AddTextNotNullValue('Поездка', ReadFloat('Temp', 'TripTimeSum'));
end
else
begin
AddTextNotNullValue('По городу', ReadFloat('Temp', 'DistanceSum'));
AddTextNotNullValue('За городом', ReadFloat('Temp', 'DistCountrySum'));
if ReadFloat('Temp', 'CityTripTimeSum') <> 0 then
AddTextNotNullValue('Время по городу', ReadFloat('Temp', 'CityTripTimeSum'));
if ReadFloat('Temp', 'CountryTripTimeSum') <> 0 then
AddTextNotNullValue('Время за городом', ReadFloat('Temp', 'CountryTripTimeSum'));
AddTextNotNullValue('Простой', ReadFloat('Temp', 'IdleTimeSum'));
AddTextNotNullValue('Остановки', ReadFloat('Temp', 'StopsSum'));
end;
if ReadFloat('ServicesSum') <> 0 then
begin
for I := 0 to ReadInt('ServiceCount') - 1 do
AddTextNotNullValue(ReadStr('ServiceName', ReadInt('OrderServiceId', I)),
ReadFloat('ServiceSum', ReadInt('OrderServiceId', I)));
end;
if ReadFloat('ServicesPercent') <> 0 then
begin
for I := 0 to ReadInt('ServiceCount') - 1 do
if ReadFloat('ServicePercent', ReadInt('OrderServiceId', I)) <> 0 then
begin
ServicePercent := ReadFloat('ServicePercent', ReadInt('OrderServiceId', I));
SumServicePercent := ServicePercent * ReadFloat('Temp', 'Check_SumBeforeServices') / 100;
AddTextNotNullValue(
ReadStr('ServiceName', ReadInt('OrderServiceId', I)) + ' ' + FloatToStr(ServicePercent, 0) + '%',
SumServicePercent);
end;
end;
end;
AddLineTextValue('',
'==' + FloatToStr(ReadFloat('Temp', 'SumBeforeDiscount'), 2));
if ReadFloat('Temp', 'Check_DiscountSum') <> 0 then
begin
AddLine('--------------------------------');
if ReadFloat('Temp', 'Check_DiscountSum') > 0 then
AddTextCostValue('Скидка', ReadFloat('Temp', 'Check_DiscountSum'))
else
AddTextCostValue('Наценка', -ReadFloat('Temp', 'Check_DiscountSum'));
AddTextCostValue('', ReadFloat('Temp', 'Check_SumAfterDiscount'));
end;
end;
AddLine( '================================');
if CALC_SUM_BY_TAXIMETER and NEED_DETAILS_IN_CHECK then
AddTextNotNullValue('Минимум', ReadFloat('Temp', 'MinSum'));
if not NEED_DETAILS_IN_CHECK then
AddLine('ПОЕЗДКА');
AddLineTextValue('ИТОГО К ОПЛАТЕ',
'==' + FloatToStr(ReadFloat('Temp', 'Check_TotalSum'), 2));
AddLineTextValue('Наличными',
'==' + FloatToStr(ReadFloat('CashSum'), 2));
AddLineBreak;
AddLine(GetDateTimeStr(ReadInt('Now')) + ' ИНН ' + TAXI_INN);
AddLineBreak;
AddLineBreak;
// Чек с фискальными данными.
if not ReadBool('PrintCheck', 'IsFiscal') and ReadBool('FiscalInfo', 'Success') then
begin
WriteStr('PrintCheck', 'Align', '0');
AddLine('КАССОВЫЙ ЧЕК');
WriteStr('PrintCheck', 'Align', '-1');
AddLine('ПРИХОД');
FiscalSum := ReadFloat('BankCardSum') + ReadFloat('CashSum');
AddLineTextValue(ReadStr('FiscalInfo', 'CommodityName'),
FloatToStr(FiscalSum, 2) + ' x 1 = ' + FloatToStr(FiscalSum, 2));
AddTextNotNullValue(' ' + ReadStr('FiscalInfo', 'TaxRate'), ReadFloat('FiscalInfo', 'TaxSum'));
DiscountSum := ReadFloat('TotalSum') - FiscalSum;
if DiscountSum > 0 then
AddTextCostValue('СКИДКА', DiscountSum);
AddLine('УСЛУГА');
if ReadStr('FiscalInfo', 'TaxRate') = 'без НДС' then
NdsSum := FiscalSum
else
NdsSum := ReadFloat('FiscalInfo', 'TaxSum');
WriteStr('PrintCheck', 'FontSize', '1');
AddTextCostValue('ИТОГ', FiscalSum);
WriteStr('PrintCheck', 'FontSize', '0');
AddTextNotNullValue(' Сумма ' + ReadStr('FiscalInfo', 'TaxRate'), NdsSum);
AddTextNotNullValue('НАЛИЧНЫМИ', ReadFloat('CashSum'));
AddTextNotNullValue('БАНК. КАРТОЙ', ReadFloat('BankCardSum'));
AddTextCostValue('ПОЛУЧЕНО', FiscalSum);
AddLineTextValue('СНО:', ReadStr('FiscalInfo', 'Taxation'));
if ReadStr('FiscalInfo', 'ClientPhone') <> '' then
AddLineTextValue('Тел.покупателя', ReadStr('FiscalInfo', 'ClientPhone'));
if (ReadStr('FiscalInfo', 'ClientPhone') = '') and (ReadStr('FiscalInfo', 'ClientEmail') <> '') then
AddLineTextValue('Эл.адр.покупателя', ReadStr('FiscalInfo', 'ClientEmail'));
AddLineTextValue('Пользователь:', ReadStr('FiscalInfo', 'OrganizationName'));
AddLineTextValue('Адрес:', ReadStr('FiscalInfo', 'OrganizationAddress'));
AddLineTextValue('Место расчетов:', ReadStr('FiscalInfo', 'OrganizationAddress'));
AddLineTextValue('Кассир:', ReadStr('FiscalInfo', 'OperatorName'));
AddLineTextValue('Сайт ФНС:', ReadStr('FiscalInfo', 'FnsUrl'));
AddLineTextValue('ЗН ККТ:', ReadStr('FiscalInfo', 'SerialNumber'));
AddLineTextValue('Смена №', IntToStr(ReadInt('FiscalInfo', 'ShiftNumber')));
AddLineTextValue('Чек №', IntToStr(ReadInt('FiscalInfo', 'CheckNumber')));
AddLineTextValue('Дата Время', GetDateTimeStr(ReadInt('FiscalInfo', 'CompleteTime')));
AddLineTextValue('ОФД:', ReadStr('FiscalInfo', 'OfdName'));
AddLineTextValue('ИНН:', ReadStr('FiscalInfo', 'OfdVatin'));
AddLineTextValue('РН ККТ:', ReadStr('FiscalInfo', 'RegistrationNumber'));
AddLineTextValue('ФН №', ReadStr('FiscalInfo', 'FiscalNumber'));
AddLineTextValue('ФД №', IntToStr(ReadInt('FiscalInfo', 'FiscalDocumentNumber')));
AddLineTextValue('ФП:', ReadStr('FiscalInfo', 'FiscalDocumentSign'));
WriteStr('PrintCheck','QR', GetQrCode);
AddLineBreak;
AddLineBreak;
end;
end;
Параметры, которые позволяют учитывать время проезда по маршруту в тарифе (справочник "Тарифы"):
- Обычный заказ - По городу - Стоимость минуты.
- Обычный заказ - За городом - Стоимость минуты.
Расчет времени происходит через онлайн карты (в данном примере используется 2GIS).
Нужно выбрать карту как источник для расчета времени доезда экипажа (Файл - Настройки - Карта - Онлайн карты - Функционал - Расчет времени доезда экипажа до заказа в карточке заказа).
Обратите внимание, для использования онлайн карт 2GIS, Яндекс и Google нужен API-ключ, который указывается в Файл - Настройки - Карта - Онлайн карты - Настройки - API-ключ для использования онлайн карт.
Пример расчета стоимости поездки с учетом времени проезда по маршруту и километража в разное время.

