asb_cloud_front/ReportEditor.jsx
2022-07-27 11:44:24 +05:00

500 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { DatePicker, Descriptions, Divider, Form, Input, InputNumber, Modal, Select, Space, Table } from 'antd'
import { memo, useCallback, useEffect, useState } from 'react'
import moment from 'moment'
import { useIdWell } from '@asb/context'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { makeColumn, makeGroupColumn } from '@components/Table'
import { DailyReportService } from '@api'
import { Tabs } from 'antd'
const { Item: RawItem } = Form
const { Summary } = Table
const { TabPane } = Tabs;
const onChange = (key) => {
console.log(key);
};
const Item = memo(({ style, ...other }) => <RawItem style={{ margin: 0, ...style }} {...other} />)
const table1Columns = [
makeGroupColumn('Отчётный период', [
makeColumn('От (дата, время)', 'dateStart', { width: 200, render: (_, { disabled, onChange, checkIsDateBusy }) => (
<Item name={'reportDate'}>
<DatePicker
onChange={onChange}
disabled={disabled}
format={'DD.MM.YYYY'}
style={{ width: '100%' }}
disabledDate={checkIsDateBusy}
/>
</Item>
)}),
]),
makeGroupColumn('Забой за отчётный период, м', [
makeColumn('От', 'depthStart', { width: 200, render: () => (
<Item name={'wellDepthIntervalStartDate'}>
<InputNumber style={{ width: '100%' }} />
</Item>
)}),
makeColumn('До', 'depthEnd', { width: 200, render: () => (
<Item name={'wellDepthIntervalFinishDate'}>
<InputNumber style={{ width: '100%' }} />
</Item>
)}),
])
]
const cellData = {
width: 200,
render: (name) => (
<Item name={name}>
<InputNumber style={{ width: '100%' }} />
</Item>
)
}
const table2Columns = [
makeColumn('Работа модулей САУБ', 'label', { width: 400 }),
makeColumn('Часов:', 'hours', cellData),
makeColumn('Метров:', 'meters', cellData),
]
const table2Data = [
{ key: '1', label: 'АПД (автоматическая подача долота), ч/м:', hours: 'workTimeSAUB', meters: 'penetrationSAUB' },
{ key: '2', label: 'Спин Мастер (осцилляция), ч/м:', hours: 'workTimeSpinMaster', meters: 'penetrationSpinMaster' },
{ key: '3', label: 'Торк Мастер (демпфирование), ч/м:', hours: 'workTimeTorkMaster', meters: 'penetrationTorkMaster' },
]
const table3Columns = [
makeGroupColumn('Бурение в роторе (за отчётный период) с использованием САУБ-1', [
makeColumn('Проходка', 'sinking', cellData),
makeColumn('Часы бурения', 'hours', cellData),
makeColumn('Среднее диф. Давление', 'pressure', cellData),
]),
]
const table3Data = [{ key: '', sinking: 'penetrationInRotor', hours: 'numberDrillingHours', pressure: 'avgDiffDropRotor' }]
const table4Columns = [
makeGroupColumn('Бурение в слайде (за отчётный период) с использованием САУБ-1', [
makeColumn('Проходка', 'sinking', cellData),
makeColumn('Часы бурения', 'hours', cellData),
makeColumn('Среднее диф. Давление', 'pressure', cellData),
]),
]
const table4Data = [{ key: '', sinking: 'penetrationInSlide', hours: 'drillingTimeInRotor', pressure: 'avgDiffPressureSlide' }]
const table6Columns = [
makeGroupColumn('БЕЗМЕТРАЖНЫЕ РАБОТЫ', [
makeColumn('Подготовка ствола скважины к наращиванию', 'l_label', { colSpan: 2, width: 200 }),
makeColumn('', 'l_value', { colSpan: 0, ...cellData }),
makeColumn('Наращивание', 'r_label', { colSpan: 2, width: 200 }),
makeColumn('', 'r_value', { colSpan: 0, ...cellData }),
]),
]
const table6Data = [{
key: '1',
l_label: 'Норматив на одну операцию, (мин):',
r_label: 'Норматив на одну операцию, (мин):',
l_value: 'standardTimeBarrelPreparation',
r_value: 'standardTimeExtension'
}, {
key: '2',
l_label: 'Проработка при бур, факт (ч):',
r_label: 'Наращивание, факт (ч):',
l_value: 'actualTimeBarrelPreparation',
r_value: 'actualTimeExtension'
}]
const table6Summary = () => (
<Summary.Row>
<Summary.Cell colSpan={2}>
Краткие причины: доп проработки при переходе из слайда в ротор, в середине свечи.
</Summary.Cell>
<Summary.Cell colSpan={2}>
Краткие причины: нехватка пальцев на обоих руках у первого помощника бурильщика.
</Summary.Cell>
</Summary.Row>
)
const table2Summary = () => (
<Summary.Row>
<Summary.Cell>МСЕ, колличество запусков, раз:</Summary.Cell>
<Summary.Cell colSpan={2}>
<Item name={'countLaunchesMSE'}>
<InputNumber style={{ width: '100%' }} />
</Item>
</Summary.Cell>
</Summary.Row>
)
export const ReportEditor = memo(({ visible, data, onDone, onCancel, checkIsDateBusy }) => {
const [form] = Form.useForm()
const [isInvalid, setIsInvalid] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const idWell = useIdWell()
const setFields = useCallback((data) => form.setFieldsValue(data ? {
...data,
rotorDrillingModes: Array.isArray(data.rotorDrillingModes) ? data.rotorDrillingModes ?? [] : [],
slideDrillingModes: Array.isArray(data.slideDrillingModes) ? data.slideDrillingModes ?? [] : [],
reportDate: moment.utc(data.reportDate).local(),
} : {}), [form])
useEffect(() => setFields(data), [data, setFields])
const onFormChange = useCallback(async () => await form.validateFields()
.then(() => setIsInvalid(false))
.catch(() => setIsInvalid(true))
, [form])
const onFormFinish = useCallback((formData) => invokeWebApiWrapperAsync(
async () => {
if (data)
await DailyReportService.update(idWell, data.reportDate, formData)
else
await DailyReportService.add(idWell, formData)
onDone?.(formData)
form.resetFields()
},
setIsLoading,
'Не удалось сохранить суточный рапорт',
'Сохранение суточного рапорта',
), [data, onDone, idWell, form])
const onDateChange = useCallback((date) => invokeWebApiWrapperAsync(
async () => {
if (data) return
const newData = await DailyReportService.getOrGenerate(idWell, date.format('YYYY-MM-DD') + 'Z')
if (checkIsDateBusy(moment(newData.reportDate)))
throw new Error('Рапорт на данную дату уже существует')
setFields(newData)
},
setIsLoading,
(e) => `Не удалось загрузить автозаполняемые данные для нового рапорта: ${e}`,
'Получение автозаполняемых данных суточного рапорта',
), [idWell, data, setFields, checkIsDateBusy])
return (
<Modal
centered
width={1200}
visible={visible}
onCancel={onCancel}
okText={'Сохранить'}
title={data ?
<>Суточная сводка бурения скважины {data?.wellName} куст {data?.clusterName}</> :
<>Новая cуточная сводка бурения скважины</>
}
onOk={form.submit}
okButtonProps={{
disabled: isInvalid,
loading: isLoading,
}}
>
<LoaderPortal show={isLoading}>
<Form
form={form}
onFinish={onFormFinish}
onChange={onFormChange}
>
<Tabs defaultActiveKey="1" onChange={onChange}>
<TabPane tab="Заголовок" key="1">
<div>Имя скважины:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>Имя кластера:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>Заказчик:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>Подрядчик:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>Дата рапорта:</div>
<DatePicker
disabled={!!data}
format={'DD.MM.YYYY'}
onChange={onDateChange}
disabledDate={checkIsDateBusy}
/>
<Divider />
<div>Глубина забоя на дату начала интервала:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Глубина забоя на дату окончания интервала:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Глубина забоя по стволу на окончание отчетного периода:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Глубина забоя по вертикали на дату окончания отчетного периода:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Зенитный угол на дату окончания отчетного периода:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Азимутальный угол на дату окончания отчетного периода:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>ФИО бурильщиков:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>ФИО бурильщиков:</div>
<Input.TextArea rows={1}
/>
<Divider />
<div>Время работы АПД:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Время работы спин мастер:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Время работы torqueMaster:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Количество метров пробуренных с включенным АПД:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Количество метров пробуренных с включенным Спин мастер:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Количество метров пробуренных с включенным torqueMaster:</div>
<InputNumber style={{ width: '100%' }}
/>
<Divider />
<div>Количество запусков МСЕ:</div>
<InputNumber style={{ width: '100%' }}
/>
</TabPane>
<TabPane tab="КНБК" key="2">
<div>КНБК описание:</div>
<Input.TextArea rows={1}
/><Divider /><div>Бурение с наращиваниями в инт. 2195-2763м. Время начала:</div>
<Input.TextArea rows={1}
/><Divider /><div>Бурение с наращиваниями в инт. 2195-2763м. Время окончания:</div>
<Input.TextArea rows={1}
/><Divider /><div>Промывка. Время начала:</div>
<Input.TextArea rows={1}
/><Divider /><div>Промывка. Время окончания:</div>
<Input.TextArea rows={1}
/><Divider /><div>Подьем КНБК. Время начала:</div>
<Input.TextArea rows={1}
/><Divider /><div>Подьем КНБК. Время окончания:</div>
<Input.TextArea rows={1}
/><Divider /><div>Спуск КНБК. Время начала:</div>
<Input.TextArea rows={1}
/><Divider /><div>Бурение с наращиваниями в инт. 2763-2850м. Время начала:</div>
<Input.TextArea rows={1}
/><Divider /><div>Бурение с наращиваниями в инт. 2763-2850м. Время окончания:</div>
<Input.TextArea rows={1}
/>
</TabPane>
<TabPane tab="Безметражные работы" key="3">
<div>Нормативное время на одну операцию по подготовке ствола скважины к наращиванию:</div>
<InputNumber style={{ width: '100%' }}/>
<Divider /><div>Нормативное время на одну операцию по наращиванию:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<Divider /><div>Фактическое время проработок при подготовке ствола скважины к наращиванию.:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Фактическое время наращиваний:</div>
<InputNumber style={{ width: '100%' }}/>
</TabPane>
<TabPane tab="Баланс времени" key="4">
<div>Бурение:</div>
<Input.TextArea rows={1}/>
<Divider /><div>Промывка:</div>
<InputNumber style={{ width: '100%' }}/>
<Divider /><div>Наращивание:</div>
<Input.TextArea rows={1}/><Divider />
<div>Проработка:</div>
<Input.TextArea rows={1}/><Divider />
<div>Расширка:</div>
<Input.TextArea rows={1}/><Divider />
<div>Ремонт:</div>
<Input.TextArea rows={1}/><Divider />
<div>КНБК:</div>
<Input.TextArea rows={1}/><Divider />
<div>СПО:</div>
<Input.TextArea rows={1}/><Divider />
<div>ПЗР:</div>
<Input.TextArea rows={1}/><Divider />
<div>ПВО:</div>
<Input.TextArea rows={1}/><Divider />
<div>ПГР:</div>
<Input.TextArea rows={1}/><Divider />
<div>ГИС:</div>
<Input.TextArea rows={1}/><Divider />
<div>ОЗЦ:</div>
<Input.TextArea rows={1}/><Divider />
<div>Тех.работы:</div>
<Input.TextArea rows={1}/><Divider />
<div>Снятие замера:</div>
<Input.TextArea rows={1}/><Divider />
<div>Цементирование:</div>
<Input.TextArea rows={1}/><Divider />
<div>Простой:</div>
<Input.TextArea rows={1}/><Divider />
<div>НПВ:</div>
<Input.TextArea rows={1}/><Divider />
</TabPane>
<TabPane tab="САУБ" key="5">
<div>Режимы бурения на роторе:</div>
<Input.TextArea rows={1}/>
<Divider /><div>Режимы бурения на слайде:</div>
<InputNumber style={{ width: '100%' }}/>
<Divider /><div>Количество метров пробуренных в роторе за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Количество часов бурения в роторе за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Средний диф. перепад в роторе за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Количество метров пробуренных в слайде за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Время бурения в роторе за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Средний диф. перепад в слайде за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Плановая МСП за секцию:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Общее время бурения за секцию:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Общая проходка за секцию:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Количество наращиваний за отчетный период:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Отклонение относительно ГГД:</div>
<InputNumber style={{ width: '100%' }}/><Divider />
<div>Указываются все причины, которые влияют на снижение МСП.:</div>
<Input.TextArea rows={1}/>
</TabPane>
<TabPane tab="Подписи" key="6">
<div>ФИО Мастера буровой:</div>
<Input.TextArea rows={1}/>
<Divider /><div>ФИО супервайзера:</div>
<Input.TextArea rows={1}/>
</TabPane>
</Tabs>
{/* <Item name={'reportDate'} label={'Дата рапорта'} rules={[{ required: true }]}>
<DatePicker
disabled={!!data}
format={'DD.MM.YYYY'}
onChange={onDateChange}
disabledDate={checkIsDateBusy}
/>
</Item>
<Divider />
<Space direction={'vertical'} size={'middle'} style={{ width: '100%' }}>
<Item name={'customer'} label={'Заказчк'}><Input /></Item>
<Item name={'contractor'} label={'Подрядчик'}><Input /></Item>
<Table
bordered
size={'small'}
columns={table1Columns}
dataSource={[{ key: '', disabled: !!data, onChange: onDateChange, checkIsDateBusy }]}
pagination={false}
/>
<Item label={'Бурильщик 1 смена'} name={'firstDriller'}><Input /></Item>
<Item label={'Бурильщик 2 смена'} name={'secondDriller'}><Input /></Item>
<Table
bordered
size={'small'}
columns={table2Columns}
dataSource={table2Data}
summary={table2Summary}
pagination={false}
/>
<Item name={'bhaDescription'} label={'Описание КНБК'}>
<Input.TextArea rows={4} />
</Item>
<Table bordered size={'small'} columns={table6Columns} dataSource={table6Data} pagination={false} summary={table6Summary} />
<Descriptions column={1} size={'small'} bordered>
<Descriptions.Item label={'Бурение в роторе:'}>
<Item name={'rotorDrillingModes'}>
<Select mode={'tags'} style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
<Descriptions.Item label={'Бурение в слайде:'}>
<Item name={'slideDrillingModes'}>
<Select mode={'tags'} style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
</Descriptions>
<Table bordered size={'small'} columns={table3Columns} dataSource={table3Data} pagination={false} />
<Table bordered size={'small'} columns={table4Columns} dataSource={table4Data} pagination={false} />
<Item label={'Плановая мех скорость'} name={'sectionROPPlan'}>
<InputNumber style={{ width: '100%' }}/>
</Item>
<Descriptions bordered size={'small'} column={1}>
<Descriptions.Item label={'Время бурения за секцию'}>
<Item name={'sectionDrillingTimeTotal'}>
<InputNumber style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
<Descriptions.Item label={'Проходка за секцию'}>
<Item name={'sectionPenetrationTotal'}>
<InputNumber style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
<Descriptions.Item label={'Кол-во наращиваний'}>
<Item name={'extensionsCount'}>
<InputNumber style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
<Descriptions.Item label={'Отклонение от ГГД +/-, сут'}>
<Item name={'deviationFromTVD'}>
<InputNumber style={{ width: '100%' }} />
</Item>
</Descriptions.Item>
</Descriptions>
<Item name={'declinesReasonsROP'} label={'Примечание:'}>
<Input.TextArea rows={4} />
</Item>
<Item label={'Мастер буровой'} name={'drillingMaster'}><Input /></Item>
<Item label={'Супервайзер'} name={'supervisor'}><Input /></Item>
</Space> */}
</Form>
</LoaderPortal>
</Modal>
)
})
export default ReportEditor