Commit d7a47844 by Elias Sarraf

Merge remote-tracking branch 'origin/cam'

parents 85750ff1 d217635b
...@@ -45,6 +45,7 @@ procedure LoadConfig(LoadProc: TConfigLoadedProc); ...@@ -45,6 +45,7 @@ procedure LoadConfig(LoadProc: TConfigLoadedProc);
if JS.toString(Obj['ApiUrl']) <> '' then if JS.toString(Obj['ApiUrl']) <> '' then
Config.ApiUrl := JS.toString(Obj['ApiUrl']); Config.ApiUrl := JS.toString(Obj['ApiUrl']);
end; end;
finally finally
LoadProc(Config); LoadProc(Config);
......
...@@ -19,7 +19,7 @@ type ...@@ -19,7 +19,7 @@ type
FUnauthorizedAccessProc: TUnauthorizedAccessProc; FUnauthorizedAccessProc: TUnauthorizedAccessProc;
public public
const clientVersion = '0.9.13.3'; const clientVersion = '0.9.13.9';
procedure InitApp(SuccessProc: TSuccessProc; procedure InitApp(SuccessProc: TSuccessProc;
UnauthorizedAccessProc: TUnauthorizedAccessProc); UnauthorizedAccessProc: TUnauthorizedAccessProc);
procedure SetClientConfig(Callback: TVersionCheckCallback); procedure SetClientConfig(Callback: TVersionCheckCallback);
......
...@@ -6,7 +6,7 @@ object FViewAddCustomer: TFViewAddCustomer ...@@ -6,7 +6,7 @@ object FViewAddCustomer: TFViewAddCustomer
object lblFormState: TWebLabel object lblFormState: TWebLabel
Left = 395 Left = 395
Top = 8 Top = 8
Width = 26 Width = 3
Height = 15 Height = 15
ElementID = 'lbl_form_state' ElementID = 'lbl_form_state'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
...@@ -408,6 +408,7 @@ object FViewAddCustomer: TFViewAddCustomer ...@@ -408,6 +408,7 @@ object FViewAddCustomer: TFViewAddCustomer
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnChange = wdblcbRepChange OnChange = wdblcbRepChange
OnEnter = wdblcbRepChange
DataField = 'REP_USER_ID' DataField = 'REP_USER_ID'
DataSource = WebDataSource1 DataSource = WebDataSource1
KeyField = 'userID' KeyField = 'userID'
......
...@@ -370,8 +370,8 @@ begin ...@@ -370,8 +370,8 @@ begin
XDataWebDataSet1.Edit; XDataWebDataSet1.Edit;
XDataWebDataSet1QB_LIST_ID.AsString := newform.QB_ID; XDataWebDataSet1QB_LIST_ID.AsString := newform.QB_ID;
XDataWebDataSet1.Post; XDataWebDataSet1.Post;
UpdateCustomer();
end; end;
end end
); );
end; end;
......
...@@ -132,18 +132,18 @@ object FViewMain: TFViewMain ...@@ -132,18 +132,18 @@ object FViewMain: TFViewMain
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object lblLinkToQB: TWebLabel object lblQBInfo: TWebLabel
Left = 538 Left = 552
Top = 128 Top = 126
Width = 49 Width = 36
Height = 14 Height = 14
Caption = 'Link to QB' Caption = 'QB Info'
ElementID = 'dropdown.menu.linktoqb' ElementID = 'dropdown.menu.linktoqb'
ElementFont = efCSS ElementFont = efCSS
HeightStyle = ssAuto HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = lblLinkToQBClick OnClick = lblQBInfoClick
end end
object WebPanel1: TWebPanel object WebPanel1: TWebPanel
Left = 77 Left = 77
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
<a class="dropdown-item" id="dropdown.menu.users" href="#"><i class="fas fa-address-book fa-fw"></i><span> Users</span></a> <a class="dropdown-item" id="dropdown.menu.users" href="#"><i class="fas fa-address-book fa-fw"></i><span> Users</span></a>
</li> </li>
<li> <li>
<a class="dropdown-item" id="dropdown.menu.linktoqb" href="#"><i class="fas fa-book fa-fw"></i><span> Link to QB</span></a> <a class="dropdown-item" id="dropdown.menu.linktoqb" href="#"><i class="fas fa-book fa-fw"></i><span> QB Info</span></a>
</li> </li>
<li> <li>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
......
...@@ -6,7 +6,8 @@ uses ...@@ -6,7 +6,8 @@ uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls, System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, WEBLib.ExtCtrls, Vcl.Controls, Vcl.StdCtrls, WEBLib.Forms, WEBLib.Dialogs, WEBLib.ExtCtrls, Vcl.Controls, Vcl.StdCtrls,
WEBLib.StdCtrls, Data.DB, XData.Web.JsonDataset, XData.Web.Dataset, WEBLib.StdCtrls, Data.DB, XData.Web.JsonDataset, XData.Web.Dataset,
App.Types, ConnectionModule, XData.Web.Client, WEBLib.Menus, Utils; App.Types, ConnectionModule, XData.Web.Client, WEBLib.Menus, Utils, System.IOUtils,
Vcl.Forms;
type type
TFViewMain = class(TWebForm) TFViewMain = class(TWebForm)
...@@ -24,7 +25,7 @@ type ...@@ -24,7 +25,7 @@ type
lblorders: TWebLabel; lblorders: TWebLabel;
lblCustomers: TWebLabel; lblCustomers: TWebLabel;
lblVersion: TWebLabel; lblVersion: TWebLabel;
lblLinkToQB: TWebLabel; lblQBInfo: TWebLabel;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure mnuLogoutClick(Sender: TObject); procedure mnuLogoutClick(Sender: TObject);
procedure wllblUserProfileClick(Sender: TObject); procedure wllblUserProfileClick(Sender: TObject);
...@@ -34,7 +35,7 @@ type ...@@ -34,7 +35,7 @@ type
procedure lblUsersClick(Sender: TObject); procedure lblUsersClick(Sender: TObject);
procedure lblordersClick(Sender: TObject); procedure lblordersClick(Sender: TObject);
procedure lblCustomersClick(Sender: TObject); procedure lblCustomersClick(Sender: TObject);
procedure lblLinkToQBClick(Sender: TObject); procedure lblQBInfoClick(Sender: TObject);
{ Private declarations } { Private declarations }
private private
FUserInfo: string; FUserInfo: string;
...@@ -47,6 +48,7 @@ type ...@@ -47,6 +48,7 @@ type
function GetUserInfo: string; function GetUserInfo: string;
procedure setActive(page: string); procedure setActive(page: string);
procedure ConfirmLogout; procedure ConfirmLogout;
procedure ShowQBInfoForm();
public public
{ Public declarations } { Public declarations }
class procedure Display(LogoutProc: TLogoutProc); class procedure Display(LogoutProc: TLogoutProc);
...@@ -81,7 +83,9 @@ uses ...@@ -81,7 +83,9 @@ uses
View.OrderEntryCorrugated, View.OrderEntryCorrugated,
View.OrderEntryCuttingDie, View.OrderEntryCuttingDie,
View.OrderEntryWeb, View.OrderEntryWeb,
View.Customers, View.Customer.Add; View.Customers,
View.Customer.Add,
View.QBInfo;
{$R *.dfm} {$R *.dfm}
...@@ -99,7 +103,7 @@ begin ...@@ -99,7 +103,7 @@ begin
if (not (JS.toString(AuthService.TokenPayload.Properties['user_access_type']) = 'ADMIN')) then if (not (JS.toString(AuthService.TokenPayload.Properties['user_access_type']) = 'ADMIN')) then
begin begin
lblUsers.enabled := false; lblUsers.enabled := false;
lblLinkToQB.Enabled := false; lblQBInfo.Enabled := false;
lblCustomers.Enabled := false; lblCustomers.Enabled := false;
end; end;
lblAppTitle.Caption := 'Koehler-Gibson Orders'; lblAppTitle.Caption := 'Koehler-Gibson Orders';
...@@ -176,20 +180,43 @@ begin ...@@ -176,20 +180,43 @@ begin
ShowToast('Please Save or Cancel your changes', 'danger'); ShowToast('Please Save or Cancel your changes', 'danger');
end; end;
procedure TFViewMain.lblQBInfoClick(Sender: TObject);
procedure TFViewMain.lblLinkToQBClick(Sender: TObject);
var var
qblink: string; qblink, redirectUri: string;
qbWindow: TJSWindow; qbWindow: TJSWindow;
begin begin
qblink := 'https://appcenter.intuit.com/connect/oauth2'; ShowQBInfoForm();
qblink := qblink + '?client_id=ABYqlDx1EsacZYXvHIJ7RDB7zmnQdwABU3fwQLIZPmBgU0VW1P'; end;
qblink := qblink + '&response_type=code';
qblink := qblink + '&scope=com.intuit.quickbooks.accounting'; procedure TFViewMain.ShowQBInfoForm();
qblink := qblink + '&redirect_uri=http://localhost:2004/kgOrders/auth/AuthService/Authorize&state=7'; var
qbWindow := window.open('', '_blank'); newform: TFQBInfo;
if Assigned(qbWindow) then begin
qbWindow.location.href := qbLink; newform := TFQBInfo.CreateNew;
newform.Caption := 'Quickbooks information';
newForm.Popup := True;
newForm.Border := fbDialog;
newForm.Position := poScreenCenter;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
begin
// if newform.confirm then
// begin
// if newform.cbCorrugatedPlate.Checked then
// orderType := 'corrugated'
// else if newform.cbWebPlate.Checked then
// orderType := 'web'
// else
// orderType := 'cutting';
// orderEntry('', newForm.DBID, 'ADD', orderType);
// end;
end
);
end; end;
procedure TFViewMain.setActive(page: string); procedure TFViewMain.setActive(page: string);
......
object FQBInfo: TFQBInfo
Width = 449
Height = 191
OnCreate = WebFormCreate
OnShow = WebFormShow
object lblConnected: TWebLabel
Left = 16
Top = 8
Width = 7
Height = 32
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -24
Font.Name = 'Segoe UI'
Font.Style = []
HeightPercent = 100.000000000000000000
ParentFont = False
WidthPercent = 100.000000000000000000
end
object lblCompanyName: TWebLabel
Left = 16
Top = 46
Width = 120
Height = 21
Caption = 'Company Name: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'Segoe UI'
Font.Style = []
HeightPercent = 100.000000000000000000
ParentFont = False
WidthPercent = 100.000000000000000000
end
object lblCompanyID: TWebLabel
Left = 15
Top = 73
Width = 93
Height = 21
Caption = 'Company ID: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'Segoe UI'
Font.Style = []
HeightPercent = 100.000000000000000000
ParentFont = False
WidthPercent = 100.000000000000000000
end
object lblLastRefresh: TWebLabel
Left = 16
Top = 100
Width = 92
Height = 21
Caption = 'Last Refresh: '
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'Segoe UI'
Font.Style = []
HeightPercent = 100.000000000000000000
ParentFont = False
WidthPercent = 100.000000000000000000
end
object btnLinkToQB: TWebButton
Left = 13
Top = 137
Width = 96
Height = 25
Caption = 'Link to QB'
ChildOrder = 3
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnLinkToQBClick
end
object btnClose: TWebButton
Left = 115
Top = 137
Width = 96
Height = 25
Caption = 'Close'
ChildOrder = 3
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnCloseClick
end
object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 376
Top = 63
end
end
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>TMS Web Project</title>
<style>
</style>
</head>
<body>
</body>
</html>
\ No newline at end of file
unit View.QBInfo;
interface
uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls,
XData.Web.Client, ConnectionModule;
type
TFQBInfo = class(TWebForm)
lblConnected: TWebLabel;
lblCompanyName: TWebLabel;
lblCompanyID: TWebLabel;
btnLinkToQB: TWebButton;
XDataWebClient1: TXDataWebClient;
lblLastRefresh: TWebLabel;
btnClose: TWebButton;
procedure btnLinkToQBClick(Sender: TObject);
procedure WebFormCreate(Sender: TObject);
procedure WebFormShow(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
private
{ Private declarations }
ClientID: string;
[async] procedure GetQBInfo();
public
{ Public declarations }
end;
var
FQBInfo: TFQBInfo;
implementation
{$R *.dfm}
uses View.Main, Utils;
procedure TFQBInfo.btnLinkToQBClick(Sender: TObject);
var
qblink, redirectUri: string;
qbWindow: TJSWindow;
begin
qblink := 'https://appcenter.intuit.com/connect/oauth2';
qblink := qblink + '?client_id=' + ClientID;
qblink := qblink + '&response_type=code';
qblink := qblink + '&scope=com.intuit.quickbooks.accounting';
qblink := qblink + '&state=7';
redirectUri := DMConnection.AuthConnection.URL + 'AuthService/QBAuthorize';
qblink := qblink + '&redirect_uri=' + RedirectUri;
console.log(redirectUri);
console.log(qbLink);
qbWindow := window.open('', '_blank');
if Assigned(qbWindow) then
qbWindow.location.href := qbLink;
Close();
end;
procedure TFQBInfo.WebFormCreate(Sender: TObject);
begin
if not DMConnection.ApiConnection.Connected then
begin
DMConnection.ApiConnection.OpenAsync;
console.log('report requirements connection open')
end;
end;
procedure TFQBInfo.WebFormShow(Sender: TObject);
begin
GetQBInfo();
end;
procedure TFQBInfo.btnCloseClick(Sender: TObject);
begin
Close();
end;
procedure TFQBInfo.GetQBInfo();
// retrieves customer list from server
var
xdcResponse: TXDataClientResponse;
QBInfo: TJSObject;
begin
try
Utils.ShowSpinner('spinner');
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.getQBInfo', []));
QBInfo := TJSObject(xdcResponse.Result);
ClientID := String(QBInfo['clientID']);
console.log(QBInfo);
if boolean(QBInfo['connected']) then
begin
lblCompanyName.Caption := lblCompanyName.Caption + String(QBInfo['CompanyName']);
lblCompanyID.Caption := lblCompanyID.Caption + String(QBInfo['CompanyID']);
lblConnected.Caption := 'QuickBooks is connected.';
lblLastRefresh.Caption := lblLastRefresh.Caption + String(QBInfo['LastRefresh']);
end
else
lblConnected.Caption := 'Quickbooks is not connected.';
Utils.HideSpinner('spinner');
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
end;
end;
end.
...@@ -29,7 +29,8 @@ uses ...@@ -29,7 +29,8 @@ uses
View.Address.Add in 'View.Address.Add.pas' {FViewAddAddress: TWebForm} {*.html}, View.Address.Add in 'View.Address.Add.pas' {FViewAddAddress: TWebForm} {*.html},
View.Customer.Select in 'View.Customer.Select.pas' {FSelectCustomer: TWebForm} {*.html}, View.Customer.Select in 'View.Customer.Select.pas' {FSelectCustomer: TWebForm} {*.html},
Utils in 'Utils.pas', Utils in 'Utils.pas',
View.Item.Add in 'View.Item.Add.pas' {fViewAddItem: TWebForm} {*.html}; View.Item.Add in 'View.Item.Add.pas' {fViewAddItem: TWebForm} {*.html},
View.QBInfo in 'View.QBInfo.pas' {FQBInfo: TWebForm} {*.html};
{$R *.res} {$R *.res}
......
...@@ -216,6 +216,11 @@ ...@@ -216,6 +216,11 @@
<Form>fViewAddItem</Form> <Form>fViewAddItem</Form>
<DesignClass>TWebForm</DesignClass> <DesignClass>TWebForm</DesignClass>
</DCCReference> </DCCReference>
<DCCReference Include="View.QBInfo.pas">
<Form>FQBInfo</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<None Include="index.html"/> <None Include="index.html"/>
<None Include="css\app.css"/> <None Include="css\app.css"/>
<None Include="config\config.json"/> <None Include="config\config.json"/>
...@@ -288,6 +293,12 @@ ...@@ -288,6 +293,12 @@
<Overwrite>true</Overwrite> <Overwrite>true</Overwrite>
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="css\spinner.css" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="css\spinner.css" Configuration="Release" Class="ProjectFile"> <DeployFile LocalName="css\spinner.css" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
......
...@@ -41,7 +41,7 @@ uses ...@@ -41,7 +41,7 @@ uses
System.JSON, System.JSON,
Common.Config, Common.Config,
Common.Logging, Common.Logging,
uLibrary; uLibrary, XData.Sys.Exceptions;
{%CLASSGROUP 'Vcl.Controls.TControl'} {%CLASSGROUP 'Vcl.Controls.TControl'}
...@@ -57,6 +57,7 @@ begin ...@@ -57,6 +57,7 @@ begin
on E: Exception do on E: Exception do
begin begin
Logger.Log( 1, '--TAuthDatabase.DataModuleCreate -Error connecting to database: ' + E.Message ); Logger.Log( 1, '--TAuthDatabase.DataModuleCreate -Error connecting to database: ' + E.Message );
raise EXDataHttpException.Create(500, 'Error Connecting to database! Please try again later or contact a system admin!');
end; end;
end; end;
end; end;
......
...@@ -20,7 +20,7 @@ type ...@@ -20,7 +20,7 @@ type
['{9CFD59B2-A832-4F82-82BB-9A25FC93F305}'] ['{9CFD59B2-A832-4F82-82BB-9A25FC93F305}']
function Login(const user, password: string): string; function Login(const user, password: string): string;
function VerifyVersion(clientVersion: string): TJSONObject; function VerifyVersion(clientVersion: string): TJSONObject;
[HttpGet] function Authorize(code, realmId, state: string): string; [HttpGet] function QBAuthorize(code, realmId, state: string): string;
end; end;
implementation implementation
......
...@@ -23,8 +23,8 @@ type ...@@ -23,8 +23,8 @@ type
public public
function Login(const user, password: string): string; function Login(const user, password: string): string;
function VerifyVersion(ClientVersion: string): TJSONObject; function VerifyVersion(ClientVersion: string): TJSONObject;
function Authorize(code, realmId, state: string): string; function QBAuthorize(code, realmId, state: string): string;
function ExchangeAuthCode(code: string): string; function ExchangeQBAuthCode(code: string): string;
procedure AfterConstruction; override; procedure AfterConstruction; override;
procedure BeforeDestruction; override; procedure BeforeDestruction; override;
end; end;
...@@ -135,7 +135,7 @@ begin ...@@ -135,7 +135,7 @@ begin
iniFile := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini')); iniFile := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
try try
qbEnabled := iniFile.ReadBool('Quickbooks', 'Enabled', false); qbEnabled := iniFile.ReadBool('Quickbooks', 'Enabled', true);
finally finally
iniFile.Free; iniFile.Free;
end; end;
...@@ -189,19 +189,19 @@ begin ...@@ -189,19 +189,19 @@ begin
end; end;
end; end;
function TAuthService.Authorize(code, realmId, state: string): string; function TAuthService.QBAuthorize(code, realmId, state: string): string;
var var
iniFile: TIniFile; iniFile: TIniFile;
begin begin
Logger.Log(3, 'TAuthService.Authorize - begin'); Logger.Log(3, 'TAuthService.QBAuthorize - begin');
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini'); iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
iniFile.WriteString('Quickbooks', 'CompanyID', realmId); iniFile.WriteString('Quickbooks', 'CompanyID', realmId);
iniFile.Free; iniFile.Free;
result := ExchangeAuthCode(code); result := ExchangeQBAuthCode(code);
Logger.Log(3, 'TAuthService.Authorize - end - result: ' + result); Logger.Log(3, 'TAuthService.QBAuthorize - end - result: ' + result);
end; end;
function TAuthService.ExchangeAuthCode(code: string): string; function TAuthService.ExchangeQBAuthCode(code: string): string;
var var
iniFile: TIniFile; iniFile: TIniFile;
restClient: TRESTClient; restClient: TRESTClient;
...@@ -211,7 +211,7 @@ var ...@@ -211,7 +211,7 @@ var
Client, Secret, authString, AccessToken, RefreshToken, RedirectUri: string; Client, Secret, authString, AccessToken, RefreshToken, RedirectUri: string;
jsonObj: TJSONObject; jsonObj: TJSONObject;
begin begin
logger.Log(3, 'AuthService.ExchangeAuthCode - start'); logger.Log(3, 'AuthService.ExchangeQBAuthCode - start');
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini'); iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
restClient := TRESTClient.Create(nil); restClient := TRESTClient.Create(nil);
...@@ -282,7 +282,7 @@ begin ...@@ -282,7 +282,7 @@ begin
on E: Exception do on E: Exception do
begin begin
result := 'The server has ran into an error please try again later...'; result := 'The server has ran into an error please try again later...';
logger.Log(1, 'ExchangeAuthCode Error: ' + E.Message); logger.Log(1, 'ExchangeQBAuthCode Error: ' + E.Message);
end; end;
end; end;
finally finally
...@@ -290,7 +290,7 @@ begin ...@@ -290,7 +290,7 @@ begin
restRequest.Free; restRequest.Free;
restResponse.Free; restResponse.Free;
iniFile.Free; iniFile.Free;
logger.Log(3, 'AuthService.ExchangeAuthCode - end'); logger.Log(3, 'AuthService.ExchangeQBAuthCode - end');
end; end;
end; end;
......
...@@ -20,6 +20,14 @@ const ...@@ -20,6 +20,14 @@ const
API_MODEL = 'Api'; API_MODEL = 'Api';
type type
TQBInfo = class
public
clientID: string;
CompanyName: string;
CompanyID: string;
connected: boolean;
LastRefresh: string;
end;
TUserItem = class TUserItem = class
public public
...@@ -489,6 +497,7 @@ type ...@@ -489,6 +497,7 @@ type
[HttpGet] function GetRepUsers(): TList<TUserItem>; [HttpGet] function GetRepUsers(): TList<TUserItem>;
[HttpGet] function UpdateCustomer(QB_ID: string): TCustomerItem; [HttpGet] function UpdateCustomer(QB_ID: string): TCustomerItem;
[HttpGet] function UpdateItem(itemName: string): TItemItem; [HttpGet] function UpdateItem(itemName: string): TItemItem;
[HttpGet] function GetQBInfo(): TQBInfo;
function AddUser(userInfo: string): string; function AddUser(userInfo: string): string;
......
...@@ -41,6 +41,7 @@ type ...@@ -41,6 +41,7 @@ type
function GetRepUsers(): TList<TUserItem>; function GetRepUsers(): TList<TUserItem>;
function UpdateCustomer(QB_ID: string): TCustomerItem; function UpdateCustomer(QB_ID: string): TCustomerItem;
function UpdateItem(itemName: string): TItemItem; function UpdateItem(itemName: string): TItemItem;
function GetQBInfo(): TQBInfo;
function EditUser(const editOptions: string): string; function EditUser(const editOptions: string): string;
...@@ -87,6 +88,96 @@ implementation ...@@ -87,6 +88,96 @@ implementation
uses uses
XData.Sys.Exceptions, uLibrary, rOrderWeb, rOrderCutting; XData.Sys.Exceptions, uLibrary, rOrderWeb, rOrderCutting;
function TLookupService.GetQBInfo: TQBInfo;
var
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
jsObj: TJSONObject;
CompanyInfoList: TJSONArray;
CompanyInfo: TJSONObject;
I: integer;
AccessToken, RefreshToken, CompanyID, Client, Secret, SQL, desc, BaseUrl: string;
LastRefresh: TDateTime;
iniFile: TIniFile;
begin
logger.Log(3, 'TLookupService.GetQBItems');
iniFile := nil;
restClient := nil;
restRequest := nil;
restResponse := nil;
try
try
result := TQBInfo.Create;
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
restClient := TRESTClient.Create(nil);
restRequest := TRESTRequest.Create(nil);
restResponse := TRESTResponse.Create(nil);
result.clientID := iniFile.ReadString('Quickbooks', 'ClientID', '');
if iniFile.ReadString('Quickbooks', 'CompanyID', '') = '' then
begin
result.connected := false;
end
else
begin
restRequest.Client := restClient;
restRequest.Response := restResponse;
if iniFile.ReadString('Quickbooks', 'LastRefresh', '') = '' then
LastRefresh := 0
else
LastRefresh := StrToDateTime(iniFile.ReadString('Quickbooks', 'LastRefresh', ''));
if MinutesBetween(Now, LastRefresh) > 58 then
RefreshAccessToken();
Client := iniFile.ReadString('Quickbooks', 'ClientID', '');
Secret := iniFile.ReadString('Quickbooks', 'ClientSecret', '');
CompanyID := iniFile.ReadString('Quickbooks', 'CompanyID', '');
RefreshToken := iniFile.ReadString('Quickbooks', 'RefreshToken', '');
AccessToken := iniFile.ReadString('Quickbooks', 'AccessToken', '');
BaseUrl := iniFile.ReadString('Quickbooks', 'BaseUrl', '');
restClient.BaseURL := BaseUrl;
restRequest.Method := rmGET;
res := '/v3/company/' + companyID + '/query?query=select * from CompanyInfo&minorversion=75';
restRequest.Resource := res;
param := restRequest.Params.AddItem;
param.Name := 'Authorization';
param.Kind := pkHTTPHEADER;
param.Options := param.Options + [TRESTRequestParameterOption.poDoNotEncode];
param.Value := 'Bearer ' + AccessToken;
restRequest.Execute;
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
CompanyInfoList := TJSONArray(TJSONObject(jsObj.GetValue('QueryResponse')).GetValue('CompanyInfo'));
CompanyInfo := CompanyInfoList.Items[I] as TJSONObject;
result.CompanyName := CompanyInfo.GetValue('CompanyName').Value;
result.CompanyID := CompanyID;
result.connected := true;
result.LastRefresh := iniFile.ReadString('Quickbooks', 'LastRefresh', '');
end;
except
on E: Exception do
begin
Logger.Log(1, 'Error in getQBItems: ' + E.Message);
raise EXDataHttpException.Create(500, 'Unable to retrieve QuickBooks Items: A QuickBooks interface error has occurred!');
end;
end;
finally
iniFile.Free;
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
end;
function TLookupService.addEstimate(orderInfo: string): TJSONObject; function TLookupService.addEstimate(orderInfo: string): TJSONObject;
var var
...@@ -3064,6 +3155,11 @@ begin ...@@ -3064,6 +3155,11 @@ begin
jsObj := TJSONObject(jsValue); jsObj := TJSONObject(jsValue);
ItemList := TJSONArray(TJSONObject(jsObj.GetValue('QueryResponse')).GetValue('Item')); ItemList := TJSONArray(TJSONObject(jsObj.GetValue('QueryResponse')).GetValue('Item'));
if ItemList = nil then
begin
Logger.Log(1, 'Unable to find match in Quickbooks for item: ' + itemName);
raise EXDataHttpException.Create(500, 'Unable to find match in Quickbooks for item: ' + itemName + '! Make sure to double check the spelling.');
end;
Item := ItemList.Items[0] as TJSONObject; Item := ItemList.Items[0] as TJSONObject;
ParsedItem := TJSONObject.Create; ParsedItem := TJSONObject.Create;
...@@ -3084,9 +3180,12 @@ begin ...@@ -3084,9 +3180,12 @@ begin
result.QB_ID := Item.GetValue<string>('Id'); result.QB_ID := Item.GetValue<string>('Id');
except except
on E: EXDataHttpException do
raise;
on E: Exception do on E: Exception do
begin begin
Logger.Log(2, 'Error in UpdateItem: ' + E.Message); Logger.Log(1, 'Error in UpdateItem: ' + E.Message);
raise EXDataHttpException.Create(500, 'Unable to retrieve QuickBooks Items: A QuickBooks interface error has occurred!'); raise EXDataHttpException.Create(500, 'Unable to retrieve QuickBooks Items: A QuickBooks interface error has occurred!');
end; end;
end; end;
......
...@@ -183,7 +183,7 @@ begin ...@@ -183,7 +183,7 @@ begin
Logger.Log(1, '---Quickbooks---'); Logger.Log(1, '---Quickbooks---');
iniStr := IniFile.ReadString( 'Quickbooks', 'Enabled', '' ); iniStr := IniFile.ReadString( 'Quickbooks', 'Enabled', '' );
if iniStr.IsEmpty then if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->Enabled: Entry not found - default: false' ) Logger.Log( 1, '--Quickbooks->Enabled: Entry not found - default: true' )
else else
Logger.Log( 1, '--Quickbooks->Enabled: ' + iniStr ); Logger.Log( 1, '--Quickbooks->Enabled: ' + iniStr );
......
...@@ -114,11 +114,11 @@ ...@@ -114,11 +114,11 @@
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<DCC_ExeOutput>.\bin</DCC_ExeOutput> <DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath> <DCC_UnitSearchPath>C:\RADTOOLS\FastMM4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<VerInfo_Keys>CompanyName=EM Systems;FileDescription=$(MSBuildProjectName);FileVersion=0.9.13.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.13.9;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=0.9.11;Comments=</VerInfo_Keys>
<VerInfo_MajorVer>0</VerInfo_MajorVer> <VerInfo_MajorVer>0</VerInfo_MajorVer>
<VerInfo_MinorVer>9</VerInfo_MinorVer> <VerInfo_MinorVer>9</VerInfo_MinorVer>
<VerInfo_Release>13</VerInfo_Release> <VerInfo_Release>13</VerInfo_Release>
<VerInfo_Build>3</VerInfo_Build> <VerInfo_Build>9</VerInfo_Build>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''"> <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode> <AppDPIAwarenessMode>PerMonitorV2</AppDPIAwarenessMode>
......
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