Тариф, учитывающий время проезда по маршруту и километраж
В тарифе существуют параметры, которые позволяют учитывать не только километраж маршрута, но и предварительно рассчитанное время проезда по этому маршруту, которое может зависеть от загруженности дорог.
Начиная с версии Такси-Мастер 3.12 нужные параметры уже присутствуют в расширенном тарифе по умолчанию.
Текст тарифа (Развернуть/Свернуть) →
//<?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 и Яндекс.
Обратите внимание, для использования онлайн карт 2GIS и Яндекс нужен API-ключ, который указывается в Файл - Настройки - Карта - Онлайн карты - Настройки - API-ключ для использования онлайн карт .
Пример расчета стоимости поездки с учетом времени проезда по маршруту и километража в разное время.