fix(pwa): в штрафах «погашен», а не «оплачен»

Слово «оплачен» водитель читает как «я ничего не должен», а постановление к тому
моменту оплачено парком — не им. Поэтому в списке и карточке состояние теперь
«не погашен / погашен / не выставлялся / уточняется», долг в шапке берётся из
баланса 1С, а карточка объясняет расхождение сумм: «постановление — 750 ₽, парк
оплатил его со скидкой и выставил вам фактическую сумму».

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 17:36:01 +10:00
co-authored by Claude Opus 5
parent f4a9da25cf
commit eac59b823c
5 changed files with 104 additions and 32 deletions
+18 -9
View File
@@ -3,6 +3,7 @@ import { useQuery } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import { ChevronRight, Image as ImageIcon } from "lucide-react";
import { getFines } from "@/api/driver";
import { fineStatusText, isOwed } from "@/lib/fineStatus";
import { formatDate, formatMoney } from "@/lib/format";
import { OperationIcon } from "@/components/operationIcon";
import { Spinner } from "@/components/Spinner";
@@ -13,6 +14,11 @@ import { Spinner } from "@/components/Spinner";
* Строка «Долг по штрафам −5 156 ₽» на балансе не отвечает на вопрос «за что»,
* и водитель идёт выяснять звонком. Здесь он видит каждое постановление, а в
* карточке — фотографию с камеры.
*
* Долг в шапке берём из баланса 1С, а не суммой строк: постановление парк гасит
* авансом, и по бумагам ГИБДД оно закрыто в тот же день — долг перед парком от
* этого никуда не девается. Список без этой оговорки показывал бы «неоплаченных
* нет» при −5 156 ₽ на главном экране.
*/
export function FinesPage() {
const nav = useNavigate();
@@ -29,14 +35,19 @@ export function FinesPage() {
<h1 className="text-lg font-extrabold mb-1">Штрафы</h1>
<p className="text-muted text-xs mb-4">
{data
? data.open_count > 0
? `Не оплачено: ${data.open_count} на ${formatMoney(data.open_sum)}`
: "Неоплаченных нет"
? data.debt !== 0 || data.open_count > 0
? `Долг по штрафам ${formatMoney(data.debt)} · не погашено: ${data.open_count}`
: "Долгов по штрафам нет"
: " "}
</p>
<p className="text-muted text-[11px] mb-3 leading-4">
Постановление в ГИБДД оплачивает парк как правило, сразу и со скидкой.
Вы возвращаете парку начисленную сумму: она и складывается в долг по штрафам.
</p>
<div className="flex gap-1.5 mb-3">
{([["open", "Неоплаченные"], ["all", "Все"]] as const).map(([key, label]) => (
{([["open", "Не погашены"], ["all", "Все"]] as const).map(([key, label]) => (
<button
key={key}
onClick={() => setTab(key)}
@@ -58,7 +69,7 @@ export function FinesPage() {
</div>
) : items.length === 0 ? (
<p className="text-muted text-sm text-center py-10">
{tab === "open" ? "Неоплаченных штрафов нет" : "Штрафов не найдено"}
{tab === "open" ? "Непогашенных штрафов нет" : "Штрафов не найдено"}
</p>
) : (
<div>
@@ -78,10 +89,8 @@ export function FinesPage() {
</span>
</span>
<span className="shrink-0 text-right">
<b className={f.paid ? "text-muted" : "text-neg"}>{formatMoney(f.amount)}</b>
<span className="block text-muted text-[11px]">
{f.cancelled ? "отменён" : f.paid ? "оплачен" : "не оплачен"}
</span>
<b className={isOwed(f) ? "text-neg" : "text-muted"}>{formatMoney(f.amount)}</b>
<span className="block text-muted text-[11px]">{fineStatusText(f)}</span>
</span>
<ChevronRight size={16} className="text-muted shrink-0" />
</button>