feat: форма «Заявка на оплату» (СТ/потребность, счёт через OCR и ИИ) #27
@@ -20,6 +20,12 @@ export interface IPreviousPayment {
|
||||
/** Уникальный код заявки на оплату. */
|
||||
code: string;
|
||||
amount: number;
|
||||
/** Id элемента списка данных — для ссылки на заявку. Нет у снимков, сохранённых до появления ссылок. */
|
||||
id?: number;
|
||||
/** Список партиции (серверный относительный URL), где лежит заявка; '' — текущая. */
|
||||
listId?: string;
|
||||
/** Статус заявки на момент чтения. */
|
||||
status?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,8 @@ import * as React from 'react';
|
||||
import styles from './PaymentSections.module.scss';
|
||||
import { FormField, TextInput, TextArea } from '../../../shared/ui';
|
||||
import { formatAmount, overLimitAmount, previousPaymentsTotal } from '../amounts';
|
||||
import { ISectionProps } from '../model';
|
||||
import { FORM_ID, ISectionProps } from '../model';
|
||||
import { routeUrl } from '../../../shared/routing';
|
||||
import { AmountInput } from './AmountInput';
|
||||
|
||||
/**
|
||||
@@ -51,20 +52,35 @@ export const AmountsSection: React.FC<ISectionProps> = ({ data, set }) => {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер заявки на оплату</th>
|
||||
<th>Статус</th>
|
||||
<th className={styles.num}>Сумма оплаты</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.PreviousPayments.map((p) => (
|
||||
<tr key={p.code}>
|
||||
<td>{p.code}</td>
|
||||
<td>
|
||||
{p.id ? (
|
||||
<a
|
||||
className={styles.link}
|
||||
href={routeUrl({ mode: 'approve', nav: 'new', formKey: FORM_ID, itemId: p.id, listId: p.listId || undefined })}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{p.code}
|
||||
</a>
|
||||
) : (
|
||||
p.code
|
||||
)}
|
||||
</td>
|
||||
<td>{p.status || ''}</td>
|
||||
<td className={styles.num}>{formatAmount(p.amount)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Итого ранее</td>
|
||||
<td colSpan={2}>Итого ранее</td>
|
||||
<td className={styles.num}>{formatAmount(previousTotal)}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
||||
@@ -108,3 +108,13 @@
|
||||
grid-column: 1 / -1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: $navy-700;
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: $gold-600;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -1,6 +1,6 @@
|
||||
import { getSP } from '../../../shared/pnp/pnpjs';
|
||||
import { dataListTitle } from '../../../shared/listTitles';
|
||||
import { REQUEST_STATUS } from '../../../shared/approval';
|
||||
import { REQUEST_STATUS, currentPartitionForPageUrl } from '../../../shared/approval';
|
||||
import { FORM_ID, IPreviousPayment } from '../model';
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,14 @@ export async function loadPreviousPayments(basisKey: string, excludeId?: number)
|
||||
.filter(`BasisKey eq '${safeKey}'`)
|
||||
.top(MAX_PAYMENTS)()) as IPaymentRow[];
|
||||
|
||||
const listId = currentPartitionForPageUrl(FORM_ID)?.listId || '';
|
||||
return rows
|
||||
.filter((row) => row.Id !== excludeId && NOT_COUNTED_STATUSES.indexOf(row.RequestStatus || '') === -1)
|
||||
.map((row) => ({ code: row.RequestUniqueCode || `№${row.Id}`, amount: Number(row.PayAmount || 0) }));
|
||||
.map((row) => ({
|
||||
code: row.RequestUniqueCode || `№${row.Id}`,
|
||||
amount: Number(row.PayAmount || 0),
|
||||
id: row.Id,
|
||||
listId,
|
||||
status: row.RequestStatus || ''
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user