unit Api.ServiceImpl;

interface

uses
  XData.Server.Module,
  XData.Service.Common,
  System.Variants,
  System.DateUtils,
  Api.Service,
  Api.Database,
  Common.Logging,
  System.SysUtils;

type
  [ServiceImplementation]
  TApiService = class(TInterfacedObject, IApiService)
  strict private
    ApiDB: TApiDatabase;
  private
    procedure EnsureBlankWebTaskRow(const taskId: string);
    function SaveTaskRow(const Item: TTaskRowSave): Boolean;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    function GetTaskItems(taskId: string): TTasksList;
  end;

implementation

procedure TApiService.AfterConstruction;
begin
  inherited;
  ApiDB := TApiDatabase.Create(nil);
  Logger.Log(4, 'ApiService.AfterConstruction - ApiDB created');
end;

procedure TApiService.BeforeDestruction;
begin
  Logger.Log(4, 'ApiService.BeforeDestruction - freeing ApiDB');
  ApiDB.Free;
  inherited;
end;

function TApiService.GetTaskItems(taskId: string): TTasksList;
var
  task: TTask;
  item: TTaskItem;
begin
  Logger.Log(4, Format('ApiService.GetTaskItems - TASK_ID="%s"', [taskId]));

  Result := TTasksList.Create;
  TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);

  try
    ApiDB.uqWebTasks.Close;
    ApiDB.uqWebTasks.ParamByName('TASK_ID').AsString := taskId;
    ApiDB.uqWebTasks.Open;

    if ApiDB.uqWebTasks.IsEmpty then
    begin
      Logger.Log(4, Format('ApiService.GetTaskItems - no rows for TASK_ID="%s", ensuring blank row', [taskId]));
      EnsureBlankWebTaskRow(taskId);

      ApiDB.uqWebTasks.Close;
      ApiDB.uqWebTasks.ParamByName('TASK_ID').AsString := taskId;
      ApiDB.uqWebTasks.Open;
    end;

    if ApiDB.uqWebTasks.IsEmpty then
    begin
      Logger.Log(2, Format('ApiService.GetTaskItems - still no rows after ensure blank for TASK_ID="%s"', [taskId]));
      Result.count := 0;
      Exit;
    end;

    task := TTask.Create;
    TXDataOperationContext.Current.Handler.ManagedObjects.Add(task);

    task.taskId := taskId;
    task.projectId := ApiDB.uqWebTasksPROJECT_ID.AsString;

    Result.data.Add(task);

    while not ApiDB.uqWebTasks.Eof do
    begin
      item := TTaskItem.Create;
      TXDataOperationContext.Current.Handler.ManagedObjects.Add(item);

      item.taskItemId := ApiDB.uqWebTasksTASK_ITEM_ID.AsString;
      item.taskId := ApiDB.uqWebTasksTASK_ID.AsString;
      item.projectId := ApiDB.uqWebTasksPROJECT_ID.AsString;

      item.application := ApiDB.uqWebTasksAPPLICATION.AsString;
      item.version := ApiDB.uqWebTasksAPP_VERSION.AsString;

      if ApiDB.uqWebTasksTASK_DATE.IsNull then
        item.taskDate := 0
      else
        item.taskDate := ApiDB.uqWebTasksTASK_DATE.AsDateTime;

      item.reportedBy := ApiDB.uqWebTasksREPORTED_BY.AsString;
      item.assignedTo := ApiDB.uqWebTasksASSIGNED_TO.AsString;

      item.status := ApiDB.uqWebTasksSTATUS.AsString;

      if ApiDB.uqWebTasksSTATUS_DATE.IsNull then
        item.statusDate := Null
      else
        item.statusDate := ApiDB.uqWebTasksSTATUS_DATE.AsDateTime;

      item.fixedVersion := ApiDB.uqWebTasksFIXED_VERSION.AsString;
      item.formSection := ApiDB.uqWebTasksFORM_SECTION.AsString;
      item.issue := ApiDB.uqWebTasksISSUE.AsString;
      item.notes := ApiDB.uqWebTasksNOTES.AsString;

      task.items.Add(item);

      ApiDB.uqWebTasks.Next;
    end;

    Result.count := Result.data.Count;
    Logger.Log(4, Format('ApiService.GetTaskItems - returned %d task(s)', [Result.count]));
  except
    on E: Exception do
    begin
      Logger.Log(2, 'ApiService.GetTaskItems - ERROR: ' + E.Message);
      raise;
    end;
  end;
end;

procedure TApiService.EnsureBlankWebTaskRow(const taskId: string);
begin
  Logger.Log(4, Format('ApiService.EnsureBlankWebTaskRow - TASK_ID="%s"', [taskId]));
  try
    ApiDB.uqEnsureBlankRow.Close;
    ApiDB.uqEnsureBlankRow.ParamByName('TASK_ID').AsString := taskId;
    ApiDB.uqEnsureBlankRow.ExecSQL;
  except
    on E: Exception do
    begin
      Logger.Log(2, 'ApiService.EnsureBlankWebTaskRow - ERROR: ' + E.Message);
      raise;
    end;
  end;
end;

function TApiService.SaveTaskRow(const Item: TTaskRowSave): Boolean;

  function ParseDateOrZero(const S: string; out D: TDateTime): Boolean;
  begin
    Result := Trim(S) <> '';
    if Result then
      D := ISO8601ToDate(S, False);
  end;

var
  d: TDateTime;
begin
  Logger.Log(4, Format('ApiService.SaveTaskRow - TASK_ITEM_ID="%s"', [Item.taskItemId]));

  try
    ApiDB.uqSaveTaskRow.Close;

    ApiDB.uqSaveTaskRow.ParamByName('TASK_ITEM_ID').AsString := Item.taskItemId;

    ApiDB.uqSaveTaskRow.ParamByName('APPLICATION').AsString := Item.application;
    ApiDB.uqSaveTaskRow.ParamByName('APP_VERSION').AsString := Item.version;

    if ParseDateOrZero(Item.taskDate, d) then
      ApiDB.uqSaveTaskRow.ParamByName('TASK_DATE').AsDateTime := d
    else
      ApiDB.uqSaveTaskRow.ParamByName('TASK_DATE').Clear;

    ApiDB.uqSaveTaskRow.ParamByName('REPORTED_BY').AsString := Item.reportedBy;
    ApiDB.uqSaveTaskRow.ParamByName('ASSIGNED_TO').AsString := Item.assignedTo;

    ApiDB.uqSaveTaskRow.ParamByName('STATUS').AsString := Item.status;

    if ParseDateOrZero(Item.statusDate, d) then
      ApiDB.uqSaveTaskRow.ParamByName('STATUS_DATE').AsDateTime := d
    else
      ApiDB.uqSaveTaskRow.ParamByName('STATUS_DATE').AsDateTime := Date;

    ApiDB.uqSaveTaskRow.ParamByName('FIXED_VERSION').AsString := Item.fixedVersion;
    ApiDB.uqSaveTaskRow.ParamByName('FORM_SECTION').AsString := Item.formSection;
    ApiDB.uqSaveTaskRow.ParamByName('ISSUE').AsString := Item.issue;
    ApiDB.uqSaveTaskRow.ParamByName('NOTES').AsString := Item.notes;

    ApiDB.uqSaveTaskRow.ExecSQL;

    Result := True;
    Logger.Log(4, 'ApiService.SaveTaskRow - OK');
  except
    on E: Exception do
    begin
      Logger.Log(2, 'ApiService.SaveTaskRow - ERROR: ' + E.Message);
      raise;
    end;
  end;
end;

initialization
  RegisterServiceType(TypeInfo(IApiService));
  RegisterServiceType(TApiService);

end.

