Commit b956dc72 by Mac Stephens

Merge branch 'cam3'

parents 29f8d956 95296f5f
object FViewAddCustomer: TFViewAddCustomer
Width = 842
Height = 607
OnShow = WebFormShow
object dtpStartDate: TWebDateTimePicker
Left = 19
Top = 216
Width = 170
Height = 22
ElementID = 'dtpstartdate'
BorderStyle = bsSingle
ChildOrder = 10
Color = clWhite
Date = 45779.471405393520000000
Role = ''
Text = ''
end
object dtpEndDate: TWebDateTimePicker
Left = 19
Top = 248
Width = 170
Height = 22
ElementID = 'dtpenddate'
BorderStyle = bsSingle
ChildOrder = 10
Color = clWhite
Date = 45779.471405393520000000
Role = ''
Text = ''
end
object edtShortName: TWebDBEdit
Left = 19
Top = 12
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtcompanyaccountname'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'SHORT_NAME'
DataSource = WebDataSource1
end
object edtName: TWebDBEdit
Left = 19
Top = 40
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtcompanyname'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'NAME'
DataSource = WebDataSource1
end
object edtBillAddress: TWebDBEdit
Left = 19
Top = 68
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtbillingaddress'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'BILL_ADDRESS'
DataSource = WebDataSource1
end
object edtBillCity: TWebDBEdit
Left = 19
Top = 98
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtbillingcity'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'BILL_CITY'
DataSource = WebDataSource1
end
object edtBillState: TWebDBEdit
Left = 19
Top = 126
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtbillingstate'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'BILL_STATE'
DataSource = WebDataSource1
end
object edtBillZip: TWebDBEdit
Left = 19
Top = 160
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtbillingzip'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'BILL_ZIP'
DataSource = WebDataSource1
end
object edtBillContact: TWebDBEdit
Left = 19
Top = 188
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtbillingcontact'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'BILL_CONTACT'
DataSource = WebDataSource1
end
object edtPhone: TWebDBEdit
Left = 19
Top = 276
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtphone'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'PHONE'
DataSource = WebDataSource1
end
object edtFax: TWebDBEdit
Left = 19
Top = 304
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtfax'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'FAX'
DataSource = WebDataSource1
end
object btnSave: TWebButton
Left = 19
Top = 402
Width = 96
Height = 25
Caption = 'Save'
ChildOrder = 79
ElementID = 'btnconfirm'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
WidthPercent = 100.000000000000000000
OnClick = btnSaveClick
end
object btnCancel: TWebButton
Left = 19
Top = 473
Width = 96
Height = 25
Caption = 'Cancel'
ChildOrder = 79
ElementID = 'btncancel'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
end
object btnDelete: TWebButton
Left = 19
Top = 371
Width = 96
Height = 25
Caption = 'Delete'
ChildOrder = 79
ElementID = 'btndelete'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnDeleteClick
end
object btnClose: TWebButton
Left = 19
Top = 433
Width = 96
Height = 25
Caption = 'Close'
ChildOrder = 80
ElementID = 'btnclose'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnCloseClick
end
object btnEdit: TWebButton
Left = 19
Top = 504
Width = 96
Height = 25
Caption = 'Edit'
ChildOrder = 83
ElementID = 'btnedit'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnEditClick
end
object pnlMessage: TWebPanel
Left = 324
Top = 19
Width = 121
Height = 33
ElementID = 'view.login.message'
ChildOrder = 5
ElementPosition = epRelative
Role = 'null'
TabOrder = 16
object lblMessage: TWebLabel
Left = 28
Top = 9
Width = 46
Height = 15
Caption = 'Message'
ElementID = 'view.login.message.label'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object btnCloseNotification: TWebButton
Left = 96
Top = 3
Width = 22
Height = 25
ChildOrder = 1
ElementID = 'view.login.message.button'
ElementFont = efCSS
ElementPosition = epRelative
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
Role = 'null'
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000
OnClick = btnCloseNotificationClick
end
end
object edtCustomerID: TWebDBEdit
Left = 151
Top = 12
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtcompanyid'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'CUSTOMER_ID'
DataSource = WebDataSource1
end
object edtQBID: TWebDBEdit
Left = 151
Top = 40
Width = 121
Height = 22
ChildOrder = 12
ElementID = 'edtqbid'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'QB_LIST_ID'
DataSource = WebDataSource1
end
object wdbtcAddresses: TWebDBTableControl
Left = 190
Top = 204
Width = 631
Height = 200
ElementClassName = 'table'
ElementId = 'tblPhoneGrid'
BorderColor = clSilver
ChildOrder = 11
ElementFont = efCSS
ElementHeaderClassName = 'thead-light sticky-top bg-light'
ElementPosition = epRelative
ElementTableClassName = 'table table-striped table-hover table-bordered text-sm'
Footer.ButtonActiveElementClassName = 'btn btn-primary'
Footer.ButtonElementClassName = 'btn btn-light'
Footer.DropDownElementClassName = 'form-control'
Footer.InputElementClassName = 'form-control'
Footer.LinkActiveElementClassName = 'link-primary'
Footer.LinkElementClassName = 'link-secondary'
Footer.ListElementClassName = 'pagination'
Footer.ListItemElementClassName = 'page-item'
Footer.ListLinkElementClassName = 'page-link'
Header.ButtonActiveElementClassName = 'btn btn-primary'
Header.ButtonElementClassName = 'btn btn-light'
Header.DropDownElementClassName = 'form-control'
Header.InputElementClassName = 'form-control'
Header.LinkActiveElementClassName = 'link-primary'
Header.LinkElementClassName = 'link-secondary'
Header.ListElementClassName = 'pagination'
Header.ListItemElementClassName = 'page-item'
Header.ListLinkElementClassName = 'page-link'
WordWrap = True
OnDblClickCell = wdbtcAddressesDblClickCell
Columns = <
item
DataField = 'ship_id'
Title = 'ID'
end
item
DataField = 'ADDRESS'
Title = 'Address'
end>
DataSource = wdsShipTo
end
object edtShippingAddress: TWebEdit
Left = 190
Top = 460
Width = 121
Height = 22
ChildOrder = 22
ElementID = 'edtshippingaddress'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object edtShippingState: TWebEdit
Left = 190
Top = 516
Width = 121
Height = 22
ChildOrder = 22
ElementID = 'edtshippingstate'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object edtShippingContact: TWebEdit
Left = 190
Top = 578
Width = 121
Height = 22
ChildOrder = 22
ElementID = 'edtshippingcontact'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object edtShippingZip: TWebEdit
Left = 190
Top = 550
Width = 121
Height = 22
ChildOrder = 22
ElementID = 'edtshippingzip'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object edtShippingCity: TWebEdit
Left = 190
Top = 488
Width = 121
Height = 22
ChildOrder = 22
ElementID = 'edtshippingcity'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object memoShipBlock: TWebMemo
Left = 508
Top = 460
Width = 185
Height = 89
ElementID = 'memoshipblock'
Enabled = False
HeightPercent = 100.000000000000000000
SelLength = 0
SelStart = 0
WidthPercent = 100.000000000000000000
OnChange = edtShippingAddressChange
end
object memoAddressBlock: TWebMemo
Left = 162
Top = 86
Width = 185
Height = 89
ElementID = 'memoaddressblock'
Enabled = False
HeightPercent = 100.000000000000000000
SelLength = 0
SelStart = 0
WidthPercent = 100.000000000000000000
OnChange = memoAddressBlockChange
end
object btnAdd: TWebButton
Left = 19
Top = 535
Width = 96
Height = 25
Caption = 'Add'
ChildOrder = 84
ElementID = 'btnadd'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnAddClick
end
object btnShipSave: TWebButton
Left = 339
Top = 441
Width = 96
Height = 25
Caption = 'Save'
ChildOrder = 79
ElementID = 'btnshipconfirm'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
WidthPercent = 100.000000000000000000
OnClick = btnShipSaveClick
end
object btnShipCancel: TWebButton
Left = 339
Top = 480
Width = 96
Height = 25
Caption = 'Cancel'
ChildOrder = 79
ElementID = 'btnshipcancel'
ElementPosition = epRelative
HeightPercent = 100.000000000000000000
Role = 'null'
WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
end
object btnShipDelete: TWebButton
Left = 339
Top = 410
Width = 96
Height = 25
Caption = 'Delete'
ChildOrder = 79
ElementID = 'btnshipdelete'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnShipDeleteClick
end
object btnShipEdit: TWebButton
Left = 339
Top = 511
Width = 96
Height = 25
Caption = 'Edit'
ChildOrder = 83
ElementID = 'btnshipedit'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnShipEditClick
end
object btnShipAdd: TWebButton
Left = 339
Top = 549
Width = 96
Height = 25
Caption = 'Add'
ChildOrder = 84
ElementID = 'btnshipadd'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnShipAddClick
end
object btn_confirm_delete: TWebButton
Left = 725
Top = 433
Width = 96
Height = 25
Caption = 'Delete'
ChildOrder = 82
ElementID = 'btn_confirm_delete'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btn_confirm_deleteClick
end
object edtFirstLine: TWebEdit
Left = 190
Top = 430
Width = 121
Height = 22
ChildOrder = 35
ElementID = 'edtfirstline'
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object wdblcbRep: TWebDBLookupComboBox
Left = 19
Top = 336
Width = 145
Height = 22
ElementID = 'wdblcbrep'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
DataField = 'REP_USER_ID'
DataSource = WebDataSource1
KeyField = 'userID'
ListField = 'full_name'
ListSource = wdsUsers
end
object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 454
Top = 72
end
object WebDataSource1: TWebDataSource
DataSet = XDataWebDataSet1
Left = 532
Top = 126
end
object XDataWebDataSet1: TXDataWebDataSet
AfterEdit = XDataWebDataSet1AfterEdit
Connection = DMConnection.ApiConnection
Left = 426
Top = 132
object XDataWebDataSet1SHORT_NAME: TStringField
FieldName = 'SHORT_NAME'
end
object XDataWebDataSet1NAME: TStringField
FieldName = 'NAME'
end
object XDataWebDataSet1BILL_ADDRESS: TStringField
FieldName = 'BILL_ADDRESS'
end
object XDataWebDataSet1BILL_CITY: TStringField
FieldName = 'BILL_CITY'
end
object XDataWebDataSet1BILL_STATE: TStringField
FieldName = 'BILL_STATE'
end
object XDataWebDataSet1BILL_CONTACT: TStringField
FieldName = 'BILL_CONTACT'
end
object XDataWebDataSet1BILL_ZIP: TStringField
FieldName = 'BILL_ZIP'
end
object XDataWebDataSet1START_DATE: TStringField
FieldName = 'START_DATE'
end
object XDataWebDataSet1QB_LIST_ID: TStringField
FieldName = 'QB_LIST_ID'
end
object XDataWebDataSet1END_DATE: TStringField
FieldName = 'END_DATE'
end
object XDataWebDataSet1FAX: TStringField
FieldName = 'FAX'
end
object XDataWebDataSet1PHONE: TStringField
FieldName = 'PHONE'
end
object XDataWebDataSet1CUSTOMER_ID: TIntegerField
FieldName = 'CUSTOMER_ID'
end
object XDataWebDataSet1REP_USER_ID: TStringField
FieldName = 'REP_USER_ID'
end
end
object wdsShipTo: TWebDataSource
DataSet = xdwdsShipTo
Left = 698
Top = 128
end
object xdwdsShipTo: TXDataWebDataSet
AfterEdit = xdwdsShipToAfterEdit
Left = 698
Top = 44
object xdwdsShipToADDRESS: TStringField
FieldName = 'ADDRESS'
end
object xdwdsShipToship_id: TStringField
FieldName = 'ship_id'
end
object xdwdsShipToshipping_address: TStringField
FieldName = 'shipping_address'
end
object xdwdsShipTocity: TStringField
FieldName = 'city'
end
object xdwdsShipTostate: TStringField
FieldName = 'state'
end
object xdwdsShipTozip: TStringField
FieldName = 'zip'
end
object xdwdsShipTocontact: TStringField
FieldName = 'contact'
end
end
object tmrReturn: TWebTimer
Enabled = False
OnTimer = tmrReturnTimer
Left = 542
Top = 42
end
object wdsUsers: TWebDataSource
DataSet = xdwdsUsers
Left = 776
Top = 144
end
object xdwdsUsers: TXDataWebDataSet
Left = 776
Top = 54
object xdwdsUsersuserID: TStringField
FieldName = 'userID'
end
object xdwdsUsersfull_name: TStringField
FieldName = 'full_name'
Size = 0
end
end
end
<nav class="navbar navbar-expand navbar-light bg-light sticky-top" style="z-index: 100;">
<div class="container-fluid ps-0">
<div id="view.login.message" class="alert alert-danger"
style="padding: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; display: flex; align-items: center; margin: 0 0 0 60px; height: 32px; width: 400px;">
<button id="view.login.message.button" type="button" class="btn-close" aria-label="Close"></button>
<span id="view.login.message.label"></span>
</div>
<ul class="navbar-nav me-auto ps-2">
<li class="nav-item pe-2">
<button id="btnadd" class="btn btn-primary btn-sm">Add</button>
</li>
<li class="nav-item pe-2">
<button id="btnedit" class="btn btn-primary btn-sm">Edit</button>
</li>
<li class="nav-item pe-2">
<button id="btndelete" class="btn btn-danger btn-sm">Delete</button>
</li>
<li class="nav-item pe-2">
<button id="btnconfirm" class="btn btn-success btn-sm">Save</button>
</li>
<li class="nav-item pe-2">
<button id="btncancel" class="btn btn-danger btn-sm">Cancel</button>
</li>
<li class="nav-item">
<button id="btnclose" class="btn btn-primary btn-sm">Close</button>
</li>
</ul>
</div>
</nav>
<div class="row mx-5">
<h4 class="custom-h4 mt-3">Customer Information</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 mt-2">Customer Num</label>
<input id="edtcompanyid" class="form-control input-sm"style="width: 100px" required/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Quickbooks ID:</label>
<input id="edtqbid" class="form-control input-sm"style="width: 200px" required/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer Name:</label>
<input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Name.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer ID:</label>
<input id="edtcompanyaccountname"type="text" class="form-control" style="width: 150px" required/>
<div class="invalid-feedback" id="shortnamefeedback" style="font-size: 15px;">
Please Provide a Company Account Name.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Start Date:</label>
<input class="form-control input-sm" id="dtpstartdate" type="date" required>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">End Date:</label>
<input class="form-control input-sm" id="dtpenddate" type="date" required>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Phone:</label>
<input id="edtphone" type="text" class="form-control"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Fax:</label>
<input id="edtfax" class="form-control input-sm"style="width: 200px"/>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Representative:</label>
<select id="wdblcbrep" class='form-select'></select>
</div>
</div>
<h4 class="custom-h4 mt-3">Billing Information</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 mt-2">Billing Address:</label>
<input id="edtbillingaddress" class="form-control input-sm" style="width: 300px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Address.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Billing City</label>
<input id="edtbillingcity" class="form-control input-sm" style="width: 250px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a City.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Billing State:</label>
<input id="edtbillingstate" class="form-control input-sm" style="width: 100px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a State.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Billing Zip Code:</label>
<input id="edtbillingzip" class="form-control input-sm" style="width: 200px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Zip Code.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Billing Contact:</label>
<input id="edtbillingcontact" class="form-control input-sm" style="width: 250px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Billing Contact.
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label">Billing Address Block</label>
<textarea id="memoaddressblock" class="form-control" style=" width: 500px; height: 150px;" required></textarea>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a Billing Address Block.
</div>
</div>
</div>
<h4 class="custom-h4 mt-3">Shipping Addresses</h4>
<hr class="custom-hr">
<div class="row">
<table id="tblPhoneGrid" class="table table-striped table-bordered" style="width: 100%;">
<thead class="sticky-top thead-light">
<tr style="font-size: 0.875rem;">
<!-- Table headers are dynamically generated -->
</tr>
</thead>
<tbody id="orderTableBody" class="align-middle">
<!-- Table rows are dynamically generated -->
</tbody>
</table>
</div>
<div class="row mt-1">
<div class="col-auto">
<button id="btnshipadd" class="btn btn-primary btn-sm">Add</button>
</div>
<div class="col-auto">
<button id="btnshipedit" class="btn btn-primary btn-sm">Edit</button>
</div>
<div class="col-auto">
<button id="btnshipdelete" class="btn btn-danger btn-sm">Delete</button>
</div>
<div class="col-auto">
<button id="btnshipconfirm" class="btn btn-success btn-sm">Save</button>
</div>
<div class="col-auto">
<button id="btnshipcancel" class="btn btn-danger btn-sm">Cancel</button>
</div>
</div>
<div class="row mt-3">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">First Line:</label>
<input id="edtfirstline" class="form-control input-sm" style="width: 300px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter the First Line.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Address:</label>
<input id="edtshippingaddress" class="form-control input-sm" style="width: 300px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter an Address.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">City</label>
<input id="edtshippingcity" class="form-control input-sm" style="width: 250px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a City.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">State:</label>
<input id="edtshippingstate" class="form-control input-sm" style="width: 100px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a State.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Zip Code:</label>
<input id="edtshippingzip" class="form-control input-sm" style="width: 200px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a Zip Code.
</div>
</div>
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Contact:</label>
<input id="edtshippingcontact" class="form-control input-sm" style="width: 250px" required/>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a Shipping Contact.
</div>
</div>
</div>
<div class="row my-3">
<div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label">Shipping Block</label>
<textarea id="memoshipblock" class="form-control" style=" width: 500px; height: 150px;" required></textarea>
<div class="invalid-feedback" style="font-size: 15px;">
Please Enter a Shipping Block.
</div>
</div>
</div>
</div>
<div class="modal fade" id="confirmation_modal" tabindex="-1" aria-labelledby="confirmation_modal_label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmation_modal_label">Confirm</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="modal_body">
Are you sure you want to delete this order?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id= 'btn_confirm_cancel'>Cancel</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="btn_confirm_delete">Delete</button>
</div>
</div>
</div>
</div>
<style>
.modal-backdrop {
opacity: 0 !important;
}
</style>
// Add Customer page for KGOrders. Handles Adding and Editting Customers and
// Their shipping addresses.
unit AddCustomer;
interface
uses
System.SysUtils, System.Generics.Collections, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
Data.DB, XData.Web.JsonDataset, XData.Web.Dataset, WEBLib.DB, WEBLib.Grids;
type
TFViewAddCustomer = class(TWebForm)
dtpStartDate: TWebDateTimePicker;
dtpEndDate: TWebDateTimePicker;
edtShortName: TWebDBEdit;
edtName: TWebDBEdit;
edtBillAddress: TWebDBEdit;
edtBillCity: TWebDBEdit;
edtBillState: TWebDBEdit;
edtBillZip: TWebDBEdit;
edtBillContact: TWebDBEdit;
edtPhone: TWebDBEdit;
edtFax: TWebDBEdit;
btnSave: TWebButton;
btnCancel: TWebButton;
btnDelete: TWebButton;
btnClose: TWebButton;
btnEdit: TWebButton;
pnlMessage: TWebPanel;
lblMessage: TWebLabel;
btnCloseNotification: TWebButton;
XDataWebClient1: TXDataWebClient;
WebDataSource1: TWebDataSource;
XDataWebDataSet1: TXDataWebDataSet;
XDataWebDataSet1SHORT_NAME: TStringField;
XDataWebDataSet1NAME: TStringField;
XDataWebDataSet1BILL_ADDRESS: TStringField;
XDataWebDataSet1BILL_CITY: TStringField;
edtCustomerID: TWebDBEdit;
edtQBID: TWebDBEdit;
wdbtcAddresses: TWebDBTableControl;
wdsShipTo: TWebDataSource;
xdwdsShipTo: TXDataWebDataSet;
XDataWebDataSet1BILL_STATE: TStringField;
XDataWebDataSet1BILL_CONTACT: TStringField;
XDataWebDataSet1BILL_ZIP: TStringField;
XDataWebDataSet1START_DATE: TStringField;
XDataWebDataSet1END_DATE: TStringField;
XDataWebDataSet1QB_LIST_ID: TStringField;
XDataWebDataSet1FAX: TStringField;
XDataWebDataSet1PHONE: TStringField;
XDataWebDataSet1CUSTOMER_ID: TIntegerField;
edtShippingAddress: TWebEdit;
edtShippingState: TWebEdit;
edtShippingContact: TWebEdit;
edtShippingZip: TWebEdit;
edtShippingCity: TWebEdit;
xdwdsShipToADDRESS: TStringField;
xdwdsShipToship_id: TStringField;
xdwdsShipToshipping_address: TStringField;
xdwdsShipTocity: TStringField;
xdwdsShipTostate: TStringField;
xdwdsShipTozip: TStringField;
xdwdsShipTocontact: TStringField;
memoShipBlock: TWebMemo;
memoAddressBlock: TWebMemo;
btnAdd: TWebButton;
btnShipSave: TWebButton;
btnShipCancel: TWebButton;
btnShipDelete: TWebButton;
btnShipEdit: TWebButton;
btnShipAdd: TWebButton;
btn_confirm_delete: TWebButton;
tmrReturn: TWebTimer;
edtFirstLine: TWebEdit;
wdsUsers: TWebDataSource;
xdwdsUsers: TXDataWebDataSet;
wdblcbRep: TWebDBLookupComboBox;
xdwdsUsersuserID: TStringField;
XDataWebDataSet1REP_USER_ID: TStringField;
xdwdsUsersfull_name: TStringField;
procedure WebFormShow(Sender: TObject);
procedure btnCloseNotificationClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
procedure xdwdsShipToAfterEdit(DataSet: TDataSet);
procedure XDataWebDataSet1AfterEdit(DataSet: TDataSet);
procedure btnCloseClick(Sender: TObject);
procedure btnEditClick(Sender: TObject);
procedure wdbtcAddressesDblClickCell(Sender: TObject; ACol, ARow: Integer);
procedure btnClearClick(Sender: TObject);
procedure memoAddressBlockChange(Sender: TObject);
procedure AddressEditMode();
procedure edtShippingAddressChange(Sender: TObject);
procedure btnAddClick(Sender: TObject);
procedure btn_confirm_deleteClick(Sender: TObject);
procedure tmrReturnTimer(Sender: TObject);
procedure btnDeleteClick(Sender: TObject);
procedure btnShipAddClick(Sender: TObject);
procedure btnShipEditClick(Sender: TObject);
procedure btnShipSaveClick(Sender: TObject);
procedure btnShipDeleteClick(Sender: TObject);
private
{ Private declarations }
procedure HideNotification();
procedure ShowNotification(Notification: string);
procedure ViewMode();
procedure EditMode();
[async] procedure GetCustomer();
[async] procedure SendCustomerToServer();
[async] procedure SendAddressToServer();
[async] procedure DelAddress();
function VerifyCustomer(): boolean;
function VerifyAddress(): boolean;
procedure Clear();
procedure ShowSelectCustomerForm();
var
customerID: string;
notification: string;
mode: string;
shipmode: string;
public
{ Public declarations }
class function CreateForm(AElementID, customerInfo, info: string): TWebForm;
end;
var
FViewAddCustomer: TFViewAddCustomer;
implementation
{$R *.dfm}
uses View.Main, View.Customers, View.SelectCustomer;
procedure TFViewAddCustomer.Clear();
// Clears the shipping address fields.
begin
edtShippingAddress.Text := '';
edtShippingCity.Text := '';
edtShippingState.Text := '';
edtShippingZip.Text := '';
edtShippingContact.Text := '';
memoShipBlock.Text := '';
edtFirstLine.Text := '';
end;
procedure TFViewAddCustomer.ShowSelectCustomerForm();
// displays the add order pop-up so the user can choose a customer
var
newform: TFSelectCustomer;
begin
newform := TFSelectCustomer.CreateNew;
newform.Caption := 'Select Customer and Order Type';
newForm.Popup := True;
newForm.Border := fbDialog;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
begin
end
);
end;
procedure TFViewAddCustomer.DelAddress;
// Deletes a shipping address.
var
Response: TXDataClientResponse;
notification: TJSObject;
begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.DelShippingAddress',
[xdwdsShipTo.FieldByName('ship_id').AsString, customerID]));
notification := TJSObject(Response.Result);
ShowNotification(string(notification['status']));
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
asm
endSpinner();
end;
end;
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;
ship_block: string;
begin
AddressJSON := TJSONObject.Create;
AddressJSON.AddPair('address', edtShippingAddress.Text);
AddressJSON.AddPair('city', edtShippingcity.Text);
AddressJSON.AddPair('state', edtShippingstate.Text);
AddressJSON.AddPair('zip', edtShippingzip.Text);
AddressJSON.AddPair('contact', edtShippingContact.Text);
AddressJSON.AddPair('customer_id', customerID);
ship_block := edtFirstLine.Text + slinebreak +
edtName.Text + slinebreak +
edtShippingContact.Text + slinebreak +
edtShippingAddress.Text + slinebreak +
edtShippingCity.Text + ', ' + edtShippingState.Text + ' ' + edtShippingZip.Text;
AddressJSON.AddPair('ship_block', ship_block);
if shipmode = 'EDIT' then
AddressJSON.AddPair('customer_ship_id', xdwdsShipTo.FieldByName('ship_id').AsString);
AddressJSON.AddPair('mode', shipmode);
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddShippingAddress',
[AddressJSON.ToString]));
notification := TJSObject(Response.Result);
ShowNotification(string(notification['status']));
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
end;
procedure TFViewAddCustomer.btnAddClick(Sender: TObject);
// Takes the user to the Add Customer Page.
begin
ShowSelectCustomerForm();
end;
procedure TFViewAddCustomer.btnCancelClick(Sender: TObject);
// Shows a pop-up to confirm the user would like to cancel their changes.
begin
document.getElementById('modal_body').innerHTML := 'Are you sure you want to cancel all changes to the customer?';
document.getElementById('btn_confirm_cancel').innerText := 'No';
document.getElementById('btn_confirm_delete').innerText := 'Yes';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
end;
end;
procedure TFViewAddCustomer.btnClearClick(Sender: TObject);
// Clears the shipping address fields.
begin
Clear();
end;
procedure TFViewAddCustomer.btnCloseClick(Sender: TObject);
// closes the Add Customer page.
begin
FViewMain.ShowForm(TFViewCustomers)
end;
procedure TFViewAddCustomer.btnCloseNotificationClick(Sender: TObject);
// Closes a Notification.
begin
HideNotification();
end;
procedure TFViewAddCustomer.btnDeleteClick(Sender: TObject);
// Eventually will delete customers after a confirmation
// TODO implement deleting customers
begin
ShowMessage('Deleting Customers Is Not Yet Available');
end;
procedure TFViewAddCustomer.btnEditClick(Sender: TObject);
// Puts the form into edit mode
begin
EditMode();
end;
procedure TFViewAddCustomer.edtShippingAddressChange(Sender: TObject);
// Puts the form into Address Edit Mode
begin
AddressEditMode();
end;
procedure TFViewAddCustomer.EditMode;
// Enables Customer Fields while disabling shipping address fields.
begin
FViewMain.change := true;
btnAdd.Enabled := false;
btnDelete.Enabled := false;
btnClose.Enabled := false;
btnSave.Enabled := true;
btnCancel.Enabled := True;
btnEdit.Enabled := false;
// Disable Shipping Address Editting
edtShippingAddress.Enabled := false;
edtShippingCity.Enabled := false;
edtShippingState.Enabled := false;
edtShippingZip.Enabled := false;
edtShippingContact.Enabled := false;
edtFirstLine.Enabled := false;
btnShipDelete.Enabled := false;
btnShipSave.Enabled := false;
btnShipCancel.Enabled := false;
btnShipEdit.Enabled := false;
btnShipAdd.Enabled := false;
end;
procedure TFViewAddCustomer.AddressEditMode;
// Enables Shipping Address fields while disabling customer fields.
begin
FViewMain.change := true;
btnDelete.Enabled := false;
btnClose.Enabled := false;
btnSave.Enabled := false;
btnCancel.Enabled := false;
btnEdit.Enabled := false;
btnAdd.Enabled := false;
btnShipDelete.Enabled := false;
btnShipSave.Enabled := true;
btnShipCancel.Enabled := true;
btnShipEdit.Enabled := false;
btnShipAdd.Enabled := false;
edtShippingAddress.Enabled := true;
edtShippingCity.Enabled := true;
edtShippingState.Enabled := true;
edtShippingZip.Enabled := true;
edtShippingContact.Enabled := true;
edtFirstLine.Enabled := true;
edtName.Enabled := false;
edtShortName.Enabled := false;
edtBillAddress.Enabled := false;
edtBillCity.Enabled := false;
edtBillState.Enabled := false;
edtBillZip.Enabled := false;
edtBillContact.Enabled := false;
dtpStartDate.Enabled := false;
dtpEndDate.Enabled := false;
edtFax.Enabled := false;
edtPhone.enabled := false;
wdblcbRep.Enabled := false;
end;
procedure TFViewAddCustomer.ViewMode;
// Enables Customer Fields while disabling shipping address fields.
begin
btnAdd.Enabled := true;
btnDelete.Enabled := true;
btnClose.Enabled := true;
btnSave.Enabled := false;
btnCancel.Enabled := false;
btnEdit.Enabled := true;
FViewMain.change := false;
btnShipAdd.Enabled := true;
if ( not xdwdsShipTo.IsEmpty ) then
btnShipDelete.Enabled := true;
btnShipSave.Enabled := false;
btnShipCancel.Enabled := false;
btnShipEdit.Enabled := true;
FViewMain.change := false;
edtName.Enabled := true;
edtShortName.Enabled := true;
edtBillAddress.Enabled := true;
edtBillCity.Enabled := true;
edtBillState.Enabled := true;
edtBillZip.Enabled := true;
edtBillContact.Enabled := true;
dtpStartDate.Enabled := true;
dtpEndDate.Enabled := true;
edtFax.Enabled := true;
edtPhone.enabled := true;
wdblcbRep.Enabled := true;
end;
procedure TFViewAddCustomer.wdbtcAddressesDblClickCell(Sender: TObject; ACol,
ARow: Integer);
// Retrieves the shipping address allowing it to be edited.
begin
xdwdsShipTo.Locate('ship_id', wdbtcAddresses.Cells[0, ARow], []);
edtShippingAddress.Text := xdwdsShipTo.FieldByName('shipping_address').AsString;
edtShippingCity.Text := xdwdsShipTo.FieldByName('city').AsString;
edtShippingState.Text := xdwdsShipTo.FieldByName('state').AsString;
edtShippingZip.Text := xdwdsShipTo.FieldByName('zip').AsString;
edtShippingContact.Text := xdwdsShipTo.FieldByName('contact').AsString;
memoShipBlock.Text := xdwdsShipTo.FieldByName('ADDRESS').AsString;
edtFirstLine.Text := memoShipBlock.Lines[0];
end;
procedure TFViewAddCustomer.SendCustomerToServer();
// Creates the customer JSON and then sends it to the server.
var
customerJSON: TJSONObject;
Field: TField;
Response: TXDataClientResponse;
notification: TJSObject;
input: TJSHTMLElement;
msg: string;
BILL_ADDRESS_BLOCK: string;
begin
customerJSON := TJSONObject.Create;
if dtpStartDate.Date <> 0 then
XDataWebDataSet1START_DATE.Value := DateTimeToStr(dtpStartDate.Date);
if dtpEndDate.Date <> 0 then
XDataWebDataSet1END_DATE.Value := DateTimeToStr(dtpEndDate.Date);
XDataWebDataSet1.First;
while not XDataWebDataSet1.Eof do
begin
for Field in XDataWebDataSet1.Fields do
begin
if Field is TStringField then
begin
if Field.AsString = '' then
customerJSON.AddPair(Field.FieldName, '')
else
customerJSON.AddPair(Field.FieldName, Field.AsString); // Add all other fields
end
else if Field is TIntegerField then
begin
customerJSON.AddPair(Field.FieldName, Field.AsString);
end;
end;
XDataWebDataSet1.Next;
end;
BILL_ADDRESS_BLOCK := edtName.Text + slinebreak +
edtBillContact.Text + slinebreak +
edtBillAddress.Text + slinebreak +
edtBillCity.Text + ', ' + edtBillState.Text + ' ' + edtBillZip.Text;
CustomerJSON.AddPair('BILL_ADDRESS_BLOCK', BILL_ADDRESS_BLOCK);
customerJSON.AddPair('mode', mode);
if mode = 'EDIT' then
customerJSON.AddPair('CUSTOMER_ID', customerID);
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCustomer',
[customerJSON.ToString]));
notification := TJSObject(Response.Result);
msg := string(notification['status']);
if CustomerID = '' then
CustomerID := string(notification['CustomerID']);
edtCustomerID.Text := CustomerID;
ShowNotification(msg);
//TODO update the BILL_ADDRESS_BLOCK memo after saving.
if msg.Contains('Failure') then
begin
input := TJSHTMLInputElement(document.getElementById('edtcompanyaccountname'));
input.classList.add('is-invalid');
input := TJSHTMLInputElement(document.getElementById('shortnamefeedback'));
input.innerHTML := 'Company Account Name must be Unique.' ;
end;
end;
procedure TFViewAddCustomer.btnSaveClick(Sender: TObject);
// Sends the customer JSON to the server
begin
if VerifyCustomer() then
begin
sendCustomerToServer();
ViewMode();
end;
end;
procedure TFViewAddCustomer.btnShipAddClick(Sender: TObject);
// Sets the form to address edit mode and allows the user to add a shipping address.
begin
shipmode := 'ADD';
Clear();
AddressEditMode();
end;
procedure TFViewAddCustomer.btnShipDeleteClick(Sender: TObject);
// Allows the user to delete a Shipping Address.
begin
document.getElementById('modal_body').innerHTML := 'Are you sure you want to delete this address?';
document.getElementById('btn_confirm_cancel').innerText := 'Cancel';
document.getElementById('btn_confirm_delete').innerText := 'Delete';
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.show();
end;
end;
procedure TFViewAddCustomer.btnShipEditClick(Sender: TObject);
// Sets the form into AddressEdit mode.
begin
shipmode := 'EDIT';
AddressEditMode();
end;
procedure TFViewAddCustomer.btnShipSaveClick(Sender: TObject);
// After Verifying the Address it sends the address down to the server.
begin
if VerifyAddress() then
begin
SendAddressToServer();
Clear();
ViewMode();
end;
end;
procedure TFViewAddCustomer.btn_confirm_deleteClick(Sender: TObject);
// Modal Confirmation button. Checks if the user is cancelling changes, or
// Deleting a shipping address/ customer
begin
FViewMain.change := false;
if document.getElementById('btn_confirm_delete').innerText = 'Yes' then
// checks if the user is canceling or deleting
begin
if CustomerID <> '' then
begin
FViewMain.ViewAddCustomer(CustomerID, 'Failure:Changes Discarded');
end
else
FViewMain.ShowForm(TFViewCustomers);
end
else if document.getElementById('modal_body').innerHTML.Contains('customer') then
// checks if the user is deleting a customer or a shipping address
begin
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
end;
//delCustomer();
tmrReturn.Enabled := true;
end
else
begin
asm
var confirmationModal = new bootstrap.Modal(document.getElementById('confirmation_modal'), {
keyboard: false });
confirmationModal.hide();
startSpinner();
end;
delAddress();
end;
end;
class function TFViewAddCustomer.CreateForm(AElementID: string; customerInfo: string; info: string): TWebForm;
// Creates the Add Customer form. Setting the customer id so the customer can be
// Retrieved and the notification to be shown.
begin
Application.CreateForm(TFViewAddCustomer, AElementID, Result,
procedure(AForm: TObject)
begin
with TFViewAddCustomer(AForm) do
begin
TFViewAddCustomer(AForm).customerID := customerInfo;
TFViewAddCustomer(AForm).notification := info;
end;
end
);
end;
procedure TFViewAddCustomer.GetCustomer;
// Retrieves a customer for a given CustomerID.
var
xdcResponse: TXDataClientResponse;
customer : TJSObject;
address: string;
items: TJSObject;
ship_block: TStringList;
begin
if CustomerID = '' then
begin
mode := 'ADD';
end
else
mode := 'EDIT';
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomer',
[customerID]));
customer := TJSObject(xdcResponse.Result);
console.log(customer);
xdwdsUsers.Close;
xdwdsUsers.SetJSONData(customer['USERS']);
xdwdsUsers.Open;
XDataWebDataSet1.Close;
XDataWebDataSet1.SetJsonData(customer);
XDataWebDataSet1.Open;
edtCustomerID.Text := CustomerID;
if XDataWebDataSet1.FieldByName('START_DATE').AsString <> '' then
dtpStartDate.Date := XDataWebDataSet1.FieldByName('START_DATE').AsDateTime;
if XDataWebDataSet1.FieldByName('END_DATE').AsString <> '' then
dtpEndDate.Date := XDataWebDataSet1.FieldByName('End_DATE').AsDateTime;
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(customer['ADDRESS_LIST']);
xdwdsShipTo.Open;
memoAddressBlock.Text := string(customer['staff_fields_invoice_to']);
edtShippingAddress.Text := xdwdsShipTo.FieldByName('shipping_address').AsString;
edtShippingCity.Text := xdwdsShipTo.FieldByName('city').AsString;
edtShippingState.Text := xdwdsShipTo.FieldByName('state').AsString;
edtShippingZip.Text := xdwdsShipTo.FieldByName('zip').AsString;
edtShippingContact.Text := xdwdsShipTo.FieldByName('contact').AsString;
memoShipBlock.Text := xdwdsShipTo.FieldByName('ADDRESS').AsString;
if memoShipBlock.Lines.Count > 0 then
edtFirstLine.Text := memoShipBlock.Lines[0]
else
edtFirstLine.Text := '';
end;
procedure TFViewAddCustomer.WebFormShow(Sender: TObject);
// Sets the form up whenever it is shown.
var
SQL: string;
begin
if customerID = '' then
mode := 'ADD'
else
mode := 'EDIT';
if notification = '' then
hideNotification()
else
showNotification(notification);
if mode = 'ADD' then
EditMode()
else
ViewMode();
getCustomer();
dtpStartDate.Date := 0;
dtpEndDate.Date := 0;
end;
procedure TFViewAddCustomer.XDataWebDataSet1AfterEdit(DataSet: TDataSet);
begin
EditMode();
end;
procedure TFViewAddCustomer.xdwdsShipToAfterEdit(DataSet: TDataSet);
begin
EditMode();
end;
procedure TFViewAddCustomer.HideNotification;
begin
pnlMessage.ElementHandle.hidden := True;
end;
procedure TFViewAddCustomer.memoAddressBlockChange(Sender: TObject);
begin
EditMode();
end;
procedure TFViewAddCustomer.ShowNotification(Notification: string);
var
splitNotification: TArray<string>;
begin
if Notification <> '' then
begin
splitNotification := Notification.Split([':']);
if(splitNotification[0] = 'Success') then
begin
asm
var messageDiv = document.getElementById('view.login.message');
messageDiv.classList.remove('alert-danger');
messageDiv.classList.add('alert-success');
end;
end
else
begin
asm
var messageDiv = document.getElementById('view.login.message');
messageDiv.classList.remove('alert-success');
messageDiv.classList.add('alert-danger');
end;
end;
lblMessage.Caption := splitNotification[1];
pnlMessage.ElementHandle.hidden := False;
end;
end;
procedure TFViewAddCustomer.tmrReturnTimer(Sender: TObject);
// Timer to returnto the customer page because it takes slightly too long to
// Delete customers causing ghost customers to show up.
begin
asm
endSpinner();
end;
tmrReturn.Enabled := false;
FViewMain.ViewCustomerList('Success:Customer Successfully Deleted');
end;
function TFViewAddCustomer.VerifyCustomer(): boolean;
var
input: TJSHTMLElement;
begin
result := true;
// Company Verification
input := TJSHTMLInputElement(document.getElementById('edtcompanyname'));
if edtName.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtcompanyaccountname'));
if edtShortName.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
// Billing Information Verification
input := TJSHTMLInputElement(document.getElementById('edtbillingaddress'));
if edtBillAddress.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtbillingcity'));
if edtBillCity.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtbillingstate'));
if edtBillState.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtbillingzip'));
if edtBillZip.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtbillingcontact'));
if edtBillContact.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
end;
function TFViewAddCustomer.VerifyAddress: Boolean;
// Verifies all the shipping information is filled in.
var
input: TJSHTMLElement;
begin
result := true;
input := TJSHTMLInputElement(document.getElementById('edtshippingaddress'));
if edtShippingAddress.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtshippingcity'));
if edtShippingCity.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtshippingstate'));
if edtShippingState.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtshippingzip'));
if edtShippingZip.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtshippingcontact'));
if edtShippingContact.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
input := TJSHTMLInputElement(document.getElementById('edtfirstline'));
if edtFirstLine.Text = '' then
begin
input.classList.add('is-invalid');
result := false;
end
else
input.classList.remove('is-invalid');
end;
end.
\ No newline at end of file
object FViewAddAddress: TFViewAddAddress
Width = 281
Height = 402
object WebLabel1: TWebLabel
Left = 8
Top = 283
Width = 92
Height = 15
Caption = 'Shipping Contact'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel2: TWebLabel
Left = 8
Top = 234
Width = 67
Height = 15
Caption = 'Shipping Zip'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel3: TWebLabel
Left = 8
Top = 136
Width = 71
Height = 15
Caption = 'Shipping City'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel4: TWebLabel
Left = 8
Top = 185
Width = 76
Height = 15
Caption = 'Shipping State'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel5: TWebLabel
Left = 8
Top = 87
Width = 92
Height = 15
Caption = 'Shipping Address'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel6: TWebLabel
Left = 8
Top = 36
Width = 47
Height = 15
Caption = 'First Line'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtState: TWebEdit
Left = 8
Top = 206
Width = 78
Height = 22
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtFirstLine: TWebEdit
Left = 8
Top = 59
Width = 198
Height = 22
ChildOrder = 1
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtCity: TWebEdit
Left = 8
Top = 157
Width = 149
Height = 22
ChildOrder = 2
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtZip: TWebEdit
Left = 8
Top = 255
Width = 121
Height = 22
ChildOrder = 3
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtContact: TWebEdit
Left = 8
Top = 304
Width = 198
Height = 22
ChildOrder = 4
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtAddress: TWebEdit
Left = 8
Top = 108
Width = 198
Height = 22
ChildOrder = 1
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtNotification: TWebEdit
Left = 8
Top = 8
Width = 198
Height = 22
ChildOrder = 12
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object btnSave: TWebButton
Left = 8
Top = 340
Width = 96
Height = 25
Caption = 'Save'
ChildOrder = 13
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnSaveClick
end
object btnCancel: TWebButton
Left = 110
Top = 340
Width = 96
Height = 25
Caption = 'Cancel'
ChildOrder = 13
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
end
end
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>TMS Web Project</title>
<style>
</style>
</head>
<body>
</body>
</html>
\ No newline at end of file
// Small Pop-Up page when adding orders if you want to quickly add an address
unit View.AddAddress;
interface
uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls;
type
TFViewAddAddress = class(TWebForm)
edtState: TWebEdit;
edtFirstLine: TWebEdit;
edtCity: TWebEdit;
edtZip: TWebEdit;
edtContact: TWebEdit;
edtAddress: TWebEdit;
WebLabel1: TWebLabel;
WebLabel2: TWebLabel;
WebLabel3: TWebLabel;
WebLabel4: TWebLabel;
WebLabel5: TWebLabel;
WebLabel6: TWebLabel;
edtNotification: TWebEdit;
btnSave: TWebButton;
btnCancel: TWebButton;
procedure btnCancelClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
private
{ Private declarations }
function Verify(): boolean;
public
{ Public declarations }
var
confirm: boolean;
end;
var
FViewAddAddress: TFViewAddAddress;
implementation
{$R *.dfm}
procedure TFViewAddAddress.btnSaveClick(Sender: TObject);
begin
if Verify() then
begin
confirm := true;
Close;
end;
end;
function TFViewAddAddress.Verify(): boolean;
// Makes sure the address is filled in.
begin
result := true;
if edtFirstLine.Text = '' then
begin
edtNotification.Text := 'Please Fill in the First Line';
result := false;
end
else if edtAddress.Text = '' then
begin
edtNotification.Text := 'Please Fill in the Address';
result := false;
end
else if edtCity.Text = '' then
begin
edtNotification.Text := 'Please Fill in the City';
result := false;
end
else
if edtState.Text = '' then
begin
edtNotification.Text := 'Please Fill in the State';
result := false;
end
else if edtZip.Text = '' then
begin
edtNotification.Text := 'Please Fill in the Zip Code';
result := false;
end
else if edtContact.Text = '' then
begin
edtNotification.Text := 'Please Fill in the Contact';
result := false;
end
end;
procedure TFViewAddAddress.btnCancelClick(Sender: TObject);
begin
Close;
end;
end.
\ No newline at end of file
...@@ -5,18 +5,27 @@ object FAddOrder: TFAddOrder ...@@ -5,18 +5,27 @@ object FAddOrder: TFAddOrder
object WebLabel1: TWebLabel object WebLabel1: TWebLabel
Left = 4 Left = 4
Top = 81 Top = 81
Width = 35 Width = 95
Height = 15 Height = 15
Caption = 'Search' Caption = 'Search Customers'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object WebLabel2: TWebLabel object WebLabel2: TWebLabel
Left = 143 Left = 135
Top = 81 Top = 81
Width = 113 Width = 113
Height = 15 Height = 15
Caption = 'Selected Company ID' Caption = 'Selected Customer ID'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel3: TWebLabel
Left = 283
Top = 81
Width = 134
Height = 15
Caption = 'Selected Customer Name'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
...@@ -30,7 +39,7 @@ object FAddOrder: TFAddOrder ...@@ -30,7 +39,7 @@ object FAddOrder: TFAddOrder
OnChange = edtSearchChange OnChange = edtSearchChange
end end
object edtID: TWebEdit object edtID: TWebEdit
Left = 143 Left = 135
Top = 102 Top = 102
Width = 142 Width = 142
Height = 22 Height = 22
...@@ -74,7 +83,7 @@ object FAddOrder: TFAddOrder ...@@ -74,7 +83,7 @@ object FAddOrder: TFAddOrder
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 70.000000000000000000 Width = 90.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -119,7 +128,7 @@ object FAddOrder: TFAddOrder ...@@ -119,7 +128,7 @@ object FAddOrder: TFAddOrder
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 382.000000000000000000 Width = 362.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -220,8 +229,8 @@ object FAddOrder: TFAddOrder ...@@ -220,8 +229,8 @@ object FAddOrder: TFAddOrder
OnClick = cbWebPlateClick OnClick = cbWebPlateClick
end end
object btnCancel: TWebButton object btnCancel: TWebButton
Left = 436 Left = 542
Top = 105 Top = 101
Width = 96 Width = 96
Height = 25 Height = 25
Caption = 'Cancel' Caption = 'Cancel'
...@@ -231,8 +240,8 @@ object FAddOrder: TFAddOrder ...@@ -231,8 +240,8 @@ object FAddOrder: TFAddOrder
OnClick = btnCancelClick OnClick = btnCancelClick
end end
object btnConfirm: TWebButton object btnConfirm: TWebButton
Left = 328 Left = 436
Top = 105 Top = 101
Width = 96 Width = 96
Height = 25 Height = 25
Caption = 'Select' Caption = 'Select'
...@@ -273,6 +282,16 @@ object FAddOrder: TFAddOrder ...@@ -273,6 +282,16 @@ object FAddOrder: TFAddOrder
TabOrder = 1 TabOrder = 1
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object edtName: TWebEdit
Left = 283
Top = 102
Width = 142
Height = 22
ChildOrder = 1
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object XDataWebClient1: TXDataWebClient object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 780 Left = 780
...@@ -282,9 +301,6 @@ object FAddOrder: TFAddOrder ...@@ -282,9 +301,6 @@ object FAddOrder: TFAddOrder
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 726 Left = 726
Top = 7 Top = 7
object xdwdsCustomersID: TIntegerField
FieldName = 'ID'
end
object xdwdsCustomersNAME: TStringField object xdwdsCustomersNAME: TStringField
FieldName = 'NAME' FieldName = 'NAME'
end end
...@@ -294,6 +310,9 @@ object FAddOrder: TFAddOrder ...@@ -294,6 +310,9 @@ object FAddOrder: TFAddOrder
object xdwdsCustomersstaff_fields_invoice_to: TStringField object xdwdsCustomersstaff_fields_invoice_to: TStringField
FieldName = 'staff_fields_invoice_to' FieldName = 'staff_fields_invoice_to'
end end
object xdwdsCustomersCUSTOMER_ID: TIntegerField
FieldName = 'CUSTOMER_ID'
end
end end
object wdsCustomers: TWebDataSource object wdsCustomers: TWebDataSource
DataSet = xdwdsCustomers DataSet = xdwdsCustomers
......
...@@ -26,13 +26,15 @@ type ...@@ -26,13 +26,15 @@ type
WebLabel2: TWebLabel; WebLabel2: TWebLabel;
XDataWebClient1: TXDataWebClient; XDataWebClient1: TXDataWebClient;
xdwdsCustomers: TXDataWebDataSet; xdwdsCustomers: TXDataWebDataSet;
xdwdsCustomersID: TIntegerField;
xdwdsCustomersNAME: TStringField; xdwdsCustomersNAME: TStringField;
xdwdsCustomersSHORT_NAME: TStringField; xdwdsCustomersSHORT_NAME: TStringField;
wdsCustomers: TWebDataSource; wdsCustomers: TWebDataSource;
cbCuttingDie: TWebCheckBox; cbCuttingDie: TWebCheckBox;
edtNotification: TWebEdit; edtNotification: TWebEdit;
xdwdsCustomersstaff_fields_invoice_to: TStringField; xdwdsCustomersstaff_fields_invoice_to: TStringField;
xdwdsCustomersCUSTOMER_ID: TIntegerField;
WebLabel3: TWebLabel;
edtName: TWebEdit;
procedure WebFormShow(Sender: TObject); procedure WebFormShow(Sender: TObject);
procedure edtSearchChange(Sender: TObject); procedure edtSearchChange(Sender: TObject);
procedure cbCorrugatedPlateClick(Sender: TObject); procedure cbCorrugatedPlateClick(Sender: TObject);
...@@ -154,9 +156,9 @@ begin ...@@ -154,9 +156,9 @@ begin
// Set up column headers // Set up column headers
TMSFNCGrid1.ColumnCount := 4; TMSFNCGrid1.ColumnCount := 4;
TMSFNCGrid1.RowCount := 1; TMSFNCGrid1.RowCount := 1;
TMSFNCGrid1.Cells[0, 0] := 'DBID'; TMSFNCGrid1.Cells[0, 0] := 'Customer Num';
TMSFNCGrid1.Cells[1, 0] := 'ID'; TMSFNCGrid1.Cells[1, 0] := 'Customer ID';
TMSFNCGrid1.Cells[2, 0] := 'Name'; TMSFNCGrid1.Cells[2, 0] := 'Customer Name';
TMSFNCGrid1.Cells[3, 0] := 'Address'; TMSFNCGrid1.Cells[3, 0] := 'Address';
// Populate the grid with data from the dataset // Populate the grid with data from the dataset
...@@ -166,7 +168,7 @@ begin ...@@ -166,7 +168,7 @@ begin
while not xdwdsCustomers.EOF do while not xdwdsCustomers.EOF do
begin begin
TMSFNCGrid1.RowCount := RowIndex + 1; TMSFNCGrid1.RowCount := RowIndex + 1;
TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('ID').AsString; TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('CUSTOMER_ID').AsString;
TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString; TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString; TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString;
TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('staff_fields_invoice_to').AsString; TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('staff_fields_invoice_to').AsString;
...@@ -185,6 +187,7 @@ end; ...@@ -185,6 +187,7 @@ end;
procedure TFAddOrder.TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer); procedure TFAddOrder.TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
begin begin
edtID.Text := TMSFNCGrid1.Cells[1, ARow]; edtID.Text := TMSFNCGrid1.Cells[1, ARow];
edtName.Text := TMSFNCGrid1.Cells[2, ARow];
DBID := TMSFNCGrid1.Cells[0, ARow]; DBID := TMSFNCGrid1.Cells[0, ARow];
end; end;
......
unit View.AddOrder2;
interface
uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, WEBLib.StdCtrls, XData.Web.Client, WEBLib.ExtCtrls,
Data.DB, XData.Web.Dataset, VCL.TMSFNCTypes, VCL.TMSFNCGrid, VCL.TMSFNCGridData,
VCL.TMSFNCUtils, VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes,
VCL.TMSFNCGridCell, VCL.TMSFNCGridOptions, VCL.TMSFNCCustomComponent,
VCL.TMSFNCCustomGrid, VCL.TMSFNCGridDatabaseAdapter, VCL.TMSFNCCustomControl,
VCL.TMSFNCCustomScrollControl, WEBLib.DB, XData.Web.JsonDataset, Vcl.StdCtrls,
Vcl.Controls, ConnectionModule;
type
TFAddOrder = class(TWebForm)
edtSearch: TWebEdit;
edtID: TWebEdit;
btnCancel: TWebButton;
XDataWebClient1: TXDataWebClient;
wdsCustomers: TWebDataSource;
xdwdsCustomers: TXDataWebDataSet;
xdwdsCustomersID: TIntegerField;
xdwdsCustomersNAME: TStringField;
xdwdsCustomersSHORT_NAME: TStringField;
btnConfirm: TWebButton;
cbCorrugatedPlate: TWebCheckBox;
cbWebPlate: TWebCheckBox;
TMSFNCGrid1: TTMSFNCGrid;
procedure WebFormShow(Sender: TObject);
procedure cbCorrugatedPlateClick(Sender: TObject);
procedure cbWebPlateClick(Sender: TObject);
procedure btnConfirmClick(Sender: TObject);
procedure edtSearchChange(Sender: TObject);
procedure btnCancelClick(Sender: TObject);
procedure TMSFNCGrid1SelectedCell(Sender: TObject; ACol, ARow: Integer);
private
[async] procedure getCustomers();
procedure PopulateGridManually;
procedure ApplyFilter;
public
end;
var
FAddOrder: TFAddOrder;
implementation
{$R *.dfm}
procedure TFAddOrder.WebFormShow(Sender: TObject);
begin
getCustomers(); // Fetch and populate the grid with customer data
end;
[async]
procedure TFAddOrder.getCustomers();
var
xdcResponse: TXDataClientResponse;
customerList: TJSObject;
begin
// Fetch data from XData service
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', []));
customerList := TJSObject(xdcResponse.Result);
// Load data into TXDataWebDataset
xdwdsCustomers.Close;
xdwdsCustomers.SetJsonData(customerList['data']);
xdwdsCustomers.Open;
// Manually populate the grid
PopulateGridManually;
end;
procedure TFAddOrder.PopulateGridManually;
var
RowIndex: Integer;
begin
TMSFNCGrid1.BeginUpdate;
try
TMSFNCGrid1.Clear; // Clear any existing data
// Set up column headers
TMSFNCGrid1.ColumnCount := 4;
TMSFNCGrid1.RowCount := 1;
TMSFNCGrid1.Cells[0, 0] := 'ID';
TMSFNCGrid1.Cells[1, 0] := 'Short Name';
TMSFNCGrid1.Cells[2, 0] := 'Name';
// TMSFNCGrid1.ColumnWidths[0] := 40;
// TMSFNCGrid1.ColumnWidths[1] := 80;
// TMSFNCGrid1.ColumnWidths[2] := 250;
// Populate the grid with data from the dataset
xdwdsCustomers.First;
RowIndex := 1;
while not xdwdsCustomers.EOF do
begin
TMSFNCGrid1.RowCount := RowIndex + 1;
TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('ID').AsString;
TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString;
Inc(RowIndex);
xdwdsCustomers.Next;
end;
finally
TMSFNCGrid1.EndUpdate;
end;
end;
procedure TFAddOrder.TMSFNCGrid1SelectedCell(Sender: TObject; ACol,
ARow: Integer);
begin
edtID.Text := TMSFNCGrid1.Cells[0, ARow];
end;
procedure TFAddOrder.ApplyFilter;
var
fd: TTMSFNCGridFilterData;
i: Integer;
SearchText: string;
begin
SearchText := Trim(edtSearch.Text);
TMSFNCGrid1.RemoveFilter;
TMSFNCGrid1.Filter.Clear;
// match on first 3 columns
for i := 0 to 2 do
begin
fd := TMSFNCGrid1.Filter.Add;
fd.Column := i;
fd.Condition := '*' + SearchText + '*'; // Match text anywhere in the cell
fd.CaseSensitive := False; // Make the filter case-insensitive
// Use foOR for "match any column" logic
if i > 0 then
fd.Operation := foOR
else
fd.Operation := foNONE; // First filter has no logical operation
end;
// Apply the filters to the grid
TMSFNCGrid1.ApplyFilter;
end;
procedure TFAddOrder.cbCorrugatedPlateClick(Sender: TObject);
begin
cbWebPlate.Checked := False;
end;
procedure TFAddOrder.cbWebPlateClick(Sender: TObject);
begin
cbCorrugatedPlate.Checked := False;
end;
procedure TFAddOrder.btnConfirmClick(Sender: TObject);
begin
Close;
end;
procedure TFAddOrder.btnCancelClick(Sender: TObject);
begin
edtID.Text := '';
Close;
end;
procedure TFAddOrder.edtSearchChange(Sender: TObject);
begin
ApplyFilter;
end;
end.
//unit View.AddOrder;
//
//interface
//
//uses
// System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
// WEBLib.Forms, WEBLib.Dialogs, WEBLib.StdCtrls, XData.Web.Client, WEBLib.ExtCtrls,
// Data.DB, XData.Web.Dataset, VCL.TMSFNCTypes, VCL.TMSFNCGrid, VCL.TMSFNCGridData,
// VCL.TMSFNCUtils, VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes,
// VCL.TMSFNCGridCell, VCL.TMSFNCGridOptions, VCL.TMSFNCCustomComponent,
// VCL.TMSFNCCustomGrid, VCL.TMSFNCGridDatabaseAdapter, VCL.TMSFNCCustomControl,
// VCL.TMSFNCCustomScrollControl, WEBLib.DB, XData.Web.JsonDataset, Vcl.StdCtrls,
// Vcl.Controls, ConnectionModule, WEBLib.WebCtrls;
//
//type
// TFAddOrder = class(TWebForm)
// XDataWebClient1: TXDataWebClient;
// wdsCustomers: TWebDataSource;
// xdwdsCustomers: TXDataWebDataSet;
// xdwdsCustomersID: TIntegerField;
// xdwdsCustomersNAME: TStringField;
// xdwdsCustomersSHORT_NAME: TStringField;
// xdwdsCustomersADDRESS: TStringField;
// cbWebPlate: TWebCheckBox;
// cbCorrugatedPlate: TWebCheckBox;
// edtSearch: TWebEdit;
// edtID: TWebEdit;
// btnConfirm: TWebButton;
// btnCancel: TWebButton;
// TMSFNCGrid1: TTMSFNCGrid;
// procedure cbCorrugatedPlateClick(Sender: TObject);
// procedure cbWebPlateClick(Sender: TObject);
// procedure btnConfirmClick(Sender: TObject);
// procedure btnCancelClick(Sender: TObject);
// procedure TMSFNCGrid1SelectedCell(Sender: TObject; ACol, ARow: Integer);
// procedure edtSearchChange(Sender: TObject);
// private
// [async] procedure GetCustomers();
// procedure PopulateGridManually;
// procedure ApplyFilter;
// public
// class function CreateForm(AElementID: string): TWebForm;
// end;
//
//var
// FAddOrder: TFAddOrder;
//
//implementation
//
//{$R *.dfm}
//
//
//class function TFAddOrder.CreateForm(AElementID: string): TWebForm;
//begin
// Application.CreateForm(TFAddOrder, AElementID, Result,
// procedure(AForm: TObject)
// begin
// with TFAddOrder(AForm) do
// begin
// GetCustomers();
// Console.Log('AddOrder form created and dynamic styles applied.');
// end;
// end
// );
//end;
//
//
//
//procedure TFAddOrder.edtSearchChange(Sender: TObject);
//begin
// ApplyFilter;
//end;
//
//
//[async] procedure TFAddOrder.GetCustomers();
//var
// xdcResponse: TXDataClientResponse;
// customerList: TJSObject;
//begin
// // Fetch data from XData service
// xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', []));
// customerList := TJSObject(xdcResponse.Result);
//
// // Load data into TXDataWebDataset
// xdwdsCustomers.Close;
// xdwdsCustomers.SetJsonData(customerList['data']);
// xdwdsCustomers.Open;
//
// // Manually populate the grid
// PopulateGridManually;
//end;
//
//
//procedure TFAddOrder.PopulateGridManually;
//var
// RowIndex: Integer;
//begin
// TMSFNCGrid1.BeginUpdate;
// try
// TMSFNCGrid1.Clear; // Clear any existing data
//
// // Set up column headers
// TMSFNCGrid1.ColumnCount := 3;
// TMSFNCGrid1.RowCount := 1;
// TMSFNCGrid1.Cells[0, 0] := 'ID';
// TMSFNCGrid1.Cells[1, 0] := 'Short Name';
// TMSFNCGrid1.Cells[2, 0] := 'Name';
//
//// TMSFNCGrid1.ColumnWidths[0] := 40;
//// TMSFNCGrid1.ColumnWidths[1] := 80;
//// TMSFNCGrid1.ColumnWidths[2] := 250;
//
// // Populate the grid with data from the dataset
// xdwdsCustomers.First;
// RowIndex := 1;
//
// while not xdwdsCustomers.EOF do
// begin
// TMSFNCGrid1.RowCount := RowIndex + 1;
//
// TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('ID').AsString;
// TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
// TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString;
//
// Inc(RowIndex);
// xdwdsCustomers.Next;
// end;
//
// finally
// TMSFNCGrid1.EndUpdate;
// end;
//end;
//
//
//procedure TFAddOrder.TMSFNCGrid1SelectedCell(Sender: TObject; ACol,
// ARow: Integer);
//begin
// edtID.Text := TMSFNCGrid1.Cells[0, ARow];
//end;
//
//
//procedure TFAddOrder.ApplyFilter;
//var
// fd: TTMSFNCGridFilterData;
// i: Integer;
// SearchText: string;
//begin
// SearchText := Trim(edtSearch.Text);
// Console.Log('Filter Applied: ' + SearchText);
//
// TMSFNCGrid1.RemoveFilter;
// TMSFNCGrid1.Filter.Clear;
//
// for i := 0 to 2 do
// begin
// fd := TMSFNCGrid1.Filter.Add;
// fd.Column := i;
// fd.Condition := '*' + SearchText + '*'; // Match text anywhere in the cell
// fd.CaseSensitive := False;
//
// if i > 0 then
// fd.Operation := foOR
// else
// fd.Operation := foNONE;
// end;
//
// TMSFNCGrid1.ApplyFilter;
//end;
//
//
//procedure TFAddOrder.cbCorrugatedPlateClick(Sender: TObject);
//begin
// cbWebPlate.Checked := False;
//end;
//
//
//procedure TFAddOrder.cbWebPlateClick(Sender: TObject);
//begin
// cbCorrugatedPlate.Checked := False;
//end;
//
//procedure TFAddOrder.btnConfirmClick(Sender: TObject);
//begin
// edtID.Text := '';
// window.location.reload(true);
//end;
//
//
//procedure TFAddOrder.btnCancelClick(Sender: TObject);
//var
// OrdersPanel: TJSHTMLElement;
//begin
// edtID.Text := '';
//
// // Get the panel element by its ID
// OrdersPanel := TJSHTMLElement(document.getElementById('pnl_orders'));
//
// // Hide the panel
// if Assigned(OrdersPanel) then
// begin
// OrdersPanel.style.setProperty('display', 'none');
//
// // Remove all child nodes of the container to clear the DOM
// while OrdersPanel.firstChild <> nil do
// OrdersPanel.removeChild(OrdersPanel.firstChild);
// end;
//
// // Free the current form instance to clean up resources
// Free;
//
// Console.Log('Panel hidden, DOM cleared, and form instance destroyed.');
//end;
//
//
//
//
//
//end.
object FViewCustomers: TFViewCustomers
Width = 640
Height = 480
OnCreate = WebFormCreate
object lblEntries: TWebLabel
Left = 12
Top = 117
Width = 81
Height = 15
Caption = 'Showing 0 of ...'
ElementID = 'lblentries'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object btnAddCustomer: TWebButton
Left = 12
Top = 81
Width = 96
Height = 25
Caption = 'Add Customer'
ChildOrder = 5
ElementID = 'btnaddcustomer'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
TabOrder = 6
TabStop = False
WidthPercent = 100.000000000000000000
OnClick = btnAddCustomerClick
end
object wcbPageSize: TWebComboBox
Left = 22
Top = 52
Width = 145
Height = 23
ElementClassName = 'custom-select'
ElementID = 'wcbpagesize'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
Text = '500'
WidthPercent = 100.000000000000000000
ItemIndex = -1
Items.Strings = (
'100'
'250'
'500'
'1000')
end
object pnlMessage: TWebPanel
Left = 12
Top = 16
Width = 121
Height = 33
ElementID = 'view.login.message'
ChildOrder = 17
TabOrder = 2
object lblMessage: TWebLabel
Left = 16
Top = 11
Width = 46
Height = 15
Caption = 'Message'
ElementID = 'view.login.message.label'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object btnCloseNotification: TWebButton
Left = 96
Top = 3
Width = 22
Height = 25
ChildOrder = 1
ElementID = 'view.login.message.button'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
end
object wdbtcCustomers: TWebDBTableControl
Left = 8
Top = 202
Width = 631
Height = 200
ElementClassName = 'table'
ElementId = 'tblPhoneGrid'
BorderColor = clSilver
ChildOrder = 11
ElementFont = efCSS
ElementHeaderClassName = 'thead-light sticky-top bg-light'
ElementPosition = epRelative
ElementTableClassName = 'table table-striped table-hover table-bordered text-sm'
Footer.ButtonActiveElementClassName = 'btn btn-primary'
Footer.ButtonElementClassName = 'btn btn-light'
Footer.DropDownElementClassName = 'form-control'
Footer.InputElementClassName = 'form-control'
Footer.LinkActiveElementClassName = 'link-primary'
Footer.LinkElementClassName = 'link-secondary'
Footer.ListElementClassName = 'pagination'
Footer.ListItemElementClassName = 'page-item'
Footer.ListLinkElementClassName = 'page-link'
Header.ButtonActiveElementClassName = 'btn btn-primary'
Header.ButtonElementClassName = 'btn btn-light'
Header.DropDownElementClassName = 'form-control'
Header.InputElementClassName = 'form-control'
Header.LinkActiveElementClassName = 'link-primary'
Header.LinkElementClassName = 'link-secondary'
Header.ListElementClassName = 'pagination'
Header.ListItemElementClassName = 'page-item'
Header.ListLinkElementClassName = 'page-link'
WordWrap = True
OnDblClickCell = wdbtcCustomersDblClickCell
Columns = <
item
DataField = 'CUSTOMER_ID'
Title = 'Customer Num'
end
item
DataField = 'SHORT_NAME'
Title = 'Customer ID'
end
item
DataField = 'NAME'
Title = 'Customer Name'
end
item
DataField = 'START_DATE'
Title = 'Start Date'
end>
DataSource = wdsCustomers
end
object edtFilter: TWebEdit
Left = 246
Top = 20
Width = 121
Height = 22
ChildOrder = 5
ElementID = 'edtfilter'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnChange = edtFilterChange
end
object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 158
Top = 90
end
object wdsCustomers: TWebDataSource
DataSet = xdwdsCustomers
Left = 262
Top = 116
end
object xdwdsCustomers: TXDataWebDataSet
Connection = DMConnection.ApiConnection
Left = 346
Top = 92
object xdwdsCustomersSHORT_NAME: TStringField
FieldName = 'SHORT_NAME'
Size = 0
end
object xdwdsCustomersNAME: TStringField
FieldName = 'NAME'
end
object xdwdsCustomersSTART_DATE: TStringField
FieldName = 'START_DATE'
end
object xdwdsCustomersCUSTOMER_ID: TIntegerField
FieldName = 'CUSTOMER_ID'
end
end
end
<div class="container h-100 d-flex flex-column mt-0" style="max-width: 100%; padding-bottom: 0;">
<!-- Alert Section -->
<div class="row">
<div class=col-sm>
<div id="view.login.message" class="alert alert-danger">
<button id="view.login.message.button" type="button" class="btn-close" aria-label="Close"></button>
<span id="view.login.message.label"></span>
</div>
</div>
</div>
<!-- Actions Row -->
<div class="row mt-3 justify-content-center align-items-end">
<div class="col-auto">
<label for="wcbpagesize" class="form-label fw-bold" style="font-size: 1.1rem;">
Show
<select class="form-select d-inline-block w-auto" id="wcbpagesize" style="font-size: 1rem;"></select>
entries
</label>
</div>
<div class="col-auto">
<button id="btnaddcustomer" class="btn btn-secondary">Add Customer</button>
</div>
<div class="col-auto">
<label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer ID:</label>
<input id="edtfilter" type="text" class="form-control" style="width: 200px;" />
</div>
</div>
<!-- Entries Label Section d-flex justify-content-between w-100 mt-2-->
<div class="row">
<div class="col-auto">
<label id="lblentries" style="font-size: 1.10rem;"></label>
</div>
</div>
<!-- Table Section -->
<div id="order_table_section" class="overflow-auto mt-2"
style="max-height: calc(100vh - 250px); padding-bottom: 0; width: 100%;">
<table id="tblPhoneGrid" class="table table-striped table-bordered" style="width: 100%;">
<thead class="sticky-top thead-light">
<tr style="font-size: 0.875rem;">
<!-- Table headers are dynamically generated -->
</tr>
</thead>
<tbody id="orderTableBody" class="align-middle">
<!-- Table rows are dynamically generated -->
</tbody>
</table>
</div>
<!-- Pagination Section -->
<div class="d-flex justify-content-center w-100 mt-4">
<nav aria-label="Page navigation">
<ul id="pagination" class="pagination">
<!-- Pagination items added dynamically -->
</ul>
</nav>
</div>
</div>
// Customer Form accessed from the ccustomer header in the main form.
unit View.Customers;
interface
uses
System.SysUtils, System.Generics.Collections, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
XData.Web.JsonDataset, WEBLib.DB, Data.DB, XData.Web.Dataset,
WEBLib.Grids, VCL.TMSFNCTypes, VCL.TMSFNCUtils, VCL.TMSFNCGraphics,
VCL.TMSFNCGraphicsTypes, VCL.TMSFNCGridCell, VCL.TMSFNCGridOptions,
VCL.TMSFNCCustomControl, VCL.TMSFNCCustomScrollControl, VCL.TMSFNCGridData,
VCL.TMSFNCCustomGrid, VCL.TMSFNCGrid;
type
TFViewCustomers = class(TWebForm)
btnAddCustomer: TWebButton;
wcbPageSize: TWebComboBox;
pnlMessage: TWebPanel;
lblMessage: TWebLabel;
btnCloseNotification: TWebButton;
XDataWebClient1: TXDataWebClient;
wdsCustomers: TWebDataSource;
xdwdsCustomers: TXDataWebDataSet;
xdwdsCustomersNAME: TStringField;
xdwdsCustomersSTART_DATE: TStringField;
xdwdsCustomersSHORT_NAME: TStringField;
xdwdsCustomersCUSTOMER_ID: TIntegerField;
wdbtcCustomers: TWebDBTableControl;
edtFilter: TWebEdit;
lblEntries: TWebLabel;
procedure WebFormCreate(Sender: TObject);
procedure btnAddCustomerClick(Sender: TObject);
procedure wdbtcCustomersDblClickCell(Sender: TObject; ACol, ARow: Integer);
procedure edtFilterChange(Sender: TObject);
private
{ Private declarations }
procedure GeneratePagination(TotalPages: Integer);
[async] procedure GetCustomers(searchOptions: string);
function GenerateSearchOptions(): string;
procedure HideNotification();
procedure ShowNotification(Notification: string);
procedure ShowSelectCustomerForm();
var
PageNumber: integer;
PageSize: integer;
TotalPages: integer;
info: string;
public
{ Public declarations }
end;
var
FViewCustomers: TFViewCustomers;
implementation
uses
XData.Model.Classes, View.Main, View.SelectCustomer;
{$R *.dfm}
procedure TFViewCustomers.ShowSelectCustomerForm();
// displays the add order pop-up so the user can choose a customer
var
newform: TFSelectCustomer;
begin
newform := TFSelectCustomer.CreateNew;
newform.Caption := 'Select Customer and Order Type';
newForm.Popup := True;
newForm.Border := fbDialog;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
begin
{if newform.confirm then
begin
if newform.cbCorrugatedPlate.Checked then
orderType := 'corrugated'
else if newform.cbWebPlate.Checked then
orderType := 'web'
else
orderType := 'cutting';
orderEntry('', newForm.DBID, 'ADD', orderType);
end; }
end
);
end;
Procedure TFViewCustomers.WebFormCreate(Sender: TObject);
// Initializes important values:
// 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;
TotalPages := 1; // Initial total pages
wcbPageSize.Text := '500';
PageSize := 500;
HideNotification();
getCustomers(GenerateSearchOptions());
end;
procedure TFViewCustomers.GetCustomers(searchOptions: string);
// retrieves a list of Customers that fit a given search criteria
// searchOptions: search info to be sent to the server
var
xdcResponse: TXDataClientResponse;
customerList: TJSObject;
customerListLength: integer;
TotalPages: integer;
begin
if PageNumber > 0 then
begin
asm
startSpinner();
end;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetCustomers', [searchOptions]));
customerList := TJSObject(xdcResponse.Result);
// Load data into the dataset
xdwdsCustomers.Close;
xdwdsCustomers.SetJsonData(customerList['data']);
xdwdsCustomers.Open;
asm
endSpinner();
end;
customerListLength := integer(customerList['count']);
TotalPages := ( (customerListLength + PageSize - 1) div PageSize);
if customerListLength = 0 then
begin
lblEntries.Caption := 'No entries found';
end
else if (PageNumber * PageSize) < customerListLength then
// Currently these do the same thing. If you want to limit the number of entries
// You will need to edit the server side, and then change this if statement so the label
// Correctly displayes. I believe it is IntToStr(PageSize * PageNum)
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(customerListLength) +
' of ' + IntToStr(customerListLength);
end
else if (PageNumber * PageSize) >= customerListLength then
begin
lblEntries.Caption := 'Showing entries ' + IntToStr((PageNumber - 1) * PageSize + 1) +
' - ' + IntToStr(customerListLength) +
' of ' + IntToStr(customerListLength);
end;
end;
end;
function TFViewCustomers.GenerateSearchOptions(): string;
// Generates searchOptions for GetOrders.
var
searchOptions: string;
begin
searchOptions := '&pagenumber=' + IntToStr(PageNumber) +
'&pagesize=' + IntToStr(PageSize);
Result := searchOptions;
end;
procedure TFViewCustomers.HideNotification;
begin
pnlMessage.ElementHandle.hidden := True;
info := '';
end;
procedure TFViewCustomers.ShowNotification(Notification: string);
var
splitNotification: TArray<string>;
begin
if Notification <> '' then
begin
splitNotification := Notification.Split([':']);
if(splitNotification[0] = 'Success') then
begin
asm
var messageDiv = document.getElementById('view.login.message');
messageDiv.classList.remove('alert-danger');
messageDiv.classList.add('alert-success');
end;
end
else
begin
asm
var messageDiv = document.getElementById('view.login.message');
messageDiv.classList.remove('alert-success');
messageDiv.classList.add('alert-danger');
end;
end;
lblMessage.Caption := splitNotification[1];
pnlMessage.ElementHandle.hidden := False;
end;
end;
procedure TFViewCustomers.wdbtcCustomersDblClickCell(Sender: TObject; ACol,
ARow: Integer);
begin
FViewMain.ViewAddCustomer(wdbtcCustomers.Cells[0, ARow], '') ;
end;
procedure TFViewCustomers.btnAddCustomerClick(Sender: TObject);
begin
ShowSelectCustomerForm();
end;
procedure TFViewCustomers.edtFilterChange(Sender: TObject);
begin
xdwdsCustomers.Filter := 'SHORT_NAME LIKE ' + quotedStr('%' + edtFilter.Text + '%');
xdwdsCustomers.Filtered := true;
end;
procedure TFViewCustomers.GeneratePagination(TotalPages: Integer);
// Generates pagination for the table.
// TotalPages: Total amount of pages generated by the search
// This could definitely be improved.
var
PaginationElement, PageItem, PageLink: TJSHTMLElement;
I, Start, Finish: Integer;
begin
PaginationElement := TJSHTMLElement(document.getElementById('pagination'));
PaginationElement.innerHTML := ''; // Clear existing pagination
// Previous Button
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if PageNumber = 1 then
PageItem.classList.add('disabled');
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := 'Previous';
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
begin
if PageNumber > 1 then
begin
Dec(PageNumber);
GetCustomers(GenerateSearchOptions());
end;
end);
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
// Page Numbers
if TotalPages <= 7 then
begin
for I := 1 to 7 do
begin
if I <= TotalPages then
begin
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if I = PageNumber then
PageItem.classList.add('selected-number'); // Add the selected-number class
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := IntToStr(I);
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
var
PageNum: Integer;
begin
PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
PageNumber := PageNum;
GetCustomers(GenerateSearchOptions());
end);
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
end;
end
else
begin
if PageNumber <= 4 then
// If page number is low enough no early elipsis needed
Begin
Start := 2;
Finish := 5;
End
else if (PageNumber >= (TotalPages - 3)) then
// If page number is high enough no late elipsis needed
begin
Start := TotalPages - 3;
Finish := TotalPages - 1;
end
else
begin
Start := PageNumber - 1;
Finish := PageNumber + 1;
end;
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if 1 = PageNumber then
PageItem.classList.add('selected-number'); // Add the selected-number class
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := '1';
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
var
PageNum: Integer;
begin
PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
PageNumber := PageNum;
GetCustomers(GenerateSearchOptions());
end);
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
// Adds Elipse to pagination if page number is too big
if PageNumber > 4 then
begin
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
PageItem.classList.add('disabled');
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := '...';
PageLink.setAttribute('href', 'javascript:void(0)');
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
// Adds Page, page - 1, and page + 1 to pagination
for I := Start to Finish do
begin
if ( I > 1) and (I < TotalPages) then
begin
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if I = PageNumber then
PageItem.classList.add('selected-number'); // Add the selected-number class
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := IntToStr(I);
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
var
PageNum: Integer;
begin
PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
PageNumber := PageNum;
GetCustomers(GenerateSearchOptions());
end);
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
end;
// adds ellipse if number is too small
if PageNumber < TotalPages - 4 then
begin
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
PageItem.classList.add('disabled');
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := '...';
PageLink.setAttribute('href', 'javascript:void(0)');
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
if TotalPages <> 1 then
begin
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if TotalPages = PageNumber then
PageItem.classList.add('selected-number');
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := IntToStr(TotalPages);
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
var
PageNum: Integer;
begin
PageNum := StrToInt((Event.currentTarget as TJSHTMLElement).innerText);
PageNumber := PageNum;
GetCustomers(generateSearchOptions());
end);
end;
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
// Next Button
PageItem := TJSHTMLElement(document.createElement('li'));
PageItem.className := 'page-item';
if PageNumber = TotalPages then
PageItem.classList.add('disabled');
PageLink := TJSHTMLElement(document.createElement('a'));
PageLink.className := 'page-link';
PageLink.innerText := 'Next';
PageLink.setAttribute('href', 'javascript:void(0)');
PageLink.addEventListener('click', procedure(Event: TJSMouseEvent)
begin
if PageNumber < TotalPages then
begin
Inc(PageNumber);
GetCustomers(GenerateSearchOptions());
end;
end);
PageItem.appendChild(PageLink);
PaginationElement.appendChild(PageItem);
end;
end.
\ No newline at end of file
...@@ -24,17 +24,6 @@ object FViewEditUser: TFViewEditUser ...@@ -24,17 +24,6 @@ object FViewEditUser: TFViewEditUser
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object lblQB: TWebLabel
Left = 256
Top = 65
Width = 80
Height = 15
Caption = 'Quickbooks ID:'
Color = clBtnFace
ElementID = 'lblQB'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object WebLabel5: TWebLabel object WebLabel5: TWebLabel
Left = 284 Left = 284
Top = 8 Top = 8
...@@ -92,20 +81,21 @@ object FViewEditUser: TFViewEditUser ...@@ -92,20 +81,21 @@ object FViewEditUser: TFViewEditUser
object lblAccess: TWebLabel object lblAccess: TWebLabel
Left = 272 Left = 272
Top = 96 Top = 96
Width = 66 Width = 67
Height = 15 Height = 15
Caption = 'Access Type:' Caption = 'Access Type:'
ElementID = 'lblaccess' ElementID = 'lblaccess'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object lblPerspective: TWebLabel object lblQB: TWebLabel
Left = 3 Left = 256
Top = 132 Top = 65
Width = 77 Width = 80
Height = 15 Height = 15
Caption = 'Perspective ID:' Caption = 'Quickbooks ID:'
ElementID = 'lblperspective' Color = clBtnFace
ElementID = 'lblQB'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
...@@ -256,16 +246,6 @@ object FViewEditUser: TFViewEditUser ...@@ -256,16 +246,6 @@ object FViewEditUser: TFViewEditUser
ParentFont = False ParentFont = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object edtQB: TWebEdit
Left = 348
Top = 62
Width = 121
Height = 22
ChildOrder = 7
ElementID = 'edtQB'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object edtRights: TWebEdit object edtRights: TWebEdit
Left = 96 Left = 96
Top = 93 Top = 93
...@@ -293,13 +273,13 @@ object FViewEditUser: TFViewEditUser ...@@ -293,13 +273,13 @@ object FViewEditUser: TFViewEditUser
'ALL' 'ALL'
'ACTIVE') 'ACTIVE')
end end
object edtPerspective: TWebEdit object edtQB: TWebEdit
Left = 96 Left = 346
Top = 129 Top = 62
Width = 121 Width = 121
Height = 22 Height = 22
ChildOrder = 23 ChildOrder = 7
ElementID = 'edtperspective' ElementID = 'edtQB'
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
......
...@@ -48,15 +48,10 @@ ...@@ -48,15 +48,10 @@
</div> </div>
</form> </form>
<div class="row"> <div class="row">
<div class="col-sm"> <div class="col-6">
<label class='pe-2' style="font-weight: 700;font-size: 15px;" id="lblrights">System Rights:</label> <label class='pe-2' style="font-weight: 700;font-size: 15px;" id="lblrights">System Rights:</label>
<input id="edtrights" class= "form-control input-sm" width='50%'/> <input id="edtrights" class= "form-control input-sm" width='50%'/>
</div> </div>
<div class="col-sm-6">
<label class='pe-2' style="font-weight: 700;font-size: 15px;" id="lblperspective">Perspective ID:</label>
<input id="edtperspective" class= "form-control input-sm" width='50%'/>
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm py-3"> <div class="col-sm py-3">
......
...@@ -14,7 +14,6 @@ type ...@@ -14,7 +14,6 @@ type
TFViewEditUser = class(TWebForm) TFViewEditUser = class(TWebForm)
WebLabel2: TWebLabel; WebLabel2: TWebLabel;
WebLabel3: TWebLabel; WebLabel3: TWebLabel;
lblQB: TWebLabel;
WebLabel5: TWebLabel; WebLabel5: TWebLabel;
WebLabel6: TWebLabel; WebLabel6: TWebLabel;
WebLabel7: TWebLabel; WebLabel7: TWebLabel;
...@@ -34,12 +33,11 @@ type ...@@ -34,12 +33,11 @@ type
lblactive: TWebLabel; lblactive: TWebLabel;
cbStatus: TWebCheckBox; cbStatus: TWebCheckBox;
lblRights: TWebLabel; lblRights: TWebLabel;
edtQB: TWebEdit;
edtRights: TWebEdit; edtRights: TWebEdit;
lblAccess: TWebLabel; lblAccess: TWebLabel;
cbAccess: TWebComboBox; cbAccess: TWebComboBox;
lblPerspective: TWebLabel; lblQB: TWebLabel;
edtPerspective: TWebEdit; edtQB: TWebEdit;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure btnConfirmClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject); procedure btnCancelClick(Sender: TObject);
...@@ -120,7 +118,6 @@ begin ...@@ -120,7 +118,6 @@ begin
'&access=' + cbAccess.Text + '&access=' + cbAccess.Text +
'&newuser=' + edtUsername.Text + '&newuser=' + edtUsername.Text +
'&rights=' + edtRights.Text + '&rights=' + edtRights.Text +
'&perspective=' + edtPerspective.Text +
'&QB=' + edtQB.Text; '&QB=' + edtQB.Text;
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser', xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddUser',
...@@ -159,7 +156,6 @@ begin ...@@ -159,7 +156,6 @@ begin
'&access=' + cbAccess.Text + '&access=' + cbAccess.Text +
'&newuser=' + edtUsername.Text + '&newuser=' + edtUsername.Text +
'&rights=' + edtRights.Text + '&rights=' + edtRights.Text +
'&perspective=' + edtPerspective.Text +
'&QB=' + edtQB.Text; '&QB=' + edtQB.Text;
console.log(editOptions); console.log(editOptions);
...@@ -214,7 +210,6 @@ begin ...@@ -214,7 +210,6 @@ begin
edtQB.Text := QB; edtQB.Text := QB;
if Status = 'ACTIVE' then if Status = 'ACTIVE' then
cbStatus.checked := true; cbStatus.checked := true;
edtPerspective.Text := Perspective
end; end;
procedure TFViewEditUser.WebTimer1Timer(Sender: TObject); procedure TFViewEditUser.WebTimer1Timer(Sender: TObject);
......
...@@ -55,7 +55,9 @@ type ...@@ -55,7 +55,9 @@ type
procedure ViewOrderEntryWeb(orderInfo, customerInfo, mode, info: string); procedure ViewOrderEntryWeb(orderInfo, customerInfo, mode, info: string);
procedure ViewOrderEntryCuttingDie(orderInfo, customerInfo, mode, info: string); procedure ViewOrderEntryCuttingDie(orderInfo, customerInfo, mode, info: string);
procedure ViewOrders(info: string); procedure ViewOrders(info: string);
procedure ViewCustomerList(info: string);
procedure ShowUserForm(Info: string); procedure ShowUserForm(Info: string);
procedure ViewAddCustomer(customerInfo, info: string);
var var
search: string; search: string;
change: boolean; change: boolean;
...@@ -77,7 +79,8 @@ uses ...@@ -77,7 +79,8 @@ uses
View.Orders, View.Orders,
View.OrderEntryCorrugated, View.OrderEntryCorrugated,
View.OrderEntryCuttingDie, View.OrderEntryCuttingDie,
View.OrderEntryWeb; View.OrderEntryWeb,
View.Customers, AddCustomer;
{$R *.dfm} {$R *.dfm}
...@@ -109,9 +112,9 @@ procedure TFViewMain.lblCustomersClick(Sender: TObject); ...@@ -109,9 +112,9 @@ procedure TFViewMain.lblCustomersClick(Sender: TObject);
begin begin
if ( not ( change ) ) then if ( not ( change ) ) then
begin begin
//ShowForm(TFViewCustomers); ShowForm(TFViewCustomers);
lblAppTitle.Caption := 'Koehler-Gibson Customers'; lblAppTitle.Caption := 'Koehler-Gibson Customers';
setActive('Customers'); setActive('Customers');
end end
else else
ShowMessage('Please Save or Cancel your changes'); ShowMessage('Please Save or Cancel your changes');
...@@ -251,6 +254,11 @@ begin ...@@ -251,6 +254,11 @@ begin
Application.CreateForm(AFormClass, WebPanel1.ElementID, FChildForm); Application.CreateForm(AFormClass, WebPanel1.ElementID, FChildForm);
end; end;
procedure TFViewMain.ViewCustomerList(info: string);
begin
end;
procedure TFViewMain.EditUser(Mode, Username, Password, Name, Status, Email, procedure TFViewMain.EditUser(Mode, Username, Password, Name, Status, Email,
Access, Rights, Perspective, QB: string); Access, Rights, Perspective, QB: string);
begin begin
...@@ -292,6 +300,14 @@ begin ...@@ -292,6 +300,14 @@ begin
FChildForm := TFOrderEntryCuttingDie.CreateForm(WebPanel1.ElementID, orderInfo, customerInfo, mode, info); FChildForm := TFOrderEntryCuttingDie.CreateForm(WebPanel1.ElementID, orderInfo, customerInfo, mode, info);
end; end;
procedure TFViewMain.ViewAddCustomer(customerInfo: string; info: string);
begin
lblAppTitle.Caption := 'Koehler-Gibson Add Customer';
if Assigned(FChildForm) then
FChildForm.Free;
FChildForm := TFViewAddCustomer.CreateForm(WebPanel1.ElementID, customerInfo, info);
end;
procedure TFViewMain.ShowUserForm(Info: string); procedure TFViewMain.ShowUserForm(Info: string);
begin begin
if Assigned(FChildForm) then if Assigned(FChildForm) then
......
...@@ -864,7 +864,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated ...@@ -864,7 +864,7 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
DataSource = WebDataSource1 DataSource = WebDataSource1
end end
object btnSave: TWebButton object btnSave: TWebButton
Left = 526 Left = 530
Top = 560 Top = 560
Width = 96 Width = 96
Height = 25 Height = 25
...@@ -1226,6 +1226,18 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated ...@@ -1226,6 +1226,18 @@ object FOrderEntryCorrugated: TFOrderEntryCorrugated
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = btnAddClick OnClick = btnAddClick
end end
object WebButton2: TWebButton
Left = 186
Top = 429
Width = 96
Height = 25
Caption = 'Add Address'
ChildOrder = 85
ElementID = 'btnaddaddress'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = WebButton2Click
end
object XDataWebClient1: TXDataWebClient object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 1014 Left = 1014
......
...@@ -38,25 +38,25 @@ ...@@ -38,25 +38,25 @@
<div class="col-12 col-md-8"> <div class="col-12 col-md-8">
</div> </div>
<h4 class="custom-h4 mt-3">Company</h4> <h4 class="custom-h4 mt-3">Customer</h4>
<hr class="custom-hr"> <hr class="custom-hr">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer Name:</label>
<input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/> <input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Name. Please Provide a Customer Name.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Account Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer ID:</label>
<input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/> <input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Account Name. Please Provide a Customer ID Name.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">In Quickbooks?:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">In Quickbooks?:</label>
<input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/> <input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/>
</div> </div>
</div> </div>
...@@ -107,6 +107,9 @@ ...@@ -107,6 +107,9 @@
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Ship To Address. Please Provide a Ship To Address.
</div> </div>
<div class="mt-2">
<button id="btnaddaddress" class="btn btn-primary btn-sm">Add Address</button>
</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label>
......
...@@ -202,6 +202,7 @@ type ...@@ -202,6 +202,7 @@ type
tmrReturn: TWebTimer; tmrReturn: TWebTimer;
btnEdit: TWebButton; btnEdit: TWebButton;
btnAdd: TWebButton; btnAdd: TWebButton;
WebButton2: TWebButton;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure HideNotification(); procedure HideNotification();
procedure ShowNotification(Notification: string); procedure ShowNotification(Notification: string);
...@@ -238,6 +239,9 @@ type ...@@ -238,6 +239,9 @@ type
procedure btnAddClick(Sender: TObject); procedure btnAddClick(Sender: TObject);
procedure xdwdsQBItemAfterEdit(DataSet: TDataSet); procedure xdwdsQBItemAfterEdit(DataSet: TDataSet);
procedure ViewMode(); procedure ViewMode();
procedure WebButton2Click(Sender: TObject);
procedure ShowAddAddressForm();
[async] procedure SendAddressToServer(AddressJSON: TJSONObject);
private private
FAgencyCode: string; FAgencyCode: string;
FCurrentReportType: string; FCurrentReportType: string;
...@@ -260,9 +264,12 @@ implementation ...@@ -260,9 +264,12 @@ implementation
{$R *.dfm} {$R *.dfm}
uses uses
View.Home, View.Main, View.AddOrder, Utils; View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryCorrugated.sendOrderToServer(); procedure TFOrderEntryCorrugated.sendOrderToServer();
// This can be improved. I was struggling to get the checkboxes to work with
// The dataset at first, but if you just change the fields in the database to be
// Booleans it should work
var var
colorList: TJSONArray; colorList: TJSONArray;
container: TJSElement; container: TJSElement;
...@@ -530,7 +537,7 @@ begin ...@@ -530,7 +537,7 @@ begin
else else
FViewMain.ViewOrders(''); FViewMain.ViewOrders('');
end end
else else
begin begin
Utils.ShowSpinner('spinner'); Utils.ShowSpinner('spinner');
asm asm
...@@ -577,7 +584,8 @@ begin ...@@ -577,7 +584,8 @@ begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCorrugatedOrder', Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCorrugatedOrder',
[orderJSON.ToString])); [orderJSON.ToString]));
jsObj := JS.TJSObject(Response.Result); jsObj := JS.TJSObject(Response.Result);
OrderID := JS.toString(jsObj.Properties['OrderID']); if mode = 'ADD' then
OrderID := String(jsObj.Properties['OrderID']);
mode := 'EDIT'; mode := 'EDIT';
end; end;
...@@ -667,6 +675,73 @@ begin ...@@ -667,6 +675,73 @@ begin
addColorRow('','','',''); addColorRow('','','','');
end; end;
procedure TFOrderEntryCorrugated.WebButton2Click(Sender: TObject);
begin
ShowAddAddressForm();
end;
procedure TFOrderEntryCorrugated.SendAddressToServer(AddressJSON: TJSONObject);
var
Response: TXDataClientResponse;
notification: TJSObject;
begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddShippingAddress',
[AddressJSON.ToString]));
notification := TJSObject(Response.Result);
ShowNotification(string(notification['status']));
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
end;
procedure TFOrderEntryCorrugated.ShowAddAddressForm;
// displays the search pop-up that allows the user to filter the order list
var
newform: TFViewAddAddress;
AddressJSON: TJSONObject;
ship_block: string;
begin
newform := TFViewAddAddress.CreateNew;
newform.Caption := 'Input Shipping Information';
newForm.Popup := True;
newForm.Border := fbDialog;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
var
searchOptions: string;
begin
if newform.confirm then
begin
AddressJSON := TJSONObject.Create;
AddressJSON.AddPair('address', newform.edtAddress.Text);
AddressJSON.AddPair('city', newform.edtCity.Text);
AddressJSON.AddPair('state', newform.edtState.Text);
AddressJSON.AddPair('zip', newform.edtZip.Text);
AddressJSON.AddPair('contact', newform.edtContact.Text);
AddressJSON.AddPair('customer_id', customerID);
ship_block := newform.edtFirstLine.Text + slinebreak +
edtCompanyName.Text + slinebreak +
newform.edtContact.Text + slinebreak +
newform.edtAddress.Text + slinebreak +
newform.edtCity.Text + ', ' + newform.edtState.Text + ' ' + newform.edtZip.Text;
AddressJSON.AddPair('ship_block', ship_block);
AddressJSON.AddPair('mode', 'ADD');
sendAddressToServer(AddressJSON);
end;
end
);
end;
procedure TFOrderEntryCorrugated.btnAddClick(Sender: TObject); procedure TFOrderEntryCorrugated.btnAddClick(Sender: TObject);
var var
newform: TFAddOrder; newform: TFAddOrder;
......
...@@ -386,6 +386,18 @@ object FOrderEntryCuttingDie: TFOrderEntryCuttingDie ...@@ -386,6 +386,18 @@ object FOrderEntryCuttingDie: TFOrderEntryCuttingDie
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = btnAddClick OnClick = btnAddClick
end end
object WebButton2: TWebButton
Left = 186
Top = 429
Width = 96
Height = 25
Caption = 'Add Address'
ChildOrder = 85
ElementID = 'btnaddaddress'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = WebButton2Click
end
object WebDataSource1: TWebDataSource object WebDataSource1: TWebDataSource
DataSet = XDataWebDataSet1 DataSet = XDataWebDataSet1
Left = 22 Left = 22
...@@ -470,13 +482,13 @@ object FOrderEntryCuttingDie: TFOrderEntryCuttingDie ...@@ -470,13 +482,13 @@ object FOrderEntryCuttingDie: TFOrderEntryCuttingDie
end end
object wdsShipTo: TWebDataSource object wdsShipTo: TWebDataSource
DataSet = xdwdsShipTo DataSet = xdwdsShipTo
Left = 212 Left = 302
Top = 436 Top = 418
end end
object xdwdsShipTo: TXDataWebDataSet object xdwdsShipTo: TXDataWebDataSet
AfterEdit = xdwdsShipToAfterEdit AfterEdit = xdwdsShipToAfterEdit
Left = 270 Left = 288
Top = 436 Top = 370
object xdwdsShipToADDRESS: TStringField object xdwdsShipToADDRESS: TStringField
FieldName = 'ADDRESS' FieldName = 'ADDRESS'
end end
......
...@@ -34,25 +34,25 @@ ...@@ -34,25 +34,25 @@
</div> </div>
</nav> </nav>
<div class="row mx-5"> <div class="row mx-5">
<h4 class="custom-h4 mt-3">Company</h4> <h4 class="custom-h4 mt-3">Customer</h4>
<hr class="custom-hr"> <hr class="custom-hr">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer Name:</label>
<input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/> <input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Name. Please Provide a Customer Name.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Account Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer ID:</label>
<input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/> <input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Account Name. Please Provide a Customer ID.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">In Quickbooks?:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">In Quickbooks?:</label>
<input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/> <input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/>
</div> </div>
</div> </div>
...@@ -103,6 +103,9 @@ ...@@ -103,6 +103,9 @@
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Ship To Address. Please Provide a Ship To Address.
</div> </div>
<div class="mt-2">
<button id="btnaddaddress" class="btn btn-primary btn-sm">Add Address</button>
</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label>
...@@ -125,32 +128,6 @@ ...@@ -125,32 +128,6 @@
<textarea id="edtspecialinstructions" class="form-control" style=" width: 500px; height: 150px;"></textarea> <textarea id="edtspecialinstructions" class="form-control" style=" width: 500px; height: 150px;"></textarea>
</div> </div>
</div> </div>
<div class="row">
<div class="col-auto">
<button id="btnconfirm" class="btn btn-primary btn-sm float-end my-2">Save</button>
</div>
<div class="col-auto">
<button id="btncancel" class="btn btn-primary btn-sm float-end my-2">Cancel</button>
</div>
<div class="col-auto">
<button id="btncopy" class="btn btn-primary btn-sm float-end my-2">Copy</button>
</div>
<div class="col-auto">
<button id="btnpdf" class="btn btn-primary btn-sm float-end my-2">PDF</button>
</div>
<div class="col-auto">
<button id="btndelete" class="btn btn-primary btn-sm float-end my-2">Delete</button>
</div>
<div class="col-auto">
<button id="btnclose" class="btn btn-primary btn-sm float-end my-2">Close</button>
</div>
<div class="col-auto">
<button id="btnedit" class="btn btn-primary btn-sm float-end my-2">Edit</button>
</div>
<div class="col-auto">
<button id="btnadd" class="btn btn-primary btn-sm float-end my-2">Add</button>
</div>
</div>
</div> </div>
<div class="modal fade" id="confirmation_modal" tabindex="-1" aria-labelledby="confirmation_modal_label" aria-hidden="true"> <div class="modal fade" id="confirmation_modal" tabindex="-1" aria-labelledby="confirmation_modal_label" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
......
...@@ -73,6 +73,7 @@ type ...@@ -73,6 +73,7 @@ type
tmrReturn: TWebTimer; tmrReturn: TWebTimer;
btnEdit: TWebButton; btnEdit: TWebButton;
btnAdd: TWebButton; btnAdd: TWebButton;
WebButton2: TWebButton;
procedure btnSaveClick(Sender: TObject); procedure btnSaveClick(Sender: TObject);
procedure btnCancelClick(Sender: TObject); procedure btnCancelClick(Sender: TObject);
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
...@@ -101,6 +102,9 @@ type ...@@ -101,6 +102,9 @@ type
procedure dtpOrderDateChange(Sender: TObject); procedure dtpOrderDateChange(Sender: TObject);
procedure btnEditClick(Sender: TObject); procedure btnEditClick(Sender: TObject);
procedure ViewMode(); procedure ViewMode();
procedure WebButton2Click(Sender: TObject);
procedure ShowAddAddressForm();
[async] procedure SendAddressToServer(AddressJSON: TJSONObject);
private private
FAgencyCode: string; FAgencyCode: string;
FCurrentReportType: string; FCurrentReportType: string;
...@@ -121,7 +125,73 @@ implementation ...@@ -121,7 +125,73 @@ implementation
{$R *.dfm} {$R *.dfm}
uses uses
View.Home, View.Main, View.AddOrder, Utils; View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryCuttingDie.WebButton2Click(Sender: TObject);
begin
ShowAddAddressForm();
end;
procedure TFOrderEntryCuttingDie.SendAddressToServer(AddressJSON: TJSONObject);
var
Response: TXDataClientResponse;
notification: TJSObject;
begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddShippingAddress',
[AddressJSON.ToString]));
notification := TJSObject(Response.Result);
ShowNotification(string(notification['status']));
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
end;
procedure TFOrderEntryCuttingDie.ShowAddAddressForm;
// displays the search pop-up that allows the user to filter the order list
var
newform: TFViewAddAddress;
AddressJSON: TJSONObject;
ship_block: string;
begin
newform := TFViewAddAddress.CreateNew;
newform.Caption := 'Shipping Information';
newForm.Popup := True;
newForm.Border := fbDialog;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
var
searchOptions: string;
begin
if newform.confirm then
begin
AddressJSON := TJSONObject.Create;
AddressJSON.AddPair('address', newform.edtAddress.Text);
AddressJSON.AddPair('city', newform.edtCity.Text);
AddressJSON.AddPair('state', newform.edtState.Text);
AddressJSON.AddPair('zip', newform.edtZip.Text);
AddressJSON.AddPair('contact', newform.edtContact.Text);
AddressJSON.AddPair('customer_id', customerID);
ship_block := newform.edtFirstLine.Text + slinebreak +
edtCompanyName.Text + slinebreak +
newform.edtContact.Text + slinebreak +
newform.edtAddress.Text + slinebreak +
newform.edtCity.Text + ', ' + newform.edtState.Text + ' ' + newform.edtZip.Text;
AddressJSON.AddPair('ship_block', ship_block);
AddressJSON.AddPair('mode', 'ADD');
sendAddressToServer(AddressJSON);
end;
end
);
end;
function TFOrderEntryCuttingDie.VerifyOrder: Boolean; function TFOrderEntryCuttingDie.VerifyOrder: Boolean;
var var
...@@ -224,8 +294,6 @@ begin ...@@ -224,8 +294,6 @@ begin
orderJSON.AddPair('mode', mode); orderJSON.AddPair('mode', mode);
if mode = 'EDIT' then if mode = 'EDIT' then
orderJSON.AddPair('ORDER_ID', orderID); orderJSON.AddPair('ORDER_ID', orderID);
console.log(orderJSON.GetValue('ORDER_ID'));
console.log(orderJSON);
if mode = 'ADD' then if mode = 'ADD' then
ShowNotification('Success:Order Added Successfully!') ShowNotification('Success:Order Added Successfully!')
...@@ -345,10 +413,15 @@ end; ...@@ -345,10 +413,15 @@ end;
procedure TFOrderEntryCuttingDie.AddCuttingDieOrder(orderJSON: TJSONObject); procedure TFOrderEntryCuttingDie.AddCuttingDieOrder(orderJSON: TJSONObject);
// sends the order JSON object to the server // sends the order JSON object to the server
var var
Response: TXDataClientResponse; Response: TXDataClientResponse;
jsObj: TJSObject;
begin begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCuttingDieOrder', Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddCuttingDieOrder',
[orderJSON.ToString])); [orderJSON.ToString]));
jsObj := JS.TJSObject(Response.Result);
if mode = 'ADD' then
OrderID := String(jsObj.Properties['OrderID']);
mode := 'EDIT';
end; end;
class function TFOrderEntryCuttingDie.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm; class function TFOrderEntryCuttingDie.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm;
...@@ -513,6 +586,10 @@ begin ...@@ -513,6 +586,10 @@ begin
XDataWebDataSet1.Open; XDataWebDataSet1.Open;
console.log(XDataWebDataSet1NAME.AsString); console.log(XDataWebDataSet1NAME.AsString);
dtpOrderDate.Date := 0;
dtpProofDate.Date := 0;
dtpShipDate.Date := 0;
xdwdsShipTo.Close; xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(customer['ADDRESS_LIST']); xdwdsShipTo.SetJSONData(customer['ADDRESS_LIST']);
xdwdsShipTo.Open; xdwdsShipTo.Open;
......
...@@ -1284,6 +1284,18 @@ object FOrderEntryWeb: TFOrderEntryWeb ...@@ -1284,6 +1284,18 @@ object FOrderEntryWeb: TFOrderEntryWeb
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = btnAddClick OnClick = btnAddClick
end end
object WebButton2: TWebButton
Left = 174
Top = 372
Width = 96
Height = 25
Caption = 'Add Address'
ChildOrder = 85
ElementID = 'btnaddaddress'
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = WebButton2Click
end
object XDataWebClient1: TXDataWebClient object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 160 Left = 160
......
...@@ -34,25 +34,25 @@ ...@@ -34,25 +34,25 @@
</div> </div>
</nav> </nav>
<div class="row mx-5"> <div class="row mx-5">
<h4 class="custom-h4 mt-3">Company</h4> <h4 class="custom-h4 mt-3">Customer</h4>
<hr class="custom-hr"> <hr class="custom-hr">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer Name:</label>
<input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/> <input id="edtcompanyname" type="text" class="form-control" style="width: 300px;" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Name. Please Provide a Customer Name.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">Account Company Name:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">Customer ID:</label>
<input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/> <input id="edtaccountcompanyname"type="text" class="form-control" style="width: 150px" required/>
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Company Account Name. Please Provide a Customer ID.
</div> </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label for="wdbe_first_name" class="form-label mt-2">In Quickbooks?:</label> <label for="wdbe_first_name" style="font-weight: 700; font-size: 15px;" class="form-label mt-2">In Quickbooks?:</label>
<input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/> <input id="edtinquickbooks"type="text" class="form-control" style="width: 150px"/>
</div> </div>
</div> </div>
...@@ -103,6 +103,9 @@ ...@@ -103,6 +103,9 @@
<div class="invalid-feedback" style="font-size: 15px;"> <div class="invalid-feedback" style="font-size: 15px;">
Please Provide a Ship To Address. Please Provide a Ship To Address.
</div> </div>
<div class="mt-2">
<button id="btnaddaddress" class="btn btn-primary btn-sm">Add Address</button>
</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label> <label style="font-weight: 700; font-size: 15px;" class="form-label mt-2">PO Number:</label>
......
...@@ -206,6 +206,7 @@ type ...@@ -206,6 +206,7 @@ type
tmrReturn: TWebTimer; tmrReturn: TWebTimer;
btnEdit: TWebButton; btnEdit: TWebButton;
btnAdd: TWebButton; btnAdd: TWebButton;
WebButton2: TWebButton;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure HideNotification(); procedure HideNotification();
procedure ShowNotification(Notification: string); procedure ShowNotification(Notification: string);
...@@ -235,6 +236,9 @@ type ...@@ -235,6 +236,9 @@ type
procedure XDataWebDataSet1AfterEdit(DataSet: TDataSet); procedure XDataWebDataSet1AfterEdit(DataSet: TDataSet);
procedure dtpOrderDateChange(Sender: TObject); procedure dtpOrderDateChange(Sender: TObject);
procedure ViewMode(); procedure ViewMode();
procedure WebButton2Click(Sender: TObject);
procedure ShowAddAddressForm();
[async] procedure SendAddressToServer(AddressJSON: TJSONObject);
private private
FAgencyCode: string; FAgencyCode: string;
FCurrentReportType: string; FCurrentReportType: string;
...@@ -256,7 +260,73 @@ implementation ...@@ -256,7 +260,73 @@ implementation
{$R *.dfm} {$R *.dfm}
uses uses
View.Home, View.Main, View.AddOrder, Utils; View.Home, View.Main, View.AddOrder, View.AddAddress, Utils;
procedure TFOrderEntryWeb.WebButton2Click(Sender: TObject);
begin
ShowAddAddressForm();
end;
procedure TFOrderEntryWeb.SendAddressToServer(AddressJSON: TJSONObject);
var
Response: TXDataClientResponse;
notification: TJSObject;
begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddShippingAddress',
[AddressJSON.ToString]));
notification := TJSObject(Response.Result);
ShowNotification(string(notification['status']));
xdwdsShipTo.Close;
xdwdsShipTo.SetJSONData(notification['ADDRESS']);
xdwdsShipTo.Open;
end;
procedure TFOrderEntryWeb.ShowAddAddressForm;
// displays the search pop-up that allows the user to filter the order list
var
newform: TFViewAddAddress;
AddressJSON: TJSONObject;
ship_block: string;
begin
newform := TFViewAddAddress.CreateNew;
newform.Caption := 'Input Shipping Information';
newForm.Popup := True;
newForm.Border := fbDialog;
// used to manage Back button handling to close subform
window.location.hash := 'subform';
newform.ShowModal(
procedure(AValue: TModalResult)
var
searchOptions: string;
begin
if newform.confirm then
begin
AddressJSON := TJSONObject.Create;
AddressJSON.AddPair('address', newform.edtAddress.Text);
AddressJSON.AddPair('city', newform.edtCity.Text);
AddressJSON.AddPair('state', newform.edtState.Text);
AddressJSON.AddPair('zip', newform.edtZip.Text);
AddressJSON.AddPair('contact', newform.edtContact.Text);
AddressJSON.AddPair('customer_id', customerID);
ship_block := newform.edtFirstLine.Text + slinebreak +
edtCompanyName.Text + slinebreak +
newform.edtContact.Text + slinebreak +
newform.edtAddress.Text + slinebreak +
newform.edtCity.Text + ', ' + newform.edtState.Text + ' ' + newform.edtZip.Text;
AddressJSON.AddPair('ship_block', ship_block);
AddressJSON.AddPair('mode', 'ADD');
sendAddressToServer(AddressJSON);
end;
end
);
end;
procedure TFOrderEntryWeb.btnSaveClick(Sender: TObject); procedure TFOrderEntryWeb.btnSaveClick(Sender: TObject);
begin begin
...@@ -297,7 +367,6 @@ begin ...@@ -297,7 +367,6 @@ begin
input := TJSHTMLInputElement(document.getElementById('edtinvoiceto')); input := TJSHTMLInputElement(document.getElementById('edtinvoiceto'));
if edtInvoiceTo.Text = '' then if edtInvoiceTo.Text = '' then
begin begin
console.log('hot');
input.classList.add('is-invalid'); input.classList.add('is-invalid');
result := false; result := false;
end end
...@@ -530,7 +599,6 @@ var ...@@ -530,7 +599,6 @@ var
begin begin
// Call the server method to generate the PDF // Call the server method to generate the PDF
console.log(orderID);
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderWebPDF', [orderID])); xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GenerateOrderWebPDF', [orderID]));
jsObject := JS.TJSObject(xdcResponse.Result); jsObject := JS.TJSObject(xdcResponse.Result);
pdfURL := JS.toString(jsObject.Properties['value']); pdfURL := JS.toString(jsObject.Properties['value']);
...@@ -538,16 +606,21 @@ begin ...@@ -538,16 +606,21 @@ begin
// Open the PDF in a new browser tab without needing a different form // Open the PDF in a new browser tab without needing a different form
// This method is much faster too, even for large datasets // This method is much faster too, even for large datasets
window.open(pdfURL, '_blank'); window.open(pdfURL, '_blank');
console.log(pdfURL);
end; end;
procedure TFOrderEntryWeb.AddWebOrder(orderJSON: TJSONObject); procedure TFOrderEntryWeb.AddWebOrder(orderJSON: TJSONObject);
// sends the order JSON object to the server // sends the order JSON object to the server
var var
Response: TXDataClientResponse; Response: TXDataClientResponse;
jsObj: TJSObject;
begin begin
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddWebOrder', Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.AddWebOrder',
[orderJSON.ToString])); [orderJSON.ToString]));
jsObj := JS.TJSObject(Response.Result);
if mode = 'ADD' then
OrderID := String(jsObj.Properties['OrderID']);
console.log(OrderID);
mode := 'EDIT';
end; end;
class function TFOrderEntryWeb.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm; class function TFOrderEntryWeb.CreateForm(AElementID, orderInfo, customerInfo, mode, info: string): TWebForm;
...@@ -725,7 +798,6 @@ begin ...@@ -725,7 +798,6 @@ begin
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetWebOrder', xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.GetWebOrder',
[Order_ID])); [Order_ID]));
order := TJSObject(xdcResponse.Result); order := TJSObject(xdcResponse.Result);
console.log(order);
data := TJSArray(order['data']); data := TJSArray(order['data']);
XDataWebDataSet1.Close; XDataWebDataSet1.Close;
XDataWebDataSet1.SetJsonData(order); XDataWebDataSet1.SetJsonData(order);
...@@ -733,12 +805,10 @@ begin ...@@ -733,12 +805,10 @@ begin
if XDataWebDataSet1quantity_and_colors_qty_colors.Value <> '' then if XDataWebDataSet1quantity_and_colors_qty_colors.Value <> '' then
begin begin
colorObject := TJSObject(TJSJSON.parse(XDataWebDataSet1quantity_and_colors_qty_colors.Value)); colorObject := TJSObject(TJSJSON.parse(XDataWebDataSet1quantity_and_colors_qty_colors.Value));
console.log(colorObject);
colorList := TJSArray(colorObject['items']); colorList := TJSArray(colorObject['items']);
for I := 0 to colorList.length -1 do for I := 0 to colorList.length -1 do
begin begin
color := TJSObject(colorList[i]); color := TJSObject(colorList[i]);
console.log(color);
addColorRow(String(color['#']), string(color['Color']), string(color['LPI']), string(color['Size'])); addColorRow(String(color['#']), string(color['Color']), string(color['LPI']), string(color['Size']));
end; end;
end; end;
......
...@@ -129,11 +129,11 @@ object FViewOrders: TFViewOrders ...@@ -129,11 +129,11 @@ object FViewOrders: TFViewOrders
end end
item item
DataField = 'ID' DataField = 'ID'
Title = 'ID' Title = 'Customer ID'
end end
item item
DataField = 'companyName' DataField = 'companyName'
Title = 'Company Name' Title = 'Customer Name'
end end
item item
DataField = 'jobName' DataField = 'jobName'
...@@ -443,4 +443,10 @@ object FViewOrders: TFViewOrders ...@@ -443,4 +443,10 @@ object FViewOrders: TFViewOrders
Left = 346 Left = 346
Top = 412 Top = 412
end end
object tmrReturn: TWebTimer
Enabled = False
OnTimer = tmrReturnTimer
Left = 294
Top = 362
end
end end
...@@ -60,6 +60,7 @@ type ...@@ -60,6 +60,7 @@ type
lblMessage: TWebLabel; lblMessage: TWebLabel;
btnCloseNotification: TWebButton; btnCloseNotification: TWebButton;
xdwdsOrdersDBID: TStringField; xdwdsOrdersDBID: TStringField;
tmrReturn: TWebTimer;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure btnAddOrderClick(Sender: TObject); procedure btnAddOrderClick(Sender: TObject);
procedure btnSearchClick(Sender: TObject); procedure btnSearchClick(Sender: TObject);
...@@ -71,6 +72,7 @@ type ...@@ -71,6 +72,7 @@ type
procedure wdbtcOrdersDblClickCell(Sender: TObject; ACol, ARow: Integer); procedure wdbtcOrdersDblClickCell(Sender: TObject; ACol, ARow: Integer);
procedure wdbtcOrdersClickCell(Sender: TObject; ACol, ARow: Integer); procedure wdbtcOrdersClickCell(Sender: TObject; ACol, ARow: Integer);
procedure WebButton1Click(Sender: TObject); procedure WebButton1Click(Sender: TObject);
procedure tmrReturnTimer(Sender: TObject);
private private
FChildForm: TWebForm; FChildForm: TWebForm;
procedure ClearTable(); procedure ClearTable();
...@@ -192,7 +194,7 @@ begin ...@@ -192,7 +194,7 @@ begin
DMConnection.ApiConnection.Connected := True; DMConnection.ApiConnection.Connected := True;
PageNumber := 1; PageNumber := 1;
TotalPages := 1; // Initial total pages TotalPages := 1; // Initial total pages
console.log(FViewMain.search = '');
if FViewMain.search = '' then if FViewMain.search = '' then
begin begin
//Status 1 //Status 1
...@@ -251,7 +253,8 @@ begin ...@@ -251,7 +253,8 @@ begin
else else
null2 := StrToBool(params.Values['null2']); null2 := StrToBool(params.Values['null2']);
end; end;
getOrders(GenerateSearchOptions()); FViewMain.search := GenerateSearchOptions();
getOrders(FViewMain.search);
end; end;
...@@ -393,6 +396,9 @@ begin ...@@ -393,6 +396,9 @@ begin
begin begin
if newform.confirm then if newform.confirm then
begin begin
asm
startSpinner();
end;
StatusJSON := TJSONObject.Create; StatusJSON := TJSONObject.Create;
StatusJSON.AddPair('ORDER_ID', OrderID); StatusJSON.AddPair('ORDER_ID', OrderID);
StatusJSON.AddPair('date', DateTimeToStr(newform.dtpDate.Date)); StatusJSON.AddPair('date', DateTimeToStr(newform.dtpDate.Date));
...@@ -403,16 +409,26 @@ begin ...@@ -403,16 +409,26 @@ begin
StatusJSON.AddPair('staff_fields_mount_due', DateToStr(newForm.dtpNewMountDue.Date)); StatusJSON.AddPair('staff_fields_mount_due', DateToStr(newForm.dtpNewMountDue.Date));
StatusJSON.AddPair('staff_fields_plate_due', DateToStr(newForm.dtpNewPlateDue.Date)); StatusJSON.AddPair('staff_fields_plate_due', DateToStr(newForm.dtpNewPlateDue.Date));
StatusJSON.AddPair('staff_fields_art_due', DateToStr(newForm.dtpNewArtDue.Date)); StatusJSON.AddPair('staff_fields_art_due', DateToStr(newForm.dtpNewArtDue.Date));
StatusJSON.AddPair('OrderType', NewForm.OrderType);
SetStatus(StatusJSON.ToString); SetStatus(StatusJSON.ToString);
OrderID := ''; OrderID := '';
getOrders(GenerateSearchOptions()); tmrReturn.Enabled := true;
end; end;
end end
); );
end; end;
procedure TFViewOrders.tmrReturnTimer(Sender: TObject);
begin
asm
endSpinner();
end;
tmrReturn.Enabled := false;
getOrders(fViewMain.search);
end;
procedure TFViewOrders.SetStatus(statusInfo: string); procedure TFViewOrders.SetStatus(statusInfo: string);
var var
xdcResponse: TXDataClientResponse; xdcResponse: TXDataClientResponse;
...@@ -712,7 +728,7 @@ end; ...@@ -712,7 +728,7 @@ end;
procedure TFViewOrders.btnSearchClick(Sender: TObject); procedure TFViewOrders.btnSearchClick(Sender: TObject);
var var
filterSection: TJSHTMLElement; filterSection: TJSHTMLElement;
begin begin
ShowSearchForm(); ShowSearchForm();
end; end;
......
...@@ -149,7 +149,7 @@ object FSearch: TFSearch ...@@ -149,7 +149,7 @@ object FSearch: TFSearch
Top = 56 Top = 56
Width = 107 Width = 107
Height = 14 Height = 14
Caption = 'Search Companies:' Caption = 'Search Customers:'
Font.Charset = ANSI_CHARSET Font.Charset = ANSI_CHARSET
Font.Color = clBlack Font.Color = clBlack
Font.Height = -11 Font.Height = -11
...@@ -162,9 +162,9 @@ object FSearch: TFSearch ...@@ -162,9 +162,9 @@ object FSearch: TFSearch
object lblCompanyID: TWebLabel object lblCompanyID: TWebLabel
Left = 174 Left = 174
Top = 56 Top = 56
Width = 68 Width = 72
Height = 14 Height = 14
Caption = 'Company ID:' Caption = 'Customer ID:'
Font.Charset = ANSI_CHARSET Font.Charset = ANSI_CHARSET
Font.Color = clBlack Font.Color = clBlack
Font.Height = -11 Font.Height = -11
...@@ -207,9 +207,9 @@ object FSearch: TFSearch ...@@ -207,9 +207,9 @@ object FSearch: TFSearch
object WebLabel5: TWebLabel object WebLabel5: TWebLabel
Left = 338 Left = 338
Top = 56 Top = 56
Width = 89 Width = 93
Height = 14 Height = 14
Caption = 'Company Name:' Caption = 'Customer Name:'
Font.Charset = ANSI_CHARSET Font.Charset = ANSI_CHARSET
Font.Color = clBlack Font.Color = clBlack
Font.Height = -11 Font.Height = -11
...@@ -457,7 +457,7 @@ object FSearch: TFSearch ...@@ -457,7 +457,7 @@ object FSearch: TFSearch
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 40.000000000000000000 Width = 80.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -502,7 +502,7 @@ object FSearch: TFSearch ...@@ -502,7 +502,7 @@ object FSearch: TFSearch
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 320.000000000000000000 Width = 280.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -717,8 +717,8 @@ object FSearch: TFSearch ...@@ -717,8 +717,8 @@ object FSearch: TFSearch
object xdwdsCustomersstaff_fields_invoice_to: TStringField object xdwdsCustomersstaff_fields_invoice_to: TStringField
FieldName = 'staff_fields_invoice_to' FieldName = 'staff_fields_invoice_to'
end end
object xdwdsCustomersID: TIntegerField object xdwdsCustomersCUSTOMER_ID: TIntegerField
FieldName = 'ID' FieldName = 'CUSTOMER_ID'
end end
end end
object wdsCustomers: TWebDataSource object wdsCustomers: TWebDataSource
......
...@@ -55,7 +55,7 @@ type ...@@ -55,7 +55,7 @@ type
WebLabel5: TWebLabel; WebLabel5: TWebLabel;
edtCompanyName: TWebEdit; edtCompanyName: TWebEdit;
xdwdsCustomersSHORT_NAME: TStringField; xdwdsCustomersSHORT_NAME: TStringField;
xdwdsCustomersID: TIntegerField; xdwdsCustomersCUSTOMER_ID: TIntegerField;
procedure btnConfirmClick(Sender: TObject); procedure btnConfirmClick(Sender: TObject);
procedure WebFormShow(Sender: TObject); procedure WebFormShow(Sender: TObject);
procedure btnCancelClick(Sender: TObject); procedure btnCancelClick(Sender: TObject);
...@@ -116,7 +116,6 @@ begin ...@@ -116,7 +116,6 @@ begin
DateFormatSettings := TFormatSettings.Create; DateFormatSettings := TFormatSettings.Create;
DateFormatSettings.ShortDateFormat := 'yyyy/mm/dd'; DateFormatSettings.ShortDateFormat := 'yyyy/mm/dd';
console.log(UpperCase(Copy(params.Values['orderType'], 1, 1)) + LowerCase(Copy(params.Values['orderType'], 2, MaxInt)));
wcbOrderType.Text := UpperCase(Copy(params.Values['orderType'], 1, 1)) + LowerCase(Copy(params.Values['orderType'], 2, MaxInt)); wcbOrderType.Text := UpperCase(Copy(params.Values['orderType'], 1, 1)) + LowerCase(Copy(params.Values['orderType'], 2, MaxInt));
edtOrderID.Text := params.Values['orderID']; edtOrderID.Text := params.Values['orderID'];
edtCompanyID.Text := params.Values['companyID']; edtCompanyID.Text := params.Values['companyID'];
...@@ -279,9 +278,9 @@ begin ...@@ -279,9 +278,9 @@ begin
// Set up column headers // Set up column headers
TMSFNCGrid1.ColumnCount := 4; TMSFNCGrid1.ColumnCount := 4;
TMSFNCGrid1.RowCount := 1; TMSFNCGrid1.RowCount := 1;
TMSFNCGrid1.Cells[0, 0] := 'DBID'; TMSFNCGrid1.Cells[0, 0] := 'Customer Num';
TMSFNCGrid1.Cells[1, 0] := 'ID'; TMSFNCGrid1.Cells[1, 0] := 'Customer ID';
TMSFNCGrid1.Cells[2, 0] := 'Name'; TMSFNCGrid1.Cells[2, 0] := 'Customer Name';
TMSFNCGrid1.Cells[3, 0] := 'Address'; TMSFNCGrid1.Cells[3, 0] := 'Address';
// Populate the grid with data from the dataset // Populate the grid with data from the dataset
...@@ -291,7 +290,7 @@ begin ...@@ -291,7 +290,7 @@ begin
while not xdwdsCustomers.EOF do while not xdwdsCustomers.EOF do
begin begin
TMSFNCGrid1.RowCount := RowIndex + 1; TMSFNCGrid1.RowCount := RowIndex + 1;
TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('ID').AsString; TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('CUSTOMER_ID').AsString;
TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString; TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('SHORT_NAME').AsString;
TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString; TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('NAME').AsString;
TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('staff_fields_invoice_to').AsString; TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('staff_fields_invoice_to').AsString;
......
object FAddOrder: TFAddOrder object FSelectCustomer: TFSelectCustomer
Width = 894 Width = 765
Height = 633 Height = 480
Align = alClient OnCreate = WebFormCreate
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'Arial'
Font.Style = []
ParentFont = False
OnShow = WebFormShow OnShow = WebFormShow
object cbWebPlate: TWebCheckBox object WebLabel1: TWebLabel
Left = 172 Left = 8
Top = 55 Top = 81
Width = 113 Width = 95
Height = 22 Height = 15
Caption = 'Web Plate' Caption = 'Search Customers'
ChildOrder = 5
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = cbWebPlateClick
end end
object cbCorrugatedPlate: TWebCheckBox object WebLabel2: TWebLabel
Left = 40 Left = 279
Top = 55 Top = 81
Width = 113 Width = 134
Height = 22 Height = 15
Caption = 'Corrugated Plate' Caption = 'Selected Customer Name'
Checked = True
ChildOrder = 5
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
State = cbChecked
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = cbCorrugatedPlateClick
end end
object edtSearch: TWebEdit object WebLabel3: TWebLabel
Left = 306 Left = 131
Top = 55 Top = 81
Width = 146 Width = 113
Height = 22 Height = 15
ChildOrder = 8 Caption = 'Selected Customer ID'
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnChange = edtSearchChange
end end
object edtID: TWebEdit object edtSearch: TWebEdit
Left = 475 Left = 4
Top = 55 Top = 102
Width = 121 Width = 121
Height = 22 Height = 22
ChildOrder = 8 ChildOrder = 2
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object btnConfirm: TWebButton object edtName: TWebEdit
Left = 612 Left = 279
Top = 52 Top = 102
Width = 96 Width = 142
Height = 25 Height = 22
Caption = 'Confirm' ChildOrder = 1
ChildOrder = 9 Enabled = False
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000
OnClick = btnConfirmClick
end
object btnCancel: TWebButton
Left = 730
Top = 52
Width = 96
Height = 25
Caption = 'Cancel'
ChildOrder = 9
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthStyle = ssAuto
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
OnClick = btnCancelClick
end end
object TMSFNCGrid1: TTMSFNCGrid object TMSFNCGrid1: TTMSFNCGrid
Left = 0 Left = 0
Top = 220 Top = 163
Width = 894 Width = 765
Height = 413 Height = 317
Align = alBottom Align = alBottom
ParentDoubleBuffered = False ParentDoubleBuffered = False
DoubleBuffered = True DoubleBuffered = True
TabOrder = 6 TabOrder = 2
DefaultRowHeight = 40.000000000000000000 DefaultRowHeight = 40.000000000000000000
FixedColumns = 0 FixedColumns = 0
ColumnCount = 3 ColumnCount = 4
Options.Bands.Enabled = True Options.Bands.Enabled = True
Options.ColumnSize.Stretch = True Options.ColumnSize.Stretch = True
Options.Editing.CalcFormat = '%g' Options.Editing.CalcFormat = '%g'
...@@ -121,7 +84,37 @@ object FAddOrder: TFAddOrder ...@@ -121,7 +84,37 @@ object FAddOrder: TFAddOrder
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 327.000000000000000000 Width = 90.000000000000000000
end
item
BorderWidth = 1
FixedFont.Charset = DEFAULT_CHARSET
FixedFont.Color = 4539717
FixedFont.Height = -11
FixedFont.Name = 'Segoe UI'
FixedFont.Style = [fsBold]
Font.Charset = DEFAULT_CHARSET
Font.Color = 8026746
Font.Height = -11
Font.Name = 'Segoe UI'
Font.Style = []
ID = ''
Width = 150.000000000000000000
end
item
BorderWidth = 1
FixedFont.Charset = DEFAULT_CHARSET
FixedFont.Color = 4539717
FixedFont.Height = -11
FixedFont.Name = 'Segoe UI'
FixedFont.Style = [fsBold]
Font.Charset = DEFAULT_CHARSET
Font.Color = 8026746
Font.Height = -11
Font.Name = 'Segoe UI'
Font.Style = []
ID = ''
Width = 200.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -136,7 +129,7 @@ object FAddOrder: TFAddOrder ...@@ -136,7 +129,7 @@ object FAddOrder: TFAddOrder
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 327.000000000000000000 Width = 306.000000000000000000
end end
item item
BorderWidth = 1 BorderWidth = 1
...@@ -151,7 +144,7 @@ object FAddOrder: TFAddOrder ...@@ -151,7 +144,7 @@ object FAddOrder: TFAddOrder
Font.Name = 'Segoe UI' Font.Name = 'Segoe UI'
Font.Style = [] Font.Style = []
ID = '' ID = ''
Width = 239.000000000000000000 Width = 90.000000000000000000
end> end>
DefaultFont.Charset = DEFAULT_CHARSET DefaultFont.Charset = DEFAULT_CHARSET
DefaultFont.Color = clWindowText DefaultFont.Color = clWindowText
...@@ -211,30 +204,115 @@ object FAddOrder: TFAddOrder ...@@ -211,30 +204,115 @@ object FAddOrder: TFAddOrder
LeftCol = 0 LeftCol = 0
ScrollMode = scmItemScrolling ScrollMode = scmItemScrolling
DesignTimeSampleData = True DesignTimeSampleData = True
ExplicitWidth = 982 OnCellClick = TMSFNCGrid1CellClick
end
object btnCancel: TWebButton
Left = 556
Top = 101
Width = 96
Height = 25
Caption = 'Cancel'
ChildOrder = 5
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
object btnConfirm: TWebButton
Left = 440
Top = 101
Width = 96
Height = 25
Caption = 'Select'
ChildOrder = 5
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnConfirmClick
end
object edtNotification: TWebEdit
Left = 4
Top = 16
Width = 510
Height = 22
HelpType = htKeyword
TabStop = False
ChildOrder = 8
ElementFont = efCSS
Enabled = False
Font.Charset = ANSI_CHARSET
Font.Color = clRed
Font.Height = -13
Font.Name = 'Arial'
Font.Style = []
HeightPercent = 100.000000000000000000
HideSelection = False
ParentFont = False
TabOrder = 1
WidthPercent = 100.000000000000000000
end
object edtID: TWebEdit
Left = 131
Top = 102
Width = 142
Height = 22
ChildOrder = 1
Enabled = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end end
object XDataWebClient1: TXDataWebClient object XDataWebClient1: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 370 Left = 630
Top = 562 Top = 47
end end
object xdwdsCustomers: TXDataWebDataSet object xdwdsCustomers: TXDataWebDataSet
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 206 Left = 166
Top = 564 Top = 129
object xdwdsCustomersID: TIntegerField object xdwdsCustomersBillAddr: TStringField
FieldName = 'ID' FieldName = 'BillAddr'
end
object xdwdsCustomersCompanyName: TStringField
FieldName = 'CompanyName'
end
object xdwdsCustomersId: TStringField
FieldName = 'Id'
end
object xdwdsCustomersPrimaryPhone: TStringField
FieldName = 'PrimaryPhone'
end
object xdwdsCustomersShipAddr: TStringField
FieldName = 'ShipAddr'
end
object xdwdsCustomersShipAddrLine1: TStringField
FieldName = 'ShipAddrLine1'
end
object xdwdsCustomersShipAddrCity: TStringField
FieldName = 'ShipAddrCity'
end
object xdwdsCustomersShipAddrState: TStringField
FieldName = 'ShipAddrState'
end
object xdwdsCustomersShipAddrZip: TStringField
FieldName = 'ShipAddrZip'
end
object xdwdsCustomersBillAddrLine1: TStringField
FieldName = 'BillAddrLine1'
end
object xdwdsCustomersBillAddrCity: TStringField
FieldName = 'BillAddrCity'
end
object xdwdsCustomersBillAddrState: TStringField
FieldName = 'BillAddrState'
end end
object xdwdsCustomersNAME: TStringField object xdwdsCustomersBillAddrZip: TStringField
FieldName = 'NAME' FieldName = 'BillAddrZip'
end end
object xdwdsCustomersSHORT_NAME: TStringField object xdwdsCustomersInKGOrders: TBooleanField
FieldName = 'SHORT_NAME' FieldName = 'In KGOrders'
end end
end end
object wdsCustomers: TWebDataSource object wdsCustomers: TWebDataSource
DataSet = xdwdsCustomers DataSet = xdwdsCustomers
Left = 38 Left = 104
Top = 562 Top = 135
end end
end end
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>TMS Web Project</title>
<style>
</style>
</head>
<body>
</body>
</html>
\ No newline at end of file
unit View.SelectCustomer;
interface
uses
System.SysUtils, System.Generics.Collections, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, WEBLib.Menus, WEBLib.ExtCtrls, WEBLib.StdCtrls,
WEBLib.JSON, Auth.Service, XData.Web.Client, WebLib.Storage,
ConnectionModule, App.Types, Vcl.StdCtrls, Vcl.Controls, WEBLib.DBCtrls,
Data.DB, XData.Web.JsonDataset, XData.Web.Dataset, WEBLib.DB, VCL.TMSFNCTypes, VCL.TMSFNCUtils,
VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, VCL.TMSFNCGridCell,
VCL.TMSFNCGridOptions, VCL.TMSFNCCustomControl, VCL.TMSFNCCustomScrollControl,
VCL.TMSFNCGridData, VCL.TMSFNCCustomGrid, VCL.TMSFNCGrid;
type
TFSelectCustomer = class(TWebForm)
WebLabel1: TWebLabel;
WebLabel2: TWebLabel;
edtSearch: TWebEdit;
edtName: TWebEdit;
TMSFNCGrid1: TTMSFNCGrid;
btnCancel: TWebButton;
btnConfirm: TWebButton;
edtNotification: TWebEdit;
XDataWebClient1: TXDataWebClient;
xdwdsCustomers: TXDataWebDataSet;
wdsCustomers: TWebDataSource;
xdwdsCustomersBillAddr: TStringField;
xdwdsCustomersCompanyName: TStringField;
xdwdsCustomersId: TStringField;
xdwdsCustomersPrimaryPhone: TStringField;
xdwdsCustomersShipAddr: TStringField;
xdwdsCustomersShipAddrLine1: TStringField;
xdwdsCustomersShipAddrCity: TStringField;
xdwdsCustomersShipAddrState: TStringField;
xdwdsCustomersShipAddrZip: TStringField;
xdwdsCustomersBillAddrLine1: TStringField;
xdwdsCustomersBillAddrCity: TStringField;
xdwdsCustomersBillAddrState: TStringField;
xdwdsCustomersBillAddrZip: TStringField;
WebLabel3: TWebLabel;
edtID: TWebEdit;
xdwdsCustomersInKGOrders: TBooleanField;
procedure WebFormCreate(Sender: TObject);
procedure WebFormShow(Sender: TObject);
procedure TMSFNCGrid1CellDblClick(Sender: TObject; ACol, ARow: Integer);
procedure btnConfirmClick(Sender: TObject);
procedure TMSFNCGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
private
{ Private declarations }
[Async] procedure GetCustomers();
[Async] procedure SendCustomerToServer();
procedure PopulateGridManually();
public
{ Public declarations }
end;
var
FSelectCustomer: TFSelectCustomer;
implementation
{$R *.dfm}
uses View.Main;
procedure TFSelectCustomer.WebFormCreate(Sender: TObject);
begin
if not DMConnection.ApiConnection.Connected then
begin
DMConnection.ApiConnection.OpenAsync;
console.log('report requirements connection open')
end;
end;
procedure TFSelectCustomer.WebFormShow(Sender: TObject);
begin
asm
startSpinner();
end;
getCustomers();
end;
procedure TFSelectCustomer.btnConfirmClick(Sender: TObject);
begin
if edtID.Text = '' then
edtNotification.Text := 'Please Select a Customer'
else
begin
xdwdsCustomers.Locate('Id', edtID.Text, []);
SendCustomerToServer();
end;
end;
[async] procedure TFSelectCustomer.getCustomers();
// retrieves customer list from server
var
xdcResponse: TXDataClientResponse;
customerList: TJSObject;
i: integer;
begin
// Fetch data from XData service
xdcResponse := await(XDataWebClient1.RawInvokeAsync('ILookupService.getQBCustomers', []));
customerList := TJSObject(xdcResponse.Result);
//console.log(customerList);
// Load data into TXDataWebDataset
xdwdsCustomers.Close;
xdwdsCustomers.SetJsonData(customerList);
xdwdsCustomers.Open;
// Manually populate the grid
PopulateGridManually;
asm
endSpinner();
end;
end;
procedure TFSelectCustomer.PopulateGridManually;
// populates the grid with customers manually.
var
RowIndex: Integer;
begin
TMSFNCGrid1.BeginUpdate;
try
TMSFNCGrid1.Clear; // Clear any existing data
// Set up column headers
TMSFNCGrid1.ColumnCount := 4;
TMSFNCGrid1.RowCount := 1;
TMSFNCGrid1.Cells[0, 0] := 'Quickbooks ID';
TMSFNCGrid1.Cells[1, 0] := 'Customer Name';
TMSFNCGrid1.Cells[2, 0] := 'Address';
TMSFNCGrid1.Cells[3, 0] := 'In KGOrders';
// Populate the grid with data from the dataset
xdwdsCustomers.First;
RowIndex := 1;
while not xdwdsCustomers.EOF do
begin
TMSFNCGrid1.RowCount := RowIndex + 1;
TMSFNCGrid1.Cells[0, RowIndex] := xdwdsCustomers.FieldByName('Id').AsString;
TMSFNCGrid1.Cells[1, RowIndex] := xdwdsCustomers.FieldByName('CompanyName').AsString;
TMSFNCGrid1.Cells[2, RowIndex] := xdwdsCustomers.FieldByName('BillAddr').AsString;
TMSFNCGrid1.Cells[3, RowIndex] := xdwdsCustomers.FieldByName('In KGOrders').AsString;
Inc(RowIndex);
xdwdsCustomers.Next;
end;
finally
TMSFNCGrid1.EndUpdate;
end;
end;
procedure TFSelectCustomer.TMSFNCGrid1CellClick(Sender: TObject; ACol,
ARow: Integer);
begin
edtID.Text := TMSFNCGrid1.Cells[0, ARow];
edtName.Text := TMSFNCGrid1.Cells[1, ARow];
end;
procedure TFSelectCustomer.TMSFNCGrid1CellDblClick(Sender: TObject; ACol,
ARow: Integer);
begin
edtID.Text := TMSFNCGrid1.Cells[2, ARow];
xdwdsCustomers.Locate('Id', TMSFNCGrid1.Cells[0, ARow], [] );
end;
procedure TFSelectCustomer.SendCustomerToServer;
var
CustomerJSON: TJSONObject;
Response: TXDataClientResponse;
notification: TJSObject;
begin
CustomerJSON := TJSONObject.Create;
CustomerJSON.AddPair('NAME', xdwdsCustomers.FieldByName('CompanyName').AsString);
CustomerJSON.AddPair('QB_LIST_ID', xdwdsCustomers.FieldByName('Id').AsString);
CustomerJSON.AddPair('PHONE', xdwdsCustomers.FieldByName('PrimaryPhone').AsString);
CustomerJSON.AddPair('BILL_ADDRESS', xdwdsCustomers.FieldByName('BillAddrLine1').AsString);
CustomerJSON.AddPair('BILL_CITY', xdwdsCustomers.FieldByName('BillAddrCity').AsString);
CustomerJSON.AddPair('BILL_STATE', xdwdsCustomers.FieldByName('BillAddrState').AsString);
CustomerJSON.AddPair('BILL_ZIP', xdwdsCustomers.FieldByName('BillAddrZip').AsString);
CustomerJSON.AddPair('BILL_ADDRESS_BLOCK', xdwdsCustomers.FieldByName('BillAddr').AsString);
CustomerJSON.AddPair('address', xdwdsCustomers.FieldByName('ShipAddrLine1').AsString);
CustomerJSON.AddPair('city', xdwdsCustomers.FieldByName('ShipAddrCity').AsString);
CustomerJSON.AddPair('state', xdwdsCustomers.FieldByName('ShipAddrState').AsString);
CustomerJSON.AddPair('zip', xdwdsCustomers.FieldByName('ShipAddrZip').AsString);
CustomerJSON.AddPair('ship_block', xdwdsCustomers.FieldByName('ShipAddr').AsString);
CustomerJSON.AddPair('name', xdwdsCustomers.FieldByName('CompanyName').AsString);
CustomerJSON.AddPair('mode', 'ADD');
asm
startSpinner()
end;
Response := await(XDataWebClient1.RawInvokeAsync('ILookupService.ImportQBCustomer',
[customerJSON.ToString]));
notification := TJSObject(Response.Result);
asm
endSpinner();
end;
FViewMain.ViewAddCustomer(string(notification['CustomerID']), string(notification['status']));
Close();
end;
end.
\ No newline at end of file
...@@ -191,27 +191,7 @@ object FSetStatus: TFSetStatus ...@@ -191,27 +191,7 @@ object FSetStatus: TFSetStatus
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
ItemIndex = -1 ItemIndex = -1
LookupValues = < LookupValues = <>
item
Value = 'PROOF'
DisplayText = 'Proof Done'
end
item
Value = 'ART'
DisplayText = 'Art Done'
end
item
Value = 'PLATE'
DisplayText = 'Plate Done'
end
item
Value = 'MOUNT'
DisplayText = 'Mount Done'
end
item
Value = 'SHIP'
DisplayText = 'Ship Done'
end>
end end
object dtpDate: TWebDateTimePicker object dtpDate: TWebDateTimePicker
Left = 484 Left = 484
......
...@@ -78,6 +78,10 @@ begin ...@@ -78,6 +78,10 @@ begin
end; end;
procedure TFSetStatus.WebFormShow(Sender: TObject); procedure TFSetStatus.WebFormShow(Sender: TObject);
var
ItemsToRemove: TStringList;
i: integer;
filteredItems: TJSArray;
begin begin
HideNotification(); HideNotification();
edtOrderID.Text := OrderID; edtOrderID.Text := OrderID;
...@@ -91,14 +95,17 @@ begin ...@@ -91,14 +95,17 @@ begin
dtpNewMountDue.Date := 0; dtpNewMountDue.Date := 0;
dtpNewPlateDue.Date := 0; dtpNewPlateDue.Date := 0;
dtpNewArtDue.Date := 0; dtpNewArtDue.Date := 0;
ItemsToRemove := TStringList.Create;
if orderType = 'web plate' then if orderType = 'web plate' then
begin begin
dtpNewMountDue.Visible := false; dtpNewMountDue.Visible := false;
dtpMountDue.Visible := false; dtpMountDue.Visible := false;
lblMount.Visible := false; lblMount.Visible := false;
lblMountNew.Visible := false; lblMountNew.Visible := false;
wlcbStatus.LookupValues.AddPair('PROOF', 'Proof Done');
wlcbStatus.LookupValues.AddPair('Art', 'Art Done');
wlcbStatus.LookupValues.AddPair('PLATE', 'Plate Done');
wlcbStatus.LookupValues.AddPair('SHIP', 'Ship Done');
end end
else if orderType = 'cutting die' then else if orderType = 'cutting die' then
begin begin
...@@ -116,9 +123,18 @@ begin ...@@ -116,9 +123,18 @@ begin
dtpNewArtDue.Visible := false; dtpNewArtDue.Visible := false;
lblArt.Visible := false; lblArt.Visible := false;
lblArtNew.Visible := false; lblArtNew.Visible := false;
end;
wlcbStatus.LookupValues.AddPair('PROOF', 'Proof Done');
wlcbStatus.LookupValues.AddPair('SHIP', 'Ship Done');
end
else
begin
wlcbStatus.LookupValues.AddPair('PROOF', 'Proof Done');
wlcbStatus.LookupValues.AddPair('Art', 'Art Done');
wlcbStatus.LookupValues.AddPair('PLATE', 'Plate Done');
wlcbStatus.LookupValues.AddPair('MOUNT', 'Mount Done');
wlcbStatus.LookupValues.AddPair('SHIP', 'Ship Done');
end;
end; end;
procedure TFSetStatus.HideNotification; procedure TFSetStatus.HideNotification;
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
<th scope="col">Email Address</th> <th scope="col">Email Address</th>
<th scope="col">Access Type</th> <th scope="col">Access Type</th>
<th scope="col">System Rights</th> <th scope="col">System Rights</th>
<th scope="col">Perspective ID</th>
<th scope="col">QB ID</th> <th scope="col">QB ID</th>
<th scope="col">Edit</th> <th scope="col">Edit</th>
</tr> </tr>
......
...@@ -433,12 +433,6 @@ begin ...@@ -433,12 +433,6 @@ begin
Cell.innerText := IntToStr(Rights); Cell.innerText := IntToStr(Rights);
NewRow.appendChild(Cell); NewRow.appendChild(Cell);
// Perspective ID Cell
Cell := TJSHTMLElement(document.createElement('td'));
Cell.setAttribute('data-label', 'Perspective ID');
Cell.innerText := PID;
NewRow.appendChild(Cell);
// QB ID Cell // QB ID Cell
Cell := TJSHTMLElement(document.createElement('td')); Cell := TJSHTMLElement(document.createElement('td'));
Cell.setAttribute('data-label', 'QB ID'); Cell.setAttribute('data-label', 'QB ID');
......
program webKGOrders; program webKGOrders;
uses uses
...@@ -24,6 +25,10 @@ uses ...@@ -24,6 +25,10 @@ uses
View.SetStatus in 'View.SetStatus.pas' {FSetStatus: TWebForm} {*.html}, View.SetStatus in 'View.SetStatus.pas' {FSetStatus: TWebForm} {*.html},
View.OrderEntryCuttingDie in 'View.OrderEntryCuttingDie.pas' {FOrderEntryCuttingDie: TWebForm} {*.html}, View.OrderEntryCuttingDie in 'View.OrderEntryCuttingDie.pas' {FOrderEntryCuttingDie: TWebForm} {*.html},
View.OrderEntryWeb in 'View.OrderEntryWeb.pas' {FOrderEntryWeb: 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};
Utils in 'Utils.pas'; Utils in 'Utils.pas';
{$R *.res} {$R *.res}
......
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{DB6F5DBF-7E4B-45DA-AFFA-6C8DF15BA740}</ProjectGuid> <ProjectGuid>{DB6F5DBF-7E4B-45DA-AFFA-6C8DF15BA740}</ProjectGuid>
<ProjectVersion>20.2</ProjectVersion> <ProjectVersion>20.2</ProjectVersion>
...@@ -185,6 +185,26 @@ ...@@ -185,6 +185,26 @@
<Form>FOrderEntryWeb</Form> <Form>FOrderEntryWeb</Form>
<DesignClass>TWebForm</DesignClass> <DesignClass>TWebForm</DesignClass>
</DCCReference> </DCCReference>
<DCCReference Include="View.Customers.pas">
<Form>FViewCustomers</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="AddCustomer.pas">
<Form>FViewAddCustomer</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.AddAddress.pas">
<Form>FViewAddAddress</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="View.SelectCustomer.pas">
<Form>FSelectCustomer</Form>
<FormType>dfm</FormType>
<DesignClass>TWebForm</DesignClass>
</DCCReference>
<DCCReference Include="Utils.pas"/> <DCCReference Include="Utils.pas"/>
<None Include="index.html"/> <None Include="index.html"/>
<None Include="css\app.css"/> <None Include="css\app.css"/>
...@@ -220,6 +240,12 @@ ...@@ -220,6 +240,12 @@
<Deployment Version="5"> <Deployment Version="5">
<DeployFile LocalName="Win32\Debug\webCharms.exe" Configuration="Debug" Class="ProjectOutput"/> <DeployFile LocalName="Win32\Debug\webCharms.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployFile LocalName="Win32\Debug\webKGOrders.exe" Configuration="Debug" Class="ProjectOutput"/> <DeployFile LocalName="Win32\Debug\webKGOrders.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployFile LocalName="Win32\Debug\webKGOrders.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>webKGOrders.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="Win32\Release\webKGOrders.exe" Configuration="Release" Class="ProjectOutput"> <DeployFile LocalName="Win32\Release\webKGOrders.exe" Configuration="Release" Class="ProjectOutput">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteName>webKGOrders.exe</RemoteName> <RemoteName>webKGOrders.exe</RemoteName>
...@@ -227,6 +253,12 @@ ...@@ -227,6 +253,12 @@
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="config\config.json" Configuration="Debug" Class="ProjectFile"/> <DeployFile LocalName="config\config.json" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="config\config.json" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="config\config.json" Configuration="Release" Class="ProjectFile"> <DeployFile LocalName="config\config.json" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
...@@ -234,6 +266,12 @@ ...@@ -234,6 +266,12 @@
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="css\app.css" Configuration="Debug" Class="ProjectFile"/> <DeployFile LocalName="css\app.css" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="css\app.css" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="css\app.css" Configuration="Release" Class="ProjectFile"> <DeployFile LocalName="css\app.css" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
...@@ -247,6 +285,12 @@ ...@@ -247,6 +285,12 @@
</Platform> </Platform>
</DeployFile> </DeployFile>
<DeployFile LocalName="index.html" Configuration="Debug" Class="ProjectFile"/> <DeployFile LocalName="index.html" Configuration="Debug" Class="ProjectFile"/>
<DeployFile LocalName="index.html" Configuration="Debug" Class="ProjectFile">
<Platform Name="Win32">
<RemoteDir>.\</RemoteDir>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="index.html" Configuration="Release" Class="ProjectFile"> <DeployFile LocalName="index.html" Configuration="Release" Class="ProjectFile">
<Platform Name="Win32"> <Platform Name="Win32">
<RemoteDir>.\</RemoteDir> <RemoteDir>.\</RemoteDir>
......
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;
iniFile: TIniFile;
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
Logger.Log(1, 'Missing Client ID or Client Secret in INI File');
Exit();
end;
EncodedAuth := Encoder.Encode(Client + ':' + Secret);
if RefreshToken = '' then
begin
Logger.Log(3, 'Missing Refresh Token, Please Manually Get a New One and Store in INI File');
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 (EXACT match with Postman)
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;
Logger.Log(1, 'qbAPI - Tokens Successfully Saved');
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;
iniStr, line: string;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
try
iniFile.WriteString('Quickbooks', 'RefreshToken', RefreshToken);
LastRefresh := Now;
Logger.Log(1, 'Tokens Successfully Saved');
finally
IniFile.Free;
end;
f := TStringList.Create;
// Save to file (overwrites existing file)
f.SaveToFile('QB.txt');
f.Free;
end;
initialization
RegisterServiceType(TQBService);
end.
...@@ -43,6 +43,8 @@ object FData: TFData ...@@ -43,6 +43,8 @@ object FData: TFData
Lines.Strings = ( Lines.Strings = (
'Memo1') 'Memo1')
TabOrder = 1 TabOrder = 1
ExplicitLeft = -2
ExplicitTop = 435
end end
object DBAdvGrid1: TDBAdvGrid object DBAdvGrid1: TDBAdvGrid
Left = 6 Left = 6
...@@ -1602,8 +1604,8 @@ object FData: TFData ...@@ -1602,8 +1604,8 @@ object FData: TFData
object uqWeb: TUniQuery object uqWeb: TUniQuery
SQL.Strings = ( SQL.Strings = (
'select * from web_plate_orders') 'select * from web_plate_orders')
Left = 745 Left = 743
Top = 464 Top = 476
object uqWebORDER_ID: TIntegerField object uqWebORDER_ID: TIntegerField
FieldName = 'ORDER_ID' FieldName = 'ORDER_ID'
Required = True Required = True
......
...@@ -109,16 +109,34 @@ type ...@@ -109,16 +109,34 @@ type
TAddressItem = class TAddressItem = class
Public Public
ADDRESS: string; ADDRESS: string;
shipping_address: string;
city: string;
state: string;
contact: string;
zip: string;
ship_id: string;
end; end;
TCustomerItem = class TCustomerItem = class
Public Public
NAME: string; NAME: string;
ID: integer; CUSTOMER_ID: integer;
SHORT_NAME: string; SHORT_NAME: string;
BILL_ADDRESS: string;
BILL_CITY: string;
BILL_STATE: string;
BILL_ZIP: string;
BILL_CONTACT: string;
PHONE: string;
staff_fields_invoice_to: string; staff_fields_invoice_to: string;
START_DATE: String;
END_DATE: string;
QB_LIST_ID: string;
FFAX: string;
REP_USER_ID: string;
ADDRESS_LIST: TList<TAddressItem>; ADDRESS_LIST: TList<TAddressItem>;
ITEMS: TItemList; ITEMS: TItemList;
USERS: TList<TUserItem>
end; end;
TCustomerList = class TCustomerList = class
...@@ -375,10 +393,13 @@ type ...@@ -375,10 +393,13 @@ type
[HttpGet] function GenerateOrderCorrugatedPDF(orderID: string): string; [HttpGet] function GenerateOrderCorrugatedPDF(orderID: string): string;
[HttpGet] function GenerateOrderWebPDF(orderID: string): string; [HttpGet] function GenerateOrderWebPDF(orderID: string): string;
[HttpGet] function GenerateOrderCuttingPDF(orderID: string): string; [HttpGet] function GenerateOrderCuttingPDF(orderID: string): string;
[HttpGet] function getQBCustomers(): TJSONArray;
function AddUser(userInfo: string): string; function AddUser(userInfo: string): string;
function AddItem(itemInfo: string): string; function AddItem(itemInfo: string): string;
function AddShippingAddress(Addressinfo: string): TJSONObject;
function DelShippingAddress(AddressID, CustomerID: string): TJSONObject;
function DelUser(username: string): string; function DelUser(username: string): string;
function DelOrder(orderID, orderType, UserID: string): TJSONObject; function DelOrder(orderID, orderType, UserID: string): TJSONObject;
function EditUser(const editOptions: string): string; function EditUser(const editOptions: string): string;
...@@ -387,6 +408,8 @@ type ...@@ -387,6 +408,8 @@ type
function AddCuttingDieOrder(orderInfo: string): TJSONObject; function AddCuttingDieOrder(orderInfo: string): TJSONObject;
function AddStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: integer): string; function AddStatusSchedule(StatusType: string; order: TJSONObject; ORDER_ID: integer): string;
function SetStatus(statusOptions: string): string; function SetStatus(statusOptions: string): string;
function AddCustomer(customerInfo: string): TJSONObject;
function ImportQBCustomer(CustomerInfo: string): TJSONObject;
end; end;
implementation implementation
......
...@@ -20,7 +20,9 @@ uses ...@@ -20,7 +20,9 @@ uses
dbimageen, Vcl.ExtCtrls, ieview, imageenview, IdBaseComponent, IdComponent, dbimageen, Vcl.ExtCtrls, ieview, imageenview, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP,
iexProcEffects, frxDBSet, frxExportBaseDialog, frCoreClasses, rOrderList, rOrderCorrugated, Common.Logging, iexProcEffects, frxDBSet, frxExportBaseDialog, frCoreClasses, rOrderList, rOrderCorrugated, Common.Logging,
DateUtils; DateUtils, REST.Client, REST.Types, WEBLib.REST, WEBLib.WebTools,System.Net.HttpClient,
System.Net.URLClient, System.Net.HttpClientComponent, System.netencoding,
IdHTTP, IdSSLOpenSSL, IdSSLOpenSSLHeaders, System.IniFiles;
type type
...@@ -37,6 +39,8 @@ type ...@@ -37,6 +39,8 @@ type
function GetCustomer(ID: string): TCustomerItem; function GetCustomer(ID: string): TCustomerItem;
function GetWebOrder(orderInfo: string): TWebOrder; function GetWebOrder(orderInfo: string): TWebOrder;
function GetCuttingDieOrder(orderInfo: string): TCuttingDie; function GetCuttingDieOrder(orderInfo: string): TCuttingDie;
function GetQBCustomers: TJSONArray;
function EditUser(const editOptions: string): string; function EditUser(const editOptions: string): string;
...@@ -46,12 +50,15 @@ type ...@@ -46,12 +50,15 @@ type
function GenerateOrderCuttingPDF(orderID: string): string; function GenerateOrderCuttingPDF(orderID: string): string;
function AddUser(userInfo: string): string; function AddUser(userInfo: string): string;
function AddCustomer(customerInfo: string): TJSONObject;
function AddItem(itemInfo: string): string; function AddItem(itemInfo: string): string;
function DelUser(username: string): string; function DelUser(username: string): string;
function AddCorrugatedOrder(orderInfo: string): TJSONObject; function AddCorrugatedOrder(orderInfo: string): TJSONObject;
function AddWebOrder(orderInfo: string): TJSONObject; function AddWebOrder(orderInfo: string): TJSONObject;
function AddCuttingDieOrder(orderInfo: string): TJSONObject; function AddCuttingDieOrder(orderInfo: string): TJSONObject;
function AddShippingAddress(AddressInfo: string): TJSONObject;
function delOrder(OrderID, OrderType, UserID: string): TJSONObject; function delOrder(OrderID, OrderType, UserID: string): TJSONObject;
function DelShippingAddress(AddressID, CustomerID: string): TJSONObject;
function GenerateSubQuery(currStatus: string): string; function GenerateSubQuery(currStatus: string): string;
...@@ -66,6 +73,11 @@ type ...@@ -66,6 +73,11 @@ type
procedure AfterConstruction; override; procedure AfterConstruction; override;
procedure BeforeDestruction; override; procedure BeforeDestruction; override;
procedure AddToRevisionsTable(OrderID, table: string; order: TJSONObject); 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);
end; end;
implementation implementation
...@@ -87,6 +99,38 @@ begin ...@@ -87,6 +99,38 @@ begin
inherited; inherited;
end; end;
function TLookupService.DelShippingAddress(AddressID, CustomerID: string): TJSONObject;
var
SQL: string;
ADDRESS_LIST: TJSONArray;
ADDRESS: TJSONObject;
begin
SQL := 'DELETE FROM customers_ship WHERE customer_ship_id = ' + AddressID;
OrdersDB.UniQuery1.SQL.Text := SQL;
OrdersDB.UniQuery1.ExecSQL;
result := TJSONObject.Create;
result.AddPair('status', 'Success:Address Successfully Deleted');
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;
while not ordersDB.UniQuery1.Eof do
begin
ADDRESS := TJSONObject.Create;
ADDRESS.AddPair('ADDRESS', ordersDB.UniQuery1.FieldByName('ship_block').AsString);
ADDRESS.AddPair('shipping_address', ordersDB.UniQuery1.FieldByName('address').AsString);
ADDRESS.AddPair('city', ordersDB.UniQuery1.FieldByName('city').AsString);
ADDRESS.AddPair('state', ordersDB.UniQuery1.FieldByName('state').AsString);
ADDRESS.AddPair('zip', ordersDB.UniQuery1.FieldByName('zip').AsString);
ADDRESS.AddPair('contact', ordersDB.UniQuery1.FieldByName('contact').AsString);
ADDRESS.AddPair('ship_id', ordersDB.UniQuery1.FieldByName('customer_ship_id').AsString);
ADDRESS_LIST.Add(ADDRESS);
ordersDB.UniQuery1.Next;
end;
Result.AddPair('ADDRESS', ADDRESS_LIST);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
end;
function TLookupService.GetCustomers: TCustomerList; function TLookupService.GetCustomers: TCustomerList;
// Retrieves a list of customers and sends it to the client in object form. // Retrieves a list of customers and sends it to the client in object form.
// The object contains the ID, Name, Short Name, and the shipping address. // The object contains the ID, Name, Short Name, and the shipping address.
...@@ -94,7 +138,7 @@ var ...@@ -94,7 +138,7 @@ var
SQL: string; SQL: string;
customer: TCustomerItem; customer: TCustomerItem;
begin begin
SQL := 'select NAME, CUSTOMER_ID, SHORT_NAME, BILL_ADDRESS, BILL_CITY, BILL_STATE, BILL_ZIP from customers'; SQL := 'select * from customers';
doQuery(ordersDB.UniQuery1, SQL); doQuery(ordersDB.UniQuery1, SQL);
result := TCustomerList.Create; result := TCustomerList.Create;
...@@ -106,12 +150,16 @@ begin ...@@ -106,12 +150,16 @@ begin
begin begin
customer := TCustomerItem.Create; customer := TCustomerItem.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add( customer ); TXDataOperationContext.Current.Handler.ManagedObjects.Add( customer );
customer.NAME := ordersDB.UniQuery1.FieldByName('NAME').AsString; customer.NAME := ordersDB.UniQuery1.FieldByName('NAME').AsString;
customer.ID := ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger; customer.CUSTOMER_ID := ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger;
customer.SHORT_NAME := ordersDB.UniQuery1.FieldByName('SHORT_NAME').AsString; customer.SHORT_NAME := ordersDB.UniQuery1.FieldByName('SHORT_NAME').AsString;
customer.staff_fields_invoice_to := ordersDB.UniQuery1.FieldByName('BILL_ADDRESS').AsString + customer.staff_fields_invoice_to := ordersDB.UniQuery1.FieldByName('BILL_ADDRESS').AsString +
', ' + ordersDB.UniQuery1.FieldByName('BILL_CITY').AsString + ', ' + ordersDB.UniQuery1.FieldByName('BILL_CITY').AsString +
', ' + ordersDB.UniQuery1.FieldByName('BILL_STATE').AsString +
' ' + ordersDB.UniQuery1.FieldByName('BILL_ZIP').AsString; ' ' + ordersDB.UniQuery1.FieldByName('BILL_ZIP').AsString;
customer.START_DATE := ordersDB.UniQuery1.FieldByName('START_DATE').AsString;
result.data.Add(customer); result.data.Add(customer);
result.count := result.count + 1; result.count := result.count + 1;
ordersDB.UniQuery1.Next; ordersDB.UniQuery1.Next;
...@@ -125,23 +173,45 @@ function TLookupService.GetCustomer(ID: string): TCustomerItem; ...@@ -125,23 +173,45 @@ function TLookupService.GetCustomer(ID: string): TCustomerItem;
var var
SQL: string; SQL: string;
ADDRESS: TAddressItem; ADDRESS: TAddressItem;
USER: TUserItem;
begin begin
SQL := 'SELECT c.NAME, c.SHORT_NAME, c.BILL_ADDRESS_BLOCK, s.ship_block FROM customers c JOIN customers_ship s ON c.CUSTOMER_ID = s.customer_id WHERE c.CUSTOMER_ID = ' + ID; if ID = '' then
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;
doQuery(ordersDB.UniQuery1, SQL); doQuery(ordersDB.UniQuery1, SQL);
result := TCustomerItem.Create; result := TCustomerItem.Create;
result.ADDRESS_LIST := TList<TAddressItem>.Create; result.ADDRESS_LIST := TList<TAddressItem>.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add( Result.ADDRESS_LIST ); TXDataOperationContext.Current.Handler.ManagedObjects.Add( Result.ADDRESS_LIST );
result.NAME := ordersDB.UniQuery1.FieldByName('NAME').AsString; result.NAME := ordersDB.UniQuery1.FieldByName('NAME').AsString;
result.ID := StrToInt(ID); result.CUSTOMER_ID := ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger;
result.SHORT_NAME := ordersDB.UniQuery1.FieldByName('SHORT_NAME').AsString; result.SHORT_NAME := ordersDB.UniQuery1.FieldByName('SHORT_NAME').AsString;
result.staff_fields_invoice_to := ordersDB.UniQuery1.FieldByName('BILL_ADDRESS_BLOCK').AsString; result.staff_fields_invoice_to := ordersDB.UniQuery1.FieldByName('BILL_ADDRESS_BLOCK').AsString;
result.START_DATE := ordersDB.UniQuery1.FieldByName('START_DATE').AsString;
result.BILL_ADDRESS := ordersDB.UniQuery1.FieldByName('BILL_ADDRESS').AsString;
result.BILL_CITY := ordersDB.UniQuery1.FieldByName('BILL_CITY').AsString;
result.BILL_STATE := ordersDB.UniQuery1.FieldByName('BILL_STATE').AsString;
result.BILL_ZIP := ordersDB.UniQuery1.FieldByName('BILL_ZIP').AsString;
result.START_DATE := ordersDB.UniQuery1.FieldByName('START_DATE').AsString;
result.BILL_CONTACT := ordersDB.UniQuery1.FieldByName('BILL_CONTACT').AsString;
result.PHONE := ordersDB.UniQuery1.FieldByName('PHONE').AsString;
result.END_DATE := ordersDB.UniQuery1.FieldByName('END_DATE').AsString;
result.QB_LIST_ID := ordersDB.UniQuery1.FieldByName('QB_LIST_ID').AsString;
result.FFAX := ordersDB.UniQuery1.FieldByName('FAX').AsString;
result.REP_USER_ID := ordersDB.UniQuery1.FieldByName('REP_USER_ID').AsString;
while not ordersDB.UniQuery1.Eof do while not ordersDB.UniQuery1.Eof do
begin begin
ADDRESS := TAddressItem.Create; ADDRESS := TAddressItem.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add( ADDRESS ); TXDataOperationContext.Current.Handler.ManagedObjects.Add( ADDRESS );
ADDRESS.ADDRESS := ordersDB.UniQuery1.FieldByName('ship_block').AsString; ADDRESS.ADDRESS := ordersDB.UniQuery1.FieldByName('ship_block').AsString;
ADDRESS.shipping_address := ordersDB.UniQuery1.FieldByName('address').AsString;
ADDRESS.city := ordersDB.UniQuery1.FieldByName('city').AsString;
ADDRESS.state := ordersDB.UniQuery1.FieldByName('state').AsString;
ADDRESS.zip := ordersDB.UniQuery1.FieldByName('zip').AsString;
ADDRESS.contact := ordersDB.UniQuery1.FieldByName('contact').AsString;
ADDRESS.ship_id := ordersDB.UniQuery1.FieldByName('customer_ship_id').AsString;
result.ADDRESS_LIST.Add(ADDRESS); result.ADDRESS_LIST.Add(ADDRESS);
ordersDB.UniQuery1.Next; ordersDB.UniQuery1.Next;
end; end;
...@@ -149,6 +219,21 @@ begin ...@@ -149,6 +219,21 @@ begin
ordersDB.UniQuery1.Close; ordersDB.UniQuery1.Close;
result.ITEMS := GetItems(''); result.ITEMS := GetItems('');
SQL := 'SELECT USER_ID, NAME from users where QB_ID IS NOT NULL AND QB_ID <> ' + quotedStr('');
result.USERS := TList<TUserItem>.Create;
doQuery(ordersDB.UniQuery1, SQL);
while not ordersDB.UniQuery1.Eof do
begin
USER := TUserItem.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add( USER );
USER.userID := ordersDB.UniQuery1.FieldByName('USER_ID').AsString;
USER.full_name := ordersDB.UniQuery1.FieldByName('NAME').AsString;
result.USERS.Add(USER);
ordersDB.UniQuery1.Next;
end;
end; end;
function TLookupService.GenerateOrderListPDF(searchOptions: string): string; function TLookupService.GenerateOrderListPDF(searchOptions: string): string;
...@@ -189,6 +274,214 @@ begin ...@@ -189,6 +274,214 @@ begin
end; end;
end; end;
function TLookupService.AddShippingAddress(AddressInfo: string): TJSONObject;
var
JSONData: TJSONObject;
SQL: string;
Pair: TJSONPair;
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
result := TJSONObject.Create;
JSONData := TJSONObject.ParseJSONValue(AddressInfo) as TJSONObject;
if JSONData = nil then
raise Exception.Create('Invalid JSON format'); // If parsing fails, raise an exception
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
SQL := 'select * from customers_ship where customer_ship_id = ' + IntToStr(ShipID);
end;
doQuery(ordersDB.UniQuery1, SQL);
try
if mode = 'ADD' then
ordersDB.UniQuery1.Insert
else
ordersDB.UniQuery1.Edit;
for Pair in JSONData do
begin
Field := ordersDB.UniQuery1.FindField(Pair.JsonString.Value); // Checks if the field exists in the dataset
if Assigned(Field) then
begin
if (Field is TDateTimeField) then
begin
if (Pair.JsonValue.Value = '') or (Pair.JsonValue.Value = 'null') or (Pair.JsonValue.Value = '12/30/1899') then
Field.Clear // This sets the field to NULL (empty)
else
TDateTimeField(Field).AsDateTime := StrToDate(Pair.JsonValue.Value);
end
else if Pair.JsonValue.Value <> '' then
Field.AsString := Pair.JsonValue.Value;
end;
end;
ordersDB.UniQuery1.Post;
if mode = 'ADD' then
begin
msg := 'Success:Shipping Address Successfully Added';
end
else
msg := 'Success:Shipping Address Successfully Edited';
// 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;
doQuery(ordersDB.UniQuery1, SQL);
ADDRESS_LIST := TJSONArray.Create;
while not ordersDB.UniQuery1.Eof do
begin
ADDRESS := TJSONObject.Create;
ADDRESS.AddPair('ADDRESS', ordersDB.UniQuery1.FieldByName('ship_block').AsString);
ADDRESS.AddPair('shipping_address', ordersDB.UniQuery1.FieldByName('address').AsString);
ADDRESS.AddPair('city', ordersDB.UniQuery1.FieldByName('city').AsString);
ADDRESS.AddPair('state', ordersDB.UniQuery1.FieldByName('state').AsString);
ADDRESS.AddPair('zip', ordersDB.UniQuery1.FieldByName('zip').AsString);
ADDRESS.AddPair('contact', ordersDB.UniQuery1.FieldByName('contact').AsString);
ADDRESS.AddPair('ship_id', ordersDB.UniQuery1.FieldByName('customer_ship_id').AsString);
ADDRESS_LIST.Add(ADDRESS);
ordersDB.UniQuery1.Next;
end;
Result.AddPair('status', msg);
Result.AddPair('ADDRESS', ADDRESS_LIST);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
except
on E: Exception do
begin
Result.AddPair('error', E.Message);
end
end;
end;
function TLookupService.AddCustomer(customerInfo: string): TJSONObject;
var
JSONData: TJSONObject;
SQL: string;
Pair: TJSONPair;
Field: TField;
DateFormat: TFormatSettings;
CustomerID: integer;
mode: string;
temp: string;
msg: string;
unique: boolean;
begin
DateFormat := TFormatSettings.Create;
DateFormat.ShortDateFormat := 'yyyy-mm-dd';
DateFormat.DateSeparator := '-';
JSONData := TJSONObject.ParseJSONValue(customerInfo) as TJSONObject;
if JSONData = nil then
raise Exception.Create('Invalid JSON format'); // If parsing fails, raise an exception
mode := JSONData.GetValue<string>('mode');
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;
OrdersDB.UniQuery1.ExecSQL;
// Retrieve updated RevisionID
SQL := 'select KEYVALUE from idfield where KEYNAME = ' + quotedStr('GEN_CUSTOMER_ID');
doQuery(OrdersDB.UniQuery1, SQL);
CustomerID := OrdersDB.UniQuery1.FieldByName('KEYVALUE').AsInteger;
end
else
CustomerID := JSONData.GetValue<integer>('CUSTOMER_ID');
SQL := 'select CUSTOMER_ID from customers where SHORT_NAME = ' + quotedStr(JSONData.GetValue<string>('SHORT_NAME'));
doQuery(OrdersDB.UniQuery1, SQL);
if mode = 'ADD' then
begin
if OrdersDB.UniQuery1.IsEmpty then
unique := true
else
unique := false;
end
else
begin
if ( (OrdersDB.UniQuery1.IsEmpty) or (OrdersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger = CustomerID) ) then
unique := true
else
unique := false;
end;
if unique then
begin
if mode = 'ADD' then
SQL := 'select * from customers where CUSTOMER_ID = 0 and CUSTOMER_ID <> 0'
else
begin
SQL := 'select * from customers where CUSTOMER_ID = ' + IntToStr(CustomerID);
end;
doQuery(ordersDB.UniQuery1, SQL);
try
if mode = 'ADD' then
ordersDB.UniQuery1.Insert
else
ordersDB.UniQuery1.Edit;
for Pair in JSONData do
begin
Field := ordersDB.UniQuery1.FindField(Pair.JsonString.Value); // Checks if the field exists in the dataset
if Assigned(Field) then
begin
if (Field is TDateTimeField) then
begin
if (Pair.JsonValue.Value = '') or (Pair.JsonValue.Value = 'null') or (Pair.JsonValue.Value = '12/30/1899') then
Field.Clear // This sets the field to NULL (empty)
else
TDateTimeField(Field).AsDateTime := StrToDate(Pair.JsonValue.Value);
end
else if Pair.JsonValue.Value <> '' then
Field.AsString := Pair.JsonValue.Value;
end;
end;
ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger := CustomerID;
// Post the record to the database
ordersDB.UniQuery1.Post;
if mode = 'ADD' then
msg := 'Success:Customer Successfully Added'
else
msg := 'Success:Customer Successfully Edited';
Result := TJSONObject.Create.AddPair('status', msg);
Result.AddPair('CustomerID', CustomerID);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
except
on E: Exception do
begin
Result := TJSONObject.Create.AddPair('error', E.Message);
end
end;
end
else
Result := TJSONObject.Create.AddPair('status', 'Failure:Company Account Name Must Be Unique');
end;
function TLookupService.GenerateOrderCorrugatedPDF(orderID: string): string; function TLookupService.GenerateOrderCorrugatedPDF(orderID: string): string;
var var
...@@ -350,44 +643,26 @@ begin ...@@ -350,44 +643,26 @@ begin
+ status.statusTableShort +'.ORDER_ID = o.ORDER_ID ' + + status.statusTableShort +'.ORDER_ID = o.ORDER_ID ' +
'AND ' + status.statusTableShort + '.ORDER_STATUS = ' + 'AND ' + status.statusTableShort + '.ORDER_STATUS = ' +
quotedStr(status.statusType) + ')'; quotedStr(status.statusType) + ')';
// out dated useage. uncomment if you want to return entries where dues are null, but dones exist or vice versa.
//generateStatusSelectSQL(status.altStatusTableShort, status.altStatusTableLong, status.startDate, status.endDate, status.statusType);
end end
else else
result := result + ' AND ' + generateStatusSelectSQL(status.statusTableShort, status.statusTableLong, status.startDate, status.endDate, status.statusType); result := result + ' AND ' + generateStatusSelectSQL(status.statusTableShort, status.statusTableLong, status.startDate, status.endDate, status.statusType);
end end
else else
begin begin
if status.filterType <> 'ORDER_DATE' then if status.null then
begin begin
if status.null then result := result + ' AND ' + quotedStr(status.startDate) + ' IS NULL';
begin
result := result + ' AND not exists (select 1 from ' + status.statusTableLong +
' ' + status.statusTableShort + ' where '
+ status.statusTableShort +'.ORDER_ID = o.ORDER_ID ' +
'AND ' + status.statusTableShort + '.ORDER_STATUS = ' +
quotedStr(status.statusType) + ')';
end
else
result := result + ' AND ' + generateStatusSelectSQL(status.statusTableShort, status.statusTableLong, status.startDate, status.endDate, status.statusType);
end end
else else
begin begin
if status.null then if status.startDate <> '' then
begin
result := result + ' AND ' + quotedStr(status.startDate) + ' IS NULL';
end
else
begin begin
if status.startDate <> '' then result := result + ' AND ' + quotedStr(status.startDate) + ' <= COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date)';
begin end;
result := result + ' AND ' + quotedStr(status.startDate) + ' <= COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date)';
end;
if ( ( status.endDate <> '1899/12/30' ) AND ( status.endDate <> '' ) ) then if ( ( status.endDate <> '1899/12/30' ) AND ( status.endDate <> '' ) ) then
begin begin
result := result + ' AND ' + quotedStr(status.endDate) + ' >= COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date)'; result := result + ' AND ' + quotedStr(status.endDate) + ' >= COALESCE(cpo.staff_fields_order_date, wpo.staff_fields_order_date, cdo.staff_fields_order_date)';
end;
end; end;
end; end;
end; end;
...@@ -1402,7 +1677,11 @@ var ...@@ -1402,7 +1677,11 @@ var
Status: string; Status: string;
UserID: string; UserID: string;
SQL: string; SQL: string;
temp: string; NextStatus: string;
StatusField: string;
table: string;
OrderType: string;
order: TJSONObject;
begin begin
try try
logger.Log(1, 'Set Status Hit'); logger.Log(1, 'Set Status Hit');
...@@ -1416,6 +1695,30 @@ begin ...@@ -1416,6 +1695,30 @@ begin
Date := StatusInfo.GetValue<string>('date'); Date := StatusInfo.GetValue<string>('date');
Status := StatusInfo.GetValue<string>('status'); Status := StatusInfo.GetValue<string>('status');
UserID := StatusInfo.GetValue<string>('USER_ID'); UserID := StatusInfo.GetValue<string>('USER_ID');
OrderType := StatusInfo.GetValue<string>('OrderType');
if ( (Status = 'PROOF') and (OrderType <> 'cutting die') ) then
begin
NextStatus := 'ART';
StatusField := 'staff_fields_art_due';
end
else if Status = 'ART' then
begin
NextStatus := 'PLATE';
StatusField := 'staff_fields_plate_due';
end
else if ( (Status = 'PLATE') and (OrderType <> 'web plate') ) then
begin
NextStatus := 'MOUNT';
StatusField := 'staff_fields_mount_due';
end
else
begin
NextStatus := 'SHIP';
StatusField := 'staff_fields_ship_date';
end;
Date := DateToStr(StrToDate(Date) + 1);
SQL := 'select * from orders_status where ORDER_ID = ' + IntToStr(ORDER_ID) + ' AND ' + SQL := 'select * from orders_status where ORDER_ID = ' + IntToStr(ORDER_ID) + ' AND ' +
'ORDER_STATUS = ' + quotedStr(Status); 'ORDER_STATUS = ' + quotedStr(Status);
...@@ -1454,7 +1757,44 @@ begin ...@@ -1454,7 +1757,44 @@ begin
if StatusInfo.GetValue<string>('staff_fields_mount_due') <> '12/30/1899' then if StatusInfo.GetValue<string>('staff_fields_mount_due') <> '12/30/1899' then
AddStatusSchedule('MOUNT', StatusInfo, ORDER_ID); AddStatusSchedule('MOUNT', StatusInfo, ORDER_ID);
logger.Log(1, 'Status Successfully set'); if Status <> 'SHIP' then
begin
order := TJSONObject.Create;
try
SQL := 'select * from orders_status_schedule where ORDER_ID = ' + IntToStr(ORDER_ID) + ' AND ' +
'ORDER_STATUS = ' + quotedStr(NextStatus);
doQuery(ordersDB.UniQuery1, SQL);
if ordersDB.UniQuery1.IsEmpty then
order.AddPair('mode', 'ADD')
else
order.AddPair('mode', 'EDIT');
order.AddPair(StatusField, Date);
order.AddPair('USER_ID', UserID);
AddStatusSchedule(NextStatus, order, ORDER_ID);
// update the order as well
if OrderType = 'web plate' then
table := 'web_plate_orders'
else if OrderType = 'cutting die' then
table := 'cutting_die_orders'
else
table := 'corrugated_plate_orders';
SQL := 'select ORDER_ID, ' + StatusField + ' from ' + table + ' where ORDER_ID = ' + IntToStr(ORDER_ID);
doQuery(OrdersDB.UniQuery1, SQL);
OrdersDB.UniQuery1.Edit;
OrdersDB.UniQuery1.FieldByName(StatusField).AsString := Date;
OrdersDB.UniQuery1.Post;
finally
order.Free;
end;
end;
result := 'success'; result := 'success';
except except
on E: Exception do on E: Exception do
...@@ -1681,14 +2021,13 @@ begin ...@@ -1681,14 +2021,13 @@ begin
AddToRevisionsTable(IntToStr(ORDER_ID), 'web_plate_orders_revisions', JSONData); AddToRevisionsTable(IntToStr(ORDER_ID), 'web_plate_orders_revisions', JSONData);
Result := TJSONObject.Create.AddPair('status', 'success'); Result := TJSONObject.Create.AddPair('status', 'success');
Result.AddPair('OrderID', ORDER_ID);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result); TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
except except
on E: Exception do on E: Exception do
begin begin
Result := TJSONObject.Create.AddPair('error', E.Message); Result := TJSONObject.Create.AddPair('error', E.Message);
end end
else
result := TJSONObject.Create.AddPair('OrderID', ORDER_ID);
end; end;
end; end;
...@@ -1711,7 +2050,6 @@ begin ...@@ -1711,7 +2050,6 @@ begin
if JSONData = nil then if JSONData = nil then
raise Exception.Create('Invalid JSON format'); // If parsing fails, raise an exception raise Exception.Create('Invalid JSON format'); // If parsing fails, raise an exception
mode := JSONData.GetValue<string>('mode'); mode := JSONData.GetValue<string>('mode');
ORDER_ID := JSONData.GetValue<integer>('ORDER_ID');
AddToOrdersTable(mode, 'cutting_die', JSONData); AddToOrdersTable(mode, 'cutting_die', JSONData);
...@@ -1764,7 +2102,10 @@ begin ...@@ -1764,7 +2102,10 @@ begin
if ( JSONData.GetValue<string>('staff_fields_ship_date') <> '' ) and ( JSONData.GetValue<string>('staff_fields_ship_date') <> '12/30/1899' ) then if ( JSONData.GetValue<string>('staff_fields_ship_date') <> '' ) and ( JSONData.GetValue<string>('staff_fields_ship_date') <> '12/30/1899' ) then
AddStatusSchedule('SHIP', JSONData, ORDER_ID); AddStatusSchedule('SHIP', JSONData, ORDER_ID);
AddToRevisionsTable(IntToStr(ORDER_ID), 'cutting_die_orders_revisions', JSONData);
Result := TJSONObject.Create.AddPair('status', 'success');
Result.AddPair('OrderID', ORDER_ID);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result); TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
except except
on E: Exception do on E: Exception do
...@@ -1960,6 +2301,375 @@ begin ...@@ -1960,6 +2301,375 @@ begin
end; end;
function TLookupService.getQBCustomers: TJSONArray;
var
iniFile: TIniFile;
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
ParsedCustomer, Customer, BillAddr: TJSONObject;
jsObj: TJSONObject;
CustomerList: TJSONArray;
AccessToken, RefreshToken, CompanyID, Client, Secret: string;
LastRefresh: TDateTime;
I: integer;
SQL: string;
begin
Result := TJSONArray.Create;
iniFile := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini');
restClient := TRESTClient.Create(nil);
restRequest := TRESTRequest.Create(nil);
restResponse := TRESTResponse.Create(nil);
try
restRequest.Client := restClient;
restRequest.Response := restResponse;
if iniFile.ReadString('Quickbooks', 'LastRefresh', '') = '' then
LastRefresh := 0
else
LastRefresh := StrToDateTime(iniFile.ReadString('Quickbooks', 'LastRefresh', ''));
if MinutesBetween(Now, LastRefresh) > 58 then
RefreshAccessToken();
Client := iniFile.ReadString('Quickbooks', 'ClientID', '');
Secret := iniFile.ReadString('Quickbooks', 'ClientSecret', '');
CompanyID := iniFile.ReadString('Quickbooks', 'CompanyID', '');
RefreshToken := iniFile.ReadString('Quickbooks', 'RefreshToken', '');
AccessToken := iniFile.ReadString('Quickbooks', 'AccessToken', '');
restClient.BaseURL := 'https://sandbox-quickbooks.api.intuit.com';
restRequest.Method := rmGET;
res := '/v3/company/' + CompanyID + '/query?query=select * from Customer&minorversion=75';
restRequest.Resource := res;
param := restRequest.Params.AddItem;
param.Name := 'Authorization';
param.Kind := pkHTTPHEADER;
param.Options := param.Options + [TRESTRequestParameterOption.poDoNotEncode];
param.Value := 'Bearer ' + AccessToken;
restRequest.Execute;
jsValue := restResponse.JSONValue;
if not Assigned(jsValue) then
Exit;
jsObj := jsValue as TJSONObject;
if not Assigned(jsObj) then
Exit;
CustomerList := jsObj.GetValue<TJSONArray>('QueryResponse.Customer');
if not Assigned(CustomerList) then
Exit;
for I := 0 to CustomerList.Count - 1 do
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'));
// Handle Bill Address
if Customer.GetValue('BillAddr') is TJSONObject then
begin
BillAddr := Customer.GetValue('BillAddr') as TJSONObject;
ParsedCustomer.AddPair('BillAddrLine1', TJSONString.Create(BillAddr.GetValue<string>('Line1', '')));
ParsedCustomer.AddPair('BillAddrCity', TJSONString.Create(BillAddr.GetValue<string>('City', '')));
ParsedCustomer.AddPair('BillAddrState', TJSONString.Create(BillAddr.GetValue<string>('CountrySubDivisionCode', '')));
ParsedCustomer.AddPair('BillAddrZip', TJSONString.Create(BillAddr.GetValue<string>('PostalCode', '')));
ParsedCustomer.AddPair('BillAddr',
TJSONString.Create(
Customer.GetValue<string>('DisplayName') + sLineBreak +
BillAddr.GetValue('Line1', '') + ',' + sLineBreak +
BillAddr.GetValue('City', '') + ', ' +
BillAddr.GetValue('CountrySubDivisionCode', '') + ' ' +
BillAddr.GetValue('PostalCode', '')
)
);
end;
// 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', '')));
ParsedCustomer.AddPair('ShipAddr',
TJSONString.Create(
Customer.GetValue<string>('DisplayName') + sLineBreak +
BillAddr.GetValue('Line1', '') + ',' + sLineBreak +
BillAddr.GetValue('City', '') + ', ' +
BillAddr.GetValue('CountrySubDivisionCode', '') + ' ' +
BillAddr.GetValue('PostalCode', '')
)
);
end;
Result.AddElement(ParsedCustomer);
except
ParsedCustomer.Free;
raise;
end;
end;
finally
iniFile.Free;
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
end;
procedure TLookupService.AddAddrBlock(prefix: string; AddrJSON: TJSONObject);
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;
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', '');
Secret := iniFile.ReadString('Quickbooks', 'ClientSecret', '');
CompanyID := iniFile.ReadString('Quickbooks', 'CompanyID', '');
RefreshToken := iniFile.ReadString('Quickbooks', 'RefreshToken', '');
// 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
Logger.Log(1, 'Missing Client ID or Client Secret in INI File');
Exit();
end;
EncodedAuth := Encoder.Encode(Client + ':' + Secret);
if RefreshToken = '' then
begin
Logger.Log(3, 'Missing Refresh Token, Please Manually Get a New One and Store in INI File');
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 (EXACT match with Postman)
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;
Logger.Log(1, 'qbAPI - Tokens Successfully Saved');
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 TLookupService.SaveTokens(AccessToken, RefreshToken: string);
var
f: TStringList;
iniStr, line: string;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
try
iniFile.WriteString('Quickbooks', 'RefreshToken', RefreshToken);
iniFile.WriteString('Quickbooks', 'AccessToken', AccessToken);
iniFile.WriteString('Quickbooks', 'LastRefresh', DateTimeToStr(Now));
Logger.Log(1, 'Tokens Successfully Saved');
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;
var
JSONData: TJSONObject;
SQL: string;
Pair: TJSONPair;
Field: TField;
DateFormat: TFormatSettings;
CustomerID: Integer;
mode: string;
temp: string;
msg: string;
QB_LIST_ID: string;
unique: Boolean;
begin
DateFormat := TFormatSettings.Create;
DateFormat.ShortDateFormat := 'yyyy-mm-dd';
DateFormat.DateSeparator := '-';
JSONData := TJSONObject.ParseJSONValue(CustomerInfo) as TJSONObject;
if JSONData = nil then
raise Exception.Create('Invalid JSON format');
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;
OrdersDB.UniQuery1.ExecSQL;
// Retrieve updated RevisionID
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);
try
if OrdersDB.UniQuery1.IsEmpty then
begin
OrdersDB.UniQuery1.Insert;
for Pair in JSONData do
begin
Field := OrdersDB.UniQuery1.FindField(Pair.JsonString.Value);
if Assigned(Field) then
begin
if Field is TDateTimeField then
begin
if (Pair.JsonValue.Value = '') or (Pair.JsonValue.Value = 'null') or (Pair.JsonValue.Value = '12/30/1899') then
Field.Clear
else
TDateTimeField(Field).AsDateTime := StrToDate(Pair.JsonValue.Value, DateFormat);
end
else if Pair.JsonValue.Value <> '' then
Field.AsString := Pair.JsonValue.Value;
end;
end;
OrdersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger := CustomerID;
JSONData.AddPair('customer_id', TJSONNumber.Create(CustomerID));
OrdersDB.UniQuery1.Post;
if mode = 'ADD' then
msg := 'Success:Customer Successfully Added'
else
msg := 'Success:Customer Successfully Edited';
Result := TJSONObject.Create;
Result.AddPair('status', msg);
Result.AddPair('CustomerID', CustomerID);
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
// Add Shipping Information
if JSONData.GetValue<string>('ship_block') <> '' then
begin
SQL := 'SELECT * FROM customers_ship WHERE customer_id = 0 AND customer_id <> 0';
doQuery(OrdersDB.UniQuery1, SQL);
OrdersDB.UniQuery1.Insert;
for Pair in JSONData do
begin
Field := OrdersDB.UniQuery1.FindField(Pair.JsonString.Value);
if Assigned(Field) then
begin
if Field is TDateTimeField then
begin
if (Pair.JsonValue.Value = '') or (Pair.JsonValue.Value = 'null') or (Pair.JsonValue.Value = '12/30/1899') then
Field.Clear
else
TDateTimeField(Field).AsDateTime := StrToDate(Pair.JsonValue.Value, DateFormat);
end
else if Pair.JsonValue.Value <> '' then
Field.AsString := Pair.JsonValue.Value;
end;
end;
OrdersDB.UniQuery1.Post;
end;
end
else
begin
msg := 'Failure:Customer Already in Database';
CustomerID := OrdersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsInteger;
Result := TJSONObject.Create;
Result.AddPair('status', msg);
Result.AddPair('CustomerID', CustomerID);
end;
except
on E: Exception do
begin
Result := TJSONObject.Create;
Result.AddPair('error', E.Message);
end;
end;
end;
initialization initialization
RegisterServiceType(TLookupService); RegisterServiceType(TLookupService);
end. end.
......
...@@ -67,6 +67,15 @@ object FMain: TFMain ...@@ -67,6 +67,15 @@ object FMain: TFMain
TabOrder = 4 TabOrder = 4
OnClick = btnAuthSwaggerUIClick OnClick = btnAuthSwaggerUIClick
end end
object btnQB: TButton
Left = 444
Top = 8
Width = 75
Height = 25
Caption = 'QB'
TabOrder = 5
OnClick = btnQBClick
end
object initTimer: TTimer object initTimer: TTimer
OnTimer = initTimerTimer OnTimer = initTimerTimer
Left = 58 Left = 58
......
...@@ -21,6 +21,7 @@ type ...@@ -21,6 +21,7 @@ type
initTimer: TTimer; initTimer: TTimer;
btnAuthSwaggerUI: TButton; btnAuthSwaggerUI: TButton;
ExeInfo1: TExeInfo; ExeInfo1: TExeInfo;
btnQB: TButton;
procedure btnApiSwaggerUIClick(Sender: TObject); procedure btnApiSwaggerUIClick(Sender: TObject);
procedure btnDataClick(Sender: TObject); procedure btnDataClick(Sender: TObject);
procedure btnExitClick(Sender: TObject); procedure btnExitClick(Sender: TObject);
...@@ -28,6 +29,7 @@ type ...@@ -28,6 +29,7 @@ type
procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure initTimerTimer(Sender: TObject); procedure initTimerTimer(Sender: TObject);
procedure btnAuthSwaggerUIClick(Sender: TObject); procedure btnAuthSwaggerUIClick(Sender: TObject);
procedure btnQBClick(Sender: TObject);
strict private strict private
procedure StartServers; procedure StartServers;
...@@ -44,7 +46,7 @@ uses ...@@ -44,7 +46,7 @@ uses
Common.Config, Common.Config,
Sparkle.Utils, Sparkle.Utils,
Api.Database, Api.Database,
Data; Data, qbAPI;
{$R *.dfm} {$R *.dfm}
...@@ -76,6 +78,13 @@ begin ...@@ -76,6 +78,13 @@ begin
Close; Close;
end; end;
procedure TFMain.btnQBClick(Sender: TObject);
begin
FQB := TfQB.Create( self );
FQB.ShowModal;
FQB.Free;
end;
procedure TFMain.btnAuthSwaggerUIClick(Sender: TObject); procedure TFMain.btnAuthSwaggerUIClick(Sender: TObject);
begin begin
ShellExecute(Handle, 'open', PChar(TSparkleUtils.CombineUrlFast(AuthServerModule.XDataServer.BaseUrl, 'swaggerui')), nil, nil, SW_SHOWNORMAL); ShellExecute(Handle, 'open', PChar(TSparkleUtils.CombineUrlFast(AuthServerModule.XDataServer.BaseUrl, 'swaggerui')), nil, nil, SW_SHOWNORMAL);
......
object fQB: TfQB
Left = 0
Top = 0
Caption = 'fQB'
ClientHeight = 711
ClientWidth = 962
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
OnCreate = FormCreate
OnDestroy = FormDestroy
TextHeight = 15
object Memo1: TMemo
Left = 0
Top = 76
Width = 962
Height = 260
Align = alBottom
Lines.Strings = (
'Memo1')
ScrollBars = ssVertical
TabOrder = 0
end
object Button1: TButton
Left = 42
Top = 18
Width = 87
Height = 25
Caption = 'Company Info'
TabOrder = 1
OnClick = Button1Click
end
object Memo2: TMemo
Left = 0
Top = 336
Width = 962
Height = 196
Align = alBottom
Lines.Strings = (
'')
ScrollBars = ssVertical
TabOrder = 2
end
object Button2: TButton
Left = 135
Top = 22
Width = 87
Height = 25
Caption = 'Get Customers'
TabOrder = 3
OnClick = Button2Click
end
object asgData: TAdvStringGrid
Left = 0
Top = 532
Width = 962
Height = 179
Align = alBottom
DrawingStyle = gdsClassic
FixedColor = clWhite
TabOrder = 4
GridLineColor = 13948116
GridFixedLineColor = 11250603
ActiveCellFont.Charset = DEFAULT_CHARSET
ActiveCellFont.Color = 4474440
ActiveCellFont.Height = -12
ActiveCellFont.Name = 'Segoe UI'
ActiveCellFont.Style = [fsBold]
ActiveCellColor = 11565130
ActiveCellColorTo = 11565130
BorderColor = 11250603
ControlLook.FixedGradientFrom = clWhite
ControlLook.FixedGradientTo = clWhite
ControlLook.FixedGradientHoverFrom = clGray
ControlLook.FixedGradientHoverTo = clWhite
ControlLook.FixedGradientHoverMirrorFrom = clWhite
ControlLook.FixedGradientHoverMirrorTo = clWhite
ControlLook.FixedGradientHoverBorder = 11645361
ControlLook.FixedGradientDownFrom = clWhite
ControlLook.FixedGradientDownTo = clWhite
ControlLook.FixedGradientDownMirrorFrom = clWhite
ControlLook.FixedGradientDownMirrorTo = clWhite
ControlLook.FixedGradientDownBorder = 11250603
ControlLook.DropDownHeader.Font.Charset = DEFAULT_CHARSET
ControlLook.DropDownHeader.Font.Color = clWindowText
ControlLook.DropDownHeader.Font.Height = -11
ControlLook.DropDownHeader.Font.Name = 'Segoe UI'
ControlLook.DropDownHeader.Font.Style = []
ControlLook.DropDownHeader.Visible = True
ControlLook.DropDownHeader.Buttons = <>
ControlLook.DropDownFooter.Font.Charset = DEFAULT_CHARSET
ControlLook.DropDownFooter.Font.Color = clWindowText
ControlLook.DropDownFooter.Font.Height = -11
ControlLook.DropDownFooter.Font.Name = 'Segoe UI'
ControlLook.DropDownFooter.Font.Style = []
ControlLook.DropDownFooter.Visible = True
ControlLook.DropDownFooter.Buttons = <>
ControlLook.ToggleSwitch.BackgroundBorderWidth = 1.000000000000000000
ControlLook.ToggleSwitch.ButtonBorderWidth = 1.000000000000000000
ControlLook.ToggleSwitch.CaptionFont.Charset = DEFAULT_CHARSET
ControlLook.ToggleSwitch.CaptionFont.Color = clWindowText
ControlLook.ToggleSwitch.CaptionFont.Height = -12
ControlLook.ToggleSwitch.CaptionFont.Name = 'Segoe UI'
ControlLook.ToggleSwitch.CaptionFont.Style = []
ControlLook.ToggleSwitch.Shadow = False
Filter = <>
FilterDropDown.Font.Charset = DEFAULT_CHARSET
FilterDropDown.Font.Color = clWindowText
FilterDropDown.Font.Height = -12
FilterDropDown.Font.Name = 'Segoe UI'
FilterDropDown.Font.Style = []
FilterDropDown.TextChecked = 'Checked'
FilterDropDown.TextUnChecked = 'Unchecked'
FilterDropDownClear = '(All)'
FilterEdit.TypeNames.Strings = (
'Starts with'
'Ends with'
'Contains'
'Not contains'
'Equal'
'Not equal'
'Larger than'
'Smaller than'
'Clear')
FixedRowHeight = 22
FixedFont.Charset = DEFAULT_CHARSET
FixedFont.Color = 3881787
FixedFont.Height = -11
FixedFont.Name = 'Segoe UI'
FixedFont.Style = [fsBold]
FloatFormat = '%.2f'
HoverButtons.Buttons = <>
HTMLSettings.ImageFolder = 'images'
HTMLSettings.ImageBaseName = 'img'
Look = glCustom
PrintSettings.DateFormat = 'dd/mm/yyyy'
PrintSettings.Font.Charset = DEFAULT_CHARSET
PrintSettings.Font.Color = clWindowText
PrintSettings.Font.Height = -12
PrintSettings.Font.Name = 'Segoe UI'
PrintSettings.Font.Style = []
PrintSettings.FixedFont.Charset = DEFAULT_CHARSET
PrintSettings.FixedFont.Color = clWindowText
PrintSettings.FixedFont.Height = -12
PrintSettings.FixedFont.Name = 'Segoe UI'
PrintSettings.FixedFont.Style = []
PrintSettings.HeaderFont.Charset = DEFAULT_CHARSET
PrintSettings.HeaderFont.Color = clWindowText
PrintSettings.HeaderFont.Height = -12
PrintSettings.HeaderFont.Name = 'Segoe UI'
PrintSettings.HeaderFont.Style = []
PrintSettings.FooterFont.Charset = DEFAULT_CHARSET
PrintSettings.FooterFont.Color = clWindowText
PrintSettings.FooterFont.Height = -12
PrintSettings.FooterFont.Name = 'Segoe UI'
PrintSettings.FooterFont.Style = []
PrintSettings.PageNumSep = '/'
SearchFooter.ColorTo = clNone
SearchFooter.FindNextCaption = 'Find &next'
SearchFooter.FindPrevCaption = 'Find &previous'
SearchFooter.Font.Charset = DEFAULT_CHARSET
SearchFooter.Font.Color = clWindowText
SearchFooter.Font.Height = -12
SearchFooter.Font.Name = 'Segoe UI'
SearchFooter.Font.Style = []
SearchFooter.HighLightCaption = 'Highlight'
SearchFooter.HintClose = 'Close'
SearchFooter.HintFindNext = 'Find next occurrence'
SearchFooter.HintFindPrev = 'Find previous occurrence'
SearchFooter.HintHighlight = 'Highlight occurrences'
SearchFooter.MatchCaseCaption = 'Match case'
SearchFooter.ResultFormat = '(%d of %d)'
SelectionColor = 13744549
SortSettings.HeaderColor = clWhite
SortSettings.HeaderColorTo = clWhite
SortSettings.HeaderMirrorColor = clWhite
SortSettings.HeaderMirrorColorTo = clWhite
Version = '9.1.4.1'
ColWidths = (
64
64
64
64
64)
RowHeights = (
22
22
22
22
22
22
22
22
22
22)
end
object Button3: TButton
Left = 228
Top = 22
Width = 139
Height = 25
Caption = 'Get Customer By ID'
TabOrder = 5
OnClick = Button3Click
end
object Button4: TButton
Left = 373
Top = 22
Width = 95
Height = 25
Caption = 'Add Estimate'
TabOrder = 6
OnClick = Button4Click
end
object Button5: TButton
Left = 472
Top = 22
Width = 169
Height = 25
Caption = 'Show Customers with Orders'
TabOrder = 7
OnClick = Button5Click
end
object uq: TUniQuery
Connection = ApiDatabase.ucKG
SQL.Strings = (
'select * from web_plate_orders')
Left = 743
Top = 36
object uqORDER_ID: TIntegerField
FieldName = 'ORDER_ID'
Required = True
end
object uqCOMPANY_ID: TIntegerField
FieldName = 'COMPANY_ID'
Required = True
end
object uqUSER_ID: TIntegerField
FieldName = 'USER_ID'
Required = True
end
object uqORDER_DATE: TDateTimeField
FieldName = 'ORDER_DATE'
end
object uqSTART_DATE: TDateField
FieldName = 'START_DATE'
end
object uqEND_DATE: TDateField
FieldName = 'END_DATE'
end
object uqORDER_STATUS: TStringField
FieldName = 'ORDER_STATUS'
Size = 10
end
object uqSCHED_JSON: TStringField
FieldName = 'SCHED_JSON'
Size = 4096
end
object uqstaff_fields_order_date: TDateField
FieldName = 'staff_fields_order_date'
end
object uqstaff_fields_proof_date: TDateField
FieldName = 'staff_fields_proof_date'
end
object uqstaff_fields_ship_date: TDateField
FieldName = 'staff_fields_ship_date'
end
object uqstaff_fields_ship_via: TStringField
FieldName = 'staff_fields_ship_via'
Size = 45
end
object uqstaff_fields_price: TStringField
FieldName = 'staff_fields_price'
Size = 10
end
object uqstaff_fields_invoice_to: TStringField
FieldName = 'staff_fields_invoice_to'
Size = 128
end
object uqstaff_fields_invoice_attention: TStringField
FieldName = 'staff_fields_invoice_attention'
Size = 256
end
object uqstaff_fields_ship_to: TStringField
FieldName = 'staff_fields_ship_to'
Size = 128
end
object uqstaff_fields_ship_attention: TStringField
FieldName = 'staff_fields_ship_attention'
Size = 256
end
object uqstaff_fields_po_number: TStringField
FieldName = 'staff_fields_po_number'
Size = 16
end
object uqstaff_fields_job_name: TStringField
FieldName = 'staff_fields_job_name'
Size = 45
end
object uqstaff_fields_art_due: TDateField
FieldName = 'staff_fields_art_due'
end
object uqstaff_fields_plate_due: TDateField
FieldName = 'staff_fields_plate_due'
end
object uqplates_job_number: TStringField
FieldName = 'plates_job_number'
Size = 16
end
object uqsupplied_by_customer_b_w_or_co: TStringField
FieldName = 'supplied_by_customer_b_w_or_co'
Size = 4
end
object uqsupplied_by_customer_plates: TStringField
FieldName = 'supplied_by_customer_plates'
Size = 4
end
object uqsupplied_by_customer_sample: TStringField
FieldName = 'supplied_by_customer_sample'
Size = 45
end
object uqsupplied_by_customer_dimension: TStringField
FieldName = 'supplied_by_customer_dimension'
Size = 4
end
object uqsupplied_by_customer_other: TStringField
FieldName = 'supplied_by_customer_other'
Size = 45
end
object uqsupplied_by_customer_disk: TStringField
FieldName = 'supplied_by_customer_disk'
Size = 4
end
object uqsupplied_by_customer_e_mail: TStringField
FieldName = 'supplied_by_customer_e_mail'
Size = 128
end
object uqsupplied_by_customer_ftp: TStringField
FieldName = 'supplied_by_customer_ftp'
Size = 128
end
object uqplates_plate_material: TStringField
FieldName = 'plates_plate_material'
Size = 16
end
object uqplates_thickness: TStringField
FieldName = 'plates_thickness'
Size = 5
end
object uqsupplied_by_customer_total_inc: TStringField
FieldName = 'supplied_by_customer_total_inc'
Size = 32
end
object uqsupplied_by_customer_sheets_us: TStringField
FieldName = 'supplied_by_customer_sheets_us'
Size = 32
end
object uqsupplied_by_customer_initials: TStringField
FieldName = 'supplied_by_customer_initials'
Size = 16
end
object uqproofing_pdf: TStringField
FieldName = 'proofing_pdf'
Size = 1
end
object uqproofing_pdf_to: TStringField
FieldName = 'proofing_pdf_to'
Size = 256
end
object uqproofing_pdf_date_1: TDateField
FieldName = 'proofing_pdf_date_1'
end
object uqproofing_pdf_date_2: TDateField
FieldName = 'proofing_pdf_date_2'
end
object uqproofing_pdf_date_3: TDateField
FieldName = 'proofing_pdf_date_3'
end
object uqproofing_full_size_ink_jet_for: TStringField
FieldName = 'proofing_full_size_ink_jet_for'
Size = 1
end
object uqproofing_ink_jet_to: TStringField
FieldName = 'proofing_ink_jet_to'
Size = 256
end
object uqproofing_ink_jet_to_2: TStringField
FieldName = 'proofing_ink_jet_to_2'
Size = 256
end
object uqproofing_ink_jet_date_1: TDateField
FieldName = 'proofing_ink_jet_date_1'
end
object uqproofing_ink_jet_date_2: TDateField
FieldName = 'proofing_ink_jet_date_2'
end
object uqproofing_ink_jet_date_3: TDateField
FieldName = 'proofing_ink_jet_date_3'
end
object uqproofing_color_contract: TStringField
FieldName = 'proofing_color_contract'
Size = 17
end
object uqproofing_color_contrac_to: TStringField
FieldName = 'proofing_color_contrac_to'
Size = 256
end
object uqproofing_color_contrac_date_1: TDateField
FieldName = 'proofing_color_contrac_date_1'
end
object uqproofing_color_contrac_date_2: TDateField
FieldName = 'proofing_color_contrac_date_2'
end
object uqproofing_digital_color_key: TStringField
FieldName = 'proofing_digital_color_key'
Size = 10
end
object uqproofing_digital_color_to: TStringField
FieldName = 'proofing_digital_color_to'
Size = 256
end
object uqproofing_digital_color_date_1: TDateField
FieldName = 'proofing_digital_color_date_1'
end
object uqquantity_and_colors_press_name: TStringField
FieldName = 'quantity_and_colors_press_name'
Size = 64
end
object uqquantity_and_colors_anilox_info: TStringField
FieldName = 'quantity_and_colors_anilox_info'
Size = 64
end
object uqplate_marks_microdots: TStringField
FieldName = 'plate_marks_microdots'
Size = 10
end
object uqplate_marks_microdots_comments: TStringField
FieldName = 'plate_marks_microdots_comments'
Size = 128
end
object uqplate_marks_crosshairs: TStringField
FieldName = 'plate_marks_crosshairs'
Size = 10
end
object uqplate_marks_crosshairs_comments: TStringField
FieldName = 'plate_marks_crosshairs_comments'
Size = 128
end
object uqplate_marks_color_bars: TStringField
FieldName = 'plate_marks_color_bars'
Size = 10
end
object uqplate_marks_color_bars_comments: TStringField
FieldName = 'plate_marks_color_bars_comments'
Size = 128
end
object uqplate_marks_other: TStringField
FieldName = 'plate_marks_other'
Size = 16
end
object uqplate_marks_other_comments: TStringField
FieldName = 'plate_marks_other_comments'
Size = 128
end
object uqprint_orientation_print_orient: TStringField
FieldName = 'print_orientation_print_orient'
Size = 10
end
object uqlayout_around: TStringField
FieldName = 'layout_around'
Size = 10
end
object uqlayout_accross: TStringField
FieldName = 'layout_accross'
Size = 10
end
object uqlayout_surface_print: TStringField
FieldName = 'layout_surface_print'
Size = 10
end
object uqlayout_reverse_print: TStringField
FieldName = 'layout_reverse_print'
Size = 10
end
object uqlayout_cylinder_repeat: TStringField
FieldName = 'layout_cylinder_repeat'
Size = 16
end
object uqlayout_cutoff_dimension: TStringField
FieldName = 'layout_cutoff_dimension'
Size = 16
end
object uqlayout_pitch: TStringField
FieldName = 'layout_pitch'
Size = 16
end
object uqlayout_teeth: TStringField
FieldName = 'layout_teeth'
Size = 16
end
object uqlayout_bleed: TStringField
FieldName = 'layout_bleed'
Size = 16
end
object uqlayout_cutback: TStringField
FieldName = 'layout_cutback'
Size = 16
end
object uqlayout_minimum_trap_dim: TStringField
FieldName = 'layout_minimum_trap_dim'
Size = 10
end
object uqlayout_maximum_trap_dim: TStringField
FieldName = 'layout_maximum_trap_dim'
Size = 10
end
object uqupc_size: TStringField
FieldName = 'upc_size'
Size = 16
end
object uqupc_bar_width_reduction: TStringField
FieldName = 'upc_bar_width_reduction'
Size = 16
end
object uqquantity_and_colors_qty_colors: TStringField
FieldName = 'quantity_and_colors_qty_colors'
Size = 4096
end
object uqgeneral_comments: TStringField
FieldName = 'general_comments'
Size = 4096
end
object uqstaff_fields_quickbooks_item: TStringField
FieldName = 'staff_fields_quickbooks_item'
Size = 45
end
object uqstaff_fields_quantity: TStringField
FieldName = 'staff_fields_quantity'
Size = 10
end
object uqupc_distortion_percent: TStringField
FieldName = 'upc_distortion_percent'
Size = 16
end
object uqupc_distortion_amount: TStringField
FieldName = 'upc_distortion_amount'
Size = 16
end
object uqstaff_fields_art_location: TStringField
FieldName = 'staff_fields_art_location'
Size = 16
end
end
end
unit qbAPI;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, AdvUtil, Data.DB, Vcl.Grids, AdvObj,
BaseGrid, AdvGrid, DBAdvGrid, MemDS, DBAccess, Uni, Vcl.StdCtrls, Vcl.Mask,
vcl.wwdbedit, vcl.wwdotdot, vcl.wwdbcomb, REST.Client, REST.Types, System.JSON,
System.Generics.Collections, AdvEdit, vcl.wwdblook, vcl.wwdbdatetimepicker,
System.Hash, Api.Database, Vcl.ExtCtrls, WEBLib.Forms, WEBLib.Controls, WEBLib.StdCtrls,
WEBLib.ExtCtrls, WEBLib.REST, WEBLib.WebTools,System.Net.HttpClient,
System.Net.URLClient, System.Net.HttpClientComponent, System.netencoding,
IdHTTP, IdSSLOpenSSL, IdSSLOpenSSLHeaders, System.DateUtils, System.IniFiles;
type
TfQB = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
Button2: TButton;
asgData: TAdvStringGrid;
Button3: TButton;
Button4: TButton;
Button5: TButton;
uq: TUniQuery;
uqORDER_ID: TIntegerField;
uqCOMPANY_ID: TIntegerField;
uqUSER_ID: TIntegerField;
uqORDER_DATE: TDateTimeField;
uqSTART_DATE: TDateField;
uqEND_DATE: TDateField;
uqORDER_STATUS: TStringField;
uqSCHED_JSON: TStringField;
uqstaff_fields_order_date: TDateField;
uqstaff_fields_proof_date: TDateField;
uqstaff_fields_ship_date: TDateField;
uqstaff_fields_ship_via: TStringField;
uqstaff_fields_price: TStringField;
uqstaff_fields_invoice_to: TStringField;
uqstaff_fields_invoice_attention: TStringField;
uqstaff_fields_ship_to: TStringField;
uqstaff_fields_ship_attention: TStringField;
uqstaff_fields_po_number: TStringField;
uqstaff_fields_job_name: TStringField;
uqstaff_fields_art_due: TDateField;
uqstaff_fields_plate_due: TDateField;
uqplates_job_number: TStringField;
uqsupplied_by_customer_b_w_or_co: TStringField;
uqsupplied_by_customer_plates: TStringField;
uqsupplied_by_customer_sample: TStringField;
uqsupplied_by_customer_dimension: TStringField;
uqsupplied_by_customer_other: TStringField;
uqsupplied_by_customer_disk: TStringField;
uqsupplied_by_customer_e_mail: TStringField;
uqsupplied_by_customer_ftp: TStringField;
uqplates_plate_material: TStringField;
uqplates_thickness: TStringField;
uqsupplied_by_customer_total_inc: TStringField;
uqsupplied_by_customer_sheets_us: TStringField;
uqsupplied_by_customer_initials: TStringField;
uqproofing_pdf: TStringField;
uqproofing_pdf_to: TStringField;
uqproofing_pdf_date_1: TDateField;
uqproofing_pdf_date_2: TDateField;
uqproofing_pdf_date_3: TDateField;
uqproofing_full_size_ink_jet_for: TStringField;
uqproofing_ink_jet_to: TStringField;
uqproofing_ink_jet_to_2: TStringField;
uqproofing_ink_jet_date_1: TDateField;
uqproofing_ink_jet_date_2: TDateField;
uqproofing_ink_jet_date_3: TDateField;
uqproofing_color_contract: TStringField;
uqproofing_color_contrac_to: TStringField;
uqproofing_color_contrac_date_1: TDateField;
uqproofing_color_contrac_date_2: TDateField;
uqproofing_digital_color_key: TStringField;
uqproofing_digital_color_to: TStringField;
uqproofing_digital_color_date_1: TDateField;
uqquantity_and_colors_press_name: TStringField;
uqquantity_and_colors_anilox_info: TStringField;
uqplate_marks_microdots: TStringField;
uqplate_marks_microdots_comments: TStringField;
uqplate_marks_crosshairs: TStringField;
uqplate_marks_crosshairs_comments: TStringField;
uqplate_marks_color_bars: TStringField;
uqplate_marks_color_bars_comments: TStringField;
uqplate_marks_other: TStringField;
uqplate_marks_other_comments: TStringField;
uqprint_orientation_print_orient: TStringField;
uqlayout_around: TStringField;
uqlayout_accross: TStringField;
uqlayout_surface_print: TStringField;
uqlayout_reverse_print: TStringField;
uqlayout_cylinder_repeat: TStringField;
uqlayout_cutoff_dimension: TStringField;
uqlayout_pitch: TStringField;
uqlayout_teeth: TStringField;
uqlayout_bleed: TStringField;
uqlayout_cutback: TStringField;
uqlayout_minimum_trap_dim: TStringField;
uqlayout_maximum_trap_dim: TStringField;
uqupc_size: TStringField;
uqupc_bar_width_reduction: TStringField;
uqquantity_and_colors_qty_colors: TStringField;
uqgeneral_comments: TStringField;
uqstaff_fields_quickbooks_item: TStringField;
uqstaff_fields_quantity: TStringField;
uqupc_distortion_percent: TStringField;
uqupc_distortion_amount: TStringField;
uqstaff_fields_art_location: TStringField;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
strict private
ordersDB: TApiDatabase;
httpReqTokenRefresh: TWebHttpRequest;
var
AccessToken,RefreshToken,CompanyID,Client,Secret: string;
LastRefresh: TDateTime;
public
{ Public declarations }
procedure getCompanyInfo();
procedure LoadJsonArray(jaData: TJSONArray);
function RefreshAccessToken(): string;
procedure ConfigureSSL(IOHandler: TIdSSLIOHandlerSocketOpenSSL);
procedure SaveTokens(AccessToken, RefreshToken: string);
procedure getCustomers();
end;
var
fQB: TfQB;
implementation
uses
Common.Logging, uLibrary;
{$R *.dfm}
procedure TfQB.Button1Click(Sender: TObject);
begin
getCompanyInfo();
end;
procedure TfQB.SaveTokens(AccessToken, RefreshToken: string);
var
f: TStringList;
iniStr, line: string;
iniFile: TIniFile;
begin
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
try
iniFile.WriteString('Quickbooks', 'RefreshToken', RefreshToken);
LastRefresh := Now;
Logger.Log(1, 'Tokens Successfully Saved');
finally
IniFile.Free;
end;
f := TStringList.Create;
// Save to file (overwrites existing file)
f.SaveToFile('QB.txt');
f.Free;
end;
procedure TfQB.Button2Click(Sender: TObject);
begin
GetCustomers();
end;
procedure TfQB.Button3Click(Sender: TObject);
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;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//Memo2.Lines.Add(res);
Memo1.Lines.Add( jsObj.Format(2) );
// CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
// LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
procedure TfQB.Button4Click(Sender: TObject);
var
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
Customer: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
estimateJSON: TJSONObject;
begin
///v3/company/<realmID>/estimate
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 := rmPOST;
res := '/v3/company/' + companyID + '/estimate';
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;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
//Memo2.Lines.Add(res);
Memo1.Lines.Add( jsObj.Format(2) );
//CustomerList := TJSONArray(restResponse.JSONValue);
// CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
// LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
procedure TfQB.Button5Click(Sender: TObject);
var
SQL: string;
count: integer;
begin
SQL := 'SELECT c.CUSTOMER_ID, c.SHORT_NAME, c.NAME FROM customers c ' +
'WHERE EXISTS (SELECT 1 FROM corrugated_plate_orders cpo WHERE cpo.COMPANY_ID = c.CUSTOMER_ID) '+
'OR EXISTS (SELECT 1 FROM web_plate_orders wpo WHERE wpo.COMPANY_ID = c.CUSTOMER_ID) ORDER BY c.SHORT_NAME';
doQuery(ordersDB.UniQuery1, SQL);
while not ordersDB.UniQuery1.Eof do
begin
Memo2.Lines.Add(ordersDB.UniQuery1.FieldByName('CUSTOMER_ID').AsString + ', ' + ordersDB.UniQuery1.FieldByName('SHORT_NAME').AsString + ', ' + ordersDB.UniQuery1.FieldByName('NAME').AsString);
OrdersDB.UniQuery1.Next;
count := count + 1;
end;
Memo2.Lines.Add('Showing ' + IntToStr(count) + ' entries');
end;
procedure TfQB.getCustomers();
var
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
jsObj: TJSONObject;
CustomerList: TJSONArray;
pair: TJSONPair;
ModifiedList: TJSONArray;
ParsedCustomer, Customer: TJSONObject;
I: integer;
BillAddr: TJSONObject;
ShipAddr: TJSONObject;
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;
//res := '/v3/company/' + companyID + '/preferences';
res := '/v3/company/' + companyID + '/query?query=select * from Customer&minorversion=75'; // '/customer/58';
restRequest.Resource := res;
///query?query=select * from Customer where CompanyName = ' + quotedStr('TYOGA CONTAINER') + '&minorversion=75';
param := restRequest.Params.AddItem;
param.Name := 'Authorization';
param.Kind := pkHTTPHEADER;
param.Options := param.Options + [TRESTRequestParameterOption.poDoNotEncode];
param.Value := 'Bearer ' + AccessToken;
restRequest.Execute;
//memo1.Lines.Add(restresponse.Content);
jsValue := restResponse.JSONValue;
jsObj := TJSONObject(jsValue);
Memo2.Lines.Add(res);
Memo2.Lines.Add( jsObj.Format(2) );
//CustomerList := TJSONArray(restResponse.JSONValue);
CustomerList := TJSONArray( TJSONObject( jsObj.GetValue('QueryResponse') ).GetValue('Customer')) ;
LoadJSONArray( CustomerList );
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
procedure TfQB.ConfigureSSL(IOHandler: TIdSSLIOHandlerSocketOpenSSL);
begin
// For Indy 10.6.2+ (Delphi 10.2 Tokyo+)
IOHandler.SSLOptions.Method := sslvTLSv1_2;
// Set SSL versions - maximum compatibility
IOHandler.SSLOptions.SSLVersions := [sslvTLSv1_2];
// For very old Indy versions (fallback)
if not (sslvTLSv1_2 in IOHandler.SSLOptions.SSLVersions) then
begin
IOHandler.SSLOptions.Method := sslvSSLv23;
IOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
end;
IOHandler.SSLOptions.Mode := sslmClient;
end;
procedure TfQB.FormCreate(Sender: TObject);
var
iniFile: TIniFile;
begin
inherited;
ordersDB := TApiDatabase.Create(nil);
iniFile := TIniFile.Create( ExtractFilePath(Application.ExeName) + 'kgOrdersServer.ini' );
Client := iniFile.ReadString('Quickbooks', 'ClientID', '');
Secret := iniFile.ReadString('Quickbooks', 'ClientSecret', '');
CompanyID := iniFile.ReadString('Quickbooks', 'CompanyID', '');
RefreshToken := iniFile.ReadString('Quickbooks', 'RefreshToken', '');
end;
procedure TfQB.FormDestroy(Sender: TObject);
begin
ordersDB.Free;
inherited;
end;
function TfQB.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;
iniFile: TIniFile;
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
Logger.Log(1, 'Missing Client ID or Client Secret in INI File');
Exit();
end;
EncodedAuth := Encoder.Encode(Client + ':' + Secret);
Memo1.Lines.Add(EncodedAuth);
if RefreshToken = '' then
begin
Logger.Log(3, 'Missing Refresh Token, Please Manually Get a New One and Store in INI File');
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 (EXACT match with Postman)
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;
Logger.Log(1, 'qbAPI - Tokens Successfully Saved');
Memo1.Lines.Add('Tokens Successfully Saved');
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 TfQB.getCompanyInfo();
var
restClient: TRESTClient;
restRequest: TRESTRequest;
restResponse: TRESTResponse;
param: TRESTRequestParameter;
res: string;
jsValue: TJSONValue;
jsObj, companyInfo: TJSONObject;
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;
res := '/v3/company/' + companyID + '/companyinfo/' + companyID;
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;
memo1.Lines.Add(restresponse.Content) ;
//jsValue := restResponse.JSONValue;
//jsObj := TJSONObject.ParseJSONValue(restresponse.Content) as TJSONObject;
//companyInfo := TJSONObject(jsObj.GetValue('CompanyInfo'));
restClient.Free;
restRequest.Free;
restResponse.Free;
end;
procedure TfQB.LoadJsonArray(jaData: TJSONArray);
var
jso: TJSONObject;
i, j: integer;
row: integer;
begin
Memo1.Lines.Add( '---------------------------------------------------------------' );
Memo1.Lines.Add( 'LoadJsonArray into asgData' );
asgData.ClearAll;
asgData.RowCount := 1;
asgData.StartUpdate;
jso := TJSONObject(jaData.Items[0]);
asgData.ColCount := jso.Count;
for i := 0 to jso.Count - 1 do
asgData.Cells[i+1, 0] := jso.Pairs[i].JsonString.Value;
for i := 0 to jaData.Count - 1 do
begin
jso := TJSONObject(jaData.Items[i]);
asgData.RowCount := asgData.RowCount + 1;
row := asgData.RowCount - 1;
for j := 0 to jso.Count - 1 do
asgData.Cells[j+1, row] := jso.Pairs[j].JsonValue.Value;
end;
asgData.EndUpdate;
asgData.AutoSizeColumns(true);
end;
end.
...@@ -25,7 +25,10 @@ uses ...@@ -25,7 +25,10 @@ uses
rOrderList in 'Source\rOrderList.pas' {rptOrderList: TDataModule}, rOrderList in 'Source\rOrderList.pas' {rptOrderList: TDataModule},
rOrderCorrugated in 'Source\rOrderCorrugated.pas' {rptOrderCorrugated: TDataModule}, rOrderCorrugated in 'Source\rOrderCorrugated.pas' {rptOrderCorrugated: TDataModule},
rOrderWeb in 'Source\rOrderWeb.pas' {rptOrderWeb: TDataModule}, rOrderWeb in 'Source\rOrderWeb.pas' {rptOrderWeb: TDataModule},
rOrderCutting in 'Source\rOrderCutting.pas' {rptOrderCutting: TDataModule}; rOrderCutting in 'Source\rOrderCutting.pas' {rptOrderCutting: TDataModule},
qbAPI in 'Source\qbAPI.pas' {fQB},
QBService in 'QBService.pas',
QBServiceImplementation in 'QBServiceImplementation.pas';
type type
TMemoLogAppender = class( TInterfacedObject, ILogAppender ) TMemoLogAppender = class( TInterfacedObject, ILogAppender )
......
...@@ -203,6 +203,12 @@ ...@@ -203,6 +203,12 @@
<FormType>dfm</FormType> <FormType>dfm</FormType>
<DesignClass>TDataModule</DesignClass> <DesignClass>TDataModule</DesignClass>
</DCCReference> </DCCReference>
<DCCReference Include="Source\qbAPI.pas">
<Form>fQB</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="QBService.pas"/>
<DCCReference Include="QBServiceImplementation.pas"/>
<BuildConfiguration Include="Base"> <BuildConfiguration Include="Base">
<Key>Base</Key> <Key>Base</Key>
</BuildConfiguration> </BuildConfiguration>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
MemoLogLevel=3 MemoLogLevel=3
FileLogLevel=5 FileLogLevel=5
webClientVersion=0.9.3 webClientVersion=0.9.3
LogFileNum=453 LogFileNum=621
[Database] [Database]
--Server=192.168.159.131 --Server=192.168.159.131
...@@ -13,3 +13,10 @@ Username=root ...@@ -13,3 +13,10 @@ Username=root
Password=emsys01 Password=emsys01
--Password=emsys!012 --Password=emsys!012
[Quickbooks]
CompanyID=9341454272655710
ClientID=ABgO14uvjh8XqLud7spQ8lkb98AUpcdA7HbyMJfCAtl65sQ5yy
ClientSecret=bQ06TRemHeAGFzVHRaTUvUoBU9jpU9itK6MOMgqN
RefreshToken=RT1-113-H0-1757255538seyqgsf5e04vo9schkoa
AccessToken=eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwieC5vcmciOiJIMCJ9..Cqnj0xScf85NYKa6g4lanA.LN1AIU3ZlnDDbIMt-J4vl8V_gvcTfynSjGKYsmbhbfBJovq5IfZU4dHt6cqDAwUfnfOm42l-OpbwN9hWrZvUGlVx8x_3MA-vdtxIOByp7neq5vL2t4XcR5svPKIkX-CqlTsTb2ylBARiXehgk3tVHBysbHcnp0Ka0Ic_Waj64wQMYvE3Z-D19gCu-Xn9WFQwDICn8HSgJmHL2huLvRX-OrcxH6uERzLcQqRLsgT7fx9j68UWDW-KL_KRnzE43ieXlxXCwiCDnaF39Ei5iPHstnh19lGMgo1Z1mlF6tVZ9-8Z1prZutpiX8rzaPzS7Wdqo8pKtYaUqQZP6AGa6ZCqWR2BlF3y-R_FtheERNpafRiXWIDW68jOOrgp8QXc1uKA0sxDMjiLE7Bd0t9QAsIzln-0WiWIXFSlLGLimMd2oxxLoR7fpQvgB851I50b4S3V-c891WA8bHfuzScmjVwp40JxofhviFXwAevLNzRYvGkvIyz4oS9d6U6K_ZWKDB3iYxEgJzkFFwnfuPybWX7iNHwnmvFfAXz61jdaL9KRJM-lCChGuaQuv8_df9z_az_sbUtXJw2I8ivEppmDEQVxv49ZwzJlb6bFbqtnhy6ILO7_ecx3G1d4Utg-BrtgvzsR.oFJV6VBShL1-cERGZEqqkw
LastRefresh=5/28/2025 10:46:30 AM
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
"jwtTokenSecret": "super_secret0123super_secret4567", "jwtTokenSecret": "super_secret0123super_secret4567",
"adminPassword": "whatisthisusedfor", "adminPassword": "whatisthisusedfor",
"webAppFolder": "static", "webAppFolder": "static",
"reportsFolder": "reports/" "reportsFolder": "..\\kgOrdersClient\\TMSWeb\\Debug\\"
} }
\ No newline at end of file
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