unit Api.ServiceImpl;

interface

uses
  XData.Server.Module, System.Generics.Collections,
  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
    function SaveTaskRow(const Item: TTaskRowSave): Boolean;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    function GetProjectTasks(projectId: string): TTasksList;
  end;

implementation


procedure TApiService.AfterConstruction;
begin
  inherited;
  ApiDB := TApiDatabase.Create(nil);
end;


procedure TApiService.BeforeDestruction;
begin
  ApiDB.Free;
  inherited;
end;



function TApiService.GetProjectTasks(projectId: string): TTasksList;
var
  taskMap: TDictionary<string, TTask>;
  task: TTask;
  item: TTaskItem;
  taskId: string;
begin
  Result := TTasksList.Create;
  TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);

  taskMap := TDictionary<string, TTask>.Create;
  try
    ApiDB.uqProjectTasks.Close;
    ApiDB.uqProjectTasks.ParamByName('PROJECT_ID').AsString := projectId;
    ApiDB.uqProjectTasks.Open;

    while not ApiDB.uqProjectTasks.Eof do
    begin
      taskId := ApiDB.uqProjectTasksTASK_ID.AsString;

      if not taskMap.TryGetValue(taskId, task) then
      begin
        task := TTask.Create;
        TXDataOperationContext.Current.Handler.ManagedObjects.Add(task);

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

        taskMap.Add(taskId, task);
        Result.data.Add(task);
      end;

      item := TTaskItem.Create;
      TXDataOperationContext.Current.Handler.ManagedObjects.Add(item);

      item.taskItemId := ApiDB.uqProjectTasksTASK_ITEM_ID.AsString;
      item.taskId := ApiDB.uqProjectTasksTASK_ID.AsString;
      item.projectId := ApiDB.uqProjectTasksPROJECT_ID.AsString;

      item.application := ApiDB.uqProjectTasksAPPLICATION.AsString;
      item.version := ApiDB.uqProjectTasksAPP_VERSION.AsString;

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

      item.reportedBy := ApiDB.uqProjectTasksREPORTED_BY.AsString;
      item.assignedTo := ApiDB.uqProjectTasksASSIGNED_TO.AsString;

      item.status := ApiDB.uqProjectTasksSTATUS.AsString;

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

      item.fixedVersion := ApiDB.uqProjectTasksFIXED_VERSION.AsString;
      item.formSection := ApiDB.uqProjectTasksFORM_SECTION.AsString;
      item.issue := ApiDB.uqProjectTasksISSUE.AsString;
      item.notes := ApiDB.uqProjectTasksNOTES.AsString;

      task.items.Add(item);

      ApiDB.uqProjectTasks.Next;
    end;

    Result.count := Result.data.Count;
  finally
    taskMap.Free;
  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
  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').Clear;

  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;
end;


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

end.
