Commit bd2cab6e by Mac Stephens

big update to http exception handling - both client and server api calls updated…

big update to http exception handling - both client and server api calls updated with new error modal
parent 7a8ad9bf
...@@ -9,6 +9,7 @@ procedure ShowStatusMessage(const AMessage, AClass: string; const AElementId: st ...@@ -9,6 +9,7 @@ procedure ShowStatusMessage(const AMessage, AClass: string; const AElementId: st
procedure HideStatusMessage(const AElementId: string); procedure HideStatusMessage(const AElementId: string);
procedure ShowSpinner(SpinnerID: string); procedure ShowSpinner(SpinnerID: string);
procedure HideSpinner(SpinnerID: string); procedure HideSpinner(SpinnerID: string);
procedure ShowErrorModal(const msg: string);
function CalculateAge(DateOfBirth: TDateTime): Integer; function CalculateAge(DateOfBirth: TDateTime): Integer;
function FormatPhoneNumber(PhoneNumber: string): string; function FormatPhoneNumber(PhoneNumber: string): string;
procedure ApplyReportTitle(CurrentReportType: string); procedure ApplyReportTitle(CurrentReportType: string);
...@@ -82,6 +83,39 @@ begin ...@@ -82,6 +83,39 @@ begin
end; end;
end; end;
// The $IFNDEF WIN32 was recommended by Holger to deal with any modal issues
procedure ShowErrorModal(const msg: string);
begin
{$IFNDEF WIN32}
asm
var modal = document.getElementById('main_errormodal');
var label = document.getElementById('main_lblmodal_body');
var reloadBtn = document.getElementById('btn_modal_restart');
if (label) label.innerText = msg;
// Ensure modal is a direct child of <body>
if (modal && modal.parentNode !== document.body) {
document.body.appendChild(modal);
}
// Bind hard reload to button
if (reloadBtn) {
reloadBtn.onclick = function () {
window.location.reload(true); // hard reload, bypass cache
};
}
// Show the Bootstrap modal
var bsModal = new bootstrap.Modal(modal, { keyboard: false });
bsModal.show();
end;
{$ENDIF}
end;
function CalculateAge(DateOfBirth: TDateTime): Integer; function CalculateAge(DateOfBirth: TDateTime): Integer;
var var
......
...@@ -125,39 +125,32 @@ begin ...@@ -125,39 +125,32 @@ begin
if PageNumber > 0 then if PageNumber > 0 then
begin begin
Utils.ShowSpinner('spinner'); Utils.ShowSpinner('spinner');
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', [searchOptions])); try
customerList := TJSObject(xdcResponse.Result); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', [searchOptions]));
customerList := TJSObject(xdcResponse.Result);
// Load data into the dataset
xdwdsCustomers.Close; xdwdsCustomers.Close;
xdwdsCustomers.SetJsonData(customerList['data']); xdwdsCustomers.SetJsonData(customerList['data']);
xdwdsCustomers.Open; xdwdsCustomers.Open;
Utils.HideSpinner('spinner'); customerListLength := integer(customerList['count']);
TotalPages := ( (customerListLength + PageSize - 1) div PageSize);
customerListLength := integer(customerList['count']);
TotalPages := ( (customerListLength + PageSize - 1) div PageSize); if customerListLength = 0 then
lblEntries.Caption := 'No entries found'
if customerListLength = 0 then else if (PageNumber * PageSize) < customerListLength then
begin lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
lblEntries.Caption := 'No entries found'; ' - ' + IntToStr(customerListLength) +
end ' of ' + IntToStr(customerListLength)
else if (PageNumber * PageSize) < customerListLength then else
// Currently these do the same thing. If you want to limit the number of entries lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
// You will need to edit the server side, and then change this if statement so the label ' - ' + IntToStr(customerListLength) +
// Correctly displayes. I believe it is IntToStr(PageSize * PageNum) ' of ' + IntToStr(customerListLength);
begin except
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) + on E: EXDataClientRequestException do
' - ' + IntToStr(customerListLength) + Utils.ShowErrorModal('Could not retrieve customers: ' + E.ErrorResult.ErrorMessage);
' of ' + IntToStr(customerListLength);
end
else if (PageNumber * PageSize) >= customerListLength then
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(customerListLength) +
' of ' + IntToStr(customerListLength);
end; end;
Utils.HideSpinner('spinner');
end; end;
end; end;
......
...@@ -103,7 +103,7 @@ begin ...@@ -103,7 +103,7 @@ begin
Utils.ShowSpinner('spinner'); Utils.ShowSpinner('spinner');
end; end;
function TFViewEditUser.AddUser(): string; function TFViewEditUser.AddUser: string;
// Sends UserInfo over to the server so it can be added to the database // Sends UserInfo over to the server so it can be added to the database
var var
userInfo: string; userInfo: string;
...@@ -111,21 +111,26 @@ var ...@@ -111,21 +111,26 @@ var
responseString: TJSObject; responseString: TJSObject;
begin begin
userInfo := '&username=' + edtUsername.Text + userInfo := '&username=' + edtUsername.Text +
'&fullname=' + edtFullName.Text + '&fullname=' + edtFullName.Text +
'&password=' + edtPassword.Text + '&password=' + edtPassword.Text +
'&status=' + BoolToStr(cbStatus.Checked) + '&status=' + BoolToStr(cbStatus.Checked) +
'&email=' + edtEmail.Text + '&email=' + edtEmail.Text +
'&access=' + cbAccess.Text + '&access=' + cbAccess.Text +
'&newuser=' + edtUsername.Text + '&newuser=' + edtUsername.Text +
'&rights=' + edtRights.Text + '&rights=' + edtRights.Text +
'&QB=' + edtQB.Text; '&QB=' + edtQB.Text;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser', try
[userInfo])); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser', [userInfo]));
responseString := TJSObject(xdcResponse.Result); responseString := TJSObject(xdcResponse.Result);
Info := string(responseString['value']); Info := string(responseString['value']);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not add user: ' + E.ErrorResult.ErrorMessage);
end;
end; end;
procedure TFViewEditUser.HideNotification; procedure TFViewEditUser.HideNotification;
begin begin
pnlMessage.ElementHandle.hidden := True; pnlMessage.ElementHandle.hidden := True;
......
...@@ -303,39 +303,45 @@ var ...@@ -303,39 +303,45 @@ var
itemListLength: integer; itemListLength: integer;
begin begin
console.log('correct'); console.log('correct');
if PageNumber > 0 then if PageNumber > 0 then
begin begin
Utils.ShowSpinner('spinner'); Utils.ShowSpinner('spinner');
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetItems', try
[searchOptions])); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetItems',
itemList := TJSObject(xdcResponse.Result); [searchOptions]));
data := TJSArray(itemList['data']); itemList := TJSObject(xdcResponse.Result);
itemListLength := integer(itemList['count']); data := TJSArray(itemList['data']);
ClearTable(); itemListLength := integer(itemList['count']);
Utils.HideSpinner('Spinner'); ClearTable();
for i := 0 to data.Length - 1 do for i := 0 to data.Length - 1 do
begin begin
item := TJSObject(data[i]); item := TJSObject(data[i]);
AddRowToTable(string(item['ID']), string(item['name']), string(item['description']), AddRowToTable(string(item['ID']), string(item['name']), string(item['description']),
string(item['status'])); string(item['status']));
end; end;
TotalPages := (itemListLength + PageSize - 1) div PageSize; TotalPages := (itemListLength + PageSize - 1) div PageSize;
if (PageNumber * PageSize) < itemListLength then if (PageNumber * PageSize) < itemListLength then
begin begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) + lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(PageNumber * PageSize) + ' - ' + IntToStr(PageNumber * PageSize) +
' of ' + IntToStr(itemListLength); ' of ' + IntToStr(itemListLength);
end end
else else
begin begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) + lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(itemListLength) + ' - ' + IntToStr(itemListLength) +
' of ' + IntToStr(itemListLength); ' of ' + IntToStr(itemListLength);
end;
GeneratePagination(TotalPages);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not retrieve items: ' + E.ErrorResult.ErrorMessage);
end; end;
GeneratePagination(TotalPages); Utils.HideSpinner('spinner');
end; end;
end; end;
procedure TFViewItems.btnApplyClick(Sender: TObject); procedure TFViewItems.btnApplyClick(Sender: TObject);
// Button that effectively functions as a GetItems() button // Button that effectively functions as a GetItems() button
var var
...@@ -356,11 +362,16 @@ procedure TFViewItems.AddItem(itemOptions: string); ...@@ -356,11 +362,16 @@ procedure TFViewItems.AddItem(itemOptions: string);
var var
xdcResponse: TXDataClientResponse; xdcResponse: TXDataClientResponse;
begin begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddItem', try
[itemOptions])); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddItem', [itemOptions]));
getItems(GenerateSearchOptions()); getItems(GenerateSearchOptions());
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not add item: ' + E.ErrorResult.ErrorMessage);
end;
end; end;
procedure TFViewItems.wcbPageSizeChange(Sender: TObject); procedure TFViewItems.wcbPageSizeChange(Sender: TObject);
// gets a new amount of items based when the page size is changed // gets a new amount of items based when the page size is changed
begin begin
......
...@@ -69,6 +69,27 @@ ...@@ -69,6 +69,27 @@
</div> </div>
</div> </div>
<div class="modal fade" id="main_errormodal" tabindex="-1" aria-labelledby="main_lblmodal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content shadow-lg">
<div class="modal-header">
<h5 class="modal-title" id="main_lblmodal">Error</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body fs-6 fw-bold" id="main_lblmodal_body">
Please contact EMSystems to solve the issue.
</div>
<div class="modal-footer justify-content-center">
<button type="button" id="btn_modal_restart" class="btn btn-primary">Restart WebApp</button>
</div>
</div>
</div>
</div>
...@@ -315,4 +315,5 @@ begin ...@@ -315,4 +315,5 @@ begin
FChildForm := TFViewUsers.CreateForm(WebPanel1.ElementID, Info); FChildForm := TFViewUsers.CreateForm(WebPanel1.ElementID, Info);
end; end;
end. end.
...@@ -394,32 +394,43 @@ var ...@@ -394,32 +394,43 @@ var
searchOptions, pdfURL: string; searchOptions, pdfURL: string;
jsObject: TJSObject; jsObject: TJSObject;
begin begin
try
// Call the server method to generate the PDF // Call the server method to generate the PDF
console.log(orderID); console.log(orderID);
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderCuttingPDF', [orderID])); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderCuttingPDF', [orderID]));
jsObject := JS.TJSObject(xdcResponse.Result); jsObject := JS.TJSObject(xdcResponse.Result);
pdfURL := JS.toString(jsObject.Properties['value']); pdfURL := JS.toString(jsObject.Properties['value']);
// Open the PDF in a new browser tab without needing a different form // Open the PDF in a new browser tab without needing a different form
// This method is much faster too, even for large datasets // This method is much faster too, even for large datasets
window.open(pdfURL, '_blank'); window.open(pdfURL, '_blank');
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not generate cutting die PDF: ' + E.ErrorResult.ErrorMessage);
end;
end; end;
procedure TFOrderEntryCuttingDie.AddCuttingDieOrder(orderJSON: TJSONObject); procedure TFOrderEntryCuttingDie.AddCuttingDieOrder(orderJSON: TJSONObject);
// sends the order JSON object to the server // sends the order JSON object to the server
var var
Response: TXDataClientResponse; Response: TXDataClientResponse;
jsObj: TJSObject; jsObj: TJSObject;
begin begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCuttingDieOrder', try
[orderJSON.ToString])); Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCuttingDieOrder',
jsObj := JS.TJSObject(Response.Result); [orderJSON.ToString]));
if mode = 'ADD' then jsObj := JS.TJSObject(Response.Result);
OrderID := String(jsObj.Properties['OrderID']); if mode = 'ADD' then
mode := 'EDIT'; OrderID := String(jsObj.Properties['OrderID']);
mode := 'EDIT';
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not save cutting die order: ' + E.ErrorResult.ErrorMessage);
end;
end; end;
class function TFOrderEntryCuttingDie.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm; class function TFOrderEntryCuttingDie.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm;
var var
localMode: string; localMode: string;
...@@ -438,7 +449,6 @@ begin ...@@ -438,7 +449,6 @@ begin
end; end;
end end
); );
end; end;
procedure TFOrderEntryCuttingDie.btnAddClick(Sender: TObject); procedure TFOrderEntryCuttingDie.btnAddClick(Sender: TObject);
...@@ -513,50 +523,57 @@ var ...@@ -513,50 +523,57 @@ var
data: TJSArray; data: TJSArray;
order, items: TJSObject; order, items: TJSObject;
begin begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCuttingDieOrder', Utils.ShowSpinner('spinner');
[Order_ID])); try
order := TJSObject(xdcResponse.Result); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCuttingDieOrder',
data := TJSArray(order['data']); [Order_ID]));
XDataWebDataSet1.Close; order := TJSObject(xdcResponse.Result);
XDataWebDataSet1.SetJsonData(order); data := TJSArray(order['data']);
XDataWebDataSet1.Open; XDataWebDataSet1.Close;
XDataWebDataSet1.SetJsonData(order);
XDataWebDataSet1.Open;
// Check boxes and dates need to be manually set
if not (XDataWebDataSet1staff_fields_order_date.AsString = '') then
dtpOrderDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_order_date.Value)
else
dtpOrderDate.Date := 0;
if not (XDataWebDataSet1staff_fields_proof_date.AsString = '') then
dtpProofDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_proof_date.AsString)
else
dtpProofDate.Date := 0;
if not (XDataWebDataSet1staff_fields_ship_date.AsString = '') then
dtpShipDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_ship_date.AsString)
else
dtpShipDate.Date := 0;
// Check boxes and dates need to be manually set console.log(mode);
console.log(XDataWebDataSet1COMPANY_ID.AsString);
if mode = 'EDIT' then
CustomerID := XDataWebDataSet1COMPANY_ID.AsString;
console.log(CustomerID);
if not (XDataWebDataSet1staff_fields_order_date.AsString = '') then if mode = 'EDIT' then
dtpOrderDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_order_date.Value) begin
else CustomerID := XDataWebDataSet1COMPANY_ID.AsString;
dtpOrderDate.Date := 0; xdwdsShipTo.Close;
if not (XDataWebDataSet1staff_fields_proof_date.AsString = '') then xdwdsShipTo.SetJSONData(order['ADDRESS_LIST']);
dtpProofDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_proof_date.AsString) xdwdsShipTo.Open;
else end;
dtpProofDate.Date := 0;
if not (XDataWebDataSet1staff_fields_ship_date.AsString = '') then
dtpShipDate.Date := StrToDateTime(XDataWebDataSet1staff_fields_ship_date.AsString)
else
dtpShipDate.Date := 0;
console.log(mode); xdwdsQBItem.Close;
console.log(XDataWebDataSet1COMPANY_ID.AsString); items := TJSObject(order['ITEMS']);
if mode = 'EDIT' then xdwdsQBItem.SetJsonData(items['data']);
CustomerID := XDataWebDataSet1COMPANY_ID.AsString; xdwdsQBITEM.Open;
console.log(CustomerID);
if mode = 'EDIT' then except
begin on E: EXDataClientRequestException do
CustomerID := XDataWebDataSet1COMPANY_ID.AsString; Utils.ShowErrorModal('Could not retrieve order: ' + E.ErrorResult.ErrorMessage);
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(order['ADDRESS_LIST']);
xdwdsShipTo.Open;
end; end;
Utils.HideSpinner('spinner');
xdwdsQBItem.Close;
items := TJSObject(order['ITEMS']);
xdwdsQBItem.SetJsonData(items['data']);
xdwdsQBITEM.Open;
end; end;
procedure TFOrderEntryCuttingDie.getCustomer(customerID: string); procedure TFOrderEntryCuttingDie.getCustomer(customerID: string);
// gets a customer from the database then loads the appropiate fields // gets a customer from the database then loads the appropiate fields
var var
......
object FViewOrders: TFViewOrders object FViewOrders: TFViewOrders
Width = 676 Width = 676
Height = 480 Height = 480
Caption = 'main.errorpanel'
CSSLibrary = cssBootstrap CSSLibrary = cssBootstrap
ElementFont = efCSS ElementFont = efCSS
Font.Charset = DEFAULT_CHARSET Font.Charset = DEFAULT_CHARSET
......
...@@ -13,7 +13,7 @@ uses ...@@ -13,7 +13,7 @@ uses
WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls, WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage, WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls, ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
XData.Web.JsonDataset, WEBLib.DB, Data.DB, XData.Web.Dataset, XData.Web.JsonDataset, WEBLib.DB, Data.DB, XData.Web.Dataset, XData.Web.DatasetCommon,
WEBLib.Grids; WEBLib.Grids;
type type
...@@ -156,23 +156,25 @@ var ...@@ -156,23 +156,25 @@ var
searchOptions, pdfURL: string; searchOptions, pdfURL: string;
jsObject: TJSObject; jsObject: TJSObject;
begin begin
searchOptions := edtSearch.Text; Utils.ShowSpinner('spinner');
try
// Call the server method to generate the PDF searchOptions := edtSearch.Text;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderListPDF', [searchOptions]));
jsObject := JS.TJSObject(xdcResponse.Result); // Call the server method to generate the PDF
pdfURL := JS.toString(jsObject.Properties['value']); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderListPDF', [searchOptions]));
jsObject := JS.TJSObject(xdcResponse.Result);
// Open the PDF in a new browser tab without needing a different form pdfURL := JS.toString(jsObject.Properties['value']);
// This method is much faster too, even for large datasets
window.open(pdfURL, '_blank'); // Open the PDF in a new browser tab
begin window.open(pdfURL, '_blank');
Utils.HideSpinner('Spinner'); except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not generate report PDF: ' + E.ErrorResult.ErrorMessage);
end; end;
Utils.HideSpinner('spinner');
end; end;
procedure TFViewOrders.WebButton1Click(Sender: TObject); procedure TFViewOrders.WebButton1Click(Sender: TObject);
begin begin
if OrderID <> '' then if OrderID <> '' then
...@@ -651,57 +653,56 @@ begin ...@@ -651,57 +653,56 @@ begin
end); end);
PageItem.appendChild(PageLink); PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem); PaginationElement.appendChild(PageItem);
end; end;
procedure TFViewOrders.GetOrders(searchOptions: string); procedure TFViewOrders.GetOrders(searchOptions: string);
// retrieves a list of orders that fit a given search criteria
// searchOptions: search info to be sent to the server
var var
xdcResponse: TXDataClientResponse; xdcResponse: TXDataClientResponse;
orderList: TJSObject; orderList: TJSObject;
orderListLength: integer; orderListLength, TotalPages: Integer;
TotalPages: integer;
begin begin
Utils.ShowSpinner('spinner'); Utils.ShowSpinner('spinner');
if PageNumber > 0 then try
begin try
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetOrders', [searchOptions])); xdcResponse := await(XDataWebClient1.RawInvokeAsync(
orderList := TJSObject(xdcResponse.Result); 'ILookupService.GetOrders', [searchOptions]));
// Load data into the dataset if Assigned(xdcResponse.Result) then
xdwdsOrders.Close; begin
xdwdsOrders.SetJsonData(orderList['data']); orderList := TJSObject(xdcResponse.Result);
xdwdsOrders.Open; xdwdsOrders.Close;
xdwdsOrders.SetJsonData(orderList['data']);
orderListLength := integer(orderList['count']); xdwdsOrders.Open;
TotalPages := ( (orderListLength + PageSize - 1) div PageSize);
orderListLength := Integer(orderList['count']);
TotalPages := (orderListLength + PageSize - 1) div PageSize;
GeneratePagination(TotalPages);
// Update label
if orderListLength = 0 then
lblEntries.Caption := 'No entries found'
else if (PageNumber * PageSize) < orderListLength then
lblEntries.Caption := Format('Showing entries %d - %d of %d',
[(PageNumber - 1) * PageSize + 1, PageNumber * PageSize, orderListLength])
else
lblEntries.Caption := Format('Showing entries %d - %d of %d',
[(PageNumber - 1) * PageSize + 1, orderListLength, orderListLength]);
end;
if orderListLength = 0 then except
begin on E: EXDataClientRequestException do
lblEntries.Caption := 'No entries found'; Utils.ShowErrorModal('Could not retrieve orders: ' + E.ErrorResult.ErrorMessage);
end
else if (PageNumber * PageSize) < orderListLength then
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(PageNumber * PageSize) +
' of ' + IntToStr(orderListLength);
end
else if (PageNumber * PageSize) >= orderListLength then
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(orderListLength) +
' of ' + IntToStr(orderListLength);
end; end;
finally
// Optional: Continue using pagination if needed
GeneratePagination(TotalPages);
Utils.HideSpinner('spinner'); Utils.HideSpinner('spinner');
end; end;
end; end;
procedure TFViewOrders.btnAddOrderClick(Sender: TObject); procedure TFViewOrders.btnAddOrderClick(Sender: TObject);
begin begin
ShowAddOrderForm(); ShowAddOrderForm();
......
...@@ -97,21 +97,26 @@ var ...@@ -97,21 +97,26 @@ var
customerList: TJSObject; customerList: TJSObject;
i: integer; i: integer;
begin begin
// Fetch data from XData service try
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.getQBCustomers', [])); // Fetch data from XData service
customerList := TJSObject(xdcResponse.Result); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.getQBCustomers', []));
customerList := TJSObject(xdcResponse.Result);
// Load data into TXDataWebDataset
// Load data into TXDataWebDataset
xdwdsCustomers.Close; xdwdsCustomers.Close;
xdwdsCustomers.SetJsonData(customerList); xdwdsCustomers.SetJsonData(customerList);
xdwdsCustomers.Open; xdwdsCustomers.Open;
// Manually populate the grid // Manually populate the grid
PopulateGridManually; PopulateGridManually;
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not retrieve QuickBooks customers: ' + E.ErrorResult.ErrorMessage);
end;
Utils.HideSpinner('spinner'); Utils.HideSpinner('spinner');
end; end;
procedure TFSelectCustomer.PopulateGridManually; procedure TFSelectCustomer.PopulateGridManually;
// populates the grid with customers manually. // populates the grid with customers manually.
var var
......
...@@ -6,7 +6,7 @@ uses ...@@ -6,7 +6,7 @@ uses
System.SysUtils, System.Classes, Web, WEBLib.Graphics, WEBLib.Forms, WEBLib.Dialogs, System.SysUtils, System.Classes, Web, WEBLib.Graphics, WEBLib.Forms, WEBLib.Dialogs,
Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, WEBLib.Controls, WEBLib.Grids, WebLib.Lists, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, WEBLib.Controls, WEBLib.Grids, WebLib.Lists,
XData.Web.Client, WEBLib.ExtCtrls, DB, XData.Web.JsonDataset, XData.Web.Client, WEBLib.ExtCtrls, DB, XData.Web.JsonDataset,
XData.Web.Dataset, XData.Web.Connection, Vcl.Forms, WEBLib.DBCtrls, JS; XData.Web.Dataset, XData.Web.Connection, Vcl.Forms, WEBLib.DBCtrls, JS, Utils;
type type
TFViewUsers = class(TWebForm) TFViewUsers = class(TWebForm)
...@@ -330,44 +330,50 @@ var ...@@ -330,44 +330,50 @@ var
data: TJSArray; data: TJSArray;
user: TJSObject; user: TJSObject;
userListLength: integer; userListLength: integer;
begin begin
if PageNumber > 0 then if PageNumber > 0 then
begin begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetUsers', Utils.ShowSpinner('spinner');
[searchOptions])); try
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetUsers',
userList := TJSObject(xdcResponse.Result); [searchOptions]));
data := TJSArray(userList['data']);
userListLength := integer(userList['count']); userList := TJSObject(xdcResponse.Result);
ClearTable(); data := TJSArray(userList['data']);
XDataWebDataSet1.Close; userListLength := integer(userList['count']);
XDataWebDataSet1.SetJsonData(userList['data']); ClearTable();
XDataWebDataSet1.Open; XDataWebDataSet1.Close;
for i := 0 to data.Length - 1 do XDataWebDataSet1.SetJsonData(userList['data']);
begin XDataWebDataSet1.Open;
user := TJSObject(data[i]); for i := 0 to data.Length - 1 do
AddRowToTable(XDataWebDataSet1userID.AsString, XDataWebDataSet1username.AsString, begin
XDataWebDataSet1password.AsString, XDataWebDataSet1full_name.AsString, user := TJSObject(data[i]);
XDataWebDataSet1status.AsString, XDataWebDataSet1email_address.AsString, AddRowToTable(XDataWebDataSet1userID.AsString, XDataWebDataSet1username.AsString,
XDataWebDataSet1Atype.AsString, XDataWebDataSet1perspectiveID.AsString, XDataWebDataSet1password.AsString, XDataWebDataSet1full_name.AsString,
XDataWebDataSet1QBID.AsString, XDataWebDataSet1rights.AsInteger); XDataWebDataSet1status.AsString, XDataWebDataSet1email_address.AsString,
XDataWebDataSet1.Next; XDataWebDataSet1Atype.AsString, XDataWebDataSet1perspectiveID.AsString,
end; XDataWebDataSet1QBID.AsString, XDataWebDataSet1rights.AsInteger);
TotalPages := (userListLength + PageSize - 1) div PageSize; XDataWebDataSet1.Next;
if (PageNumber * PageSize) < userListLength then end;
begin TotalPages := (userListLength + PageSize - 1) div PageSize;
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) + if (PageNumber * PageSize) < userListLength then
' - ' + IntToStr(PageNumber * PageSize) + begin
' of ' + IntToStr(userListLength); lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
end ' - ' + IntToStr(PageNumber * PageSize) +
else ' of ' + IntToStr(userListLength);
begin end
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) + else
' - ' + IntToStr(userListLength) + begin
' of ' + IntToStr(userListLength); lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(userListLength) +
' of ' + IntToStr(userListLength);
end;
GeneratePagination(TotalPages);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal('Could not retrieve users: ' + E.ErrorResult.ErrorMessage);
end; end;
GeneratePagination(TotalPages); Utils.HideSpinner('spinner');
end; end;
end; end;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<MainSource>webKGOrders.dpr</MainSource> <MainSource>webKGOrders.dpr</MainSource>
<Base>True</Base> <Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config> <Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform> <Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms> <TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType> <AppType>Application</AppType>
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
MemoLogLevel=3 MemoLogLevel=3
FileLogLevel=5 FileLogLevel=5
webClientVersion=0.9.4 webClientVersion=0.9.4
LogFileNum=701 LogFileNum=719
[Database] [Database]
Server=192.168.159.131 --Server=192.168.159.131
--Server=192.168.102.130 Server=192.168.102.130
--Server=192.168.75.133 --Server=192.168.75.133
Database=kg_order_entry Database=kg_order_entry
Username=root Username=root
...@@ -17,6 +17,6 @@ Password=emsys01 ...@@ -17,6 +17,6 @@ Password=emsys01
CompanyID=9341454272655710 CompanyID=9341454272655710
ClientID=ABgO14uvjh8XqLud7spQ8lkb98AUpcdA7HbyMJfCAtl65sQ5yy ClientID=ABgO14uvjh8XqLud7spQ8lkb98AUpcdA7HbyMJfCAtl65sQ5yy
ClientSecret=bQ06TRemHeAGFzVHRaTUvUoBU9jpU9itK6MOMgqN ClientSecret=bQ06TRemHeAGFzVHRaTUvUoBU9jpU9itK6MOMgqN
RefreshToken=RT1-60-H0-1758811104981v5rmhboxz6ul6wqho RefreshToken=RT1-7-H0-1758919884sgbdvdaawcewm26l9f9k
AccessToken=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwieC5vcmciOiJIMCJ9..KXZ2aHmt3JzwsJaoKRo_BA.GUVXmUIAgHt28CVuT1CDpBWLVxzhkpXwoUhIxfUvWlSzzc5HBrtOUd7GRQtij2NciITS4W_Gsyc5J_SLNjayFfrTPuZDfFFTmfnfkCOEvzw_dWgXLshTSFX9kkLdHH7IMIuRwNsvH907ECdWMazzY0r0wuGWcU4c1EphwYXqAeorH43ONIBtl0JTbiNtCUVdptn5UCF2VgN74bO3MbfSTtQIN8lKFJgGAKsnXolpK71D4OYS2-YW9dH8XFL1K8FD5fauNWb-pn4MxwQ1Y_vOEIB_bF26IM7Pdh7uG-mQSO-ljhXWTEqYmWjK-Z9P_Igznwcqy6RIhtEu216dGpF43JIuGgHxta_yRJLGYsdWjnQbIqW6VvZ4x8jwuLGX0cCu2mKcxkjgghABol6D34lWQcov3Q32oa5ZlIkTzolOxTnlYZ-hhtQBcY-X08CfnPJ3y2Yq4FKAFiu7wBRQ5V0l1RzyPHCkGDJKNNv-yY5aTpRkPwsjdko9xgIAB4gWSyGV-PKoSURNu5jodxQkAcMMIh59y7QuKM5WytAfAtpklGfqEj-vn-d2cWY9-zWfmw0D1KVakH0da5xxdnqr5qO4a1w_b2RT6zVfNvfJRApSlMpes1DZ6Bo_K0yo5rxzUpg0.kkYUlFG-TCl21bRQWpVMaA AccessToken=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwieC5vcmciOiJIMCJ9..OvT3ztJMwwJz7VSYEwhdBg.9iJ-2Gigq5PPVxIDTNVmIyQJOXn0UBlrFYXov83TIjLu8KvS7E4s4FSlgIc11AG-jYWu4fWHwFVwRIqeOPqEtzSrMk_hAGc07jotA9mi6MD8UpAWl_1Y1fPKuBYSe9X_00DlhCclLIMP04fn77iU71DdxC0MweciovuHDK3Gy-X26DDR_yueejvjPoHsEwhMSVshbmElgaNe2dOqtDPIuwre22piNPST7ws9o6v0wuq3juYEtW1h7qZM-S-c5yZgG25RzzFG0mShbzdfnpHimhW2n6-IGr7-ESveMOfeMHuW5M0q-QGK0IuMLIqTrRKyDl_3LXOHZSQWuAuvFpLE_EXcuRrm1JXgl43nh5U2y0MzG6JnN2pQhY_tjKdvNZmvj2XCHLKOmifLUanOhWq20bg__aZLM69iJC3VBlZeKvhqZMgNeAffle3yOX6d5cVNHCmGoZnqMXUebPzKqp-dgvoDx7qaa780Tozh2l32DDFmAStTgIYtuUxI9y5g18SnD9en2RcrUIksSEyOUMZrbfyEcN3zA0DSw6K6sqhcFAW_rMFoUqZK2sV0rZYGwmOpCN82ka_8uXke28fInem7aXpxaqOQOuxFEbBUpZxS-oTJ879-LtRs6gE8OzrwjIgF.sqyNz-sm9cjo343x7HnRvw
LastRefresh=6/16/2025 10:38:38 AM LastRefresh=6/17/2025 4:51:25 PM
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