import { Component, FC, useEffect, useState, createContext, useContext, cloneElement } from 'react' import { useSearchParams } from 'react-router-dom'; import { State, DataResult } from "@progress/kendo-data-query"; import { HeaderWrapper } from '../../../../_metronic/layout/components/header'; import { SubHeader } from '../../../../_metronic/layout/components/header/SubHeader'; import { PageHeader } from '../../../../_metronic/layout/components/header/pageHeader/PageHeader'; import { IntlProvider, LocalizationProvider } from '@progress/kendo-react-intl'; import { GetTrainingPlanById, TrainingPlanSetIsCostActive } from '../../../services/TrainingPlanService'; import { PostTrainingPlanInvoiceDistribution, DeleteTrainingPlanInvoiceDistribution, GetTrainingPlanInvoiceDistributionCompanies, PutTrainingPlanInvoiceDistribution, GetTrainingPlanInvoiceDistributionList } from '../../../services/TrainingPlanInvoiceDistributionService'; import Endpoints from '../../../enums/Endpoints'; import { Grid, GridToolbar, GridColumn as Column, GridDataStateChangeEvent, GridCellProps, GridItemChangeEvent } from "@progress/kendo-react-grid"; import './Training.css' import { SimpleGridDataLoader } from '../../../modules/grid/SimpleGridDataLoader'; import { Dialog, DialogActionsBar } from "@progress/kendo-react-dialogs"; import { Button } from "@progress/kendo-react-buttons"; import { TrainingPlanInvoiceDistribution } from '../../../models/TrainingPlanInvoiceDistribution'; import { UpdateTrainingPlanInvoiceDistribution } from '../../../models/UpdateTrainingPlanInvoiceDistribution'; import { DropDownList, DropDownListChangeEvent, } from "@progress/kendo-react-dropdowns"; import { GetVatList } from '../../../services/VatService'; import { GetInvoiceTypeList } from '../../../services/InvoiceTypeService'; import { UpdateTrainingPlanInvoice } from '../../../models/UpdateTrainingPlanInvoice'; import { DeleteInvoiceContentDoc, DownloadInvoiceContentTrainingPlan, GetInvoiceContentTrainingPlanUrl, GetTrainingPlanInvoiceListWithTrainingPlanId, PutTrainingPlanInvoice, UploadInvoiceContentForTrainingPlan } from '../../../services/TrainingPlanInvoiceService'; import { TrainingPlanInvoice } from '../../../models/TrainingPlanInvoice'; import { PlanWizardHeader, PlanWizardHeaderProp } from '../../../../_metronic/layout/components/wizard/PlanWizardHeader'; import { getErrorToast, getSuccessToast } from '../../ToastMessages'; import { Modal } from 'react-bootstrap'; import { Viewer } from '../../../modules/viewer/Viewer'; import { SelectActive } from '../../../models/SelectActive'; import { createRoot } from 'react-dom/client'; const rootmasterHeader = createRoot(document.getElementById('masterHeader')!); const rootSubHeader=createRoot(document.getElementById('subHeader')!); const rootPageHeader=createRoot(document.getElementById('pageHeader')!); export const MyCommandCell = (props) => { const { dataItem } = props; const inEdit = dataItem[props.editField]; const isNewItem = dataItem.id === 0; const [visible, setVisible] = useState(false); const onDeleteData = () => { props.remove(props.dataItem); setVisible(!visible); }; const toggleDialog = () => { setVisible(!visible); }; return ( {visible && (
Silmek istediğinize emin misiniz?
)} ); }; const ExternalTrainerCost: FC = () => { const [showTopUpdateButton, setShowTopUpdateButton] = useState(false); const [clickedToTopUpdateButton, setClickedToTopUpdateButton] = useState(false); const [trainingName,setTrainingName]=useState(""); const [trainerCompanyName,setTrainerCompanyName]=useState(""); const subHeaderDataX: SubHeader = { icon: '~/../media/icons/masterDataManagement.svg', title: 'YYXXCC', }; const subHeaderData: SubHeader = { icon: '/media/icons/layout-text-sidebar-reverse.svg', title: trainingName, menu: [ {title:trainerCompanyName} ], }; const GridContext = createContext({}); const CommandCell = (props: GridCellProps) => { const { add, editField, enterEdit, update, cancel, discard, remove } = useContext(GridContext); return ( ); }; const pageHeaderData: PageHeader = { title: 'Maliyet', menu: [ { icon: '', title: 'İşlem Geçmişi', path: '/trainingManagement/PlanList/CostHistory?sourceid={id}' }, showTopUpdateButton ? { icon: '', title: 'Güncelle', path: '', onClick: () => { setClickedToTopUpdateButton(true); setShowTopUpdateButton(false); getSuccessToast("Maliyetler güncellenebilir duruma geldi"); } } : { title: '' } ] }; class MasterDataManagement extends Component { componentDidMount() { /**ReacDOM.render adds components into div in MasterLayout */ rootmasterHeader.render( /**HeaderWrapper is for top header on pages. It gets 2 parameters (title, back icon visibility) */ , ); rootSubHeader.render( , ); } render() { return ( <> ); } } class ExternalTrainerCostPage extends Component { componentDidMount() { rootSubHeader.render( , ); rootPageHeader.render( , ); } render() { return ( <> ); } } const [searchParams] = useSearchParams(); const [id, setId] = useState(searchParams.get("id")); const endpoint = `${Endpoints.TrainingPlanInvoiceDistribution}/WithTrainingPlanId/${id}`; const trainingPlanInvoiceEndpoint = `${Endpoints.TrainingPlanInvoice}/WithTrainingPlanId/${id}`; const [result, setResult] = useState({ data: [], total: 0, }); const [trainingPlanInvoiceResult, setTrainingPlanInvoiceResult] = useState({ data: [], total: 0, }); const refreshGrid = () => { const dataResult = GetTrainingPlanInvoiceDistributionList(Number(id)); dataResult.then((response) => { const dataResult = { data: response.data, total: response.data.length }; setResult(dataResult); refreshTrainingPlanInvoiceGrid(); equalityIndicator(); }).catch((error) => { console.error("Update failed:", error); }); }; const refreshTrainingPlanInvoiceGrid = () => { const dataResult = GetTrainingPlanInvoiceListWithTrainingPlanId(Number(id)); dataResult.then((response) => { const dataResult = { data: response.data, total: response.data.length }; setTrainingPlanInvoiceResult(dataResult); }).catch((error) => { console.error("Update failed:", error); }); }; const add = (dataItem: TrainingPlanInvoiceDistribution) => { if(!allowPageEdit()) return; dataItem.inEdit = true; dataItem.TrainingPlanId = Number(id); dataItem["attendeeCompany"] = null; dataItem["distributionCompany"] = null; if (result.data.find((item) => item.id > 0 && item.attendeeCompanyId === dataItem["attendeeCompanyId"] && item.distributionCompanyId === dataItem["distributionCompanyId"])) { getErrorToast("Seçilen katılım ve dağıtım şirketi zaten tabloda var!"); return; } setLoading(true); const insertion = PostTrainingPlanInvoiceDistribution(dataItem); insertion.then(() => { refreshGrid(); setLoading(false); }).catch((error) => { console.error("Insert failed:", error); }); }; const update = (dataItem: UpdateTrainingPlanInvoiceDistribution) => { if(!allowPageEdit()) return; dataItem.inEdit = false; setLoading(true); const updatePromise = PutTrainingPlanInvoiceDistribution(dataItem.id, dataItem); updatePromise.then(() => { refreshGrid(); setLoading(false); }) .catch((error) => { console.error("Update failed:", error); }); }; const cancel = () => { refreshGrid(); }; const trainingPlanInvoiceUpdate = (dataItem: UpdateTrainingPlanInvoice) => { if(!allowPageEdit()) return; dataItem.inEdit = false; setLoading(true); const updatePromise = PutTrainingPlanInvoice(dataItem.id, dataItem); updatePromise.then(() => { refreshTrainingPlanInvoiceGrid(); setLoading(false); }) .catch((error) => { console.error("Update failed:", error); }); }; const trainingPlanInvoiceCancel = () => { refreshTrainingPlanInvoiceGrid(); }; const remove = (dataItem: UpdateTrainingPlanInvoiceDistribution) => { if(!allowPageEdit()) return; setLoading(true); const deletePromise = DeleteTrainingPlanInvoiceDistribution(dataItem.id); deletePromise.then(() => { refreshGrid(); setLoading(false); }) .catch((error) => { console.error("Update failed:", error); }); }; const discard = () => { const newData = [...result.data]; newData.splice(newData.findIndex((item) => item.id === 0), 1); const dataResult = { data: newData, total: newData.length }; setResult(dataResult); }; const trainingPlanInvoiceDiscard = () => { const newData = [...result.data]; newData.splice(newData.findIndex((item) => item.id === 0), 1); const dataResult = { data: newData, total: newData.length }; setTrainingPlanInvoiceResult(dataResult); }; const editField = "inEdit"; const enterEdit = (dataItem: TrainingPlanInvoiceDistribution) => { if(!allowPageEdit()) return; if( result.data.some(item=>item.inEdit)) { getErrorToast("Duzenlenebilir durumda olan diger satiri tamamlayiniz"); return; } const newData = result.data.map((item) => { return item.id === dataItem.id ? { ...item, inEdit: true } : item } ); const dataResult = { data: newData, total: newData.length }; setResult(dataResult); }; const trainingPlanInvoiceEnterEdit = (dataItem: TrainingPlanInvoice) => { if(!allowPageEdit()) return; const newData = trainingPlanInvoiceResult.data.map((item) => { return item.id === dataItem.id ? { ...item, inEdit: true } : item } ); const dataResult = { data: newData, total: newData.length }; setTrainingPlanInvoiceResult(dataResult); }; const itemChange = (event: GridItemChangeEvent) => { const field = event.field || ""; const newData = result.data.map((item) => { return item.id === event.dataItem.id ? { ...item, [field]: event.value } : item }); const dataResult = { data: newData, total: newData.length }; setResult(dataResult); }; const trainingPlanInvoiceItemChange = (event: GridItemChangeEvent) => { const field = event.field || ""; const newData = trainingPlanInvoiceResult.data.map((item) => { return item.id === event.dataItem.id ? { ...item, [field]: event.value } : item }); const dataResult = { data: newData, total: newData.length }; setTrainingPlanInvoiceResult(dataResult); }; const [dataState, setDataState] = useState({ take: 100, skip: 0 }); const [trainingPlanInvoiceDataState, setTrainingPlanInvoiceDataState] = useState({ take: 100, skip: 0 }); const trainingPlanInvoiceDataReceived = (result: DataResult) => { setTrainingPlanInvoiceResult(result); }; const dataReceived = (result: DataResult) => { setResult(result); }; let firstRender = true; const dataItemKey = "id"; const selectedField = "selected"; const trainingPlanInvoiceDataItemKey = "id"; const trainingPlanInvoiceSelectedField = "selected"; const dataStateChange = (e: GridDataStateChangeEvent) => { setDataState(e.dataState); }; const trainingPlanInvoiceDataStateChange = (e: GridDataStateChangeEvent) => { setTrainingPlanInvoiceDataState(e.dataState); }; const addNew = () => { if(!allowPageEdit()) return; if( result.data.some(item=>item.inEdit)) { getErrorToast("Duzenlenebilir durumda olan diger satiri tamamlayiniz"); return; } setResult({ data: [...result.data, { attendeeCompany: { name: '' }, distributionCompany: { name: '' }, ratio: 0, id: 0, inEdit: true }], total: result.total + 1 }); }; const equalityIndicator = () => { const invoiceSum = trainingPlanInvoiceResult.data.reduce((a, b) => a + b.amount, 0); return ( invoiceSum === trainingData?.proposalCost ?   :   ) } const turkishLiraFormat = new Intl.NumberFormat('tr-TR', { style: 'currency', currency: 'TRY', maximumFractionDigits: 0 }); const [dropdownCompanyData, setDropdownCompanyData] = useState([]) const [dropdownVatData, setDropdownVatData] = useState([]) const [dropdownInvoiceTypeData, setDropdownInvoiceTypeData] = useState([]) useEffect(() => { const fetchData = async () => { try { const trainingPlanData=await GetTrainingPlanById(id!); setTrainingName(trainingPlanData.data.trainingName); setTrainerCompanyName(trainingPlanData.data.trainerCompany); const dropdownDatas = await GetTrainingPlanInvoiceDistributionCompanies(Number(id)); setDropdownCompanyData(dropdownDatas.data); const dropdownVatDatas = await GetVatList(); setDropdownVatData(dropdownVatDatas.data); const dropdownInvoiceTypeDatas = await GetInvoiceTypeList(); setDropdownInvoiceTypeData(dropdownInvoiceTypeDatas.data); } catch (error) { console.error('Error fetching GetTrainingPlanInvoiceDistributionCompanies data', error); } }; fetchData(); }, []); const DropDownCellVat = (props: GridCellProps) => { const handleChange = (e: DropDownListChangeEvent) => { if (props.onChange) { props.onChange({ dataIndex: 0, dataItem: props.dataItem, field: props.field, syntheticEvent: e.syntheticEvent, value: e.target.value.id, }); } }; const { dataItem } = props; const field = props.field || ""; const dataValue = dataItem[field] === null ? "" : dataItem[field]; const selected = dataItem["vat"]["value"]; return ( {dataItem.inEdit ? ( c["id"] === dataValue)} data={dropdownVatData} textField="value" /> ) : selected} ); }; const DropDownCellInvoiceType = (props: GridCellProps) => { const handleChange = (e: DropDownListChangeEvent) => { if (props.onChange) { props.onChange({ dataIndex: 0, dataItem: props.dataItem, field: props.field, syntheticEvent: e.syntheticEvent, value: e.target.value.id, }); } }; const { dataItem } = props; const field = props.field || ""; const dataValue = dataItem[field] === null ? "" : dataItem[field]; const selected = dataItem["invoiceType"]["name"]; return ( {dataItem.inEdit ? ( c["id"] === dataValue)} data={dropdownInvoiceTypeData} textField="name" /> ) : selected} ); }; const DropDownCellDistributionCompanies = (props: GridCellProps) => { const handleChange = (e: DropDownListChangeEvent) => { if (props.onChange) { props.onChange({ dataIndex: 0, dataItem: props.dataItem, field: props.field, syntheticEvent: e.syntheticEvent, value: e.target.value.id, }); } }; const { dataItem } = props; const field = props.field || ""; const dataValue = dataItem[field] === null ? "" : dataItem[field]; const selected = dataItem["distributionCompany"] !== null ? dataItem["distributionCompany"]["name"] : ""; return ( {dataItem.inEdit ? ( c["id"] === dataValue)} data={dropdownCompanyData} textField="name" /> ) : selected} ); }; const DropDownCellAttendeeCompanies = (props: GridCellProps) => { const handleChange = (e: DropDownListChangeEvent) => { if (props.onChange) { props.onChange({ dataIndex: 0, dataItem: props.dataItem, field: props.field, syntheticEvent: e.syntheticEvent, value: e.target.value.id, }); } }; const { dataItem } = props; const field = props.field || ""; const dataValue = dataItem[field] === null ? "" : dataItem[field]; const selected = dataItem["attendeeCompany"] !== null ? dataItem["attendeeCompany"]["name"] : ""; return ( {dataItem.inEdit ? ( c["id"] === dataValue)} data={dropdownCompanyData} textField="name" /> ) : selected} ); }; const allowPageEdit=function():boolean{ if(trainingPlanIsCostActive===false || clickedToTopUpdateButton) return true; getErrorToast( `Maliyetler güncellenebilir durumda değil` ); return false; } const topBoxes = (proposalCost: number, vatCost: number, attendeeCount: number, serviceCost: number, invoiceCost: number) => { return (
Teklif Tutarı

{turkishLiraFormat.format(proposalCost || 0)} {equalityIndicator()}

Onaylanan teklif tutarıdır.

Hizmet Tutarı

{turkishLiraFormat.format(serviceCost || 0)}

Faturada yer alan hizmet tutarlarının toplamıdır.

Vergi Tutarı

{turkishLiraFormat.format(vatCost || 0)}

Faturada yer alan vergi tutarlarının toplamıdır.

Fatura Tutarı

{turkishLiraFormat.format(invoiceCost || 0)}

Faturanın toplam tutarıdır.

Kişi Başı Ödenecek Tutar

{turkishLiraFormat.format((proposalCost / attendeeCount)||0)}

Hizmet tutarının kişi başına düşen tutarıdır.

); }; const rowRender = (trElement, props) => { let sum = 0; const filterSameCompanyAttendees = result.data.filter(item => item.attendeeCompanyId === props.dataItem.attendeeCompanyId); filterSameCompanyAttendees.forEach(num => { sum += num.ratio; }) const rowColor = sum !== 100 && props.dataItem.id != 0 ? 'lightpink' : 'white'; const rowProps = { ...trElement.props, style: { backgroundColor: rowColor }, }; return cloneElement(trElement, { ...rowProps }, trElement.props.children); }; const [trainingData, setTrainingData] = useState(); const [trainingPlanIsCostActive, setTrainingPlanIsCostActive] = useState(false); const [loading, setLoading] = useState(false) useEffect(() => { firstRender = false; setLoading(true); GetTrainingPlanById(id!).then(function (response) { if (response.status === 200) { setId(id) setTrainingData(response.data); setTrainingPlanIsCostActive(response.data.isCostActive); setShowTopUpdateButton(response.data.isCostActive === null || response.data.isCostActive === false ? false : true); } setLoading(false); }); }, [firstRender]) const [wizardProp, setWizardProp] = useState({ id: Number(id)!,stateChanger:false }); const TrainingPlanUpdateActivation = (activate: boolean) => (event: React.MouseEvent) => { event.preventDefault(); interface AttendeeCompanyData { Id: number; Ratio: number; } const resultForCheck: AttendeeCompanyData[] = []; result.data.reduce(function (res, value) { if (!res[value.attendeeCompanyId]) { res[value.attendeeCompanyId] = { Id: value.attendeeCompanyId, Ratio: 0 }; resultForCheck.push(res[value.attendeeCompanyId]) } res[value.attendeeCompanyId].Ratio += value.ratio; return res; }, {}); if (resultForCheck.some(value => value.Ratio != 100)) { getErrorToast( `Dağılımları %100 olmamış olan kayıtlar mevcut` ); return; } const invoiceSum = trainingPlanInvoiceResult.data.reduce((a, b) => a + b.amount, 0); if(invoiceSum !== trainingData?.proposalCost){ getErrorToast( `Faturalandırılan tutar teklif tutarı ile aynı değil` ); return; } const trainingPlanActivationModel: SelectActive = { id: Number(id), active: activate } setLoading(true); TrainingPlanSetIsCostActive(Number(id), trainingPlanActivationModel).then(function (response) { if (response.status === 202) { setTrainingPlanIsCostActive(activate); setShowTopUpdateButton(true); setClickedToTopUpdateButton(false); setWizardProp( { id: Number(id)!,stateChanger:!wizardProp.stateChanger }) setLoading(false); getSuccessToast( `Maliyet aktivasyonu güncellendi` ); } }); return; }; const handleTrainingPlanInvoiceContentUpload = (Id) => { const fileContentInput = document.createElement('input'); fileContentInput.type = 'file'; fileContentInput.onchange = (inputChangeEvent: Event) => { const inputElement = inputChangeEvent.target as HTMLInputElement; const file = inputElement.files ? inputElement.files[0] : null; if (file) { const formData = new FormData(); formData.append("File", file); formData.append("Id", Id.toString()); setLoading(true); UploadInvoiceContentForTrainingPlan(Id, formData) .then((response) => { if (response.status === 202) { const uploadDate = new Date().toLocaleString(); const fileName = file.name; getSuccessToast( `Fatura içeriği başarıyla yüklendi. Yükleme Tarihi: ${uploadDate}, Dosya Adı: ${fileName}` ); setLoading(false); refreshTrainingPlanInvoiceGrid(); } }) .catch(() => { getErrorToast("Fatura içeriği yüklenirken bir hata oluştu"); }); } }; fileContentInput.click(); // Dosya seçim penceresini aç } const CommandCellTrainingPlanInvoice = (props: GridCellProps) => { const { editField, trainingPlanInvoiceEnterEdit, trainingPlanInvoiceUpdate, trainingPlanInvoiceCancel, trainingPlanInvoiceDiscard } = useContext(GridContext); return ( ); }; const MyCommandTrainingPlanInvoiceCell = (props) => { const { dataItem } = props; const inEdit = dataItem[props.editField]; const isNewItem = dataItem.id === 0; const [visible, setVisible] = useState(false); const [viewerIsOpen, setViewerIsOpen] = useState(false); const [viewerFileUrl, setViewerFileUrl] = useState(""); const openViewer = (fileName: string) => { setViewerFileUrl(GetInvoiceContentTrainingPlanUrl(fileName)); setViewerIsOpen(true); } const closeViewer = () => { setViewerIsOpen(false); } const DeleteInvoiceContent = (id: number) => { if(!allowPageEdit()) return; DeleteInvoiceContentDoc(id).then((response) => { if (response.status === 204) { refreshTrainingPlanInvoiceGrid(); getSuccessToast( `Dosya başarıyla silindi` ); } }) .catch(() => { getErrorToast("Dosya silinirken bir hata oluştu"); }); } const toggleDialog = () => { setVisible(!visible); }; const isLoading = false; return ( {props.dataItem.invoiceUrl !== null ? (<> {allowPageEdit() && ()} ) : (<>)}   
); }; return ( <> <>



{(loading &&
Loading...
)} {topBoxes(trainingData?.proposalCost, trainingData?.vatCost, trainingData?.attendees.length, trainingData?.serviceCost, trainingData?.invoiceCost)} <>



<>
<>

{(trainingPlanIsCostActive === null || trainingPlanIsCostActive === false) && !showTopUpdateButton && ()} {clickedToTopUpdateButton && ()}
<>

); } export default ExternalTrainerCost