diff --git a/src/Components/Corresponsales/PedimentosConsolidados/PedimentosConsolidados.tsx b/src/Components/Corresponsales/PedimentosConsolidados/PedimentosConsolidados.tsx new file mode 100644 index 0000000..891d9d4 --- /dev/null +++ b/src/Components/Corresponsales/PedimentosConsolidados/PedimentosConsolidados.tsx @@ -0,0 +1,309 @@ +import { Button, Card, Col, Form, FormControl, FormLabel, Row } from "react-bootstrap" +import CurrencyFormat from "react-currency-format" +import { ICatClavesPedimentos } from "../../../Interfaces/Catalogos/ICatClavesPedimentos" +import { useEffect, useState } from "react" +import CorresponsalesTraficoServices from "../../../Services/Corresponsalias/Corresponsales.Trafico.Services" +import { AgGridReact } from "ag-grid-react" +import { DTOPedimentosConsolidados } from "../../../DTO/Corresponsales/DTOPedimentosConsolidados" +import PedimentosConsolidadosService from "../../../Services/Corresponsalias/Corresponsales.Trafico.Pedimento.Consolidados.Service" +import { IconContext } from "react-icons" +import { BiDownload } from "react-icons/bi" +import { BsPencilFill, BsFileEarmarkPdf, BsTrash } from "react-icons/bs" +import { useDispatch, useSelector } from "react-redux" +import { RootState } from "../../../store/store" +import { addPedimento, deletePedimento, updatePedimento } from "../../../store/features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice" +import { MsgInformativo } from "../../Utils/Toast/msgInformativo" +import { FaEraser } from "react-icons/fa" + +interface IProps { + IdTrafico: number + Aduana: number + Patente: number + ClavesPedimento: ICatClavesPedimentos[] + Depto: string +} + +export const PedimentosConsolidados:React.FC = (props) => { + const dispatch = useDispatch() + const [header, setHeader] = useState('') + const [show, setShowMsg] = useState(false) + const [msg, setMsg] = useState('') + const msgColor = 'primary' + + const [Id, setId] = useState(0) + const [Aduana, setAduana] = useState(props.Aduana) + const [Patente, setPatente] = useState(props.Patente) + const [Pedimento, setPedimento] = useState(0) + const [ClavePedimento, setClavePedimento] = useState(''); + const [FechaPago, setFechaPago] = useState('') + const mCPedimentosConsolidados = useSelector((state:RootState) => state.CPedimentosConsolidados.PedimentosConsolidados) + const [columnDefs] = useState([ + props.Depto === 'Corresponsalias' ? + { + field: 'id', + headerName: 'Acciones', + width: 120, + sortable: true, + filter: true, + cellRenderer: (params: any) => { + return ( +
+ + { + loadRow(params.data) + }} + style={{ cursor: 'pointer' }} + /> + +     + + { + Delete(params.data.id) + }} + style={{ cursor: 'pointer' }} + /> + +
+ ) + } + } : { + field: 'id', + headerName: 'Acciones', + width: 110, + sortable: true, + filter: true, + }, + { field: 'patente', width: 110, sortable: true, filter: true }, + { field: 'aduana', width: 110, sortable: true, filter: true }, + { field: 'pedimento', width: 120, sortable: true, filter: true }, + { field: 'clave', width: 100, sortable: true, filter: true }, + { + field: 'fechaPago', + sortable: true, + filter: true, + flex: 1, //Se encarga de llenar el espacio sobrante de las columnas + cellRenderer: (params: any) => { + if (params.value) return params.value.substring(0, 10) + else return '' + }, + }, + ]) + const [Data, setData] = useState() + + const cleanForm = () => { + setId(0) + setPedimento(0) + setClavePedimento('') + setFechaPago('') + } + + const loadRow = (data: DTOPedimentosConsolidados) => { + setId(data.id) + setAduana(data.aduana) + setPatente(data.patente) + setPedimento(data.pedimento) + setClavePedimento(data.clave) + setFechaPago(setDate(data.fechaPago)) + } + + function setDate(fecha: string | undefined): string { + if (!fecha) return '' + else { + var dd = fecha?.substring(8, 10) + var mm = fecha?.substring(5, 7) + var yyyy = fecha?.substring(0, 4) + return yyyy + '-' + mm + '-' + dd + } + } + + const Append = () => { + if(Aduana !== 0 && + Patente !== 0 && + Pedimento !== 0 && + FechaPago !== '' && + ClavePedimento !== '' ){ + PedimentosConsolidadosService.Append({ + id: Id, + idTrafico: props.IdTrafico, + aduana: Aduana, + patente: Patente, + pedimento: Pedimento, + clave: ClavePedimento, + fechaPago: FechaPago + }).then(resp => { + if(Id > 0){ + dispatch(updatePedimento(resp.data)) + setHeader('Informativo') + setMsg('Datos actualizados correctamente') + setShowMsg(true) + return + } + dispatch(addPedimento(resp.data)) + setHeader('Informativo') + setMsg('Pedimento guardado correctamente') + setShowMsg(true) + return + }).catch((e) => { + setHeader('Error') + setMsg('OcurriĆ³ un error al guardar el pedimento, favor de intentarlo de nuevo.') + setShowMsg(true) + return + }) + }else{ + setHeader('Error') + setMsg('Favor de llenar todos los datos del pedimento') + setShowMsg(true) + return + } + } + + const Delete = (id: number) => { + PedimentosConsolidadosService.Delete(id) + .then(resp => { + dispatch(deletePedimento(id)) + setHeader('Informativo') + setMsg('Pedimento eliminado correctamente') + setShowMsg(true) + return + }) + .catch((e) => { + setHeader('Error') + setMsg('OcurriĆ³ un error al borrar el pedimento, favor de intentarlo de nuevo.') + setShowMsg(true) + return + }) + } + return ( + <> + + + {props.Depto === 'Corresponsalias' ? <> + + { + cleanForm(); + }} + > + + + + + + + Aduana + setAduana(+e.target.value)}> + + + + + Patente + setPatente(+e.target.value)}> + + + + + Pedimento + { + const { value } = values + if(value.length === 7 ){ + CorresponsalesTraficoServices.ValidaTraficoDuplicado(Aduana, Patente, value, props.IdTrafico).then( response => { + if(response.data !== ""){ + /*setHeader('Informativo') + setMsg(`Pedimento Duplicado.\n\rLa referencia ${response.data} ya cuenta con los mismos datos de aduana, patente y pedimento`) + setShowMsg(true)*/ + alert('Ya existe un pedimento con los mismos datos en esta referencia') + return + } + setPedimento(value.length === 0 ? 0 : value) + }) + } + }} + style={{ + fontSize: '18px', + backgroundColor: '#FEFDF5', + border: '2px solid #837F5D', + width: '100%', + textAlign: 'right', + borderRadius: '10px' + }} + /> + + + + + Clave + { + setClavePedimento(e.target.value) + }} + className="form-select form-select-sm" + value={ClavePedimento} + > + + {props.ClavesPedimento + ? props.ClavesPedimento.map((item, index) => { + return ( + + ) + }) + : ''} + + + + + + Fec. Pago + setFechaPago(e.target.value)} + /> + + + + + + +
: ("") } +
+ +
+
+
+ { + setShowMsg(false) + }} + /> + ) +} \ No newline at end of file diff --git a/src/Components/Corresponsales/TraficoCorresponsales.tsx b/src/Components/Corresponsales/TraficoCorresponsales.tsx index 348966d..9581664 100644 --- a/src/Components/Corresponsales/TraficoCorresponsales.tsx +++ b/src/Components/Corresponsales/TraficoCorresponsales.tsx @@ -8,6 +8,7 @@ import { Container, Form, FormControl, + FormLabel, InputGroup, Modal, Row, @@ -121,6 +122,9 @@ import FileManagerServices from '../../Services/Utils/FileManager.Services' import CorresponsalesAnticiposServices from '../../Services/Corresponsalias/Corresponsales.Anticipos.Services' import { BiDownload } from 'react-icons/bi' import CorresponsalesFacturasServices from '../../Services/Corresponsalias/Corresponsales.Facturas.Services' +import { PedimentosConsolidados } from './PedimentosConsolidados/PedimentosConsolidados' +import PedimentosConsolidadosService from '../../Services/Corresponsalias/Corresponsales.Trafico.Pedimento.Consolidados.Service' +import { populatePedimentos } from '../../store/features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice' interface IProps { IDTrafico: number @@ -181,6 +185,9 @@ export default function TraficoCorresponsales (props:IProps) { state.CCueCompEstatus.CorresponsalesCuentasComplementariasEstatus ) const mCProveedores = useSelector((state:RootState) => state.CatProveedores.CatalogoProveedores) + const mCPedimentosConsolidados = useSelector( + (state:RootState) => state.CPedimentosConsolidados.PedimentosConsolidados + ) const [ModalSize, setModalSize] = useState('sm') const [showModal, setShowModal] = useState(false) @@ -249,6 +256,9 @@ export default function TraficoCorresponsales (props:IProps) { 'Facturas pagos a terceros' ) const [LblAnticipos, setLblAnticipos] = useState('Anticipos') + const [LblPedimentos, setLblPedimentos] = useState(() => { + return Depto === 'Corresponsalias' ? 'Consolidar Pedimentos' : 'Pedimentos Consolidados' + }) const [StatusTrafico, setStatusTrafico] = useState(1) const [StatusColor, setStatusColor] = useState('#FFFFFF') const [PagosaTerceros, setPagosaTerceros] = useState(0) @@ -772,6 +782,11 @@ export default function TraficoCorresponsales (props:IProps) { setShowMsg(true) return }) + PedimentosConsolidadosService.GetAll(IDTrafico) + .then((resp) => { + dispatch(populatePedimentos(resp.data)) + }) + .catch(() => {}) loadRectificacionHistorico() DoesThe2ZipFileExists() } @@ -1064,6 +1079,12 @@ export default function TraficoCorresponsales (props:IProps) { setLblAnticipos('(' + ant + ') anticipos') }, [mCAnticipos]) + useEffect(() => { + let ant = mCPedimentosConsolidados.length + let label = Depto === 'Corresponsalias' ? `Consolidar Pedimentos (${ant})` : `Pedimentos Consolidados (${ant})` + setLblPedimentos(label) + }, [mCPedimentosConsolidados]) + useEffect(() => { let fac3 = mCFTerceros.filter(function (row) { return row.factura !== '-Seleccione-' && row.idTrafico === IDTrafico @@ -1985,170 +2006,178 @@ export default function TraficoCorresponsales (props:IProps) {
{EncabezadoPedimento1} - - - - Trafico - + + + + + + Trafico + { + setTrafico(e.target.value) + }} + /> + + + + + Aduana + + + + + + Patente + + + + + + + + { + openSOIA() + }} + style={{ cursor: 'pointer' }} + > + Pedimento + + { + const { value } = values + if(value.length === 7 ){ + CTrafDataService.ValidaTraficoDuplicado(Aduana, Patente, value, IDTrafico).then( response => { + if(response.data !== ""){ + setHeader('Informativo') + setMsg(`Pedimento Duplicado.\n\rLa referencia ${response.data} ya cuenta con los mismos datos de aduana, patente y pedimento`) + setShowMsg(true) + return + } + setPedimento(value.length === 0 ? 0 : value) + }) + } + }} + style={{ + fontSize: '18px', + backgroundColor: '#FEFDF5', + border: '2px solid #837F5D', + width: '100%', + textAlign: 'right', + borderRadius: '10px' + }} + /> + + + + + Clave + { + setClavePedimento(e.target.value) + }} + className="form-select form-select-sm" + value={ClavePedimento} + disabled={(Depto !== 'Corresponsalias')} + > + + {ClavesPedimentos + ? ClavesPedimentos.map((item, index) => { + return ( + + ) + }) + : ''} + + + + + + Fec. Pago + { - setTrafico(e.target.value) - }} - /> - - - - - Aduana - - - - - - Patente - - - - - - { - openSOIA() - }} - style={{ cursor: 'pointer' }} - > - Pedimento - - { - const { value } = values - if(value.length === 7 ){ - CTrafDataService.ValidaTraficoDuplicado(Aduana, Patente, value, IDTrafico).then( response => { - if(response.data !== ""){ - setHeader('Informativo') - setMsg(`Pedimento Duplicado.\n\rLa referencia ${response.data} ya cuenta con los mismos datos de aduana, patente y pedimento`) - setShowMsg(true) - return - } - setPedimento(value.length === 0 ? 0 : value) - }) + onChange={(e) => setFechaPago(e.target.value)} + /> + + + + + Cargo A + - - - - - - - Clave - { - setClavePedimento(e.target.value) - }} - className="form-select form-select-sm" - value={ClavePedimento} - disabled={(Depto !== 'Corresponsalias')} - > - - {ClavesPedimentos - ? ClavesPedimentos.map((item, index) => { - return ( - - ) - }) - : ''} - - - - - - Fec. Pago + onChange={(e) => { + setCargoPara(parseInt(e.target.value)) + }} + + > + + + + + + + + + + Causa Rectificacion: + + setFechaPago(e.target.value)} + as="textarea" + id="Observacion" + size="sm" + value={CausaRectificacion} + disabled={Depto !== 'Corresponsalias'} + onChange={(e) => setCausaRectificacion(e.target.value)} + style={{visibility: AduanaH === '' ? 'hidden':'visible'}} /> - - - - - Cargo A - { - setCargoPara(parseInt(e.target.value)) - }} - - > - - - - - - - - - - Causa Rectificacion: - - - setCausaRectificacion(e.target.value)} - style={{visibility: AduanaH === '' ? 'hidden':'visible'}} - /> - - + +
@@ -4199,7 +4228,7 @@ export default function TraficoCorresponsales (props:IProps) { dialogClassName={ LoadComponent === 1 || LoadComponent === 2 || LoadComponent === 9 ? 'modal-90w' - : 'modal-50w' + : LoadComponent === 13 ? 'modal-70w' : 'modal-50w' } > @@ -4280,6 +4309,11 @@ export default function TraficoCorresponsales (props:IProps) { /> ) : null} + {LoadComponent === 13 ? ( +
+ +
+ ) : null}
("/Corresponsalias/PedimentosConsolidados/Append", data); + } + GetAll(idTrafico: number) { + return http.get(`/Corresponsalias/PedimentosConsolidados/GetAll?IdTrafico=${idTrafico}`); + } + Delete(id: number) { + return http.delete(`/Corresponsalias/PedimentosConsolidados/Delete/${id}`); + } +} + +export default new PedimentosConsolidadosService(); \ No newline at end of file diff --git a/src/store/features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice.ts b/src/store/features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice.ts new file mode 100644 index 0000000..16cb56c --- /dev/null +++ b/src/store/features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice.ts @@ -0,0 +1,40 @@ +import { createSlice, PayloadAction } from "@reduxjs/toolkit"; +import { DTOPedimentosConsolidados } from "../../../DTO/Corresponsales/DTOPedimentosConsolidados"; + +const PedimentosConsolidados: DTOPedimentosConsolidados[] = [] + +const initialState = {PedimentosConsolidados}; + +export const PedimentosConsolidadosSlice = createSlice({ + name: 'PedimentosConsolidados', + initialState: initialState, + reducers: { + populatePedimentos : (state, action: PayloadAction) => { + state.PedimentosConsolidados = [] + state.PedimentosConsolidados.push(... action.payload) + }, + addPedimento : (state, action: PayloadAction) => { + var Existe = state.PedimentosConsolidados.find(function(item) { + return item.id === action.payload.id; + }); + if (!Existe) state.PedimentosConsolidados.push(action.payload) + }, + updatePedimento : (state, action: PayloadAction) => { + const i = state.PedimentosConsolidados.findIndex(_element => _element.id === action.payload.id); + if (i > -1) state.PedimentosConsolidados[i] = action.payload; + else state.PedimentosConsolidados.push(action.payload); + }, + deletePedimento : (state, action: PayloadAction) => { + const newArr = state.PedimentosConsolidados.filter(data => data.id != action.payload); + state.PedimentosConsolidados=newArr + }, + } +}) + + +export const { populatePedimentos, + addPedimento, + updatePedimento, + deletePedimento, +} = PedimentosConsolidadosSlice.actions; +export default PedimentosConsolidadosSlice.reducer; \ No newline at end of file diff --git a/src/store/store.ts b/src/store/store.ts index 6f61208..f7458c5 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -10,6 +10,7 @@ import CorresponsalesAnticipos from './features/Corresponsales/CorresponsalesAnt import CorresponsalesGuiasSlice from './features/Corresponsales/CorresponsalesGuiasSlice' import CorresponsalesPartidasSlice from './features/Corresponsales/CorresponsalesPartidasSlice' import CorresponsalesCuentasComplementariasEstatusSlice from './features/Corresponsales/CorresponsalesCuentasComplementariasEstatusSlice' +import PedimentosConsolidadosSlice from './features/Corresponsales/CorresponsalesPedimentosConsolidadosSlice' export const store = configureStore({ @@ -24,7 +25,8 @@ export const store = configureStore({ CAnticipos: CorresponsalesAnticipos, CGuias: CorresponsalesGuiasSlice, CPartidas: CorresponsalesPartidasSlice, - CCueCompEstatus : CorresponsalesCuentasComplementariasEstatusSlice + CCueCompEstatus : CorresponsalesCuentasComplementariasEstatusSlice, + CPedimentosConsolidados: PedimentosConsolidadosSlice } })