Commit d87ba778 by Daniel Barker

Add web task picker with Focused Task option

parent 44a9fed1
......@@ -13,6 +13,7 @@ emT3XDataServer/bin/static/
emT3XDataServer/Source/__history/
emT3XDataServer/Source/__recovery/
emT3XDataServer/Win32/
.validation/
*.exe
*.local
......
......@@ -3,6 +3,7 @@
<h5 class="mb-0 text-nowrap" id="lbl_time_entries_title"></h5>
<div class="d-flex align-items-center gap-2 ms-auto flex-nowrap">
<div id="lbl_time_total_hours" class="me-2 text-nowrap fw-semibold">Total Hours: 0</div>
<div id="lbl_time_total_rows" class="me-2 text-nowrap"></div>
<div class="d-flex align-items-center gap-2 flex-nowrap">
......@@ -72,10 +73,18 @@
<div id="task_picker_status" class="alert alert-danger py-1 px-2 mb-3 d-none small"></div>
<div class="d-flex justify-content-end gap-2">
<div class="d-flex align-items-center gap-2">
<div class="d-flex align-items-center gap-2 me-auto">
<input class="form-check-input m-0" type="checkbox" id="task_picker_add_focus" />
<label class="form-check-label mb-0" for="task_picker_add_focus">
Focused Task
</label>
</div>
<button type="button" class="btn btn-outline-secondary btn-sm" data-bs-dismiss="offcanvas">
Cancel
</button>
<button type="button" class="btn btn-primary btn-sm" id="btn_task_picker_save" disabled>
Save
</button>
......
......@@ -76,6 +76,7 @@ type
function DateToIso(const AValue: TDateTime): string;
procedure SetWeekRangeFromAnchor(const ADateValue: string; ALoadAfterSet: Boolean);
procedure SetTotalRowsLabel(ARowCount: Integer);
procedure UpdateTotalHours;
procedure SetTimeEntriesLabel(const AName: string);
procedure CaptureTableScroll;
procedure RestoreTableScroll;
......@@ -93,7 +94,7 @@ type
function GetTargetRowIndex(ATarget: TJSHTMLElement): Integer;
procedure DocumentMouseDown(Event: TJSEvent);
[async] procedure TaskPickerButtonClick(Event: TJSEvent);
procedure TaskPickerTaskSelected(ARowIndex: Integer; const ATaskId, ATaskDisplay: string);
procedure TaskPickerTaskSelected(ARowIndex: Integer; const ATaskId, ATaskDisplay: string; AAddedToFocus: Boolean);
procedure ApplyActiveRowState;
procedure EditorBlur(Event: TJSEvent);
[async] procedure SaveField(AIndex: Integer; const AFieldName: string);
......@@ -215,7 +216,7 @@ var
weekEnd: TDateTime;
begin
anchorDate := IsoToDate(ADateValue);
weekStart := anchorDate - (DayOfTheWeek(anchorDate) - 1);
weekStart := anchorDate;
weekEnd := weekStart + 6;
FUpdatingDates := True;
......@@ -271,6 +272,37 @@ begin
el.innerText := 'Total Rows: ' + IntToStr(ARowCount);
end;
procedure TFTimeEntries.UpdateTotalHours;
var
el: TJSHTMLElement;
totalHours: Double;
currentRecNo: Integer;
begin
totalHours := 0;
if xdwdsTimeEntries.Active then
begin
currentRecNo := xdwdsTimeEntries.RecNo;
xdwdsTimeEntries.First;
while not xdwdsTimeEntries.Eof do
begin
if (xdwdsTimeEntriesentryId.AsInteger > 0) and
(xdwdsTimeEntriestaskDate.AsString >= FStartDate) and
(xdwdsTimeEntriestaskDate.AsString <= FEndDate) and
(not xdwdsTimeEntrieshours.IsNull) then
totalHours := totalHours + xdwdsTimeEntrieshours.AsFloat;
xdwdsTimeEntries.Next;
end;
if currentRecNo > 0 then
xdwdsTimeEntries.RecNo := currentRecNo;
end;
el := TJSHTMLElement(document.getElementById('lbl_time_total_hours'));
el.innerText := 'Total Hours: ' + FormatFloat('0.##', totalHours);
end;
procedure TFTimeEntries.SetTimeEntriesLabel(const AName: string);
var
el: TJSHTMLElement;
......@@ -333,6 +365,7 @@ begin
xdwdsTimeEntries.Close;
xdwdsTimeEntries.SetJsonData(itemsArray);
xdwdsTimeEntries.Open;
UpdateTotalHours;
FActiveRowIndex := -1;
HideRowValidationMessage;
......@@ -1667,14 +1700,17 @@ begin
if not Assigned(FTaskPickerOffCanvas) then
FTaskPickerOffCanvas := TTaskPickerOffCanvas.Create(xdwcTimeEntries, @TaskPickerTaskSelected);
await(FTaskPickerOffCanvas.Open(FUserId, idx));
await(FTaskPickerOffCanvas.Open(FUserId, idx, FTaskOptions));
end;
procedure TFTimeEntries.TaskPickerTaskSelected(ARowIndex: Integer; const ATaskId, ATaskDisplay: string);
procedure TFTimeEntries.TaskPickerTaskSelected(ARowIndex: Integer; const ATaskId, ATaskDisplay: string; AAddedToFocus: Boolean);
var
btn: TJSHTMLElement;
triggerId: string;
i: Integer;
taskOption: TJSObject;
taskFound: Boolean;
begin
if not xdwdsTimeEntries.Active then
Exit;
......@@ -1692,6 +1728,30 @@ begin
btnDeleteEntry.Enabled := not IsNewEntryRow(ARowIndex);
btnCopyEntry.Enabled := not IsNewEntryRow(ARowIndex);
if AAddedToFocus then
begin
taskFound := False;
for i := 0 to FTaskOptions.length - 1 do
begin
taskOption := TJSObject(FTaskOptions[i]);
if string(taskOption['taskId']) = ATaskId then
begin
taskFound := True;
Break;
end;
end;
if not taskFound then
begin
taskOption := TJSObject.new;
taskOption['taskId'] := ATaskId;
taskOption['taskDisplay'] := ATaskDisplay;
FTaskOptions.push(taskOption);
end;
end;
CaptureTableScroll;
RenderTable;
......@@ -1833,6 +1893,9 @@ begin
));
console.log('SaveField: response=' + string(TJSJSON.stringify(response.Result)));
if SameText(AFieldName, 'hours') or SameText(AFieldName, 'taskDate') then
UpdateTotalHours;
except
on E: EXDataClientRequestException do
begin
......
......@@ -6,7 +6,11 @@ uses
System.SysUtils, JS, Web, XData.Web.Client;
type
TTaskPickedProc = reference to procedure(ARowIndex: Integer; const ATaskId, ATaskDisplay: string);
TTaskPickedProc = reference to procedure(
ARowIndex: Integer;
const ATaskId, ATaskDisplay: string;
AAddedToFocus: Boolean
);
TTaskPickerOffCanvas = class
private
......@@ -17,10 +21,12 @@ type
FCustomers: TJSArray;
FProjects: TJSArray;
FTasks: TJSArray;
FFocusedTasks: TJSArray;
procedure BindEvents;
procedure ClearSelect(const AElementId: string; ADisabled: Boolean);
procedure FillSelect(const AElementId: string; AItems: TJSArray);
procedure FilterProjects(const ACustomerId: string);
function SelectedValue(const AElementId: string): string;
function FindDisplay(AItems: TJSArray; const AValue: string): string;
procedure SetStatus(const AMessage: string);
......@@ -33,13 +39,14 @@ type
[async] procedure LoadProjects(const ACustomerId: string);
[async] procedure LoadTasks(const AProjectId: string);
[async] procedure CustomerChanged(Event: TJSEvent);
procedure CustomerChanged(Event: TJSEvent);
[async] procedure ProjectChanged(Event: TJSEvent);
procedure TaskChanged(Event: TJSEvent);
procedure SaveClicked(Event: TJSEvent);
procedure UpdateFocusCheckbox;
[async] procedure SaveClicked(Event: TJSEvent);
public
constructor Create(AClient: TXDataWebClient; AOnTaskPicked: TTaskPickedProc);
[async] procedure Open(const AUserId: string; ARowIndex: Integer);
[async] procedure Open(const AUserId: string; ARowIndex: Integer; AFocusedTasks: TJSArray);
end;
implementation
......@@ -115,6 +122,28 @@ begin
selectEl.disabled := False;
end;
procedure TTaskPickerOffCanvas.FilterProjects(const ACustomerId: string);
var
filteredProjects: TJSArray;
project: TJSObject;
i: Integer;
begin
//create an empty filtered project list
filteredProjects := TJSArray.new;
//loop through the full project list
for i := 0 to FProjects.length -1 do
begin
project := TJSObject(FProjects[i]);
if (ACustomerId = '') or (string(project['customerId']) = ACustomerId) then
begin
filteredProjects.push(project);
end;
end;
FillSelect('task_picker_project', filteredProjects)
end;
function TTaskPickerOffCanvas.SelectedValue(const AElementId: string): string;
var
selectEl: TJSHTMLSelectElement;
......@@ -202,8 +231,7 @@ var
resultObj: TJSObject;
begin
response := await(FClient.RawInvokeAsync(
'ITimeEntryService.GetTaskPickerCustomers',
[FUserId]
'ITimeEntryService.GetTaskPickerCustomers', []
));
resultObj := TJSObject(response.Result);
......@@ -218,12 +246,11 @@ var
begin
response := await(FClient.RawInvokeAsync(
'ITimeEntryService.GetTaskPickerProjects',
[FUserId, ACustomerId]
[ACustomerId]
));
resultObj := TJSObject(response.Result);
FProjects := TJSArray(resultObj['options']);
FillSelect('task_picker_project', FProjects);
end;
[async] procedure TTaskPickerOffCanvas.LoadTasks(const AProjectId: string);
......@@ -233,7 +260,7 @@ var
begin
response := await(FClient.RawInvokeAsync(
'ITimeEntryService.GetTaskPickerTasks',
[FUserId, AProjectId]
[AProjectId]
));
resultObj := TJSObject(response.Result);
......@@ -241,7 +268,7 @@ begin
FillSelect('task_picker_task', FTasks);
end;
[async] procedure TTaskPickerOffCanvas.CustomerChanged(Event: TJSEvent);
procedure TTaskPickerOffCanvas.CustomerChanged(Event: TJSEvent);
var
customerId: string;
begin
......@@ -249,31 +276,48 @@ begin
SetSaveEnabled(False);
ClearSelect('task_picker_project', True);
ClearSelect('task_picker_task', True);
UpdateFocusCheckbox;
customerId := SelectedValue('task_picker_customer');
if customerId = '' then
Exit;
try
await(LoadProjects(customerId));
except
on E: Exception do
SetStatus('Unable to load projects.');
end;
FilterProjects(customerId);
end;
[async] procedure TTaskPickerOffCanvas.ProjectChanged(Event: TJSEvent);
var
projectId: string;
customerId: string;
project: TJSObject;
i: Integer;
begin
ClearStatus;
SetSaveEnabled(False);
ClearSelect('task_picker_task', True);
UpdateFocusCheckbox;
projectId := SelectedValue('task_picker_project');
if projectId = '' then
Exit;
customerId := SelectedValue('task_picker_customer');
if customerId = '' then
begin
for i := 0 to FProjects.length - 1 do
begin
project := TJSObject(FProjects[i]);
if string(project['value']) = projectId then
begin
customerId := string(project['customerId']);
Break;
end;
end;
TJSHTMLSelectElement(document.getElementById('task_picker_customer')).value := customerId;
FilterProjects(customerId);
TJSHTMLSelectElement(document.getElementById('task_picker_project')).value := projectId;
end;
try
await(LoadTasks(projectId));
except
......@@ -282,16 +326,52 @@ begin
end;
end;
procedure TTaskPickerOffCanvas.UpdateFocusCheckbox;
var
taskId: string;
taskOption: TJSObject;
alreadyFocused: Boolean;
addFocus: TJSHTMLInputElement;
i: Integer;
begin
taskId := SelectedValue('task_picker_task');
alreadyFocused := False;
if taskId <> '' then
begin
for i := 0 to FFocusedTasks.length - 1 do
begin
taskOption := TJSObject(FFocusedTasks[i]);
if string(taskOption['taskId']) = taskId then
begin
alreadyFocused := True;
Break;
end;
end;
end;
addFocus := TJSHTMLInputElement(
document.getElementById('task_picker_add_focus')
);
addFocus.checked := alreadyFocused;
addFocus.disabled := alreadyFocused or (taskId = '');
end;
procedure TTaskPickerOffCanvas.TaskChanged(Event: TJSEvent);
begin
ClearStatus;
UpdateFocusCheckbox;
SetSaveEnabled(SelectedValue('task_picker_task') <> '');
end;
procedure TTaskPickerOffCanvas.SaveClicked(Event: TJSEvent);
[async] procedure TTaskPickerOffCanvas.SaveClicked(Event: TJSEvent);
var
taskId: string;
taskDisplay: string;
addFocus: TJSHTMLInputElement;
addedToFocus: Boolean;
begin
Event.preventDefault;
......@@ -303,31 +383,66 @@ begin
end;
taskDisplay := FindDisplay(FTasks, taskId);
addFocus := TJSHTMLInputElement(
document.getElementById('task_picker_add_focus')
);
ClearStatus;
addedToFocus := False;
if addFocus.checked and not addFocus.disabled then
begin
SetSaveEnabled(False);
try
await(FClient.RawInvokeAsync(
'ITimeEntryService.AddTaskToFocus',
[FUserId, taskId]
));
addedToFocus := True;
except
on E: EXDataClientRequestException do
begin
SetStatus(E.ErrorResult.ErrorMessage);
SetSaveEnabled(True);
Exit;
end;
end;
SetSaveEnabled(True);
end;
if Assigned(FOnTaskPicked) then
FOnTaskPicked(FRowIndex, taskId, taskDisplay);
FOnTaskPicked(FRowIndex, taskId, taskDisplay, addedToFocus);
Hide;
end;
[async] procedure TTaskPickerOffCanvas.Open(const AUserId: string; ARowIndex: Integer);
[async] procedure TTaskPickerOffCanvas.Open(
const AUserId: string;
ARowIndex: Integer;
AFocusedTasks: TJSArray
);
begin
FUserId := AUserId;
FRowIndex := ARowIndex;
FFocusedTasks := AFocusedTasks;
ClearStatus;
SetSaveEnabled(False);
ClearSelect('task_picker_customer', True);
ClearSelect('task_picker_project', True);
ClearSelect('task_picker_task', True);
UpdateFocusCheckbox;
Show;
try
await(LoadCustomers);
await(LoadProjects(''));
FilterProjects('');
except
on E: Exception do
SetStatus('Unable to load customers.');
SetStatus('Unable to load customers or projects.');
end;
end;
......
......@@ -7,10 +7,10 @@ object ApiDatabase: TApiDatabase
ProviderName = 'MySQL'
Database = 'eTask'
Username = 'root'
Server = '192.168.102.133'
Server = '192.168.90.131'
LoginPrompt = False
Left = 435
Top = 359
Left = 439
Top = 363
EncryptedPassword = '9AFF92FF8CFF86FF8CFFCFFFCEFF'
end
object MySQLUniProvider1: TMySQLUniProvider
......@@ -300,8 +300,8 @@ object ApiDatabase: TApiDatabase
'from task_items'
'where TASK_ID = :TASK_ID'
' and TASK_ITEM_ID = :TASK_ITEM_ID')
Left = 656
Top = 282
Left = 708
Top = 302
ParamData = <
item
DataType = ftInteger
......@@ -853,7 +853,7 @@ object ApiDatabase: TApiDatabase
'where target_task.TASK_ID = :TASK_ID'
'order by tia.NAME')
Left = 58
Top = 314
Top = 316
ParamData = <
item
DataType = ftUnknown
......@@ -1279,50 +1279,47 @@ object ApiDatabase: TApiDatabase
SQL.Strings = (
'select distinct'
' c.CUSTOMER_ID,'
' c.SHORT_NAME as CUSTOMER_SHORT_NAME'
'from user_project up'
'join project p on p.PROJECT_ID = up.PROJECT_ID'
'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID'
'where up.USER_ID = :USER_ID'
'order by c.SHORT_NAME')
Left = 402
' c.NAME as CUSTOMER_NAME'
'from customers c '
'join project p on p.CUSTOMER_ID = c.CUSTOMER_ID'
'where p.STATUS = '#39'ACTIVE'#39
'order by c.NAME'
'')
Left = 404
Top = 494
ParamData = <
item
DataType = ftUnknown
Name = 'USER_ID'
Value = nil
end>
object uqTaskPickerCustomersCUSTOMER_ID: TStringField
FieldName = 'CUSTOMER_ID'
Size = 7
end
object uqTaskPickerCustomersCUSTOMER_SHORT_NAME: TStringField
FieldName = 'CUSTOMER_SHORT_NAME'
Size = 10
object uqTaskPickerCustomersCUSTOMER_NAME: TStringField
FieldName = 'CUSTOMER_NAME'
Size = 30
end
end
object uqTaskPickerProjects: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'select distinct'
'select'
' p.PROJECT_ID,'
' p.NAME as PROJECT_NAME'
'from user_project up'
'join project p on p.PROJECT_ID = up.PROJECT_ID'
'where up.USER_ID = :USER_ID'
' and p.CUSTOMER_ID = :CUSTOMER_ID'
'order by p.NAME')
' p.NAME as PROJECT_NAME,'
' p.CUSTOMER_ID'
'from project p '
'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID'
'where p.STATUS = '#39'ACTIVE'#39
'and (:CUSTOMER_ID = '#39#39' or p.CUSTOMER_ID = :CUSTOMER_ID)'
'order by p.NAME'
''
''
''
''
''
''
'')
Left = 544
Top = 494
ParamData = <
item
DataType = ftUnknown
Name = 'USER_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'CUSTOMER_ID'
Value = nil
end>
......@@ -1335,13 +1332,17 @@ object ApiDatabase: TApiDatabase
FieldName = 'PROJECT_NAME'
Size = 30
end
object uqTaskPickerProjectsCUSTOMER_ID: TStringField
FieldName = 'CUSTOMER_ID'
Size = 7
end
end
object uqTaskPickerTasks: TUniQuery
Connection = ucETaskApi
SQL.Strings = (
'select distinct'
' t.TASK_ID,'
' c.SHORT_NAME as CUSTOMER_SHORT_NAME,'
' c.NAME as CUSTOMER_NAME,'
' p.NAME as PROJECT_NAME,'
' t.TASK_NUM_1,'
' t.TASK_NUM_2,'
......@@ -1353,9 +1354,8 @@ object ApiDatabase: TApiDatabase
'from tasks t'
'join project p on p.PROJECT_ID = t.PROJECT_ID'
'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID'
'join user_project up on up.PROJECT_ID = p.PROJECT_ID'
'where up.USER_ID = :USER_ID'
' and t.PROJECT_ID = :PROJECT_ID'
' where t.PROJECT_ID = :PROJECT_ID'
' and p.STATUS = '#39'ACTIVE'#39
'order by'
' t.TASK_NUM_1,'
' t.TASK_NUM_2,'
......@@ -1363,17 +1363,13 @@ object ApiDatabase: TApiDatabase
' t.TASK_NUM_4,'
' t.TASK_NUM_5,'
' t.TASK_NUM_6,'
' t.SUBJECT')
' t.SUBJECT'
'')
Left = 676
Top = 502
ParamData = <
item
DataType = ftUnknown
Name = 'USER_ID'
Value = nil
end
item
DataType = ftUnknown
Name = 'PROJECT_ID'
Value = nil
end>
......@@ -1382,10 +1378,10 @@ object ApiDatabase: TApiDatabase
Required = True
Size = 7
end
object uqTaskPickerTasksCUSTOMER_SHORT_NAME: TStringField
FieldName = 'CUSTOMER_SHORT_NAME'
object uqTaskPickerTasksCUSTOMER_NAME: TStringField
FieldName = 'CUSTOMER_NAME'
ReadOnly = True
Size = 10
Size = 30
end
object uqTaskPickerTasksPROJECT_NAME: TStringField
FieldName = 'PROJECT_NAME'
......
......@@ -94,12 +94,11 @@ type
uqTaskPickerCustomers: TUniQuery;
uqTaskPickerProjects: TUniQuery;
uqTaskPickerTasks: TUniQuery;
uqTaskPickerCustomersCUSTOMER_ID: TStringField;
uqTaskPickerCustomersCUSTOMER_SHORT_NAME: TStringField;
uqTaskPickerProjectsPROJECT_ID: TStringField;
uqTaskPickerProjectsPROJECT_NAME: TStringField;
uqTaskPickerProjectsCUSTOMER_ID: TStringField;
uqTaskPickerTasksTASK_ID: TStringField;
uqTaskPickerTasksCUSTOMER_SHORT_NAME: TStringField;
uqTaskPickerTasksCUSTOMER_NAME: TStringField;
uqTaskPickerTasksPROJECT_NAME: TStringField;
uqTaskPickerTasksTASK_NUM_1: TIntegerField;
uqTaskPickerTasksTASK_NUM_2: TIntegerField;
......@@ -108,6 +107,8 @@ type
uqTaskPickerTasksTASK_NUM_5: TIntegerField;
uqTaskPickerTasksTASK_NUM_6: TIntegerField;
uqTaskPickerTasksTASK_SUBJECT: TStringField;
uqTaskPickerCustomersCUSTOMER_ID: TStringField;
uqTaskPickerCustomersCUSTOMER_NAME: TStringField;
procedure DataModuleCreate(Sender: TObject);
procedure uqUsersCalcFields(DataSet: TDataSet);
private
......
......@@ -51,6 +51,7 @@ implementation
procedure TTaskItemService.AfterConstruction;
begin
inherited;
Logger.Log(4, 'TaskItemService.AfterConstruction->TApiDatabase.Create(nil)');
apiDB := TApiDatabase.Create(nil);
Logger.Log(4, 'TaskItemService.AfterConstruction - apiDB created');
end;
......
......@@ -78,6 +78,7 @@ type
public
value: string;
display: string;
customerId: string;
end;
TTaskPickerOptionsResponse = class
......@@ -95,9 +96,10 @@ type
[HttpPost] function SaveTimeEntry(Item: TTimeEntrySave): string;
[HttpPost] function SaveTimeEntryField(Item: TTimeEntryFieldSave): Boolean;
[HttpPost] function DeleteTimeEntry(userId: string; entryId: Integer): Boolean;
function GetTaskPickerCustomers(userId: string): TTaskPickerOptionsResponse;
function GetTaskPickerProjects(userId, customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(userId, projectId: string): TTaskPickerOptionsResponse;
[HttpPost] function AddTaskToFocus(userId, taskId: string): Boolean;
function GetTaskPickerCustomers: TTaskPickerOptionsResponse;
function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse;
end;
implementation
......
......@@ -34,10 +34,11 @@ type
function AddTimeEntry(userId, taskDate: string): string;
function SaveTimeEntry(Item: TTimeEntrySave): string;
function SaveTimeEntryField(Item: TTimeEntryFieldSave): Boolean;
function GetTaskPickerCustomers(userId: string): TTaskPickerOptionsResponse;
function GetTaskPickerProjects(userId, customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(userId, projectId: string): TTaskPickerOptionsResponse;
function GetTaskPickerCustomers: TTaskPickerOptionsResponse;
function GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse;
function GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse;
function DeleteTimeEntry(userId: string; entryId: Integer): Boolean;
function AddTaskToFocus(userId, taskId: string): Boolean;
end;
implementation
......@@ -50,7 +51,9 @@ uses
procedure TTimeEntryService.AfterConstruction;
begin
inherited;
Logger.Log(4, 'TTimeEntryService.AfterConstruction->TApiDatabase.Create(nil)');
apiDB := TApiDatabase.Create(nil);
Logger.Log(4, 'TTimeEntryService.AfterConstruction - apiDB created')
end;
......@@ -130,7 +133,7 @@ var
leftText: string;
taskText: string;
begin
customerText := FieldText(AQuery, 'CUSTOMER_SHORT_NAME');
customerText := FieldText(AQuery, 'CUSTOMER_NAME');
projectText := FieldText(AQuery, 'PROJECT_NAME');
taskNumberText := BuildTaskNumber(AQuery);
subjectText := FieldText(AQuery, 'TASK_SUBJECT');
......@@ -210,7 +213,7 @@ begin
' ti.CATEGORY, ' +
' cat.CODE_DESC as CATEGORY_DESC, ' +
' ti.SUMMARY, ' +
' c.SHORT_NAME as CUSTOMER_SHORT_NAME, ' +
' c.NAME as CUSTOMER_NAME, ' +
' p.NAME as PROJECT_NAME, ' +
' t.TASK_NUM_1, ' +
' t.TASK_NUM_2, ' +
......@@ -290,7 +293,7 @@ begin
tasksQuery.SQL.Text :=
'select distinct ' +
' t.TASK_ID, ' +
' c.SHORT_NAME as CUSTOMER_SHORT_NAME, ' +
' c.NAME as CUSTOMER_NAME, ' +
' p.NAME as PROJECT_NAME, ' +
' t.TASK_NUM_1, ' +
' t.TASK_NUM_2, ' +
......@@ -305,7 +308,7 @@ begin
'join customers c on c.CUSTOMER_ID = p.CUSTOMER_ID ' +
'where tau.USER_ID = :USER_ID ' +
' and upper(trim(coalesce(tau.FOCUSED_TASK, ''''))) = ''T'' ' +
'order by c.SHORT_NAME, p.NAME, t.TASK_NUM_1, t.TASK_NUM_2, t.TASK_NUM_3, t.TASK_NUM_4, t.TASK_NUM_5, t.TASK_NUM_6';
'order by c.NAME, p.NAME, t.TASK_NUM_1, t.TASK_NUM_2, t.TASK_NUM_3, t.TASK_NUM_4, t.TASK_NUM_5, t.TASK_NUM_6';
tasksQuery.ParamByName('USER_ID').AsString := userId;
tasksQuery.Open;
......@@ -764,15 +767,14 @@ begin
end;
function TTimeEntryService.GetTaskPickerCustomers(userId: string): TTaskPickerOptionsResponse;
function TTimeEntryService.GetTaskPickerCustomers: TTaskPickerOptionsResponse;
begin
Logger.Log(4, Format('TimeEntryService.GetTaskPickerCustomers - USER_ID="%s"', [userId]));
Logger.Log(4, 'TimeEntryService.GetTaskPickerCustomers Start');
Result := TTaskPickerOptionsResponse.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
apiDB.uqTaskPickerCustomers.Close;
apiDB.uqTaskPickerCustomers.ParamByName('USER_ID').AsString := userId;
apiDB.uqTaskPickerCustomers.Open;
try
while not apiDB.uqTaskPickerCustomers.Eof do
......@@ -780,7 +782,7 @@ begin
AddTaskPickerOption(
Result,
FieldText(apiDB.uqTaskPickerCustomers, 'CUSTOMER_ID'),
FieldText(apiDB.uqTaskPickerCustomers, 'CUSTOMER_SHORT_NAME')
FieldText(apiDB.uqTaskPickerCustomers, 'CUSTOMER_NAME')
);
apiDB.uqTaskPickerCustomers.Next;
......@@ -791,15 +793,14 @@ begin
end;
function TTimeEntryService.GetTaskPickerProjects(userId, customerId: string): TTaskPickerOptionsResponse;
function TTimeEntryService.GetTaskPickerProjects(customerId: string): TTaskPickerOptionsResponse;
begin
Logger.Log(4, Format('TimeEntryService.GetTaskPickerProjects - USER_ID="%s" CUSTOMER_ID="%s"', [userId, customerId]));
Logger.Log(4, Format('TimeEntryService.GetTaskPickerProjects - CUSTOMER_ID="%s"', [customerId]));
Result := TTaskPickerOptionsResponse.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
apiDB.uqTaskPickerProjects.Close;
apiDB.uqTaskPickerProjects.ParamByName('USER_ID').AsString := userId;
apiDB.uqTaskPickerProjects.ParamByName('CUSTOMER_ID').AsString := customerId;
apiDB.uqTaskPickerProjects.Open;
try
......@@ -811,6 +812,9 @@ begin
FieldText(apiDB.uqTaskPickerProjects, 'PROJECT_NAME')
);
Result.options[Result.options.Count - 1].customerId :=
apiDB.uqTaskPickerProjectsCUSTOMER_ID.AsString;
apiDB.uqTaskPickerProjects.Next;
end;
finally
......@@ -819,15 +823,14 @@ begin
end;
function TTimeEntryService.GetTaskPickerTasks(userId, projectId: string): TTaskPickerOptionsResponse;
function TTimeEntryService.GetTaskPickerTasks(projectId: string): TTaskPickerOptionsResponse;
begin
Logger.Log(4, Format('TimeEntryService.GetTaskPickerTasks - USER_ID="%s" PROJECT_ID="%s"', [userId, projectId]));
Logger.Log(4, Format('TimeEntryService.GetTaskPickerTasks - PROJECT_ID="%s"', [projectId]));
Result := TTaskPickerOptionsResponse.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
apiDB.uqTaskPickerTasks.Close;
apiDB.uqTaskPickerTasks.ParamByName('USER_ID').AsString := userId;
apiDB.uqTaskPickerTasks.ParamByName('PROJECT_ID').AsString := projectId;
apiDB.uqTaskPickerTasks.Open;
try
......@@ -890,6 +893,64 @@ begin
end;
end;
function TTimeEntryService.AddTaskToFocus(userId, taskId: string): Boolean;
var
q: TUniQuery;
begin
Logger.Log(4, Format(
'TimeEntryService.AddTaskToFocus - USER_ID="%s" TASK_ID="%s"',
[userId, taskId]
));
q := TUniQuery.Create(nil);
try
q.Connection := apiDB.ucETaskApi;
q.Connection.StartTransaction;
try
q.SQL.Text :=
'select TASK_ID from task_assigned_user ' +
'where USER_ID = :USER_ID and TASK_ID = :TASK_ID';
q.ParamByName('USER_ID').AsString := userId;
q.ParamByName('TASK_ID').AsString := taskId;
q.Open;
if q.IsEmpty then
begin
q.Close;
q.SQL.Text :=
'insert into task_assigned_user ' +
'(USER_ID, TASK_ID, FOCUSED_TASK) ' +
'values (:USER_ID, :TASK_ID, ''T'')';
end
else
begin
q.Close;
q.SQL.Text :=
'update task_assigned_user ' +
'set FOCUSED_TASK = ''T'' ' +
'where USER_ID = :USER_ID and TASK_ID = :TASK_ID';
end;
q.ParamByName('USER_ID').AsString := userId;
q.ParamByName('TASK_ID').AsString := taskId;
q.ExecSQL;
q.Connection.Commit;
Result := True;
except
on E: Exception do
begin
if q.Connection.InTransaction then
q.Connection.Rollback;
Logger.Log(2, 'TimeEntryService.AddTaskToFocus - ERROR: ' + E.Message);
raise;
end;
end;
finally
q.Free;
end;
end;
initialization
RegisterServiceType(TTimeEntryService);
......
[Settings]
MemoLogLevel=4
FileLogLevel=4
MemoLogLevel=5
FileLogLevel=5
webClientVersion=0.9.3
LogFileNum=167
LogFileNum=207
[Database]
--Server=192.168.102.131
--Server=192.168.116.128
--Server=192.168.102.131
--Server=192.168.159.10
Server=192.168.90.129
Server=192.168.90.12
Database=eTask
Username=root
Password=emsys01
......
......@@ -114,11 +114,11 @@
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.3.3;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.3.16;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys>
<VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>9</VerInfo_MinorVer>
<VerInfo_AutoIncVersion>true</VerInfo_AutoIncVersion>
<VerInfo_Build>3</VerInfo_Build>
<VerInfo_Build>16</VerInfo_Build>
<VerInfo_Release>3</VerInfo_Release>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment