2022-02-25 16:57:08 +05:00
|
|
|
|
import { Link, useLocation } from 'react-router-dom'
|
2022-03-29 17:03:04 +05:00
|
|
|
|
import { useState, useEffect, memo, useMemo } from 'react'
|
2021-10-14 11:07:11 +05:00
|
|
|
|
import { LineChartOutlined, ProfileOutlined } from '@ant-design/icons'
|
2022-03-29 17:03:04 +05:00
|
|
|
|
import { Table, Tag, Button, Badge, Divider, Modal, Row, Col } from 'antd'
|
2021-12-28 14:41:23 +05:00
|
|
|
|
|
2022-02-07 14:58:38 +05:00
|
|
|
|
import { CompanyView } from '@components/views'
|
|
|
|
|
import LoaderPortal from '@components/LoaderPortal'
|
|
|
|
|
import { invokeWebApiWrapperAsync } from '@components/factory'
|
|
|
|
|
import { makeTextColumn, makeNumericColumnPlanFact } from '@components/Table'
|
2022-03-29 17:03:04 +05:00
|
|
|
|
import { WellCompositeService } from '@api'
|
2022-02-08 19:19:00 +05:00
|
|
|
|
import { hasPermission } from '@utils/permissions'
|
2021-12-28 14:41:23 +05:00
|
|
|
|
import {
|
|
|
|
|
calcAndUpdateStatsBySections,
|
2021-10-14 11:07:11 +05:00
|
|
|
|
makeFilterMinMaxFunction,
|
2021-12-28 14:41:23 +05:00
|
|
|
|
getOperations
|
2022-02-10 14:35:14 +05:00
|
|
|
|
} from '@utils/functions'
|
2022-02-14 17:47:03 +05:00
|
|
|
|
|
|
|
|
|
import { Tvd } from '@pages/WellOperations/Tvd'
|
2022-02-07 14:58:38 +05:00
|
|
|
|
import WellOperationsTable from '@pages/Cluster/WellOperationsTable'
|
2022-03-29 17:03:04 +05:00
|
|
|
|
import NewParamsTable from './NewParamsTable'
|
2021-10-14 11:07:11 +05:00
|
|
|
|
|
|
|
|
|
const filtersMinMax = [
|
2021-10-15 10:52:01 +05:00
|
|
|
|
{ text: 'min', value: 'min' },
|
|
|
|
|
{ text: 'max', value: 'max' },
|
2021-10-14 11:07:11 +05:00
|
|
|
|
]
|
|
|
|
|
|
2022-03-29 16:36:04 +05:00
|
|
|
|
const sortBySectionId = (a, b) => a.sectionId - b.sectionId
|
|
|
|
|
|
2021-10-14 11:07:11 +05:00
|
|
|
|
const filtersSectionsType = []
|
|
|
|
|
const DAY_IN_MS = 1000 * 60 * 60 * 24
|
|
|
|
|
|
2022-02-07 14:58:38 +05:00
|
|
|
|
export const WellCompositeSections = memo(({ idWell, statsWells, selectedSections }) => {
|
2021-10-14 11:07:11 +05:00
|
|
|
|
const [selectedWells, setSelectedWells] = useState([])
|
2022-01-11 16:06:36 +05:00
|
|
|
|
const [wellOperations, setWellOperations] = useState([])
|
2021-10-14 11:07:11 +05:00
|
|
|
|
const [selectedWellsKeys, setSelectedWellsKeys] = useState([])
|
2022-01-11 16:06:36 +05:00
|
|
|
|
const [selectedWellId, setSelectedWellId] = useState(0)
|
|
|
|
|
const [showLoader, setShowLoader] = useState(false)
|
2021-10-14 11:07:11 +05:00
|
|
|
|
const [isTVDModalVisible, setIsTVDModalVisible] = useState(false)
|
|
|
|
|
const [isOpsModalVisible, setIsOpsModalVisible] = useState(false)
|
2021-12-29 11:11:49 +05:00
|
|
|
|
|
2022-02-25 16:57:08 +05:00
|
|
|
|
const location = useLocation()
|
|
|
|
|
|
2022-03-18 19:40:52 +05:00
|
|
|
|
const rows = useMemo(() => {
|
2021-10-14 11:07:11 +05:00
|
|
|
|
const rows = []
|
|
|
|
|
statsWells?.forEach((well) => {
|
|
|
|
|
well.sections?.forEach((section) => {
|
|
|
|
|
if (!filtersSectionsType.some((el) => el.text === section.caption))
|
|
|
|
|
filtersSectionsType.push({ text: section.caption, value: section.caption })
|
|
|
|
|
|
2022-01-11 16:06:36 +05:00
|
|
|
|
const row = {
|
2021-10-14 11:07:11 +05:00
|
|
|
|
key: well.caption + section.id,
|
|
|
|
|
id: well.id,
|
2021-10-14 16:56:29 +05:00
|
|
|
|
sectionId: section.id,
|
2021-10-14 11:07:11 +05:00
|
|
|
|
caption: well.caption,
|
|
|
|
|
sectionType: section.caption,
|
|
|
|
|
sectionWellDepthPlan: section.plan?.wellDepthEnd,
|
|
|
|
|
sectionWellDepthFact: section.fact?.wellDepthEnd,
|
|
|
|
|
sectionBuildDaysPlan: (new Date(section.plan?.end) - new Date(section.plan?.start)) / DAY_IN_MS,
|
|
|
|
|
sectionBuildDaysFact: (new Date(section.fact?.end) - new Date(section.fact?.start)) / DAY_IN_MS,
|
|
|
|
|
sectionRateOfPenetrationPlan: section.plan?.rop,
|
|
|
|
|
sectionRateOfPenetrationFact: section.fact?.rop,
|
|
|
|
|
sectionRouteSpeedPlan: section.plan?.routeSpeed,
|
|
|
|
|
sectionRouteSpeedFact: section.fact?.routeSpeed,
|
|
|
|
|
sectionBhaDownSpeedPlan: section.plan?.bhaDownSpeed,
|
|
|
|
|
sectionBhaDownSpeedFact: section.fact?.bhaDownSpeed,
|
|
|
|
|
sectionBhaUpSpeedPlan: section.plan?.bhaUpSpeed,
|
|
|
|
|
sectionBhaUpSpeedFact: section.fact?.bhaUpSpeed,
|
|
|
|
|
sectionCasingDownSpeedPlan: section.plan?.casingDownSpeed,
|
|
|
|
|
sectionCasingDownSpeedFact: section.fact?.casingDownSpeed,
|
|
|
|
|
nonProductiveTimePlan: section.plan?.nonProductiveHours,
|
|
|
|
|
nonProductiveTimeFact: section.fact?.nonProductiveHours,
|
|
|
|
|
companies: well.companies,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows.push(row)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
calcAndUpdateStatsBySections(rows ?? [], [
|
2021-10-15 10:52:01 +05:00
|
|
|
|
'sectionWellDepthPlan',
|
|
|
|
|
'sectionWellDepthFact',
|
|
|
|
|
'sectionBuildDaysPlan',
|
|
|
|
|
'sectionBuildDaysFact',
|
|
|
|
|
'sectionRateOfPenetrationPlan',
|
|
|
|
|
'sectionRateOfPenetrationFact',
|
|
|
|
|
'sectionRouteSpeedPlan',
|
|
|
|
|
'sectionRouteSpeedFact',
|
|
|
|
|
'sectionBhaDownSpeedPlan',
|
|
|
|
|
'sectionBhaDownSpeedFact',
|
|
|
|
|
'sectionBhaUpSpeedPlan',
|
|
|
|
|
'sectionBhaUpSpeedFact',
|
|
|
|
|
'sectionCasingDownSpeedPlan',
|
|
|
|
|
'sectionCasingDownSpeedFact',
|
|
|
|
|
'nonProductiveTimePlan',
|
|
|
|
|
'nonProductiveTimeFact',
|
2021-10-14 11:07:11 +05:00
|
|
|
|
])
|
|
|
|
|
|
2022-03-18 19:40:52 +05:00
|
|
|
|
return rows
|
2021-10-14 11:07:11 +05:00
|
|
|
|
}, [statsWells])
|
|
|
|
|
|
2022-03-18 19:40:52 +05:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (isOpsModalVisible || selectedWellId <= 0) return
|
|
|
|
|
invokeWebApiWrapperAsync(
|
|
|
|
|
async () => {
|
|
|
|
|
const { operations } = await getOperations(selectedWellId)
|
|
|
|
|
setWellOperations(operations)
|
|
|
|
|
},
|
|
|
|
|
setShowLoader,
|
|
|
|
|
`Не удалось загрузить операции по скважине "${selectedWellId}"`,
|
|
|
|
|
)
|
|
|
|
|
}, [selectedWellId, isOpsModalVisible])
|
|
|
|
|
|
2021-10-14 11:07:11 +05:00
|
|
|
|
useEffect(() => {
|
2021-10-14 16:56:29 +05:00
|
|
|
|
const selected = rows.filter((row) => selectedSections.some(section => (
|
|
|
|
|
section.idWellSrc === row.id && section.idWellSectionType === row.sectionId
|
|
|
|
|
)))
|
|
|
|
|
|
|
|
|
|
setSelectedWells(selected)
|
|
|
|
|
setSelectedWellsKeys(selected.map((row) => row.key))
|
|
|
|
|
}, [rows, selectedSections])
|
2021-10-14 11:07:11 +05:00
|
|
|
|
|
2022-03-29 17:03:04 +05:00
|
|
|
|
const rowSelection = useMemo(() => hasPermission('WellOperation.edit') && {
|
|
|
|
|
selectedRowKeys: selectedWellsKeys,
|
|
|
|
|
onChange: (keys, items) => invokeWebApiWrapperAsync(
|
|
|
|
|
async () => {
|
|
|
|
|
const selectedSections = items.map((row) => ({idWell, idWellSrc: row.id, idWellSectionType: row.sectionId}))
|
|
|
|
|
await WellCompositeService.save(idWell, selectedSections)
|
|
|
|
|
|
|
|
|
|
setSelectedWells(items)
|
|
|
|
|
setSelectedWellsKeys(keys)
|
|
|
|
|
},
|
|
|
|
|
setShowLoader,
|
|
|
|
|
`Не удалось сохранить изменения выбранных секций для композитной скважины "${idWell}"`,
|
|
|
|
|
'Изменение выбранных секций скважины'
|
|
|
|
|
)
|
|
|
|
|
}, [idWell, selectedWellsKeys])
|
|
|
|
|
|
2022-03-18 19:40:52 +05:00
|
|
|
|
const columns = useMemo(() => [
|
2021-12-28 14:41:23 +05:00
|
|
|
|
makeTextColumn('скв №', 'caption', null, null,
|
2022-02-25 16:57:08 +05:00
|
|
|
|
(text, item) => <Link to={{ pathname: `/well/${item?.id}`, state: { from: location.pathname }}}>{text ?? '-'}</Link>
|
2021-10-14 11:07:11 +05:00
|
|
|
|
),
|
2022-03-29 16:36:04 +05:00
|
|
|
|
makeTextColumn('Секция', 'sectionType', filtersSectionsType, sortBySectionId, (text) => text ?? '-'),
|
2021-12-27 15:18:20 +05:00
|
|
|
|
makeNumericColumnPlanFact('Глубина, м', 'sectionWellDepth', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('Продолжительность, ч', 'sectionBuildDays', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('МСП, м/ч', 'sectionRateOfPenetration', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('Рейсовая скорость, м/ч', 'sectionRouteSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('Спуск КНБК, м/ч', 'sectionBhaDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('Подъем КНБК, м/ч', 'sectionBhaUpSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
|
|
|
|
makeNumericColumnPlanFact('Скорость спуска ОК, м/ч', 'sectionCasingDownSpeed', filtersMinMax, makeFilterMinMaxFunction),
|
2021-10-15 10:52:01 +05:00
|
|
|
|
makeNumericColumnPlanFact('НПВ, сут', 'nonProductiveTime', filtersMinMax, makeFilterMinMaxFunction, null, '70px'),
|
2021-10-14 11:07:11 +05:00
|
|
|
|
{
|
2021-10-15 10:52:01 +05:00
|
|
|
|
title: 'TVD',
|
2022-01-11 16:06:36 +05:00
|
|
|
|
render: (value) => (
|
|
|
|
|
<Button onClick={() => {
|
|
|
|
|
setSelectedWellId(value.id)
|
|
|
|
|
setIsTVDModalVisible(true)
|
|
|
|
|
}}>
|
|
|
|
|
<LineChartOutlined />
|
|
|
|
|
</Button>
|
|
|
|
|
),
|
2021-10-14 11:07:11 +05:00
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
2021-10-15 10:52:01 +05:00
|
|
|
|
title: 'Операции',
|
2022-01-11 16:06:36 +05:00
|
|
|
|
render: (value) => (
|
|
|
|
|
<Button onClick={()=> {
|
|
|
|
|
setSelectedWellId(value.id)
|
|
|
|
|
setIsOpsModalVisible(true)
|
|
|
|
|
}}>
|
|
|
|
|
<ProfileOutlined />
|
|
|
|
|
</Button>
|
|
|
|
|
),
|
2021-10-14 11:07:11 +05:00
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
2021-10-19 10:08:32 +05:00
|
|
|
|
title: 'Участники',
|
2021-10-15 10:52:01 +05:00
|
|
|
|
dataIndex: 'companies',
|
2021-12-28 14:41:23 +05:00
|
|
|
|
render: (item) => item?.map((company) => (
|
|
|
|
|
<Tag key={company.caption} color={'blue'}>
|
|
|
|
|
<CompanyView company={company} />
|
|
|
|
|
</Tag>
|
|
|
|
|
)) ?? '-',
|
2021-10-14 11:07:11 +05:00
|
|
|
|
},
|
2022-03-18 19:40:52 +05:00
|
|
|
|
], [location.pathname])
|
2021-10-14 11:07:11 +05:00
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Table
|
|
|
|
|
columns={columns}
|
|
|
|
|
dataSource={rows}
|
2021-10-15 10:52:01 +05:00
|
|
|
|
size={'small'}
|
2021-10-14 11:07:11 +05:00
|
|
|
|
bordered
|
|
|
|
|
scroll={{ x: true, y: 620 }}
|
|
|
|
|
rowSelection={rowSelection}
|
|
|
|
|
pagination={false}
|
|
|
|
|
/>
|
|
|
|
|
<Divider />
|
2021-10-15 10:52:01 +05:00
|
|
|
|
<Badge.Ribbon text={'комбинированная скважина'} color={'gray'}>
|
2021-10-14 11:07:11 +05:00
|
|
|
|
<h3>Выбранные секции</h3>
|
|
|
|
|
</Badge.Ribbon>
|
|
|
|
|
<Table
|
|
|
|
|
columns={columns}
|
|
|
|
|
dataSource={selectedWells}
|
|
|
|
|
rowSelection={rowSelection}
|
2021-10-15 10:52:01 +05:00
|
|
|
|
size={'small'}
|
2021-10-14 11:07:11 +05:00
|
|
|
|
bordered
|
|
|
|
|
scroll={{ x: true }}
|
|
|
|
|
pagination={false}
|
|
|
|
|
/>
|
2022-01-11 16:06:36 +05:00
|
|
|
|
<Row justify={'end'} style={{ margin: '1rem 0' }}>
|
|
|
|
|
<Col>
|
2022-03-29 17:03:04 +05:00
|
|
|
|
<NewParamsTable idWell={idWell} selectedWellsKeys={selectedWellsKeys} />
|
2022-01-11 16:06:36 +05:00
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
2021-10-14 11:07:11 +05:00
|
|
|
|
|
|
|
|
|
<Modal
|
2021-10-15 10:52:01 +05:00
|
|
|
|
title={'TVD'}
|
2021-10-14 11:07:11 +05:00
|
|
|
|
centered
|
|
|
|
|
visible={isTVDModalVisible}
|
|
|
|
|
onCancel={() => setIsTVDModalVisible(false)}
|
|
|
|
|
width={1500}
|
|
|
|
|
footer={null}
|
|
|
|
|
>
|
2022-03-29 14:25:31 +05:00
|
|
|
|
<Tvd idWell={selectedWellId} style={{ height: '80vh' }} />
|
2021-10-14 11:07:11 +05:00
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<Modal
|
2021-10-15 10:52:01 +05:00
|
|
|
|
title={'Операции'}
|
2021-10-14 11:07:11 +05:00
|
|
|
|
centered
|
|
|
|
|
visible={isOpsModalVisible}
|
|
|
|
|
onCancel={() => setIsOpsModalVisible(false)}
|
|
|
|
|
width={1500}
|
|
|
|
|
footer={null}
|
|
|
|
|
>
|
|
|
|
|
<LoaderPortal show={showLoader}>
|
|
|
|
|
<WellOperationsTable wellOperations={wellOperations} />
|
|
|
|
|
</LoaderPortal>
|
|
|
|
|
</Modal>
|
|
|
|
|
</>
|
2021-10-15 10:52:01 +05:00
|
|
|
|
)
|
2022-02-07 14:58:38 +05:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export default WellCompositeSections
|