Manuales POS



CORTE_CAJA_11_CIERRE PENDIENTE DE OPERACIÓN - CORTE MANUAL

Audiencia 

Este documento está pensado para ser consumido por los equipos de:

  1. Soporte Farmax OR (Niveles 1 y 2)

  2. Equipo de desarrollo TI (Farmacias del Ahorro y proveedor externo)

 

Descripción general

Se presenta que la sucursal 1556 Caja 21 no pueden loguearse después de una reinstalación y quedó un turno por finalizar su corte de cierre desde el día 22 de Febrero del 2024.

 

Impacto a la operación

El impacto de la operación es media en virtud de que la operación no se ve comprometida por esta incidencia.Criticidad

Alto

 

Medio

X

Bajo

 

Sistemas/módulos involucrados

POS

Precondiciones 

Aquí se debe especificar el nivel de acceso requerido por cada sistema (aplicativo o base de datos), indicando el rol o perfil necesario para para el diagnóstico y/o solución del incidente.

 

POS

Usuario: 

Contraseña: 

Procedimiento de diagnóstico

Este el seguimiento que se dio para la revisión de la Caja 21 Sucursal 1556.

 

  1. Se valido el log de la caja Farmax POS que se encuentra en la siguiente ruta C:\ProgramData\FAhorro\FARMAX_POS\ y se encontró el siguiente mensaje de error.

 

[2024-02-28 13:12:02:754],FARMAX_POS,,ERROR,[CATCHEXCEPTION],Excepción no controlada ToString(): System.OutOfMemoryException: No hay suficiente memoria para continuar ejecutando el programa.
     en System.Runtime.InteropServices.ComTypes.IDataObject.GetData(FORMATETC& format, STGMEDIUM& medium)
     en System.Windows.DataObject.OleConverter.GetDataInner(FORMATETC& formatetc, STGMEDIUM& medium)

 

  1. Se procedió a validar los recursos de la caja y también se comparó otras cajas para ver si manejaban lo mismo.

Interfaz de usuario gráfica, Texto, AplicaciónDescripción generada automáticamente

  1. Una vez validado los recursos y que compartan el mismo margen para las demás cajas se procedió a validar el usuario 00133534 con el siguiente query

 

use POSDB_OR;
declare @empleado int =  00133534
declare @login varchar(20) = '00133534'   --00150253, 00170679, 00170984
SELECT 'admEmpleados',* FROM admEmpleados where idnomina = @empleado 
SELECT 'admEmpleadosSucursales',* FROM admEmpleadosSucursales where idempleado = @empleado 
select 'segUsuariosCat',* from [dbo].[segUsuariosCat] where idempleado = @empleado 
select 'segUsuariosCat',* from [dbo].[segUsuariosCat] where logIn = @login 
select 'segUsuariosReg',* from [dbo].[segUsuariosReg]  where idUsuario in (select idUsuario from [dbo].[segUsuariosCat] where idempleado = @empleado) 
select 'segUsuariosRoles',sur.idRol,src.nombreRol,sur.idUsuario,sur.estaActivo from [dbo].[segUsuariosRoles] sur 
inner join segRolesCat src on sur.idRol = src.idRol 
where idUsuario in (select idUsuario from [dbo].[segUsuariosCat] where idempleado = @empleado) 
select '[segUsuariosSucursales]', sus.codigoSucursal,gsc.descripcion, sus.idUsuario, sus.estaActivo from [dbo].[segUsuariosSucursales] sus 
inner Join genSucursalesCat gsc on sus.codigoSucursal = gsc.codigoSucursal 
where idUsuario in (select idUsuario from [dbo].[segUsuariosCat] where idempleado = @empleado) 
select 'segHistoriaContrasenasReg',* from segHistoriaContrasenasReg where idUsuario in (select idUsuario from [dbo].[segUsuariosCat] where idempleado = @empleado)

 

  1. Se encontró que el usuario no tenia nombre y que no estaba asignado a la sucursal indicada, que no tenía rol, una fecha de vigencia, accesos y bloqueos, etc.


 

Interfaz de usuario gráfica, Texto, Aplicación, Correo electrónicoDescripción generada automáticamente

 

  1. Se procedió a reportar el usuario con farmacias para que validaran con People soft los datos faltantes y la asignación correspondiente a la sucursal.


 

  1. Se procedió a validar la sincronización de la caja en la taba genCajasCat y se visualizo que el dato no había sincronizado, hasta el día 29 de febrero se vio reflejado el dato actualizado, est se ejecuta con el siguiente query  

 

use POSDB_OR
select * from [dbo].[genCajasCat] where codigoSucursal = 1556 and numeroCaja in (21);

 

 

  1. Se valido el archivo host que se encuentra en la siguiente ruta; C:\Windows\System32\drivers\etc\ y se encontró que las demás cajas tenían una url de más por lo cual se procedió a copiar y a modificar el archivo agregándole la url faltante, antes de realizar el cambio y actualizarlo, se realizó un respaldo del archivo host copiándolo en documentos.

10.0.1.111 FAHORROMEX126
FAHORROMEX221
  1.  


Se procedió a realizar el corte manual desde el store, debemos conectarnos a la base de datos para esto debemos ejecutar el siguiente query, copiar la ip y realizar una nueva conexión.

 

use POSDB_OR
SELECT * FROM upRegistroServidorSucursal WITH(NOLOCK)
WHERE codigoSucursal = 1553

 

 

  1. Una vez conectados debemos copiar el código de turno que está pendiente por finalizar, esto se obtiene con el siguiente query.

 

use POSDB_OR
select * from venTurnosCajaReg (nolock)
where codigoSucursal = 1553 and codigoSucursal = 21 --and fechaOperacion >= '2024-03-02' and fechaOperacion <= '2024-03-02' --and codigoCajero = 129096 
order by fechaHoraFinalTurno desc
  1.  Ya que tenemos el código de turno reemplazamos y pegamos en el query que se ejecutara para realizar el corte de turno manual.

select @@servername
-- parametros
DECLARE @codigoTurno UNIQUEIDENTIFIER = 'BB2925C4-E5D8-EE11-9E3B-644ED71D5D89';
-- Valores que se obtienen en tiempo de ejecucion
DECLARE @turnoCerrado BIT = 0;
DECLARE @sucursal INT;
DECLARE @caja INT;
DECLARE @empleado INT;
DECLARE @usuario INT;
DECLARE @idFechaOperacion BIGINT;
DECLARE @fechaOperacion DATE;
DECLARE @versionSoftware BIGINT;
-- Revisa si el turno ya fue cerrado
SELECT
    @turnoCerrado = IIF(turno.estadoActual = 'C', 1, 0),
    @sucursal = turno.codigoSucursal,
    @caja = turno.numeroCaja,
    @empleado = turno.codigoCajero,
    @usuario = turno.codigoUsuario,
    @idFechaOperacion = turno.idFechaOperacion,
    @fechaOperacion = turno.fechaOperacion,
    @versionSoftware = turno.versionSoftware
FROM venTurnosCajaReg turno (NOLOCK)
WHERE codigoTurno = @codigoTurno;
IF @turnoCerrado = 1
BEGIN
    print 'El turno ya esta cerrado'
    RETURN
END
DECLARE @totales TABLE(
    codigoFormaDePago INT,
    renglon INT,
    importeFisico DECIMAL(19, 4),
    importeTeorico DECIMAL(19, 4),
    importeRetiro DECIMAL(19, 4),
    cambio DECIMAL(19, 4),
    tipoCambio DECIMAL(19, 4)
);
-- Obtiene los totales
INSERT INTO @totales
SELECT
    movimientoDetalle.codigoFormaPago,
    ROW_NUMBER() over (order by movimientoDetalle.codigoFormaPago),
    SUM(
        (
            movimientoDetalle.importePago
            - IIF(movimientoDetalle.codigoFormaPago = 1, ISNULL(transaccion.cambio, 0), 0)
        )
        * IIF(movimiento.tipoMovimiento = N'E', -1, 1)
    ),
    SUM(IIF(movimiento.tipoMovimiento = 'I', movimientoDetalle.importePago, 0)),
    SUM(IIF(movimiento.tipoTransaccion = 'RV', movimientoDetalle.importePago, 0)),
    SUM(IIF(movimientoDetalle.codigoFormaPago = 1, ISNULL(transaccion.cambio, 0), 0)),
    MAX(movimientoDetalle.tipoDeCambio)
FROM genMovimientosCajasCab movimiento (NOLOCK)
    INNER JOIN genMovimientosCajasDet movimientoDetalle (NOLOCK)
        ON movimiento.codigoMovimientoCaja = movimientoDetalle.codigoMovimientoCaja
    INNER JOIN genFormasDePagoCat forma (NOLOCK)
        ON movimientoDetalle.codigoFormaPago = forma.codigoFormaPago
    LEFT JOIN trnTransaccionesCab  transaccion (NOLOCK)
        ON movimiento.folioOperacion = transaccion.folioTransaccion
WHERE codigoTurno = @codigoTurno
GROUP BY movimientoDetalle.codigoFormaPago;
BEGIN TRANSACTION
-- parametros
DECLARE @tipoRetiro INT = 2; -- retiro de administracion
-- nuevos identificadores
DECLARE @codigoRetiroNuevo UNIQUEIDENTIFIER = NEWID();
DECLARE @codigoMovimientoCajaNuevo UNIQUEIDENTIFIER = NEWID();
DECLARE @codigoCorteNuevo UNIQUEIDENTIFIER = NEWID();
DECLARE @codigoFajillaNueva UNIQUEIDENTIFIER = NEWID();
-- nuevos folios
DECLARE @folioCorte NVARCHAR(15);
DECLARE @folioRetiro NVARCHAR(15);
DECLARE @folioFajilla NVARCHAR(15);
-- id de categorias de foliadores
DECLARE @foliadorCorteId INT = 18;
DECLARE @foliadorRetiroId INT = 19;
-- nuevo folio de corte
SELECT
    @folioCorte = LTRIM(RTRIM(tipoFoliador.prefijo))
    + RIGHT('0000'+CAST(foliadorCaja.codigoSucursal AS NVARCHAR), 4)
    + RIGHT('00'+CAST(foliadorCaja.numeroCaja AS NVARCHAR), 2)
    + RIGHT('000000000'+CAST(foliadorCaja.consecutivo + 1 AS NVARCHAR), 9 - LEN(tipoFoliador.prefijo))
FROM dbo.genFoliadoresCajasReg foliadorCaja
    INNER JOIN dbo.cnfTiposFoliadoresCat tipoFoliador ON foliadorCaja.codigoTipoFoliadorCat = tipoFoliador.codigoTipoFoliadorCat
WHERE codigoSucursal = @sucursal
    AND numeroCaja = @caja
    AND tipoFoliador.codigoTipoFoliadorCat = @foliadorCorteId;
-- se actualiza el foliador
UPDATE genFoliadoresCajasReg
SET consecutivo = consecutivo + 1
WHERE codigoSucursal = @sucursal
    AND numeroCaja = @caja
    AND codigoTipoFoliadorCat = @foliadorCorteId;
-- nuevo folio de retiro
SELECT
    @folioRetiro = LTRIM(RTRIM(tipoFoliador.prefijo))
    + RIGHT('0000'+CAST(foliadorCaja.codigoSucursal AS NVARCHAR), 4)
    + RIGHT('00'+CAST(foliadorCaja.numeroCaja AS NVARCHAR), 2)
    + RIGHT('000000000'+CAST(foliadorCaja.consecutivo + 1 AS NVARCHAR), 9 - LEN(tipoFoliador.prefijo))
FROM dbo.genFoliadoresCajasReg foliadorCaja
    INNER JOIN dbo.cnfTiposFoliadoresCat tipoFoliador ON foliadorCaja.codigoTipoFoliadorCat = tipoFoliador.codigoTipoFoliadorCat
WHERE codigoSucursal = @sucursal
    AND numeroCaja = @caja
    AND tipoFoliador.codigoTipoFoliadorCat = @foliadorRetiroId;
-- se actualiza el foliador
UPDATE genFoliadoresCajasReg
SET consecutivo = consecutivo + 1
WHERE codigoSucursal = @sucursal
    AND numeroCaja = @caja
    AND codigoTipoFoliadorCat = @foliadorRetiroId;
-- para la fajilla no se utiliza un foliador aunque si existe
-- el tipo en la tabla catalogo, el folio de la fajilla
-- es el folio del retiro sustituyendo RV por F0
-- se crea el movimiento de caja para el retiro
INSERT INTO genMovimientosCajasCab (codigoMovimientoCaja, codigoTurno, tipoMovimiento, idFechaOperacion, codigoSucursal, fechaOperacion, folioOperacion, folioCorte, estaModoEntrenamiento, tipoTransaccion, codigoUsuario, fechaActualizacion, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
VALUES (@codigoMovimientoCajaNuevo, @codigoTurno, N'E', @idFechaOperacion, @sucursal, @fechaOperacion, @folioRetiro, @folioCorte, 0, N'RV', @usuario, GETDATE(), GETDATE(), GETDATE(), N'FARMAX.DEFAULT', 1, N'N');
-- se crea el retiro
INSERT INTO venRetiroValoresCab (codigoRetiro, codigoTipoRetiro, codigoSucursal, numeroCaja, codigoCajero, codigoMovimientoCaja, folioRetiro, fecha, importe, retiroEnCorte, estaModoEntrenamiento, codigoUsuario, fechaActualizacion, tiempoTranscurridoDesdeAlerta, versionSoftware, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
VALUES (@codigoRetiroNuevo, @tipoRetiro, @sucursal, @caja, @empleado, @codigoMovimientoCajaNuevo, @folioRetiro, GETDATE(), (SELECT SUM(importeFisico) FROM @totales), 1, 0, @usuario, GETDATE(), 0, @versionSoftware, GETDATE(), GETDATE(), N'FARMAX.DEFAULT', 1, N'N');
-- se crea el corte
INSERT INTO venCortesCab (codigoCorte, codigoRetiro, codigoTurno, codigoSucursal, idFechaOperacion, fechaOperacion, tipoCorte, folioCorte, estaModoEntrenamiento, codigoUsuario, fechaCreacion, fechaActualizacion, versionSoftware, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
VALUES (@codigoCorteNuevo, @codigoRetiroNuevo, @codigoTurno, @sucursal, @idFechaOperacion, @fechaOperacion, 'P', @folioCorte, 0, @usuario, GETDATE(), GETDATE(), @versionSoftware, GETDATE(), GETDATE(), N'FARMAX.DEFAULT', 1, N'N');
-- detalle del corte
INSERT INTO venCortesDet (codigoCorte, codigoFormaPago, renglon, importeFisico, importeTeorico, importeRetiro, cambio, tipoDeCambio, importeFaltanteRecuperado, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
SELECT
    @codigoCorteNuevo,
    total.codigoFormaDePago,
    total.renglon,
    total.importeFisico,
    total.importeTeorico,
    total.importeRetiro,
    total.cambio,
    total.tipoCambio,
    0,
    GETDATE(),
    GETDATE(),
    N'FARMAX.DEFAULT',
    1,
    N'N'
FROM @totales total;
-- se crea la fajilla para la forma de pago de efectivo
IF (SELECT TOP 1 1 FROM @totales total WHERE total.codigoFormaDePago = 1) = 1
BEGIN
    -- Asi se genera el folio de la fajilla en el codigo
    -- se utiliza el mismo numero sustituyendo 'RV' por 'F0'
    SET @folioFajilla = CONCAT('F0', SUBSTRING(@folioRetiro, 3, LEN(@folioRetiro) - 2))
    INSERT INTO venFajillasReg (codigoFajilla, codigoSucursal, numeroCaja, folioFajilla, fecha, folioRetiro, codigoFajillaAgrupador, codigoCajero, importe, status, estaModoEntrenamiento, codigoUsuario, fechaActualizacion, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
    SELECT
        @codigoFajillaNueva,
        @sucursal,
        @caja,
        @folioFajilla,
        GETDATE(),
        @folioRetiro,
        NULL,
        @empleado,
        total.importeFisico,
        'V',
        0,
        @usuario,
        GETDATE(),
        GETDATE(),
        GETDATE(),
        N'FARMAX.DEFAULT',
        1,
        N'N'
    FROM @totales total
    WHERE codigoFormaDePago = 1;
END
-- se crea el detalle del retiro
INSERT INTO venRetiroValoresDet (codigoRetiro, codigoFormaPago, renglon, codigoFajilla, importe, tipoDeCambio, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
SELECT
    @codigoRetiroNuevo,
    total.codigoFormaDePago,
    total.renglon,
    IIF(total.codigoFormaDePago = 1, @codigoFajillaNueva, NULL), -- las fajillas son solo para el efectivo
    total.importeFisico,
    0, -- se pone en cero por cierta regla en codigo que revisa si es mayor a cero o si es de tipo efectivo para crear una fajilla
    GETDATE(),
    GETDATE(),
    N'FARMAX.DEFAULT',
    1,
    N'N'
FROM @totales total;
-- se crea el detalle de retiro documentos
INSERT INTO venRetirosDocumentosReg (codigoRetiro, codigoFormaDePago, renglon, folio, importe, syncCreadoFecha, syncActualizadoFecha, syncActualizadoPor, syncVersionRegistro, syncTransferido)
SELECT
    @codigoRetiroNuevo,
    movimientoDetalle.codigoFormaPago,
    ROW_NUMBER() over (order by movimientoDetalle.codigoFormaPago),
    transaccion.folioTransaccion,
    transaccion.subTotal + transaccion.iva,
    GETDATE(),
    GETDATE(),
    N'FARMAX.DEFAULT',
    1,
    N'N'
FROM trnTransaccionesCab transaccion (NOLOCK)
    INNER JOIN genMovimientosCajasCab movimiento (NOLOCK)
        ON transaccion.codigoMovimientoCaja = movimiento.codigoMovimientoCaja
    INNER JOIN genMovimientosCajasDet movimientoDetalle (NOLOCK)
        ON movimiento.codigoMovimientoCaja = movimientoDetalle.codigoMovimientoCaja
    INNER JOIN genFormasDePagoCat formaDePago (NOLOCK)
        ON movimientoDetalle.codigoFormaPago = formaDePago.codigoFormaPago
WHERE movimiento.codigoTurno = @codigoTurno
    AND movimiento.tipoMovimiento = 'I'
    AND formaDePago.codigoFormaPago IN (11, 12, 16, 24, 60) -- estas son las formas de pago para las que se ha hecho retiro de documentos en todo archiving
    AND transaccion.estaActivo = 1
    AND transaccion.status = 'V'
ORDER BY movimientoDetalle.codigoFormaPago;
-- Asignar el folio de corte a los movimientos del turno
UPDATE genMovimientosCajasCab
SET folioCorte = @folioCorte,
    syncActualizadoFecha = GETDATE(),
    syncActualizadoPor = 'FARMAX.DEFAULT',
    syncVersionRegistro = syncVersionRegistro + 1,
    syncTransferido = N'N'
WHERE codigoTurno = @codigoTurno
    AND folioCorte IS NULL;
-- cerrar el turno
UPDATE venTurnosCajaReg
SET estadoActual = 'C',
    cajaDisponible = 1,
    cierreAutomaticoTurno = 1,
    fechaHoraFinalTurno = GETDATE(),
    fechaActualizacion = GETDATE(),
    syncActualizadoFecha = GETDATE(),
    syncActualizadoPor = N'FARMAX.DEFAULT',
    syncVersionRegistro = syncVersionRegistro + 1,
    syncTransferido = N'N'
WHERE codigoTurno = @codigoTurno;
COMMIT;

Procedimiento de solución

La solución son todos los puntos que se trataron para la sucursal y una vez revisada procedimos a iniciar sesión en el PV, solicitando el usuario que tenia el problema y tambien solicitando otro usuario asignado a la misma sucursal.

 

Validación

No aplica.

 

Notificación de resolución

Especificar la lista de usuarios que deben ser notificados al momento que se ha confirmado la resolución de la incidencia.

Incidencia relacionada

INC 2024-125540
INC 2024-131543
INC 2024-103611
INC 2024-087022
INC 2024-116328
INC 2024-234106
INC 2024-233445
INC 2024-249651

 

Glosario

Revisa el glosario del equipo de soporte de Farmacias del ahorro aquí

 

Beskrivning
INC 2024-125540 INC 2024-131543 INC 2024-103611 INC 2024-087022 INC 2024-116328 INC 2024-234106 INC 2024-233445 INC 2024-249651
Categoría: Corte de caja
Taggar
cortes
Senaste
REPORTES_01_Generacion reporte de uso monedero Föregående