Commit d4ed3814 by Elias Sarraf

Merge remote-tracking branch 'origin/cam'

parents b2f7a7bc 7068c939
......@@ -122,6 +122,7 @@ object FViewAddAddress: TFViewAddAddress
ChildOrder = 12
Enabled = False
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
end
object btnSave: TWebButton
......@@ -132,6 +133,7 @@ object FViewAddAddress: TFViewAddAddress
Caption = 'Save'
ChildOrder = 13
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
OnClick = btnSaveClick
end
......@@ -143,6 +145,7 @@ object FViewAddAddress: TFViewAddAddress
Caption = 'Cancel'
ChildOrder = 13
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
end
......
// Small Pop-Up page when adding orders if you want to quickly add an address
unit View.AddAddress;
unit View.Address.Add;
interface
......
// Add Customer page for KGOrders. Handles Adding and Editting Customers and
// Their shipping addresses.
unit AddCustomer;
unit View.Customer.Add;
interface
......@@ -127,7 +127,7 @@ implementation
{$R *.dfm}
uses View.Main, View.Customers, View.SelectCustomer, Utils;
uses View.Main, View.Customers, View.Customer.Select, Utils;
class function TFViewAddCustomer.CreateForm(AElementID, customerInfo, info: string): TWebForm;
......@@ -223,7 +223,6 @@ procedure TFViewAddCustomer.SendAddressToServer;
// Creates an Address JSON and then sends it to the server for the address to be
// Added or edited.
var
Field: TField;
AddressJSON: TJSONObject;
Response: TXDataClientResponse;
notification: TJSObject;
......@@ -516,8 +515,6 @@ procedure TFViewAddCustomer.GetCustomer;
var
xdcResponse: TXDataClientResponse;
customer, RepUsers : TJSObject;
items: TJSObject;
ship_block: TStringList;
begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomer', [customerID]));
customer := TJSObject(xdcResponse.Result);
......
unit View.SelectCustomer;
unit View.Customer.Select;
interface
......@@ -109,7 +109,6 @@ procedure TFSelectCustomer.getCustomers();
var
xdcResponse: TXDataClientResponse;
customerList: TJSObject;
i: integer;
begin
try
Utils.ShowSpinner('spinner');
......
......@@ -49,8 +49,6 @@ type
PageNumber: integer;
PageSize: integer;
TotalPages: integer;
info: string;
public
{ Public declarations }
end;
......@@ -61,7 +59,7 @@ var
implementation
uses
XData.Model.Classes, View.Main, View.SelectCustomer, Utils;
XData.Model.Classes, View.Main, View.Customer.Select, Utils;
{$R *.dfm}
......@@ -93,8 +91,6 @@ Procedure TFViewCustomers.WebFormCreate(Sender: TObject);
// PageNumber: What page number the user is on IE 1: 1-10, 2: 11-20 etc
// TotalPages: Total number of pages returned from the search.
// PageSize: Number of entries per page.
var
today: TDateTime;
begin
DMConnection.ApiConnection.Connected := True;
PageNumber := 1;
......@@ -163,7 +159,6 @@ end;
procedure TFViewCustomers.HideNotification;
begin
pnlMessage.ElementHandle.hidden := True;
info := '';
end;
......
object FViewHome: TFViewHome
Width = 640
Height = 480
OnCreate = WebFormCreate
object WebLabel1: TWebLabel
Left = 24
Top = 43
......@@ -12,7 +13,7 @@ object FViewHome: TFViewHome
Transparent = False
WidthPercent = 100.000000000000000000
end
object WebMemo1: TWebMemo
object mmoNotes: TWebMemo
Left = 24
Top = 62
Width = 471
......@@ -20,10 +21,19 @@ object FViewHome: TFViewHome
ElementID = 'view.home.notesmemo'
HeightPercent = 100.000000000000000000
Lines.Strings = (
'KG Orders Alpha Version')
'Change Log:'
'1) Setting a status now autofills due dates.'
'2) Fixed order dates displaying on 3 lines rather than 2.'
'3) Adjusted pdfs so that special instructions would have enough ' +
'space.'
'4) Fixed issue with PDF generation.'
'5) Removed ability to put 0 or a negative number for price and q' +
'uantity on order entry fields.')
ReadOnly = True
SelLength = 0
SelStart = 25
SelStart = 323
WidthPercent = 100.000000000000000000
end
end
......@@ -5,12 +5,12 @@ interface
uses
System.SysUtils, System.Classes, WEBLib.Graphics, WEBLib.Forms, WEBLib.Dialogs,
Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, WEBLib.Controls, WEBLib.Grids,
XData.Web.Client, WEBLib.ExtCtrls, DB;
XData.Web.Client, WEBLib.ExtCtrls, DB, JS;
type
TFViewHome = class(TWebForm)
WebLabel1: TWebLabel;
WebMemo1: TWebMemo;
mmoNotes: TWebMemo;
procedure WebFormCreate(Sender: TObject);
end;
......@@ -20,7 +20,7 @@ var
implementation
uses
JS, XData.Model.Classes,
XData.Model.Classes,
ConnectionModule;
{$R *.dfm}
......@@ -28,7 +28,7 @@ uses
procedure TFViewHome.WebFormCreate(Sender: TObject);
begin
WebLabel1.Caption := 'Please select a menu option to continue!';
mmoNotes.Lines.Insert(0, 'Welcome to KG Orders Version ' + TDMConnection.clientVersion);
end;
end.
......@@ -78,7 +78,7 @@ implementation
uses
XData.Model.Classes,
ConnectionModule, Auth.Service, Utils, View.AddItem, View.Main;
ConnectionModule, Auth.Service, Utils, View.Item.Add, View.Main;
{$R *.dfm}
......
......@@ -46533,7 +46533,7 @@ object FViewLogin: TFViewLogin
Width = 72
Height = 13
Caption = 'lblClientVersion'
ElementID = 'lbl_client_version'
ElementID = 'view.login.version'
ElementFont = efCSS
ElementPosition = epRelative
HeightStyle = ssAuto
<nav class="navbar navbar-light bg-light login-navbar">
<div class="container-fluid">
<a class="navbar-brand" href="#">Koehler-Gibson Orders</a>
<div class="d-flex align-items-center">
<a id="view.login.apptitle" class="navbar-brand ps-2" href="index.html"> Koehler-Gibson Orders</a>
<span id="view.login.version" class="small text-muted ms-2"></span>
</div>
</nav>
<div class="container mt-5">
......
......@@ -5,8 +5,9 @@ interface
uses
System.SysUtils, System.Classes, Web, WEBLib.Graphics, WEBLib.Controls, WEBLib.Forms, WEBLib.Dialogs,
Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, WEBLib.JSON,
JS, XData.Web.Connection, WEBLib.ExtCtrls,
App.Types, ConnectionModule, XData.Web.Client, Vcl.Imaging.pngimage;
XData.Web.Client, WEBLib.ExtCtrls, Vcl.Imaging.pngimage,
JS, XData.Web.Connection,
App.Types, ConnectionModule;
type
TFViewLogin = class(TWebForm)
......@@ -55,7 +56,8 @@ procedure TFViewLogin.btnLoginClick(Sender: TObject);
begin
ShowNotification('Login Error: ' + AMsg);
end;
var
hashPW: string;
begin
AuthService.Login(
edtUsername.Text, edtPassword.Text,
......
......@@ -120,7 +120,7 @@
<div class="modal-dialog">
<div class="modal-content shadow-lg">
<div class="modal-header">
<h5 class="modal-title" id="main_notification_modal">Error</h5>
<h5 class="modal-title" id="main_notification_modal">Info</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_notification_modal_body">
......
......@@ -33,7 +33,6 @@ type
procedure lblUsersClick(Sender: TObject);
procedure lblordersClick(Sender: TObject);
procedure lblCustomersClick(Sender: TObject);
procedure lblQuickbooksClick(Sender: TObject);
private
{ Private declarations }
FUserInfo: string;
......@@ -75,12 +74,12 @@ uses
View.Home,
View.Items,
View.Users,
View.EditUser,
View.User.Add,
View.Orders,
View.OrderEntryCorrugated,
View.OrderEntryCuttingDie,
View.OrderEntryWeb,
View.Customers, AddCustomer;
View.Customers, View.Customer.Add;
{$R *.dfm}
......@@ -101,10 +100,9 @@ begin
lblCustomers.Enabled := false;
end;
ShowForm(TFViewOrders);
lblAppTitle.Caption := 'Koehler-Gibson Orders';
lblVersion.Caption := 'v' + DMConnection.clientVersion;
ShowForm(TFViewOrders);
setActive('Orders');
end;
......@@ -129,7 +127,7 @@ begin
begin
ShowForm(TFViewHome);
lblAppTitle.Caption := 'Koehler-Gibson Home';
//setActive('Home');
setActive('Home');
end
else
ShowToast('Please Save or Cancel your changes', 'danger');
......@@ -147,24 +145,13 @@ begin
ShowToast('Please Save or Cancel your changes', 'danger');
end;
procedure TFViewMain.lblQuickbooksClick(Sender: TObject);
begin
if ( not ( change ) ) then
begin
//ShowForm(TFViewQuickbooks);
lblAppTitle.Caption := 'Koehler-Gibson QuickBooks';
setActive('QuickBooks');
end
else
ShowToast('Please Save or Cancel your changes', 'danger');
end;
procedure TFViewMain.lblUsersClick(Sender: TObject);
begin
if ( not ( change ) ) then
begin
ShowForm(TFViewUsers);
lblAppTitle.Caption := 'Koehler-Gibson Users';
setActive('Users');
end
else
ShowToast('Please Save or Cancel your changes', 'danger');
......@@ -233,6 +220,7 @@ procedure TFViewMain.wllblUserProfileClick(Sender: TObject);
begin
ShowCrudForm(TFViewUserProfile);
lblAppTitle.Caption := 'Koehler-Gibson User Profile';
setActive('User Profile');
end;
//needs to be changed
......
// Pop-Up menu that appears when Add Order button is clicked on orders page.
// Used to select customer before entering an order.
unit View.AddOrder;
unit View.Order.Add;
interface
......
......@@ -669,7 +669,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 480
Width = 113
Height = 22
TabStop = False
Caption = 'Art Approved As Is'
ChildOrder = 79
ElementID = 'cbartapprovedasis'
......@@ -677,6 +676,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
HeightPercent = 100.000000000000000000
Role = 'null'
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_art_approved_as_is'
DataSource = wdsOrder
......@@ -688,7 +688,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 430
Width = 113
Height = 22
TabStop = False
Caption = 'PDF File'
ChildOrder = 79
ElementID = 'cbpdffile'
......@@ -696,6 +695,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
HeightPercent = 100.000000000000000000
Role = 'null'
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_pdf_file'
DataSource = wdsOrder
......@@ -707,7 +707,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 406
Width = 113
Height = 22
TabStop = False
Caption = 'Wide Format'
ChildOrder = 79
ElementID = 'cbwideformat'
......@@ -715,6 +714,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
HeightPercent = 100.000000000000000000
Role = 'null'
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_wide_format'
DataSource = wdsOrder
......@@ -726,7 +726,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 382
Width = 113
Height = 22
TabStop = False
Caption = 'Print Card'
ChildOrder = 79
ElementID = 'cbprintcard'
......@@ -734,6 +733,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
HeightPercent = 100.000000000000000000
Role = 'null'
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_print_card'
DataSource = wdsOrder
......@@ -745,7 +745,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 356
Width = 113
Height = 22
TabStop = False
Caption = 'Full Size Panel'
ChildOrder = 79
ElementID = 'cbfullsizepanel'
......@@ -753,6 +752,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
HeightPercent = 100.000000000000000000
Role = 'null'
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_full_size_panel'
DataSource = wdsOrder
......@@ -799,6 +799,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
TabStop = False
WidthPercent = 100.000000000000000000
ItemIndex = -1
DataField = 'staff_fields_ship_to'
......@@ -829,6 +830,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
TabStop = False
WidthPercent = 100.000000000000000000
OnChange = wdbcbQuickbooksItemChange
ItemIndex = -1
......@@ -1023,7 +1025,6 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Role = ''
ShowFocus = False
ShowSeconds = False
TabStop = False
Text = ''
DataField = 'proofing_approved_date'
DataSource = wdsOrder
......@@ -1082,6 +1083,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'cbplates'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_plates'
DataSource = wdsOrder
......@@ -1097,6 +1099,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'cbsampleCarton'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_sample_ca'
DataSource = wdsOrder
......@@ -1112,6 +1115,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'cbftp'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_ftp'
DataSource = wdsOrder
......@@ -1127,6 +1131,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'cbcolorcopy'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_color_copy'
DataSource = wdsOrder
......@@ -1142,6 +1147,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'edtemail'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_e_mail'
DataSource = wdsOrder
......@@ -1157,6 +1163,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'edtexistingcuttingdie'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_existing_'
DataSource = wdsOrder
......@@ -1172,6 +1179,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'edtrefartapdf'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_ref_art_a'
DataSource = wdsOrder
......@@ -1187,6 +1195,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
ChildOrder = 85
ElementID = 'edtrefartprintcard'
HeightPercent = 100.000000000000000000
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'supplied_by_customer_ref_art_p'
DataSource = wdsOrder
......@@ -1198,12 +1207,12 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 378
Width = 113
Height = 22
TabStop = False
Caption = 'Full Mount'
ChildOrder = 85
ElementID = 'cbfullmount'
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'mounting_full_mount'
DataSource = wdsOrder
......@@ -1215,12 +1224,12 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 356
Width = 113
Height = 22
TabStop = False
Caption = 'Sticky Bak'
ChildOrder = 85
ElementID = 'cbstickybak'
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'mounting_sticky_bak'
DataSource = wdsOrder
......@@ -1232,12 +1241,12 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 235
Width = 113
Height = 22
TabStop = False
Caption = 'Excalibur Die'
ChildOrder = 85
ElementID = 'cbexcaliburdie'
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'layout_excalibur_die'
DataSource = wdsOrder
......@@ -1249,12 +1258,12 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 309
Width = 113
Height = 22
TabStop = False
Caption = 'Loose'
ChildOrder = 84
ElementID = 'cbloose'
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
end
object cbStripMount: TWebCheckBox
......@@ -1262,12 +1271,12 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 402
Width = 113
Height = 22
TabStop = False
Caption = 'Strip Mount'
ChildOrder = 84
ElementID = 'cbstripmount'
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
end
object edtQBItemDescription: TWebEdit
......@@ -1275,6 +1284,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 551
Width = 121
Height = 22
TabStop = False
ChildOrder = 31
ElementID = 'edtitemdescription'
Enabled = False
......@@ -1286,6 +1296,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 149
Width = 121
Height = 22
TabStop = False
AutoCompletion = acNope
AutoSize = True
ChildOrder = 79
......@@ -1301,6 +1312,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 149
Width = 113
Height = 22
TabStop = False
Caption = 'In Quickbooks?'
ChildOrder = 29
ElementID = 'wdbcbinqb'
......@@ -1317,6 +1329,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
Top = 185
Width = 121
Height = 22
TabStop = False
ChildOrder = 30
ElementID = 'edtordernum'
Enabled = False
......
......@@ -97,14 +97,14 @@
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Quantity:</label>
<input id="edtquantity" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;" required>
Please Provide a Quantity.
Please Provide a Valid Quantity.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Price:</label>
<input id="edtprice" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Price.
Please Provide a Valid Price.
</div>
</div>
<div>
......@@ -167,40 +167,40 @@
<hr class="custom-hr">
<div class="row">
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Color Copy:</label>
<input type="checkbox" id="cbcolorcopy">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Color Copy?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Plates:</label>
<input type="checkbox" id="cbplates">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Plates?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Sample Carton:</label>
<input type="checkbox" id="cbsampleCarton">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Sample Carton?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Email:</label>
<input type="checkbox" id="edtemail"/>
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Email?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">FTP:</label>
<input type="checkbox" id="cbftp"/>
<label class='pe-2' style="font-weight: 700; font-size: 15px;">FTP?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Other:</label>
<input class="form-control input-sm" id="edtother" style="width: 150px"/>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Existing Cutting Die:</label>
<input type="checkbox" id="edtexistingcuttingdie"/>
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Existing Cutting Die?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Ref Art Print Card:</label>
<input type="checkbox" id="edtrefartprintcard"/>
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Ref Art Print Card?</label>
</div>
<div class="col-auto">
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Ref Art A PDF:</label>
<input type="checkbox" id="edtrefartapdf"/>
<label class='pe-2' style="font-weight: 700; font-size: 15px;">Ref Art A PDF?</label>
</div>
</div>
<h4 class="custom-h4 mt-3">Layout</h4>
......@@ -235,8 +235,8 @@
<input id="edtcadfile" class="form-control input-sm" style="width: 150px"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Excalibur Die:</label>
<input type="checkbox" id="cbexcaliburdie">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Excalibur Die?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">RSC Style:</label>
......@@ -247,21 +247,21 @@
<hr class="custom-hr">
<div class="row">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Loose:</label>
<input type="checkbox" id="cbloose">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Loose:</label>
<input id="edtloose" class="form-control input-sm" style="width: 150px"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Sticky Bak:</label>
<input type="checkbox" id="cbstickybak">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Sticky Bak?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Mount:</label>
<input type="checkbox" id="cbfullmount">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Mount?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Strip Mount:</label>
<input type="checkbox" id="cbstripmount">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Strip Mount:</label>
<input id="edtstripmount" class="form-control input-sm" style="width: 150px"/>
</div>
<div class="col-auto">
......@@ -337,28 +337,28 @@
<input id="edtproofshipto" class="form-control input-sm" style="width: 150px"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Size Panel:</label>
<input type="checkbox" id="cbfullsizepanel">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Size Panel?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Print Card:</label>
<input type="checkbox" id="cbprintcard">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Print Card?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Wide Format:</label>
<input type="checkbox" id="cbwideformat">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Wide Format?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PDF File:</label>
<input type="checkbox" id="cbpdffile">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PDF File?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Other:</label>
<input id="edtproofother" class="form-control input-sm" style="width: 150px"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Art Approved As Is:</label>
<input type="checkbox" id="cbartapprovedasis">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Art Approved As Is?</label>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Approved Date:</label>
......@@ -386,7 +386,7 @@
<div class="row pb-3">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label">Special Instructions</label>
<textarea id="edtspecialinstructions" class="form-control" style=" width: 500px; height: 150px;"></textarea>
<textarea id="edtspecialinstructions" class="form-control mb-3" style=" width: 800px; height: 150px;"></textarea>
</div>
</div>
</div>
......@@ -259,7 +259,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
View.Home, View.Main, View.Order.Add, View.Address.Add, Utils;
class function TFOrderEntryCorrugated.CreateForm(AElementID, orderInfo, customerInfo, modeParam, info: string): TWebForm;
begin
......@@ -354,8 +354,8 @@ procedure TFOrderEntryCorrugated.btnDeleteClick(Sender: TObject);
begin
ShowConfirmationModal(
'Are you sure you want to delete this order?',
'Delete',
'Cancel',
'Yes',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
......@@ -388,10 +388,16 @@ end;
procedure TFOrderEntryCorrugated.btnQBClick(Sender: TObject);
var
orderJSON: TJSONObject;
qbEnabled: boolean;
begin
if AuthService.TokenPayload.Properties['qb_enabled'] then
begin
qbEnabled := boolean(AuthService.TokenPayload.Properties['qb_enabled']);
if not qbEnabled then
begin
ShowToast('QB interface not currently active', 'info');
Exit;
end;
if JS.toString(AuthService.TokenPayload.Properties['user_qb_id']) <> '' then
begin
if ( VerifyQBOrder() )then
......@@ -410,10 +416,6 @@ begin
end
else
ShowToast('Failure:User not authorized to add to QuickBooks', 'failure');
end
end
else
ShowToast('QB interface not currently active', 'info');
end;
[async] procedure TFOrderEntryCorrugated.GenerateReportPDF;
......@@ -1143,7 +1145,7 @@ begin
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtprice'));
if edtPrice.Text = '' then
if ( ( edtPrice.Text = '' ) or ( StrToFloat(edtPrice.Text) <= 0 ) )then
begin
input.classList.add('is-invalid');
......@@ -1153,7 +1155,7 @@ begin
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtquantity'));
if edtQuantity.Text = '' then
if ( ( edtQuantity.Text = '' ) or ( StrToFloat(edtQuantity.Text) <= 0 ) ) then
begin
input.classList.add('is-invalid');
......
......@@ -100,14 +100,14 @@
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Quantity:</label>
<input id="edtquantity" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;" required>
Please Provide a Quantity.
Please Provide a Valid Quantity.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Price:</label>
<input id="edtprice" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Price.
Please Provide a Valid Price.
</div>
</div>
<div>
......@@ -154,12 +154,12 @@
</div>
</div>
</div>
<h4 class="custom-h4 mt-3">General</h4>
<h4 class="custom-h4 mt-3 mt-3">General</h4>
<hr class="custom-hr">
<div class="row">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label">Special Instructions</label>
<textarea id="edtspecialinstructions" class="form-control" style=" width: 500px; height: 150px;"></textarea>
<textarea id="edtspecialinstructions" class="form-control mb-3" style=" width: 800px; height: 150px;"></textarea>
</div>
</div>
</div>
......
......@@ -129,7 +129,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
View.Home, View.Main, View.Order.Add, View.Address.Add, Utils;
class function TFOrderEntryCuttingDie.CreateForm(AElementID, orderInfo, customerInfo, modeParam, info: string): TWebForm;
......@@ -192,9 +192,16 @@ end;
procedure TFOrderEntryCuttingDie.btnQBClick(Sender: TObject);
var
orderJSON: TJSONObject;
qbEnabled: boolean;
begin
if AuthService.TokenPayload.Properties['qb_enabled'] then
qbEnabled := boolean(AuthService.TokenPayload.Properties['qb_enabled']);
if not qbEnabled then
begin
ShowToast('QB interface not currently active', 'info');
Exit;
end;
if JS.toString(AuthService.TokenPayload.Properties['user_qb_id']) <> '' then
begin
if ( VerifyQBOrder() )then
......@@ -213,9 +220,6 @@ begin
end
else
ShowToast('Failure:User not authorized to add to QuickBooks', 'failure');
end
else
ShowToast('QB interface not currently active', 'info');
end;
procedure TFOrderEntryCuttingDie.WebButton2Click(Sender: TObject);
......@@ -320,8 +324,8 @@ end;
begin
ShowConfirmationModal(
'Are you sure you want to delete this order?',
'Delete',
'Cancel',
'Yes',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
......
......@@ -414,13 +414,13 @@ object FOrderEntryWeb: TFOrderEntryWeb
Top = 96
Width = 113
Height = 22
TabStop = False
Caption = 'PDF'
ChildOrder = 79
ElementID = 'cbpdf'
Enabled = False
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_pdf'
DataSource = wdsOrder
......@@ -446,13 +446,13 @@ object FOrderEntryWeb: TFOrderEntryWeb
Top = 238
Width = 113
Height = 22
TabStop = False
Caption = 'Full Size Ink Jet For Layout Content Only'
ChildOrder = 79
ElementID = 'cbfullsizeinkjet'
Enabled = False
HeightPercent = 100.000000000000000000
ShowFocus = False
TabOrder = -1
WidthPercent = 100.000000000000000000
DataField = 'proofing_full_size_ink_jet_for'
DataSource = wdsOrder
......
......@@ -97,14 +97,14 @@
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Quantity:</label>
<input id="edtquantity" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;" required>
Please Provide a Quantity.
Please Provide a Valid Quantity.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Price:</label>
<input id="edtprice" class="form-control input-sm" style="width: 100px" type="number" min="1" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Price.
Please Provide a Valid Price.
</div>
</div>
<div>
......@@ -207,8 +207,8 @@
<hr class="custom-hr">
<div class="row">
<div class="col-auto">
<label label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PDF:</label>
<input type="checkbox" id="cbpdf">
<label label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PDF?</label>
</div>
<div class="col-auto">
<label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PDF To:</label>
......@@ -227,8 +227,8 @@
<input class="form-control input-sm" id="dtppdfdate3" type="date">
</div>
<div class="col-auto">
<label label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Size Ink Jet For Layout Content Only:</label>
<input type="checkbox" id="cbfullsizeinkjet">
<label label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Full Size Ink Jet For Layout Content Only?</label>
</div>
<div class="col-auto">
<label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Ink Jet To:</label>
......@@ -450,7 +450,7 @@
<div class="row">
<div class="col-auto">
<label style="font-weight: 700; font-size: 15px;" class="form-label">Comments</label>
<textarea id="edtcomments" class="form-control" style=" width: 500px; height: 150px;"></textarea>
<textarea id="edtcomments" class="form-control mb-3" style=" width: 800px; height: 150px;"></textarea>
</div>
</div>
</div>
......
......@@ -265,7 +265,7 @@ implementation
{$R *.dfm}
uses
View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
View.Home, View.Main, View.Order.Add, View.Address.Add, Utils;
class function TFOrderEntryWeb.CreateForm(AElementID, orderInfo, customerInfo, modeParam, info: string): TWebForm;
......@@ -418,8 +418,8 @@ procedure TFOrderEntryWeb.btnDeleteClick(Sender: TObject);
begin
ShowConfirmationModal(
'Are you sure you want to delete this order?',
'Delete',
'Cancel',
'Yes',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
......@@ -453,9 +453,16 @@ end;
procedure TFOrderEntryWeb.btnQBClick(Sender: TObject);
var
orderJSON: TJSONObject;
qbEnabled: boolean;
begin
if AuthService.TokenPayload.Properties['qb_enabled'] then
qbEnabled := boolean(AuthService.TokenPayload.Properties['qb_enabled']);
if not qbEnabled then
begin
ShowToast('QB interface not currently active', 'info');
Exit;
end;
if JS.toString(AuthService.TokenPayload.Properties['user_qb_id']) <> '' then
begin
if ( VerifyQBOrder() )then
......@@ -474,9 +481,6 @@ begin
end
else
ShowToast('Failure:User not authorized to add to QuickBooks', 'failure');
end
else
ShowToast('QB interface not currently active', 'info');
end;
procedure TFOrderEntryWeb.AddEstimate(orderID: string);
......@@ -773,10 +777,7 @@ var
tempString, strColorList: string;
colorObject: TJSObject;
colorList: TJSArray;
colorLength: integer;
color: TJSObject;
colorJSON: TJSONObject;
colorListJSON: TJSONArray;
items: TJSObject;
begin
Utils.ShowSpinner('spinner');
......@@ -836,7 +837,6 @@ procedure TFOrderEntryWeb.SetNewOrderInfo(customerID: string);
var
xdcResponse: TXDataClientResponse;
customer : TJSObject;
address: string;
items: TJSObject;
begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomer',
......@@ -1027,7 +1027,7 @@ end;
function TFOrderEntryWeb.VerifyQBOrder: Boolean;
var
msg, SQL: string;
msg: string;
begin
Result := True;
msg := 'To add an order to QuickBooks, the following must be present:' + sLineBreak;
......
......@@ -156,40 +156,50 @@ object FViewOrders: TFViewOrders
Title = 'Proof Due'
end
item
ElementClassName = 'tbl-min-120'
DataField = 'proofDone'
Title = 'Proof Done'
TitleElementClassName = 'tbl-min-120'
end
item
DataField = 'artDue'
Title = 'Art Due'
end
item
ElementClassName = 'tbl-min-120'
DataField = 'artDone'
Title = 'Art Done'
TitleElementClassName = 'tbl-min-120'
end
item
DataField = 'plateDue'
Title = 'Plate Due'
end
item
ElementClassName = 'tbl-min-120'
DataField = 'plateDone'
Title = 'Plate Done'
TitleElementClassName = 'tbl-min-120'
end
item
DataField = 'mountDue'
Title = 'Mount Due'
end
item
ElementClassName = 'tbl-min-120'
DataField = 'mountDone'
Title = 'Mount Done'
TitleElementClassName = 'tbl-min-120'
end
item
DataField = 'shipDue'
Title = 'Ship Due'
end
item
ElementClassName = 'tbl-min-120'
DataField = 'shipDone'
Title = 'Ship Done'
TitleElementClassName = 'tbl-min-120'
end
item
DataField = 'price'
......@@ -360,6 +370,7 @@ object FViewOrders: TFViewOrders
FieldName = 'proofDue'
end
object xdwdsOrdersproofDone: TStringField
DisplayWidth = 40
FieldName = 'proofDone'
end
object xdwdsOrdersartDue: TStringField
......
......@@ -125,7 +125,7 @@ var
implementation
uses
XData.Model.Classes, View.Main, View.AddOrder, View.Search, View.SetStatus, Utils;
XData.Model.Classes, View.Main, View.Order.Add, View.Search, View.SetStatus, Utils;
{$R *.dfm}
......@@ -175,7 +175,7 @@ begin
ShowConfirmationModal(
'You are about to generate a PDF for over 100 orders. This may take some time. Continue?',
'Yes',
'Cancel',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
......@@ -285,6 +285,7 @@ procedure TFViewOrders.WebFormCreate(Sender: TObject);
var
today: TDateTime;
params: TStringList;
btn: TJSHTMLElement;
begin
Utils.ShowSpinner('spinner');
DMConnection.ApiConnection.Connected := True;
......@@ -331,6 +332,22 @@ begin
statusOrderID := params.Values['orderID'];
companyID := params.Values['companyID'];
jobName := params.Values['jobName'];
wlcbOrderBy.Value := OrderBy;
btn := document.getElementById('btnorderby') as TJSHTMLElement;
if direction = 'DESC' then
begin
btnOrderBy.Caption := 'Descending';
btn.innerHTML := 'Descending <i class="fa fa-arrow-down"></i>';
direction := 'DESC';
end
else
begin
btnOrderBy.Caption := 'Ascending';
btn.innerHTML := 'Ascending <i class="fa fa-arrow-up"></i>';
direction := 'ASC';
end;
// Status1
startDate1 := params.Values['startDate1'];
......@@ -350,7 +367,7 @@ begin
else
null2 := StrToBool(params.Values['null2']);
end;
FViewMain.search := GenerateSearchOptions();
GenerateSearchOptions();
getOrders(FViewMain.search);
end;
......@@ -443,7 +460,7 @@ begin
companyID := newform.DBID;
orderType := newform.wcbOrderType.Text;
FViewMain.search := generateSearchOptions();
generateSearchOptions();
//searchOptions := generateSearchOptions();
edtSearch.Text := FViewMain.search;
getOrders(FViewMain.search);
......@@ -459,12 +476,12 @@ var
begin
newform := TFSetStatus.CreateNew;
newform.Caption := 'Input Search Options';
newform.Caption := 'Set Status';
newForm.Popup := True;
newForm.Border := fbDialog;
newForm.Position := poScreenCenter;
newForm.OrderID := statusOrderID;
newForm.JobName := wdbtcOrders.Cells[3, row];
newForm.JobName := wdbtcOrders.Cells[4, row];
if wdbtcOrders.Cells[15, row] <> '' then
newForm.ShipDue := StrToDateTime(wdbtcOrders.Cells[15, row])
else
......@@ -893,6 +910,7 @@ begin
if orderID <> '' then
searchOptions := searchOptions + '&orderID=' + orderID;
edtSearch.text := searchOptions;
FViewMain.search := searchOptions;
Result := searchOptions;
end;
......
......@@ -48,7 +48,7 @@ object FSetStatus: TFSetStatus
WidthPercent = 100.000000000000000000
end
object WebLabel3: TWebLabel
Left = 174
Left = 90
Top = 14
Width = 57
Height = 14
......@@ -184,7 +184,7 @@ object FSetStatus: TFSetStatus
object edtOrderID: TWebEdit
Left = 16
Top = 34
Width = 145
Width = 63
Height = 22
HelpType = htKeyword
TabStop = False
......@@ -204,9 +204,9 @@ object FSetStatus: TFSetStatus
WidthPercent = 100.000000000000000000
end
object edtJobName: TWebEdit
Left = 174
Left = 90
Top = 34
Width = 145
Width = 229
Height = 22
HelpType = htKeyword
TabStop = False
......
......@@ -170,7 +170,13 @@ procedure TFSetStatus.SetDueDates();
begin
if OrderType = 'corrugated plate' then
begin
if wlcbStatus.DisplayText = 'Art Done' then
if wlcbStatus.DisplayText = 'Proof Done' then
begin
dtpPlateDue.Date := plateDue;
dtpMountDue.Date := mountDue;
dtpShipDue.Date := shipDue;
end
else if wlcbStatus.DisplayText = 'Art Done' then
begin
dtpPlateDue.Date := getNextDate(dtpDate.Date);
dtpMountDue.Date := getNextDate(dtpPlateDue.Date);
......@@ -178,29 +184,60 @@ begin
end
else if wlcbStatus.DisplayText = 'Plate Done' then
begin
dtpPlateDue.Date := plateDue;
dtpMountDue.Date := getNextDate(dtpDate.Date);
dtpShipDue.Date := getNextDate(dtpMountDue.Date);
end
else if wlcbStatus.DisplayText = 'Mount Done' then
begin
dtpPlateDue.Date := plateDue;
dtpMountDue.Date := mountDue;
dtpShipDue.Date := getNextDate(dtpDate.Date);
end
else if wlcbStatus.DisplayText = 'Ship Done' then
begin
dtpPlateDue.Date := plateDue;
dtpMountDue.Date := mountDue;
dtpShipDue.Date := shipDue;
end;
end
else if OrderType = 'web plate' then
begin
if wlcbStatus.DisplayText = 'Art Done' then
if wlcbStatus.DisplayText = 'Proof Done' then
begin
dtpPlateDue.Date := plateDue;
dtpShipDue.Date := shipDue;
end
else if wlcbStatus.DisplayText = 'Art Done' then
begin
dtpPlateDue.Date := getNextDate(dtpDate.Date);
dtpShipDue.Date := getNextDate(dtpMountDue.Date);
dtpShipDue.Date := getNextDate(dtpPlateDue.Date);
end
else if wlcbStatus.DisplayText = 'Plate Done' then
begin
dtpShipDue.Date := getNextDate(dtpMountDue.Date);
dtpPlateDue.Date := plateDue;
dtpShipDue.Date := getNextDate(dtpDate.Date);
end
else if wlcbStatus.DisplayText = 'Ship Done' then
begin
dtpPlateDue.Date := plateDue;
dtpShipDue.Date := shipDue;
end;
end
else
begin
if wlcbStatus.DisplayText = 'Art Done' then
if wlcbStatus.DisplayText = 'Proof Done' then
begin
dtpShipDue.Date := shipDue;
end
else if wlcbStatus.DisplayText = 'Art Done' then
begin
dtpShipDue.Date := getNextDate(dtpDate.Date);
end
else if wlcbStatus.DisplayText = 'Ship Done' then
begin
dtpShipDue.Date := shipDue;
end;
end;
end;
......
......@@ -93,6 +93,7 @@ object FViewEditUser: TFViewEditUser
Top = 62
Width = 121
Height = 22
TabStop = False
ChildOrder = 7
ElementID = 'edtemail'
HeightPercent = 100.000000000000000000
......@@ -103,6 +104,7 @@ object FViewEditUser: TFViewEditUser
Top = 34
Width = 121
Height = 22
TabStop = False
ChildOrder = 13
ElementID = 'edtpassword'
HeightPercent = 100.000000000000000000
......@@ -131,6 +133,7 @@ object FViewEditUser: TFViewEditUser
Top = 5
Width = 121
Height = 22
TabStop = False
ChildOrder = 14
ElementID = 'edtfullname'
HeightPercent = 100.000000000000000000
......@@ -141,6 +144,7 @@ object FViewEditUser: TFViewEditUser
Top = 6
Width = 121
Height = 22
TabStop = False
ChildOrder = 14
ElementID = 'edtusername'
HeightPercent = 100.000000000000000000
......@@ -179,6 +183,7 @@ object FViewEditUser: TFViewEditUser
Font.Style = [fsBold]
HeightPercent = 100.000000000000000000
ParentFont = False
TabOrder = -1
WidthPercent = 100.000000000000000000
end
object edtRights: TWebEdit
......@@ -186,6 +191,7 @@ object FViewEditUser: TFViewEditUser
Top = 93
Width = 121
Height = 22
TabStop = False
ChildOrder = 19
ElementID = 'edtrights'
HeightPercent = 100.000000000000000000
......@@ -198,6 +204,7 @@ object FViewEditUser: TFViewEditUser
Height = 23
ElementID = 'cbaccess'
HeightPercent = 100.000000000000000000
TabStop = False
WidthPercent = 100.000000000000000000
ItemIndex = -1
Items.Strings = (
......@@ -210,6 +217,7 @@ object FViewEditUser: TFViewEditUser
Top = 62
Width = 121
Height = 22
TabStop = False
ChildOrder = 7
ElementID = 'edtQB'
HeightPercent = 100.000000000000000000
......
// Form that functions as both a way to edit or add users to the database
// Author: Cameron Hayes
unit View.EditUser;
unit View.User.Add;
interface
......@@ -99,6 +99,7 @@ begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser', [userInfo]));
responseString := TJSObject(xdcResponse.Result);
Info := string(responseString['value']);
FViewMain.ShowUserForm(Info);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
......@@ -123,14 +124,16 @@ begin
'&newuser=' + edtUsername.Text +
'&rights=' + edtRights.Text +
'&QB=' + edtQB.Text;
console.log(editOptions);
try
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.EditUser',
[editOptions]));
responseString := TJSObject(xdcResponse.Result);
Info := string(responseString['value']);
FViewMain.ShowUserForm(Info);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
end;
end;
class function TFViewEditUser.CreateForm(AElementID, Mode, Username, Password, Name, Status, Email,
......@@ -162,7 +165,7 @@ begin
ShowToast(FMessage);
edtUsername.Text := Username;
edtFullName.Text := FullName;
if Mode = 'Edit' then
if Mode = 'EDIT' then
begin
edtPassword.Text := 'hidden';
end;
......@@ -193,6 +196,7 @@ var
FormEl: TJSHTMLFormElement;
AllValid: Boolean;
begin
console.log(mode);
FormEl := TJSHTMLFormElement(document.getElementById('userprofileform'));
// Clear previous invalid state
......@@ -227,12 +231,15 @@ begin
ShowConfirmationModal(
'Are you sure you want to save changes?',
'Save',
'Cancel',
'Yes',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
EditUser;
if mode = 'ADD' then
AddUser()
else
EditUser();
end
);
end;
......
......@@ -28,8 +28,8 @@ object FViewUserProfile: TFViewUserProfile
WidthPercent = 100.000000000000000000
end
object WebLabel3: TWebLabel
Left = 39
Top = 59
Left = 41
Top = 60
Width = 38
Height = 14
Caption = 'User ID:'
......@@ -45,8 +45,8 @@ object FViewUserProfile: TFViewUserProfile
WidthPercent = 100.000000000000000000
end
object WebLabel2: TWebLabel
Left = 13
Top = 131
Left = 8
Top = 143
Width = 71
Height = 14
Caption = 'Email Address:'
......@@ -62,8 +62,8 @@ object FViewUserProfile: TFViewUserProfile
WidthPercent = 100.000000000000000000
end
object WebLabel4: TWebLabel
Left = 29
Top = 83
Left = 27
Top = 84
Width = 52
Height = 14
Caption = 'Username:'
......@@ -79,8 +79,8 @@ object FViewUserProfile: TFViewUserProfile
WidthPercent = 100.000000000000000000
end
object WebLabel5: TWebLabel
Left = 29
Top = 107
Left = 30
Top = 117
Width = 49
Height = 14
Caption = 'Full Name:'
......@@ -95,160 +95,157 @@ object FViewUserProfile: TFViewUserProfile
ParentFont = False
WidthPercent = 100.000000000000000000
end
object lblResult: TWebLabel
Left = 85
Top = 246
Width = 3
Height = 14
ElementID = 'view.userprofile.form.lblresult'
ElementPosition = epRelative
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
object WebLabel6: TWebLabel
Left = 15
Top = 171
Width = 64
Height = 13
Caption = 'Access Type:'
ElementID = 'view.userprofile.form.lblAccessType'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
ParentFont = False
WidthPercent = 100.000000000000000000
end
object edtUsername: TWebEdit
Left = 85
Top = 80
Width = 121
Height = 21
ElementID = 'view.userprofile.form.edtUsername'
ElementPosition = epRelative
Enabled = False
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
object WebLabel7: TWebLabel
Left = 47
Top = 196
Width = 32
Height = 13
Caption = 'QB ID:'
ElementID = 'view.userprofile.form.lblQBID'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
HideSelection = False
ParentFont = False
ReadOnly = True
WidthPercent = 100.000000000000000000
end
object edtUserId: TWebEdit
Left = 85
Top = 56
object WebDBEdit1: TWebDBEdit
Left = 90
Top = 168
Width = 121
Height = 21
ElementID = 'view.userprofile.form.edtUserID'
ElementPosition = epRelative
Enabled = False
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
Height = 22
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtAccessType'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
HideSelection = False
ParentFont = False
ReadOnly = True
TabOrder = 1
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
DataField = 'AType'
DataSource = wdsUser
end
object edtFullName: TWebEdit
Left = 85
Top = 104
object WebDBEdit2: TWebDBEdit
Left = 90
Top = 140
Width = 121
Height = 21
ChildOrder = 5
ElementID = 'view.userprofile.form.edtFullName'
ElementPosition = epRelative
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
Height = 22
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtEmail'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
HideSelection = False
ParentFont = False
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
DataField = 'email_address'
DataSource = wdsUser
end
object chkAdminUser: TWebCheckBox
Left = 85
Top = 179
Width = 113
object WebDBEdit3: TWebDBEdit
Left = 90
Top = 114
Width = 121
Height = 22
Caption = 'chkAdminUser'
ChildOrder = 9
ElementID = 'view.userprofile.form.chkAdminUser'
ElementPosition = epRelative
Enabled = False
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtFullName'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
ParentFont = False
Role = 'null'
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
DataField = 'full_name'
DataSource = wdsUser
end
object edtEmail: TWebEdit
object WebDBEdit4: TWebDBEdit
Left = 85
Top = 126
Top = 81
Width = 121
Height = 21
ChildOrder = 7
ElementID = 'view.userprofile.form.edtEmail'
ElementPosition = epRelative
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
Height = 22
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtUsername'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
HideSelection = False
ParentFont = False
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
DataField = 'username'
DataSource = wdsUser
end
object btnConfirm: TWebButton
object WebDBEdit5: TWebDBEdit
Left = 85
Top = 207
Width = 96
Height = 25
Caption = 'Confirm Changes'
ChildOrder = 12
ElementID = 'view.userprofile.form.btnconfirm'
ElementPosition = epRelative
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
Top = 57
Width = 121
Height = 22
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtUserID'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
ParentFont = False
Role = 'button'
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
OnClick = btnConfirmClick
end
object btnCancel: TWebButton
Left = 208
Top = 210
Width = 96
Height = 25
Caption = 'Cancel Changes'
ChildOrder = 14
ElementID = 'view.userprofile.form.btncancel'
ElementPosition = epRelative
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
DataField = 'userID'
DataSource = wdsUser
end
object WebDBEdit6: TWebDBEdit
Left = 90
Top = 196
Width = 121
Height = 22
ChildOrder = 13
ElementClassName = 'form-control'
ElementID = 'view.userprofile.form.edtQBID'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
ParentFont = False
Role = 'button'
Text = 'WebDBEdit1'
WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
DataField = 'QBID'
DataSource = wdsUser
end
object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 359
Top = 52
end
object xdwdsUser: TXDataWebDataSet
Left = 314
Top = 216
object xdwdsUseruserID: TStringField
FieldName = 'userID'
end
object xdwdsUserusername: TStringField
FieldName = 'username'
end
object xdwdsUseremail_address: TStringField
FieldName = 'email_address'
end
object xdwdsUserQBID: TStringField
FieldName = 'QBID'
end
object xdwdsUserAType: TStringField
FieldName = 'Atype'
end
object xdwdsUserfull_name: TStringField
FieldName = 'full_name'
end
end
object wdsUser: TWebDataSource
AutoEdit = False
DataSet = xdwdsUser
Left = 422
Top = 262
end
end
......@@ -18,9 +18,7 @@
for="view.userprofile.form.edtUsername"
class="form-label">Username</label>
<input id="view.userprofile.form.edtUsername"
class="form-control"
required>
<div class="invalid-feedback">Username is required.</div>
class="form-control">
</div>
<div class="mb-3">
......@@ -28,9 +26,7 @@
for="view.userprofile.form.edtFullName"
class="form-label">Full&nbsp;Name</label>
<input id="view.userprofile.form.edtFullName"
class="form-control"
required>
<div class="invalid-feedback">Full Name is required.</div>
class="form-control">
</div>
<div class="mb-3">
......@@ -39,36 +35,26 @@
class="form-label">Email&nbsp;Address</label>
<input id="view.userprofile.form.edtEmail"
type="email"
class="form-control"
required>
<div class="invalid-feedback">Valid email is required.</div>
class="form-control">
</div>
<div class="form-check mb-4">
<input type="checkbox"
id="view.userprofile.form.chkAdminUser"
class="form-check-input">
<label for="view.userprofile.form.chkAdminUser"
class="form-check-label">
Admin&nbsp;User
</label>
<div class="mb-3">
<label id="view.userprofile.form.lblAccessType"
for="view.userprofile.form.edtAccessType"
class="form-label">Email&nbsp;Address</label>
<input id="view.userprofile.form.edtAccessType"
type="email"
class="form-control">
</div>
<div class="d-flex gap-2 mb-4">
<button id="view.userprofile.form.btnconfirm"
class="btn btn-primary flex-grow-1"
type="button">
Confirm&nbsp;Changes
</button>
<button id="view.userprofile.form.btncancel"
class="btn btn-danger flex-grow-1"
type="button">
Cancel&nbsp;Changes
</button>
<div class="mb-3">
<label id="view.userprofile.form.lblQBID"
for="view.userprofile.form.edtQBID"
class="form-label">Email&nbsp;Address</label>
<input id="view.userprofile.form.edtQBID"
type="email"
class="form-control">
</div>
<label id="view.userprofile.form.lblresult" class="form-text"></label>
</form>
</div>
</div>
......
......@@ -7,29 +7,34 @@ uses
WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls,
XData.Web.Client, WEBLib.ExtCtrls, DB, XData.Web.JsonDataset,
XData.Web.Dataset, XData.Web.Connection, Vcl.Forms, ConnectionModule,
WEBLib.Toast;
WEBLib.Toast, WEBLib.DBCtrls;
type
TFViewUserProfile = class(TWebForm)
WebLabel1: TWebLabel;
WebLabel3: TWebLabel;
edtUsername: TWebEdit;
WebLabel2: TWebLabel;
edtUserId: TWebEdit;
edtFullName: TWebEdit;
WebLabel4: TWebLabel;
WebLabel5: TWebLabel;
chkAdminUser: TWebCheckBox;
edtEmail: TWebEdit;
btnConfirm: TWebButton;
lblResult: TWebLabel;
XDataWebClient1: TXDataWebClient;
btnCancel: TWebButton;
WebDBEdit1: TWebDBEdit;
WebDBEdit2: TWebDBEdit;
WebDBEdit3: TWebDBEdit;
WebDBEdit4: TWebDBEdit;
WebDBEdit5: TWebDBEdit;
WebDBEdit6: TWebDBEdit;
WebLabel6: TWebLabel;
WebLabel7: TWebLabel;
xdwdsUser: TXDataWebDataSet;
wdsUser: TWebDataSource;
xdwdsUseruserID: TStringField;
xdwdsUserusername: TStringField;
xdwdsUseremail_address: TStringField;
xdwdsUserQBID: TStringField;
xdwdsUserAType: TStringField;
xdwdsUserfull_name: TStringField;
procedure WebFormShow(Sender: TObject);
procedure btnConfirmClick(Sender: TObject);
[async] procedure EditUser();
[async] procedure GetUser();
procedure btnCancelClick(Sender: TObject);
end;
var
......@@ -46,77 +51,9 @@ uses
{$R *.dfm}
procedure TFViewUserProfile.btnConfirmClick(Sender: TObject);
var
FormEl: TJSHTMLFormElement;
begin
FormEl := TJSHTMLFormElement(document.querySelector('form'));
ShowConfirmationModal(
'Are you sure you want to save changes to your profile?',
'Save',
'Cancel',
procedure(confirmed: Boolean)
begin
if confirmed then
EditUser;
end
);
end;
[async] procedure TFViewUserProfile.EditUser;
var
xdcResponse: TXDataClientResponse;
responseString: TJSObject;
editOptions, resultMsg: string;
begin
try
editOptions := '&username=' + edtUsername.Text +
'&fullname=' + edtFullName.Text +
'&email=' + edtEmail.Text;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.EditUser', [editOptions]));
responseString := TJSObject(xdcResponse.Result);
resultMsg := string(responseString['value']);
Utils.ShowToast(resultMsg);
if resultMsg.ToLower.StartsWith('success:') then
FViewMain.ViewOrders('');
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
on E: Exception do
Utils.ShowErrorModal('Unexpected error: ' + E.Message);
end;
end;
procedure TFViewUserProfile.btnCancelClick(Sender: TObject);
begin
ShowConfirmationModal(
'Are you sure you want to cancel all your changes?',
'Yes',
'No',
procedure(confirmed: Boolean)
begin
if confirmed then
begin
GetUser();
ShowToast('Changes discarded', 'danger');
end;
end
);
end;
procedure TFViewUserProfile.WebFormShow(Sender: TObject);
begin
GetUser();
//edtJwt.Text := TJSJSON.stringify(AuthService.TokenPayload);
// View.UserProfile.WebFormShow
chkAdminUser.Checked := SameText(string(AuthService.TokenPayload.Properties['user_admin']), 'true');
end;
......@@ -133,11 +70,9 @@ begin
userList := TJSObject(xdcResponse.Result);
data := TJSArray(userList['data']);
user := TJSObject(data[0]);
edtUsername.Text := string(user['username']);
edtFullName.Text := string(user['full_name']);
edtEmail.Text := string(user['email_address']);
edtUserId.Text := string(user['userID']);
chkAdminUser.Checked := boolean(user['admin']);
console.log(user);
xdwdsUser.SetJsonData(user);
xdwdsUser.Open;
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
......
......@@ -140,7 +140,7 @@ begin
Rights := cells[7];
QB := cells[8];
FViewMain.EditUser('Edit', Username.innerText, Password.innerText, FullName.innerText,
FViewMain.EditUser('EDIT', Username.innerText, Password.innerText, FullName.innerText,
Status.innerText, Email.innerText, Access.innerText,
Rights.innerText, QB.innerText);
......@@ -343,20 +343,9 @@ begin
XDataWebDataSet1QBID.AsString, XDataWebDataSet1rights.AsInteger);
XDataWebDataSet1.Next;
end;
TotalPages := (userListLength + PageSize - 1) div PageSize;
if (PageNumber * PageSize) < userListLength then
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(PageNumber * PageSize) +
' of ' + IntToStr(userListLength);
end
else
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(userListLength) +
' of ' + IntToStr(userListLength);
end;
GeneratePagination(TotalPages);
except
on E: EXDataClientRequestException do
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
......@@ -453,7 +442,7 @@ end;
procedure TFViewUsers.btnAddUserClick(Sender: TObject);
begin
//Info := '';
FViewMain.EditUser('Add', '', '', '', '', '', '', '', '');
FViewMain.EditUser('ADD', '', '', '', '', '', '', '', '');
end;
......
......@@ -7,6 +7,10 @@
background-color: #fff;
}
.tbl-min-120 {
min-width: 120px;
}
input[type="text"] {
min-width: 50px;
max-width: 100%;
......
......@@ -16,20 +16,20 @@ uses
View.Main in 'View.Main.pas' {FViewMain: TWebForm} {*.html},
View.Home in 'View.Home.pas' {FViewHome: TWebForm} {*.html},
View.Users in 'View.Users.pas' {FViewUsers: TWebForm} {*.html},
View.EditUser in 'View.EditUser.pas' {FViewEditUser: TWebForm} {*.html},
View.User.Add in 'View.User.Add.pas' {FViewEditUser: TWebForm} {*.html},
View.Orders in 'View.Orders.pas' {FViewOrders: TWebForm} {*.html},
View.OrderEntryCorrugated in 'View.OrderEntryCorrugated.pas' {FOrderEntryCorrugated: TWebForm} {*.html},
View.AddOrder in 'View.AddOrder.pas' {FAddOrder: TWebForm} {*.html},
View.Order.Add in 'View.Order.Add.pas' {FAddOrder: TWebForm} {*.html},
View.Search in 'View.Search.pas' {FSearch: TWebForm} {*.html},
View.SetStatus in 'View.SetStatus.pas' {FSetStatus: TWebForm} {*.html},
View.OrderEntryCuttingDie in 'View.OrderEntryCuttingDie.pas' {FOrderEntryCuttingDie: TWebForm} {*.html},
View.OrderEntryWeb in 'View.OrderEntryWeb.pas' {FOrderEntryWeb: TWebForm} {*.html},
View.Customers in 'View.Customers.pas' {FViewCustomers: TWebForm} {*.html},
AddCustomer in 'AddCustomer.pas' {FViewAddCustomer: TWebForm} {*.html},
View.AddAddress in 'View.AddAddress.pas' {FViewAddAddress: TWebForm} {*.html},
View.SelectCustomer in 'View.SelectCustomer.pas' {FSelectCustomer: TWebForm} {*.html},
View.Customer.Add in 'View.Customer.Add.pas' {FViewAddCustomer: TWebForm} {*.html},
View.Address.Add in 'View.Address.Add.pas' {FViewAddAddress: TWebForm} {*.html},
View.Customer.Select in 'View.Customer.Select.pas' {FSelectCustomer: TWebForm} {*.html},
Utils in 'Utils.pas',
View.AddItem in 'View.AddItem.pas' {fViewAddItem: TWebForm} {*.html};
View.Item.Add in 'View.Item.Add.pas' {fViewAddItem: TWebForm} {*.html};
{$R *.res}
......
......@@ -159,7 +159,7 @@
<Form>FViewUsers</Form>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.EditUser.pas">
<DCCReference Include="View.User.Add.pas">
<Form>FViewEditUser</Form>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
......@@ -171,7 +171,7 @@
<Form>FOrderEntryCorrugated</Form>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.AddOrder.pas">
<DCCReference Include="View.Order.Add.pas">
<Form>FAddOrder</Form>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
......@@ -196,23 +196,23 @@
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="AddCustomer.pas">
<DCCReference Include="View.Customer.Add.pas">
<Form>FViewAddCustomer</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.AddAddress.pas">
<DCCReference Include="View.Address.Add.pas">
<Form>FViewAddAddress</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.SelectCustomer.pas">
<DCCReference Include="View.Customer.Select.pas">
<Form>FSelectCustomer</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="Utils.pas"/>
<DCCReference Include="View.AddItem.pas">
<DCCReference Include="View.Item.Add.pas">
<Form>fViewAddItem</Form>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
......
......@@ -10,6 +10,45 @@ object AuthDatabase: TAuthDatabase
FetchRows = 100
Left = 162
Top = 45
object uqUSER_ID: TIntegerField
FieldName = 'USER_ID'
end
object uqUSER_NAME: TStringField
FieldName = 'USER_NAME'
Required = True
Size = 56
end
object uqPASSWORD: TStringField
FieldName = 'PASSWORD'
Size = 128
end
object uqNAME: TStringField
FieldName = 'NAME'
Size = 40
end
object uqSTATUS: TStringField
FieldName = 'STATUS'
Size = 7
end
object uqEMAIL: TStringField
FieldName = 'EMAIL'
Size = 50
end
object uqACCESS_TYPE: TStringField
FieldName = 'ACCESS_TYPE'
Size = 5
end
object uqSYSTEM_RIGHTS: TIntegerField
FieldName = 'SYSTEM_RIGHTS'
end
object uqPERSPECTIVE_ID: TStringField
FieldName = 'PERSPECTIVE_ID'
Size = 128
end
object uqQB_ID: TStringField
FieldName = 'QB_ID'
Size = 45
end
end
object uqMisc: TUniQuery
FetchRows = 100
......@@ -18,6 +57,7 @@ object AuthDatabase: TAuthDatabase
end
object ucKG: TUniConnection
ProviderName = 'MySQL'
Database = 'kg_order_entry'
LoginPrompt = False
Left = 67
Top = 131
......
......@@ -14,6 +14,16 @@ type
uqMisc: TUniQuery;
ucKG: TUniConnection;
MySQLUniProvider1: TMySQLUniProvider;
uqUSER_ID: TIntegerField;
uqUSER_NAME: TStringField;
uqPASSWORD: TStringField;
uqNAME: TStringField;
uqSTATUS: TStringField;
uqEMAIL: TStringField;
uqACCESS_TYPE: TStringField;
uqSYSTEM_RIGHTS: TIntegerField;
uqPERSPECTIVE_ID: TStringField;
uqQB_ID: TStringField;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
......
......@@ -17,23 +17,13 @@ type
TAuthService = class(TInterfacedObject, IAuthService)
strict private
authDB: TAuthDatabase;
function GetQuery: TUniQuery;
private
userName: string;
userFullName: string;
userId: string;
userPerspectiveID: string;
userQBID: string;
userAccessType: string;
userEmail: string;
userStatus: string;
qbEnabled: boolean;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
function CheckUser(const user, password: string): Integer;
public
function Login(const user, password: string): string;
function VerifyVersion(ClientVersion: string): TJSONObject;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
implementation
......@@ -72,11 +62,6 @@ begin
inherited;
end;
function TAuthService.GetQuery: TUniQuery;
begin
Result := authDB.uq;
end;
function TAuthService.VerifyVersion(ClientVersion: string): TJSONObject;
var
iniFile: TIniFile;
......@@ -89,7 +74,6 @@ begin
try
webClientVersion := iniFile.ReadString('Settings', 'webClientVersion', '');
Result.AddPair('webClientVersion', webClientVersion);
qbEnabled := iniFile.ReadBool('Quickbooks', 'Enabled', false);
if webClientVersion = '' then
begin
......@@ -98,9 +82,13 @@ begin
end;
if clientVersion <> webClientVersion then
begin
//Result.AddPair('error',
//'Your browser is running version' + webClientVersion + ' when it should be running ' +
//clientVersion + sLineBreak + 'Please click below to reload.');
Result.AddPair('error',
'Your browser is running an old version of the app.' + sLineBreak +
'Please click below to reload.');
'Version mismatch' + sLineBreak + ' Client version: ' + clientVersion +
sLineBreak + ' Server version: ' + webClientVersion +
sLineBreak + 'Please click button to clear cache and reload.');
end;
finally
iniFile.Free;
......@@ -113,10 +101,9 @@ var
userState: Integer;
iniFile: TIniFile;
JWT: TJWT;
qbEnabled: boolean;
begin
Logger.Log(3, Format( 'AuthService.Login - User: "%s"', [User]));
userState := CheckUser( user, password );
try
userState := CheckUser(user, password);
except
......@@ -129,18 +116,18 @@ begin
if userState = 0 then
begin
raise EXDataHttpUnauthorized.Create('Invalid username or password');
logger.Log(2, 'Login Error: Invalid username or password');
raise EXDataHttpUnauthorized.Create('Invalid username or password');
end
else if userState = 1 then
begin
raise EXDataHttpUnauthorized.Create('User does not exist!');
logger.Log(2, 'Login Error: User does not exist!');
raise EXDataHttpUnauthorized.Create('User does not exist!');
end
else if userState = 2 then
begin
raise EXDataHttpUnauthorized.Create('User not active!');
logger.Log(2, 'Login Error: User not active!');
raise EXDataHttpUnauthorized.Create('User not active!');
end;
......@@ -156,14 +143,13 @@ begin
JWT.Claims.JWTId := LowerCase(Copy(TUtils.GuidToVariant(TUtils.NewGuid), 2, 36));
JWT.Claims.IssuedAt := Now;
JWT.Claims.Expiration := IncHour(Now, 24);
JWT.Claims.SetClaimOfType<string>('user_name', userName);
JWT.Claims.SetClaimOfType<string>('user_fullname', userFullName);
JWT.Claims.SetClaimOfType<string>('user_id', userId);
JWT.Claims.SetClaimOfType<string>('user_perspective_id', userPerspectiveID);
JWT.Claims.SetClaimOfType<string>('user_status', userStatus);
JWT.Claims.SetClaimOfType<string>('user_email', userEmail);
JWT.Claims.SetClaimOfType<string>('user_qb_id', userQBID);
JWT.Claims.SetClaimOfType<string>('user_access_type', userAccessType);
JWT.Claims.SetClaimOfType<string>('user_name', authDB.uq.FieldByName('USER_NAME').AsString);
JWT.Claims.SetClaimOfType<string>('user_fullname', authDB.uq.FieldByName('NAME').AsString);
JWT.Claims.SetClaimOfType<string>('user_id', authDB.uq.FieldByName('USER_ID').AsString);
JWT.Claims.SetClaimOfType<string>('user_status', authDB.uq.FieldByName('STATUS').AsString);
JWT.Claims.SetClaimOfType<string>('user_email', authDB.uq.FieldByName('EMAIL').AsString);
JWT.Claims.SetClaimOfType<string>('user_qb_id', authDB.uq.FieldByName('QB_ID').AsString);
JWT.Claims.SetClaimOfType<string>('user_access_type', authDB.uq.FieldByName('ACCESS_TYPE').AsString);
JWT.Claims.SetClaimOfType<boolean>('qb_enabled', qbEnabled);
Result := TJOSE.SHA256CompactToken(serverConfig.jwtTokenSecret, JWT);
......@@ -174,12 +160,10 @@ end;
function TAuthService.CheckUser(const user, password: string): Integer;
var
userStr: string;
SQL: string;
name: string;
checkString: string;
begin
Result := 0;
Logger.Log(1, Format('AuthService.CheckUser - User: "%s"', [user]) );
SQL := 'select * from users where USER_NAME = ' + QuotedStr(user);
DoQuery(authDB.uq, SQL);
......@@ -193,22 +177,13 @@ begin
begin
name := authDB.uq.FieldByName('NAME').AsString;
checkString := THashSHA2.GetHashString(name + password, THashSHA2.TSHA2Version.SHA512).ToUpper;
if authDB.uq.FieldByName('PASSWORD').AsString = checkString then
if authDB.uq.FieldByName('PASSWORD').AsString = checkstring then
begin
userName := user;
userFullName:= authDB.uq.FieldByName('NAME').AsString;;
userId := authDB.uq.FieldByName('USER_ID').AsString;
userStatus := authDB.uq.FieldByName('STATUS').AsString;
userPerspectiveID := authDB.uq.FieldByName('PERSPECTIVE_ID').AsString;
userEmail := authDB.uq.FieldByName('EMAIL').AsString;
userQBID := authDB.uq.FieldByName('QB_ID').AsString;
userAccessType := authDB.uq.FieldByName('ACCESS_TYPE').AsString;
Logger.Log(1, Format('AuthDB.SetLoginAuditEntry: "%s"', [user]) );
Result := 3; // Succcess
end
else
Result := 0; // invalid password
Result := 0; // invalid user or password
end;
end;
......
......@@ -64,6 +64,13 @@ begin
Logger.Log(1, '-- jwtTokenSecret: ' + serverConfig.jwtTokenSecret + IfThen(serverConfig.jwtTokenSecret = 'super_secret0123super_secret4567', ' [default]', ' [from config]'));
Logger.Log(1, '-- webAppFolder: ' + serverConfig.webAppFolder + IfThen(serverConfig.webAppFolder = 'static', ' [default]', ' [from config]'));
Logger.Log(1, '-- serverConfig.reportsFolder: ' + serverConfig.reportsFolder);
if not DirectoryExists(serverConfig.reportsFolder + 'reports\') then
begin
ForceDirectories(serverConfig.reportsFolder + 'reports\');
Logger.Log(1, '-- Reports directory created: ' + serverConfig.reportsFolder + 'reports\');
end;
Logger.Log(1, '--LoadServerConfig - end');
end;
......@@ -78,7 +85,8 @@ begin
adminPassword := 'whatisthisusedfor';
jwtTokenSecret := 'super_secret0123super_secret4567';
webAppFolder := 'static';
reportsFolder := 'static/';
reportsFolder := 'static\';
ServerConfigStr := Bcl.Json.TJson.Serialize(ServerConfig);
Logger.Log(1, '--ServerConfigSerialize: ' + ServerConfigStr);
Logger.Log(1, '--TServerConfig.Create - end');
......
......@@ -43,8 +43,6 @@ object FData: TFData
Lines.Strings = (
'Memo1')
TabOrder = 1
ExplicitLeft = -2
ExplicitTop = 435
end
object DBAdvGrid1: TDBAdvGrid
Left = 6
......@@ -174,7 +172,7 @@ object FData: TFData
SortSettings.HeaderColorTo = clWhite
SortSettings.HeaderMirrorColor = clWhite
SortSettings.HeaderMirrorColorTo = clWhite
Version = '2.8.3.3'
Version = '2.8.3.8'
AutoCreateColumns = True
AutoRemoveColumns = True
Columns = <
......@@ -755,7 +753,7 @@ object FData: TFData
SortSettings.HeaderColorTo = clWhite
SortSettings.HeaderMirrorColor = clWhite
SortSettings.HeaderMirrorColorTo = clWhite
Version = '2.8.3.3'
Version = '2.8.3.8'
AutoCreateColumns = True
AutoRemoveColumns = True
Columns = <
......
......@@ -130,8 +130,6 @@ type
procedure Button1Click(Sender: TObject);
private
kgDB: TApiDatabase;
accountSID: string;
authHeader: string;
public
procedure RunOrdersReport(searchOptions: string);
end;
......@@ -190,7 +188,6 @@ procedure TFData.btnFindClick(Sender: TObject);
// whereSQL: where section of the SQL that is built in the function
var
SQL: string;
whereSQL: string;
begin
Memo1.Lines.Add(uqUsers.Connection.Server);
SQL := 'select * from users';
......
......@@ -72,14 +72,14 @@ type
function CreateStatusSearchInfo(params: TStringList; statusNum: string): TStatusSearchInfo;
function SetStatus(statusOptions: string): string;
procedure AddToOrdersTable(mode, ORDER_TYPE: string; JSONData: TJSONObject);
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
procedure AddToRevisionsTable(OrderID, table: string; order: TJSONObject);
procedure SaveTokens(AccessToken, RefreshToken: string);
function RefreshAccessToken: string;
function ImportQBCustomer(CustomerInfo: string): TJSONObject;
procedure AddAddrBlock(prefix: string; AddrJSON: TJSONObject);
function AddEstimate(orderInfo: string): TJSONObject;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
......@@ -135,16 +135,18 @@ begin
BillAddrJSON := TJSONObject.Create;
ShipAddrJSON := TJSONObject.Create;
EstimateJSON := TJSONObject.Create;
CustomerRefJSON := TJSONObject.Create;
CustomFields := TJSONArray.Create;
CustomField := TJSONObject.Create;
LineArray := TJSONArray.Create;
LineObj := TJSONObject.Create;
DetailObj := TJSONObject.Create;
ItemRefObj := TJSONObject.Create;
TaxCodeRef := TJSONObject.Create;
TxnTaxCodeRef := TJSONObject.Create;
TxnTaxDetail := TJSONObject.Create;
restClient := TRESTClient.Create(nil);
restRequest := TRESTRequest.Create(nil);
restResponse := TRESTResponse.Create(nil);
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
Logger.Log(3, 'TLookupService.AddEstimate');
try
try
......@@ -156,6 +158,7 @@ begin
USER_ID := JSONData.GetValue<string>('USER_ID');
SQL := 'select * from orders where ORDER_ID = ' + ORDER_ID;
logger.Log(5, 'Retrieving order type with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
if ordersDB.UniQuery1.FieldByName('ORDER_TYPE').AsString = 'corrugated_plate' then
begin
......@@ -169,6 +172,7 @@ begin
table := 'cutting_die_orders';
SQL := 'select * from ' + table + ' cpo join customers c on cpo.COMPANY_ID = c.CUSTOMER_ID join customers_ship cs on cpo.staff_fields_ship_to = cs.ship_block JOIN qb_items ON cpo.staff_fields_quickbooks_item = qb_items.qb_item_name where cpo.ORDER_ID = ' + ORDER_ID;
logger.Log(5, 'Retrieveing Customer Info with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
estimateJSON.AddPair('TxnDate', ordersDB.UniQuery1.FieldByName('staff_fields_order_date').AsString);
......@@ -249,18 +253,15 @@ begin
estimateJSON.AddPair('ShipDate', ordersDB.UniQuery1.FieldByName('staff_fields_ship_date').AsString)
end;
logger.Log(5, 'estimateJSON finished construction');
restClient := TRESTClient.Create(nil);
restClient.BaseURL := 'https://sandbox-quickbooks.api.intuit.com';
restRequest := TRESTRequest.Create(nil);
restRequest.Client := restClient;
restResponse := TRESTResponse.Create(nil);
restRequest.Response := restResponse;
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
if iniFile.ReadString('Quickbooks', 'LastRefresh', '') = '' then
LastRefresh := 0
else
......@@ -285,6 +286,7 @@ begin
restRequest.AddBody(estimateJSON.ToJSON, TRESTContentType.ctAPPLICATION_JSON);
logger.Log(5, 'Executing rest request with JSON: ' + estimateJSON.ToJSON);
restRequest.Execute;
jsValue := restResponse.JSONValue;
......@@ -292,6 +294,7 @@ begin
jsObj := TJSONObject(jsValue).GetValue<TJSONObject>('Estimate');
sql := 'select * from orders where ORDER_ID = ' + ORDER_ID;
logger.Log(5, 'Updating orders QB info');
doQuery(ordersDB.UniQuery1, SQL);
ordersDB.UniQuery1.Edit;
......@@ -304,10 +307,11 @@ begin
result := TJSONObject.Create;
Result.AddPair('status','Success:Estimate Successfully Added');
logger.log(3, 'AddEstimate Finished');
except
on E: Exception do
begin
logger.Log(2, 'Error when adding Estimate ' + e.Message);
logger.Log(1, 'Error when adding Estimate ' + e.Message);
jsValue := restResponse.JSONValue;
if not (jsValue is TJSONObject) then
......@@ -330,7 +334,7 @@ begin
on E: Exception do
msg := 'Unable to parse QuickBooks error: ' + E.Message;
end;
logger.Log(2, 'QuickBooks Error Message: ' + msg);
logger.Log(1, 'QuickBooks Error Message: ' + msg);
raise EXDataHttpException.Create(500, 'Unable to add QuickBooks Estimate: A QuickBooks interface error has occurred!');
end;
end;
......@@ -371,10 +375,13 @@ var
begin
logger.Log(3, 'TLookupService.DelShippingAddress');
SQL := 'DELETE FROM customers_ship WHERE customer_ship_id = ' + AddressID;
logger.Log(5, 'Deleting shipping address with SQL: ' + SQL);
OrdersDB.UniQuery1.SQL.Text := SQL;
OrdersDB.UniQuery1.ExecSQL;
result := TJSONObject.Create;
result.AddPair('status', 'Success: Address Successfully Deleted');
logger.Log(5, 'Address deleted retrieving updated address list...');
SQL := 'select * FROM customers c LEFT JOIN customers_ship s ON c.CUSTOMER_ID = s.customer_id WHERE c.CUSTOMER_ID = ' + CustomerID;
doQuery(ordersDB.UniQuery1, SQL);
ADDRESS_LIST := TJSONArray.Create;
......@@ -394,6 +401,7 @@ begin
Result.AddPair('ADDRESS', ADDRESS_LIST);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
logger.Log(3, 'DelShippingAddress Finished');
end;
......@@ -431,6 +439,7 @@ begin
try
SQL := 'select * from customers' + limitSQL;
logger.Log(5, 'retrieving customers with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
result := TCustomerList.Create;
......@@ -460,6 +469,7 @@ begin
doQuery(ordersDB.UniQuery1, SQL);
Result.count := ordersDB.UniQuery1.FieldByName('total_count').AsInteger;
ordersDB.UniQuery1.Close;
logger.Log(3, 'GetCustomers finished');
except
on E: Exception do
begin
......@@ -479,7 +489,6 @@ function TLookupService.GetCustomer(ID: string): TCustomerItem;
var
SQL: string;
ADDRESS: TAddressItem;
USER: TUserItem;
begin
logger.Log(3, 'TLookupService.GetCustomer');
try
......@@ -487,6 +496,7 @@ begin
SQL := 'select * FROM customers c LEFT JOIN customers_ship s ON c.CUSTOMER_ID = s.customer_id WHERE c.CUSTOMER_ID = -1'
else
SQL := 'select * FROM customers c LEFT JOIN customers_ship s ON c.CUSTOMER_ID = s.customer_id WHERE c.CUSTOMER_ID = ' + ID;
logger.Log(5, 'Getting customer with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
result := TCustomerItem.Create;
......@@ -525,6 +535,7 @@ begin
ordersDB.UniQuery1.Next;
end;
logger.Log(3, 'GetCustomer Finished');
except
on E: Exception do
begin
......@@ -554,6 +565,7 @@ begin
result.Add(USER);
ordersDB.uqUsers.Next;
end;
logger.Log(3, 'GetRepUsers finished');
end;
......@@ -617,14 +629,10 @@ var
Field: TField;
ShipID: integer;
mode: string;
temp: string;
msg: string;
ship_block: string;
ADDRESS: TJSONObject;
ADDRESS_LIST:TJSONArray;
CustomerID: string;
JSONArray: TJSONArray;
Item: TAddressItem;
begin
logger.Log(3, 'TLookupSerivce.AddShippingAddress');
result := TJSONObject.Create;
......@@ -635,15 +643,16 @@ begin
mode := JSONData.GetValue<string>('mode');
CustomerID := JSONData.GetValue<string>('customer_id');
if mode = 'EDIT' then
ShipID := JSONData.GetValue<integer>('customer_ship_id');
if mode = 'ADD' then
SQL := 'select * from customers_ship where customer_id = 0 and customer_id <> 0'
else
begin
ShipID := JSONData.GetValue<integer>('customer_ship_id');
SQL := 'select * from customers_ship where customer_ship_id = ' + IntToStr(ShipID);
end;
logger.Log(5, 'Retrieving Address with SQL ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
try
......@@ -676,10 +685,11 @@ begin
end
else
msg := 'Success: Shipping Address Successfully Edited';
logger.Log(3, msg);
// Sends the updated Address List Back.
SQL := 'select * FROM customers c LEFT JOIN customers_ship s ON c.CUSTOMER_ID = s.customer_id WHERE c.CUSTOMER_ID = ' + CustomerID;
logger.Log(5, 'Retrieving updated customer address list with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
ADDRESS_LIST := TJSONArray.Create;
while not ordersDB.UniQuery1.Eof do
......@@ -699,6 +709,7 @@ begin
Result.AddPair('status', msg);
Result.AddPair('ADDRESS', ADDRESS_LIST);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
logger.Log(3, 'AddShippingAddress finished');
except
on E: Exception do
begin
......@@ -716,7 +727,6 @@ var
DateFormat: TFormatSettings;
CustomerID: integer;
mode: string;
temp: string;
msg: string;
unique: boolean;
begin
......@@ -746,6 +756,7 @@ begin
CustomerID := JSONData.GetValue<integer>('CUSTOMER_ID');
SQL := 'select CUSTOMER_ID from customers where SHORT_NAME = ' + quotedStr(JSONData.GetValue<string>('SHORT_NAME'));
logger.Log(5, 'Retrieving customer with SQL: ' + SQL);
doQuery(OrdersDB.UniQuery1, SQL);
if mode = 'ADD' then
......@@ -807,6 +818,7 @@ begin
else
msg := 'Success: Customer Successfully Edited';
logger.Log(3, msg);
Result := TJSONObject.Create.AddPair('status', msg);
Result.AddPair('CustomerID', CustomerID);
......@@ -819,7 +831,10 @@ begin
end;
end
else
begin
Result := TJSONObject.Create.AddPair('status', 'Failure: Company Account Name Must Be Unique');
logger.Log(3, 'Failure: Company Account Name Must Be Unique');
end;
end;
function TLookupService.GenerateOrderCorrugatedPDF(orderID: string): string;
......@@ -838,7 +853,7 @@ begin
Result := rptOrderCorrugated.PrepareReport(SQL);
// Optionally log success
Logger.Log(5, 'PDF Report successfully generated for order ID: ' + orderID);
Logger.Log(3, 'PDF Report successfully generated for order ID: ' + orderID);
except
on E: Exception do
begin
......@@ -868,11 +883,11 @@ begin
Result := rptOrderWeb.PrepareReport(SQL);
// Optionally log success
Logger.Log(5, 'PDF Report successfully generated for order ID: ' + orderID);
Logger.Log(3, 'PDF Report successfully generated for order ID: ' + orderID);
except
on E: Exception do
begin
Logger.Log(2, 'Error generating web PDF: ' + E.Message);
Logger.Log(1, 'Error generating web PDF: ' + E.Message);
raise EXDataHttpException.Create(500, 'Error generating web PDF: A KG Orders database issue has occurred!');
end;
end;
......@@ -897,11 +912,11 @@ begin
Result := rptOrderCutting.PrepareReport(SQL);
// Optionally log success
Logger.Log(5, 'PDF Report successfully generated for order ID: ' + orderID);
Logger.Log(3, 'PDF Report successfully generated for order ID: ' + orderID);
except
on E: Exception do
begin
Logger.Log(2, 'Error generating cutting die PDF: ' + E.Message);
Logger.Log(1, 'Error generating cutting die PDF: ' + E.Message);
raise EXDataHttpException.Create(500, 'Error generating cutting die PDF: A KG Orders database issue has occurred!');
end;
end;
......@@ -951,47 +966,61 @@ begin
end;
function TLookupService.createStatusSearchInfo(params: TStringList; statusNum: string): TStatusSearchInfo;
// Takes all the status info recieved from the client and puts it into an object
// for convinence and to make it easier to expand. Returns said object.
// params: string list recieved from the client with all the search params
// statusNum: which status number we are on to make it easier to tell what info
// we want to take from client. I.E. differentiate between startDate1 and
// startDate2
// Takes all the status info received from the client and puts it into an object
// for convenience and to make it easier to expand. Returns said object.
var
statusType: string;
info: TStatusSearchInfo;
filterValue: string;
parts: TArray<string>;
begin
result := TStatusSearchInfo.Create;
result.startDate := params.Values['startDate' + statusNum];
result.endDate := params.Values['endDate' + statusNum];
info := TStatusSearchInfo.Create;
logger.log(3, 'TLookupService.createStatusSearchInfo');
try
info.startDate := params.Values['startDate' + statusNum];
info.endDate := params.Values['endDate' + statusNum];
if params.Values['null' + statusNum] <> '' then
result.null := StrToBool(params.Values['null' + statusNum]);
info.null := StrToBool(params.Values['null' + statusNum]);
info.statusType := '';
info.filterType := '';
info.statusSuffix := '';
result.statusType := '';
result.filterType := '';
result.statusSuffix := '';
if ( ( params.Values['filterType' + statusNum] <> '' ) and ( params.Values['filterType' + statusNum] <> 'NONE' ) ) then
filterValue := params.Values['filterType' + statusNum];
if (filterValue <> '') and (filterValue <> 'NONE') then
begin
result.statusType := params.Values['filterType' + statusNum].Split([' '])[0];
result.statusSuffix := params.Values['filterType' + statusNum].Split([' '])[1];
result.filterType := result.statusType + '_' + result.statusSuffix;
parts := filterValue.Split([' ']);
if Length(parts) > 0 then
info.statusType := parts[0];
if Length(parts) > 1 then
info.statusSuffix := parts[1];
if (info.statusType <> '') and (info.statusSuffix <> '') then
info.filterType := info.statusType + '_' + info.statusSuffix;
end;
// Figure out what table the status belongs to
if result.statusSuffix = 'DUE' then
if info.statusSuffix = 'DUE' then
begin
result.statusTableShort := 'oss';
result.statusTableLong := 'orders_status_schedule';
result.altStatusTableShort := 'os';
result.altStatusTableLong := 'orders_status';
info.statusTableShort := 'oss';
info.statusTableLong := 'orders_status_schedule';
info.altStatusTableShort := 'os';
info.altStatusTableLong := 'orders_status';
end
else
begin
result.statusTableShort := 'os';
result.statusTableLong := 'orders_status';
result.altStatusTableShort := 'oss';
result.altStatusTableLong := 'orders_status_schedule';
info.statusTableShort := 'os';
info.statusTableLong := 'orders_status';
info.altStatusTableShort := 'oss';
info.altStatusTableLong := 'orders_status_schedule';
end;
Result := info; // hand ownership to the caller
logger.Log(3, 'StatusSearchInfo generated successfully');
except
info.Free; // avoid leak if anything above raises
raise;
end;
end;
function TLookupService.generateStatusWhereSQL(status: TStatusSearchInfo): string;
......@@ -1039,19 +1068,23 @@ function TLookupService.generateOrdersSQL(searchOptions: string): TSQLQuery;
// searchOptions: search information sent form client to be parsed.
var
params: TStringList;
PageNum, PageSize: integer;
OrderBy, offset, limit, direction: string;
SQL, whereSQL, orderBySQL: string;
PageNum, PageSize: Integer;
OrderBy, offset, limit: string;
SQL, whereSQL: string;
OrderID, CompanyID, JobName, orderType: string;
status1, status2: TStatusSearchInfo;
ForPDF: Boolean;
accessRights, userID: string;
q: TSQLQuery;
begin
result := TSQLQuery.Create;
q := TSQLQuery.Create;
params := TStringList.Create;
status1 := nil;
status2 := nil;
logger.log(3, 'TLookupService.generatingOrdersSQL');
try
params.StrictDelimiter := true;
try
params.StrictDelimiter := True;
params.Delimiter := '&';
params.DelimitedText := searchOptions;
......@@ -1066,17 +1099,18 @@ begin
end;
OrderBy := params.Values['orderby'] + ' ' + params.Values['direction'];
orderType := params.Values['orderType'].ToLower();
orderType := params.Values['orderType'].ToLower;
OrderID := params.Values['orderID'];
companyID := params.Values['companyID'];
jobName := params.Values['jobName'];
CompanyID := params.Values['companyID'];
JobName := params.Values['jobName'];
accessRights := params.Values['accessRights'];
userID := params.Values['userID'];
status1 := createStatusSearchInfo(params, '1');
status2 := createStatusSearchInfo(params, '2');
SQL := 'SELECT o.ORDER_ID, c.SHORT_NAME, o.LOCATION AS Loc, c.NAME AS COMPANY_NAME, o.JOB_NAME, o.ORDER_TYPE, o.IN_QB, o.QB_ORDER_NUM,' +
SQL := 'SELECT o.ORDER_ID, c.SHORT_NAME, o.LOCATION AS Loc, c.NAME AS COMPANY_NAME, ' +
'o.JOB_NAME, o.ORDER_TYPE, o.IN_QB, o.QB_ORDER_NUM,' +
generateSubquery('PROOF') +
generateSubquery('ART') +
generateSubquery('PLATE') +
......@@ -1093,27 +1127,24 @@ begin
whereSQL := whereSQL + generateStatusWhereSQL(status1);
if (status2.filterType <> '') and (status2.filterType <> 'NONE') then
whereSQL := whereSQL + generateStatusWhereSQL(status2);
if (orderType <> '') and (orderType <> 'any') then
begin
if (orderType <> 'cutting die') then
if orderType <> 'cutting die' then
whereSQL := whereSQL + ' AND o.ORDER_TYPE = ' + QuotedStr(orderType + '_plate')
else
whereSQL := whereSQL + ' AND o.ORDER_TYPE = ' + QuotedStr('cutting_die');
end;
if OrderID <> '' then
whereSQL := whereSQL + ' AND o.ORDER_ID = ' + OrderID;
if companyID <> '' then
whereSQL := whereSQL + ' AND c.CUSTOMER_ID = ' + companyID;
if jobName <> '' then
whereSQL := whereSQL + ' AND o.JOB_NAME LIKE ' + QuotedStr('%' + jobName + '%');
if CompanyID <> '' then
whereSQL := whereSQL + ' AND c.CUSTOMER_ID = ' + CompanyID;
if JobName <> '' then
whereSQL := whereSQL + ' AND o.JOB_NAME LIKE ' + QuotedStr('%' + JobName + '%');
if accessRights = 'SALES' then
begin
whereSQL := whereSQL + ' AND c.REP_USER_ID = ' + userID;
end;
orderBySQL := ' ORDER BY ' + OrderBy;
SQL := SQL + ' o.PRICE, qb.QB_REF_NUM, ' +
'COALESCE(cpo.staff_fields_po_number, wpo.staff_fields_po_number, cdo.staff_fields_po_number) AS po_number, ' +
......@@ -1121,13 +1152,22 @@ begin
'COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date) AS ORDER_DATE ';
if not ForPDF then
SQL := SQL + whereSQL + orderBySQL + ' LIMIT ' + limit + ' OFFSET ' + offset
SQL := SQL + whereSQL + ' ORDER BY ' + OrderBy + ' LIMIT ' + limit + ' OFFSET ' + offset
else
SQL := SQL + whereSQL + orderBySQL;
SQL := SQL + whereSQL + ' ORDER BY ' + OrderBy;
q.SQL := SQL;
q.whereSQL := whereSQL;
result.SQL := SQL;
result.whereSQL := whereSQL;
Result := q; // hand ownership of q to the caller
logger.Log(4, 'Successfully generated orders SQL');
except
q.Free; // only if we never handed it to the caller
raise;
end;
finally
status1.Free;
status2.Free;
params.Free;
end;
end;
......@@ -1241,11 +1281,11 @@ begin
doQuery(ordersDB.UniQuery1, SQL);
Result.count := ordersDB.UniQuery1.FieldByName('total_count').AsInteger;
ordersDB.UniQuery1.Close;
logger.Log(4, 'Orders successfully retrieved');
except
on E: Exception do
begin
Logger.Log(2, 'Error in GetOrders: ' + E.Message);
Logger.Log(1, 'Error in GetOrders: ' + E.Message);
raise EXDataHttpException.Create(500, 'Unable to retrieve order list: A KG Orders database issue has occurred!');
end;
end;
......@@ -1256,10 +1296,8 @@ function TLookupService.GetCorrugatedOrder(orderInfo: string): TCorrugatedOrder;
// Gets on singular order from the database for the order entry page.
// orderInfo: the ORDER_ID.
var
orderType: string;
orderID: string;
SQL: string;
table: string;
begin
logger.Log(3,'TLookupService.GetCorrugatedOrder');
orderID := orderInfo;
......@@ -1354,6 +1392,7 @@ begin
result.general_special_instructions := ordersDB.UniQuery1.FieldByName('general_special_instructions').AsString;
ordersDB.UniQuery1.Close;
logger.Log(4, 'Corrugated order successfully retrieved');
except
on E: Exception do
begin
......@@ -1366,7 +1405,6 @@ end;
function TLookupService.GetWebOrder(orderInfo: string): TWebOrder;
var
orderType: string;
orderID: string;
SQL: string;
begin
......@@ -1481,6 +1519,7 @@ begin
result.general_comments := ordersDB.UniQuery1.FieldByName('general_comments').AsString;
ordersDB.UniQuery1.Close;
logger.Log(4, 'Web plate order successfully retrieved');
except
on E: Exception do
begin
......@@ -1493,7 +1532,6 @@ end;
function TLookupService.GetCuttingDieOrder(orderInfo: string): TCuttingDie;
var
orderType: string;
orderID: string;
SQL: string;
begin
......@@ -1530,10 +1568,12 @@ begin
ordersDB.UniQuery1.Close;
logger.Log(4, 'Cutting Die order successfully retrieved');
except
on E: Exception do
begin
logger.Log(2, 'An Error has occurred in TLookupSerivceImpl.GetCuttingDieOrder: ' + E.Message);
logger.Log(1, 'An Error has occurred in TLookupSerivceImpl.GetCuttingDieOrder: ' + E.Message);
raise EXDataHttpException.Create(500, 'Could not retrieve cutting die order: A KG Orders database issue has occurred!');
end;
end;
......@@ -1601,6 +1641,8 @@ begin
doQuery(ordersDB.UniQuery1, SQL);
Result.count := ordersDB.UniQuery1.FieldByName('total_count').AsInteger;
ordersDB.UniQuery1.Close;
logger.Log(4, 'Items list successfully retrieved');
except
on E: Exception do
begin
......@@ -1671,6 +1713,7 @@ begin
ordersDB.UniQuery1.Open;
Result.count := ordersDB.UniQuery1.FieldByName('total_count').AsInteger;
ordersDB.UniQuery1.Close;
logger.Log(4, 'Users list successfully retrieved');
except
on E: Exception do
begin
......@@ -1741,7 +1784,6 @@ begin
ordersDB.UniQuery1.FieldByName('STATUS').AsString := 'INACTIVE'
end;
if not email.IsEmpty then
ordersDB.UniQuery1.FieldByName('EMAIL').AsString := email;
if not access.IsEmpty then
......@@ -1753,7 +1795,6 @@ begin
if not perspective.IsEmpty then
ordersDB.UniQuery1.FieldByName('PERSPECTIVE_ID').AsString := perspective;
if not QB.IsEmpty then
ordersDB.UniQuery1.FieldByName('QB_ID').AsString := QB;
if((not (Password = 'hidden')) and (not (Password.IsEmpty))) then
......@@ -1765,6 +1806,7 @@ begin
ordersDB.UniQuery1.Post;
Result := 'Success: User Successfully Edited';
logger.Log(4, 'User Successfully Edited');
end;
ordersDB.UniQuery1.Close;
finally
......@@ -1776,6 +1818,7 @@ procedure TLookupService.AddToOrdersTable(mode, ORDER_TYPE: string; JSONData: TJ
var
SQL: string;
begin
logger.Log(3, 'TLookupService.AddToOrdersTable');
if mode = 'ADD' then
begin
SQL := 'select * from orders where ORDER_ID = 0 and ORDER_ID <> 0';
......@@ -1807,6 +1850,7 @@ begin
ordersDB.UniQuery1.Post;
ordersDB.UniQuery1.Close;
logger.log(4, 'Order successfully added to orders table');
end;
function TLookupService.AddCorrugatedOrder(orderInfo: string): TJSONObject;
......@@ -1895,6 +1939,7 @@ begin
else
msg := 'Success: Order Successfully Edited';
logger.Log(4, msg);
Result := JSONData;
Result.AddPair('status', msg);
Result.AddPair('ORDER_ID', ORDER_ID);
......@@ -1916,7 +1961,6 @@ function TLookupService.AddStatusSchedule(StatusType: string; order: TJSONObject
// ORDER_ID: order id sent from client if we are in edit mode empty if in add mode
var
SQL: string;
mode: string;
change: boolean;
date: string;
begin
......@@ -1955,6 +1999,7 @@ begin
ordersDB.uqOrdersStatusSchedule.Post;
logger.Log(4, 'Status schedule succesfully added');
Result := 'success';
end;
......@@ -1967,17 +2012,15 @@ var
Status: string;
UserID: string;
SQL: string;
NextStatus: string;
StatusField: string;
table: string;
OrderType: string;
order: TJSONObject;
begin
try
logger.Log(3, 'TLookupService.SetStatus');
StatusInfo := TJSONObject.ParseJSONValue(statusOptions) as TJSONObject;
params := TStringList.Create;
try
try
params.Delimiter := '&';
params.StrictDelimiter := true;
params.DelimitedText := statusOptions;
......@@ -1992,6 +2035,8 @@ begin
SQL := 'select * from orders_status where ORDER_ID = ' + IntToStr(ORDER_ID) + ' AND ' +
'ORDER_STATUS = ' + quotedStr(Status);
logger.log(5, 'Retrieving order status with SQL: ' + SQL);
doQuery(ordersDB.UniQuery1, SQL);
if ordersDB.UniQuery1.IsEmpty then
......@@ -2015,6 +2060,7 @@ begin
end;
ordersDB.UniQuery1.Post;
logger.Log(4, 'Order Status successfully posted to database');
if StatusInfo.GetValue<string>('staff_fields_ship_date') <> '12/30/1899' then
AddStatusSchedule('SHIP', StatusInfo, ORDER_ID);
......@@ -2040,6 +2086,7 @@ begin
SQL := 'select * from ' + table + ' where ORDER_ID = ' + IntToStr(ORDER_ID);
doQuery(OrdersDB.UniQuery1, SQL);
logger.Log(4, 'Updating Orders status as well with SQL: ' + SQL);
OrdersDB.UniQuery1.Edit;
if StatusInfo.GetValue<string>('staff_fields_ship_date') <> '12/30/1899' then
......@@ -2051,7 +2098,7 @@ begin
if StatusInfo.GetValue<string>('staff_fields_mount_due') <> '12/30/1899' then
OrdersDB.UniQuery1.FieldByName('staff_fields_mount_due').AsString := StatusInfo.GetValue<string>('staff_fields_mount_due');
OrdersDB.UniQuery1.Post;
logger.Log(4, 'Order status successfully set');
finally
order.Free;
end;
......@@ -2082,7 +2129,6 @@ var
perspective: string;
QB: string;
SQL: string;
dateCreated: TDateTime;
rightsInt: Integer;
params: TStringList;
begin
......@@ -2094,8 +2140,6 @@ begin
params.Delimiter := '&';
params.DelimitedText := userInfo;
dateCreated := Now;
user := params.Values['username'];
password := params.Values['password'];
full_name := params.Values['fullname'];
......@@ -2139,6 +2183,8 @@ begin
end
else
Result := 'Failure: Username already taken';
logger.Log(4, Result);
except
on E: Exception do
begin
......@@ -2218,9 +2264,11 @@ begin
ordersDB.UniQuery1.Post;
Result.AddPair('msg', 'Success: Item successfully edited');
end;
end
else
result.AddPair('msg', 'Failure: Item does not exist');
logger.Log(4, result.GetValue('msg').Value);
end;
except
on E: Exception do
......@@ -2260,12 +2308,11 @@ function TLookupService.AddWebOrder(orderInfo: string): TJSONObject;
// and orders_status_schedule. This also functions as an edit function.
// orderInfo - all the inputted order information from client side.
var
JSONData, ResponseData: TJSONObject;
JSONData: TJSONObject;
SQL: string;
Pair: TJSONPair;
Field: TField;
DateFormat: TFormatSettings;
CurrDate: TDateTime;
ORDER_ID: integer;
mode: string;
msg: string;
......@@ -2340,6 +2387,7 @@ begin
msg := 'Success: Order Successfully Added'
else
msg := 'Success: Order Successfully Edited';
logger.Log(4, msg);
Result := JSONData;
Result.AddPair('status', msg);
......@@ -2357,17 +2405,14 @@ end;
function TLookupService.AddCuttingDieOrder(orderInfo: string): TJSONObject;
var
JSONData, ResponseData: TJSONObject;
JSONData: TJSONObject;
SQL: string;
Pair: TJSONPair;
Field: TField;
DateFormat: TFormatSettings;
CurrDate: TDateTime;
ORDER_ID: integer;
mode: string;
msg: string;
temp: string;
temp2: boolean;
begin
logger.Log(3, 'TLookupService.AddCuttingDieOrder');
DateFormat := TFormatSettings.Create;
......@@ -2437,6 +2482,7 @@ begin
msg := 'Success: Order Successfully Added'
else
msg := 'Success: Order Successfully Edited';
logger.Log(4, msg);
Result := JSONData;
Result.AddPair('status', msg);
......@@ -2456,7 +2502,6 @@ function TLookupService.delOrder(OrderID, orderType, UserID: string): TJSONObjec
var
table, table2, SQL: string;
stream: TStringStream;
DateFormat: TFormatSettings;
JSONValue: TJSONValue;
JSONObject, DataObject, JSONData: TJSONObject;
JSONArray: TJSONArray;
......@@ -2500,6 +2545,8 @@ begin
SQL := 'SELECT * FROM ' + table + ' WHERE ORDER_ID = ' + IntToStr(OrderIDInt);
doQuery(OrdersDB.UniQuery1, SQL);
//convert the order into a JSON object to put it in the database using existing code
logger.Log(4, 'Adding order into the revisions table before deleting...');
stream := TStringStream.Create('', TEncoding.UTF8);
try
OrdersDB.UniQuery1.SaveToJSON(stream);
......@@ -2552,7 +2599,7 @@ begin
OrdersDB.UniQuery1.FieldByName('ORDER_REVISION_ID').AsInteger := RevisionID;
OrdersDB.UniQuery1.FieldByName('REVISION_USER_ID').AsString := UserID;
OrdersDB.UniQuery1.Post;
logger.Log(4, 'Order successfully added into revision table, beginning deletion');
finally
stream.Free;
JSONValue.Free;
......@@ -2572,7 +2619,7 @@ begin
Result.AddPair('status', 'success');
Result.AddPair('OrderID', IntToStr(OrderIDInt));
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
logger.log(4, 'order successfully deleted');
except
on E: Exception do
begin
......@@ -2585,7 +2632,7 @@ end;
procedure TLookupService.AddToRevisionsTable(OrderID: string; table: string; order: TJSONObject);
var
SQL, UserID: string;
SQL: string;
Pair: TJSONPair;
rev_num, RevisionID: integer;
Field: TField;
......@@ -2792,8 +2839,6 @@ var
jsValue: TJSONValue;
jsObj: TJSONObject;
ItemList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedItem, Item: TJSONObject;
I: integer;
AccessToken, RefreshToken, CompanyID, Client, Secret, SQL, desc: string;
......@@ -2883,28 +2928,17 @@ begin
end;
end;
procedure TLookupService.AddAddrBlock(prefix: string; AddrJSON: TJSONObject);
// the point of this function would be to save space in import QB Customer
begin
//TODO
end;
function TLookupService.RefreshAccessToken: string;
// Refresh Token changes so make sure to save refresh token.
var
IdHTTP: TIdHTTP;
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
RequestStream: TStringStream;
EncodedAuth, EncodedAuth2, PostData, response: string;
f: TStringList;
fi: string;
EncodedAuth, PostData, response: string;
JSObj: TJSONObject;
iniFile: TIniFile;
Encoder: TBase64Encoding;
AccessToken,RefreshToken,CompanyID,Client,Secret: string;
LastRefresh: TDateTime;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
Client := iniFile.ReadString('Quickbooks', 'ClientID', '');
......@@ -2975,8 +3009,6 @@ end;
procedure TLookupService.SaveTokens(AccessToken, RefreshToken: string);
var
f: TStringList;
iniStr, line: string;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
......@@ -2989,12 +3021,6 @@ begin
finally
IniFile.Free;
end;
f := TStringList.Create;
// Save to file (overwrites existing file)
f.SaveToFile('QB.txt');
f.Free;
end;
function TLookupService.ImportQBCustomer(CustomerInfo: string): TJSONObject;
......@@ -3006,10 +3032,8 @@ var
DateFormat: TFormatSettings;
CustomerID: Integer;
mode: string;
temp: string;
msg: string;
QB_LIST_ID: string;
unique: Boolean;
begin
logger.Log(3, 'TLookupService.ImportQBCustomer');
DateFormat := TFormatSettings.Create;
......@@ -3023,8 +3047,6 @@ begin
mode := JSONData.GetValue<string>('mode');
QB_LIST_ID := JSONData.GetValue<string>('QB_LIST_ID');
if mode = 'ADD' then
begin
// Update RevisionID
SQL := 'UPDATE idfield SET KEYVALUE = KEYVALUE + 1 WHERE KEYNAME = ' + QuotedStr('GEN_CUSTOMER_ID');
OrdersDB.UniQuery1.SQL.Text := SQL;
......@@ -3034,7 +3056,6 @@ begin
SQL := 'SELECT KEYVALUE FROM idfield WHERE KEYNAME = ' + QuotedStr('GEN_CUSTOMER_ID');
doQuery(OrdersDB.UniQuery1, SQL);
CustomerID := OrdersDB.UniQuery1.FieldByName('KEYVALUE').AsInteger;
end;
SQL := 'SELECT * FROM customers WHERE QB_LIST_ID = ' + QuotedStr(QB_LIST_ID);
doQuery(OrdersDB.UniQuery1, SQL);
......
......@@ -127,15 +127,15 @@ begin
Logger.Log(1, '--- Settings ---');
iniStr := iniFile.ReadString( 'Settings', 'MemoLogLevel', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Settings->memoLogLevel: Entry not found - default: 3' )
Logger.Log( 1, '--Settings->MemoLogLevel: Entry not found - default: 3' )
else
Logger.Log( 1, '--Settings->memoLogLevel: ' + iniStr );
Logger.Log( 1, '--Settings->MemoLogLevel: ' + iniStr );
iniStr := iniFile.ReadString( 'Settings', 'FileLogLevel', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Settings->fileLogLevel: Entry not found - default: 4' )
Logger.Log( 1, '--Settings->FileLogLevel: Entry not found - default: 4' )
else
Logger.Log( 1, '--Settings->fileLogLevel: ' + iniStr );
Logger.Log( 1, '--Settings->FileLogLevel: ' + iniStr );
Logger.Log( 1, '' );
iniStr := iniFile.ReadString( 'Settings', 'LogFileNum', '' );
......@@ -144,6 +144,12 @@ begin
else
Logger.Log( 1, '--Settings->LogFileNum: ' + IntToStr(StrToInt(iniStr) - 1) );
iniStr := iniFile.ReadString( 'Settings', 'WebClientVersion', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Settings->WebClientVersion: Entry not found - ERROR: ini entry required!!!')
else
Logger.Log( 1, '--Settings->WebClientVersion: ' + iniStr );
Logger.Log(1, '--- Database ---');
iniStr := IniFile.ReadString( 'Database', 'Server', '' );
if iniStr.IsEmpty then
......@@ -180,37 +186,37 @@ begin
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->CompanyID: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->CompanyID: ' + 'Entry found' );
Logger.Log( 1, '--Quickbooks->CompanyID: Entry found' );
iniStr := IniFile.ReadString( 'Quickbooks', 'ClientID', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->ClientID: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->ClientID: ' + 'Entry found' );
Logger.Log( 1, '--Quickbooks->ClientID: Entry found' );
iniStr := IniFile.ReadString( 'Quickbooks', 'ClientSecret', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->ClientSecret: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->ClientSecret: ' + 'Entry found' );
Logger.Log( 1, '--Quickbooks->ClientSecret: Entry found' );
iniStr := IniFile.ReadString( 'Quickbooks', 'RefreshToken', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->RefreshToken: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->RefreshToken: ' + 'Entry found' );
Logger.Log( 1, '--Quickbooks->RefreshToken: Entry found' );
iniStr := IniFile.ReadString( 'Quickbooks', 'AccessToken', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->AccessToken: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->AccessToken: ' + 'Entry found' );
Logger.Log( 1, '--Quickbooks->AccessToken: Entry found' );
iniStr := IniFile.ReadString( 'Quickbooks', 'LastRefresh', '' );
if iniStr.IsEmpty then
Logger.Log( 1, '--Quickbooks->LastRefresh: Entry not found' )
else
Logger.Log( 1, '--Quickbooks->LastRefresh: ' + iniStr );
Logger.Log( 1, '--Quickbooks->LastRefresh: Entry Found' );
Logger.Log( 1, '' );
finally
......
unit QBService;
interface
uses
XData.Service.Common,
Aurelius.Mapping.Attributes,
System.JSON,
System.Generics.Collections,
System.Classes;
type
[ServiceContract]
IQBService = interface(IInvokable)
['{D119A273-0644-484B-B75E-B6FE57BB422C}']
[HttpGet] function getCustomers(): TJSONArray;
end;
implementation
initialization
RegisterServiceType(TypeInfo(IQBService));
end.
unit QBServiceImplementation;
interface
uses
XData.Server.Module,
XData.Service.Common,
Api.Database, Data.DB, frxClass, frxExportPDF, JS, System.Hash, System.JSON,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, MemDS, DBAccess, Uni,
hyiedefs, hyieutils, iexBitmaps, iesettings, iexLayers, iexRulers,
iexToolbars, iexUserInteractions, imageenio, imageenproc, QuickRpt, QRCtrls,
dbimageen, Vcl.ExtCtrls, ieview, imageenview, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP,
iexProcEffects, frCoreClasses, Common.Logging,
DateUtils, QBService, WEBLib.REST, WEBLib.WebTools,System.Net.HttpClient,
System.Net.URLClient, System.Net.HttpClientComponent, System.netencoding,
IdHTTP, IdSSLOpenSSL, IdSSLOpenSSLHeaders, System.IniFiles, REST.Client, REST.Types;
type
[ServiceImplementation]
TQBService = class(TInterfacedObject, IQBService)
private
procedure SaveTokens(AccessToken, RefreshToken: string);
function getCustomers(): TJSONArray;
function refreshAccessToken(): string;
var
AccessToken,RefreshToken,CompanyID,Client,Secret: string;
LastRefresh: TDateTime;
end;
implementation
function TQBService.getCustomers: TJSONArray;
var
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
Customer: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
begin
restClient := TRESTClient.Create(nil);
restClient.BaseURL := 'https://sandbox-quickbooks.api.intuit.com';
restRequest := TRESTRequest.Create(nil);
restRequest.Client := restClient;
restResponse := TRESTResponse.Create(nil);
restRequest.Response := restResponse;
if MinutesBetween(Now, LastRefresh) > 58 then
begin
RefreshAccessToken();
end;
restRequest.Method := rmGET;
//GET /v3/company/<realmId>/customer/<customerId>
res := '/v3/company/' + companyid + '/customer/58';
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);
CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
result := CustomerList;
// LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
function TQBService.RefreshAccessToken: string;
// Refresh Token changes so make sure to save refresh token.
var
IdHTTP: TIdHTTP;
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
RequestStream: TStringStream;
EncodedAuth, EncodedAuth2, PostData, response: string;
f: TStringList;
fi: string;
JSObj: TJSONObject;
Encoder: TBase64Encoding;
begin
// 1. Encode credentials (same as working Postman request)
// TNetEncoding.Base64.Encode adds a new line every 72 chars, this stops that
Encoder := TBase64Encoding.Create(0);
if( (Client = '') or (Secret = '') ) then
begin
Exit();
end;
EncodedAuth := Encoder.Encode(Client + ':' + Secret);
if RefreshToken = '' then
begin
Exit();
end;
// 2. Prepare POST data (EXACTLY as in Postman)
PostData := 'grant_type=refresh_token&refresh_token=' + RefreshToken;
// 3. Configure HTTP client
IdHTTP := TIdHTTP.Create(nil);
SSLIO := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
// Force TLS 1.2
SSLIO.SSLOptions.Method := sslvTLSv1_2;
SSLIO.SSLOptions.SSLVersions := [sslvTLSv1_2];
IdHTTP.IOHandler := SSLIO;
// Set headers
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
IdHTTP.Request.Accept := 'application/json';
IdHTTP.Request.CustomHeaders.AddValue('Authorization', 'Basic ' + EncodedAuth);
// 4. Create and send request
RequestStream := TStringStream.Create(PostData, TEncoding.UTF8);
try
// Execute POST
try
response := IdHTTP.Post('https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer', RequestStream);
JSObj := TJSONObject.ParseJSONValue(response) as TJSONObject;
RefreshToken := JSObj.GetValue('refresh_token').ToString.Trim(['"']);
AccessToken := JSObj.GetValue('access_token').ToString.Trim(['"']);
SaveTokens(AccessToken, RefreshToken);
Result := AccessToken;
except
on E: EIdHTTPProtocolException do
// Memo2.Lines.Add('Error: ' + E.Message + #13#10 + 'Response: ' + E.ErrorMessage);
end;
finally
RequestStream.Free;
end;
finally
SSLIO.Free;
IdHTTP.Free;
end;
end;
procedure TQBService.SaveTokens(AccessToken, RefreshToken: string);
var
f: TStringList;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
try
iniFile.WriteString('Quickbooks', 'RefreshToken', RefreshToken);
LastRefresh := Now;
finally
IniFile.Free;
end;
f := TStringList.Create;
// Save to file (overwrites existing file)
f.SaveToFile('QB.txt');
f.Free;
end;
initialization
RegisterServiceType(TQBService);
end.
......@@ -12,7 +12,7 @@ uses
WEBLib.ExtCtrls, WEBLib.REST, WEBLib.WebTools,System.Net.HttpClient,
System.Net.URLClient, System.Net.HttpClientComponent, System.netencoding,
IdHTTP, IdSSLOpenSSL, IdSSLOpenSSLHeaders, System.DateUtils, System.IniFiles,
AdvPanel, AdvOfficePager;
AdvPanel, AdvOfficePager, System.UITypes;
type
......@@ -156,7 +156,6 @@ type
{ Private declarations }
strict private
ordersDB: TApiDatabase;
httpReqTokenRefresh: TWebHttpRequest;
var
AccessToken,RefreshToken,CompanyID,Client,Secret: string;
......@@ -214,8 +213,6 @@ begin
end;
procedure TfQB.asgDataClickCell(Sender: TObject; ARow, ACol: Integer);
var
point, origin: TPoint;
begin
QB_ID := asgData.Cells[1, asgData.Row];
end;
......@@ -278,12 +275,8 @@ var
jsValue: TJSONValue;
jsObj: TJSONObject;
ItemList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Item: TJSONObject;
Item: TJSONObject;
I: integer;
BillAddr: TJSONObject;
ShipAddr: TJSONObject;
sql: string;
begin
Memo1.Clear;
......@@ -304,8 +297,7 @@ begin
end;
restRequest.Method := rmGET;
//res := '/v3/company/' + companyID + '/preferences';
res := '/v3/company/' + companyID + '/query?query=select * from Item&minorversion=75'; // '/customer/58';
res := '/v3/company/' + companyID + '/query?query=select * from Item&minorversion=75';
restRequest.Resource := res;
......@@ -317,12 +309,9 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//CustomerList := TJSONArray(restResponse.JSONValue);
Memo1.Lines.Add( jsObj.Format(2) );
ItemList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Item'));
......@@ -343,10 +332,7 @@ begin
end;
Memo1.lines.add('Done');
// Load customer info
restClient.Free;
restRequest.Free;
......@@ -416,10 +402,6 @@ end;
procedure TfQB.DeleteCustomers();
var
SQL: string;
count: integer;
ModifiedList: TJSONArray;
Customer, ParsedCustomer: TJSONObject;
I: integer;
ship_count, cust_count: integer;
begin
Memo1.Clear;
......@@ -472,10 +454,8 @@ end;
procedure TfQB.getCustomers();
var
SQL: string;
count: integer;
ModifiedList: TJSONArray;
Customer, ParsedCustomer: TJSONObject;
I: integer;
ParsedCustomer: TJSONObject;
begin
Memo1.Clear;
Memo1.Lines.Add('Retrieving KG Orders Customers');
......@@ -487,12 +467,7 @@ begin
begin
ParsedCustomer := TJSONObject.Create;
//sql := 'select CUSTOMER_ID from customers where QB_LIST_ID = ' + Customer.GetValue<string>('Id');
//doQuery(ordersDB.UniQuery1, SQL);
try
//ParsedCustomer.AddPair('In KGOrders', not(ordersDB.UniQuery1.IsEmpty));
ParsedCustomer.AddPair('Id', ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsString);
ParsedCustomer.AddPair('CompanyName', ordersDB.UniQuery1.FieldByName('NAME').AsString);
ParsedCustomer.AddPair('BillAddrCity', ordersDB.UniQuery1.FieldByName('BILL_CITY').AsString);
......@@ -517,8 +492,6 @@ end;
procedure TfQB.SaveTokens(AccessToken, RefreshToken: string);
var
f: TStringList;
iniStr, line: string;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
......@@ -544,10 +517,7 @@ var
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
Customer: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
begin
Memo1.Clear;
Memo1.Lines.Add('Retrieving QB Customer Based on ID');
......@@ -567,7 +537,6 @@ begin
end;
restRequest.Method := rmGET;
//GET /v3/company/<realmId>/customer/<customerId>
res := '/v3/company/' + companyid + '/customer/58';
restRequest.Resource := res;
......@@ -579,18 +548,12 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
Memo2.Clear;
Memo2.Lines.Add( jsObj.Format(2) );
// CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
// LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
restResponse.Free;
......@@ -615,34 +578,20 @@ var
res: string;
i: integer;
jsValue: TJSONValue;
Customer: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
estimateJSON: TJSONObject;
SQL: string;
estimate: TEstimate;
CustomerRef: TRef;
CustomerRefJSON: TJSONObject;
Lines: TArray<string>;
BillAddr: TAddress;
BillAddrJSON: TJSONObject;
CustomField:TJSONObject;
CustomFields: TJSONArray;
ShipAddr: TAddress;
ShipAddrJSON: TJSONObject;
Items: TArray<TLine>;
ItemRef: TRef;
SalesItemLineDetail: TSalesItemLineDetail;
LineArray: TJSONArray;
LineObj, DetailObj, ItemRefObj: TJSONObject;
TaxCodeRef: TJSONObject;
TxnTaxCodeRef: TJSONObject;
TxnTaxDetail: TJSONObject;
JSONData: TJSONObject;
ORDER_ID: string;
table: string;
ShipMethodRef: TJSONObject;
unitPrice: double;
begin
Memo1.Clear;
......@@ -657,13 +606,9 @@ begin
LineObj := TJSONObject.Create;
DetailObj := TJSONObject.Create;
ItemRefObj := TJSONObject.Create;
TaxCodeRef := TJSONObject.Create;
TxnTaxCodeRef := TJSONObject.Create;
TxnTaxDetail := TJSONObject.Create;
JSONData := TJSONObject.ParseJSONValue(orderInfo) as TJSONObject;
ORDER_ID := JSONData.GetValue<string>('ORDER_ID');
// add logic to figure out what type of order it is
SQL := 'select * from orders where ORDER_ID = ' + ORDER_ID;
doQuery(ordersDB.UniQuery1, SQL);
if ordersDB.UniQuery1.FieldByName('ORDER_TYPE').AsString = 'corrugated_plate' then
......@@ -685,10 +630,7 @@ begin
estimateJSON.AddPair('TxnDate', ordersDB.UniQuery1.FieldByName('staff_fields_order_date').AsString);
// Update the Quickbooks list ID in the database
// CustomerRef.value :=
CustomerRefJSON := TJSONObject.Create;
CustomerRefJSON.AddPair('value', ordersDB.UniQuery1.FieldByName('QB_LIST_ID').AsString);
//CustomerRef.value := '59'
;
estimateJSON.AddPair('CustomerRef', CustomerRefJSON);
......@@ -737,8 +679,6 @@ begin
estimateJSON.AddPair('ShipAddr', ShipAddrJSON);
// 🔹 Line object representing one line item
LineObj := TJSONObject.Create;
if ( table = 'corrugated_plate_orders') or (table = 'cutting_die_orders' ) then
begin
if ordersDB.UniQuery1.FieldByName('general_special_instructions').AsString <> '' then
......@@ -800,17 +740,10 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
Memo1.Lines.Add( jsObj.Format(2) );
//CustomerList := TJSONArray(restResponse.JSONValue);
// CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
// LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
......@@ -820,10 +753,8 @@ end;
procedure TfQB.Button5Click(Sender: TObject);
var
SQL: string;
count: integer;
ModifiedList: TJSONArray;
Customer, ParsedCustomer: TJSONObject;
I: integer;
ParsedCustomer: TJSONObject;
begin
Memo1.Clear;
Memo1.Lines.Add('Showing all KG Orders Customers without Orders');
......@@ -836,12 +767,7 @@ begin
while not ordersDB.UniQuery1.Eof do
begin
ParsedCustomer := TJSONObject.Create;
//sql := 'select CUSTOMER_ID from customers where QB_LIST_ID = ' + Customer.GetValue<string>('Id');
//doQuery(ordersDB.UniQuery1, SQL);
try
//ParsedCustomer.AddPair('In KGOrders', not(ordersDB.UniQuery1.IsEmpty));
ParsedCustomer.AddPair('Id', ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsString);
ParsedCustomer.AddPair('CompanyName', ordersDB.UniQuery1.FieldByName('NAME').AsString);
......@@ -874,13 +800,6 @@ var
jsValue: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Customer: TJSONObject;
I: integer;
BillAddr: TJSONObject;
ShipAddr: TJSONObject;
SQL: string;
begin
restClient := TRESTClient.Create(nil);
restClient.BaseURL := 'https://sandbox-quickbooks.api.intuit.com';
......@@ -898,11 +817,8 @@ begin
end;
restRequest.Method := rmGET;
//res := '/v3/company/' + companyID + '/preferences';
res := '/v3/company/' + companyID + '/query?query=select * from Customer&minorversion=75'; // '/customer/58';
res := '/v3/company/' + companyID + '/query?query=select * from Customer&minorversion=75';
restRequest.Resource := res;
///query?query=select * from Customer where CompanyName = ' + quotedStr('TYOGA CONTAINER') + '&minorversion=75';
param := restRequest.Params.AddItem;
param.Name := 'Authorization';
......@@ -912,21 +828,13 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//CustomerList := TJSONArray(restResponse.JSONValue);
CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
//LoadJSONArray( CustomerList );
findMatches(CustomerList, 'DisplayName', 'Name');
//findMatches(CustomerList, 'BillAddrLine1', 'BILL_ADDRESS');
//findMatches(CustomerList, 'BillAddrCity', 'BILL_CITY');
//findMatches(CustomerList, 'BillAddrState', 'BILL_STATE');
//findMatches(CustomerList, 'BillAddrZip', 'BILL_ZIP');
end;
......@@ -934,10 +842,8 @@ end;
procedure TfQB.Button7Click(Sender: TObject);
var
SQL: string;
count: integer;
ModifiedList: TJSONArray;
Customer, ParsedCustomer: TJSONObject;
I: integer;
ParsedCustomer: TJSONObject;
begin
SQL := 'SELECT * FROM customers c ' +
'WHERE NOT EXISTS (SELECT 1 FROM corrugated_plate_orders cpo WHERE cpo.COMPANY_ID = c.CUSTOMER_ID) '+
......@@ -949,12 +855,7 @@ begin
begin
ParsedCustomer := TJSONObject.Create;
//sql := 'select CUSTOMER_ID from customers where QB_LIST_ID = ' + Customer.GetValue<string>('Id');
//doQuery(ordersDB.UniQuery1, SQL);
try
//ParsedCustomer.AddPair('In KGOrders', not(ordersDB.UniQuery1.IsEmpty));
ParsedCustomer.AddPair('Id', ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsString);
ParsedCustomer.AddPair('CompanyName', ordersDB.UniQuery1.FieldByName('NAME').AsString);
ParsedCustomer.AddPair('BillAddrCity', ordersDB.UniQuery1.FieldByName('BILL_CITY').AsString);
......@@ -986,12 +887,6 @@ var
jsValue: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Customer: TJSONObject;
I: integer;
BillAddr: TJSONObject;
ShipAddr: TJSONObject;
ItemList: TJSONArray;
Item: TJSONObject;
begin
......@@ -1014,8 +909,7 @@ begin
end;
restRequest.Method := rmGET;
//res := '/v3/company/' + companyID + '/preferences';
res := '/v3/company/' + companyID + '/query?query=select * from Item&minorversion=75'; // '/customer/58';
res := '/v3/company/' + companyID + '/query?query=select * from Item&minorversion=75';
restRequest.Resource := res;
......@@ -1027,12 +921,9 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//CustomerList := TJSONArray(restResponse.JSONValue);
Memo2.Clear;
Memo2.Lines.Add( jsObj.Format(2) );
......@@ -1078,13 +969,6 @@ var
res: string;
jsValue: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Customer: TJSONObject;
I: integer;
BillAddr: TJSONObject;
ShipAddr: TJSONObject;
begin
Memo1.Clear;
Memo1.Lines.Add('Retrieving Estimate from QB');
......@@ -1104,7 +988,6 @@ begin
end;
restRequest.Method := rmGET;
//GET /v3/company/9341454243251288/query?query=<selectStatement>&minorversion=75
res := '/v3/company/' + companyID + '/query?query=select * from estimate where DocNumber = ' + quotedStr('1002') + '&minorversion=75';
restRequest.Resource := res;
......@@ -1140,7 +1023,6 @@ var
jsValue: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Customer: TJSONObject;
I: integer;
......@@ -1165,10 +1047,8 @@ begin
end;
restRequest.Method := rmGET;
//res := '/v3/company/' + companyID + '/preferences';
res := '/v3/company/' + companyID + '/query?query=select * from Customer&minorversion=75'; // '/customer/58';
res := '/v3/company/' + companyID + '/query?query=select * from Customer&minorversion=75';
restRequest.Resource := res;
///query?query=select * from Customer where CompanyName = ' + quotedStr('TYOGA CONTAINER') + '&minorversion=75';
param := restRequest.Params.AddItem;
......@@ -1179,12 +1059,9 @@ begin
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//CustomerList := TJSONArray(restResponse.JSONValue);
Memo2.Clear;
Memo2.Lines.Add( jsObj.Format(2) );
......@@ -1197,11 +1074,7 @@ begin
Customer := CustomerList.Items[I] as TJSONObject;
ParsedCustomer := TJSONObject.Create;
//sql := 'select CUSTOMER_ID from customers where QB_LIST_ID = ' + Customer.GetValue<string>('Id');
//doQuery(ordersDB.UniQuery1, SQL);
try
//ParsedCustomer.AddPair('In KGOrders', not(ordersDB.UniQuery1.IsEmpty));
ParsedCustomer.AddPair('Id', Customer.GetValue<string>('Id'));
ParsedCustomer.AddPair('CompanyName', Customer.GetValue<string>('DisplayName'));
......@@ -1228,18 +1101,18 @@ begin
// Handle Ship Address
if Customer.GetValue('ShipAddr') is TJSONObject then
begin
BillAddr := Customer.GetValue('ShipAddr') as TJSONObject;
ParsedCustomer.AddPair('ShipAddrLine1', TJSONString.Create(BillAddr.GetValue<string>('Line1', '')));
ParsedCustomer.AddPair('ShipAddrCity', TJSONString.Create(BillAddr.GetValue<string>('City', '')));
ParsedCustomer.AddPair('ShipAddrState', TJSONString.Create(BillAddr.GetValue<string>('CountrySubDivisionCode', '')));
ParsedCustomer.AddPair('ShipAddrZip', TJSONString.Create(BillAddr.GetValue<string>('PostalCode', '')));
ShipAddr := Customer.GetValue('ShipAddr') as TJSONObject;
ParsedCustomer.AddPair('ShipAddrLine1', TJSONString.Create(ShipAddr.GetValue<string>('Line1', '')));
ParsedCustomer.AddPair('ShipAddrCity', TJSONString.Create(ShipAddr.GetValue<string>('City', '')));
ParsedCustomer.AddPair('ShipAddrState', TJSONString.Create(ShipAddr.GetValue<string>('CountrySubDivisionCode', '')));
ParsedCustomer.AddPair('ShipAddrZip', TJSONString.Create(ShipAddr.GetValue<string>('PostalCode', '')));
ParsedCustomer.AddPair('ShipAddr',
TJSONString.Create(
Customer.GetValue<string>('DisplayName') + sLineBreak +
BillAddr.GetValue('Line1', '') + ',' + sLineBreak +
BillAddr.GetValue('City', '') + ', ' +
BillAddr.GetValue('CountrySubDivisionCode', '') + ' ' +
BillAddr.GetValue('PostalCode', '')
ShipAddr.GetValue('Line1', '') + ',' + sLineBreak +
ShipAddr.GetValue('City', '') + ', ' +
ShipAddr.GetValue('CountrySubDivisionCode', '') + ' ' +
ShipAddr.GetValue('PostalCode', '')
)
);
end;
......@@ -1308,11 +1181,8 @@ var
IdHTTP: TIdHTTP;
SSLIO: TIdSSLIOHandlerSocketOpenSSL;
RequestStream: TStringStream;
EncodedAuth, EncodedAuth2, PostData, response: string;
f: TStringList;
fi: string;
EncodedAuth, PostData, response: string;
JSObj: TJSONObject;
iniFile: TIniFile;
Encoder: TBase64Encoding;
begin
// 1. Encode credentials (same as working Postman request)
......@@ -1381,8 +1251,6 @@ var
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
jsObj, companyInfo: TJSONObject;
begin
restClient := TRESTClient.Create(nil);
restClient.BaseURL := 'https://sandbox-quickbooks.api.intuit.com';
......@@ -1411,9 +1279,6 @@ begin
restRequest.Execute;
memo1.Lines.Add(restresponse.Content) ;
//jsValue := restResponse.JSONValue;
//jsObj := TJSONObject.ParseJSONValue(restresponse.Content) as TJSONObject;
//companyInfo := TJSONObject(jsObj.GetValue('CompanyInfo'));
restClient.Free;
restRequest.Free;
......
......@@ -5,7 +5,7 @@ interface
uses
System.SysUtils, System.Classes, Data.DB, MemDS, DBAccess, Uni, Common.Logging,
frxClass, frxExportBaseDialog, frxExportPDF, frCoreClasses, frxDBSet, JS, JSON,
frxTableObject, frxUtils;
frxTableObject, frxUtils, System.Generics.Collections;
type
TrptOrderCorrugated = class(TDataModule)
......@@ -133,7 +133,7 @@ implementation
{$R *.dfm}
uses
uLibrary, Common.Config;
uLibrary, Common.Config, XData.Sys.Exceptions;
procedure TrptOrderCorrugated.DataModuleCreate(Sender: TObject);
begin
......@@ -156,8 +156,7 @@ var
colorArray: TJSONArray;
colorsObject, colorObject: TJSONObject;
colorsString: string;
i, rowIndex: Integer;
temp: TObject;
i: Integer;
begin
logger.Log(5, 'Adding Color Rows');
......@@ -181,31 +180,13 @@ end;
function TrptOrderCorrugated.PrepareReport(SQL: string): string;
var
orderList : TJSObject;
i: integer;
data: TJSArray;
order: TJSObject;
callListLength: integer;
tempString, strColorList: string;
colorObject: TJSONObject;
colorList: TJSArray;
colorLength: integer;
color: TJSObject;
colorJSON: TJSONObject;
colorListJSON: TJSONArray;
items: TJSObject;
begin
Logger.Log(5, 'Generated SQL for Prepare Report: ' + SQL);
doQuery(uqOrderCorrugated, SQL);
if ( string( uqOrderCorrugated.FieldByName('colors_colors').AsString ) ) <> '' then
begin
PopulateColorTable();
end;
result := GeneratePDF;
Logger.Log(5, 'Report preparation complete.');
......@@ -219,12 +200,6 @@ var
begin
ReportDir := ServerConfig.reportsFolder;
if not DirectoryExists(ReportDir) then
begin
ForceDirectories(ReportDir);
Logger.Log(1, 'Reports directory created: ' + ReportDir);
end;
reportURL := 'reports/' + FormatDateTime('yyyymmdd_hhnnss', Now) + '.pdf';
ReportFileName := reportDir + reportUrl;
......@@ -235,10 +210,13 @@ begin
frxOrderCorrugated.PrepareReport;
frxOrderCorrugated.Export(frxPDFExport1);
//frxOrders.ShowPreparedReport;
finally
frxOrderCorrugated.Clear; // Clears the report to avoid memory bloat
end;
Logger.Log(5, 'PDF saved to: ' + ReportFileName);
result := reportURL;
end;
......
......@@ -60,7 +60,7 @@ var
implementation
uses
uLibrary, Common.Config;
uLibrary, Common.Config, XData.Sys.Exceptions;
{%CLASSGROUP 'Vcl.Controls.TControl'}
......@@ -82,29 +82,11 @@ end;
function TrptOrderCutting.PrepareReport(SQL: string): string;
var
orderList : TJSObject;
i: integer;
data: TJSArray;
order: TJSObject;
callListLength: integer;
tempString, strColorList: string;
colorObject: TJSONObject;
colorList: TJSArray;
colorLength: integer;
color: TJSObject;
colorJSON: TJSONObject;
colorListJSON: TJSONArray;
items: TJSObject;
begin
Logger.Log(3, 'Generated SQL for Prepare Report: ' + SQL);
//SQL := 'select * from corrugated_plate_orders where ORDER_ID = 18381';
doQuery(uqOrderCutting, SQL);
result := GeneratePDF;
Logger.Log(5, 'Report preparation complete.');
end;
......@@ -116,11 +98,6 @@ var
begin
ReportDir := ServerConfig.reportsFolder;
if not DirectoryExists(ReportDir) then
begin
ForceDirectories(ReportDir);
Logger.Log(1, 'Reports directory created: ' + ReportDir);
end;
reportURL := 'reports\' + FormatDateTime('yyyymmdd_hhnnss', Now) + '.pdf';
ReportFileName := reportDir + reportUrl;
......
......@@ -3,7 +3,7 @@ object rptOrderList: TrptOrderList
Height = 480
Width = 640
object frxOrderList: TfrxReport
Version = '2025.1.4'
Version = '2025.2.4'
DotMatrixReport = False
IniFile = '\Software\Fast Reports'
PreviewOptions.Buttons = [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbEdit, pbNavigator, pbExportQuick, pbCopy, pbSelection]
......@@ -26,6 +26,7 @@ object rptOrderList: TrptOrderList
end>
Variables = <>
Style = <>
Watermarks = <>
object Data: TfrxDataPage
Height = 1000.000000000000000000
Width = 1000.000000000000000000
......@@ -1065,6 +1066,7 @@ object rptOrderList: TrptOrderList
PdfA = False
PDFStandard = psNone
PDFVersion = pv17
PDFColorSpace = csDeviceRGB
Left = 288
Top = 166
end
......
......@@ -59,7 +59,7 @@ var
implementation
uses
uLibrary, Common.Config;
uLibrary, Common.Config, XData.Sys.Exceptions;
{%CLASSGROUP 'Vcl.Controls.TControl'}
......@@ -83,9 +83,7 @@ end;
function TrptOrderList.PrepareReport(SQL, CompanyName: string): string;
var
memo: TFrxMemoView;
temp: TDateTime;
DateFormat: TFormatSettings;
tempStr: string;
begin
Logger.Log(5, 'Generated SQL for Prepare Report: ' + SQL);
......@@ -103,9 +101,6 @@ begin
DateFormat.TimeSeparator := ':';
DateFormat.ShortTimeFormat := 'HH:nn';
tempStr := FormatDateTime('m/d/yyyy HH:nn', uqOrdersORDER_DATE.AsDateTime);
temp := StrToDateTime(FormatDateTime('m/d/yyyy HH:nn', uqOrdersORDER_DATE.AsDateTime), DateFormat);
uqOrdersORDER_DATE.AsDateTime := RecodeSecond(uqOrdersORDER_DATE.AsDateTime, 0);
uqOrders.Post;
......@@ -206,11 +201,6 @@ var
begin
ReportDir := ServerConfig.reportsFolder;
if not DirectoryExists(ReportDir) then
begin
ForceDirectories(ReportDir);
Logger.Log(1, 'Reports directory created: ' + ReportDir);
end;
reportURL := 'reports/' + FormatDateTime('yyyymmdd_hhnnss', Now) + '.pdf';
ReportFileName := reportDir + reportUrl;
......
......@@ -5,7 +5,7 @@ interface
uses
System.SysUtils, System.Classes, Data.DB, MemDS, DBAccess, Uni, Common.Logging,
frxClass, frxExportBaseDialog, frxExportPDF, frCoreClasses, frxDBSet, JS, JSON,
frxTableObject, frxUtils;
frxTableObject, frxUtils, System.Generics.Collections;
type
TrptOrderWeb = class(TDataModule)
......@@ -132,7 +132,7 @@ implementation
{$R *.dfm}
uses
uLibrary, Common.Config;
uLibrary, Common.Config, XData.Sys.Exceptions;
procedure TrptOrderWeb.DataModuleCreate(Sender: TObject);
begin
......@@ -155,8 +155,7 @@ var
colorArray: TJSONArray;
colorsObject, colorObject: TJSONObject;
colorsString: string;
i, rowIndex: Integer;
temp: TObject;
i: Integer;
begin
logger.Log(5, 'Adding Color Rows');
......@@ -180,32 +179,14 @@ end;
function TrptOrderWeb.PrepareReport(SQL: string): string;
var
orderList : TJSObject;
i: integer;
data: TJSArray;
order: TJSObject;
callListLength: integer;
tempString, strColorList: string;
colorObject: TJSONObject;
colorList: TJSArray;
colorLength: integer;
color: TJSObject;
colorJSON: TJSONObject;
colorListJSON: TJSONArray;
items: TJSObject;
begin
Logger.Log(3, 'Generated SQL for Prepare Report: ' + SQL);
//SQL := 'select * from corrugated_plate_orders where ORDER_ID = 18381';
doQuery(uqOrderWeb, SQL);
if ( string( uqOrderWeb.FieldByName('quantity_and_colors_qty_colors').AsString ) ) <> '' then
begin
PopulateColorTable();
end;
result := GeneratePDF;
Logger.Log(3, 'Report preparation complete.');
......@@ -219,11 +200,6 @@ var
begin
ReportDir := ServerConfig.reportsFolder;
if not DirectoryExists(ReportDir) then
begin
ForceDirectories(ReportDir);
Logger.Log(1, 'Reports directory created: ' + ReportDir);
end;
reportURL := 'reports\' + FormatDateTime('yyyymmdd_hhnnss', Now) + '.pdf';
ReportFileName := reportDir + reportUrl;
......@@ -233,7 +209,6 @@ begin
try
frxOrderWeb.PrepareReport;
frxOrderWeb.Export(frxPDFExport1);
//frxOrderWeb.ShowPreparedReport;
finally
frxOrderWeb.Clear; // Clears the report to avoid memory bloat
end;
......
[Settings]
MemoLogLevel=4
FileLogLevel=4
MemoLogLevel=5
FileLogLevel=5
webClientVersion=0.9.11
LogFileNum=164
LogFileNum=205
[Database]
Server=192.168.116.132
--Server=192.168.116.132
--Server=192.168.102.129
--Server=192.168.75.133
--Server=192.168.159.10
Server=192.168.159.10
--Database=kg_order_entry
--Username=root
--Password=emsys01
--Password=emsys!012
[Quickbooks]
Enabled=0
--Enabled=1
CompanyID=9341454336461805
ClientID=ABYqlDx1EsacZYXvHIJ7RDB7zmnQdwABU3fwQLIZPmBgU0VW1P
ClientSecret=PM7OnvQWsgOqjWfDpZAnyRttDN9446Am6d85pDxr
......
......@@ -26,9 +26,7 @@ uses
rOrderCorrugated in 'Source\rOrderCorrugated.pas' {rptOrderCorrugated: TDataModule},
rOrderWeb in 'Source\rOrderWeb.pas' {rptOrderWeb: TDataModule},
rOrderCutting in 'Source\rOrderCutting.pas' {rptOrderCutting: TDataModule},
qbAPI in 'Source\qbAPI.pas' {fQB},
QBService in 'Source\QBService.pas',
QBServiceImplementation in 'Source\QBServiceImplementation.pas';
qbAPI in 'Source\qbAPI.pas' {fQB};
type
TMemoLogAppender = class( TInterfacedObject, ILogAppender )
......@@ -160,8 +158,8 @@ end;
var
iniFile: TIniFile;
memoLogLevel: Integer;
fileLogLevel: Integer;
MemoLogLevel: Integer;
FileLogLevel: Integer;
begin
ReportMemoryLeaksOnShutdown := True;
......@@ -170,12 +168,12 @@ begin
Application.CreateForm(TFMain, FMain);
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
try
memoLogLevel := iniFile.ReadInteger( 'Settings', 'memoLogLevel', 3 );
fileLogLevel := iniFile.ReadInteger( 'Settings', 'memoLogLevel', 4 );
MemoLogLevel := iniFile.ReadInteger( 'Settings', 'MemoLogLevel', 3 );
FileLogLevel := iniFile.ReadInteger( 'Settings', 'FileLogLevel', 4 );
finally
iniFile.Free;
end;
Logger.AddAppender(TMemoLogAppender.Create( memoLogLevel, FMain.memoinfo ));
Logger.AddAppender(TFileLogAppender.Create( fileLogLevel, 'kgOrdersServer' ));
Logger.AddAppender(TMemoLogAppender.Create( MemoLogLevel, FMain.memoinfo ));
Logger.AddAppender(TFileLogAppender.Create( FileLogLevel, 'kgOrdersServer' ));
Application.Run;
end.
......@@ -208,8 +208,6 @@
<Form>fQB</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="Source\QBService.pas"/>
<DCCReference Include="Source\QBServiceImplementation.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
......@@ -238,13 +236,13 @@
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="5">
<DeployFile LocalName="kgOrdersServer.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployFile LocalName="kgOrdersServer.exe" Configuration="Debug" Class="ProjectOutput">
<DeployFile LocalName="bin\kgOrdersServer.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>kgOrdersServer.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="kgOrdersServer.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
......
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