feat: комментарий после итога сметы в командировке
Необязательное поле «Комментарий» (колонка TripComment) после итога сметы; в просмотре пустой комментарий не показывается. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,8 @@
|
||||
привязкой, у «Другого расхода» — название, у суточных — кол-во МРП.
|
||||
- Хранение: `TripEstimateJson` (статьи + total), читаемо — `TripEstimate` (позиция на
|
||||
строку), итог числом — `TripEstimateTotal`. Просмотр/печать — таблица по статьям.
|
||||
- **Комментарий** (с 10-23, `TripComment`, Note) — необязательное поле после итога сметы; в
|
||||
просмотре пустой не показывается.
|
||||
- **Обязательство** по авансовому отчёту (текст бланка) — флажок, без него не отправить.
|
||||
- **Дата подачи** (`SubmitDate`, общий столбец сайта) — ставится сегодняшней, пока заявку
|
||||
можно править (см. shared/submitDate.ts).
|
||||
|
||||
@@ -33,6 +33,7 @@ export async function loadBusinessTripRequest(itemId: number, listId?: string):
|
||||
'TripRouteJson',
|
||||
'TripTasksJson',
|
||||
'TripEstimateJson',
|
||||
'TripComment',
|
||||
'TripObligationAccepted',
|
||||
'RequestStatus',
|
||||
'RequestUniqueCode',
|
||||
@@ -53,6 +54,7 @@ export async function loadBusinessTripRequest(itemId: number, listId?: string):
|
||||
Route: parseRoute(item.TripRouteJson),
|
||||
Tasks: parseTasks(item.TripTasksJson),
|
||||
Estimate: parseEstimate(item.TripEstimateJson),
|
||||
TripComment: (item.TripComment as string) || '',
|
||||
TripObligationAccepted: item.TripObligationAccepted === true
|
||||
};
|
||||
|
||||
|
||||
@@ -315,6 +315,8 @@ export interface IFormData {
|
||||
|
||||
/** Смета: основные статьи + добавленные (суммы вводятся вручную). */
|
||||
Estimate: IEstimateArticle[];
|
||||
/** Комментарий к заявке — после итога сметы, необязательный. */
|
||||
TripComment: string;
|
||||
|
||||
/** Сотрудник принял обязательство по авансовому отчёту (см. OBLIGATION_TEXT). */
|
||||
TripObligationAccepted: boolean;
|
||||
@@ -397,6 +399,7 @@ export const EMPTY_DATA: IFormData = {
|
||||
// Новая заявка сразу показывает одну пустую строку задачи — понятнее, что заполнять.
|
||||
Tasks: [''],
|
||||
Estimate: EMPTY_ESTIMATE,
|
||||
TripComment: '',
|
||||
TripObligationAccepted: false
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
{ "internalName": "TripEstimate", "title": "Смета на командировку", "type": "Note" },
|
||||
{ "internalName": "TripEstimateJson", "title": "Смета на командировку (JSON)", "type": "Note" },
|
||||
{ "internalName": "TripEstimateTotal", "title": "Итого по смете, тенге", "type": "Number" },
|
||||
{ "internalName": "TripComment", "title": "Комментарий", "type": "Note" },
|
||||
|
||||
{ "internalName": "TripObligationAccepted", "title": "Обязательство по авансовому отчёту принято", "type": "Boolean" }
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import styles from './EstimateSection.module.scss';
|
||||
import { CollapseSection, useFormReadOnly } from '../../../shared/ui';
|
||||
import { CollapseSection, FormField, TextArea, useFormReadOnly } from '../../../shared/ui';
|
||||
import { ISectionProps } from '../model';
|
||||
import { EstimateEditor } from '../components/estimate/EstimateEditor';
|
||||
import { EstimateTable } from '../components/estimate/EstimateTable';
|
||||
@@ -9,7 +9,8 @@ import { EstimateSummary } from '../components/estimate/EstimateSummary';
|
||||
/**
|
||||
* Смета на командировку. Заполнение — карточками статей с позициями, привязанными
|
||||
* к точкам и участкам маршрута (EstimateEditor); просмотр и печать — таблицей.
|
||||
* Итог с долями и разбивкой по объектам — в обоих режимах.
|
||||
* Итог с долями и разбивкой по объектам — в обоих режимах. После итога —
|
||||
* необязательный комментарий к заявке.
|
||||
*/
|
||||
export const EstimateSection: React.FC<ISectionProps> = ({ data, set }) => {
|
||||
const readOnly = useFormReadOnly();
|
||||
@@ -26,6 +27,12 @@ export const EstimateSection: React.FC<ISectionProps> = ({ data, set }) => {
|
||||
<EstimateEditor data={data} set={set} />
|
||||
)}
|
||||
</div>
|
||||
{/* Пустой комментарий в просмотре не показываем — пустое поле только мешает читать. */}
|
||||
{(!readOnly || data.TripComment.trim()) && (
|
||||
<FormField label="Комментарий" htmlFor="TripComment" full>
|
||||
<TextArea id="TripComment" value={data.TripComment} onChange={(v) => set('TripComment', v)} rows={3} />
|
||||
</FormField>
|
||||
)}
|
||||
</CollapseSection>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -56,6 +56,7 @@ function buildItem(data: IFormData, status: string, employeeId: number, employee
|
||||
TripEstimateJson: serializeEstimate(data.Estimate),
|
||||
// Итог дублируется числовой колонкой — для отчётов и сортировки в SP.
|
||||
TripEstimateTotal: estimateTotal(data.Estimate),
|
||||
TripComment: data.TripComment.trim() || null,
|
||||
|
||||
TripObligationAccepted: data.TripObligationAccepted
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user