unit Unit1;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, DB, FIBDataSet, pFIBDataSet, Menus,
  FIBDatabase, pFIBDatabase, ComCtrls, wwdblook, wwdbdatetimepicker,
  fcOutlookList, fcButton, fcImgBtn, fcShapeBtn, fcClearPanel,
  fcButtonGroup, fcOutlookBar, ImgList, Mask, wwdbedit, FIBQuery,
  pFIBQuery, pFIBStoredProc, Wwdatsrc, Registry, WSCirculodelasalud, XSBuiltIns,
  FMTBcd, pFIBScripter, base64, AES, frxpngimage, dxGDIPlusClasses, GetBonusProductListResponse,
  xmldom, XMLIntf, msxmldom, XMLDoc;

type
  EErrorMG = class(Exception);
  TForm1 = class(TForm)
    IBDatabase1: TpFIBDatabase;
    Panel1: TPanel;
    Label5: TLabel;
    Panel2: TPanel;
    StatusBar1: TStatusBar;
    GroupBox1: TGroupBox;
    trTrans: TpFIBTransaction;
    MainMenu1: TMainMenu;
    Salir1: TMenuItem;
    Informacin1: TMenuItem;
    CentrodeReportes1: TMenuItem;
    Memo1: TMemo;
    trMetadatos: TpFIBTransaction;
    dsMetadatos: TpFIBDataSet;
    Scripter1: TpFIBScripter;
    Label1: TLabel;
    IBQuery1: TpFIBDataSet;
    Herramientas1: TMenuItem;
    Configuracion: TMenuItem;
    Timer1: TTimer;
    Timer2: TTimer;
    Button3: TButton;
    Button4: TButton;
    dsDoctosOV: TpFIBDataSet;
    dsObtenerArticulos: TpFIBDataSet;
    spDoctoId: TpFIBStoredProc;
    trElimina: TpFIBTransaction;
    dsElimina: TpFIBDataSet;
    dsFechaServidor: TpFIBDataSet;
    dsDoctosVM: TpFIBDataSet;
    dsObtenerArticulosVM: TpFIBDataSet;
    dsEliminaVM: TpFIBDataSet;
    Image1: TImage;
    CerrarVentasPendientes: TMenuItem;
    Scripter2: TpFIBScripter;
    spPrecioImpto: TpFIBStoredProc;
    Reporte1: TMenuItem;
    Scripter3: TpFIBScripter;
    dsCajas: TpFIBDataSet;
    dsoCajas: TDataSource;
    AsignarCaja1: TMenuItem;
    dsPzsPendientes: TpFIBDataSet;
    dsAgruparArt: TpFIBDataSet;
    dsModArt: TpFIBDataSet;
    trModifica: TpFIBTransaction;
    Historialdecomprasporpaciente1: TMenuItem;
    Scripter4: TpFIBScripter;
    trCerrarVen: TpFIBTransaction;
    dsCerrarVen: TpFIBDataSet;
    dsVMPendientes: TpFIBDataSet;
    dsObtenerArticulosVM1: TpFIBDataSet;
    Memo2: TMemo;
    Label2: TLabel;
    trWrite: TpFIBTransaction;
    dsWrite: TpFIBDataSet;
    IBQuery2: TpFIBDataSet;
    dsFechaServidor1: TpFIBDataSet;
    Scripter5: TpFIBScripter;
    mmError: TMemo;
    mmBien: TMemo;
    mmError1: TMemo;
    dsArticulos: TpFIBDataSet;
    lblConexion: TLabel;
    Label4: TLabel;
    mmBien1: TMemo;
    mmError2: TMemo;
    dsEliminaDet: TpFIBDataSet;
    XMLDocument1: TXMLDocument;
    dsObtenerArticulosAB: TpFIBDataSet;
    dsObtenerArticulosAB1: TpFIBDataSet;
    Panel3: TPanel;
    GroupBox2: TGroupBox;
    Button1: TButton;
    Button2: TButton;
    Button5: TButton;
    Button6: TButton;
    Panel4: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    Panel9: TPanel;
    Panel10: TPanel;
    trPromos: TpFIBTransaction;
    dsPromos: TpFIBDataSet;
    spCatalogoId: TpFIBStoredProc;
    Scripter6: TpFIBScripter;
    Panel11: TPanel;
    Scripter7: TpFIBScripter;
    Label3: TLabel;
    mmPromoArt: TMemo;
    Scripter8: TpFIBScripter;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Informacin1Click(Sender: TObject);
    procedure Salir1Click(Sender: TObject);
    procedure CentrodeReportes1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ConfiguracionClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Reporte1Click(Sender: TObject);
    procedure AsignarCaja1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Historialdecomprasporpaciente1Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure CerrarVentasPendientesClick(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }

  public

    FPGratis, FMDescto, FDescto, FPrecio:String;
    FPMP, FPVM:Integer;
    FCajeroId, FCajaId, FClienteId, VERSION_ACTUAL_MM:Integer;
    //Datos Login
    FIdCadena, FIdSucursal, FUsuario, FPassword:String;

    FConectado, FDetenido:String;

    FVersion:Integer;

    Afechanacimientorep :String;

    //metadatos
    function Verifica_Tabla():Boolean;
    procedure Inicializar_Transacciones(SN_Rollback:String);
    //interfase
    function VerificarConexionWS():Boolean;
    function ObtenerVersionWS():String;
    function IniciarSesion(var ASesion:String):Boolean;
    function ActivarTarjeta(var ASesion, ANombreCajero, ANoTarjeta, ANombre, AAPaterno, AAMaterno, ATelefono, AEmail, ASexo, ACP, AMensajeError:String; AFNacimiento:TXSDateTime):Boolean;
    function ValidarTarjeta(var ASesion, ANoTarjeta, AMensajeError, AFolioTarjeta:String):Boolean;
    function ObtenerDatos(var AClienteId,ADirCliId,AAlmacenId,ADoctoId:Integer; var ANombreCliente:String):Boolean;
    function ObtenerNoTarjeta(var Id:Integer):String;
    function ObtenerSesion(var AClienteId,ASesionId:Integer; var ASesion:String):Boolean;
    function AgruparArticulos(ADoctoId:Integer; var Error:String):Boolean;
    procedure ProcesoPrincipal();
    procedure ProcesoFinal();
    procedure IntentosCierre();

    //conexión
    procedure Conectar();
    procedure MensajeEstatus(Mensaje:String);
    procedure SetRegistryData(RootKey: HKEY; Key, Value: string; RegDataType: TRegDataType; Data: variant);
    function GetRegistryData(RootKey: HKEY; Key, Value: string): variant;
    function DescifrarTexto(Str, Clave : String): String;
    procedure Abrir();
    function VerificarConexion():Boolean;
    procedure IniciarAutoConexion();
    procedure BuscarDatos();
    procedure GuardarError(lSesionId:Integer);
    procedure GuardarFolioPedido(lResPedido, lFolioVM:String; lSesionId:Integer);
    procedure Conexion();
    procedure GuardarDatosVM(lFolioVM, Estatus:String;lAlmacenId,lCajeroId,lSesionId:Integer;lTotalVM:Double);

    function PromosEspeciales(var AMensajeError:String; PROCESO_ID:Integer):Boolean;
    function PromosArtN(var AMensajeError:String; var AMensajeRep:String; SKU:String):Boolean;
    function ActTarjeta(var ASesion, ANombreCajero, ANoTarjeta, ANombre, AAPaterno, AAMaterno, ATelefono, AEmail, ASexo, ACP, AMensajeError:String; AFNacimiento:String):Boolean;

    function VerificacionMetadatos():Boolean;
    function ConsultarTarjeta(ASesion, ANoTarjeta:String; var Amembresia, Aapellidopaterno, Aapellidomaterno, Anombre, Acodigopostal, Asexo, Atelefono, Aemail, AMensajeError:String; Afechanacimiento:TXSDateTime; var AFecha:TDateTime):Boolean;
    { Public declarations }

  end;

var
  Form1: TForm1;

implementation

uses Unit2, Unit101, Unit104, fmActivarTarjeta, fmConfiguracion, fmPromociones, fmCerrarVentas,
CajasFrm, frmComprasPaciente, fmActivarTarjeta2, fmErrores, Unit3, frmPromosEsp, frmPromoArt,
fmActualizarTarjeta;


{$R *.dfm}

{$REGION 'Metadatos'}
function TForm1.Verifica_Tabla():Boolean;
begin
Result := false;
try
begin
Inicializar_Transacciones('S');
dsMetadatos.Close;
dsMetadatos.SelectSQL.Clear;
dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) FROM MGNADRO_VERSION');
dsMetadatos.Open;
end
except
begin
 try
 begin
    dsMetadatos.Close;
    dsMetadatos.selectSQL.Clear;
    dsMetadatos.selectSQL.Add(' CREATE TABLE MGNADRO_VERSION (   VERSION_ID  INTEGER NOT NULL, ');
    dsMetadatos.selectSQL.Add(' "VERSION"   INTEGER NOT NULL ); ');
    dsMetadatos.open;

    dsMetadatos.Close;
    dsMetadatos.SelectSql.Clear;
    dsMetadatos.SelectSql.Add(' ALTER TABLE MGNADRO_VERSION ADD CONSTRAINT PK_MGNADRO_VERSION PRIMARY KEY (VERSION_ID);  ');
    dsMetadatos.open;

    dsMetadatos.Close;
    dsMetadatos.SelectSql.Clear;
    dsMetadatos.SelectSql.Add('CREATE OR ALTER TRIGGER MGNADRO_VERSION_BI FOR MGNADRO_VERSION ACTIVE BEFORE INSERT POSITION 0 ');
    dsMetadatos.SelectSql.Add('AS BEGIN IF (NEW.VERSION_ID = -1) THEN NEW.VERSION_ID = GEN_ID(ID_CATALOGOS,1); END ');
    dsMetadatos.Open;

    dsMetadatos.Close;
    dsMetadatos.SelectSql.Clear;
    dsMetadatos.SelectSql.Add('GRANT ALL ON MGNADRO_VERSION TO USUARIO_MICROSIP;  ');
    dsMetadatos.Open;

    if trMetadatos.InTransaction then
        trMetadatos.Commit;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al creal tabla V1.1. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  end;//fin del seg try
end;
Inicializar_Transacciones('N');
end;//fin del primer try

  ////////////////////////////////////////////////////////////  VERSION 1.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 0) then
    begin
      Scripter1.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 1)');
      dsMetadatos.Open;
      
      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 1. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 2.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 1) then
    begin
      Scripter2.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 2)');
      dsMetadatos.Open;
      
      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 2. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 3.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 2) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD PRECIO_UNITARIO NUMERIC(18,6)');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD UNIDADES_VENDIDAS NUMERIC(18,5)');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD PIEZASPENDIENTES INTEGER');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 3)');
      dsMetadatos.Open;
      
      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 3. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 4.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 3) then
    begin
      Scripter3.ExecuteScript(1);
      
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 4)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 4. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

  ////////////////////////////////////////////////////////////  VERSION 5.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 4) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('GRANT EXECUTE ON PROCEDURE MGNADRO_ESTIMADOS TO USUARIO_MICROSIP;');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 5)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 5. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

  ////////////////////////////////////////////////////////////  VERSION 6.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 5) then
    begin
      Scripter4.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 6)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 6. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 7.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 6) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 7)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 7. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 8.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 7) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_SESIONES ADD INTENTOS_CIERRE INTEGER;');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 8)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 8. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 9.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 8) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD PRECIO_MSP NUMERIC(18,6);');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_SESIONES ADD LOG_ERRORES BLOB SUB_TYPE 1 SEGMENT SIZE 80;');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD PIEZASPORCOMPRAR NUMERIC(18,5);');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_PROMOCIONES ADD PIEZASPENDIENTESNADRO INTEGER;');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('ALTER TABLE MGNADRO_SESIONES ADD SOLO_PENDIENTES CHAR(1);');
      dsMetadatos.Open;

      Scripter5.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 9)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 9. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 10.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 9) then
    begin
      Scripter6.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 10)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 10. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 ////////////////////////////////////////////////////////////  VERSION 11.0
 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 10) then
    begin
      Scripter7.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 11)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 11. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try


 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 11) then
    begin
      Scripter8.ExecuteScript(1);

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 12)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 12. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

 try
 begin
   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
    if (dsMetadatos.FieldByName('VER').AsInteger = 12) then
    begin
      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('GRANT EXECUTE ON PROCEDURE MGNADRO_ESTIMADOS TO USUARIO_MICROSIP;');
      dsMetadatos.Open;

      dsMetadatos.Close;
      dsMetadatos.SelectSql.Clear;
      dsMetadatos.SelectSql.Add('INSERT INTO MGNADRO_VERSION(VERSION_ID, VERSION)');
      dsMetadatos.SelectSql.Add('VALUES(-1, 13)');
      dsMetadatos.Open;

      if trMetadatos.InTransaction then
        trMetadatos.Commit;
    end;
  end
  except
  begin
    Inicializar_Transacciones('N');
    MessageDlg('Error al actualizar al Paso 13. Verifique que no haya usuarios conectados y vuelva a intentarlo.', mtError, [mbOk], 0);
  end;
  Inicializar_Transacciones('N');
  end;//fin del primer try

Result := true;
end;

procedure TForm1.Inicializar_Transacciones(SN_Rollback:String);
begin
if trMetadatos.Active = false then
   trMetadatos.Active := true;
if SN_Rollback = 'N' then
begin
  if trMetadatos.InTransaction then
     trMetadatos.Rollback;
end;
trMetadatos.StartTransaction;
end;

function TForm1.VerificacionMetadatos():Boolean;
var VERSION_ACTUAL : Integer;
begin
 try
 begin
   Result := True;

   Inicializar_Transacciones('S');
   dsMetadatos.Close;
   dsMetadatos.SelectSQL.Clear;
   dsMetadatos.SelectSQL.Add('SELECT MAX(VERSION) VER FROM MGNADRO_VERSION');
   dsMetadatos.Open;
   VERSION_ACTUAL := dsMetadatos.FieldByName('VER').AsInteger;

   if VERSION_ACTUAL < VERSION_ACTUAL_MM then
   Begin
      if Uppercase(fmConfigConexion.G_NomUsuario) <> 'SYSDBA' then
      Begin
         MessageDlg('Se requiere actualizar la base de datos, ingrese con el usuario SYSDBA antes de continuar. ', mtError,[mbOK],0);
         Result := False;
         Exit;
      End;
   End;
  end
  except
  begin
    if Uppercase(fmConfigConexion.G_NomUsuario) <> 'SYSDBA' then
    Begin
         MessageDlg('Se requiere actualizar la base de datos, ingrese con el usuario SYSDBA antes de continuar. ', mtError,[mbOK],0);
         Result := False;
         Exit;
    End;
  end;
  end;
end;
{$ENDREGION}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Timer1.Enabled:=False;
  Timer2.Enabled:=False;
  IBDatabase1.Connected:=False;
  Application.Terminate;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  {$REGION 'Versión 1 2017'}
  FVersion := 1; //Protección claves desarrollo especial Farmacias Lopez
  fmConfigConexion.lblVersion.Caption := 'Versión Evaluación';
  {$ENDREGION}

  {$REGION 'Versión 2 2017'}
  {FVersion := 2; //Protección candado desarrollo especial 2018  Farmacias Economic
  fmConfigConexion.lblVersion.Caption := '2018';}
  {$ENDREGION}
end;

procedure TForm1.FormShow(Sender: TObject);
var continuar:Boolean;
begin
  try
  begin
    //Conectar();
    VERSION_ACTUAL_MM := 13;

    if IBDatabase1.Connected  then
    begin
      continuar := VerificacionMetadatos();
      if continuar then
      begin
        if Uppercase(fmConfigConexion.G_NomUsuario) = 'SYSDBA' then
        begin
          Verifica_Tabla();
        end;
      end
      else
      begin
        Application.Terminate;
      end;
    end;
  end
  except on e: Exception do
  begin
    //IniciarAutoConexion();
  end
  end;
end;

procedure TForm1.Conectar();
var EMPRESA, LR, SERVIDOR, USER, PASS, DATOS :STRING;
begin
    if IBDatabase1.Connected = False then
    begin
      MensajeEstatus('Intentando conectarse con el servidor...');
      DATOS := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','Datos');
      EMPRESA := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','Empresa');
      LR := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','LR');
      PASS := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','Passwd');
      PASS := DescifrarTexto(PASS, '');
      SERVIDOR := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','Servidor');
      USER := GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO','Usuario');


      IBDatabase1.DBParams.Clear;
      IBDatabase1.DBParams.Add('user_name='+USER);
      IBDatabase1.DBParams.Add('password='+PASS);
      IBDatabase1.DBParams.Add('sql_role_name=USUARIO_MICROSIP');
      IBDatabase1.DBName := SERVIDOR + ':' + DATOS + '\' + EMPRESA;
      IBDatabase1.useLoginPrompt := False;
      TRY
      BEGIN
      IBDatabase1.Connected := True;
      MensajeEstatus('Conectado: ' + IBDatabase1.DBName);
      Abrir;
      Timer1.Enabled := False;
      END;
      EXCEPT
            on e:Exception do
            begin
              if pos('Your user name and password are not defined', E.Message)<>0 then
                MensajeEstatus('El usuario o la contraseña no son válidos.');

              if pos('Unable to complete network request', E.Message)<>0 then
                MensajeEstatus('No se puede hacer contacto con el servidor.');

              if pos('I/O error for file', E.Message)<>0 then
                MensajeEstatus('La carpeta de datos Microsip no es válida.');
              Exit;
            end
            ELSE MensajeEstatus('Error general al conectarse al servidor: ' + SERVIDOR);
      END;
  END else MensajeEstatus('Conectado: ' + IBDatabase1.DBName);
end;

procedure TForm1.MensajeEstatus(Mensaje:String);
begin
  StatusBar1.Panels[0].Text := Mensaje;
  Application.ProcessMessages;
end;

procedure TForm1.Abrir();
begin
  try
  begin
    if VerificarConexion() then
    begin
      if trTrans.Active = False then
        trTrans.Active := True;
    end;
  end;
  finally

  end;
end;

function TForm1.VerificarConexion():Boolean;
begin
  Result :=  IBDatabase1.Connected;
  if not IBDatabase1.Connected then
  begin
    IniciarAutoConexion();
  end;
end;

procedure TForm1.IniciarAutoConexion();
begin
  if not(IBDatabase1.Connected) then
  begin
    Timer1.Enabled := True;
    MensajeEstatus('Se perdió la comunicación con el servidor. Intentando conectarse en 5 segundos...');
  end;
  if (IBDatabase1.Connected) then
  begin
    MensajeEstatus('Conectado: ' + IBDatabase1.DBName);
  end;
end;

function TForm1.DescifrarTexto(Str, Clave : String): String;
var
  Src: TMemoryStream;
  Dst: TStringStream;
  Size: Integer;
  Key: TAESKey;
  ExpandedKey: TAESExpandedKey;
begin
  CLAVE := 'MICROSIP4856';
  Result:= EmptyStr;
  Src:= TMemoryStream.Create;
  try
    Dst:= TStringStream.Create(Str);
    try
      StrToStream(Str,Src);
      Src.Position:= 0;
      FillChar(Key,Sizeof(Key),#0);
      if Length(Clave) > Sizeof(Key) then
        move(PChar(Clave)^,Key,Sizeof(key))
      else
        move(PChar(Clave)^,Key,Length(Clave));
      AESExpandKey(ExpandedKey,Key);
      // Leemos el tamaño del texto
      Src.ReadBuffer(Size,Sizeof(Size));
      AESDecryptStreamECB(Src,Dst,ExpandedKey);
      Dst.Size:= Size;
      Result:= Dst.DataString;
    finally
      Dst.Free;
    end;
  finally
    Src.Free;
  end;
end;

procedure TForm1.SetRegistryData(RootKey: HKEY; Key, Value: string; RegDataType: TRegDataType; Data: variant);
var
  Reg: TRegistry;
  s: string;
begin
  Reg := TRegistry.Create(KEY_WRITE);
  try
    Reg.RootKey := RootKey;
    if Reg.OpenKey(Key, True) then begin
      try
        if RegDataType = rdUnknown then
          RegDataType := Reg.GetDataType(Value);
        if RegDataType = rdString then
          Reg.WriteString(Value, Data)
        else if RegDataType = rdExpandString then
          Reg.WriteExpandString(Value, Data)
        else if RegDataType = rdInteger then
          Reg.WriteInteger(Value, Data)
        else if RegDataType = rdBinary then begin
          s := Data;
          Reg.WriteBinaryData(Value, PChar(s)^, Length(s));
        end else
          raise Exception.Create(SysErrorMessage(ERROR_CANTWRITE));
      except
        Reg.CloseKey;
        raise;
      end;
      Reg.CloseKey;
    end else
      raise Exception.Create(SysErrorMessage(GetLastError));
  finally
    Reg.Free;
  end;
end;

function TForm1.GetRegistryData(RootKey: HKEY; Key, Value: string): variant;
var
  Reg: TRegistry;
  RegDataType: TRegDataType;
  DataSize, Len: integer;
  s: string;
label cantread;
begin
  Reg := nil;
  try
    Reg := TRegistry.Create(KEY_QUERY_VALUE);
    Reg.RootKey := RootKey;
    if Reg.OpenKeyReadOnly(Key) then begin
      try
        RegDataType := Reg.GetDataType(Value);
        if (RegDataType = rdString) or
           (RegDataType = rdExpandString) then
          Result := Reg.ReadString(Value)
        else if RegDataType = rdInteger then
          Result := Reg.ReadInteger(Value)
        else if RegDataType = rdBinary then begin
          DataSize := Reg.GetDataSize(Value);
          if DataSize = -1 then goto cantread;
          SetLength(s, DataSize);
          Len := Reg.ReadBinaryData(Value, PChar(s)^, DataSize);
          if Len <> DataSize then goto cantread;
          Result := s;
        end else
cantread:
          raise Exception.Create(SysErrorMessage(ERROR_CANTREAD));
      except
        s := ''; // Deallocates memory if allocated
        Reg.CloseKey;
        raise;
      end;
      Reg.CloseKey;
    end else
      raise Exception.Create(SysErrorMessage(GetLastError));
  except
    Reg.Free;
    raise;
  end;
  Reg.Free;
end;

procedure TForm1.Informacin1Click(Sender: TObject);
begin
  Form2.ShowModal;
end;

procedure TForm1.Salir1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  try
  begin
    //Conectar();
  end;
  except on e: Exception do
  begin
    //IniciarAutoConexion();
  end;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var lIniciar:Boolean;
begin
if IBDatabase1.Connected then
begin
  Timer2.Enabled := False;

  lIniciar:=True;

  if (FConectado = 'N') and (FDetenido = 'N') then
    Conexion();

  Memo1.Lines.Clear;
  Memo1.Lines.Add('Inicio de proceso.');
  try
  begin
    if trTrans.InTransaction then
      trTrans.Rollback;

    trTrans.StartTransaction;

    {$REGION 'datos de configuración'}
    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''PZSGRATIS'' ');
    IBQuery1.Open;
    FPGratis:=IBQuery1.FieldByName('VALOR').AsString;

    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''MONTODSCTO'' ');
    IBQuery1.Open;
    FMDescto:=IBQuery1.FieldByName('VALOR').AsString;

    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''PORCENTAJEDSCTO'' ');
    IBQuery1.Open;
    FDescto:=IBQuery1.FieldByName('VALOR').AsString;

    {IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''PRECIO'' ');
    IBQuery1.Open;
    FPrecio:=IBQuery1.FieldByName('VALOR').AsString;Pendiente}

    //PMP(precio máximo público)
    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''LISTAPMP'' ');
    IBQuery1.Open;
    try
    begin
      FPMP:=StrToInt(IBQuery1.FieldByName('VALOR').AsString);
    end;
    except
      FPMP:=0;
    end;

    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''LISTAPVM'' ');
    IBQuery1.Open;
    try
    begin
      FPVM:=StrToInt(IBQuery1.FieldByName('VALOR').AsString);
    end;
    except
      FPVM:=0;
    end;

    if FVersion=1 then
    begin
      IBQuery1.Close;
      IBQuery1.SelectSQL.Clear;
      IBQuery1.SelectSQL.Add('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE=''CLIENTE_ID'' ');
      IBQuery1.Open;
      try
      begin
        FClienteId:=StrToInt(IBQuery1.FieldByName('VALOR').AsString);
      end;
      except
        FClienteId:=0;
      end;

      if (FClienteId=0) then
      begin
        MessageDlg('El cliente círculo de la salud es incorrecto.'+#13+'Registre dato y de clic en iniciar.', mtInformation,  [mbOk], 0);
        Memo1.Lines.Add('Detener proceso.');
        Timer2.Enabled:=False;
        lIniciar:=False;
        fmConfig.FVersion:=FVersion;
        fmConfig.ShowModal;
      end;
    end;

    if (FPGratis='') and (FMDescto='') and (FDescto='') and (FPMP=0) and (FPVM=0) then //and (FPrecio='')
    begin
      MessageDlg('Los datos de configuración no han sido registrados.'+#13+'Registre datos y de clic en iniciar.', mtInformation,  [mbOk], 0);
      Memo1.Lines.Add('Detener proceso.');
      Timer2.Enabled:=False;
      lIniciar:=False;
      fmConfig.FVersion:=FVersion;
      fmConfig.ShowModal;
    end;

    BuscarDatos();

    if FCajaId=0 then
    begin
      MessageDlg('No se ha asignado la caja a operar.'+#13+'Registre la caja en Herramientas-->Asignar Caja.', mtInformation,  [mbOk], 0);
      Memo1.Lines.Add('Detener proceso.');
      Timer2.Enabled:=False;
      lIniciar:=False;
    end;
    {Se quito por que ya se registra en la pantalla de asignación de cajas
    else
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','CajaId',rdInteger,FCajaId);

    if (FIdCadena<>'') or (FIdSucursal<>'')  or (FUsuario<>'') or (FPassword<>'')then
    begin
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','CajaId',rdInteger,FCajaId);
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','IdCadena',rdString,FIdCadena);
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','IdSucursal',rdString,FIdSucursal);
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','Usuario',rdString,FUsuario);
      SetRegistryData(HKEY_LOCAL_MACHINE,'\Software\NGPlugOut\INTERFASECSO','Password',rdString, FPassword);
    end;
    }
    {$ENDREGION}

    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT COUNT(*) TREG FROM MGNADRO_PV A');
    IBQuery1.SelectSQL.Add('INNER JOIN DOCTOS_PV B ON (B.DOCTO_PV_ID=A.DOCTO_PV_ID)');
    IBQuery1.SelectSQL.Add('WHERE B.CAJA_ID=:CAJA_ID');
    IBQuery1.ParamByName('CAJA_ID').AsInteger:=FCajaId;
    IBQuery1.Open;
    if IBQuery1.FieldByName('TREG').AsInteger>0 then
    begin
      {$REGION 'ov'}
      if lIniciar then
      begin
        //22/11/2016 LIZ SE QUITO EL MAXIMIZAR Y MINIMIZAR POR LAS CONSULTAS DE PROMOCIONES
        //22/11/2016 LIZ Application.Restore;
        ProcesoPrincipal();
        //22/11/2016 LIZ Application.Minimize;
      end;
      {$ENDREGION}
    end;

    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT COUNT(*) TREG FROM MGNADRO_PV_VM A');
    IBQuery1.SelectSQL.Add('INNER JOIN DOCTOS_PV B ON (B.DOCTO_PV_ID=A.DOCTO_PV_ID)');
    IBQuery1.SelectSQL.Add('WHERE B.CAJA_ID=:CAJA_ID');
    IBQuery1.ParamByName('CAJA_ID').AsInteger:=FCajaId;
    IBQuery1.Open;
    if IBQuery1.FieldByName('TREG').AsInteger>0 then
    begin
      {$REGION 'vm'}
      //22/11/2016 LIZ Application.Restore;
      ProcesoFinal();
      //22/11/2016 LIZ Application.Minimize;
      {$ENDREGION}
    end;

    {$REGION 'Cierre automatico'}
     IntentosCierre();
    {$ENDREGION}

    Timer2.Enabled := True;
    //22/11/2016 LIZ Application.Minimize;
  end
  except on e:exception do
  begin
  end;
  end;
end;
end;

procedure TForm1.ProcesoPrincipal();
var lClienteId, lDirCliId:Integer;
lNombreCliente, lNoTarjeta, lSesion, lVersionWS, lMensajeError, lFolioTarjeta:String;
lListaProductos: ArrayOfBonusProductList;
RenglonListaProductos:BonusProductList;
lRespuestaPromociones:ArrayOfResponseBonusList;
lRespuestaPromocionArt:GetPromocionCurrentResponse;
I, lTotalArt, lSesionId, lArtId, lAlmacenId, lDoctoId:Integer;
lHuboError:Boolean;
lMontoDescuento, lPrecioFijo :TXSDecimal;
lPorcentajeDescuento, lTipoPrecioDescuento:Double;
lMontoDescto, lPrecioFjo, lClaveArt:String;
lConImpto:String;
lTipoPrecioDescto, lPzsGrastis, lPzsPendientes, lPzsEntregar, lTPzsEntregar, lPiezasVendidas, lPzsPorComprar:Integer;
lPrecioMaxArt, lPrecioArt, lPorcentajeDescto,  lPrecioFijoArt, lMontoDesctoArt, lPrecioMostrador, lPU, lDes, lPrecioMostrador1:Double;
lPromoAnt, lTotalPzsEntregar, lPzsNoEntregadas:Integer;
lArtiPend:String;
lTotalTArt:Integer;
lContinuar, lValidar, InsertarDet:Boolean;
ErrorAg, lFolioOV, ArtNoReg, lNomPromo, AMASB:String;
lPos, lTam, J, lArtAID, lArtAIDAnt:Integer;
begin
  try
  begin
    {$REGION 'Inicio'}
    if trWrite.InTransaction then
      trWrite.Rollback;

    trWrite.StartTransaction;

    lMensajeError:='';
    lFolioTarjeta:='';
    lContinuar:=True;

    dsDoctosOV.Close;
    dsDoctosOV.ParamByName('CAJA_ID').AsInteger:=FCajaId;
    dsDoctosOV.Open;
    dsDoctosOV.First;
    while not dsDoctosOV.Eof do
    begin
      mmError.Clear;
      Conexion();
      if FConectado='S' then
      begin
        if dsDoctosOV.FieldByName('ESTATUS').AsString<>'C' then
        begin
        {$REGION 'Proceso Principal'}
        lAlmacenId:=0;
        lClienteId:=0;
        lDirCliId:=0;
        lNombreCliente:='';
        lDoctoId:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
        lFolioOV:=dsDoctosOV.FieldByName('FOLIO').AsString;
        lValidar:=True;

        if ObtenerDatos(lClienteId,lDirCliId,lAlmacenId,lDoctoId,lNombreCliente)=False then
        begin
          Memo1.Lines.Add('Error al obtener datos de orden de venta.');
          mmError.Lines.Add('Error al obtener datos de orden de venta.');
        end;

        if FVersion=1 then
        begin
          {LIZ 14/07/2017
          if lDirCliId=0 then
          begin
            Memo1.Lines.Add('El No. de tarjeta es incorrecto.');
            mmError.Lines.Add('El No. de tarjeta es incorrecto.');
          end;
          }

          if (lClienteId<>FClienteId) or (lDirCliId<=0) then
          begin
            lValidar:=False;
          end;
        end
        else lDirCliId:=lClienteId;

        if lValidar then
        begin
          {$REGION 'Continuo'}
            //obtener no de tarjeta
            if FVersion=1 then
            begin
              lNoTarjeta:=ObtenerNoTarjeta(lDirCliId);
            end
            else
            begin
              lNoTarjeta:=ObtenerNoTarjeta(lClienteId);
            end;

            lSesionId:=0;
            lSesion:='';
            if lSesionId=0 then
            begin
                {$REGION 'Web Service Conectado'}
                if IniciarSesion(lSesion) then
                begin
                  lVersionWS:=Form1.ObtenerVersionWS();
                end
                else
                begin
                  Memo1.Lines.Add('La sesión con el servicio web NO esta disponible.'+#13+'Error: '+lSesion);
                  mmError.Lines.Add('La sesión con el servicio web NO esta disponible.'+#13+'Error: '+lSesion);
                end;
                {$ENDREGION}
            end;

            if (lNoTarjeta<>'') and (lSesion<>'') then
            begin
              if ValidarTarjeta(lSesion, lNoTarjeta, lMensajeError, lFolioTarjeta)=False then
              begin
                Memo1.Lines.Add('Error al validar tarjeta No: '+lNoTarjeta+#13+lMensajeError);
                mmError.Lines.Add('Error al validar tarjeta No: '+lNoTarjeta+#13+lMensajeError);
              end;
            end;

            if lFolioTarjeta<>'' then
            begin
              {$REGION 'tarjeta valida'}

              {$REGION 'Eliminar partidas con costo 0'}
              if trElimina.InTransaction then
                trElimina.Rollback;

              trElimina.StartTransaction;

              dsEliminaDet.Close();
              dsEliminaDet.ParamByName('DOCTO_PV_ID').AsInteger := dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
              dsEliminaDet.Open();

              if trElimina.InTransaction then
                trElimina.Commit;
              {$ENDREGION}

              {$REGION 'Agrupar'}
                lTotalTArt:=0;
                IBQuery1.Close;
                IBQuery1.SelectSQL.Clear;
                IBQuery1.SelectSQL.Add('SELECT COUNT(*) TTARTICULOS FROM');
                IBQuery1.SelectSQL.Add('(SELECT DISTINCT A.ARTICULO_ID');
                IBQuery1.SelectSQL.Add('FROM DOCTOS_PV_DET A');
                IBQuery1.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID)');
                IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                IBQuery1.Open;
                lTotalTArt:= IBQuery1.FieldByName('TTARTICULOS').AsInteger;

                lTotalArt:=0;
                IBQuery1.Close;
                IBQuery1.SelectSQL.Clear;
                IBQuery1.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM DOCTOS_PV_DET A WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
                IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                IBQuery1.Open;
                lTotalArt:=IBQuery1.FieldByName('TARTICULOS').AsInteger;

                if lTotalTArt <> lTotalArt then
                begin
                  ErrorAg:='';
                  if AgruparArticulos(dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger,ErrorAg)=False then
                  begin
                    lContinuar:=False;
                    Memo1.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
                    mmError.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
                  end;
                end;
              {$ENDREGION}

              try
              begin
                if lContinuar=True then
                begin
                  {$REGION 'Continuar'}
                  lTotalArt:=0;
                  IBQuery1.Close;
                  IBQuery1.SelectSQL.Clear;
                  IBQuery1.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM DOCTOS_PV_DET A WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
                  IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                  IBQuery1.Open;
                  lTotalArt:=IBQuery1.FieldByName('TARTICULOS').AsInteger;

                  if lTotalArt>0 then
                  begin
                  {$REGION 'Continuar'}
                  //declarar longitud de Array 1 a N
                  SetLength(lListaProductos,lTotalArt);

                  //inicializar el array 1..N
                  I := 0;

                  RenglonListaProductos:=BonusProductList.Create;

                  dsObtenerArticulos.Close;
                  dsObtenerArticulos.ParamByName('DOCTO_PV_ID').AsInteger:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                  dsObtenerArticulos.Open;

                  while not dsObtenerArticulos.Eof do
                  begin
                    lListaProductos[I]:=BonusProductList.Create;
                    lListaProductos[I].Sku:=dsObtenerArticulos.FieldByName('CLAVE_ARTICULO').AsString;
                    lListaProductos[I].Piezas:=dsObtenerArticulos.FieldByName('UNIDADES').AsInteger;

                    I:=I+1;
                    dsObtenerArticulos.Next;
                  end;

                  lMensajeError:='';

                  //Invocar WS
                  lRespuestaPromociones:=GetWSCirculodelaSaludSoap.GetBonusProductList(lSesion,lNoTarjeta,lListaProductos);

                  //verificar si esta seleccionada la opción de incluir el impuesto en los precios al registrar las ventas de punto de venta
                  IBQuery1.Close;
                  IBQuery1.SelectSQL.Clear;
                  IBQuery1.SelectSQL.Add('SELECT A.VALOR FROM REGISTRY A WHERE A.NOMBRE=''IMPUESTO_INCLUIDO''');
                  IBQuery1.Open;
                  lConImpto :=  IBQuery1.FieldByName('VALOR').AsString;

                  {$REGION 'registrar sesión'}
                  try
                  begin
                    dsWrite.Close;
                    dsWrite.SelectSQL.Clear;
                    dsWrite.SelectSQL.Add('INSERT INTO MGNADRO_SESIONES (ID_SESION, CLIENTE_ID, SESION, ESTATUS, VERSION_WEB_SERVICE, FECHA, INTENTOS_CIERRE)');
                    dsWrite.SelectSQL.Add('VALUES (:ID_SESION, :CLIENTE_ID, :SESION, :ESTATUS, :VERSION_WEB_SERVICE, :FECHA, 0)');
                    spDoctoId.ExecProc;
                    lSesionId:=spDoctoId.FieldByName('DOCTO_ID').AsInteger;
                    dsWrite.ParamByName('ID_SESION').AsInteger:=lSesionId;
                    dsWrite.ParamByName('CLIENTE_ID').AsInteger:=lDirCliId;
                    dsWrite.ParamByName('SESION').AsString:=lSesion;
                    dsWrite.ParamByName('ESTATUS').AsString:='N';
                    dsWrite.ParamByName('VERSION_WEB_SERVICE').AsString:=lVersionWS;
                    dsWrite.ParamByName('FECHA').AsDate:=Now;
                    dsWrite.Open;
                end;
                except on e:exception do
                begin
                  if trWrite.InTransaction then
                    trWrite.Rollback;

                  Memo1.Lines.Add('Error al registrar sesión. ' + Chr(13) + e.Message);
                  mmError.Lines.Add('Error al registrar sesión. ' + Chr(13) + e.Message);
                end;
                end;
                {$ENDREGION}

                  I := 0;
                  lArtAIDAnt := 0;
                  AMASB := '';
                  for I := 0 to Length(lRespuestaPromociones) - 1 do
                  begin
                    InsertarDet:=True;
                    lHuboError:=lRespuestaPromociones[I].HuboError;
                    if lHuboError then
                    begin
                      lMensajeError:=lRespuestaPromociones[I].MensajeError;
                      lPos:=0;
                      lPos:=Pos('Producto sin promoción en el programa', lMensajeError);
                      if lPos=1 then
                      begin
                        InsertarDet:=True;
                      end;
                    end;

                    if InsertarDet then
                    begin
                      {$REGION 'aplicar promociones'}
                      lPzsEntregar:=0;
                      lPrecioArt:=0;
                      lMontoDesctoArt:=0;
                      lPorcentajeDescto:=0;

                      lClaveArt:=lRespuestaPromociones[I].Sku;
                      IBQuery1.Close;
                      IBQuery1.SelectSQL.Clear;
                      IBQuery1.SelectSQL.Add('SELECT A.ARTICULO_ID FROM CLAVES_ARTICULOS A WHERE A.CLAVE_ARTICULO=:CLAVE_ARTICULO');
                      IBQuery1.ParamByName('CLAVE_ARTICULO').AsString:=lClaveArt;
                      IBQuery1.Open;
                      lArtId:=IBQuery1.FieldByName('ARTICULO_ID').AsInteger;

                      if lArtId > 0 then
                      begin
                        {$REGION 'Art Promo'}
                        //Consultar el tipo de promoción.
                        lNomPromo := '';
                        lRespuestaPromocionArt := GetWSCirculodelaSaludSoap.GetInfoPromocionProduct(lSesion,lClaveArt);
                        try
                          begin
                            lNomPromo := lRespuestaPromocionArt.Promocion.NombrePromocion;
                          end;
                        except
                          lNomPromo:='';
                        end; 

                        if AMASB='' then
                          AMASB := 'N';

                        lArtAID := lArtAIDAnt;

                        lPzsGrastis:=lRespuestaPromociones[I].PiezasGratis;
                        lPzsPendientes:=lRespuestaPromociones[I].PiezasPendientes;
                        lPzsPorComprar:=lRespuestaPromociones[I].PiezasPorComprar;

                        lPrecioFijo:=TXSDecimal.Create;
                        lPrecioFijo:=lRespuestaPromociones[I].PrecioFijo;
                        lPrecioFjo:=lPrecioFijo.NativeToXS;
                        lPrecioFijoArt:=StrToFloat(StringReplace(lPrecioFjo,',','',[rfReplaceAll, rfIgnoreCase]));

                        lTipoPrecioDescto:=lRespuestaPromociones[I].TipoPrecioDescuento;

                        lMontoDescuento:=TXSDecimal.Create;
                        lMontoDescuento:=lRespuestaPromociones[I].MontoDescuento;
                        lMontoDescto:=lMontoDescuento.NativeToXS;
                        lMontoDesctoArt:=StrToFloat(StringReplace(lMontoDescto,',','',[rfReplaceAll, rfIgnoreCase]));

                        lPorcentajeDescto:=lRespuestaPromociones[I].PorcentajeDescuento;

                          if lPrecioFijoArt>0 then
                          begin
                            lPrecioArt:=0;
                          end
                          else
                          begin
                            {$REGION 'precio no fijo'}
                            if lTipoPrecioDescto=1 then //se toma el PMP(precio máximo público)
                            begin
                              {$REGION 'MyRegion'}
                              if lPrecioMaxArt>0 then
                              begin
                                lPrecioArt:=0;
                              end;
                              if lMontoDesctoArt>0 then
                              begin
                                if FMDescto='S' then
                                  lMontoDesctoArt:=lMontoDesctoArt
                                else
                                  lMontoDesctoArt:=0;
                              end
                              else
                              begin
                                if lPorcentajeDescto>0 then
                                begin
                                  if FDescto='S' then
                                    lPorcentajeDescto:=lPorcentajeDescto
                                  else
                                    lPorcentajeDescto:=0;
                                end;
                              end;
                              {$ENDREGION}
                            end
                            else  if lTipoPrecioDescto=2 then //se tama el PM(precio mostrador)
                            begin
                              {$REGION 'MyRegion'}
                              lPrecioArt:=0;
                              if lMontoDesctoArt>0 then
                              begin
                                if FMDescto='S' then
                                  lMontoDesctoArt:=lMontoDesctoArt
                                else
                                  lMontoDesctoArt:=0;
                              end
                              else
                              begin
                                if lPorcentajeDescto>0 then
                                begin
                                  if FDescto='S' then
                                    lPorcentajeDescto:=lPorcentajeDescto
                                  else
                                    lPorcentajeDescto:=0;
                                end;
                              end;
                              {$ENDREGION}
                            end;
                            {$ENDREGION}
                          end;

                          if FPVM>0 then
                          begin
                            IBQuery1.Close;
                            IBQuery1.SelectSQL.Clear;
                            IBQuery1.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                            IBQuery1.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                            IBQuery1.ParamByName('ARTICULO_ID').AsInteger:=lArtId;
                            IBQuery1.ParamByName('PRECIO_EMPRESA_ID').AsInteger:=FPVM;
                            IBQuery1.Open;
                            if lConImpto='N' then
                              lPrecioMostrador:=IBQuery1.FieldByName('PRECIO').AsFloat
                            else
                            begin
                              spPrecioImpto.Close;
                              spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=lArtId;
                              spPrecioImpto.ParamByName('PRECIO').AsFloat:=IBQuery1.FieldByName('PRECIO').AsFloat;
                              spPrecioImpto.ExecProc;
                              lPrecioMostrador:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                            end;
                          end
                          else
                          begin
                            lPrecioMostrador:=0;
                          end;

                          //30/11/2016 LIZ MANDAR EL PRECIO DE ORDEN DE VENTA APLICANDO EL DESCUENTO
                          IBQuery2.Close;
                          IBQuery2.SelectSQL.Clear;
                          IBQuery2.SelectSQL.Add('SELECT A.UNIDADES, PRECIO_UNITARIO, PCTJE_DSCTO FROM DOCTOS_PV_DET A WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID AND A.ARTICULO_ID=:ARTICULO_ID ');  //LIZ 05/07/2016 AND A.POSICION=:POSICION
                          IBQuery2.ParamByName('DOCTO_PV_ID').AsInteger:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                          IBQuery2.ParamByName('ARTICULO_ID').AsInteger:=lArtId;
                          IBQuery2.Open;
                          lPiezasVendidas:=IBQuery2.FieldByName('UNIDADES').AsInteger;
                          lPU:=IBQuery2.FieldByName('PRECIO_UNITARIO').AsFloat;
                          lDes:=IBQuery2.FieldByName('PCTJE_DSCTO').AsFloat;
                          lPrecioMostrador1 := (lPU-(lPU*(lDes/100)));

                          if lConImpto='S' then
                          begin
                            spPrecioImpto.Close;
                            spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=lArtId;
                            spPrecioImpto.ParamByName('PRECIO').AsFloat:=lPrecioMostrador1;
                            spPrecioImpto.ExecProc;
                            lPrecioMostrador1:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                          end;

                          {$REGION 'registro de beneficios'}
                          try
                          begin
                            dsWrite.Close;
                            dsWrite.SelectSQL.Clear;
                            dsWrite.SelectSQL.Add('INSERT INTO MGNADRO_PROMOCIONES (ID_PROMO, ARTICULO_ID, ID_SESION, PIEZASGRATIS, PRECIOFIJO, MONTODESCUENTO, ');
                            dsWrite.SelectSQL.Add('PORCENTAJEDESCUENTO,  POSICION,ESTATUS, PRECIO_UNITARIO, UNIDADES_VENDIDAS, PIEZASPENDIENTES, PRECIO_MSP, ');
                            dsWrite.SelectSQL.Add('PIEZASPORCOMPRAR, PIEZASPENDIENTESNADRO, PROMOCION, AMASB, ARTICULO_A_ID, AGREGADO_OV)');
                            dsWrite.SelectSQL.Add('VALUES (:ID_PROMO, :ARTICULO_ID, :ID_SESION, :PIEZASGRATIS, :PRECIOFIJO, :MONTODESCUENTO, ');
                            dsWrite.SelectSQL.Add(':PORCENTAJEDESCUENTO,  :POSICION, :ESTATUS, :PRECIO_UNITARIO, :UNIDADES_VENDIDAS, :PIEZASPENDIENTES, :PRECIO_MSP, ');
                            dsWrite.SelectSQL.Add(':PIEZASPORCOMPRAR, :PIEZASPENDIENTESNADRO, :PROMOCION, :AMASB, :ARTICULO_A_ID, ''N'');');
                            spDoctoId.ExecProc;
                            dsWrite.ParamByName('ID_PROMO').AsInteger:=spDoctoId.FieldByName('DOCTO_ID').AsInteger;
                            dsWrite.ParamByName('ARTICULO_ID').AsInteger:=lArtId;
                            dsWrite.ParamByName('ID_SESION').AsInteger:=lSesionId;
                            dsWrite.ParamByName('PIEZASGRATIS').AsInteger:=lPzsGrastis;//lTPzsEntregar;
                            dsWrite.ParamByName('PRECIOFIJO').AsFloat:=lPrecioArt;
                            dsWrite.ParamByName('MONTODESCUENTO').AsFloat:=lMontoDesctoArt;
                            dsWrite.ParamByName('PORCENTAJEDESCUENTO').AsFloat:=lPorcentajeDescto;
                            dsWrite.ParamByName('POSICION').AsInteger:=dsObtenerArticulos.FieldByName('POSICION').AsInteger;
                            dsWrite.ParamByName('PRECIO_UNITARIO').AsFloat:=lPrecioMostrador;
                            dsWrite.ParamByName('UNIDADES_VENDIDAS').AsInteger:=lPiezasVendidas;
                            dsWrite.ParamByName('ESTATUS').AsString:='N';
                            dsWrite.ParamByName('PIEZASPENDIENTES').AsInteger:=0;//Se sabe hasta aplicar promociones
                            dsWrite.ParamByName('PRECIO_MSP').AsFloat:=lPrecioMostrador1;
                            dsWrite.ParamByName('PIEZASPORCOMPRAR').AsInteger:=lPzsPorComprar;
                            dsWrite.ParamByName('PIEZASPENDIENTESNADRO').AsInteger:=lPzsPendientes;
                            dsWrite.ParamByName('PROMOCION').AsString:=lNomPromo;
                            dsWrite.ParamByName('AMASB').AsString:=AMASB;
                            if lArtAID>0 then
                              dsWrite.ParamByName('ARTICULO_A_ID').AsInteger := lArtAID
                            else
                              dsWrite.ParamByName('ARTICULO_A_ID').Clear;
                            dsWrite.Open;
                          end;
                          except on e:exception do
                          begin
                            if trWrite.InTransaction then
                              trWrite.Rollback;
                            Memo1.Lines.Add('Error al registrar beneficios.' + Chr(13) + e.Message);
                            mmError.Lines.Add('Error al registrar beneficios. ' + Chr(13) + e.Message);
                          end;
                          end;
                        {$ENDREGION}

                          if Pos('2A + 1B', lNomPromo)>=1 then
                          begin
                            AMASB := 'S';
                            lArtAIDAnt := lArtId;
                          end
                          else
                          begin
                            AMASB := 'N';
                            lArtAIDAnt := 0;
                          end;

                        {$ENDREGION}
                      end
                      else
                      begin
                        ArtNoReg := ArtNoReg+lClaveArt+', ';
                      end;
                      {$ENDREGION}
                    end;
                  end;

                  if ArtNoReg<>'' then
                  begin
                    lTam := Length(ArtNoReg);

                    ArtNoReg := Copy(ArtNoReg, 1, (lTam-1));

                    mmError.Lines.Add('Artículos gratis NO registrados en Microsip: '+#13+lClaveArt+#13+'No fue posible registrar productos gratis.');
                  end;

                  if trWrite.InTransaction then
                    trWrite.Commit;

                  IBQuery1.Close;
                  IBQuery1.SelectSQL.Clear;
                  IBQuery1.SelectSQL.Add('SELECT COUNT(*)NREG FROM MGNADRO_PROMOCIONES A WHERE A.ID_SESION=:ID_SESION AND A.ESTATUS=''N'' ');
                  IBQuery1.ParamByName('ID_SESION').AsInteger:=lSesionId;
                  IBQuery1.Open;

                  if ((IBQuery1.FieldByName('NREG').AsInteger > 0) and (mmError.Text='')) then
                  begin
                    //22/11/2016 LIZ Application.Restore;
                    //22/11/2016 LIZ Application.Restore;

                    fmPromos.FOrdenVentaId:=dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
                    fmPromos.FSesionId:=lSesionId;
                    fmPromos.FVersion:=FVersion;
                    fmPromos.ShowModal;
                  end
                  else
                  begin
                    mmError.Lines.Add('Venta con productos sin promoción en el programa Círculo de la Salud.');
                  end;

                  {$ENDREGION}
                  end
                  else
                  begin
                    mmError.Lines.Add('Venta sin productos.');
                  end;
                  {$ENDREGION}
                end;
              end;
              finally
              begin
                lPrecioFijo.Free;
                lMontoDescuento.Free;
                for I := 0 to lTotalArt - 1 do
                begin
                  lListaProductos[I].Free;
                end;
                RenglonListaProductos.Free;
              end;
              end;
              {$ENDREGION}
            end;
          {$ENDREGION} 
        end;
        {$ENDREGION}
        end;
      end;

      {$REGION 'Eliminar'}
      if trElimina.InTransaction then
        trElimina.Rollback;

      trElimina.StartTransaction;

      dsElimina.Close();
      dsElimina.ParamByName('DOCTO_PV_ID').AsInteger := dsDoctosOV.FieldByName('DOCTO_PV_ID').AsInteger;
      dsElimina.Open();

      if trElimina.InTransaction then
        trElimina.Commit;
      {$ENDREGION}

      if mmError.Text<>'' then
      begin
        MessageDlg('Error al buscar promociones al web service de Círculo de la Salud ORO, orden de venta: '+lFolioOV+#13+mmError.Text, mtError, [mbOk], 0);
      end;

      dsDoctosOV.Next;
    end;
    {$ENDREGION}
  end;
  except on e:exception do
  begin
    if trTrans.InTransaction then
      trTrans.Rollback;

    if pos('Error de servidor', e.Message)<>0 then
    begin
      FConectado := 'N';
      MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
    end
    else
    begin
      Memo1.Lines.Add('Error al buscar promociones al web service de Círculo de la Salud ORO, orden de venta: '+lFolioOV + Chr(13) + e.Message);
      if mmError.Text<>'' then
      begin
        MessageDlg('Error al buscar promociones al web service de Círculo de la Salud ORO, orden de venta: '+lFolioOV+#13+mmError.Text+#13+e.Message, mtError, [mbOk], 0);
      end;
    end;
  end;
  end;
end;

procedure TForm1.Reporte1Click(Sender: TObject);
var WPath,WPathArchivo,NomReporte,Proceso:String;
begin
  try
  begin
    NomReporte:='Bonificaciones';
    Proceso:='V';
    with fmReportes do
    begin
      WPath := ExtractFileDir(Application.ExeName);
      WPathArchivo:=WPath + '\Reportes\' + NomReporte + '.fr3';
      if not FILEEXISTS(WPathArchivo) then
      begin
        MessageDlg('No existe la forma de impresión: ' + NomReporte + ' verifique la Ruta de reportes en preferencias del módulo.', mtInformation,[mbOk], 0);
        Exit;
      end;
      frxReport1.LoadFromFile(WPathArchivo);
      if Proceso = 'V' then//Vista Preliminar
        frxReport1.ShowReport();
    end;
  end
  except
  end;
end;

procedure TForm1.ProcesoFinal();
var lAlmacenId, lClienteId, lDoctoId, lSesionId, lDirCliId:Integer;
lNombreCliente, lNoTarjeta, lSesion, lMensajeError, lFolioTarjeta, lResPedido:String;
lPedido:Pedido;
lListaArticulos:ArrayOfPedidoArticulos;
lRenglonListaArticulos:PedidoArticulos;
lRespuestaSales:ResponseSales;
lTotalArt, I, lPzsGratis, lCajeroId:Integer;
lPrecioMaximo,lPrecioMostrador,lTotalVM:Double;
lHuboError:Boolean;
lMTotal, lPMP, lPM, lPFijo, lPDescto, lMDesc, lIva:TXSDecimal;
lCajeroVM, lFolioVM, lEstatus, lConImpto, lAviso, ErrorAg:String;
lContinuar:Boolean;
lLineaId, UnidadesPagadas, lTotalTArt1, lTotalArt1, lpos, lPosicion:Integer;
lFolioPedidoF, lFolioPedido, lEstatusVM, lSoloPen:String;
begin
try
begin
  Application.ProcessMessages;

  Memo1.Lines.Clear;
  Memo1.Lines.Add('Fin de proceso.');

  //verificar si esta seleccionada la opción de incluir el impuesto en los precios al registrar las ventas de punto de venta
  IBQuery1.Close;
  IBQuery1.SelectSQL.Clear;
  IBQuery1.SelectSQL.Add('SELECT A.VALOR FROM REGISTRY A WHERE A.NOMBRE=''IMPUESTO_INCLUIDO''');
  IBQuery1.Open;
  lConImpto :=  IBQuery1.FieldByName('VALOR').AsString;

  dsDoctosVM.Close;
  dsDoctosVM.ParamByName('CAJA_ID').AsInteger:=FCajaId;
  dsDoctosVM.Open;
  dsDoctosVM.First;
  while not dsDoctosVM.Eof do
  begin
    mmError.Lines.Clear;
    mmBien.Lines.Clear;
    mmError.Text := '';
    mmBien.Text := '';
    if (dsDoctosVM.FieldByName('ESTATUS').AsString='N') or (dsDoctosVM.FieldByName('ESTATUS').AsString='C') then
    begin
    {$REGION ''Venta mostrador'}
    lAlmacenId:=0;
    lClienteId:=0;
    lDirCliId:=0;
    lNombreCliente:='';
    lDoctoId:=dsDoctosVM.FieldByName('DOCTO_PV_ID').AsInteger;
    lContinuar:=True;
    lSesionId:=0;
    lSesion:='';

    if ObtenerDatos(lClienteId,lDirCliId,lAlmacenId,lDoctoId,lNombreCliente)=False then
    begin
      Memo1.Lines.Add('Error al obtener datos de cliente en venta mostrador.');
      mmError.Lines.Add('Error al obtener datos de cliente en venta mostrador.');
    end;

    if FVersion=1 then
    begin
      {
      if lDirCliId=0 then
      begin
        Memo1.Lines.Add('El No. de tarjeta es incorrecto.');
        mmError.Lines.Add('El No. de tarjeta es incorrecto.');
      end;
      }
      if (lClienteId<>FClienteId) or (lDirCliId<=0) then
      begin
        lContinuar:=False;
      end;

      if lContinuar then
      begin
        lNoTarjeta:=ObtenerNoTarjeta(lDirCliId);
        if ObtenerSesion(lDirCliId,lSesionId,lSesion)=False then
        begin
          lContinuar:=False;
          Memo1.Lines.Add('Error al obtener sesión.');
          mmError.Lines.Add('Error al obtener sesión.');
        end;
      end;
    end
    else
    begin
        lNoTarjeta:=ObtenerNoTarjeta(lClienteId);
        if ObtenerSesion(lClienteId,lSesionId,lSesion)=False then
        begin
          lContinuar:=False;
          Memo1.Lines.Add('Error al obtener sesión.');
          mmError.Lines.Add('Error al obtener sesión.');
        end;
    end;

    if (lContinuar) and (lSesionId>0) then
    begin
      IBQuery1.Close;
      IBQuery1.SelectSQL.Clear;
      IBQuery1.SelectSQL.Add('SELECT A.ESTATUS, A.FOLIO, A.TOTAL_IMPUESTOS, A.IMPORTE_NETO, E.NOMBRE CAJERO, A.CAJERO_ID, A.ALMACEN_ID ');
      IBQuery1.SelectSQL.Add('FROM DOCTOS_PV A');
      IBQuery1.SelectSQL.Add('INNER JOIN CAJEROS E ON (E.CAJERO_ID=A.CAJERO_ID)');
      IBQuery1.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
      IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=lDoctoId;
      IBQuery1.Open;
      lTotalVM:=IBQuery1.FieldByName('TOTAL_IMPUESTOS').AsFloat+IBQuery1.FieldByName('IMPORTE_NETO').AsFloat;
      lCajeroVM:=IBQuery1.FieldByName('CAJERO').AsString;
      lFolioVM:=IBQuery1.FieldByName('FOLIO').AsString;
      lCajeroId:=IBQuery1.FieldByName('CAJERO_ID').AsInteger;
      lAlmacenId:=IBQuery1.FieldByName('ALMACEN_ID').AsInteger;
      lEstatusVM:=IBQuery1.FieldByName('ESTATUS').AsString;
      if lEstatusVM='N' then
        lEstatusVM := 'P';

      GuardarDatosVM(lFolioVM,lEstatusVM,lAlmacenId,lCajeroId,lSesionId,lTotalVM);

      if (dsDoctosVM.FieldByName('ESTATUS').AsString='N') then
      begin

      Conexion();
      if FConectado='S' then
      begin
      {$REGION 'Agrupar artículos VM'}
      {--La venta mostrador ya no debe ser modificada
      lTotalTArt1:=0;
      IBQuery1.Close;
      IBQuery1.SelectSQL.Clear;
      IBQuery1.SelectSQL.Add('SELECT COUNT(*) TTARTICULOS FROM');
      IBQuery1.SelectSQL.Add('(SELECT DISTINCT A.ARTICULO_ID');
      IBQuery1.SelectSQL.Add('FROM DOCTOS_PV_DET A');
      IBQuery1.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
      IBQuery1.SelectSQL.Add('AND A.PRECIO_UNITARIO>0)');
      IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=lDoctoId;
      IBQuery1.Open;
      lTotalTArt1:= IBQuery1.FieldByName('TTARTICULOS').AsInteger;

      lTotalArt1:=0;
      IBQuery1.Close;
      IBQuery1.SelectSQL.Clear;
      IBQuery1.SelectSQL.Add('SELECT COUNT(*)TARTICULOS');
      IBQuery1.SelectSQL.Add('FROM DOCTOS_PV_DET A');
      IBQuery1.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
      IBQuery1.SelectSQL.Add('AND A.PRECIO_UNITARIO>0');
      IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=lDoctoId;
      IBQuery1.Open;
      lTotalArt1:=IBQuery1.FieldByName('TARTICULOS').AsInteger;

      if lTotalTArt1 <> lTotalArt1 then
      begin
        ErrorAg:='';
        if AgruparArticulos(lDoctoId, ErrorAg)=False then
        begin
          lContinuar:=False;
          Memo1.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
          mmError.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
        end;
      end;}
      {$ENDREGION}

      {$REGION 'cerrar venta'}
        try
        begin
          lTotalArt:=0;
          IBQuery1.Close;
          IBQuery1.SelectSQL.Clear;
          IBQuery1.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM MGNADRO_PROMOCIONES A WHERE A.ID_SESION=:ID_SESION AND A.ESTATUS = ''A'' ');
          IBQuery1.ParamByName('ID_SESION').AsInteger:=lSesionId;
          IBQuery1.Open;
          lTotalArt:=IBQuery1.FieldByName('TARTICULOS').AsInteger;
          if lTotalArt>0 then
          begin
            if lContinuar then
            begin
            IBQuery1.Close;
            IBQuery1.SelectSQL.Clear;
            IBQuery1.SelectSQL.Add('SELECT A.SOLO_PENDIENTES FROM MGNADRO_SESIONES A WHERE A.ID_SESION = :ID_SESION ');
            IBQuery1.ParamByName('ID_SESION').AsInteger:=lSesionId;
            IBQuery1.Open;
            lSoloPen := IBQuery1.FieldByName('SOLO_PENDIENTES').AsString;
            if lSoloPen='S' then
            begin
              IBQuery1.Close;
              IBQuery1.SelectSQL.Clear;
              IBQuery1.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM MGNADRO_PROMOCIONES A WHERE A.ID_SESION=:ID_SESION AND A.ESTATUS = ''A'' AND AMASB=''S'' ');
              IBQuery1.ParamByName('ID_SESION').AsInteger:=lSesionId;
              IBQuery1.Open;
              lTotalArt := lTotalArt + IBQuery1.FieldByName('TARTICULOS').AsInteger;
            end;
            
            {$REGION 'artículos con promoción aplicados'}
            //declarar longitud de Array 1 a N
            SetLength(lListaArticulos,lTotalArt);
            //inicializar el array 1..N
            I := 0;

            lPedido:=Pedido.Create;
            lPedido.NoTarjeta:=lNoTarjeta;
            lPedido.CedulaProfesionalMedico:='';
            lPedido.Usuario:=lCajeroVM;

            lMTotal:=TXSDecimal.Create;
            lMTotal.AsBcd:=DoubleToBcd(lTotalVM);
            lPedido.Total:=lMTotal;

            lPedido.NoTicket:=lFolioVM;

            lRenglonListaArticulos:=PedidoArticulos.Create;

            //Articulos vendicos venta mostrador
            dsObtenerArticulosVM.Close;
            dsObtenerArticulosVM.SelectSQL.Clear;
            if lSoloPen = 'S' then
            begin
              dsObtenerArticulosVM.SelectSQL.Add('SELECT C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM.SelectSQL.Add('FROM DOCTOS_PV_DET E');
              dsObtenerArticulosVM.SelectSQL.Add('INNER JOIN MGNADRO_PROMOCIONES C ON (C.ARTICULO_ID=E.ARTICULO_ID AND C.ID_SESION=:ID_SESION AND C.ESTATUS=''A'' )');
              dsObtenerArticulosVM.SelectSQL.Add('INNER JOIN ARTICULOS F ON (F.ARTICULO_ID=C.ARTICULO_ID)');
              dsObtenerArticulosVM.SelectSQL.Add('WHERE E.DOCTO_PV_ID=:DOCTO_PV_ID');
              dsObtenerArticulosVM.SelectSQL.Add('GROUP BY C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM.SelectSQL.Add('ORDER BY C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
            end
            else
            begin
              dsObtenerArticulosVM.SelectSQL.Add('SELECT C.*, E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM.SelectSQL.Add('FROM DOCTOS_PV_DET E');
              dsObtenerArticulosVM.SelectSQL.Add('INNER JOIN MGNADRO_PROMOCIONES C ON (C.ARTICULO_ID=E.ARTICULO_ID AND C.ID_SESION=:ID_SESION AND C.ESTATUS=''A'' AND C.AMASB =''N'')');
              dsObtenerArticulosVM.SelectSQL.Add('INNER JOIN ARTICULOS F ON (F.ARTICULO_ID=C.ARTICULO_ID)');
              dsObtenerArticulosVM.SelectSQL.Add('WHERE E.DOCTO_PV_ID=:DOCTO_PV_ID');
              dsObtenerArticulosVM.SelectSQL.Add('AND E.PRECIO_TOTAL_NETO>0');
            end;
            dsObtenerArticulosVM.ParamByName('DOCTO_PV_ID').AsInteger:=lDoctoId;
            dsObtenerArticulosVM.ParamByName('ID_SESION').AsInteger:=lSesionId;
            dsObtenerArticulosVM.Open;
            while not dsObtenerArticulosVM.Eof do
            begin
              if dsObtenerArticulosVM.FieldByName('AMASB').AsString='S' then
              begin
                {$REGION '//BUSCAR SU ARTICULO PADRE A'}
                dsObtenerArticulosAB.Close;
                dsObtenerArticulosAB.SelectSQL.Clear;
                dsObtenerArticulosAB.SelectSQL.Add('SELECT A.CLAVE_ARTICULO ');
                dsObtenerArticulosAB.SelectSQL.Add('FROM GET_CLAVE_ART(:ARTICULO_ID)A');
                dsObtenerArticulosAB.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_A_ID').AsInteger;
                dsObtenerArticulosAB.Open;
                if not dsObtenerArticulosAB.IsEmpty then
                begin
                  //ARTICULO A
                  if FPMP>0 then
                  begin
                    IBQuery1.Close;
                    IBQuery1.SelectSQL.Clear;
                    IBQuery1.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                    IBQuery1.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                    IBQuery1.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_A_ID').AsInteger;
                    IBQuery1.ParamByName('PRECIO_EMPRESA_ID').AsInteger:= FPMP;
                    IBQuery1.Open;
                    if lConImpto='N' then
                      lPrecioMaximo:=IBQuery1.FieldByName('PRECIO').AsFloat
                    else
                    begin
                      spPrecioImpto.Close;
                      spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_A_ID').AsInteger;
                      spPrecioImpto.ParamByName('PRECIO').AsFloat:=IBQuery1.FieldByName('PRECIO').AsFloat;
                      spPrecioImpto.ExecProc;
                      lPrecioMaximo:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                    end;
                  end
                  else
                  begin
                    lPrecioMaximo:=0;
                  end;

                  if FPVM>0 then
                  begin
                    IBQuery1.Close;
                    IBQuery1.SelectSQL.Clear;
                    IBQuery1.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                    IBQuery1.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                    IBQuery1.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_A_ID').AsInteger;
                    IBQuery1.ParamByName('PRECIO_EMPRESA_ID').AsInteger:=FPVM;
                    IBQuery1.Open;
                    if lConImpto='N' then
                      lPrecioMostrador:=IBQuery1.FieldByName('PRECIO').AsFloat
                    else
                    begin
                      spPrecioImpto.Close;
                      spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_A_ID').AsInteger;
                      spPrecioImpto.ParamByName('PRECIO').AsFloat:=IBQuery1.FieldByName('PRECIO').AsFloat;
                      spPrecioImpto.ExecProc;
                      lPrecioMostrador:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                    end;
                  end
                  else
                  begin
                    lPrecioMostrador:=0;
                  end; 

                  if lPrecioMaximo=0 then
                    lPrecioMaximo:=lPrecioMostrador;

                  lPMP:=TXSDecimal.Create;
                  lPMP.AsBcd:=DoubleToBcd(lPrecioMaximo);

                  lPM:=TXSDecimal.Create;
                  lPM.AsBcd:=DoubleToBcd(lPrecioMostrador);
                     
                  lPFijo:=TXSDecimal.Create;
                  lPFijo.AsBcd:=DoubleToBcd(0);

                  lPDescto:=TXSDecimal.Create;
                  lPDescto.AsBcd:=DoubleToBcd(0);

                  lMDesc:=TXSDecimal.Create;
                  lMDesc.AsBcd:=DoubleToBcd(0);

                  lPzsGratis:=0;

                  lIva:=TXSDecimal.Create;
                  lIva.AsBcd:=DoubleToBcd(0);

                  UnidadesPagadas:=0;

                  lListaArticulos[I]:=PedidoArticulos.Create;
                  lListaArticulos[I].Sku:=dsObtenerArticulosAB.FieldByName('CLAVE_ARTICULO').AsString;
                  lListaArticulos[I].Precio:=lPMP;
                  lListaArticulos[I].PrecioPOS:=lPM;
                  lListaArticulos[I].PrecioFijo:=lPFijo;
                  lListaArticulos[I].PorcentajeDescuento:=lPDescto;
                  lListaArticulos[I].MontoDescuento:=lMDesc;
                  lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
                  lListaArticulos[I].PiezasGratis:=lPzsGratis;
                  lListaArticulos[I].IVA:=lIva;
                  lListaArticulos[I].PorcentajeIVA:=0;

                  I:=I+1;
                end;
                {$ENDREGION}
              end;

              lEstatus:=dsObtenerArticulosVM.FieldByName('ESTATUS').AsString;

              if dsObtenerArticulosVM.FieldByName('AMASB').AsString='S' then
              begin
                lPrecioMaximo := 0.01;
                lPrecioMostrador := 0.01;
              end
              else
              begin
                {$REGION 'ARTICULOS NORMALES'}
                if FPMP>0 then
                begin
                  IBQuery1.Close;
                  IBQuery1.SelectSQL.Clear;
                  IBQuery1.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                  IBQuery1.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                  IBQuery1.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_ID').AsInteger;
                  IBQuery1.ParamByName('PRECIO_EMPRESA_ID').AsInteger:= FPMP;
                  IBQuery1.Open;
                  if lConImpto='N' then
                    lPrecioMaximo:=IBQuery1.FieldByName('PRECIO').AsFloat
                  else
                  begin
                    spPrecioImpto.Close;
                    spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_ID').AsInteger;
                    spPrecioImpto.ParamByName('PRECIO').AsFloat:=IBQuery1.FieldByName('PRECIO').AsFloat;
                    spPrecioImpto.ExecProc;
                    lPrecioMaximo:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                  end;
                end
                else
                begin
                  lPrecioMaximo:=0;
                end;

                lPrecioMostrador := dsObtenerArticulosVM.FieldByName('PRECIO_MSP').AsFloat;
                {$ENDREGION}
              end;

              if lPrecioMaximo=0 then
                lPrecioMaximo:=lPrecioMostrador;

              lPMP:=TXSDecimal.Create;
              lPMP.AsBcd:=DoubleToBcd(lPrecioMaximo);

              lPM:=TXSDecimal.Create;
              lPM.AsBcd:=DoubleToBcd(lPrecioMostrador);

              lPFijo:=TXSDecimal.Create;
              lPDescto:=TXSDecimal.Create;
              lMDesc:=TXSDecimal.Create;

              if lEstatus='A' then
              begin
                lPFijo.AsBcd:=dsObtenerArticulosVM.FieldByName('PRECIOFIJO').AsBCD;
                lPDescto.AsBcd:=dsObtenerArticulosVM.FieldByName('PORCENTAJEDESCUENTO').AsBCD;
                lMDesc.AsBcd:=dsObtenerArticulosVM.FieldByName('MONTODESCUENTO').AsBCD;
                lPzsGratis:=dsObtenerArticulosVM.FieldByName('PIEZASGRATIS').AsInteger;
              end
              else
              begin
                lPFijo.AsBcd:=DoubleToBcd(0);
                lPDescto.AsBcd:=DoubleToBcd(0);
                lMDesc.AsBcd:=DoubleToBcd(0);
                lPzsGratis:=0;
              end;

              if lSoloPen = 'S' then
                UnidadesPagadas:=0
              else
                UnidadesPagadas:=dsObtenerArticulosVM.FieldByName('UNIDADES').AsInteger;

              lIva:=TXSDecimal.Create;
              lIva.AsBcd:=DoubleToBcd(0);

              lListaArticulos[I]:=PedidoArticulos.Create;
              lListaArticulos[I].Sku:=dsObtenerArticulosVM.FieldByName('CLAVE_ARTICULO').AsString;
              lListaArticulos[I].Precio:=lPMP;
              lListaArticulos[I].PrecioPOS:=lPM;
              lListaArticulos[I].PrecioFijo:=lPFijo;
              lListaArticulos[I].PorcentajeDescuento:=lPDescto;
              lListaArticulos[I].MontoDescuento:=lMDesc;
              lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
              lListaArticulos[I].PiezasGratis:=lPzsGratis;
              lListaArticulos[I].IVA:=lIva;
              lListaArticulos[I].PorcentajeIVA:=0;

              I:=I+1;

              //PROMOCIONES APLICADAS DE PRODUCTOS A+B
              dsObtenerArticulosAB.Close;
              dsObtenerArticulosAB.SelectSQL.Clear;
              dsObtenerArticulosAB.SelectSQL.Add('SELECT FIRST 1 C.ARTICULO_ID, C.PRECIOFIJO, C.PORCENTAJEDESCUENTO, C.MONTODESCUENTO, C.PIEZASGRATIS, D.CLAVE_ARTICULO');
              dsObtenerArticulosAB.SelectSQL.Add('FROM MGNADRO_PROMOCIONES C');
              dsObtenerArticulosAB.SelectSQL.Add('LEFT JOIN GET_CLAVE_ART(C.ARTICULO_ID)D ON (D.ARTICULO_ID = C.ARTICULO_ID)');
              dsObtenerArticulosAB.SelectSQL.Add('WHERE C.ID_SESION = :ID_SESION');
              dsObtenerArticulosAB.SelectSQL.Add('AND C.ESTATUS=''A'' ');
              dsObtenerArticulosAB.SelectSQL.Add('AND C.AMASB = ''S'' ');
              dsObtenerArticulosAB.SelectSQL.Add('AND C.ARTICULO_A_ID = :ARTICULO_A_ID');
              dsObtenerArticulosAB.ParamByName('ARTICULO_A_ID').AsInteger:=dsObtenerArticulosVM.FieldByName('ARTICULO_ID').AsInteger;
              dsObtenerArticulosAB.ParamByName('ID_SESION').AsInteger:=lSesionId;
              dsObtenerArticulosAB.Open;
              if not dsObtenerArticulosAB.IsEmpty then
              begin
                //ARTICULO B
                lPMP:=TXSDecimal.Create;
                lPMP.AsBcd:=DoubleToBcd(0.01);

                lPM:=TXSDecimal.Create;
                lPM.AsBcd:=DoubleToBcd(0.01);

                lPFijo:=TXSDecimal.Create;
                lPFijo.AsBcd:=dsObtenerArticulosAB.FieldByName('PRECIOFIJO').AsBCD;

                lPDescto:=TXSDecimal.Create;
                lPDescto.AsBcd:=dsObtenerArticulosAB.FieldByName('PORCENTAJEDESCUENTO').AsBCD;

                lMDesc:=TXSDecimal.Create;
                lMDesc.AsBcd:=dsObtenerArticulosAB.FieldByName('MONTODESCUENTO').AsBCD;

                lPzsGratis:=dsObtenerArticulosAB.FieldByName('PIEZASGRATIS').AsInteger;

                lIva:=TXSDecimal.Create;
                lIva.AsBcd:=DoubleToBcd(0);

                UnidadesPagadas:=0;

                lListaArticulos[I]:=PedidoArticulos.Create;
                lListaArticulos[I].Sku:=dsObtenerArticulosAB.FieldByName('CLAVE_ARTICULO').AsString;
                lListaArticulos[I].Precio:=lPMP;
                lListaArticulos[I].PrecioPOS:=lPM;
                lListaArticulos[I].PrecioFijo:=lPFijo;
                lListaArticulos[I].PorcentajeDescuento:=lPDescto;
                lListaArticulos[I].MontoDescuento:=lMDesc;
                lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
                lListaArticulos[I].PiezasGratis:=lPzsGratis;
                lListaArticulos[I].IVA:=lIva;
                lListaArticulos[I].PorcentajeIVA:=0;

                I:=I+1;
              end;

              dsObtenerArticulosVM.Next;
            end;

            lMensajeError:='';
            //Invocar WS
            lRespuestaSales:=GetWSCirculodelaSaludSoap.Create_Sales_Folio_Receta(lSesion,lPedido,lListaArticulos,'');
            lHuboError:=lRespuestaSales.HuboError;
            if lHuboError then
            begin
              {$REGION 'Hay error'}
              lMensajeError:=lRespuestaSales.MensajeError;
              lPosicion:=0;
              lPosicion:= pos('La sesión se cerró con el id de venta:',lMensajeError);
              if lPosicion=0 then
              begin
                Memo1.Lines.Add('Error al cerrar venta con el web service círculo de la salud. Error:'+lMensajeError);
                mmError.Lines.Add('Error al cerrar venta con el web service círculo de la salud. Error:'+lMensajeError);
              end
              else
              begin
                mmError.Lines.Add(lMensajeError);
                lFolioPedido:='';
                lFolioPedidoF:='';
                lFolioPedido:=StringReplace(lMensajeError, 'La sesión se cerró con el id de venta:', '',
                          [rfReplaceAll, rfIgnoreCase]);
                lFolioPedido:=Trim(lFolioPedido);
                lPosicion:=Length(lFolioPedido);

                for I := 0 to lPosicion - 1 do
                begin
                  if lFolioPedido[I]<>' ' then
                    lFolioPedidoF:=lFolioPedidoF+lFolioPedido[I]
                  else
                    Break;
                end;
              end;
              {$ENDREGION}
            end
            else
            begin
              lResPedido:=lRespuestaSales.Pedido;
              GuardarFolioPedido(lResPedido, lFolioVM, lSesionId);
            end;

            {$ENDREGION}
            end;
          end;
        end;
        finally
          lIva.Free;
          lMDesc.Free;
          lPDescto.Free;
          lPFijo.Free;
          lPM.Free;
          lPMP.Free;
          lRenglonListaArticulos.Free;
          lMTotal.Free;
        end;
      {$ENDREGION}
      end;

      end;

    end;
    {$ENDREGION}
    end;

    {$REGION 'Eliminar'}
    if trElimina.InTransaction then
      trElimina.Rollback;

    trElimina.StartTransaction;

    dsEliminaVM.Close();
    dsEliminaVM.ParamByName('DOCTO_PV_ID').AsInteger := lDoctoId;
    dsEliminaVM.Open();

    If trElimina.InTransaction then
      trElimina.Commit;
    {$ENDREGION}

    if mmError.Text<>'' then
    begin
      if lFolioPedidoF<>'' then
      begin
        lFolioPedidoF:=Trim(lFolioPedidoF);
        GuardarFolioPedido(lFolioPedidoF, lFolioVM, lSesionId);
      end
      else
      begin
        GuardarError(lSesionId);
      end;
    end;

    if mmBien.Text<>'' then
    begin
      MessageDlg(mmBien.Text, mtInformation, [mbOk], 0);
    end;

    dsDoctosVM.Next;
  end;
end;
except on e:exception do
begin
  if trTrans.InTransaction then
    trTrans.Rollback;

  if lSesionId>0 then
  begin
    GuardarError(lSesionId);
  end;

  if pos('Error de servidor', e.Message)<>0 then
  begin
    FConectado := 'N';
    MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
  end
  else
  begin
    Memo1.Lines.Add('Error en proceso final.' + Chr(13) + e.Message);
    mmError.Lines.Add('Error en proceso final.' + Chr(13) + e.Message);
    MessageDlg('No es posible cerrar venta mostrador '+lFolioVM+' con el web service Círculo de la Salud ORO.' + #13 +'Error: '+  e.Message, mtError, [mbOk], 0);
  end;
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if FConectado='S' then
begin
  fmActualizarTar.FVersion := FVersion;
  fmActualizarTar.ShowModal;
end
else
begin
  MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if FConectado='S' then
begin
  if FVersion=1 then
  begin
    fmActivarTar.ShowModal;
  end
  else
  begin
    fmActivarTar2.ShowModal;
  end;
end
else
begin
  MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  FDetenido := 'N';
  FConectado := 'N';
  Timer2.Enabled:=True;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Timer2.Enabled := False;
  FDetenido := 'S';
  Memo1.Lines.Add('Detener proceso.');
  Memo2.Lines.Add('Detener proceso de cierre automático de ventas pendientes.');
  FConectado := 'N';
  lblConexion.Caption := 'NO Conectado';
  lblConexion.Font.Color := clRed;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
if FConectado='S' then
begin
  fmPromoArt.Showmodal;
end
else
begin
  MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
end;
end;

procedure TForm1.Button6Click(Sender: TObject);
var MensajeError:String;
PROCESO_ID:Integer;
begin
if FConectado='S' then
begin
  MensajeError:='';

  spCatalogoId.ExecProc;
  PROCESO_ID := spCatalogoId.FieldByName('CATALOGO_ID').AsInteger;
  if PromosEspeciales(MensajeError, PROCESO_ID) then
  begin
    fmPromosEsp.FProcesoId := PROCESO_ID;
    fmPromosEsp.Showmodal;
  end
  else
  begin
    MessageDlg(MensajeError, mtError, [mbOk], 0);
  end;
end
else
begin
  MessageDlg('No se puede hacer contacto con el web service de Círculo de la Salud ORO.' , mtError,[mbOK],0);
end;
end;

procedure TForm1.CentrodeReportes1Click(Sender: TObject);
begin
  fmReportes.Showmodal;
end;

procedure TForm1.CerrarVentasPendientesClick(Sender: TObject);
begin
  Form3.ShowModal;
end;

function TForm1.ObtenerDatos(var AClienteId,ADirCliId,AAlmacenId,ADoctoId:Integer; var ANombreCliente:String):Boolean;
begin
  Result:=False;
  IBQuery1.Close;
  IBQuery1.SelectSQL.Clear;
  IBQuery1.SelectSQL.Add('SELECT A.CLIENTE_ID, A.DIR_CLI_ID, B.NOMBRE, A.ALMACEN_ID');
  IBQuery1.SelectSQL.Add('FROM DOCTOS_PV A');
  IBQuery1.SelectSQL.Add('INNER JOIN CLIENTES B ON (B.CLIENTE_ID=A.CLIENTE_ID)');
  IBQuery1.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
  IBQuery1.ParamByName('DOCTO_PV_ID').AsInteger:=ADoctoId;
  IBQuery1.Open;
  AClienteId:=IBQuery1.FieldByName('CLIENTE_ID').AsInteger;
  ADirCliId:=IBQuery1.FieldByName('DIR_CLI_ID').AsInteger;
  AAlmacenId:=IBQuery1.FieldByName('ALMACEN_ID').AsInteger;
  ANombreCliente:=IBQuery1.FieldByName('NOMBRE').AsString;
  Result:=True;
end;

function TForm1.ObtenerNoTarjeta(var Id:Integer):String;
begin
  if FVersion=1 then
  begin
    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT A.NOMBRE_CONSIG ');
    IBQuery1.SelectSQL.Add('FROM DIRS_CLIENTES A ');
    IBQuery1.SelectSQL.Add('WHERE A.DIR_CLI_ID=:DIR_CLI_ID');
    IBQuery1.ParamByName('DIR_CLI_ID').AsInteger:=Id;
    IBQuery1.Open;
    Result:=IBQuery1.FieldByName('NOMBRE_CONSIG').AsString;
  end
  else
  begin
    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT A.CLAVE_CLIENTE FROM CLAVES_CLIENTES A');
    IBQuery1.SelectSQL.Add('INNER JOIN ROLES_CLAVES_CLIENTES B ON (B.ROL_CLAVE_CLI_ID=A.ROL_CLAVE_CLI_ID AND B.NOMBRE=''Nadro circulo'') ');
    IBQuery1.SelectSQL.Add('WHERE A.CLIENTE_ID=:CLIENTE_ID');
    IBQuery1.ParamByName('CLIENTE_ID').AsInteger:=Id;
    IBQuery1.Open;
    Result:=IBQuery1.FieldByName('CLAVE_CLIENTE').AsString;
  end;
end;

function TForm1.ObtenerSesion(var AClienteId,ASesionId:Integer; var ASesion:String):Boolean;
begin
    dsFechaServidor.CloseOpen(False);
    Result:=False;
    IBQuery1.Close;
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT FIRST 1 A.ID_SESION, A.SESION FROM MGNADRO_SESIONES A WHERE A.CLIENTE_ID=:CLIENTE_ID AND A.ESTATUS=''P'' AND A.FECHA = :FECHA ORDER BY A.ID_SESION DESC');
    IBQuery1.ParamByName('CLIENTE_ID').AsInteger:=AClienteId;
    IBQuery1.ParamByName('FECHA').AsDateTime:=dsFechaServidor.FieldByName('FECHA').AsDateTime;
    IBQuery1.Open;
    ASesionId:=IBQuery1.FieldByName('ID_SESION').AsInteger;
    ASesion:=IBQuery1.FieldByName('SESION').AsString;
    Result:=True;
end;

function TForm1.VerificarConexionWS():Boolean;
var lConexion:Boolean;
begin
  lConexion:=GetWSCirculodelaSaludSoap.TestConnect;
  if lConexion then
    Result := True
  else
    Result := False;
end;

function TForm1.ObtenerVersionWS():String;
var lVersion:String;
begin
  lVersion:=GetWSCirculodelaSaludSoap.getVersion;
  Result := lVersion;
end;

procedure TForm1.ConfiguracionClick(Sender: TObject);
begin
  fmConfig.FVersion:=FVersion;
  fmConfig.ShowModal;
end;

function TForm1.IniciarSesion(var ASesion:String):Boolean;
var lRepuestaLogin:ResponseLogin;
lHuboError:Boolean;
begin
  try
  lRepuestaLogin:=ResponseLogin.Create;
  //lRepuestaLogin:=GetWSCirculodelaSaludSoap.Login('FarmaEconomik','LIV06ZTK','0000000187','1');
  lRepuestaLogin:=GetWSCirculodelaSaludSoap.Login(FUsuario,FPassword,FIdCadena,FIdSucursal);
  lHuboError:=lRepuestaLogin.HuboError;
  if lHuboError then
  begin
    Result:=False;
    ASesion:=lRepuestaLogin.MensajeError;
  end
  else
  begin
    Result:=True;
    ASesion:=lRepuestaLogin.Sesion;
  end;
  finally
    lRepuestaLogin.Free;
  end;
end;

function TForm1.ActivarTarjeta(var ASesion, ANombreCajero, ANoTarjeta, ANombre, AAPaterno, AAMaterno, ATelefono, AEmail, ASexo, ACP, AMensajeError:String; AFNacimiento:TXSDateTime):Boolean;
var lRespuestaActivateCard:ResponseActivateCard;
lHuboError:Boolean;
begin
  try
  lRespuestaActivateCard:=ResponseActivateCard.Create;
  lRespuestaActivateCard:=GetWSCirculodelaSaludSoap.ActivateCardUser(ASesion, ANombreCajero, ANoTarjeta, ANombre, AAPaterno, AAMaterno, ATelefono, AEmail, ASexo, AFNacimiento, ACP);
  lHuboError:=lRespuestaActivateCard.HuboError;
  if lHuboError then
  begin
    AMensajeError:=lRespuestaActivateCard.MensajeError;
    Result:=False;
  end
  else
  begin
    AMensajeError:='';
    Result:=lRespuestaActivateCard.Activada;
  end;
  finally
    lRespuestaActivateCard.Free;
  end;
end;

procedure TForm1.AsignarCaja1Click(Sender: TObject);
begin
  if fmConfigConexion.G_NomUsuario <> 'SYSDBA' then
  begin
    IBQuery1.Close();
    IBQuery1.SelectSQL.Clear;
    IBQuery1.SelectSQL.Add('SELECT C.CAJERO_ID, C.OPERAR_CAJAS FROM  CAJEROS C WHERE UPPER(C.USUARIO) = UPPER(:USUARIO)');
    IBQuery1.ParamByName('USUARIO').AsString := fmConfigConexion.G_NomUsuario;
    IBQuery1.Open();
    FCajeroId :=  IBQuery1.FieldByName('CAJERO_ID').AsInteger;

    if FCajeroId = 0  then
    Begin
      MessageDlg('El usuario no esta registrado como cajero.'+#13+'La aplicación se cerrara.', mtInformation,[mbOk], 0);
      Application.Terminate;
    End Else
    Begin
      dsCajas.Close();
      dsCajas.ParamByName('CAJERO_ID').AsInteger := FCajeroId;
      dsCajas.Open();
      fmCaja.FCajeroId :=  FCajeroId;
      fmCaja.ShowModal();
      If ((fmCaja.FBandera=False)  or  (dsCajas.FieldByName('CAJA_ID').AsInteger = 0)) then
      Begin
        MessageDlg('No hay cajas abiertas para asignar.'+#13+'La aplicación se cerrara.', mtInformation,[mbOk], 0);
        Application.Terminate;
      End;
    End;
  end
  else
  begin
    MessageDlg('El usuario no esta registrado como cajero.'+#13+'La aplicación se cerrara.', mtInformation,[mbOk], 0);
    Application.Terminate;
  end;
end;

function TForm1.ValidarTarjeta(var ASesion, ANoTarjeta, AMensajeError, AFolioTarjeta:String):Boolean;
var lRepuestaLogin:ResponseLogin;
lHuboError:Boolean;
lInfoCard:Tarjeta;
begin
  try
  lInfoCard:=Tarjeta.Create;
  lInfoCard:=GetWSCirculodelaSaludSoap.GetInfoCard(ASesion,ANoTarjeta);
  lHuboError:=lInfoCard.HuboError;
  if lHuboError then
  begin
    AFolioTarjeta:='';
    AMensajeError:=lInfoCard.MensajeError;
    Result:=False;
  end
  else
  begin
    AFolioTarjeta:=lInfoCard.folio;
    AMensajeError:='';
    Result:=True;
  end;
  finally
    lInfoCard.Free;
  end;
end;

function TForm1.AgruparArticulos(ADoctoId:Integer; var Error:String):Boolean;
var lUnidadesAgr:Double;
lArtAgr, lDoctoVeDetId:Integer;
begin
try
begin
  if trModifica.InTransaction then trModifica.Rollback;
    trModifica.StartTransaction;

  Result:=False;

  dsAgruparArt.Close;
  dsAgruparArt.SelectSQL.Clear;
  dsAgruparArt.SelectSQL.Add('SELECT A.ARTICULO_ID, SUM(A.UNIDADES) TUNIDADES');
  dsAgruparArt.SelectSQL.Add('FROM DOCTOS_PV_DET A');
  dsAgruparArt.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
  dsAgruparArt.SelectSQL.Add('AND A.PRECIO_TOTAL_NETO>0');
  dsAgruparArt.SelectSQL.Add('GROUP BY A.ARTICULO_ID');
  dsAgruparArt.ParamByName('DOCTO_PV_ID').AsInteger:=ADoctoId;
  dsAgruparArt.Open;
  while not dsAgruparArt.Eof do
  begin
    lArtAgr:=dsAgruparArt.FieldByName('ARTICULO_ID').AsInteger;
    lUnidadesAgr:=dsAgruparArt.FieldByName('TUNIDADES').AsFloat;

    dsArticulos.Close;
    dsArticulos.SelectSQL.Clear;
    dsArticulos.SelectSQL.Add('SELECT FIRST 1 A.DOCTO_PV_DET_ID, A.ARTICULO_ID');
    dsArticulos.SelectSQL.Add('FROM DOCTOS_PV_DET A');
    dsArticulos.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
    dsArticulos.SelectSQL.Add('AND A.ARTICULO_ID=:ARTICULO_ID');
    dsArticulos.SelectSQL.Add('AND A.PRECIO_UNITARIO>0');
    dsArticulos.SelectSQL.Add('ORDER BY A.DOCTO_PV_DET_ID');
    dsArticulos.ParamByName('DOCTO_PV_ID').AsInteger:=ADoctoId;
    dsArticulos.ParamByName('ARTICULO_ID').AsInteger:=lArtAgr;
    dsArticulos.Open;
    lDoctoVeDetId:=dsArticulos.FieldByName('DOCTO_PV_DET_ID').AsInteger;
    if lDoctoVeDetId>0 then
    begin
        dsModArt.Close;
        dsModArt.SelectSQL.Clear;
        dsModArt.SelectSQL.Add('UPDATE DOCTOS_PV_DET SET UNIDADES = :UNIDADES');
        dsModArt.SelectSQL.Add('WHERE (DOCTO_PV_DET_ID = :DOCTO_PV_DET_ID);');
        dsModArt.ParamByName('UNIDADES').AsFloat:=lUnidadesAgr;
        dsModArt.ParamByName('DOCTO_PV_DET_ID').AsInteger:=lDoctoVeDetId;
        dsModArt.Open;
    end;

    dsArticulos.Close;
    dsArticulos.SelectSQL.Clear;
    dsArticulos.SelectSQL.Add('SELECT A.DOCTO_PV_DET_ID, A.ARTICULO_ID');
    dsArticulos.SelectSQL.Add('FROM DOCTOS_PV_DET A');
    dsArticulos.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
    dsArticulos.SelectSQL.Add('AND A.ARTICULO_ID=:ARTICULO_ID');
    dsArticulos.SelectSQL.Add('AND A.DOCTO_PV_DET_ID<>:DOCTO_PV_DET_ID');
    dsArticulos.SelectSQL.Add('AND A.PRECIO_UNITARIO>0');
    dsArticulos.SelectSQL.Add('ORDER BY A.DOCTO_PV_DET_ID');
    dsArticulos.ParamByName('DOCTO_PV_ID').AsInteger:=ADoctoId;
    dsArticulos.ParamByName('ARTICULO_ID').AsInteger:=lArtAgr;
    dsArticulos.ParamByName('DOCTO_PV_DET_ID').AsInteger:=lDoctoVeDetId;
    dsArticulos.Open;
    while not dsArticulos.Eof do
    begin
        dsModArt.Close;
        dsModArt.SelectSQL.Clear;
        dsModArt.SelectSQL.Add('DELETE FROM DOCTOS_PV_DET A');
        dsModArt.SelectSQL.Add('WHERE A.DOCTO_PV_DET_ID=:DOCTO_PV_DET_ID');
        dsModArt.ParamByName('DOCTO_PV_DET_ID').AsInteger:=dsArticulos.FieldByName('DOCTO_PV_DET_ID').AsInteger;
        dsModArt.Open;

      dsArticulos.Next;
    end;

    dsAgruparArt.Next;
  end;

  if trModifica.InTransaction then trModifica.Commit;

  Result:=True;
  Error:='';
end;
except on e:exception do
begin
  if trModifica.InTransaction then trModifica.Rollback;
  Result:=False;
  Error:=e.Message;
end;
end;
end;

procedure TForm1.Historialdecomprasporpaciente1Click(Sender: TObject);
begin
  fmComprasPaciente.FVersion:=FVersion;
  fmComprasPaciente.ShowModal;
end;

procedure TForm1.BuscarDatos();
begin
  FCajaId:=GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO\','CajaId');
  FIdCadena:=GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO\','IdCadena');
  FIdSucursal:=GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO\','IdSucursal');
  FUsuario:=GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO\','Usuario');
  FPassword:=GetRegistryData(HKEY_LOCAL_MACHINE,'\SOFTWARE\NGPlugOut\INTERFASECSO\','Password');
end;

procedure TForm1.GuardarError(lSesionId:Integer);
begin
    try
    begin
      if trWrite.InTransaction then
        trWrite.Rollback;

      trWrite.StartTransaction;

      dsWrite.Close;
      dsWrite.SelectSQL.Clear;
      dsWrite.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET INTENTOS_CIERRE = 1, LOG_ERRORES = :LOG_ERRORES');
      dsWrite.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION); ');
      dsWrite.ParamByName('LOG_ERRORES').AsString:='Error al cerrar venta con el web service círculo de la salud.Intento 1:'+#13+mmError.Text+#13;
      dsWrite.ParamByName('ID_SESION').AsInteger:=lSesionId;
      dsWrite.Open;

      if trWrite.InTransaction then
        trWrite.Commit;

      if mmError.Text<>'' then      
        MessageDlg(mmError.Text, mtError, [mbOk], 0);
      end;
      except on e:exception do
      begin
        if trWrite.InTransaction then trWrite.Rollback;
          trWrite.StartTransaction;

        Memo1.Lines.Add('Error al actualizar datos de cierre de venta. ' + Chr(13) + e.Message);
      end;
      end;
end;

procedure TForm1.GuardarFolioPedido(lResPedido, lFolioVM:String; lSesionId:Integer);
begin
try
begin
  if trWrite.InTransaction then
    trWrite.Rollback;

  trWrite.StartTransaction;

  dsWrite.Close;
  dsWrite.SelectSQL.Clear;
  dsWrite.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET ESTATUS = :ESTATUS, FOLIO_PEDIDO = :FOLIO_PEDIDO');
  dsWrite.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION);');
  dsWrite.ParamByName('ESTATUS').AsString:='T'; //Terminada
  dsWrite.ParamByName('FOLIO_PEDIDO').AsString:=lResPedido;
  dsWrite.ParamByName('ID_SESION').AsInteger:=lSesionId;
  dsWrite.Open;

  if trWrite.InTransaction then
    trWrite.Commit;

  mmBien.Lines.Clear;
  mmBien.Lines.Add('El cierre de venta mostrador '+lFolioVM+' con el web service círculo de la salud fue exitosa. Folio de respuesta: '+lResPedido+'.');
end;
except on e:exception do
begin
  if trWrite.InTransaction then trWrite.Rollback;
    trWrite.StartTransaction;

  Memo1.Lines.Add('Error al cerrar venta. ' + Chr(13) + e.Message);
  mmError.Lines.Add('Error al cerrar venta. ' + Chr(13) + e.Message);
end;
end;
end;

procedure TForm1.Conexion();
begin
  try
  begin
    //Revisión si existe coneción
    if VerificarConexionWS then
    begin
      FConectado := 'S';
      lblConexion.Caption := 'Conectado';
      lblConexion.Font.Color := clNavy;
    end
    else
    begin
      FConectado := 'N';
      lblConexion.Caption := 'NO Conectado';
      lblConexion.Font.Color := clRed;
    end;
  end;
  except
  begin
    FConectado := 'N';
    lblConexion.Caption := 'NO Conectado';
    lblConexion.Font.Color := clRed;
  end;
  end;
end;


procedure TForm1.IntentosCierre();
var
lPedido:Pedido;
lListaArticulos:ArrayOfPedidoArticulos;
lRenglonListaArticulos:PedidoArticulos;
lRespuestaSales:ResponseSales;
lTotalArt, I:Integer;
lPrecioMaximo,lPrecioMostrador:Double;
lHuboError, lContinuar:Boolean;
lMTotal, lPMP, lPM, lPFijo, lPDescto, lMDesc, lIva:TXSDecimal;
lCPVM, lCPMP, lPzsGratis:Integer;
lFolioVM, lMensajeError, lNoTarjeta, lSesion, lResPedido, lEstatus, lConImpto, lFolioTarjeta, ErrorAg:String;
lLineaId:Integer;
UnidadesPagadas, IntentosCierre, lPosicion, lTotalTArt1, lTotalArt1, lpos:Integer;
lFolioPedido, lFolioPedidoF, lSoloPen:String;
begin
try
begin
  Memo2.Lines.Clear;
  Memo2.Lines.Add('Inicio de cierre de ventas pendientes.');

  if trCerrarVen.InTransaction then trCerrarVen.Rollback;
    trCerrarVen.StartTransaction;

  {$REGION 'datos configuración'}
  //PMP(precio máximo público)
  dsCerrarVen.Close;
  dsCerrarVen.SelectSQL.Clear;
  dsCerrarVen.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''LISTAPMP'' ');
  dsCerrarVen.Open;
  lCPMP:=dsCerrarVen.FieldByName('VALOR').AsInteger;
  //PVM(precio venta mostrador)
  dsCerrarVen.Close;
  dsCerrarVen.SelectSQL.Clear;
  dsCerrarVen.SelectSQL.Add ('SELECT A.VALOR FROM MGNADRO_CONFIG A WHERE A.NOMBRE = ''LISTAPVM'' ');
  dsCerrarVen.Open;
  lCPVM:=dsCerrarVen.FieldByName('VALOR').AsInteger;
  {$ENDREGION}

  dsFechaServidor1.CloseOpen(False);
  mmError1.Lines.Clear;
  mmError2.Lines.Clear;
  mmBien1.Lines.Clear;
  mmError1.Text := '';
  mmError2.Text := '';
  mmBien1.Text := '';

  lContinuar:=True;
  Application.ProcessMessages;
  dsVMPendientes.Close;
  dsVMPendientes.ParamByName('FECHA_INI').AsDate := dsFechaServidor1.FieldByName('FECHA').AsDateTime;
  dsVMPendientes.ParamByName('FECHA_FIN').AsDate := dsFechaServidor1.FieldByName('FECHA').AsDateTime;
  dsVMPendientes.Open;
  if not dsVMPendientes.IsEmpty then
  begin

  //22/11/2016 LIZ Application.Restore;

  while not dsVMPendientes.Eof do
  begin
    if dsVMPendientes.FieldByName('ESTATUS').AsString = 'P' then
    begin
    {$REGION 'cerrar venta'}
    try
    begin
    Conexion();
    if FConectado='S' then
    begin
      lSesion:=dsVMPendientes.FieldByName('SESION').AsString;
      IntentosCierre:=dsVMPendientes.FieldByName('INTENTOS_CIERRE').AsInteger;
      if IntentosCierre = 0 then
        IntentosCierre := 1
      else if IntentosCierre > 0  then
        IntentosCierre := IntentosCierre + 1;

      if Form1.FVersion = 1 then
      begin
        dsCerrarVen.Close;
        dsCerrarVen.SelectSQL.Clear;
        dsCerrarVen.SelectSQL.Add('SELECT X.NOMBRE_CONSIG FROM DIRS_CLIENTES X WHERE X.DIR_CLI_ID=:DIR_CLI_ID');
        dsCerrarVen.ParamByName('DIR_CLI_ID').AsInteger:=dsVMPendientes.FieldByName('DIR_CLI_ID').AsInteger;
        dsCerrarVen.Open;
        lNoTarjeta:=dsCerrarVen.FieldByName('NOMBRE_CONSIG').AsString;
      end
      else
      begin
        {dsCerrarVen.Close;
        dsCerrarVen.SelectSQL.Clear;
        dsCerrarVen.SelectSQL.Add('SELECT A.CLAVE_CLIENTE FROM CLAVES_CLIENTES A');
        dsCerrarVen.SelectSQL.Add('INNER JOIN ROLES_CLAVES_CLIENTES B ON (B.ROL_CLAVE_CLI_ID=A.ROL_CLAVE_CLI_ID AND B.NOMBRE=''Nadro circulo'') ');
        dsCerrarVen.SelectSQL.Add('WHERE A.CLIENTE_ID=:CLIENTE_ID');
        dsCerrarVen.ParamByName('CLIENTE_ID').AsInteger:=dsVMPendientes.FieldByName('CLIENTE_ID').AsInteger;
        dsCerrarVen.Open;
        lNoTarjeta:=dsCerrarVen.FieldByName('CLAVE_CLIENTE').AsString;}
        lNoTarjeta:=dsVMPendientes.FieldByName('CLAVE_CLIENTE').AsString;
      end;

      if (lNoTarjeta<>'') and (lSesion<>'') then
      begin
        lMensajeError:='';
        if ValidarTarjeta(lSesion, lNoTarjeta, lMensajeError, lFolioTarjeta)=False then
        begin
          lpos:=0;
          lpos:=Pos('Cadena de sesión no válida', lMensajeError);
          if lpos=0 then
          begin
          lContinuar:=False;
          Memo2.Lines.Add('Error al validar tarjeta de venta mostrador: '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+Chr(10)+' '+lMensajeError);
          mmError1.Lines.Add('Error al validar tarjeta de venta mostrador: '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+Chr(10)+' '+lMensajeError);
          end;
        end;
      end;

      {$REGION 'Agrupar artículos VM'}
            { NO SE DEBE YA MODIFICAR LA VENTA MOSTRADOR
            lTotalTArt1:=0;
            dsCerrarVen.Close;
            dsCerrarVen.SelectSQL.Clear;
            dsCerrarVen.SelectSQL.Add('SELECT COUNT(*) TTARTICULOS FROM');
            dsCerrarVen.SelectSQL.Add('(SELECT DISTINCT A.ARTICULO_ID');
            dsCerrarVen.SelectSQL.Add('FROM DOCTOS_PV_DET A');
            dsCerrarVen.SelectSQL.Add('WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID');
            dsCerrarVen.SelectSQL.Add('AND A.PRECIO_UNITARIO>0)');
            dsCerrarVen.ParamByName('DOCTO_PV_ID').AsInteger:=dsVMPendientes.FieldByName('DOCTO_PV_ID').AsInteger;
            dsCerrarVen.Open;
            lTotalTArt1:= dsCerrarVen.FieldByName('TTARTICULOS').AsInteger;

            lTotalArt1:=0;
            dsCerrarVen.Close;
            dsCerrarVen.SelectSQL.Clear;
            dsCerrarVen.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM DOCTOS_PV_DET A WHERE A.DOCTO_PV_ID=:DOCTO_PV_ID AND A.PRECIO_UNITARIO>0');
            dsCerrarVen.ParamByName('DOCTO_PV_ID').AsInteger:=dsVMPendientes.FieldByName('DOCTO_PV_ID').AsInteger;
            dsCerrarVen.Open;
            lTotalArt1:=dsCerrarVen.FieldByName('TARTICULOS').AsInteger;

            if lTotalTArt1 <> lTotalArt1 then
            begin
              ErrorAg:='';
              if AgruparArticulos(dsVMPendientes.FieldByName('DOCTO_PV_ID').AsInteger, ErrorAg)=False then
              begin
                lContinuar:=False;
                Memo1.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
                mmError.Lines.Add('Error al agrupar artículos.'+#13+ErrorAg);
              end;
            end;
            }
      {$ENDREGION}

        lTotalArt:=0;
        dsCerrarVen.Close;
        dsCerrarVen.SelectSQL.Clear;
        dsCerrarVen.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM MGNADRO_PROMOCIONES A WHERE A.ID_SESION=:ID_SESION AND A.ESTATUS=''A'' ');
        dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
        dsCerrarVen.Open;
        lTotalArt:=dsCerrarVen.FieldByName('TARTICULOS').AsInteger;
        if (lTotalArt>0) and (lNoTarjeta<>'') then
        begin
          {$REGION 'artículos con promoción'}
          //verificar si esta seleccionada la opción de incluir el impuesto en los precios al registrar las ventas de punto de venta
          dsCerrarVen.Close;
          dsCerrarVen.SelectSQL.Clear;
          dsCerrarVen.SelectSQL.Add('SELECT A.VALOR FROM REGISTRY A WHERE A.NOMBRE=''IMPUESTO_INCLUIDO''');
          dsCerrarVen.Open;
          lConImpto :=  dsCerrarVen.FieldByName('VALOR').AsString;

          dsCerrarVen.Close;
          dsCerrarVen.SelectSQL.Clear;
          dsCerrarVen.SelectSQL.Add('SELECT A.SOLO_PENDIENTES FROM MGNADRO_SESIONES A WHERE A.ID_SESION = :ID_SESION ');
          dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
          dsCerrarVen.Open;
          lSoloPen := dsCerrarVen.FieldByName('SOLO_PENDIENTES').AsString;
          if lSoloPen='S' then
          begin
              dsCerrarVen.Close;
              dsCerrarVen.SelectSQL.Clear;
              dsCerrarVen.SelectSQL.Add('SELECT COUNT(*)TARTICULOS FROM MGNADRO_PROMOCIONES A WHERE A.ID_SESION=:ID_SESION AND A.ESTATUS = ''A'' AND AMASB=''S'' ');
              dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
              dsCerrarVen.Open;
              lTotalArt := lTotalArt + dsCerrarVen.FieldByName('TARTICULOS').AsInteger;
          end;

          //declarar longitud de Array 1 a N
          SetLength(lListaArticulos,lTotalArt);
          //inicializar el array 1..N
          I := 0;

          lPedido:=Pedido.Create;
          lPedido.NoTarjeta:=lNoTarjeta;
          lPedido.CedulaProfesionalMedico:='';
          lPedido.Usuario:=dsVMPendientes.FieldByName('NOMBRE_CAJEROVM').AsString;

          lMTotal:=TXSDecimal.Create;
          lMTotal.AsBcd:=dsVMPendientes.FieldByName('TOTAL_VM').AsBCD;
          lPedido.Total:=lMTotal;

          lPedido.NoTicket:=dsVMPendientes.FieldByName('FOLIO_VM').AsString;

          lRenglonListaArticulos:=PedidoArticulos.Create;

          dsObtenerArticulosVM1.Close;
          dsObtenerArticulosVM1.SelectSQL.Clear;

            if lSoloPen = 'S' then
            begin
              dsObtenerArticulosVM1.SelectSQL.Add('SELECT C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM1.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM1.SelectSQL.Add('FROM DOCTOS_PV_DET E');
              dsObtenerArticulosVM1.SelectSQL.Add('INNER JOIN MGNADRO_PROMOCIONES C ON (C.ARTICULO_ID=E.ARTICULO_ID AND C.ID_SESION=:ID_SESION AND C.ESTATUS=''A'' )');
              dsObtenerArticulosVM1.SelectSQL.Add('INNER JOIN ARTICULOS F ON (F.ARTICULO_ID=C.ARTICULO_ID)');
              dsObtenerArticulosVM1.SelectSQL.Add('WHERE E.DOCTO_PV_ID=:DOCTO_PV_ID');
              dsObtenerArticulosVM1.SelectSQL.Add('GROUP BY C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM1.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM1.SelectSQL.Add('ORDER BY C.ARTICULO_ID, C.ID_SESION, C.PIEZASGRATIS, C.PRECIOFIJO, C.MONTODESCUENTO, C.PORCENTAJEDESCUENTO,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.ESTATUS, C.PRECIO_UNITARIO, C.UNIDADES_VENDIDAS, C.PIEZASPENDIENTES, C.PRECIO_MSP, C.PIEZASPORCOMPRAR,');
              dsObtenerArticulosVM1.SelectSQL.Add('C.PIEZASPENDIENTESNADRO, C.PROMOCION, C.AMASB, C.ARTICULO_A_ID, C.AGREGADO_OV,');
              dsObtenerArticulosVM1.SelectSQL.Add('E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
            end
            else
            begin
              dsObtenerArticulosVM1.SelectSQL.Add('SELECT C.*, E.CLAVE_ARTICULO, E.UNIDADES, F.LINEA_ARTICULO_ID');
              dsObtenerArticulosVM1.SelectSQL.Add('FROM DOCTOS_PV_DET E');
              dsObtenerArticulosVM1.SelectSQL.Add('INNER JOIN MGNADRO_PROMOCIONES C ON (C.ARTICULO_ID=E.ARTICULO_ID AND C.ID_SESION=:ID_SESION AND C.ESTATUS=''A'' AND C.AMASB = ''N'')');
              dsObtenerArticulosVM1.SelectSQL.Add('INNER JOIN ARTICULOS F ON (F.ARTICULO_ID=C.ARTICULO_ID)');
              dsObtenerArticulosVM1.SelectSQL.Add('WHERE E.DOCTO_PV_ID=:DOCTO_PV_ID ');
              dsObtenerArticulosVM1.SelectSQL.Add('AND E.PRECIO_TOTAL_NETO>0');
            end;

          dsObtenerArticulosVM1.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
          dsObtenerArticulosVM1.ParamByName('DOCTO_PV_ID').AsInteger:=dsVMPendientes.FieldByName('DOCTO_PV_ID').AsInteger;
          dsObtenerArticulosVM1.Open;
          while not dsObtenerArticulosVM1.Eof do
          begin
              if dsObtenerArticulosVM1.FieldByName('AMASB').AsString='S' then
              begin
                {$REGION '//BUSCAR SU ARTICULO PADRE A'}
                dsObtenerArticulosAB1.Close;
                dsObtenerArticulosAB1.SelectSQL.Clear;
                dsObtenerArticulosAB1.SelectSQL.Add('SELECT A.CLAVE_ARTICULO ');
                dsObtenerArticulosAB1.SelectSQL.Add('FROM GET_CLAVE_ART(:ARTICULO_ID)A');
                dsObtenerArticulosAB1.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_A_ID').AsInteger;
                dsObtenerArticulosAB1.Open;
                if not dsObtenerArticulosAB1.IsEmpty then
                begin
                  //ARTICULO A
                  if lCPMP>0 then
                  begin
                    dsCerrarVen.Close;
                    dsCerrarVen.SelectSQL.Clear;
                    dsCerrarVen.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                    dsCerrarVen.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                    dsCerrarVen.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_A_ID').AsInteger;
                    dsCerrarVen.ParamByName('PRECIO_EMPRESA_ID').AsInteger:= lCPMP;
                    dsCerrarVen.Open;
                    if lConImpto='N' then
                      lPrecioMaximo:=dsCerrarVen.FieldByName('PRECIO').AsFloat
                    else
                    begin
                      spPrecioImpto.Close;
                      spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_A_ID').AsInteger;
                      spPrecioImpto.ParamByName('PRECIO').AsFloat:=dsCerrarVen.FieldByName('PRECIO').AsFloat;
                      spPrecioImpto.ExecProc;
                      lPrecioMaximo:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                    end;
                  end
                  else
                  begin
                    lPrecioMaximo:=0;
                  end;

                  if lCPVM>0 then
                  begin
                    dsCerrarVen.Close;
                    dsCerrarVen.SelectSQL.Clear;
                    dsCerrarVen.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                    dsCerrarVen.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                    dsCerrarVen.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_A_ID').AsInteger;
                    dsCerrarVen.ParamByName('PRECIO_EMPRESA_ID').AsInteger:=lCPVM;
                    dsCerrarVen.Open;
                    if lConImpto='N' then
                      lPrecioMostrador:=dsCerrarVen.FieldByName('PRECIO').AsFloat
                    else
                    begin
                      spPrecioImpto.Close;
                      spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_A_ID').AsInteger;
                      spPrecioImpto.ParamByName('PRECIO').AsFloat:=dsCerrarVen.FieldByName('PRECIO').AsFloat;
                      spPrecioImpto.ExecProc;
                      lPrecioMostrador:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                    end;
                  end
                  else
                  begin
                    lPrecioMostrador:=0;
                  end; 

                  if lPrecioMaximo=0 then
                    lPrecioMaximo:=lPrecioMostrador;

                  lPMP:=TXSDecimal.Create;
                  lPMP.AsBcd:=DoubleToBcd(lPrecioMaximo);

                  lPM:=TXSDecimal.Create;
                  lPM.AsBcd:=DoubleToBcd(lPrecioMostrador);
                     
                  lPFijo:=TXSDecimal.Create;
                  lPFijo.AsBcd:=DoubleToBcd(0);

                  lPDescto:=TXSDecimal.Create;
                  lPDescto.AsBcd:=DoubleToBcd(0);

                  lMDesc:=TXSDecimal.Create;
                  lMDesc.AsBcd:=DoubleToBcd(0);

                  lPzsGratis:=0;

                  lIva:=TXSDecimal.Create;
                  lIva.AsBcd:=DoubleToBcd(0);

                  UnidadesPagadas:=0;

                  lListaArticulos[I]:=PedidoArticulos.Create;
                  lListaArticulos[I].Sku:=dsObtenerArticulosAB1.FieldByName('CLAVE_ARTICULO').AsString;
                  lListaArticulos[I].Precio:=lPMP;
                  lListaArticulos[I].PrecioPOS:=lPM;
                  lListaArticulos[I].PrecioFijo:=lPFijo;
                  lListaArticulos[I].PorcentajeDescuento:=lPDescto;
                  lListaArticulos[I].MontoDescuento:=lMDesc;
                  lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
                  lListaArticulos[I].PiezasGratis:=lPzsGratis;
                  lListaArticulos[I].IVA:=lIva;
                  lListaArticulos[I].PorcentajeIVA:=0;

                  I:=I+1;
                end;
                {$ENDREGION}
              end;

            lEstatus:=dsObtenerArticulosVM1.FieldByName('ESTATUS').AsString;
            if dsObtenerArticulosVM1.FieldByName('AMASB').AsString='S' then
            begin
              lPrecioMaximo := 0.01;
              lPrecioMostrador := 0.01;
            end
            else
            begin
              {$REGION 'ARTICULOS NORMALES'}
              if lCPMP>0 then
              begin
                dsCerrarVen.Close;
                dsCerrarVen.SelectSQL.Clear;
                dsCerrarVen.SelectSQL.Add('SELECT A.PRECIO FROM PRECIOS_ARTICULOS A');
                dsCerrarVen.SelectSQL.Add('WHERE A.ARTICULO_ID=:ARTICULO_ID AND A.PRECIO_EMPRESA_ID=:PRECIO_EMPRESA_ID');
                dsCerrarVen.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_ID').AsInteger;
                dsCerrarVen.ParamByName('PRECIO_EMPRESA_ID').AsInteger:=lCPMP;
                dsCerrarVen.Open;
                if lConImpto='N' then
                  lPrecioMaximo:=dsCerrarVen.FieldByName('PRECIO').AsFloat
                else
                begin
                  spPrecioImpto.Close;
                  spPrecioImpto.ParamByName('ARTICULO_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_ID').AsInteger;
                  spPrecioImpto.ParamByName('PRECIO').AsFloat:=dsCerrarVen.FieldByName('PRECIO').AsFloat;
                  spPrecioImpto.ExecProc;
                  lPrecioMaximo:=spPrecioImpto.FieldByName('PRECIO').AsFloat;
                end;
              end
              else
              begin
                lPrecioMaximo:=0;
              end;

              lPrecioMostrador := dsObtenerArticulosVM1.FieldByName('PRECIO_MSP').AsFloat;
              {$ENDREGION}
            end;

            lPMP:=TXSDecimal.Create;
            lPMP.AsBcd:=DoubleToBcd(lPrecioMaximo);

            lPM:=TXSDecimal.Create;
            lPM.AsBcd:=DoubleToBcd(lPrecioMostrador);

            lPFijo:=TXSDecimal.Create;
            lPDescto:=TXSDecimal.Create;
            lMDesc:=TXSDecimal.Create;

             if lEstatus='A' then
            begin
              lPFijo.AsBcd:=dsObtenerArticulosVM1.FieldByName('PRECIOFIJO').AsBCD;
              lPDescto.AsBcd:=dsObtenerArticulosVM1.FieldByName('PORCENTAJEDESCUENTO').AsBCD;
              lMDesc.AsBcd:=dsObtenerArticulosVM1.FieldByName('MONTODESCUENTO').AsBCD;
              lPzsGratis:=dsObtenerArticulosVM1.FieldByName('PIEZASGRATIS').AsInteger;
            end
            else
            begin
              lPFijo.AsBcd:=DoubleToBcd(0);
              lPDescto.AsBcd:=DoubleToBcd(0);
              lMDesc.AsBcd:=DoubleToBcd(0);
              lPzsGratis:=0;
            end;  

            if lSoloPen = 'S' then
              UnidadesPagadas:=0
            else
              UnidadesPagadas:=dsObtenerArticulosVM1.FieldByName('UNIDADES').AsInteger;

            lIva:=TXSDecimal.Create;
            lIva.AsBcd:=DoubleToBcd(0);

            lListaArticulos[I]:=PedidoArticulos.Create;
            lListaArticulos[I].Sku:=dsObtenerArticulosVM1.FieldByName('CLAVE_ARTICULO').AsString;
            lListaArticulos[I].Precio:=lPMP;
            lListaArticulos[I].PrecioPOS:=lPM;
            lListaArticulos[I].PrecioFijo:=lPFijo;
            lListaArticulos[I].PorcentajeDescuento:=lPDescto;
            lListaArticulos[I].MontoDescuento:=lMDesc;
            lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
            lListaArticulos[I].PiezasGratis:=lPzsGratis;
            lListaArticulos[I].IVA:=lIva;
            lListaArticulos[I].PorcentajeIVA:=0;
            I:=I+1;

            //Buscar que este artículo tengo pzas grastis pendientes por falta de existencia
              dsObtenerArticulosAB1.Close;
              dsObtenerArticulosAB1.SelectSQL.Clear;
              dsObtenerArticulosAB1.SelectSQL.Add('SELECT FIRST 1 C.ARTICULO_ID, C.PRECIOFIJO, C.PORCENTAJEDESCUENTO, C.MONTODESCUENTO, C.PIEZASGRATIS, D.CLAVE_ARTICULO');
              dsObtenerArticulosAB1.SelectSQL.Add('FROM MGNADRO_PROMOCIONES C');
              dsObtenerArticulosAB1.SelectSQL.Add('LEFT JOIN GET_CLAVE_ART(C.ARTICULO_ID)D ON (D.ARTICULO_ID = C.ARTICULO_ID)');
              dsObtenerArticulosAB1.SelectSQL.Add('WHERE C.ID_SESION = :ID_SESION');
              dsObtenerArticulosAB1.SelectSQL.Add('AND C.ESTATUS = ''A'' ');
              dsObtenerArticulosAB1.SelectSQL.Add('AND C.AMASB = ''S'' ');
              dsObtenerArticulosAB1.SelectSQL.Add('AND C.ARTICULO_A_ID = :ARTICULO_A_ID');
              dsObtenerArticulosAB1.ParamByName('ARTICULO_A_ID').AsInteger:=dsObtenerArticulosVM1.FieldByName('ARTICULO_ID').AsInteger;
              dsObtenerArticulosAB1.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
              dsObtenerArticulosAB1.Open;
              if not dsObtenerArticulosAB1.IsEmpty then
              begin
                lPMP:=TXSDecimal.Create;
                lPMP.AsBcd:=DoubleToBcd(0.01);

                lPM:=TXSDecimal.Create;
                lPM.AsBcd:=DoubleToBcd(0.01);

                lPFijo:=TXSDecimal.Create;
                lPFijo.AsBcd:=dsObtenerArticulosAB1.FieldByName('PRECIOFIJO').AsBCD;

                lPDescto:=TXSDecimal.Create;
                lPDescto.AsBcd:=dsObtenerArticulosAB1.FieldByName('PORCENTAJEDESCUENTO').AsBCD;

                lMDesc:=TXSDecimal.Create;
                lMDesc.AsBcd:=dsObtenerArticulosAB1.FieldByName('MONTODESCUENTO').AsBCD;

                lPzsGratis:=dsObtenerArticulosAB1.FieldByName('PIEZASGRATIS').AsInteger;

                lIva:=TXSDecimal.Create;
                lIva.AsBcd:=DoubleToBcd(0);

                UnidadesPagadas:=0;

                lListaArticulos[I]:=PedidoArticulos.Create;
                lListaArticulos[I].Sku:=dsObtenerArticulosAB1.FieldByName('CLAVE_ARTICULO').AsString;
                lListaArticulos[I].Precio:=lPMP;
                lListaArticulos[I].PrecioPOS:=lPM;
                lListaArticulos[I].PrecioFijo:=lPFijo;
                lListaArticulos[I].PorcentajeDescuento:=lPDescto;
                lListaArticulos[I].MontoDescuento:=lMDesc;
                lListaArticulos[I].PiezasPagadas:=UnidadesPagadas;
                lListaArticulos[I].PiezasGratis:=lPzsGratis;
                lListaArticulos[I].IVA:=lIva;
                lListaArticulos[I].PorcentajeIVA:=0;

                I:=I+1;
              end; 

            dsObtenerArticulosVM1.Next;
          end;

          lMensajeError:='';
          //Invocar WS
          lRespuestaSales:=GetWSCirculodelaSaludSoap.Create_Sales_Folio_Receta(lSesion,lPedido,lListaArticulos,'');
          lHuboError:=lRespuestaSales.HuboError;
          if lHuboError then
          begin
            lMensajeError:=lRespuestaSales.MensajeError;
            lPosicion:=0;
            lPosicion:= pos('La sesión se cerró con el id de venta:',lMensajeError);
            if lPosicion=0 then
            begin
              Memo2.Lines.Add('Error al cerrar venta mostrador: '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+Chr(10)+' '+lMensajeError);
              mmError1.Lines.Add('Error al cerrar venta mostrador: '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+Chr(10)+' '+lMensajeError);
            end
            else
            begin
              mmError1.Lines.Add(lMensajeError);
              lFolioPedido:='';
              lFolioPedidoF:='';
              lFolioPedido:=StringReplace(lMensajeError, 'La sesión se cerró con el id de venta:', '',
                          [rfReplaceAll, rfIgnoreCase]);
              lFolioPedido:=Trim(lFolioPedido);
              lPosicion:=Length(lFolioPedido);

              for I := 0 to lPosicion - 1 do
              begin
                if lFolioPedido[I]<>' ' then
                  lFolioPedidoF:=lFolioPedidoF+lFolioPedido[I]
                else
                  Break;
              end; 
            end;
          end
          else
          begin
            lResPedido:=lRespuestaSales.Pedido;
            dsCerrarVen.Close;
            dsCerrarVen.SelectSQL.Clear;
            dsCerrarVen.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET ESTATUS = :ESTATUS, FOLIO_PEDIDO = :FOLIO_PEDIDO, INTENTOS_CIERRE = :INTENTOS_CIERRE');
            dsCerrarVen.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION);');
            dsCerrarVen.ParamByName('ESTATUS').AsString:='T'; //Terminada
            dsCerrarVen.ParamByName('FOLIO_PEDIDO').AsString:=lResPedido;
            dsCerrarVen.ParamByName('INTENTOS_CIERRE').AsInteger:=IntentosCierre;
            dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
            dsCerrarVen.Open;
            Memo2.Lines.Add('El cierre de venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service círculo de la salud fue exitosa. Folio de respuesta: '+lResPedido);
            mmBien1.Lines.Add('El cierre de venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service círculo de la salud fue exitosa. Folio de respuesta: '+lResPedido);
          end;
        {$ENDREGION}
        end;
    end;
    end;
    finally
      {for I := 0 to lTotalArt - 1 do
      begin
        lListaArticulos[I].Free;
      end;}
      lIva.Free;
      lMDesc.Free;
      lPDescto.Free;
      lPFijo.Free;
      lPM.Free;
      lPMP.Free;
      lRenglonListaArticulos.Free;
      lMTotal.Free;
    end;

    if mmError1.Text<>'' then
    begin
      if lFolioPedidoF<>'' then
      begin
        lFolioPedidoF:=Trim(lFolioPedidoF);
        dsCerrarVen.Close;
        dsCerrarVen.SelectSQL.Clear;
        dsCerrarVen.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET ESTATUS = :ESTATUS, FOLIO_PEDIDO = :FOLIO_PEDIDO, INTENTOS_CIERRE = :INTENTOS_CIERRE');
        dsCerrarVen.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION);');
        dsCerrarVen.ParamByName('ESTATUS').AsString:='T'; //Terminada
        dsCerrarVen.ParamByName('FOLIO_PEDIDO').AsString:=lFolioPedidoF;
        dsCerrarVen.ParamByName('INTENTOS_CIERRE').AsInteger:=IntentosCierre;
        dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
        dsCerrarVen.Open;
        Memo2.Lines.Add('El cierre de venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service círculo de la salud ORO fue exitosa. Folio de respuesta: '+lFolioPedidoF);
        mmBien1.Lines.Add('El cierre de venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service círculo de la salud ORO fue exitosa. Folio de respuesta: '+lFolioPedidoF);
      end
      else
      begin
      dsCerrarVen.Close;
      dsCerrarVen.SelectSQL.Clear;
      dsCerrarVen.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET INTENTOS_CIERRE = :INTENTOS_CIERRE, LOG_ERRORES = :LOG_ERRORES');
      dsCerrarVen.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION);');
      dsCerrarVen.ParamByName('INTENTOS_CIERRE').AsInteger:=IntentosCierre;
      dsCerrarVen.ParamByName('LOG_ERRORES').AsString:='Error al cerrar venta mostrador: '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+'Intento '+IntToStr(IntentosCierre)+'.'+Chr(10)+mmError1.Text;
      dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
      dsCerrarVen.Open;
      if IntentosCierre=5 then
      begin
        mmError2.Lines.Add('Los 5 intentos de cierre terminaron y no fue posible cerrar venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service Círculo de la salud ORO.'+#13+'Error: '+mmError1.Text);
        Memo2.Lines.Add('Los 5 intentos de cierre terminaron y no fue posible cerrar venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' con el web service Círculo de la salud ORO.'+#13+'Error: '+mmError1.Text);
      end;
      end;
    end;
    {$ENDREGION}
    end
    else if dsVMPendientes.FieldByName('ESTATUS').AsString = 'C' then
    begin
      //Actualizo estatus
      dsCerrarVen.Close;
      dsCerrarVen.SelectSQL.Clear;
      dsCerrarVen.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET ESTATUS = :ESTATUS,  INTENTOS_CIERRE = :INTENTOS_CIERRE');
      dsCerrarVen.SelectSQL.Add('WHERE (ID_SESION = :ID_SESION);');
      dsCerrarVen.ParamByName('ESTATUS').AsString:='C'; //Cancelada
      dsCerrarVen.ParamByName('INTENTOS_CIERRE').AsInteger:=IntentosCierre;
      dsCerrarVen.ParamByName('ID_SESION').AsInteger:=dsVMPendientes.FieldByName('ID_SESION').AsInteger;
      dsCerrarVen.Open;
      Memo2.Lines.Add('La venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' se canceló correctamente.');
      mmBien1.Lines.Add('La venta mostrador '+dsVMPendientes.FieldByName('FOLIO_VM').AsString+' se canceló correctamente.');
    end;

    dsVMPendientes.Next;
  end;

  if trCerrarVen.InTransaction then
    trCerrarVen.Commit;
  Memo2.Lines.Add('El proceso de cierre termino correctamente.');

  if mmBien1.Text<>'' then
  begin
    MessageDlg(mmBien1.Text, mtInformation, [mbOk], 0);
  end;

  if mmError2.Text<>'' then
  begin
    MessageDlg(mmError2.Text, mtError, [mbOk], 0);
  end;

  //22/11/2016 LIZ Application.Minimize;
  end;
end
except on e:exception do
begin
  if trCerrarVen.InTransaction then trCerrarVen.Rollback;
    trCerrarVen.StartTransaction;

  if pos('Error de servidor', e.Message)<>0 then
  begin
    FConectado := 'N';
    Memo2.Lines.Add('Error al cerrar ventas pendientes.'+e.Message);
  end
  else
  begin
    Memo2.Lines.Add('Error al cerrar ventas pendientes.'+e.Message);
  end;
end;
end;
end;

procedure TForm1.GuardarDatosVM(lFolioVM, Estatus:String;lAlmacenId,lCajeroId,lSesionId:Integer;lTotalVM:Double);
begin
try
begin
  if trWrite.InTransaction then
    trWrite.Rollback;

  trWrite.StartTransaction;

  dsWrite.Close;
  dsWrite.SelectSQL.Clear;
  dsWrite.SelectSQL.Add('UPDATE MGNADRO_SESIONES SET FOLIO_VM = :FOLIO_VM, ESTATUS = :ESTATUS,');
  dsWrite.SelectSQL.Add('ALMACEN_ID = :ALMACEN_ID, CAJERO_ID = :CAJERO_ID, TOTAL_VM = :TOTAL_VM, INTENTOS_CIERRE = 0 WHERE (ID_SESION = :ID_SESION);');
  dsWrite.ParamByName('FOLIO_VM').AsString:=lFolioVM;
  dsWrite.ParamByName('ESTATUS').AsString:=Estatus;
  dsWrite.ParamByName('ALMACEN_ID').AsInteger:=lAlmacenId;
  dsWrite.ParamByName('CAJERO_ID').AsInteger:=lCajeroId;
  dsWrite.ParamByName('TOTAL_VM').AsFloat:=lTotalVM;
  dsWrite.ParamByName('ID_SESION').AsInteger:=lSesionId;
  dsWrite.Open;

  if trWrite.InTransaction then
    trWrite.Commit;
end;
except on e:exception do
begin
  if trWrite.InTransaction then trWrite.Rollback;
    trWrite.StartTransaction;

  Memo1.Lines.Add('Error al registrar datos de venta mostrador. ' + Chr(13) + e.Message);
end;
end;
end;

function TForm1.ConsultarTarjeta(ASesion, ANoTarjeta:String; var Amembresia, Aapellidopaterno, Aapellidomaterno, Anombre, Acodigopostal, Asexo, Atelefono, Aemail, AMensajeError:String; Afechanacimiento:TXSDateTime; var AFecha:TDateTime):Boolean;
var lRespuesta:InfoPaciente;
lHuboError:Boolean;
begin
try
begin
    try
      lRespuesta:=InfoPaciente.Create;
      lRespuesta:=GetWSCirculodelaSaludSoap.GetInfoPatient(ASesion, ANoTarjeta);
      lHuboError:=lRespuesta.HuboError;
      if lHuboError then
      begin
        AMensajeError:=lRespuesta.MensajeError;
        Result := False;
      end
      else
      begin
        AMensajeError := '';
        Amembresia := lRespuesta.membresia;
        Aapellidopaterno := lRespuesta.apellidopaterno;
        Aapellidomaterno := lRespuesta.apellidomaterno;
        Anombre := lRespuesta.nombre;
        Acodigopostal := lRespuesta.codigopostal;
        Asexo := lRespuesta.sexo;
        
        Afechanacimiento.Create;
        Afechanacimiento := lRespuesta.fechanacimiento;
        AFecha := lRespuesta.fechanacimiento.AsUTCDateTime;

        Atelefono := lRespuesta.telefono;
        Aemail := lRespuesta.email;

        Result := True;
      end;
    finally
      lRespuesta.Free;
    end;

end;
except on e:exception do
begin
  Result := False;
  AMensajeError := 'Error al consultar promociones de artículo. ' + Chr(13) + e.Message;
end;
end;
end;

function TForm1.ActTarjeta(var ASesion, ANombreCajero, ANoTarjeta, ANombre, AAPaterno, AAMaterno, ATelefono, AEmail, ASexo, ACP, AMensajeError:String; AFNacimiento:String):Boolean;
var lRespuesta:ResponseUpdatePatient;
lActualizar:RequestUpdatePatient;
lHuboError:Boolean;
begin
try
begin
    try
      lActualizar:=RequestUpdatePatient.Create;
      lActualizar.Membresia := ANoTarjeta;
      lActualizar.ApellidoPaterno := AAPaterno;
      lActualizar.ApellidoMaterno := AAMaterno;
      lActualizar.Nombre := ANombre;
      lActualizar.Direccion := '';
      lActualizar.Colonia := '';
      lActualizar.Ciudad := '';
      lActualizar.Estado := '';
      lActualizar.Rfc := '';
      lActualizar.Curp := '';
      lActualizar.CodigoPostal := ACP;
      lActualizar.Sexo := ASexo;
      lActualizar.EstadoCivil := '';
      lActualizar.FechaNacimiento := AFNacimiento;
      lActualizar.Telefono := ATelefono;
      lActualizar.Celular := '';
      lActualizar.Email := AEmail;

      lRespuesta:=ResponseUpdatePatient.Create;
      lRespuesta:=GetWSCirculodelaSaludSoap.UpdatePatient(ASesion, lActualizar);
      lHuboError:=lRespuesta.HuboError;
      if lHuboError then
      begin
        AMensajeError:=lRespuesta.MensajeError;
        Result := False;
      end
      else
      begin
        AMensajeError:='';
        Result := lRespuesta.Actualizado;
      end;
    finally
      lRespuesta.Free;
      lActualizar.Free;
    end;

end;
except on e:exception do
begin
  Result := False;
  AMensajeError := 'Error al consultar promociones de artículo. ' + Chr(13) + e.Message;
end;
end;
end;

function TForm1.PromosArtN(var AMensajeError:String; var AMensajeRep:String; SKU:String):Boolean;
var lRespuestaPromos:GetPromocionCurrentResponse;
lHuboError:Boolean;
lSesion, lResp:String;
begin
try
begin
  lSesion := '';

  {$REGION 'Web Service Conectado'}
  if IniciarSesion(lSesion) then
  begin
    AMensajeRep:='';
    AMensajeError:='';
    try
      lRespuestaPromos:=GetPromocionCurrentResponse.Create;
      lRespuestaPromos:=GetWSCirculodelaSaludSoap.GetInfoPromocionProduct(lSesion, SKU);
      lHuboError:=lRespuestaPromos.HuboError;
      if lHuboError then
      begin
        AMensajeError:=lRespuestaPromos.ErrorMessage;
        Result := False;
      end
      else
      begin
        try
          begin
            mmPromoArt.Lines.Clear;
            lResp := '';
            lResp := lRespuestaPromos.Promocion.NombrePromocion;
            if lResp<>'' then
              mmPromoArt.Lines.Add('Promoción: '+lResp);
            lResp := '';
            lResp := lRespuestaPromos.Promocion.Tipo_promocion;
            if lResp<>'' then
              mmPromoArt.Lines.Add('Tipo de promoción: '+lResp);
            lResp := '';
            lResp := lRespuestaPromos.Promocion.Vigencia;
            if lResp<>'' then
              mmPromoArt.Lines.Add('Vigencia: '+lResp);
            lResp := '';
            lResp := lRespuestaPromos.Promocion.Laboratorio;
            if lResp<>'' then
              mmPromoArt.Lines.Add('Laboratorio: '+lResp);

             AMensajeRep := mmPromoArt.Text;
          end;
        finally
        begin
          if AMensajeRep<>'' then
            Result := True
          else if AMensajeRep='' then
          begin
            Result := False;
            AMensajeError := 'Promoción no encontrada.';
          end;
        end;
        end;
      end;
    finally
      lRespuestaPromos.Free;
    end;
  end
  else
  begin
    Result := False;
    AMensajeError:='La sesión con el servicio web NO esta disponible.'+Chr(13)+'Error: '+lSesion;
  end;
  {$ENDREGION}
end;
except on e:exception do
begin
  Result := False;
  AMensajeError:='Error al consultar promociones de artículo. ' + Chr(13) + e.Message;
end;
end;
end;

function TForm1.PromosEspeciales(var AMensajeError:String; PROCESO_ID:Integer):Boolean;
var lRespuestaPromos:GetPromocionesResponse;
lRespuestaPromos1:ArrayOfPromocion;
lBuscarPromo:GetPromocionesRequest;
lHuboError:Boolean;
I:Integer;
begin
try
begin
  if trPromos.InTransaction then
    trPromos.Rollback;

  trPromos.StartTransaction;

  lBuscarPromo := GetPromocionesRequest.Create;
  lBuscarPromo.Usuario := FUsuario;
  lBuscarPromo.Password := FPassword;
  lBuscarPromo.CodigoCadena := FIdCadena;

  lRespuestaPromos:=GetPromocionesResponse.Create;
  lRespuestaPromos:=GetWSCirculodelaSaludSoap.GetPromocionesEspeciales(lBuscarPromo);
  lHuboError:=lRespuestaPromos.HuboError;
  if lHuboError then
  begin
    AMensajeError:=lRespuestaPromos.ErrorMessage;
    Result := False;
  end
  else
  begin
    AMensajeError:='';
    lRespuestaPromos1:=lRespuestaPromos.Promociones;
    for I := 0 to Length(lRespuestaPromos1) - 1 do
    begin
      spCatalogoId.ExecProc;

      dsPromos.Close;
      dsPromos.SelectSQL.Clear;
      dsPromos.SelectSQL.Add('INSERT INTO MGNADRO_PROMOCIONES_ESPECIALES (ID_PROMO_ESPECIAL, SKU, PRESENTACION, PROMOCION, FECHA_FIN_PROMO, TIPO_PROMO, POLITICAS, PROCESO_ID)');
      dsPromos.SelectSQL.Add('VALUES (:ID_PROMO_ESPECIAL, :SKU, :PRESENTACION, :PROMOCION, :FECHA_FIN_PROMO, :TIPO_PROMO, :POLITICAS, :PROCESO_ID);');
      dsPromos.ParamByName('ID_PROMO_ESPECIAL').AsInteger := spCatalogoId.FieldByName('CATALOGO_ID').AsInteger;
      dsPromos.ParamByName('SKU').AsString := lRespuestaPromos1[I].Sku;
      dsPromos.ParamByName('PRESENTACION').AsString := lRespuestaPromos1[I].Presentacion;
      dsPromos.ParamByName('PROMOCION').AsString := lRespuestaPromos1[I].NombrePromocion;
      dsPromos.ParamByName('FECHA_FIN_PROMO').AsString := lRespuestaPromos1[I].FechaFin;
      dsPromos.ParamByName('TIPO_PROMO').AsString := lRespuestaPromos1[I].TipoPromocion;
      dsPromos.ParamByName('POLITICAS').AsString := lRespuestaPromos1[I].Politicas;
      dsPromos.ParamByName('PROCESO_ID').AsInteger := PROCESO_ID;
      dsPromos.Open;

    end;

    if trPromos.InTransaction then
    trPromos.Commit;

     Result := True;
  end;
end;
except on e:exception do
begin
  lRespuestaPromos.Free;
  lBuscarPromo.Free;
  Result := False;

  AMensajeError := 'Error al consultar promociones especiales. ' + Chr(13) + e.Message;
              
  if trPromos.InTransaction then trPromos.Rollback;
    trPromos.StartTransaction; 
end;
end;
end;



end.
