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 && (
)}
|
);
};
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 &&
)}
{topBoxes(trainingData?.proposalCost, trainingData?.vatCost, trainingData?.attendees.length, trainingData?.serviceCost, trainingData?.invoiceCost)}
<>
>
<>
>
<>
>
{(trainingPlanIsCostActive === null || trainingPlanIsCostActive === false) && !showTopUpdateButton && ()}
{clickedToTopUpdateButton && ()}
<>
>
>
);
}
export default ExternalTrainerCost