Backoffice stage 3: orders and providers, auto-assignment
- Auto-assignment: a new order is offered to the best free provider (same ranking as
the dispatcher hint); a decline or timeout passes it to the next one; nobody is
offered the same order twice; after N tries it waits for a dispatcher and the team
is notified once. The worker retries waiting orders every minute. Settings
assign.auto / assign.maxAutoOffers (toggle on the Orders page, checkbox in old admin).
- Orders: list by day with groups (need a provider, offered, assigned, in progress,
done, cancelled), periods and search; order card with progress, provider or ranked
candidates ("offer" / "pick automatically"), details, checklist and photos,
history in plain words, client, money (superadmin), payment, status change,
reschedule (slots or custom time), cancel with fee.
- New order for a client (from the client card or the Orders page): params form,
address, free slots for 14 days, price with the client's discount.
- Providers: list with rating, orders, declines, low ratings, next order; card with
quality, ratings, upcoming orders, schedule and districts, admission documents,
block/unblock with reason, new bot link, money and payouts (superadmin).
- Payout gets paidAt/note/createdById; Provider gets blockedReason/blockedAt/adminNote
and documents (ProviderDoc).
- Tests for auto-assignment.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2772837e29
commit
e7de4f5893
33 files changed
+4521
-45
No files matched your search
@@ -386,6 +386,242 @@ const ru = {
|
||||
'chat.notLinked': 'Рабочий бот не открыт',
|
||||
'chat.details': 'Подробнее',
|
||||
'chat.more': 'Ещё действия',
|
||||
|
||||
// ───── заказы и исполнители (этап 3) ─────
|
||||
'ord.title': 'Заказы',
|
||||
'ord.new': 'Новый заказ',
|
||||
'ord.search': '№, клиент, телефон, адрес или исполнитель',
|
||||
'ord.period': 'Период',
|
||||
'ord.period.all': 'Все даты',
|
||||
'ord.period.today': 'Сегодня',
|
||||
'ord.period.tomorrow': 'Завтра',
|
||||
'ord.period.week': '7 дней',
|
||||
'ord.period.past': 'Прошедшие',
|
||||
'ord.group.active': 'В работе у команды',
|
||||
'ord.group.new': 'Ждут исполнителя',
|
||||
'ord.group.pending': 'Предложены',
|
||||
'ord.group.assigned': 'Назначены',
|
||||
'ord.group.in_progress': 'Выполняются',
|
||||
'ord.group.done': 'Готово',
|
||||
'ord.group.cancelled': 'Отменены',
|
||||
'ord.today': 'Сегодня',
|
||||
'ord.tomorrow': 'Завтра',
|
||||
'ord.empty': 'Заказов с такими условиями нет.',
|
||||
'ord.waitsAnswer': 'ждём ответа: {name}',
|
||||
'ord.needsHuman': 'нужен диспетчер',
|
||||
'ord.searching': 'система подбирает…',
|
||||
'ord.overdue': 'время прошло, исполнителя нет',
|
||||
'ord.needsDispatcher': 'Автораспределение не нашло исполнителя для заказов: {n}. Назначьте вручную.',
|
||||
'ord.autoOn': 'Автораспределение включено',
|
||||
'ord.autoOff': 'Автораспределение выключено',
|
||||
'ord.autoHint': 'Новый заказ сам предлагается лучшему свободному исполнителю (язык клиента, район, загрузка, рейтинг). Нет ответа {minutes} мин или отказ — следующему; после {tries} попыток — диспетчеру.',
|
||||
'ord.back': 'Все заказы',
|
||||
'ord.progress': 'Ход заказа',
|
||||
'ord.details': 'Детали',
|
||||
'ord.when': 'Когда',
|
||||
'ord.where': 'Где',
|
||||
'ord.minutes': '{n} мин',
|
||||
'ord.params': 'Параметры',
|
||||
'ord.extras': 'Доп. услуги',
|
||||
'ord.note': 'Комментарий клиента',
|
||||
'ord.lang': 'Язык клиента',
|
||||
'ord.created': 'Создан',
|
||||
'ord.checklist': 'Чек-лист',
|
||||
'ord.needsPhoto': 'нужно фото',
|
||||
'ord.photo': 'Фото',
|
||||
'ord.history': 'История',
|
||||
'ord.client': 'Клиент',
|
||||
'ord.writeClient': 'Написать клиенту',
|
||||
'ord.writeProvider': 'Написать исполнителю',
|
||||
'ord.money': 'Деньги',
|
||||
'ord.base': 'Без скидки',
|
||||
'ord.discount': 'Скидка {pct}%',
|
||||
'ord.payout': 'Исполнителю',
|
||||
'ord.cancelFee': 'Удержание за отмену',
|
||||
'ord.payment': 'Оплата',
|
||||
'ord.markPaid': 'Отметить оплату',
|
||||
'ord.confirmPaid': 'Отметить, что клиент оплатил заказ?',
|
||||
'ord.paidDone': 'Оплата отмечена',
|
||||
'ord.actions': 'Действия',
|
||||
'ord.setStatus': 'Статус: {status}',
|
||||
'ord.confirmStatus': 'Перевести заказ в «{status}»? Клиент получит уведомление.',
|
||||
'ord.statusChanged': 'Статус изменён',
|
||||
'ord.reschedule': 'Перенести',
|
||||
'ord.rescheduleTitle': 'Перенос заказа №{n}',
|
||||
'ord.rescheduleHint': 'Если исполнитель занят в новое время, заказ вернётся в «Ждут исполнителя» и уйдёт в автораспределение.',
|
||||
'ord.rescheduled': 'Заказ перенесён, исполнитель тот же',
|
||||
'ord.rescheduledFree': 'Заказ перенесён; исполнитель занят — ищем нового',
|
||||
'ord.comment': 'Комментарий',
|
||||
'ord.commentPh': 'Например: клиент попросил по телефону',
|
||||
'ord.cancel': 'Отменить заказ',
|
||||
'ord.cancelTitle': 'Отмена заказа',
|
||||
'ord.cancelReason': 'Причина отмены',
|
||||
'ord.cancelReasonPh': 'Например: клиент передумал',
|
||||
'ord.cancelFeeHint': 'Сколько удержать с клиента, ֏. Обычно 0.',
|
||||
'ord.cancelHint': 'Клиент и исполнитель получат уведомление.',
|
||||
'ord.cancelled': 'Заказ отменён',
|
||||
'ord.rating': 'Оценка клиента',
|
||||
'ord.noComment': 'Без комментария',
|
||||
'ord.offers': 'Кому предлагали',
|
||||
'ord.bySystem': 'система',
|
||||
'ord.provider': 'Исполнитель',
|
||||
'ord.unassign': 'Снять исполнителя',
|
||||
'ord.revoke': 'Отозвать предложение',
|
||||
'ord.confirmUnassign': 'Снять исполнителя? Заказ вернётся в «Ждут исполнителя».',
|
||||
'ord.confirmRevoke': 'Отозвать предложение? Заказ снова будет ждать исполнителя.',
|
||||
'ord.unassigned': 'Готово — заказ снова ждёт исполнителя',
|
||||
'ord.pendingProvider': 'Предложен: {name}',
|
||||
'ord.pendingCompany': 'Передан компании «{name}» — ждём, кого назначит диспетчер',
|
||||
'ord.byAuto': 'предложила система',
|
||||
'ord.minLeft': 'на ответ ≈ {n} мин',
|
||||
'ord.pickHint': 'Свободные на это время — по порядку подбора. Или поручите выбор системе.',
|
||||
'ord.autoPick': 'Подобрать автоматически',
|
||||
'ord.autoOffered': 'Предложили: {name}',
|
||||
'ord.autoNone': 'Свободных исполнителей не нашлось',
|
||||
'ord.noFree': 'На это время все заняты. Перенесите заказ или договоритесь с исполнителем.',
|
||||
'ord.busy': 'Заняты в это время: {n}',
|
||||
'ord.company': 'компания',
|
||||
'ord.tried': 'уже предлагали',
|
||||
'ord.load': 'заказов в этот день: {n}',
|
||||
'ord.offer': 'Предложить',
|
||||
'ord.offered': 'Заказ отправлен исполнителю',
|
||||
'ord.noProvider': 'Исполнитель не назначался.',
|
||||
'ord.ev.created': 'Заказ создан',
|
||||
'ord.ev.createdByStaff': 'Заказ оформила команда',
|
||||
'ord.ev.offered': 'Предложен исполнителю',
|
||||
'ord.ev.autoOffered': 'Автораспределение: предложен',
|
||||
'ord.ev.autoNoCandidate': 'Автораспределение: свободных нет',
|
||||
'ord.ev.autoGaveUp': 'Автораспределение остановлено — нужен диспетчер',
|
||||
'no.title': 'Новый заказ',
|
||||
'no.client': 'Клиент',
|
||||
'no.clientPh': 'Имя, @username или телефон',
|
||||
'no.noClients': 'Никого не нашли',
|
||||
'no.changeClient': 'Другой клиент',
|
||||
'no.service': 'Услуга',
|
||||
'no.extras': 'Доп. услуги',
|
||||
'no.address': 'Адрес',
|
||||
'no.addressPh': 'Улица, дом, квартира',
|
||||
'no.district': 'Район',
|
||||
'no.when': 'Дата и время',
|
||||
'no.day': 'День',
|
||||
'no.noSlots': 'На этот день свободного времени нет — выберите другой день или «другое время».',
|
||||
'no.otherTime': 'Другое время (договорились с исполнителем сами)',
|
||||
'no.customTime': 'Время',
|
||||
'no.customHint': 'По Еревану. Свободных исполнителей система не гарантирует.',
|
||||
'no.note': 'Комментарий для исполнителя',
|
||||
'no.notePh': 'Код домофона, животные…',
|
||||
'no.payment': 'Оплата',
|
||||
'no.hint': 'Цена — с учётом подписки клиента. Клиент получит уведомление в бота, заказ сразу уйдёт в автораспределение.',
|
||||
'no.create': 'Оформить заказ',
|
||||
'no.created': 'Заказ №{n} оформлен',
|
||||
'prv.title': 'Исполнители',
|
||||
'prv.add': 'Добавить',
|
||||
'prv.search': 'Имя или телефон',
|
||||
'prv.status.active': 'Работают',
|
||||
'prv.status.blocked': 'Заблокированы',
|
||||
'prv.status.all': 'Все',
|
||||
'prv.empty': 'Никого не нашли.',
|
||||
'prv.col.name': 'Исполнитель',
|
||||
'prv.col.rating': 'Рейтинг',
|
||||
'prv.col.done': 'Заказов',
|
||||
'prv.col.refused': 'Отказы',
|
||||
'prv.col.next': 'Ближайший заказ',
|
||||
'prv.period30': 'Заказы, отказы и низкие оценки — за 30 дней.',
|
||||
'prv.blocked': 'заблокирован',
|
||||
'prv.onShift': 'на смене',
|
||||
'prv.offShift': 'не на смене',
|
||||
'prv.notLinked': 'не открыл бота',
|
||||
'prv.noDocs': 'нет документов',
|
||||
'prv.ratings': 'оценок: {n}',
|
||||
'prv.low': 'низких: {n}',
|
||||
'prv.today': 'сегодня: {n}',
|
||||
'prv.back': 'Все исполнители',
|
||||
'prv.write': 'Написать',
|
||||
'prv.edit': 'Редактировать',
|
||||
'prv.blockedSince': 'Заблокирован с {date}.',
|
||||
'prv.unblock': 'Вернуть к работе',
|
||||
'prv.inviteHint': 'Исполнитель ещё не открыл рабочий бот — отправьте ему ссылку.',
|
||||
'prv.copyInvite': 'Скопировать ссылку',
|
||||
'prv.quality': 'Качество',
|
||||
'prv.days30': 'за 30 дней',
|
||||
'prv.acceptRate': 'принял {a} из {n} предложений',
|
||||
'prv.refusals': 'отказы: {d}, молчал: {e}',
|
||||
'prv.lowRatings': 'оценок 3 и ниже',
|
||||
'prv.upcoming': 'Ближайшие заказы',
|
||||
'prv.noUpcoming': 'Назначенных заказов нет.',
|
||||
'prv.recent': 'Последние выполненные',
|
||||
'prv.balance': 'К выплате',
|
||||
'prv.thisMonth': 'Этот месяц',
|
||||
'prv.prevMonth': 'Прошлый',
|
||||
'prv.paidTotal': 'Выплачено',
|
||||
'prv.payout': 'Отметить выплату',
|
||||
'prv.payoutTitle': 'Выплата исполнителю',
|
||||
'prv.amount': 'Сумма, ֏',
|
||||
'prv.balanceHint': 'Долг перед исполнителем: {sum}',
|
||||
'prv.payoutNote': 'Как выплатили',
|
||||
'prv.payoutNotePh': 'Наличные / перевод на карту…',
|
||||
'prv.payoutConfirm': 'Выплачено',
|
||||
'prv.payoutDone': 'Выплата отмечена',
|
||||
'prv.rateCompany': 'ставка компании {v}',
|
||||
'prv.rateOwn': 'ставка {v}',
|
||||
'prv.ratePreset': 'по пресету «{name}»',
|
||||
'prv.work': 'Работа',
|
||||
'prv.languages': 'Языки',
|
||||
'prv.districts': 'Районы',
|
||||
'prv.anyDistrict': 'любые',
|
||||
'prv.districtsHint': 'Подбор ставит выше тех, кто работает в районе заказа.',
|
||||
'prv.docs': 'Документы для допуска',
|
||||
'prv.noDocsHint': 'Паспорт, договор, справка — всё хранится в закрытом хранилище.',
|
||||
'prv.docTitlePh': 'Название: паспорт, договор…',
|
||||
'prv.upload': 'Загрузить',
|
||||
'prv.docAdded': 'Документ добавлен',
|
||||
'prv.removeDocConfirm': 'Удалить документ?',
|
||||
'prv.access': 'Допуск',
|
||||
'prv.block': 'Заблокировать',
|
||||
'prv.blockTitle': 'Заблокировать исполнителя',
|
||||
'prv.blockReason': 'Причина',
|
||||
'prv.blockReasonPh': 'Например: жалобы клиентов, нет документов',
|
||||
'prv.blockHint': 'Заказы ему больше не предлагаются, действующие предложения отзываются. Уже назначенные заказы остаются — переназначьте их вручную.',
|
||||
'prv.resetInvite': 'Новая ссылка для входа в бот',
|
||||
'prv.resetConfirm': 'Сделать новую ссылку? Текущая привязка к Telegram снимется — исполнителю нужно будет войти заново.',
|
||||
'prv.since': 'С нами с {date}',
|
||||
'prv.saved': 'Сохранено',
|
||||
'prv.addTitle': 'Новый исполнитель',
|
||||
'prv.editTitle': 'Профиль исполнителя',
|
||||
'prv.name': 'Имя',
|
||||
'prv.role': 'Роль',
|
||||
'prv.company': 'Компания',
|
||||
'prv.freelance': 'Частный исполнитель',
|
||||
'prv.schedule': 'График',
|
||||
'prv.rate': 'Ставка',
|
||||
'prv.note': 'Заметка команды',
|
||||
'err.REASON_REQUIRED': 'Укажите причину.',
|
||||
'err.SLOT_UNAVAILABLE': 'Это время уже занято или прошло. Выберите другое или «другое время».',
|
||||
'err.ALREADY_ASSIGNED': 'Заказ уже назначен или предложен — обновите страницу.',
|
||||
'err.PROVIDER_BUSY': 'Исполнитель занят в это время.',
|
||||
'err.TRANSITION_NOT_ALLOWED': 'Сейчас этот шаг для заказа недоступен.',
|
||||
'err.CHECKLIST_INCOMPLETE': 'Сначала исполнитель должен закрыть чек-лист и приложить фото.',
|
||||
'err.CONSENT_REQUIRED': 'Клиент ещё не дал согласие на обработку данных в боте — заказ оформить нельзя.',
|
||||
'err.ADDRESS_REQUIRED': 'Укажите адрес и район.',
|
||||
'err.INVALID_PARAMS': 'Проверьте параметры заказа.',
|
||||
'err.OFFER_NOT_ACTIVE': 'Предложение уже неактуально.',
|
||||
'err.BAD_FILE_TYPE_DOC': 'Можно фото или PDF.',
|
||||
'audit.bo.orders.assign': 'предложил(а) заказ исполнителю',
|
||||
'audit.bo.orders.auto': 'запустил(а) подбор исполнителя',
|
||||
'audit.bo.orders.unassign': 'снял(а) исполнителя с заказа',
|
||||
'audit.bo.orders.transition': 'сменил(а) статус заказа',
|
||||
'audit.bo.orders.cancel': 'отменил(а) заказ',
|
||||
'audit.bo.orders.reschedule': 'перенёс(ла) заказ',
|
||||
'audit.bo.orders.markPaid': 'отметил(а) оплату заказа',
|
||||
'audit.bo.orders.create': 'оформил(а) заказ за клиента',
|
||||
'audit.bo.orders.setAutoSetting': 'изменил(а) автораспределение',
|
||||
'audit.bo.providers.create': 'добавил(а) исполнителя',
|
||||
'audit.bo.providers.update': 'изменил(а) профиль исполнителя',
|
||||
'audit.bo.providers.setActive': 'изменил(а) допуск исполнителя',
|
||||
'audit.bo.providers.resetInvite': 'выпустил(а) новую ссылку исполнителю',
|
||||
'audit.bo.providers.removeDoc': 'удалил(а) документ исполнителя',
|
||||
'audit.bo.providers.addDoc': 'загрузил(а) документ исполнителя',
|
||||
'audit.bo.providers.payout': 'отметил(а) выплату исполнителю',
|
||||
'chat.order': 'Заказ №{n}',
|
||||
'chat.noOrder': 'Без заказа',
|
||||
'chat.noOrderNow': 'Сейчас без заказа',
|
||||
@@ -792,6 +1028,242 @@ const en: Dict = {
|
||||
'chat.notLinked': 'Work bot not opened',
|
||||
'chat.details': 'Details',
|
||||
'chat.more': 'More actions',
|
||||
|
||||
// ───── заказы и исполнители (этап 3) ─────
|
||||
'ord.title': 'Orders',
|
||||
'ord.new': 'New order',
|
||||
'ord.search': 'No., client, phone, address or provider',
|
||||
'ord.period': 'Period',
|
||||
'ord.period.all': 'All dates',
|
||||
'ord.period.today': 'Today',
|
||||
'ord.period.tomorrow': 'Tomorrow',
|
||||
'ord.period.week': '7 days',
|
||||
'ord.period.past': 'Past',
|
||||
'ord.group.active': 'Active',
|
||||
'ord.group.new': 'Need a provider',
|
||||
'ord.group.pending': 'Offered',
|
||||
'ord.group.assigned': 'Assigned',
|
||||
'ord.group.in_progress': 'In progress',
|
||||
'ord.group.done': 'Done',
|
||||
'ord.group.cancelled': 'Cancelled',
|
||||
'ord.today': 'Today',
|
||||
'ord.tomorrow': 'Tomorrow',
|
||||
'ord.empty': 'No orders match these filters.',
|
||||
'ord.waitsAnswer': 'awaiting: {name}',
|
||||
'ord.needsHuman': 'needs a dispatcher',
|
||||
'ord.searching': 'auto-assigning…',
|
||||
'ord.overdue': 'time passed, no provider',
|
||||
'ord.needsDispatcher': 'Auto-assignment found no provider for {n} order(s). Assign manually.',
|
||||
'ord.autoOn': 'Auto-assign on',
|
||||
'ord.autoOff': 'Auto-assign off',
|
||||
'ord.autoHint': 'A new order is offered to the best free provider (client language, district, load, rating). No answer in {minutes} min or a decline — the next one; after {tries} tries — to a dispatcher.',
|
||||
'ord.back': 'All orders',
|
||||
'ord.progress': 'Progress',
|
||||
'ord.details': 'Details',
|
||||
'ord.when': 'When',
|
||||
'ord.where': 'Where',
|
||||
'ord.minutes': '{n} min',
|
||||
'ord.params': 'Details',
|
||||
'ord.extras': 'Extras',
|
||||
'ord.note': 'Client comment',
|
||||
'ord.lang': 'Client language',
|
||||
'ord.created': 'Created',
|
||||
'ord.checklist': 'Checklist',
|
||||
'ord.needsPhoto': 'photo needed',
|
||||
'ord.photo': 'Photo',
|
||||
'ord.history': 'History',
|
||||
'ord.client': 'Client',
|
||||
'ord.writeClient': 'Message the client',
|
||||
'ord.writeProvider': 'Message the provider',
|
||||
'ord.money': 'Money',
|
||||
'ord.base': 'Before discount',
|
||||
'ord.discount': 'Discount {pct}%',
|
||||
'ord.payout': 'To the provider',
|
||||
'ord.cancelFee': 'Cancellation fee',
|
||||
'ord.payment': 'Payment',
|
||||
'ord.markPaid': 'Mark as paid',
|
||||
'ord.confirmPaid': 'Mark the order as paid?',
|
||||
'ord.paidDone': 'Marked as paid',
|
||||
'ord.actions': 'Actions',
|
||||
'ord.setStatus': 'Status: {status}',
|
||||
'ord.confirmStatus': 'Move the order to “{status}”? The client will be notified.',
|
||||
'ord.statusChanged': 'Status changed',
|
||||
'ord.reschedule': 'Reschedule',
|
||||
'ord.rescheduleTitle': 'Reschedule order #{n}',
|
||||
'ord.rescheduleHint': 'If the provider is busy at the new time, the order goes back to “Need a provider” and to auto-assignment.',
|
||||
'ord.rescheduled': 'Rescheduled, same provider',
|
||||
'ord.rescheduledFree': 'Rescheduled; the provider is busy — looking for a new one',
|
||||
'ord.comment': 'Comment',
|
||||
'ord.commentPh': 'E.g. the client asked by phone',
|
||||
'ord.cancel': 'Cancel order',
|
||||
'ord.cancelTitle': 'Cancel the order',
|
||||
'ord.cancelReason': 'Reason',
|
||||
'ord.cancelReasonPh': 'E.g. the client changed their mind',
|
||||
'ord.cancelFeeHint': 'How much to charge the client, ֏. Usually 0.',
|
||||
'ord.cancelHint': 'The client and the provider will be notified.',
|
||||
'ord.cancelled': 'Order cancelled',
|
||||
'ord.rating': 'Client rating',
|
||||
'ord.noComment': 'No comment',
|
||||
'ord.offers': 'Offers',
|
||||
'ord.bySystem': 'system',
|
||||
'ord.provider': 'Provider',
|
||||
'ord.unassign': 'Remove provider',
|
||||
'ord.revoke': 'Withdraw offer',
|
||||
'ord.confirmUnassign': 'Remove the provider? The order goes back to “Need a provider”.',
|
||||
'ord.confirmRevoke': 'Withdraw the offer? The order will wait for a provider again.',
|
||||
'ord.unassigned': 'Done — the order needs a provider again',
|
||||
'ord.pendingProvider': 'Offered to {name}',
|
||||
'ord.pendingCompany': 'Passed to {name} — waiting for their dispatcher',
|
||||
'ord.byAuto': 'offered automatically',
|
||||
'ord.minLeft': '≈ {n} min to answer',
|
||||
'ord.pickHint': 'Free at this time, best match first. Or let the system pick.',
|
||||
'ord.autoPick': 'Pick automatically',
|
||||
'ord.autoOffered': 'Offered to {name}',
|
||||
'ord.autoNone': 'No free provider found',
|
||||
'ord.noFree': 'Everyone is busy at this time. Reschedule or arrange with a provider.',
|
||||
'ord.busy': 'Busy at this time: {n}',
|
||||
'ord.company': 'company',
|
||||
'ord.tried': 'already offered',
|
||||
'ord.load': '{n} orders that day',
|
||||
'ord.offer': 'Offer',
|
||||
'ord.offered': 'Offer sent',
|
||||
'ord.noProvider': 'No provider was assigned.',
|
||||
'ord.ev.created': 'Order created',
|
||||
'ord.ev.createdByStaff': 'Created by the team',
|
||||
'ord.ev.offered': 'Offered to a provider',
|
||||
'ord.ev.autoOffered': 'Auto-assign: offered',
|
||||
'ord.ev.autoNoCandidate': 'Auto-assign: nobody free',
|
||||
'ord.ev.autoGaveUp': 'Auto-assign stopped — needs a dispatcher',
|
||||
'no.title': 'New order',
|
||||
'no.client': 'Client',
|
||||
'no.clientPh': 'Name, @username or phone',
|
||||
'no.noClients': 'Nobody found',
|
||||
'no.changeClient': 'Another client',
|
||||
'no.service': 'Service',
|
||||
'no.extras': 'Extras',
|
||||
'no.address': 'Address',
|
||||
'no.addressPh': 'Street, building, apartment',
|
||||
'no.district': 'District',
|
||||
'no.when': 'Date and time',
|
||||
'no.day': 'Day',
|
||||
'no.noSlots': 'No free time that day — pick another day or “other time”.',
|
||||
'no.otherTime': 'Other time (arranged with a provider directly)',
|
||||
'no.customTime': 'Time',
|
||||
'no.customHint': 'Yerevan time. A free provider is not guaranteed.',
|
||||
'no.note': 'Comment for the provider',
|
||||
'no.notePh': 'Door code, pets…',
|
||||
'no.payment': 'Payment',
|
||||
'no.hint': 'The price includes the client’s subscription discount. The client is notified and the order goes to auto-assignment.',
|
||||
'no.create': 'Create order',
|
||||
'no.created': 'Order #{n} created',
|
||||
'prv.title': 'Providers',
|
||||
'prv.add': 'Add',
|
||||
'prv.search': 'Name or phone',
|
||||
'prv.status.active': 'Active',
|
||||
'prv.status.blocked': 'Blocked',
|
||||
'prv.status.all': 'All',
|
||||
'prv.empty': 'Nobody found.',
|
||||
'prv.col.name': 'Provider',
|
||||
'prv.col.rating': 'Rating',
|
||||
'prv.col.done': 'Orders',
|
||||
'prv.col.refused': 'Declines',
|
||||
'prv.col.next': 'Next order',
|
||||
'prv.period30': 'Orders, declines and low ratings — last 30 days.',
|
||||
'prv.blocked': 'blocked',
|
||||
'prv.onShift': 'on shift',
|
||||
'prv.offShift': 'off shift',
|
||||
'prv.notLinked': 'bot not opened',
|
||||
'prv.noDocs': 'no documents',
|
||||
'prv.ratings': '{n} ratings',
|
||||
'prv.low': '{n} low',
|
||||
'prv.today': 'today: {n}',
|
||||
'prv.back': 'All providers',
|
||||
'prv.write': 'Message',
|
||||
'prv.edit': 'Edit',
|
||||
'prv.blockedSince': 'Blocked since {date}.',
|
||||
'prv.unblock': 'Unblock',
|
||||
'prv.inviteHint': 'The provider hasn’t opened the work bot yet — send them the link.',
|
||||
'prv.copyInvite': 'Copy link',
|
||||
'prv.quality': 'Quality',
|
||||
'prv.days30': 'last 30 days',
|
||||
'prv.acceptRate': 'accepted {a} of {n} offers',
|
||||
'prv.refusals': 'declined: {d}, no answer: {e}',
|
||||
'prv.lowRatings': 'ratings of 3 or less',
|
||||
'prv.upcoming': 'Upcoming orders',
|
||||
'prv.noUpcoming': 'No assigned orders.',
|
||||
'prv.recent': 'Recently done',
|
||||
'prv.balance': 'To pay',
|
||||
'prv.thisMonth': 'This month',
|
||||
'prv.prevMonth': 'Last month',
|
||||
'prv.paidTotal': 'Paid',
|
||||
'prv.payout': 'Record a payout',
|
||||
'prv.payoutTitle': 'Payout to provider',
|
||||
'prv.amount': 'Amount, ֏',
|
||||
'prv.balanceHint': 'Owed to the provider: {sum}',
|
||||
'prv.payoutNote': 'How it was paid',
|
||||
'prv.payoutNotePh': 'Cash / card transfer…',
|
||||
'prv.payoutConfirm': 'Paid',
|
||||
'prv.payoutDone': 'Payout recorded',
|
||||
'prv.rateCompany': 'company rate {v}',
|
||||
'prv.rateOwn': 'rate {v}',
|
||||
'prv.ratePreset': 'preset “{name}”',
|
||||
'prv.work': 'Work',
|
||||
'prv.languages': 'Languages',
|
||||
'prv.districts': 'Districts',
|
||||
'prv.anyDistrict': 'any',
|
||||
'prv.districtsHint': 'Assignment favors providers working in the order’s district.',
|
||||
'prv.docs': 'Admission documents',
|
||||
'prv.noDocsHint': 'Passport, contract, certificate — kept in private storage.',
|
||||
'prv.docTitlePh': 'Title: passport, contract…',
|
||||
'prv.upload': 'Upload',
|
||||
'prv.docAdded': 'Document added',
|
||||
'prv.removeDocConfirm': 'Delete the document?',
|
||||
'prv.access': 'Access',
|
||||
'prv.block': 'Block',
|
||||
'prv.blockTitle': 'Block the provider',
|
||||
'prv.blockReason': 'Reason',
|
||||
'prv.blockReasonPh': 'E.g. client complaints, missing documents',
|
||||
'prv.blockHint': 'No new offers; pending offers are withdrawn. Already assigned orders stay — reassign them manually.',
|
||||
'prv.resetInvite': 'New bot link',
|
||||
'prv.resetConfirm': 'Create a new link? The current Telegram link is removed — the provider will need to log in again.',
|
||||
'prv.since': 'With us since {date}',
|
||||
'prv.saved': 'Saved',
|
||||
'prv.addTitle': 'New provider',
|
||||
'prv.editTitle': 'Provider profile',
|
||||
'prv.name': 'Name',
|
||||
'prv.role': 'Role',
|
||||
'prv.company': 'Company',
|
||||
'prv.freelance': 'Freelancer',
|
||||
'prv.schedule': 'Schedule',
|
||||
'prv.rate': 'Rate',
|
||||
'prv.note': 'Team note',
|
||||
'err.REASON_REQUIRED': 'Please give a reason.',
|
||||
'err.SLOT_UNAVAILABLE': 'This time is taken or has passed. Pick another one.',
|
||||
'err.ALREADY_ASSIGNED': 'The order is already assigned or offered — refresh the page.',
|
||||
'err.PROVIDER_BUSY': 'The provider is busy at this time.',
|
||||
'err.TRANSITION_NOT_ALLOWED': 'This step isn’t available for the order now.',
|
||||
'err.CHECKLIST_INCOMPLETE': 'The provider must finish the checklist and add photos first.',
|
||||
'err.CONSENT_REQUIRED': 'The client hasn’t given data-processing consent in the bot yet.',
|
||||
'err.ADDRESS_REQUIRED': 'Please enter the address and district.',
|
||||
'err.INVALID_PARAMS': 'Check the order details.',
|
||||
'err.OFFER_NOT_ACTIVE': 'The offer is no longer active.',
|
||||
'err.BAD_FILE_TYPE_DOC': 'Photo or PDF only.',
|
||||
'audit.bo.orders.assign': 'offered an order',
|
||||
'audit.bo.orders.auto': 'ran auto-assignment',
|
||||
'audit.bo.orders.unassign': 'removed a provider from an order',
|
||||
'audit.bo.orders.transition': 'changed an order status',
|
||||
'audit.bo.orders.cancel': 'cancelled an order',
|
||||
'audit.bo.orders.reschedule': 'rescheduled an order',
|
||||
'audit.bo.orders.markPaid': 'marked an order as paid',
|
||||
'audit.bo.orders.create': 'created an order for a client',
|
||||
'audit.bo.orders.setAutoSetting': 'changed auto-assignment',
|
||||
'audit.bo.providers.create': 'added a provider',
|
||||
'audit.bo.providers.update': 'edited a provider',
|
||||
'audit.bo.providers.setActive': 'changed provider access',
|
||||
'audit.bo.providers.resetInvite': 'reissued a provider link',
|
||||
'audit.bo.providers.removeDoc': 'deleted a provider document',
|
||||
'audit.bo.providers.addDoc': 'uploaded a provider document',
|
||||
'audit.bo.providers.payout': 'recorded a payout',
|
||||
'chat.order': 'Order #{n}',
|
||||
'chat.noOrder': 'No order',
|
||||
'chat.noOrderNow': 'No current order',
|
||||
@@ -1195,6 +1667,242 @@ const hy: Dict = {
|
||||
'chat.notLinked': 'Աշխատանքային բոտը բացված չէ',
|
||||
'chat.details': 'Մանրամասներ',
|
||||
'chat.more': 'Այլ գործողություններ',
|
||||
|
||||
// ───── заказы и исполнители (этап 3) ─────
|
||||
'ord.title': 'Պատվերներ',
|
||||
'ord.new': 'Նոր պատվեր',
|
||||
'ord.search': '№, հաճախորդ, հեռախոս, հասցե կամ կատարող',
|
||||
'ord.period': 'Ժամանակահատված',
|
||||
'ord.period.all': 'Բոլոր օրերը',
|
||||
'ord.period.today': 'Այսօր',
|
||||
'ord.period.tomorrow': 'Վաղը',
|
||||
'ord.period.week': '7 օր',
|
||||
'ord.period.past': 'Անցածները',
|
||||
'ord.group.active': 'Ակտիվ',
|
||||
'ord.group.new': 'Սպասում են կատարողի',
|
||||
'ord.group.pending': 'Առաջարկված',
|
||||
'ord.group.assigned': 'Նշանակված',
|
||||
'ord.group.in_progress': 'Կատարվում են',
|
||||
'ord.group.done': 'Պատրաստ',
|
||||
'ord.group.cancelled': 'Չեղարկված',
|
||||
'ord.today': 'Այսօր',
|
||||
'ord.tomorrow': 'Վաղը',
|
||||
'ord.empty': 'Այս պայմաններով պատվերներ չկան։',
|
||||
'ord.waitsAnswer': 'սպասում ենք՝ {name}',
|
||||
'ord.needsHuman': 'պետք է դիսպետչեր',
|
||||
'ord.searching': 'համակարգը ընտրում է…',
|
||||
'ord.overdue': 'ժամն անցել է, կատարող չկա',
|
||||
'ord.needsDispatcher': 'Ավտոմատ բաշխումը կատարող չգտավ {n} պատվերի համար։ Նշանակեք ձեռքով։',
|
||||
'ord.autoOn': 'Ավտոմատ բաշխումը միացված է',
|
||||
'ord.autoOff': 'Ավտոմատ բաշխումն անջատված է',
|
||||
'ord.autoHint': 'Նոր պատվերն ինքնաբերաբար առաջարկվում է լավագույն ազատ կատարողին։ {minutes} րոպեում պատասխան չկա կամ հրաժարվեց՝ հաջորդին, {tries} փորձից հետո՝ դիսպետչերին։',
|
||||
'ord.back': 'Բոլոր պատվերները',
|
||||
'ord.progress': 'Ընթացք',
|
||||
'ord.details': 'Մանրամասներ',
|
||||
'ord.when': 'Երբ',
|
||||
'ord.where': 'Որտեղ',
|
||||
'ord.minutes': '{n} ր',
|
||||
'ord.params': 'Պարամետրեր',
|
||||
'ord.extras': 'Լրացուցիչ',
|
||||
'ord.note': 'Հաճախորդի մեկնաբանություն',
|
||||
'ord.lang': 'Հաճախորդի լեզուն',
|
||||
'ord.created': 'Ստեղծված',
|
||||
'ord.checklist': 'Ստուգացանկ',
|
||||
'ord.needsPhoto': 'լուսանկար է պետք',
|
||||
'ord.photo': 'Լուսանկար',
|
||||
'ord.history': 'Պատմություն',
|
||||
'ord.client': 'Հաճախորդ',
|
||||
'ord.writeClient': 'Գրել հաճախորդին',
|
||||
'ord.writeProvider': 'Գրել կատարողին',
|
||||
'ord.money': 'Գումար',
|
||||
'ord.base': 'Առանց զեղչի',
|
||||
'ord.discount': 'Զեղչ {pct}%',
|
||||
'ord.payout': 'Կատարողին',
|
||||
'ord.cancelFee': 'Չեղարկման պահում',
|
||||
'ord.payment': 'Վճարում',
|
||||
'ord.markPaid': 'Նշել վճարումը',
|
||||
'ord.confirmPaid': 'Նշե՞լ, որ հաճախորդը վճարել է։',
|
||||
'ord.paidDone': 'Վճարումը նշված է',
|
||||
'ord.actions': 'Գործողություններ',
|
||||
'ord.setStatus': 'Կարգավիճակ՝ {status}',
|
||||
'ord.confirmStatus': 'Տեղափոխե՞լ «{status}»։ Հաճախորդը ծանուցում կստանա։',
|
||||
'ord.statusChanged': 'Կարգավիճակը փոխված է',
|
||||
'ord.reschedule': 'Տեղափոխել',
|
||||
'ord.rescheduleTitle': 'Պատվեր №{n}-ի տեղափոխում',
|
||||
'ord.rescheduleHint': 'Եթե կատարողը զբաղված է նոր ժամին, պատվերը կվերադառնա «Սպասում են կատարողի»։',
|
||||
'ord.rescheduled': 'Տեղափոխված է, կատարողը նույնն է',
|
||||
'ord.rescheduledFree': 'Տեղափոխված է, կատարողը զբաղված է՝ փնտրում ենք նորը',
|
||||
'ord.comment': 'Մեկնաբանություն',
|
||||
'ord.commentPh': 'Օրինակ՝ հաճախորդը խնդրեց հեռախոսով',
|
||||
'ord.cancel': 'Չեղարկել պատվերը',
|
||||
'ord.cancelTitle': 'Պատվերի չեղարկում',
|
||||
'ord.cancelReason': 'Չեղարկման պատճառը',
|
||||
'ord.cancelReasonPh': 'Օրինակ՝ հաճախորդը փոխեց միտքը',
|
||||
'ord.cancelFeeHint': 'Որքան պահել հաճախորդից, ֏։ Սովորաբար 0։',
|
||||
'ord.cancelHint': 'Հաճախորդը և կատարողը ծանուցում կստանան։',
|
||||
'ord.cancelled': 'Պատվերը չեղարկված է',
|
||||
'ord.rating': 'Հաճախորդի գնահատականը',
|
||||
'ord.noComment': 'Առանց մեկնաբանության',
|
||||
'ord.offers': 'Ում է առաջարկվել',
|
||||
'ord.bySystem': 'համակարգ',
|
||||
'ord.provider': 'Կատարող',
|
||||
'ord.unassign': 'Հանել կատարողին',
|
||||
'ord.revoke': 'Հետ կանչել առաջարկը',
|
||||
'ord.confirmUnassign': 'Հանե՞լ կատարողին։ Պատվերը կվերադառնա։',
|
||||
'ord.confirmRevoke': 'Հետ կանչե՞լ առաջարկը։',
|
||||
'ord.unassigned': 'Պատվերը կրկին սպասում է կատարողի',
|
||||
'ord.pendingProvider': 'Առաջարկված է՝ {name}',
|
||||
'ord.pendingCompany': 'Հանձնված է «{name}» ընկերությանը',
|
||||
'ord.byAuto': 'առաջարկել է համակարգը',
|
||||
'ord.minLeft': 'պատասխանի համար ≈ {n} ր',
|
||||
'ord.pickHint': 'Այս ժամին ազատներ՝ ըստ համապատասխանության։',
|
||||
'ord.autoPick': 'Ընտրել ավտոմատ',
|
||||
'ord.autoOffered': 'Առաջարկվեց՝ {name}',
|
||||
'ord.autoNone': 'Ազատ կատարող չգտնվեց',
|
||||
'ord.noFree': 'Այս ժամին բոլորը զբաղված են։',
|
||||
'ord.busy': 'Զբաղված են՝ {n}',
|
||||
'ord.company': 'ընկերություն',
|
||||
'ord.tried': 'արդեն առաջարկվել է',
|
||||
'ord.load': 'այդ օրը պատվերներ՝ {n}',
|
||||
'ord.offer': 'Առաջարկել',
|
||||
'ord.offered': 'Առաջարկն ուղարկված է',
|
||||
'ord.noProvider': 'Կատարող չի նշանակվել։',
|
||||
'ord.ev.created': 'Պատվերը ստեղծված է',
|
||||
'ord.ev.createdByStaff': 'Ստեղծել է թիմը',
|
||||
'ord.ev.offered': 'Առաջարկվել է կատարողին',
|
||||
'ord.ev.autoOffered': 'Ավտոմատ բաշխում՝ առաջարկված',
|
||||
'ord.ev.autoNoCandidate': 'Ավտոմատ բաշխում՝ ազատ չկա',
|
||||
'ord.ev.autoGaveUp': 'Ավտոմատ բաշխումը կանգնեց',
|
||||
'no.title': 'Նոր պատվեր',
|
||||
'no.client': 'Հաճախորդ',
|
||||
'no.clientPh': 'Անուն, @username կամ հեռախոս',
|
||||
'no.noClients': 'Ոչ ոք չգտնվեց',
|
||||
'no.changeClient': 'Այլ հաճախորդ',
|
||||
'no.service': 'Ծառայություն',
|
||||
'no.extras': 'Լրացուցիչ',
|
||||
'no.address': 'Հասցե',
|
||||
'no.addressPh': 'Փողոց, շենք, բնակարան',
|
||||
'no.district': 'Վարչական շրջան',
|
||||
'no.when': 'Օր և ժամ',
|
||||
'no.day': 'Օր',
|
||||
'no.noSlots': 'Այս օրը ազատ ժամ չկա։',
|
||||
'no.otherTime': 'Այլ ժամ (պայմանավորվել ենք կատարողի հետ)',
|
||||
'no.customTime': 'Ժամ',
|
||||
'no.customHint': 'Երևանի ժամով։',
|
||||
'no.note': 'Մեկնաբանություն կատարողի համար',
|
||||
'no.notePh': 'Դոմոֆոնի կոդ, կենդանիներ…',
|
||||
'no.payment': 'Վճարում',
|
||||
'no.hint': 'Գինը՝ հաշվի առնելով բաժանորդագրությունը։ Հաճախորդը ծանուցում կստանա։',
|
||||
'no.create': 'Ձևակերպել պատվերը',
|
||||
'no.created': 'Պատվեր №{n}-ը ձևակերպված է',
|
||||
'prv.title': 'Կատարողներ',
|
||||
'prv.add': 'Ավելացնել',
|
||||
'prv.search': 'Անուն կամ հեռախոս',
|
||||
'prv.status.active': 'Աշխատում են',
|
||||
'prv.status.blocked': 'Արգելափակված',
|
||||
'prv.status.all': 'Բոլորը',
|
||||
'prv.empty': 'Ոչ ոք չգտնվեց։',
|
||||
'prv.col.name': 'Կատարող',
|
||||
'prv.col.rating': 'Վարկանիշ',
|
||||
'prv.col.done': 'Պատվերներ',
|
||||
'prv.col.refused': 'Հրաժարումներ',
|
||||
'prv.col.next': 'Մոտակա պատվերը',
|
||||
'prv.period30': 'Պատվերներ, հրաժարումներ, ցածր գնահատականներ՝ 30 օրում։',
|
||||
'prv.blocked': 'արգելափակված',
|
||||
'prv.onShift': 'հերթափոխում',
|
||||
'prv.offShift': 'հերթափոխում չէ',
|
||||
'prv.notLinked': 'բոտը բացված չէ',
|
||||
'prv.noDocs': 'փաստաթղթեր չկան',
|
||||
'prv.ratings': 'գնահատականներ՝ {n}',
|
||||
'prv.low': 'ցածր՝ {n}',
|
||||
'prv.today': 'այսօր՝ {n}',
|
||||
'prv.back': 'Բոլոր կատարողները',
|
||||
'prv.write': 'Գրել',
|
||||
'prv.edit': 'Խմբագրել',
|
||||
'prv.blockedSince': 'Արգելափակված է {date}-ից։',
|
||||
'prv.unblock': 'Վերադարձնել աշխատանքի',
|
||||
'prv.inviteHint': 'Կատարողը դեռ չի բացել աշխատանքային բոտը՝ ուղարկեք հղումը։',
|
||||
'prv.copyInvite': 'Պատճենել հղումը',
|
||||
'prv.quality': 'Որակ',
|
||||
'prv.days30': '30 օրում',
|
||||
'prv.acceptRate': 'ընդունել է {a}-ը {n}-ից',
|
||||
'prv.refusals': 'հրաժարվել՝ {d}, լռել՝ {e}',
|
||||
'prv.lowRatings': 'գնահատական 3 և ցածր',
|
||||
'prv.upcoming': 'Մոտակա պատվերներ',
|
||||
'prv.noUpcoming': 'Նշանակված պատվերներ չկան։',
|
||||
'prv.recent': 'Վերջին կատարվածները',
|
||||
'prv.balance': 'Վճարման ենթակա',
|
||||
'prv.thisMonth': 'Այս ամիս',
|
||||
'prv.prevMonth': 'Անցյալ',
|
||||
'prv.paidTotal': 'Վճարված',
|
||||
'prv.payout': 'Նշել վճարումը',
|
||||
'prv.payoutTitle': 'Վճարում կատարողին',
|
||||
'prv.amount': 'Գումար, ֏',
|
||||
'prv.balanceHint': 'Պարտք կատարողին՝ {sum}',
|
||||
'prv.payoutNote': 'Ինչպես է վճարվել',
|
||||
'prv.payoutNotePh': 'Կանխիկ / փոխանցում…',
|
||||
'prv.payoutConfirm': 'Վճարված է',
|
||||
'prv.payoutDone': 'Վճարումը նշված է',
|
||||
'prv.rateCompany': 'ընկերության դրույք {v}',
|
||||
'prv.rateOwn': 'դրույք {v}',
|
||||
'prv.ratePreset': '«{name}» նախադրույքով',
|
||||
'prv.work': 'Աշխատանք',
|
||||
'prv.languages': 'Լեզուներ',
|
||||
'prv.districts': 'Շրջաններ',
|
||||
'prv.anyDistrict': 'ցանկացած',
|
||||
'prv.districtsHint': 'Ընտրությունը նախապատվություն է տալիս շրջանում աշխատողներին։',
|
||||
'prv.docs': 'Թույլտվության փաստաթղթեր',
|
||||
'prv.noDocsHint': 'Անձնագիր, պայմանագիր, տեղեկանք՝ փակ պահոցում։',
|
||||
'prv.docTitlePh': 'Անվանում՝ անձնագիր, պայմանագիր…',
|
||||
'prv.upload': 'Վերբեռնել',
|
||||
'prv.docAdded': 'Փաստաթուղթն ավելացված է',
|
||||
'prv.removeDocConfirm': 'Ջնջե՞լ փաստաթուղթը։',
|
||||
'prv.access': 'Թույլտվություն',
|
||||
'prv.block': 'Արգելափակել',
|
||||
'prv.blockTitle': 'Արգելափակել կատարողին',
|
||||
'prv.blockReason': 'Պատճառը',
|
||||
'prv.blockReasonPh': 'Օրինակ՝ բողոքներ, փաստաթղթեր չկան',
|
||||
'prv.blockHint': 'Նոր առաջարկներ չեն լինի։ Նշանակված պատվերները վերանշանակեք ձեռքով։',
|
||||
'prv.resetInvite': 'Նոր հղում բոտի համար',
|
||||
'prv.resetConfirm': 'Ստեղծե՞լ նոր հղում։ Ընթացիկ կապը կհանվի։',
|
||||
'prv.since': 'Մեզ հետ է {date}-ից',
|
||||
'prv.saved': 'Պահպանված է',
|
||||
'prv.addTitle': 'Նոր կատարող',
|
||||
'prv.editTitle': 'Կատարողի պրոֆիլ',
|
||||
'prv.name': 'Անուն',
|
||||
'prv.role': 'Դեր',
|
||||
'prv.company': 'Ընկերություն',
|
||||
'prv.freelance': 'Անհատ կատարող',
|
||||
'prv.schedule': 'Ժամանակացույց',
|
||||
'prv.rate': 'Դրույք',
|
||||
'prv.note': 'Թիմի նշում',
|
||||
'err.REASON_REQUIRED': 'Նշեք պատճառը։',
|
||||
'err.SLOT_UNAVAILABLE': 'Այս ժամը զբաղված է կամ անցել է։',
|
||||
'err.ALREADY_ASSIGNED': 'Պատվերն արդեն նշանակված է։',
|
||||
'err.PROVIDER_BUSY': 'Կատարողը զբաղված է այդ ժամին։',
|
||||
'err.TRANSITION_NOT_ALLOWED': 'Այս քայլը հիմա հասանելի չէ։',
|
||||
'err.CHECKLIST_INCOMPLETE': 'Կատարողը նախ պետք է ավարտի ստուգացանկը։',
|
||||
'err.CONSENT_REQUIRED': 'Հաճախորդը դեռ համաձայնություն չի տվել։',
|
||||
'err.ADDRESS_REQUIRED': 'Նշեք հասցեն և շրջանը։',
|
||||
'err.INVALID_PARAMS': 'Ստուգեք պատվերի պարամետրերը։',
|
||||
'err.OFFER_NOT_ACTIVE': 'Առաջարկն այլևս ակտիվ չէ։',
|
||||
'err.BAD_FILE_TYPE_DOC': 'Միայն լուսանկար կամ PDF։',
|
||||
'audit.bo.orders.assign': 'առաջարկեց պատվերը',
|
||||
'audit.bo.orders.auto': 'գործարկեց ավտոմատ ընտրությունը',
|
||||
'audit.bo.orders.unassign': 'հանեց կատարողին',
|
||||
'audit.bo.orders.transition': 'փոխեց պատվերի կարգավիճակը',
|
||||
'audit.bo.orders.cancel': 'չեղարկեց պատվերը',
|
||||
'audit.bo.orders.reschedule': 'տեղափոխեց պատվերը',
|
||||
'audit.bo.orders.markPaid': 'նշեց վճարումը',
|
||||
'audit.bo.orders.create': 'ձևակերպեց պատվեր',
|
||||
'audit.bo.orders.setAutoSetting': 'փոխեց ավտոմատ բաշխումը',
|
||||
'audit.bo.providers.create': 'ավելացրեց կատարող',
|
||||
'audit.bo.providers.update': 'փոխեց կատարողի պրոֆիլը',
|
||||
'audit.bo.providers.setActive': 'փոխեց կատարողի թույլտվությունը',
|
||||
'audit.bo.providers.resetInvite': 'նոր հղում տվեց կատարողին',
|
||||
'audit.bo.providers.removeDoc': 'ջնջեց կատարողի փաստաթուղթը',
|
||||
'audit.bo.providers.addDoc': 'վերբեռնեց կատարողի փաստաթուղթը',
|
||||
'audit.bo.providers.payout': 'նշեց վճարում կատարողին',
|
||||
'chat.order': 'Պատվեր №{n}',
|
||||
'chat.noOrder': 'Առանց պատվերի',
|
||||
'chat.noOrderNow': 'Այժմ պատվեր չկա',
|
||||
@@ -1235,8 +1943,12 @@ interface Ctx {
|
||||
locale: BoLocale;
|
||||
setLocale: (l: BoLocale) => void;
|
||||
t: T;
|
||||
/** общие переводы проекта: services.<code>.name и т.п. */
|
||||
shared: (key: string) => string;
|
||||
/** общие переводы проекта: services.<code>.name, roles.<ROLE>, params.* и т.п. */
|
||||
shared: (key: string, params?: Record<string, string | number>) => string;
|
||||
/** время по Еревану: 14:00 */
|
||||
time: (d: Date) => string;
|
||||
/** общий t проекта целиком — для хелперов @barev/web (paramsSummary и т.п.) */
|
||||
sharedT: ReturnType<typeof createSharedT>;
|
||||
amd: (n: number) => string;
|
||||
date: (d: Date) => string;
|
||||
dateTime: (d: Date) => string;
|
||||
@@ -1279,10 +1991,12 @@ export function BoI18nProvider({ children }: { children: ReactNode }) {
|
||||
},
|
||||
t: makeT(locale),
|
||||
shared: sharedT,
|
||||
sharedT,
|
||||
amd: (n) => formatAmd(locale as SharedLocale, n),
|
||||
amdShort: (n) => `${compact.format(n)} ֏`,
|
||||
date: (d) => formatDateTime(locale as SharedLocale, d, { day: 'numeric', month: 'short', year: 'numeric' }),
|
||||
dateTime: (d) => formatDateTime(locale as SharedLocale, d, { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }),
|
||||
time: (d) => formatDateTime(locale as SharedLocale, d, { hour: '2-digit', minute: '2-digit' }),
|
||||
};
|
||||
}, [locale]);
|
||||
return <I18nCtx.Provider value={value}>{children}</I18nCtx.Provider>;
|
||||
|
||||
Reference in new issue
Block a user