unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, uniGUITypes, uniGUIAbstractClasses,
  uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniEdit, uniGUIBaseClasses, uniButton, uniBitBtn, uniMultiItem,
  uniComboBox, uniLabel,uPhoneNumberCheck, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, Data.DB,
  FireDAC.Comp.DataSet, FireDAC.Comp.Client,uSendEmail,

  //added laster

  System.Types,

  //myUnits

  uGenerateUniqueCode, Vcl.ExtCtrls, uniTimer,smsc_api_PS_Gringo, uniCheckBox;

type
  TMainForm = class(TUniForm)
    bGetSMSCode: TUniBitBtn;
    ePhoneNumber: TUniEdit;
    cbCountry: TUniComboBox;
    eCode: TUniEdit;
    lPhoneExample: TUniLabel;
    lTitle: TUniLabel;
    bSendCode: TUniBitBtn;
    qStartSession: TFDQuery;
    qLastInsertID: TFDQuery;
    qSelectCode: TFDQuery;
    qInsertPhoneNumber: TFDQuery;
    qFinishSession: TFDQuery;
    qDeleteCode: TFDQuery;
    tUniEnableSendSMSButton: TUniTimer;
    qSelectNULLSessions: TFDQuery;
    qDeleteNULLSessions: TFDQuery;
    tTotal: TUniTimer;
    lCountDown: TUniLabel;
    eName: TUniEdit;
    cbFreeConsultation: TUniCheckBox;
    procedure UniFormCreate(Sender: TObject);
    procedure bGetSMSCodeClick(Sender: TObject);
    procedure cbCountrySelect(Sender: TObject);
    procedure eCodeClick(Sender: TObject);
    procedure ePhoneNumberClick(Sender: TObject);
    procedure UniFormDestroy(Sender: TObject);
    procedure bSendCodeClick(Sender: TObject);
    procedure tDisableEnableSendSMSButtonTimer(Sender: TObject);
    procedure tUniEnableSendSMSButtonEventHandler(Sender: TComponent; EventName: string; Params: TUniStrings);
    procedure tUniEnableSendSMSButtonTimer(Sender: TObject);
    procedure tTotalTimer(Sender: TObject);
    procedure eNameClick(Sender: TObject);
  private
    { Private declarations }

    FPhoneNumberCheck:TPhoneNumberCheck;

    FGenerateUniqueCode:TGenerateUniqueCode;
    FSendEmail:TSendEmail;

    FLastInsertID:integer;
    FResultPhoneNumber:string;

    FCurrentAttemptsGetSMSNumber:integer;
    FCurrentAttemptsSendCodeNumber:integer;

    FCountDown:integer;


    Fsms: SMSC;
    FResultSDA: TStringDynArray;


    procedure CenterElements;
    procedure FinishSessionAndDeleteCodeFromDB;
    procedure ClearNullSessions;

  public
    { Public declarations }



  end;

function MainForm: TMainForm;

   const MaxAttemptsGetSMSNumber=3;
   const MaxAttemptsSendCodeNumber=3;
   const MaxSessionTimeInMinutes=20; // min;

implementation

{$R *.dfm}



uses
  uniGUIVars, MainModule, uniGUIApplication, ServerModule, uDBConnection;

function MainForm: TMainForm;
begin
  Result := TMainForm(UniMainModule.GetFormInstance(TMainForm));
end;

{ TMainForm }

procedure TMainForm.bGetSMSCodeClick(Sender: TObject);

var ResultPhoneNumber:string;
    ErrorMessage:string;
    DateTime: TDateTime;
    DateTimeForMySQL:string;
    code:integer;
    LastInsertID:integer;


    i: Integer;


begin


UniMainModule.DBConnection.Connect2;

// UniMainModule.DBConnection.FDConnection.Connected then
//ShowMessage('Ok') else ShowMessage('not Ok');



ClearNullSessions;

if (ePhoneNumber.Text='') or (ePhoneNumber.Text='Введите номер телефона...') then
 begin
 ShowMessage('Введите номер телефона');
 Exit;
 end;



if (eName.Text='') or (eName.Text='Ваше имя...') then
 begin
 ShowMessage('Введите ваше имя');
 Exit;
 end;


FCurrentAttemptsSendCodeNumber:=0;
FCountDown:=30;

if FLastInsertID<>0 then
 begin

 qDeleteCode.Params.ParamValues['id'] := FLastInsertID;
 qDeleteCode.ExecSQL;

 end;



Inc(FCurrentAttemptsGetSMSNumber);

if FCurrentAttemptsGetSMSNumber>MaxAttemptsGetSMSNumber then

  begin
  ShowMessage('Вы превысили максимальное число попыток (3). Попробуйте позже');
  bGetSMSCode.Enabled:=false;
  Exit;
  end;

if FPhoneNumberCheck.IsPhoneNumberOK2(
Trim(ePhoneNumber.Text),
cbCountry.ItemIndex,
FResultPhoneNumber,
ErrorMessage
) then

begin



// Starting session
DateTime:=Now;
DateTimeForMySQL:=FormatDateTime('yyyy-mm-dd hh:mm:ss',DateTime);


qStartSession.Params.ParamValues['DateTime']:=DateTimeForMySQL;
qStartSession.ExecSQL;


qLastInsertID.Connection:=UNiMainModule.DBConnection.FDConnection;
qLastInsertID.Open();
FLastInsertID:=qLastInsertID.FieldByName('newkey').AsInteger;
qLastInsertID.Close;

//Generating new code
FGenerateUniqueCode.SessionID:=FLastInsertID;
code:=FGenerateUniqueCode.GenerateUniqueCode;

bSendCode.Show;


//Sending new code by SMS

Fsms := SMSC.Create;
FResultSDA := Fsms.send_sms(FResultPhoneNumber,
'Код авторизации в системе тестирования: '+code.ToString,0);
FreeAndNil(Fsms);


tUniEnableSendSMSButton.Enabled:=true;
eCode.Show;
bGetSMSCode.Enabled:=false;


end

 else ShowMessage(ErrorMessage);  // eCode.Text:=' not OK '+ErrorMessage;



end;

procedure TMainForm.bSendCodeClick(Sender: TObject);
var code:integer;
    FreeConsultationMessage:string;
begin

Inc(FCurrentAttemptsSendCodeNumber);

if FCurrentAttemptsSendCodeNumber>
   MaxAttemptsSendCodeNumber

then
  begin
  ShowMessage('Превышено максимальное число попыток (3). Попробуйте позже');
  Exit;
  end;


//getting code

qSelectCode.Params.ParamValues['Sessions_id']:=FLastInsertID;
qSelectCode.Open();
code:=qSelectCode.FieldByName('Code').AsInteger;
qSelectCode.Close;

if code.ToString=trim(eCode.Text) then

 begin


 ShowMessage('Все верно, переходим на сайт тестирования');

 // Write phone to DB

 qInsertPhoneNumber.Params.ParamValues['PhoneNumber']:=FResultPhoneNumber;
 qInsertPhoneNumber.Params.ParamValues['Sessions_id']:=FLastInsertID;
 qInsertPhoneNumber.ExecSQL;


 FinishSessionAndDeleteCodeFromDB;



  // Redirect
  UniSession.UrlRedirect(
  'http://system-roboxtest.ru/pupilOnline/index?hash=7bb0622e1c9ede5bf0544dccff5d0c4e&t=1&test=483ac79dd07632718577aa7e3c4f0d52');


 if cbFreeConsultation.Checked then   FreeConsultationMessage:='true' else
   FreeConsultationMessage:='false';

  //Send Email to Admin
  //ShowMessage('Email to admin');
  FSendEmail.SendEmail('Новый пользователь демо-режима http://system-roboxtest.ru',
  'Подтвержденный телефон пользователя '+FResultPhoneNumber +'<br>'+#13#10+
  'Имя пользователя '+eName.Text+'<br>'+#13#10+
  'id '+FResultSDA[0]+'<br>'+#13#10+
  'количество смс '+FResultSDA[1]+'<br>'+#13#10+
  'стоимость '+FResultSDA[2]+'<br>'+#13#10+
  'баланс '+FResultSDA[3]+'<br>'+#13#10+
  'Бесплатная консультация '+FreeConsultationMessage
  ,
  'panteleevstas@gmail.com');

 end else

 ShowMessage('Код неверный');




end;

procedure TMainForm.cbCountrySelect(Sender: TObject);
begin
case cbCountry.ItemIndex of

  0:begin
  lPhoneExample.Text:='Пример: +79163080631'; // 79163080631
  ePhoneNumber.Text:='+7';  //Russia

  //2:
  end;

  1:begin
  lPhoneExample.Text:='Пример: +38(073) 723 23 23';
  ePhoneNumber.Text:='+38';  // Ukraine
  end;


  2:begin
  lPhoneExample.Text:='Пример: +77710009998';
  ePhoneNumber.Text:='+7';  // Kazakhstan
  end;

  3:begin
    cbCountry.ItemIndex:=0;
    cbCountry.OnSelect(UniApplication);
    ShowMessage('Отправка СМС в другие страны не поддерживается. Свяжитесь со мной panteleevstas@gmail.com');
  end;

end;


end;

procedure TMainForm.CenterElements;
begin


bGetSMSCode.Left:=trunc(Self.Width/2-bGetSMSCode.Width/2);
ePhoneNumber.Left:=trunc(Self.Width/2-ePhoneNumber.Width/2);
eCode.Left:=trunc(Self.Width/2-eCode.Width/2);
cbCountry.Left:=trunc(Self.Width/2-eCode.Width/2);
lPhoneExample.Left:=trunc(Self.Width/2-lPhoneExample.Width/2);
lTitle.Left:=trunc(Self.Width/2-lTitle.Width/2);
bSendCode.Left:=trunc(Self.Width/2-bSendCode.Width/2);
eName.Left:=trunc(Self.Width/2-eName.Width/2);

cbFreeConsultation.Left:=
trunc(Self.Width/2-cbFreeConsultation.Width/2);

lCountDown.Left:=bGetSMSCode.Left+bGetSMSCode.Width+10;

end;

procedure TMainForm.ClearNullSessions;
var
  id: integer;
  SL:TStringList;
  i: Integer;
  DateTimeInDB:TDateTime;
  DateTimeNow:TDateTime;
  ResultDateTime:TDateTime;
  H,M,S,MS:Word;



begin

SL:=TStringList.Create;
DateTimeNow:=Now;

//
with qSelectNULLSessions do begin

Open();

 while not EOF do begin

  //Adding old NULL Sessions
  DateTimeInDB:=FieldByName('TimeStart').AsDateTime;
  ResultDateTime:=DateTimeNow-DateTimeInDB;
  DecodeTime(ResultDateTime,H,M,S,MS);


  if M>MaxSessionTimeInMinutes then
  SL.Add(FieldByName('id').AsInteger.ToString());

 Next;
 end;


Close;
end;


for i := 0 to SL.Count-1 do begin

  with qDeleteNULLSessions do begin
  Params.ParamValues['id']:=SL[i];
  ExecSQL;
  end;

end;

SL.Free;

end;

procedure TMainForm.FinishSessionAndDeleteCodeFromDB;
var
  DateTime: TDateTime;
  DateTimeForMySQL: string;
begin
  // Write Session is Finished
  DateTime := Now;
  DateTimeForMySQL := FormatDateTime('yyyy-mm-dd hh:mm:ss', DateTime);
  qFinishSession.Params.ParamValues['TimeFinish'] := DateTimeForMySQL;
  qFinishSession.Params.ParamValues['id'] := FLastInsertID;
  qFinishSession.ExecSQL;
  qDeleteCode.Params.ParamValues['id'] := FLastInsertID;
  qDeleteCode.ExecSQL;
end;

procedure TMainForm.eNameClick(Sender: TObject);
begin
if eName.Text='Ваше имя...' then
eName.Text:='';

end;

procedure TMainForm.eCodeClick(Sender: TObject);
begin
if eCode.Text='Введите код подтверждения...' then
eCode.Text:='';
end;

procedure TMainForm.ePhoneNumberClick(Sender: TObject);
begin

if ePhoneNumber.Text='Введите номер телефона...' then

case cbCountry.ItemIndex of
  0:ePhoneNumber.Text:='+7';  //Russia
  1:ePhoneNumber.Text:='+38'; // Ukraine
  2:ePhoneNumber.Text:='+7';  // Kazakhstan
end;


end;

procedure TMainForm.tDisableEnableSendSMSButtonTimer(Sender: TObject);
begin
//


end;

procedure TMainForm.tTotalTimer(Sender: TObject);
begin

tTotal.Tag:=tTotal.Tag+1;


 if tTotal.Tag>MaxSessionTimeInMinutes*60 then
 begin
 UniSession.Terminate('Time is over');
 tTotal.Enabled:=False;
 end;


end;

procedure TMainForm.tUniEnableSendSMSButtonEventHandler(Sender: TComponent; EventName: string; Params: TUniStrings);
begin
//


end;

procedure TMainForm.tUniEnableSendSMSButtonTimer(Sender: TObject);
begin

tUniEnableSendSMSButton.Tag:=tUniEnableSendSMSButton.Tag+1;

FCountDown:=FCountDown-1;
lCountDown.Text:='('+FCountDown.ToString+')';

if tUniEnableSendSMSButton.Tag>30 then

  begin

    FCountDown:=0;
    bGetSMSCode.Enabled:=True;
    tUniEnableSendSMSButton.Enabled:=False;
    lCountDown.Text:='';

    bSendCode.Hide;
    eCode.Hide;
    tUniEnableSendSMSButton.Tag:=0;

    // Deleting last generated code
    qDeleteCode.Params.ParamValues['id']:=FLastInsertID;
    qDeleteCode.ExecSQL;

  end;


end;

procedure TMainForm.UniFormCreate(Sender: TObject);
var
  i: Integer;
begin
CenterElements;

FLastInsertID:=0;
FCurrentAttemptsSendCodeNumber:=0;
FCurrentAttemptsGetSMSNumber:=0;

FPhoneNumberCheck:=TPhoneNumberCheck.Create(UniApplication);



lCountDown.Text:='';

// Connecting all queries



for i := 0 to Self.ComponentCount-1 do
 begin

 if (Self.Components[i] is TFDQuery) then
  (Self.Components[i] as TFDQuery).Connection:=UniMainModule.DBConnection.FDConnection;

 end;



FGenerateUniqueCode:=TGenerateUniqueCode.Create(Self);
FGenerateUniqueCode.MainForm:=Self;


FSendEmail:=TSendEmail.Create(UniApplication);



end;

procedure TMainForm.UniFormDestroy(Sender: TObject);
begin

FreeAndNil(FPhoneNumberCheck);
FinishSessionAndDeleteCodeFromDB;

end;

initialization
  RegisterAppFormClass(TMainForm);

end.
