unit Api.Database;

interface

uses
  System.SysUtils, System.Classes, Data.DB, MemDS, DBAccess, Uni, UniProvider,
  PostgreSQLUniProvider, System.Variants, System.Generics.Collections, System.IniFiles,
  Common.Logging, Vcl.Forms, OracleUniProvider, System.Character;

type
  TApiDatabaseModule = class(TDataModule)
    OracleUniProvider1: TOracleUniProvider;
    uqMapUnits: TUniQuery;
    uqUnitList: TUniQuery;
    uqComplaintUnits: TUniQuery;
    uqCFSMemos: TUniQuery;
    uqComplaintList: TUniQuery;
    uqComplaintDetails: TUniQuery;
    ucENTCAD: TUniConnection;
    uqComplaintListCOMPLAINTID: TFloatField;
    uqComplaintListCFSID: TFloatField;
    uqComplaintListCOMPLAINT: TStringField;
    uqComplaintListAGENCY: TStringField;
    uqComplaintListDISPATCH_CODE_DESC: TStringField;
    uqComplaintListSOURCE: TStringField;
    uqComplaintListSOURCE_DESC: TStringField;
    uqComplaintListPRIORITY: TStringField;
    uqComplaintListADDRESSID: TFloatField;
    uqComplaintListADDRESS: TStringField;
    uqComplaintListAPARTMENT: TStringField;
    uqComplaintListCITY: TStringField;
    uqComplaintListBUSINESS: TStringField;
    uqComplaintListDISPATCHDISTRICT: TStringField;
    uqComplaintListDISPATCHSECTOR: TStringField;
    uqComplaintListADDRESSDISTRICT: TStringField;
    uqComplaintListADDRESSSECTOR: TStringField;
    uqComplaintListXCOORD: TFloatField;
    uqComplaintListYCOORD: TFloatField;
    uqComplaintListWARNINGS: TFloatField;
    uqComplaintListCONTACTS: TFloatField;
    uqComplaintListHISTORY: TFloatField;
    uqComplaintListDATEREPORTED: TDateTimeField;
    uqComplaintListDATERECEIVED: TDateTimeField;
    uqComplaintListDATEDISPATCHED: TDateTimeField;
    uqComplaintListDATERESPONDED: TDateTimeField;
    uqComplaintListDATEARRIVED: TDateTimeField;
    uqComplaintListDATECLEARED: TDateTimeField;
    uqComplaintUnitsCOMPLAINTID: TFloatField;
    uqComplaintUnitsUNITID: TFloatField;
    uqComplaintUnitsUNITNAME: TStringField;
    uqComplaintUnitsDATEDISPATCHED: TDateTimeField;
    uqComplaintUnitsDATERESPONDED: TDateTimeField;
    uqComplaintUnitsDATEARRIVED: TDateTimeField;
    uqComplaintUnitsDATECLEARED: TDateTimeField;
    uqComplaintUnitsLOCATION: TStringField;
    uqCFSMemosMEMO_ID: TFloatField;
    uqCFSMemosCFSID: TFloatField;
    uqCFSMemosMEMO_TYPE: TFloatField;
    uqCFSMemosTIMESTAMP: TDateTimeField;
    uqCFSMemosBADGE_NUMBER: TStringField;
    uqCFSMemosREMARKS: TStringField;
    uqComplaintListcomplaintNumber: TStringField;
    uqComplaintListPRIORITY_COLOR: TFloatField;
    uqComplaintListDISTRICT_DESC: TStringField;
    uqComplaintListSECTOR_DESC: TStringField;
    uqUnitListUNITID: TFloatField;
    uqUnitListUNITNAME: TStringField;
    uqUnitListCARNUMBER_DESC: TStringField;
    uqUnitListDISTRICT_DESC: TStringField;
    uqUnitListSECTOR_DESC: TStringField;
    uqUnitListOFFICER1_EMPNUM: TStringField;
    uqUnitListOFFICER1_LAST_NAME: TStringField;
    uqUnitListOFFICER1_FIRST_NAME: TStringField;
    uqUnitListOFFICER1_MI: TStringField;
    uqUnitListOFFICER2_EMPNUM: TStringField;
    uqUnitListOFFICER2_LAST_NAME: TStringField;
    uqUnitListOFFICER2_FIRST_NAME: TStringField;
    uqUnitListOFFICER2_MI: TStringField;
    uqUnitListLOCATION: TStringField;
    uqUnitListCOMPLAINT: TStringField;
    uqUnitListUNITSTATUS: TFloatField;
    uqUnitListUNIT_STATUS_DESC: TStringField;
    uqUnitListENTRYID: TFloatField;
    uqUnitListGPS_LATITUDE: TFloatField;
    uqUnitListGPS_LONGITUDE: TFloatField;
    uqUnitListCALL_TYPE: TStringField;
    uqMapComplaints: TUniQuery;
    uqMapComplaintsCOMPLAINTID: TFloatField;
    uqMapComplaintsDISPATCHDISTRICT: TStringField;
    uqMapComplaintsLNG: TFloatField;
    uqMapComplaintsLAT: TFloatField;
    uqMapComplaintsDISPATCH_CODE_DESC: TStringField;
    uqMapComplaintsPRIORITY: TStringField;
    uqMapComplaintsDISPATCHCODECATEGORY: TStringField;
    uqMapComplaintspriorityKey: TStringField;
    uqMapComplaintspngName: TStringField;
    uqBadgeCounts: TUniQuery;
    uqBadgeCountsCOMPLAINTS: TFloatField;
    uqBadgeCountsUNITS: TFloatField;
    uqComplaintDetailsCOMPLAINTID: TFloatField;
    uqComplaintDetailsCFSID: TFloatField;
    uqComplaintDetailsCOMPLAINT: TStringField;
    uqComplaintDetailsPRIORITY: TStringField;
    uqComplaintDetailsDISPATCHCODE: TStringField;
    uqComplaintDetailsDISPATCH_CODE_DESC: TStringField;
    uqComplaintDetailsDISPATCHDISTRICT: TStringField;
    uqComplaintDetailsADDRESS: TStringField;
    uqComplaintDetailsDATEREPORTED: TDateTimeField;
    uqComplaintDetailsDATERECEIVED: TDateTimeField;
    uqComplaintDetailsDATEDISPATCHED: TDateTimeField;
    uqComplaintDetailsDATERESPONDED: TDateTimeField;
    uqComplaintDetailsDATEARRIVED: TDateTimeField;
    uqComplaintDetailsDATECLEARED: TDateTimeField;
    uqMapComplaintUnitsList: TUniQuery;
    uqMapComplaintUnitsListCOMPLAINTID: TFloatField;
    uqMapComplaintUnitsListUNITID: TFloatField;
    uqMapComplaintUnitsListUNITNAME: TStringField;
    uqMapComplaintUnitsListDATEDISPATCHED: TDateTimeField;
    uqMapComplaintUnitsListDATERESPONDED: TDateTimeField;
    uqMapComplaintUnitsListDATEARRIVED: TDateTimeField;
    uqMapComplaintUnitsListDATECLEARED: TDateTimeField;
    uqMapComplaintUnitsListLOCATION: TStringField;
    uqMapComplaintsADDRESS: TStringField;
    uqMapUnitsENTRYID: TFloatField;
    uqMapUnitsUNITID: TFloatField;
    uqMapUnitsUNITNAME: TStringField;
    uqMapUnitsUNIT_DISTRICT: TStringField;
    uqMapUnitsGPS_LATITUDE: TFloatField;
    uqMapUnitsGPS_LONGITUDE: TFloatField;
    uqMapUnitsCALL_TYPE: TStringField;
    uqMapUnitsPRIORITY: TStringField;
    uqMapUnitsUNIT_STATUS_DESC: TStringField;
    uqComplaintDetailsHISTORY: TFloatField;
    uqComplaintDetailsCONTACTS: TFloatField;
    uqComplaintDetailsWARNINGS: TFloatField;
    uqComplaintDetailsADDRESSID: TFloatField;
    uqComplaintDetailsAGENCY: TStringField;
    uqComplaintDetailsSTRNUMBER: TFloatField;
    uqComplaintDetailsSTRHNUMBER: TStringField;
    uqComplaintDetailsSTRPREFIX: TStringField;
    uqComplaintDetailsSTRNAME: TStringField;
    uqComplaintDetailsSTRSUFFIX: TStringField;
    uqComplaintDetailsCITY: TStringField;
    uqComplaintHistory: TUniQuery;
    uqComplaintContacts: TUniQuery;
    uqComplaintWarnings: TUniQuery;
    uqMapUnitsUPDATE_TIME: TDateTimeField;
    uqMapUnitsOFFICER1_LNAME: TStringField;
    uqMapUnitsOFFICER1_FNAME: TStringField;
    uqMapUnitsOFFICER1_EMPNUM: TStringField;
    uqMapUnitsOFFICER2_LNAME: TStringField;
    uqMapUnitsOFFICER2_FNAME: TStringField;
    uqMapUnitsOFFICER2_EMPNUM: TStringField;
    uqUnitDetails: TUniQuery;
    uqUnitDetailsUNITID: TFloatField;
    uqUnitDetailsUNITNAME: TStringField;
    uqUnitDetailsCARNUMBER_DESC: TStringField;
    uqUnitDetailsDISTRICT_DESC: TStringField;
    uqUnitDetailsLOCATION: TStringField;
    uqUnitDetailsUNIT_STATUS_DESC: TStringField;
    uqUnitDetailsOFFICER1_LNAME: TStringField;
    uqUnitDetailsOFFICER1_FNAME: TStringField;
    uqUnitDetailsOFFICER1_EMPNUM: TStringField;
    uqUnitDetailsOFFICER2_LNAME: TStringField;
    uqUnitDetailsOFFICER2_FNAME: TStringField;
    uqUnitDetailsOFFICER2_EMPNUM: TStringField;
    uqUnitDetailsUPDATE_TIME: TDateTimeField;
    uqUnitLogs: TUniQuery;
    uqUnitLogsLOG_TIME: TDateTimeField;
    uqUnitLogsCOMPLAINT_NUM: TStringField;
    uqUnitLogsLOG_TEXT: TStringField;
    uqMapUnitsDIS_UNITID: TFloatField;
    uqMapComplaintsBUSINESS: TStringField;
    uqComplaintDetailsBUSINESS: TStringField;
    procedure uqComplaintListCalcFields(DataSet: TDataSet);
    procedure uqMapComplaintsCalcFields(DataSet: TDataSet);
  private
    { Private declarations }
  public
    function DerivePriorityKeyFromPriorityString(const priorityString: string): string;
    function HandleUniqueFilenames(const category: string): string;
    function BadgeCounts(const BaseQuery: TUniQuery): Integer;
  end;

var
  ApiDatabaseModule: TApiDatabaseModule;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

procedure TApiDatabaseModule.uqComplaintListCalcFields(DataSet: TDataSet);
var
  raw: string;
begin
  raw := uqComplaintListCOMPLAINT.AsString.Trim;

  if raw.Length >= 3 then
    uqComplaintListcomplaintNumber.AsString := Copy(raw, 1, 2) + '-' + Copy(raw, 3, MaxInt)
  else if raw.Length = 2 then
    uqComplaintListcomplaintNumber.AsString := raw + '-'
  else
    uqComplaintListcomplaintNumber.AsString := raw;
end;


procedure TApiDatabaseModule.uqMapComplaintsCalcFields(DataSet: TDataSet);
var
  rawCategory: string;
  rawPriority: string;
  derivedPriorityKey: string;
  computedPngName: string;
begin
  rawCategory := DataSet.FieldByName('DISPATCHCODECATEGORY').AsString;
  rawPriority := DataSet.FieldByName('PRIORITY').AsString;

  derivedPriorityKey := DerivePriorityKeyFromPriorityString(rawPriority);
  DataSet.FieldByName('priorityKey').AsString := derivedPriorityKey;

  if Trim(rawCategory) = '' then
    computedPngName := Format('default_%s.png', [derivedPriorityKey])
  else
    computedPngName := Format('%s_%s.png', [HandleUniqueFilenames(rawCategory), derivedPriorityKey]);

  DataSet.FieldByName('pngName').AsString := computedPngName;
end;

function TApiDatabaseModule.HandleUniqueFilenames(const category: string): string;
var
  i: Integer;
  ch: Char;
  lowered, resultBuilder: string;
begin
  lowered := Trim(LowerCase(category));
  resultBuilder := '';
  for i := 1 to Length(lowered) do
  begin
    ch := lowered[i];
    if ch.IsLetterOrDigit then
      resultBuilder := resultBuilder + ch
    else
      resultBuilder := resultBuilder + '_';
  end;
  Result := resultBuilder;
end;

function TApiDatabaseModule.DerivePriorityKeyFromPriorityString(const priorityString: string): string;
var
  firstChar: Char;
begin
  if priorityString <> '' then
  begin
    firstChar := priorityString[1];  // handles "3J", "3P", etc.
    if (firstChar >= '1') and (firstChar <= '4') then
      Exit(string(firstChar));
    if (firstChar >= '5') and (firstChar <= '9') then
      Exit('5-9');
  end;
  Result := '5-9';
end;


function TApiDatabaseModule.BadgeCounts(const BaseQuery: TUniQuery): Integer;
var
  Q: TUniQuery;
  WrappedSQL: string;
begin
  Q := TUniQuery.Create(nil);
  try
    Q.Connection := BaseQuery.Connection;

    // Wrap the original query text in a COUNT(*) shell
    WrappedSQL := 'select count(*) as CNT from (' + BaseQuery.SQL.Text + ') t';
    Q.SQL.Text := WrappedSQL;

    // Carry over params (if the base query uses any)
    Q.Params.AssignValues(BaseQuery.Params);

    Q.Open;
    Result := Q.Fields[0].AsInteger;
  finally
    Q.Free;
  end;
end;

end.
