parent
58529b477e
commit
e8135d40d2
@ -1,2 +1,2 @@ |
||||
REACT_APP_ENVIRONMENT=qa |
||||
REACT_APP_API=https://www.gemcousa.solutions/GEMCOBackend/api |
||||
REACT_APP_API=https://www.adminusa.gemcousa.solutions/GEMCOBackend/api |
@ -1,119 +0,0 @@ |
||||
|
||||
import * as React from 'react'; |
||||
import { useState } from 'react'; |
||||
import { Button, Card, Form } from 'react-bootstrap'; |
||||
import ExelServices from '../../../Utils/ExelFiles/Exel.services'; |
||||
import { FiSend } from "react-icons/fi"; |
||||
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo'; |
||||
import * as XLSX from 'xlsx'; |
||||
|
||||
export default function FileUploadExel() { |
||||
const [WorkingHoursFile, setWorkingHoursFile] = useState<File | null>(null); |
||||
const [showToast, setShowToast] = useState<boolean>(false); |
||||
const [toastMsg, setToastMsg] = useState<string>(''); |
||||
const [toastHeader, setToastHeader] = useState<string>(''); |
||||
const [toastColor, setToastColor] = useState<string>(''); |
||||
|
||||
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => { |
||||
let file = event.target.files?.[0] || null; |
||||
|
||||
if (file && file.name.endsWith('.xls')) { |
||||
// Convertir XLS a XLSX usando la biblioteca xlsx
|
||||
const data = await file.arrayBuffer(); |
||||
const workbook = XLSX.read(data, { type: 'array' }); |
||||
const convertedData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); |
||||
file = new File([convertedData], file.name.replace('.xls', '.xlsx'), { |
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||||
}); |
||||
} |
||||
|
||||
setWorkingHoursFile(file); |
||||
}; |
||||
|
||||
const handleSendFiles = async () => { |
||||
if (!WorkingHoursFile) { |
||||
setToastMsg('No hay archivos para enviar'); |
||||
setToastHeader('Error'); |
||||
setToastColor('danger'); |
||||
setShowToast(true); |
||||
return; |
||||
} |
||||
|
||||
const formDataBook = new FormData(); |
||||
formDataBook.append('file', WorkingHoursFile); |
||||
|
||||
try { |
||||
const responseBook = await ExelServices.uploadWorkingHours(formDataBook); |
||||
|
||||
if (!responseBook || responseBook.status !== 200) { |
||||
throw new Error('Error al subir el archivo de horas de trabajo'); |
||||
} |
||||
|
||||
setToastMsg('Archivo enviado exitosamente'); |
||||
setToastHeader('Informativo'); |
||||
setToastColor('success'); |
||||
setShowToast(true); |
||||
|
||||
setWorkingHoursFile(null); |
||||
|
||||
} catch (error) { |
||||
setToastMsg(`Error al enviar archivos: ${(error as Error).message || 'Error desconocido'}`); |
||||
setToastHeader('Error'); |
||||
setToastColor('danger'); |
||||
setShowToast(true); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div className="mt-2"> |
||||
<Card> |
||||
<Card.Body> |
||||
<Form> |
||||
<div className="d-flex justify-content-around"> |
||||
<Card |
||||
className="text-center p-4 m-2" |
||||
style={{ backgroundColor: 'lightgreen', borderRadius: '8px', width: '45%' }} |
||||
> |
||||
<Form.Group> |
||||
<Form.Label className="d-block mb-2" style={{ fontWeight: 'bold' }}> |
||||
Arrastra o selecciona el archivo Excel |
||||
</Form.Label> |
||||
<Form.Control |
||||
type="file" |
||||
accept=".xlsx, .xls" |
||||
onChange={handleFileChange} |
||||
style={{ display: 'none' }} |
||||
id="workingHoursFileInput" |
||||
/> |
||||
<label |
||||
htmlFor="workingHoursFileInput" |
||||
className="btn btn-light d-block" |
||||
style={{ cursor: 'pointer', border: '2px solid green', borderRadius: '8px' }} |
||||
> |
||||
{WorkingHoursFile ? WorkingHoursFile.name : 'Seleccionar archivo'} |
||||
</label> |
||||
</Form.Group> |
||||
</Card> |
||||
|
||||
<Button |
||||
variant="success" |
||||
onClick={handleSendFiles} |
||||
style={{ marginTop: '10px', display: 'block', marginLeft: 'auto', marginRight: 'auto' }} |
||||
> |
||||
Enviar <FiSend /> |
||||
</Button> |
||||
</div> |
||||
</Form> |
||||
</Card.Body> |
||||
</Card> |
||||
|
||||
<MsgInformativo |
||||
show={showToast} |
||||
msg={toastMsg} |
||||
header={toastHeader} |
||||
msgColor={toastColor} |
||||
closeToast={setShowToast} |
||||
/> |
||||
</div> |
||||
); |
||||
} |
@ -0,0 +1,19 @@ |
||||
export default interface WorkingHours { |
||||
empNo : string,
|
||||
acNo : string,
|
||||
name: string,
|
||||
date : string,
|
||||
clockIn1 : string,
|
||||
clockOut1 : string,
|
||||
clockIn2 : string, |
||||
clockOut2 : string, |
||||
clocIn3 : string,
|
||||
clocOut3 : string,
|
||||
clocIn4 : string,
|
||||
clocOut4 : string,
|
||||
clocIn5 : string,
|
||||
clocOut5 : string,
|
||||
totalInTime : string,
|
||||
totalHoursWorked : string |
||||
|
||||
} |
@ -0,0 +1,474 @@ |
||||
|
||||
import * as React from 'react'; |
||||
import { useState } from 'react'; |
||||
import { Button, Card, Form, Col, Row, ToastHeader, } from 'react-bootstrap'; |
||||
import { BsSearch, BsFileEarmarkExcel } from 'react-icons/bs' |
||||
import ExelServices from '../../../Utils/ExelFiles/Exel.services'; |
||||
import { FiSend } from "react-icons/fi"; |
||||
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo'; |
||||
import * as XLSX from 'xlsx'; |
||||
import DataTable from 'react-data-table-component'; |
||||
import { DTOWorkingHours } from '../../../DTO/DTOWorkingHours'; |
||||
import reportesServices from '../../../Services/Reportes/reportes.services'; |
||||
|
||||
|
||||
export default function FileUploadExel() { |
||||
const [WorkingHoursFile, setWorkingHoursFile] = useState<File | null>(null); |
||||
const [showToast, setShowToast] = useState<boolean>(false); |
||||
const [toastMsg, setToastMsg] = useState<string>(''); |
||||
const [toastHeader, setToastHeader] = useState<string>(''); |
||||
const [toastColor, setToastColor] = useState<string>(''); |
||||
const [Inicio, setInicio] = useState(currentDate()) |
||||
const [Fin, setFin] = useState(currentDate()) |
||||
const [Data, setData] = useState<Array<DTOWorkingHours>>([]) |
||||
const [show, setShowMsg] = useState(false) |
||||
const [filtro, setFiltro] = useState('') |
||||
const [filteredData, setFilteredData] = useState<Array<DTOWorkingHours>>( |
||||
[] |
||||
) |
||||
|
||||
|
||||
|
||||
|
||||
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => { |
||||
let file = event.target.files?.[0] || null; |
||||
|
||||
if (file && file.name.endsWith('.xls')) { |
||||
// Convertir XLS a XLSX usando la biblioteca xlsx
|
||||
const data = await file.arrayBuffer(); |
||||
const workbook = XLSX.read(data, { type: 'array' }); |
||||
const convertedData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); |
||||
file = new File([convertedData], file.name.replace('.xls', '.xlsx'), { |
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||||
}); |
||||
} |
||||
|
||||
setWorkingHoursFile(file); |
||||
}; |
||||
|
||||
|
||||
|
||||
const columnsConcepts = [ |
||||
{ |
||||
name: 'EmpNo',
|
||||
width: '100px',
|
||||
selector: (row : DTOWorkingHours ) => row.empNo,
|
||||
sortable: true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'AcNo',
|
||||
width: '80px',
|
||||
selector :(row:DTOWorkingHours) => row.acNo,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'No',
|
||||
width: '5px',
|
||||
selector: (row : DTOWorkingHours) => row.no,
|
||||
sortable: true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'Name',
|
||||
width: '150px',
|
||||
selector: (row : DTOWorkingHours) => row.name,
|
||||
sortable : true ,
|
||||
filter : true |
||||
|
||||
},
|
||||
{ |
||||
name: 'Date',
|
||||
width: '150px',
|
||||
selector : (row : DTOWorkingHours ) => row.date,
|
||||
sortable: true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockIn1',
|
||||
width : '120px',
|
||||
selector: (row : DTOWorkingHours) => row.clockIn1,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockOut1',
|
||||
width : '120px',
|
||||
selector : (row : DTOWorkingHours) => row.clockOut1,
|
||||
sortable : true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockIn2',
|
||||
width : '120px',
|
||||
selector: (row : DTOWorkingHours) => row.clockIn2,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockOut2',
|
||||
width : '120px',
|
||||
selector : (row : DTOWorkingHours) => row.clockOut2,
|
||||
sortable : true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockIn3',
|
||||
width : '120px',
|
||||
selector: (row : DTOWorkingHours) => row.clockIn3,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockOut3',
|
||||
width : '150px',
|
||||
selector : (row : DTOWorkingHours) => row.clockOut3,
|
||||
sortable : true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockIn4',
|
||||
width : '120px',
|
||||
selector: (row : DTOWorkingHours) => row.clockIn4,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockOut4',
|
||||
width : '120px',
|
||||
selector : (row : DTOWorkingHours) => row.clockOut4,
|
||||
sortable : true,
|
||||
filter : true |
||||
} ,
|
||||
{ |
||||
name: 'ClockIn5',
|
||||
width : '120px',
|
||||
selector: (row : DTOWorkingHours) => row.clockIn5,
|
||||
sortable: true ,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'ClockOut5',
|
||||
width : '120px',
|
||||
selector : (row : DTOWorkingHours) => row.clockOut5,
|
||||
sortable : true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'TotalInTime',
|
||||
width: '120px',
|
||||
selector: (row : DTOWorkingHours) => row.totalInTime,
|
||||
sortable : true ,
|
||||
filter : true |
||||
},
|
||||
|
||||
{ |
||||
name: 'TotalHoursWorked',
|
||||
width: '130px',
|
||||
selector : (row : DTOWorkingHours) => row.totalHoursWorked,
|
||||
sortable : true,
|
||||
filter : true
|
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
] |
||||
|
||||
|
||||
function currentDate (): string { |
||||
var today = new Date() |
||||
var dd = String(today.getDate()).padEnd(2,'0') |
||||
var mm = String(today.getMonth() + 1 ).padStart(2, '0') |
||||
var yyyy = today.getFullYear() |
||||
return yyyy+'-' + mm + '-' + dd |
||||
} |
||||
|
||||
const generarReporte = () => { |
||||
reportesServices.getRptWorkingHours(Inicio, Fin) |
||||
.then((response) => { |
||||
setData(response.data) |
||||
setFilteredData(response.data) |
||||
setToastMsg('Se econtro la siguiente informacion'); |
||||
setToastHeader('Informativo'); |
||||
setToastColor('success'); |
||||
setShowToast(true); |
||||
|
||||
})
|
||||
.catch((e:Error) => { |
||||
// alert('Ocurrio un Error'+e.message.toString())
|
||||
setToastMsg('No se ha introducido fechas validas') |
||||
setToastHeader('Error') |
||||
setToastColor('danger') |
||||
setShowToast(true) |
||||
return;
|
||||
|
||||
|
||||
} ) |
||||
} |
||||
|
||||
|
||||
const donwloadExel = () => { |
||||
exportExcel(filteredData , 'Reportes de Horas Trabajadas') |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const filtraReporte = (e: any ) => { |
||||
const searchText = e.target.value.toLowerCase();
|
||||
setFiltro(searchText) |
||||
|
||||
const filtered = Data.filter((iteam) => { |
||||
return ( |
||||
(iteam.empNo && iteam.empNo.toString().toLocaleLowerCase().includes(searchText)) ||
|
||||
(iteam.name && iteam.name.toString().toLocaleLowerCase().includes(searchText)) ||
|
||||
(iteam.date && iteam.date.toString().toLocaleLowerCase().includes(searchText)) |
||||
) |
||||
} ) |
||||
|
||||
|
||||
|
||||
console.log('filtered data ', filtered ) |
||||
setFilteredData(filtered) |
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const exportExcel = (jsonData: any[], fileName: string) => { |
||||
const Heading = [ |
||||
[ |
||||
'EmpNo',
|
||||
'AcNo',
|
||||
'No', |
||||
'Name', |
||||
'Date',
|
||||
'ClockIn1',
|
||||
'ClockOut1',
|
||||
'ClockIn1',
|
||||
'ClockOut1',
|
||||
'ClockIn1',
|
||||
'ClockOut1',
|
||||
'ClockIn1',
|
||||
'ClockOut1',
|
||||
'ClockIn1',
|
||||
'ClockOut1',
|
||||
'TotalInTime',
|
||||
'TotalHoursWorked' |
||||
] |
||||
|
||||
] |
||||
|
||||
const wb = XLSX.utils.book_new() |
||||
const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet([]) |
||||
XLSX.utils.sheet_add_aoa(ws, Heading) |
||||
XLSX.utils.sheet_add_json(ws, jsonData, { origin: 'A2', skipHeader: true }) |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1') |
||||
XLSX.writeFile(wb, `${fileName}.xlsx`) |
||||
const range = XLSX.utils.decode_range(ws['!ref']!) |
||||
for (let C = range.s.c; C <= range.e.c; ++C) { |
||||
const address = XLSX.utils.encode_col(C) + '1' |
||||
if (!ws[address]) continue |
||||
ws[address].v = ws[address].v.toUpperCase() |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const handleSendFiles = async () => { |
||||
if (!WorkingHoursFile) { |
||||
setToastMsg('No hay archivos para enviar'); |
||||
setToastHeader('Error'); |
||||
setToastColor('danger'); |
||||
setShowToast(true); |
||||
return; |
||||
} |
||||
|
||||
const formDataBook = new FormData(); |
||||
formDataBook.append('file', WorkingHoursFile); |
||||
|
||||
try { |
||||
const responseBook = await ExelServices.uploadWorkingHours(formDataBook); |
||||
|
||||
if (!responseBook || responseBook.status !== 200) { |
||||
throw new Error('Error al subir el archivo de horas de trabajo'); |
||||
} |
||||
|
||||
setToastMsg('Archivo enviado exitosamente'); |
||||
setToastHeader('Informativo'); |
||||
setToastColor('success'); |
||||
setShowToast(true); |
||||
|
||||
setWorkingHoursFile(null); |
||||
|
||||
} catch (error) { |
||||
setToastMsg(`Error al enviar archivos: ${(error as Error).message || 'Error desconocido'}`); |
||||
setToastHeader('Error'); |
||||
setToastColor('danger'); |
||||
setShowToast(true); |
||||
} |
||||
}; |
||||
|
||||
|
||||
|
||||
return ( |
||||
<div className="mt-2"> |
||||
<Card> |
||||
<Card.Body> |
||||
<Form> |
||||
<div className="d-flex justify-content-around"> |
||||
<Card |
||||
className="text-center p-4 m-2" |
||||
style={{ backgroundColor: 'lightgreen', borderRadius: '8px', width: '25%' }} |
||||
> |
||||
<Form.Group> |
||||
<Form.Label className="d-block mb-2" style={{ fontWeight: 'bold' }}> |
||||
Arrastra o selecciona el archivo Excel |
||||
</Form.Label> |
||||
<Form.Control |
||||
type="file" |
||||
accept=".xlsx, .xls" |
||||
onChange={handleFileChange} |
||||
style={{ display: 'none' }} |
||||
id="workingHoursFileInput" |
||||
/> |
||||
<label |
||||
htmlFor="workingHoursFileInput" |
||||
className="btn btn-light d-block" |
||||
style={{ cursor: 'pointer', border: '2px solid green', borderRadius: '8px' }} |
||||
> |
||||
{WorkingHoursFile ? WorkingHoursFile.name : 'Seleccionar archivo'} |
||||
</label> |
||||
</Form.Group> |
||||
</Card> |
||||
|
||||
<Button |
||||
variant="success" |
||||
onClick={handleSendFiles} |
||||
style={{ marginTop: '10px', display: 'block', marginLeft: 'auto', marginRight: 'auto', height: '40px' }} |
||||
> |
||||
Enviar <FiSend /> |
||||
</Button> |
||||
</div> |
||||
</Form> |
||||
</Card.Body> |
||||
</Card> |
||||
|
||||
<MsgInformativo |
||||
show={showToast} |
||||
msg={toastMsg} |
||||
header={toastHeader} |
||||
msgColor={toastColor} |
||||
closeToast={setShowToast} |
||||
/> |
||||
|
||||
<Card className="mt-3"> |
||||
<Card.Body> |
||||
<Form> |
||||
<Row className="align-items-center"> |
||||
<Col xs={1}> |
||||
<Form.Label>Desde</Form.Label> |
||||
<Form.Control |
||||
defaultValue={Inicio} |
||||
type="date" |
||||
name="Inicio" |
||||
placeholder="Inicio" |
||||
title="Inicio" |
||||
alt="Inicio" |
||||
data-date-format="YYYY-mm-dd" |
||||
onChange={(e) => setInicio(e.target.value)} |
||||
size="sm" |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={1}> |
||||
<Form.Label>Hasta</Form.Label> |
||||
<Form.Control |
||||
defaultValue={Fin} |
||||
type="date" |
||||
name="Fin" |
||||
placeholder="Fin" |
||||
title="Fin" |
||||
alt="Fin" |
||||
onChange={(e) => setFin(e.target.value)} |
||||
size="sm" |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
<Form.Control |
||||
type="text" |
||||
size="sm" |
||||
placeholder="Search..." |
||||
onChange={ (e) => { |
||||
filtraReporte(e) |
||||
} } |
||||
|
||||
style={{ height: '20px', padding: '5px' }} |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={3}> |
||||
<Button |
||||
// size="sm"
|
||||
variant="success" |
||||
onClick={donwloadExel} |
||||
style={{ width: '30%' }} |
||||
> |
||||
<BsFileEarmarkExcel /> |
||||
Excel |
||||
</Button> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
<Button |
||||
variant="primary" |
||||
onClick={generarReporte} |
||||
style={{ width: '30%' }} |
||||
> |
||||
<BsSearch /> |
||||
Buscar |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
</Card.Body> |
||||
</Card> |
||||
|
||||
<Card className="mt-3"> |
||||
<Card.Body> |
||||
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}> |
||||
<DataTable |
||||
noHeader |
||||
defaultSortFieldId={''} |
||||
defaultSortAsc={true} |
||||
striped={true} |
||||
dense={true} |
||||
paginationPerPage={10} |
||||
pagination |
||||
highlightOnHover |
||||
columns={columnsConcepts} |
||||
data={filteredData} |
||||
pointerOnHover |
||||
/> |
||||
</div> |
||||
</Card.Body> |
||||
</Card> |
||||
</div> |
||||
); |
||||
} |
@ -0,0 +1,448 @@ |
||||
import * as react from 'react' |
||||
import { useState } from 'react' |
||||
import reportesServices from '../../../Services/Reportes/reportes.services' |
||||
import DataTable from 'react-data-table-component' |
||||
import {DTOTotalHours} from '../../../DTO/Reportes/DTOTotalHours' |
||||
import * as XLSX from 'xlsx' |
||||
import { MsgInformativo } from '../../../Utils/Toast/msgInformativo' |
||||
import { Button, Card, Form, Col, Row, ToastHeader, CardBody, } from 'react-bootstrap'; |
||||
import { BsSearch, BsFileEarmarkExcel } from 'react-icons/bs' |
||||
import { DTOWorkingHours } from '../../../DTO/DTOWorkingHours' |
||||
|
||||
|
||||
|
||||
export default function RptTotalHours () |
||||
{ |
||||
const [Inicio, setInicio] = useState(currentDate())
|
||||
const [Fin , setFin] = useState(currentDate) |
||||
const [filtro, setFiltro] = useState('') |
||||
const [filteredData, setFilteredData] = useState<Array<DTOTotalHours>> ( |
||||
[] |
||||
) |
||||
const [filteredDataDet, setFilteredDataDet] = useState <Array<DTOWorkingHours>>( |
||||
[] |
||||
) |
||||
|
||||
const [Data, setData] = useState<Array<DTOTotalHours>> ([]) |
||||
const [DataDet , setDataDet ] = useState <Array <DTOWorkingHours>> ([]) |
||||
const [showToast, setShowToast] = useState<boolean>(false); |
||||
const [toastMsg, setToastMsg] = useState<string>(''); |
||||
const [toastHeader, setToastHeader] = useState<string>(''); |
||||
const [toastColor, setToastColor] = useState<string>(''); |
||||
|
||||
|
||||
function currentDate (): string { |
||||
var today = new Date() |
||||
var dd = String(today.getDate()).padEnd(2,'0') |
||||
var mm = String(today.getMonth() + 1 ).padStart(2, '0') |
||||
var yyyy = today.getFullYear() |
||||
return yyyy+'-' + mm + '-' + dd |
||||
} |
||||
|
||||
const generarRptRes = () => { |
||||
reportesServices.getRptTotalHours(Inicio, Fin) |
||||
.then((response) => { |
||||
setData(response.data) |
||||
setFilteredData(response.data) |
||||
setToastMsg('Se econtro la siguiente informacion'); |
||||
setToastHeader('Informativo'); |
||||
setToastColor('success'); |
||||
setShowToast(true); |
||||
|
||||
})
|
||||
.catch((e:Error) => { |
||||
// alert('Ocurrio un Error'+e.message.toString())
|
||||
setToastMsg('No se ha introducido fechas validas') |
||||
setToastHeader('Error') |
||||
setToastColor('danger') |
||||
setShowToast(true) |
||||
return;
|
||||
} ) |
||||
} |
||||
|
||||
const generarRptDet = () => { |
||||
reportesServices.getRptWorkingHours(Inicio, Fin) |
||||
.then((response) => { |
||||
setDataDet(response.data); |
||||
}) |
||||
.catch((e: Error) => { |
||||
setToastMsg('Fechas No Validas'); |
||||
setToastHeader('Error'); |
||||
setToastColor('danger'); |
||||
setShowToast(true); |
||||
}); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const columnsConcepts = [ |
||||
{ |
||||
name: 'EmpNo',
|
||||
width : '100px', |
||||
selector : (row : DTOTotalHours ) => row.empNo,
|
||||
sortable: true,
|
||||
filter : true |
||||
},
|
||||
|
||||
|
||||
|
||||
{ |
||||
name: 'AcNo',
|
||||
width : '100px',
|
||||
selector : (row : DTOTotalHours) => row.acNo,
|
||||
sortable : true,
|
||||
filter : true
|
||||
},
|
||||
{ |
||||
name: 'Name',
|
||||
width : '200px',
|
||||
selector: (row: DTOTotalHours) => row.name,
|
||||
sortable: true,
|
||||
filter: true
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
{ |
||||
name: 'TotalHoursAccumulated',
|
||||
width: '200px',
|
||||
selector : (row: DTOTotalHours ) => row.totalHoursAccumulated,
|
||||
sortable : true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'TotalHoursWithMilitaryMinutes',
|
||||
with: '200px',
|
||||
selector : (row: DTOTotalHours) => row.totalHoursWithMilitaryMinutes,
|
||||
filter : true |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
] |
||||
|
||||
const columnsConceptsDet = [ |
||||
[ |
||||
{ |
||||
name: 'Name' ,
|
||||
selector : (row: DTOWorkingHours ) => row.name,
|
||||
sortable : true,
|
||||
filter : true |
||||
},
|
||||
{ |
||||
name: 'EmpNo',
|
||||
|
||||
selector : (row : DTOWorkingHours ) => row.empNo,
|
||||
sortable: true,
|
||||
filter : true |
||||
} |
||||
] |
||||
] |
||||
|
||||
|
||||
|
||||
|
||||
// const donwloadExel = () => {
|
||||
// exportExcel(filteredData, 'ReporteTotalHoras' )
|
||||
// }
|
||||
|
||||
|
||||
// const exportExcel = (jsonData: any[], fileName: string) => {
|
||||
// const Heading = [
|
||||
// [
|
||||
// 'EmpNo',
|
||||
// 'AcNo',
|
||||
// 'No',
|
||||
// 'TotalHoursAccumuled',
|
||||
// 'TotalHoursWithMilitaryMinutes'
|
||||
|
||||
// ]
|
||||
|
||||
|
||||
// ]
|
||||
|
||||
|
||||
|
||||
// const Heading1 = [[
|
||||
// 'EmpNo', 'AcNo', 'Name', 'Date', 'ClockIn1', 'ClockOut1 ' ,'ClockIn1', 'ClockOut1 ' ,
|
||||
// 'ClockIn2', 'ClockOut2 ', 'ClockIn3', 'ClockOut3 ', 'ClockIn4', 'ClockOut4 ',
|
||||
// 'ClockIn5', 'ClockOut5 '
|
||||
|
||||
|
||||
// ]]
|
||||
|
||||
|
||||
// const wb = XLSX.utils.book_new()
|
||||
// const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet([])
|
||||
// XLSX.utils.sheet_add_aoa(ws, Heading)
|
||||
// XLSX.utils.sheet_add_json(ws, jsonData, { origin: 'A2', skipHeader: true })
|
||||
// XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
|
||||
// XLSX.writeFile(wb, `${fileName}.xlsx`)
|
||||
// const range = XLSX.utils.decode_range(ws['!ref']!)
|
||||
// for (let C = range.s.c; C <= range.e.c; ++C) {
|
||||
// const address = XLSX.utils.encode_col(C) + '1'
|
||||
// if (!ws[address]) continue
|
||||
// ws[address].v = ws[address].v.toUpperCase()
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const donwloadExel = () => { |
||||
exportExcel(filteredData, DataDet, 'ReporteTotal');
|
||||
|
||||
|
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const exportExcel = (jsonData1: any[], jsonData2: any[], fileName: string) => { |
||||
const Heading1 = [ |
||||
[ |
||||
'EmpNo',
|
||||
'AcNo',
|
||||
'No',
|
||||
'TotalHoursAccumuled',
|
||||
'TotalHoursWithMilitaryMinutes' |
||||
] |
||||
]; |
||||
|
||||
const Heading2 = [ |
||||
[ |
||||
'EmpNo', 'AcNo', 'Name', 'Date', 'ClockIn1', 'ClockOut1', 'ClockIn1', 'ClockOut1',
|
||||
'ClockIn2', 'ClockOut2', 'ClockIn3', 'ClockOut3', 'ClockIn4', 'ClockOut4',
|
||||
'ClockIn5', 'ClockOut5' , 'TotalInTime' |
||||
] |
||||
]; |
||||
|
||||
// Crear libro de trabajo
|
||||
const wb = XLSX.utils.book_new(); |
||||
|
||||
// Hoja 1
|
||||
const ws1: XLSX.WorkSheet = XLSX.utils.json_to_sheet([]); |
||||
XLSX.utils.sheet_add_aoa(ws1, Heading1); |
||||
XLSX.utils.sheet_add_json(ws1, jsonData1, { origin: 'A2', skipHeader: true }); |
||||
XLSX.utils.book_append_sheet(wb, ws1, 'Resumen'); |
||||
|
||||
// Hoja 2
|
||||
const ws2: XLSX.WorkSheet = XLSX.utils.json_to_sheet([]); |
||||
XLSX.utils.sheet_add_aoa(ws2, Heading2); |
||||
XLSX.utils.sheet_add_json(ws2, jsonData2, { origin: 'A2', skipHeader: true }); |
||||
XLSX.utils.book_append_sheet(wb, ws2, 'Detalle'); |
||||
|
||||
// Convertir títulos a mayúsculas en ambas hojas
|
||||
const capitalizeHeaders = (ws: XLSX.WorkSheet) => { |
||||
const range = XLSX.utils.decode_range(ws['!ref']!); |
||||
for (let C = range.s.c; C <= range.e.c; ++C) { |
||||
const address = XLSX.utils.encode_col(C) + '1'; |
||||
if (!ws[address]) continue; |
||||
ws[address].v = ws[address].v.toUpperCase(); |
||||
} |
||||
}; |
||||
|
||||
capitalizeHeaders(ws1); |
||||
capitalizeHeaders(ws2); |
||||
|
||||
// Escribir y descargar el archivo Excel
|
||||
XLSX.writeFile(wb, `${fileName}.xlsx`); |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const filtraReporte1 = (e: any) => { |
||||
const searchText = e.target.value.toLowerCase();
|
||||
setFiltro(searchText) |
||||
|
||||
const filtered = DataDet.filter((iteam) => { |
||||
return ( |
||||
(iteam.empNo && iteam.empNo.toString().toLocaleUpperCase().includes(searchText)) ||
|
||||
(iteam.name && iteam.name.toString().toLocaleLowerCase().includes(searchText) )
|
||||
|
||||
|
||||
) |
||||
} ) |
||||
|
||||
setFilteredDataDet(filtered) |
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const filtraReporte = (e: any) => { |
||||
const searchText = e.target.value.toLowerCase();
|
||||
setFiltro(searchText) |
||||
|
||||
const filtered = Data.filter((iteam) => { |
||||
return ( |
||||
(iteam.empNo && iteam.empNo.toString().toLocaleUpperCase().includes(searchText)) ||
|
||||
(iteam.name && iteam.name.toString().toLocaleLowerCase().includes(searchText) )
|
||||
|
||||
|
||||
) |
||||
} ) |
||||
|
||||
setFilteredData(filtered) |
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const generReportes = () => { |
||||
generarRptRes() |
||||
generarRptDet() |
||||
}
|
||||
|
||||
|
||||
|
||||
// const filtros = (e: any) => {
|
||||
// filtraReporte(e);
|
||||
// filtraReporte1(e);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return( |
||||
<div className='mt-2'>
|
||||
{/* <Card className="mt-3"> */} |
||||
<Card.Body> |
||||
<Form> |
||||
<Row className="align-items-center"> |
||||
<Col xs={1}> |
||||
{/* <Form.Label>Desde</Form.Label> */} |
||||
|
||||
<Col style={{textAlign: 'center'}} >Desde</Col> |
||||
<Form.Control |
||||
defaultValue={Inicio} |
||||
type="date" |
||||
name="Inicio" |
||||
placeholder="Inicio" |
||||
title="Inicio" |
||||
alt="Inicio" |
||||
data-date-format="YYYY-mm-dd" |
||||
onChange={(e) => setInicio(e.target.value)} |
||||
size="sm" |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
{/* <Form.Label>Hasta</Form.Label> */} |
||||
<Col style={{textAlign: 'center'}} >Hasta</Col> |
||||
<Form.Control |
||||
defaultValue={Fin} |
||||
type="date" |
||||
name="Fin" |
||||
placeholder="Fin" |
||||
title="Fin" |
||||
alt="Fin" |
||||
onChange={(e) => setFin(e.target.value)} |
||||
size="sm" |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
<Form.Control |
||||
type="text" |
||||
size="sm" |
||||
placeholder="Search..." |
||||
onChange={ (e) => { |
||||
filtraReporte(e) |
||||
} } |
||||
// onChange={filtros}
|
||||
style={{ height: '10px', padding: '5px' }} |
||||
/> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
<Button |
||||
// size="sm"
|
||||
variant="success" |
||||
onClick={donwloadExel} |
||||
style={{ width: '35%' }} |
||||
> |
||||
<BsFileEarmarkExcel /> |
||||
Excel |
||||
</Button> |
||||
</Col> |
||||
|
||||
<Col xs={2}> |
||||
<Button |
||||
variant="primary" |
||||
onClick={generReportes}
|
||||
style={{ width: '40%' }} |
||||
> |
||||
<BsSearch /> |
||||
Buscar |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
</Card.Body> |
||||
{/* </Card> */} |
||||
|
||||
<MsgInformativo |
||||
show={showToast} |
||||
msg={toastMsg} |
||||
header={toastHeader} |
||||
msgColor={toastColor} |
||||
closeToast={setShowToast} |
||||
/> |
||||
|
||||
|
||||
<Card className='mt-3'>
|
||||
|
||||
<Card.Body>
|
||||
<div className='ag-theme-alpine' style={{ height: 500, width: '100%'}}> |
||||
|
||||
<DataTable
|
||||
noHeader
|
||||
defaultSortFieldId={''} |
||||
defaultSortAsc = {true} |
||||
striped= {true} |
||||
dense = {true} |
||||
paginationPerPage={10} |
||||
pagination
|
||||
highlightOnHover
|
||||
columns={columnsConcepts} |
||||
data={filteredData} |
||||
pointerOnHover |
||||
|
||||
|
||||
|
||||
/> |
||||
</div> |
||||
</Card.Body> |
||||
</Card> |
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
) |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,11 @@ |
||||
export interface DTOTotalHours { |
||||
|
||||
empNo : string ,
|
||||
acNo : string,
|
||||
name : string, |
||||
totalHoursAccumulated : string
|
||||
totalHoursWithMilitaryMinutes : string |
||||
|
||||
|
||||
|
||||
} |
Loading…
Reference in new issue