Files
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

1459 lines
62 KiB
Plaintext
Executable File

@{
ViewBag.Title = "Search";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
.k-upload .k-upload-status-total {
visibility: hidden;
}
.k-grid-content {
max-height: 300px;
}
</style>
@Scripts.Render("~/Scripts/confirmationDialog.js")
@Scripts.Render("~/Scripts/model/models.js")
@Scripts.Render("~/Scripts/jQuery-ui-1.9.0.min.js")
@Scripts.Render("~/Scripts/jQuery.FileUpload/jquery.fileupload.js")
@Scripts.Render("~/Scripts/jQuery.FileUpload/jquery.iframe-transport.js")
@Scripts.Render("~/Scripts/jQuery.FileUpload/jquery.fileupload-process.js")
@Scripts.Render("~/Scripts/jQuery.FileUpload/jquery.fileupload-ui.js")
@Scripts.Render("~/Scripts/js-cookie/js.cookie.js")
@Scripts.Render("~/Scripts/jquery.signalR-2.2.1.js")
<script src="~/signalr/hubs"></script>
<h2>
@ViewBag.Title
<button id="submitBTN" class="btn btn-sm btn-primary">Submit</button>
</h2>
<div id="editPanel">
<!-- Readonly notice -->
<div class="alert alert-warning" data-bind="visible: IsReadOnly" style="display: none;">
<strong>Note:</strong> search is readonly because it has already been submitted. To change or re-run the search again click the Copy button.
<button class="btn btn-default" id="copyBTN">Copy</button>
</div>
<!-- Search general data-->
<div class="panel panel-default">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="col-md-3 checkbox">
Search Details
</div>
</div>
</div>
<div class="panel-body container" style="padding-left: 0;">
<div class="form-group col-md-12">
<label for="searchTypeDD">Search Type</label>
<input data-role="dropdownlist"
data-auto-bind="false"
data-text-field="Name"
data-value-field="ID"
data-option-label="Select type"
class="form-control"
id="searchTypeDD"
name="searchTypeDD"
style="width: 100%"
data-bind="value: SearchType, disabled: IsReadOnly, source: ValidCombinations, events: {change: SearchType_Change}"
required data-required-msg="Search Type is required.">
<span class="k-invalid-msg" data-for="searchTypeDD"></span>
</div>
<div class="form-group col-md-12">
<label for="nameTB">Name</label>
<input type="text" class="form-control" id="nameTB" name="nameTB" data-bind="value: Name, readonly: IsReadOnly" required data-required-msg="Name is required.">
<span class="k-invalid-msg" data-for="nameTB"></span>
</div>
<div class="form-group col-md-4">
<label for="searchSubmitDTTB">Submitted At</label>
<input type="text"
class="form-control"
id="searchSubmitDTTB"
readonly="readonly"
data-bind="value: SubmitDT">
</div>
<div class="form-group col-md-4">
<label for="searchStartDTTB">Started At</label>
<input type="text"
class="form-control"
id="searchStartDTTB"
readonly="readonly"
data-bind="value: StartDT">
</div>
<div class="form-group col-md-4">
<label for="searchEndDTTB">Completed At</label>
<input type="text"
class="form-control"
id="searchEndDTTB"
readonly="readonly"
data-bind="value: EndDT">
</div>
<div class="form-group col-md-4">
<label for="usernameTB">User</label>
<input type="text" class="form-control" id="usernameTB" readonly="readonly" data-bind="value: UserName">
</div>
<div class="form-group col-md-4">
<label for="searchStatusTB">Status</label>
<input type="text" class="form-control" id="searchStatusTB" readonly="readonly" data-bind="value: Status, style: {backgroundColor: StatusColor}">
</div>
<div class="form-group col-md-4" style="display: none;" data-bind="visible: HasResults">
<label for="downloadResultsBTN">&nbsp;</label>
<button class="btn btn-success form-control" id="downloadResultsBTN" style="text-align: center;" data-bind="click: downloadResults">Download Results</button>
</div>
</div>
</div>
<!-- Search criteria -->
<div id="criteriaTab">
<!-- Timespan filter -->
<div class="panel panel-default" data-bind="visible: TimeSpan_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0;">
<div class="col-md-3 checkbox">
Filter by timespan
</div>
</div>
</div>
<div class="panel-body container" style="padding-left: 0;">
<div class="form-group col-md-5">
<label for="minimumTimeStampTB">Min Date</label>
<input data-role="datepicker"
data-bind="value: MinimumDT, enabled: TimeSpan_FilterFlag"
name="minimumTimeStampTB"
id="minimumTimeStampTB"
style="width: 100%;"
required data-required-msg="Min Date is required.">
<span class="k-invalid-msg" data-for="minimumTimeStampTB"></span>
</div>
<div class="form-group col-md-5 col-md-offset-1">
<label for="maximumTimeStampTB">Max Date</label>
<input data-role="datepicker"
data-bind="value: MaximumDT, enabled: TimeSpan_FilterFlag"
name="maximumTimeStampTB"
id="maximumTimeStampTB"
style="width: 100%;"
required data-required-msg="Max Date is required.">
<span class="k-invalid-msg" data-for="maximumTimeStampTB"></span>
</div>
</div>
</div>
<!-- Work order filter -->
<div class="panel panel-default" data-bind="visible: LotNumbers_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0;">
<div class="col-md-3 checkbox">
Filter by work order
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="lotNumberDownloadBTN" class="btn btn-default templateDownload">Download Template</button>
<label for="lotNumberUpload" class="btn btn-default templateUpload">Upload Data</label>
<input type="file" name="lotNumberUpload" id="lotNumberUpload" style="display: none" />
<button id="lotNumberClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div id="LotNumbers_Grid"
data-role="grid"
data-editable="false"
data-bind="source: LotNumbers"
data-columns="[
{ 'field': 'WorkOrderNumber', title: 'Work Order Number' },
{ 'field': 'ItemNumber', title: 'Item Number' }
]"
style="min-height: 50px;"></div>
<div class="col-md-12" style="font-weight: bold; margin-top: 10px;">
# of work orders: <span data-bind="text: LotNumbers.data().length"></span>
</div>
</div>
</div>
<!-- Items filter -->
<div class="panel panel-default" data-bind="visible: PartNumbers_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="col-md-3 checkbox">
Filter by item number
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="partNumberDownloadBTN" class="btn btn-default templateDownload">Download Template</button>
<label for="partNumberUpload" class="btn btn-default templateUpload">Upload Data</label>
<input type="file" name="partNumberUpload" id="partNumberUpload" style="display: none" />
<button id="PartNumbers_ClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div class="form-group col-md-12">
<label for="PartNumbers_DD">Item Number</label>
<input type="text" class="form-control" id="PartNumbers_DD" style="width: 550px;" />
<button class="btn btn-default" data-bind="visible: PartNumbers_AddItemSelected" id="PartNumbers_AddBTN">Add to filter</button>
</div>
<div id="PartNumbers_Grid"
data-role="grid"
data-editable="false"
data-bind="source: PartNumbers"
data-columns="[
{ 'field': 'ItemNumber', title: 'Item Number' },
{ 'field': 'Description', title: 'Description' },
{ 'command' : [ { 'name' : 'deleteItem', 'text': 'Delete', 'click': viewModel.DeletePartNumber} ], 'title': 'Actions', 'width': '100px'}
]"
style="min-height: 50px;"></div>
<div class="col-md-12" style="font-weight: bold; margin-top: 10px;">
# of item numbers: <span data-bind="text: PartNumbers.data().length"></span>
</div>
</div>
</div>
<!-- Profit centers filter -->
<div class="panel panel-default" data-bind="visible: ProfitCenters_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3">
Filter by profit center
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="ProfitCenters_ClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div class="form-group col-md-12">
<label for="ProfitCenters_DD">Profit Center</label>
<input type="text" class="form-control" id="ProfitCenters_DD" style="width: 550px;" />
<button class="btn btn-default" data-bind="visible: ProfitCenters_AddItemSelected" id="ProfitCenters_AddBTN">Add to filter</button>
</div>
<div id="ProfitCenters_Grid"
data-role="grid"
data-editable="false"
data-bind="source: ProfitCenters"
data-columns="[
{ 'field': 'Code', title: 'Profit Center' },
{ 'field': 'Description', title: 'Description' },
{ 'command' : [ { 'name' : 'deleteItem', 'text': 'Delete', 'click': viewModel.DeleteProfitCenter} ], 'title': 'Actions', 'width': '100px'}
]"
style="min-height: 50px;"></div>
</div>
</div>
<!-- Work centers filter -->
<div class="panel panel-default" data-bind="visible: WorkCenters_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3">
Filter by work center
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="WorkCenters_ClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div class="form-group col-md-12">
<label for="WorkCenters_DD">Work Center</label>
<input type="text" class="form-control" id="WorkCenters_DD" style="width: 550px;" />
<button class="btn btn-default" data-bind="visible: WorkCenters_AddItemSelected" id="WorkCenters_AddBTN">Add to filter</button>
</div>
<div id="WorkCenters_Grid"
data-role="grid"
data-editable="false"
data-bind="source: WorkCenters"
data-columns="[
{ 'field': 'Code', title: 'Work Center' },
{ 'field': 'Description', title: 'Description' },
{ 'command' : [ { 'name' : 'deleteItem', 'text': 'Delete', 'click': viewModel.DeleteWorkCenter} ], 'title': 'Actions', 'width': '100px', 'disabled': viewModel.IsReadOnly}
]"
style="min-height: 50px;"></div>
</div>
</div>
<!-- Component lots filter-->
<div class="panel panel-default" data-bind="visible: ComponentLotNumbers_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3">
Filter by component lot
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="componentLotNumberDownloadBTN" class="btn btn-default templateDownload">Download Template</button>
<label for="componentLotNumberUpload" class="btn btn-default templateUpload">Upload Data</label>
<input type="file" name="componentLotNumberUpload" id="componentLotNumberUpload" style="display: none" />
<button id="componentLotNumberClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div id="ComponentLotNumbers_Grid"
data-role="grid"
data-editable="false"
data-bind="source: ComponentLotNumbers"
data-columns="[
{ 'field': 'LotNumber', title: 'Lot Number' },
{ 'field': 'ItemNumber', title: 'Item Number' }
]"
style="min-height: 50px;"></div>
<div class="col-md-12" style="font-weight: bold; margin-top: 10px;">
# of component lots: <span data-bind="text: ComponentLotNumbers.total()"></span>
</div>
</div>
</div>
<!-- Operators filter -->
<div class="panel panel-default" data-bind="visible: OperatorIDs_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3">
Filter by operator
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="OperatorIDs_ClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div class="form-group col-md-12">
<label for="OperatorIDs_DD">Name</label>
<input type="text" class="form-control" id="OperatorIDs_DD" style="width: 650px;" />
<button class="btn btn-default" data-bind="visible: OperatorIDs_AddItemSelected" id="OperatorIDs_AddBTN">Add to filter</button>
</div>
<div id="OperatorIDs_Grid"
data-role="grid"
data-editable="false"
data-bind="source: OperatorIDs"
data-columns="[
{ 'field': 'AddressNumber', title: 'Address Number' },
{ 'field': 'UserID', title: 'User Name' },
{ 'field': 'FullName', title: 'Full Name' },
{ 'command' : [ { 'name' : 'deleteItem', 'text': 'Delete', 'click': viewModel.DeleteOperatorID} ], 'title': 'Actions', 'width': '100px'}
]"
style="min-height: 50px;"></div>
</div>
</div>
<!-- PartOperations filter -->
<div class="panel panel-default" data-bind="visible: PartOperations_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3">
Filter By Item/Operation/MIS
</div>
<div class="col-md-9">
<div class="btn-group" style="float: right;">
<button id="partOperationDownloadBTN" class="btn btn-default templateDownload">Download Template</button>
<label for="partOperationUpload" class="btn btn-default templateUpload">Upload Data</label>
<input type="file" name="partOperationUpload" id="partOperationUpload" style="display: none" />
<button id="partOperationClearBTN" class="btn btn-default clearButton">Clear Data</button>
</div>
</div>
</div>
</div>
<div class="panel-body container">
<div id="PartOperations_Grid"
data-role="grid"
data-editable="false"
data-bind="source: PartOperations"
data-columns="[
{ 'field': 'ItemNumber', title: 'Item Number' },
{ 'field': 'OperationNumber', title: 'Operation Step Number' },
{ 'field': 'MisNumber', title: 'MIS Number' },
{ 'field': 'MisRevision', title: 'MIS Revision' }
]"
style="min-height: 50px;"></div>
<div class="col-md-12" style="font-weight: bold; margin-top: 10px;">
# of item / operations: <span data-bind="text: PartOperations.data().length"></span>
</div>
</div>
</div>
<!-- ExtractMisData option -->
<div class="panel panel-default" data-bind="visible: ExtractMisData_FilterFlag">
<div class="panel-heading">
<div class="container" style="padding-left: 0px;">
<div class="checkbox col-md-3" style="margin-top: 0px; margin-bottom: 0px;">
<label for="ExtractMisData_CB">
<input type="checkbox" id="ExtractMisData_CB" data-bind="checked: ExtractMisData_FilterFlag" readonly="readonly" disabled="disabled">
Extract MIS data
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document.body).delegate('[type="checkbox"][readonly="readonly"]', 'click', function (e) {
e.preventDefault();
});
//Setup date formatting
kendo.data.binders.date = kendo.data.Binder.extend({
init: function (element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
this.dateformat = $(element).data("dateformat");
},
refresh: function () {
var data = this.bindings["date"].get();
if (data) {
var dateObj = new Date(data);
$(this.element).text(kendo.toString(dateObj, this.dateformat));
}
}
});
var validator = null;
var editPanel = null;
var viewModel = new kendo.observable({
//Search details
ID: null,
Name: null,
SubmitDT: null,
StartDT: null,
EndDT: null,
UserName: null,
Status: null,
StatusColor: function() {
if (this.get('Status') === 'Error') {
return '#FF6347';
} else {
return '#eee';
}
},
//Timestamp filter
TimeSpan_FilterFlag: false,
MinimumDT: null,
MaximumDT: null,
//Work order filter
LotNumbers_FilterFlag: false,
LotNumbers: new kendo.data.DataSource({ data: [] }),
//Items filter
PartNumbers_FilterFlag: false,
PartNumbers_AddItem: null,
PartNumbers_AddItemSelected: function() {
return this.get('PartNumbers_AddItem') != null;
},
PartNumbers: new kendo.data.DataSource({
schema: {
model: {
id: 'ItemNumber'
}
},
data: []
}),
DeletePartNumber: function(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.get("PartNumbers").pushDestroy(dataItem);
},
//Profit centers filter
ProfitCenters_FilterFlag: false,
ProfitCenters_AddItem: null,
ProfitCenters_AddItemSelected: function() {
return this.get('ProfitCenters_AddItem') != null;
},
ProfitCenters: new kendo.data.DataSource({
schema: {
model: {
id: 'Code'
}
},
data: []
}),
DeleteProfitCenter: function(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.get("ProfitCenters").pushDestroy(dataItem);
},
//Work centers filter
WorkCenters_FilterFlag: false,
WorkCenters_AddItem: null,
WorkCenters_AddItemSelected: function() {
return this.get('WorkCenters_AddItem') != null;
},
WorkCenters: new kendo.data.DataSource({
schema: {
model: {
id: 'Code'
}
},
data: []
}),
DeleteWorkCenter: function(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.get("WorkCenters").pushDestroy(dataItem);
},
//Operators filter
OperatorIDs_FilterFlag: false,
OperatorIDs_AddItem: null,
OperatorIDs_AddItemSelected: function() {
return this.get('OperatorIDs_AddItem') != null;
},
OperatorIDs: new kendo.data.DataSource({
schema: {
model: {
id: 'UserID'
}
},
data: []
}),
DeleteOperatorID: function(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
viewModel.get("OperatorIDs").pushDestroy(dataItem);
},
//Component lots filter
ComponentLotNumbers_FilterFlag: false,
ComponentLotNumbers: new kendo.data.DataSource({ data: [] }),
//Part operations filter
PartOperations_FilterFlag: false,
PartOperations: new kendo.data.DataSource({ data: [] }),
//Extract MIS data option
ExtractMisData_FilterFlag: false,
IsReadOnly: true,
HasResults: false,
downloadResults: function() {
var searchID = this.get('ID');
window.open('@Url.Action("GetResults", "Search")?id=' + searchID, '_blank');
},
ValidCombinations: validCombinations,
SearchType: null,
SearchType_Change: function () {
var searchType = this.get("SearchType") || new ValidCombination();
this.set("TimeSpan_FilterFlag", searchType.Timespan);
this.set("LotNumbers_FilterFlag", searchType.WorkOrder);
this.set("PartNumbers_FilterFlag", searchType.ItemNumber);
this.set("ProfitCenters_FilterFlag", searchType.ProfitCenter);
this.set("WorkCenters_FilterFlag", searchType.WorkCenter);
this.set("ComponentLotNumbers_FilterFlag", searchType.ComponentLot);
this.set("OperatorIDs_FilterFlag", searchType.Operator);
this.set("PartOperations_FilterFlag", searchType.ItemOperationMis);
this.set("ExtractMisData_FilterFlag", searchType.ExtractMis);
}
});
viewModel.setData = function (data) {
//Ensure data is not null
data = data || new Object();
//Parse details
this.set('ID', getValue(data.ID, null));
this.set('Name', getValue(data.Name, null));
var submitDT = getValue(data.SubmitDT, null);
this.set('SubmitDT', submitDT != null ? kendo.toString(kendo.parseDate(submitDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
var startDT = getValue(data.StartDT, null);
this.set('StartDT', startDT != null ? kendo.toString(kendo.parseDate(startDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
var endDT = getValue(data.EndDT, null);
this.set('EndDT', endDT != null ? kendo.toString(kendo.parseDate(endDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
this.set('UserName', getValue(data.UserName, null));
//Set status
var statusCode = getValue(data.Status, null);
this.set('Status', statusCode);
if (statusCode === 'Ended') {
this.set('HasResults', true);
}
//Parse timestamp filter
this.set('MinimumDT', getValue(data.Criteria.MinimumDT, null));
this.set('MaximumDT', getValue(data.Criteria.MaximumDT, null));
this.set('TimeSpan_FilterFlag', (data.Criteria.MinimumDT!==null || data.Criteria.MaximumDT !== null));
//Parse work orders
this.LotNumbers.data(data.Criteria.WorkOrders);
this.set('LotNumbers_FilterFlag', this.LotNumbers.data().length > 0);
//Parse items
this.PartNumbers.data(data.Criteria.Items);
this.set('PartNumbers_FilterFlag', this.PartNumbers.data().length > 0);
//Parse profit centers
this.ProfitCenters.data(data.Criteria.ProfitCenters);
this.set('ProfitCenters_FilterFlag', this.ProfitCenters.data().length > 0);
//Parse work centers
this.WorkCenters.data(data.Criteria.WorkCenters);
this.set('WorkCenters_FilterFlag', this.WorkCenters.data().length > 0);
//Parse component lots
this.ComponentLotNumbers.data(data.Criteria.ComponentLots);
this.set('ComponentLotNumbers_FilterFlag', this.ComponentLotNumbers.data().length > 0);
//Parse operators
this.OperatorIDs.data(data.Criteria.Operators);
this.set('OperatorIDs_FilterFlag', this.OperatorIDs.data().length > 0);
//Parse part operations
this.PartOperations.data(data.Criteria.PartOperations);
this.set('PartOperations_FilterFlag', this.PartOperations.data().length > 0);
//Parse extract MIS data option
this.set('ExtractMisData_FilterFlag', getValue(data.Criteria.ExtractMisData, null) || false);
//Find matching search type
var timeSpan = this.get('TimeSpan_FilterFlag');
var workOrder = this.get('LotNumbers_FilterFlag');
var itemNumber = this.get('PartNumbers_FilterFlag');
var profitCenter = this.get('ProfitCenters_FilterFlag');
var workCenter = this.get('WorkCenters_FilterFlag');
var componentLot = this.get('ComponentLotNumbers_FilterFlag');
var operator = this.get('OperatorIDs_FilterFlag');
var itemOperationMis = this.get('PartOperations_FilterFlag');
var extractMis = this.get('ExtractMisData_FilterFlag');
for (var i = 0; i < this.ValidCombinations.length; i++) {
var validCombination = this.ValidCombinations[i];
if (validCombination.matches(timeSpan, workOrder, itemNumber, profitCenter, workCenter, componentLot, operator, itemOperationMis, extractMis)) {
this.set('SearchType', validCombination);
break;
}
}
if (statusCode === 'New') {
this.set('IsReadOnly', false);
} else {
this.set('IsReadOnly', true);
//Setup read-only
$('#submitBTN').hide();
$("#editPanel input").prop("disabled", true);
$("#editPanel .k-button").each(function(index) {
$(this).hide();
});
$('.templateDownload').hide();
$('.templateUpload').hide();
$('.clearButton').hide();
$("#minimumTimeStampTB").data("kendoDatePicker").enable(false);
$("#maximumTimeStampTB").data("kendoDatePicker").enable(false);
$("#PartNumbers_DD").data("kendoComboBox").enable(false);
$("#ProfitCenters_DD").data("kendoComboBox").enable(false);
$("#WorkCenters_DD").data("kendoComboBox").enable(false);
$("#OperatorIDs_DD").data("kendoComboBox").enable(false);
}
};
//Register to search update events
var statusHub = $.connection.statusHub;
statusHub.client.searchUpdate = function (searchUpdate) {
var thisID = viewModel.get('ID');
if (searchUpdate.ID === thisID) {
var submitDT = getValue(searchUpdate.SubmitDT, null);
viewModel.set('SubmitDT', submitDT != null ? kendo.toString(kendo.parseDate(submitDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
var startDT = getValue(searchUpdate.StartDT, null);
viewModel.set('StartDT', startDT != null ? kendo.toString(kendo.parseDate(startDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
var endDT = getValue(searchUpdate.EndDT, null);
viewModel.set('EndDT', endDT != null ? kendo.toString(kendo.parseDate(endDT), 'MM/dd/yyyy hh:mm:ss tt') : null);
//Set status
var statusCode = getValue(searchUpdate.Status, null);
viewModel.set('Status', statusCode);
if (statusCode === 'Ended') {
viewModel.set('HasResults', true);
}
}
};
window.hubReady = $.connection.hub.start().done(function () { });
$.connection.hub.disconnected(function () {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
$(document).ready(function () {
$.ajaxSetup({ cache: false });
//Find grid container
editPanel = $('#editPanel');
//Bind data model
kendo.bind(editPanel, viewModel);
//Display loading indicator
kendo.ui.progress(editPanel, true);
validator = $("#editPanel").kendoValidator({
rules: {
datepicker: function(input) {
if (input.is("[data-role=datepicker]")) {
//Get the DatePicker instance
var dp = input.data("kendoDatePicker");
//Get the DatePicker value (the input parsed by the widget)
var dpValue = dp.value();
//Get the DatePicker input as is - no parsing whatsoever
var dpUserInput = dp.element.val();
if(!dpValue && dpUserInput){
return false;
}
return true;
} else {
return true;
}
}
},
messages: {
datepicker: "Invalid date"
}
}).data("kendoValidator");
//Check if session details need to be loaded
var id = getParameterByName('id');
var copySearchID = getParameterByName('copySearchID');
if (copySearchID) {
copySearchDetails(copySearchID);
} else {
loadSearchDetails(id);
}
function startChange() {
var startDate = minTimestampPicker.value(),
endDate = maxTimestampPicker.value();
if (!startDate) {
maxTimestampPicker.min(new Date(2002,10,1));
}
if (startDate) {
startDate = new Date(startDate);
startDate.setDate(startDate.getDate());
maxTimestampPicker.min(startDate);
} else if (endDate) {
minTimestampPicker.max(new Date(endDate));
} else {
minTimestampPicker.max(new Date());
maxTimestampPicker.min(new Date(2002,10,1));
}
}
function endChange() {
var endDate = maxTimestampPicker.value(),
startDate = minTimestampPicker.value();
if (!endDate) {
minTimestampPicker.max(new Date());
}
if (endDate) {
endDate = new Date(endDate);
endDate.setDate(endDate.getDate());
minTimestampPicker.max(endDate);
} else if (startDate) {
maxTimestampPicker.min(new Date(startDate));
} else {
minTimestampPicker.max(new Date());
maxTimestampPicker.min(new Date(2002,10,1));
}
}
var minTimestampPicker = $("#minimumTimeStampTB").kendoDatePicker({
change: startChange,
min: new Date(2002, 10, 1),
max: new Date()
}).data("kendoDatePicker");
var maxTimestampPicker = $("#maximumTimeStampTB").kendoDatePicker({
change: endChange,
min: new Date(2002, 10, 1),
max: new Date()
}).data("kendoDatePicker");
//Setup work order number file upload
$('#lotNumberUpload').fileupload({
url: '@Url.Action("UploadWorkOrders","FileIO")',
dataType: 'json',
type: 'POST',
autoUpload: true,
done: function (e, data) {
if (data.result && data.result.WasSuccessful) {
//Use new work order data
viewModel.LotNumbers.data(data.result.Data);
} else {
alert('Work order data upload failed.');
}
}
});
//Setup work order download button
$("#lotNumberDownloadBTN").click(function () {
//Collect existing data
var workOrders = new Array();
$.each(viewModel.get('LotNumbers').data(), function (index, workOrder) {
workOrders.push(workOrder.WorkOrderNumber);
});
//Upload data and download template data
$.post(
'@Url.Action("DownloadWorkOrders", "FileIO")',
{ workOrders: workOrders },
function (result) {
$("body").append("<iframe src='@Url.Action("DownloadWorkOrders", "FileIO")?key=" + result + "' style='display: none;' ></iframe>");
}
);
});
//Setup work order clear button
$("#lotNumberClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all work orders?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.LotNumbers.data([]);
}
});
});
//Setup PartNumbers combobox
$("#PartNumbers_DD").kendoComboBox({
dataTextField: "ItemNumber",
dataValueField: "ItemNumber",
autoBind: false,
minLength: 3,
filter: 'contains',
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: '@Url.Action("FindItem", "Lookup")',
data: function () {
return {
itemNumber: $("#PartNumbers_DD").data("kendoComboBox").text()
};
}
}
}
}),
template: "<table><tr><td width='150px'>${ ItemNumber }</td><td width='350px'>${ Description }</td></tr></table>",
select: function (e) {
if (e.item) {
var dataItem = this.dataItem(e.item.index());
var selectedItem = {
ItemNumber: dataItem.ItemNumber,
Description: dataItem.Description
};
viewModel.set('PartNumbers_AddItem', selectedItem);
} else {
viewModel.set('PartNumbers_AddItem', null);
}
},
change: function (e) {
if (!$("#PartNumbers_DD").data("kendoComboBox").dataItem()) {
viewModel.set('PartNumbers_AddItem', null);
}
}
});
$('<div/>').html("<table><tr><td width='150px'>Item Number</td><td width='350px'>Description</td></tr></table>").prependTo('#PartNumbers_DD-list');
$("#PartNumbers_AddBTN").click(function () {
//Get selection
var selectedItem = viewModel.get('PartNumbers_AddItem');
//Add selection to filter list
if (selectedItem) {
viewModel.PartNumbers.pushCreate(selectedItem);
}
//Clear selection
viewModel.set('PartNumbers_AddItem', null);
$("#PartNumbers_DD").data("kendoComboBox").text('');
});
$("#PartNumbers_ClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all items?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.PartNumbers.data([]);
}
});
});
//Setup part number upload button
$('#partNumberUpload').fileupload({
url: '@Url.Action("UploadPartNumbers","FileIO")',
dataType: 'json',
type: 'POST',
autoUpload: true,
done: function (e, data) {
if (data.result && data.result.WasSuccessful) {
//Use new work order data
viewModel.PartNumbers.data(data.result.Data);
} else {
alert('Part number data upload failed.');
}
}
});
//Setup part number download button
$("#partNumberDownloadBTN").click(function () {
//Collect existing data
var items = new Array();
$.each(viewModel.get('PartNumbers').data(), function (index, item) {
items.push({ItemNumber:item.ItemNumber,Description:item.Description});
});
//Upload data and download template data
$.post('@Url.Action("DownloadPartNumbers", "FileIO")', { items: items }, function (result) {
$("body").append("<iframe src='@Url.Action("DownloadPartNumbers", "FileIO")?key=" + result + "' style='display: none;' ></iframe>");
});
});
//Setup ProfitCenters combobox
$("#ProfitCenters_DD").kendoComboBox({
dataTextField: "Code",
dataValueField: "Code",
autoBind: false,
minLength: 3,
filter: 'contains',
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: '@Url.Action("FindProfitCenter", "Lookup")',
data: function () {
return {
profitCenter: $("#ProfitCenters_DD").data("kendoComboBox").text()
};
}
}
}
}),
template: "<table><tr><td width='150px'>${ Code }</td><td width='350px'>${ Description }</td></tr></table>",
select: function (e) {
if (e.item) {
var dataItem = this.dataItem(e.item.index());
var selectedItem = {
Code: dataItem.Code,
Description: dataItem.Description
};
viewModel.set('ProfitCenters_AddItem', selectedItem);
} else {
viewModel.set('ProfitCenters_AddItem', null);
}
},
change: function (e) {
if (!$("#ProfitCenters_DD").data("kendoComboBox").dataItem()) {
viewModel.set('ProfitCenters_AddItem', null);
}
}
});
$('<div/>').html("<table><tr><td width='150px'>Profit Center</td><td width='350px'>Description</td></tr></table>").prependTo('#ProfitCenters_DD-list');
$("#ProfitCenters_AddBTN").click(function () {
//Get selection
var selectedItem = viewModel.get('ProfitCenters_AddItem');
//Add selection to filter list
if (selectedItem) {
viewModel.ProfitCenters.pushCreate(selectedItem);
}
//Clear selection
viewModel.set('ProfitCenters_AddItem', null);
$("#ProfitCenters_DD").data("kendoComboBox").text('');
});
$("#ProfitCenters_ClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all profit centers?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.ProfitCenters.data([]);
}
});
});
//Setup WorkCenters combobox
$("#WorkCenters_DD").kendoComboBox({
dataTextField: "Code",
dataValueField: "Code",
autoBind: false,
minLength: 3,
filter: 'contains',
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: '@Url.Action("FindWorkCenter", "Lookup")',
data: function () {
return {
workCenter: $("#WorkCenters_DD").data("kendoComboBox").text()
};
}
}
}
}),
template: "<table><tr><td width='150px'>${ Code }</td><td width='350px'>${ Description }</td></tr></table>",
select: function (e) {
if (e.item) {
var dataItem = this.dataItem(e.item.index());
var selectedItem = {
Code: dataItem.Code,
Description: dataItem.Description
};
viewModel.set('WorkCenters_AddItem', selectedItem);
} else {
viewModel.set('WorkCenters_AddItem', null);
}
},
change: function (e) {
if (!$("#WorkCenters_DD").data("kendoComboBox").dataItem()) {
viewModel.set('WorkCenters_AddItem', null);
}
}
});
$('<div/>').html("<table><tr><td width='150px'>Work Center</td><td width='350px'>Description</td></tr></table>").prependTo('#WorkCenters_DD-list');
$("#WorkCenters_AddBTN").click(function () {
//Get selection
var selectedItem = viewModel.get('WorkCenters_AddItem');
//Add selection to filter list
if (selectedItem) {
viewModel.WorkCenters.pushCreate(selectedItem);
}
//Clear selection
viewModel.set('WorkCenters_AddItem', null);
$("#WorkCenters_DD").data("kendoComboBox").text('');
});
$("#WorkCenters_ClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all work centers?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.WorkCenters.data([]);
}
});
});
$('#componentLotNumberUpload').fileupload({
url: '@Url.Action("UploadComponentLots","FileIO")',
dataType: 'json',
type: 'POST',
autoUpload: true,
done: function (e, data) {
if (data.result && data.result.WasSuccessful) {
//Use new work order data
viewModel.ComponentLotNumbers.data(data.result.Data);
} else {
alert('Component lot number data upload failed.');
}
}
});
//Setup component lot number download button
$("#componentLotNumberDownloadBTN").click(function () {
//Collect existing data
var componentLotNumbers = new Array();
$.each(viewModel.get('ComponentLotNumbers').data(), function (index, componentLot) {
componentLotNumbers.push({ LotNumber: componentLot.LotNumber, ItemNumber: componentLot.ItemNumber});
});
//Upload data and download template data
$.post('@Url.Action("DownloadComponentLots", "FileIO")', { lotNumbers: componentLotNumbers }, function (result) {
$("body").append("<iframe src='@Url.Action("DownloadComponentLots", "FileIO")?key=" + result + "' style='display: none;' ></iframe>");
});
});
//Setup lot number clear button
$("#componentLotNumberClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all component lots?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.ComponentLotNumbers.data([]);
}
});
});
//Setup OperatorIDs combobox
$("#OperatorIDs_DD").kendoComboBox({
dataTextField: "FullName",
dataValueField: "UserID",
autoBind: false,
minLength: 3,
filter: 'contains',
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: '@Url.Action("FindOperator","Lookup")',
data: function () {
return {
operatorName: $("#OperatorIDs_DD").data("kendoComboBox").text()
};
}
}
}
}),
template: "<table style='table-layout: fixed; width: 650px;'><tr><td width='150px'>${ AddressNumber }</td><td width='150px'>${ UserID }</td><td width='350px'>${ FullName }</td></tr></table>",
select: function (e) {
if (e.item) {
var dataItem = this.dataItem(e.item.index());
var selectedItem = {
AddressNumber: dataItem.AddressNumber,
UserID: dataItem.UserID,
FullName: dataItem.FullName
};
viewModel.set('OperatorIDs_AddItem', selectedItem);
} else {
viewModel.set('OperatorIDs_AddItem', null);
}
},
change: function (e) {
if (!$("#OperatorIDs_DD").data("kendoComboBox").dataItem()) {
viewModel.set('OperatorIDs_AddItem', null);
}
}
});
$('<div/>').html("<table style='table-layout: fixed; width: 650px;'><tr><td width='150px'>Address #</td><td width='150px'>User ID</td><td width='350px'>Full Name</td></tr></table>").prependTo('#OperatorIDs_DD-list');
$("#OperatorIDs_AddBTN").click(function () {
//Get selection
var selectedItem = viewModel.get('OperatorIDs_AddItem');
//Add selection to filter list
if (selectedItem) {
viewModel.OperatorIDs.pushCreate(selectedItem);
}
//Clear selection
viewModel.set('OperatorIDs_AddItem', null);
$("#OperatorIDs_DD").data("kendoComboBox").text('');
});
$("#OperatorIDs_ClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all operators?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.OperatorIDs.data([]);
}
});
});
//Setup part/operation file upload
$('#partOperationUpload').fileupload({
url: '@Url.Action("UploadPartOperations","FileIO")',
dataType: 'json',
type: 'POST',
autoUpload: true,
done: function (e, data) {
if (data.result && data.result.WasSuccessful) {
viewModel.PartOperations.data(data.result.Data);
} else {
alert('Item/Operation data upload failed.');
}
}
});
//Setup part/operation download button
$("#partOperationDownloadBTN").click(function () {
//Collect existing data
var partOperations = new Array();
$.each(viewModel.get('PartOperations').data(), function (index, partOperation) {
partOperations.push({ ItemNumber: partOperation.ItemNumber, OperationNumber: partOperation.OperationNumber, MisNumber: partOperation.MisNumber, MisRevision: partOperation.MisRevision });
});
//Upload data and download template data
$.post(
'@Url.Action("DownloadPartOperations", "FileIO")',
{ partOperations: partOperations },
function (result) {
$("body").append("<iframe src='@Url.Action("DownloadPartOperations", "FileIO")?key=" + result + "' style='display: none;' ></iframe>");
}
);
});
//Setup part/operation clear button
$("#partOperationClearBTN").click(function () {
//Confirm action
$.when(showConfirmationWindow('Are you sure you want to clear all item/operation/MIS entries?')).then(function (confirmed) {
if (confirmed) {
//Clear data
viewModel.PartOperations.data([]);
}
});
});
//Setup save button handler
$('#submitBTN').click(function () {
//Verify selections are made correctly
var lotNumberFilter = viewModel.get('LotNumbers_FilterFlag');
var partNumberFilter = viewModel.get('PartNumbers_FilterFlag');
var profitCenterFilter = viewModel.get('ProfitCenters_FilterFlag');
var workCenterFilter = viewModel.get('WorkCenters_FilterFlag');
var componentLotFilter = viewModel.get('ComponentLotNumbers_FilterFlag');
var operatorFilter = viewModel.get('OperatorIDs_FilterFlag');
var partOperationsFilter = viewModel.get('PartOperations_FilterFlag');
if (lotNumberFilter && viewModel.get('LotNumbers').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one work order must be specified for the work order filter."
}).data("kendoAlert").open();
return;
}
if (partNumberFilter && viewModel.get('PartNumbers').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one item number must be specified for the item number filter."
}).data("kendoAlert").open();
return;
}
if (profitCenterFilter && viewModel.get('ProfitCenters').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one profit center must be specified for the profit center filter."
}).data("kendoAlert").open();
return;
}
if (workCenterFilter && viewModel.get('WorkCenters').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one work center must be specified for the work center filter."
}).data("kendoAlert").open();
return;
}
if (componentLotFilter && viewModel.get('ComponentLotNumbers').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one component lot must be specified for the component lot filter."
}).data("kendoAlert").open();
return;
}
if (operatorFilter && viewModel.get('OperatorIDs').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one operator must be specified for the operator filter."
}).data("kendoAlert").open();
return;
}
if (partOperationsFilter && viewModel.get('PartOperations').total() === 0) {
$("<div></div>").kendoAlert({
title: "Filter Validation Error",
content: "At least one item/operation/MIS entry must be specified for the MIS data filter."
}).data("kendoAlert").open();
return;
}
if (validator.validate()) {
$.when(showConfirmationWindow('Are you sure you want to submit the search?')).then(function(confirmed) {
if (confirmed) {
//Display waiting indicator
kendo.ui.progress(editPanel, true);
submitSearch();
}
});
}
});
});
//Saves the search details to the server
function submitSearch() {
//Set timeout
var errorTimeout = setTimeout(function () {
// Handle error accordingly
$("<div></div>").kendoAlert({
title: "Search Error",
content: "Failed to submit search to system."
}).data("kendoAlert").open();
alert("Failed to submit.");
kendo.ui.progress(editPanel, false);
}, 7500);
//Extract form data to save
var saveData = {
Name: viewModel.get('Name'),
UserName: viewModel.get('UserName'),
Criteria: {
MinimumDT: null,
MaximumDT: null,
WorkOrders: new Array(),
Items: new Array(),
ProfitCenters: new Array(),
WorkCenters: new Array(),
ComponentLots: new Array(),
Operators: new Array(),
PartOperations: new Array(),
ExtractMisData: viewModel.get('ExtractMisData_FilterFlag'),
CheckCamstar: viewModel.get('CheckCamstar_Flag')
}
};
//Extract min/max time settings if set
if (viewModel.get('TimeSpan_FilterFlag')) {
saveData.Criteria.MinimumDT = viewModel.get('MinimumDT');
saveData.Criteria.MaximumDT = viewModel.get('MaximumDT');
}
if (viewModel.get('LotNumbers_FilterFlag')) {
$.each(viewModel.get('LotNumbers').data(), function (index, workorder) {
saveData.Criteria.WorkOrders.push({ WorkOrderNumber: workorder.WorkOrderNumber });
});
}
if (viewModel.get('PartNumbers_FilterFlag')) {
$.each(viewModel.get('PartNumbers').data(), function (index, item) {
saveData.Criteria.Items.push({ ItemNumber: item.ItemNumber });
});
}
if (viewModel.get('ProfitCenters_FilterFlag')) {
$.each(viewModel.get('ProfitCenters').data(), function (index, profitCenter) {
saveData.Criteria.ProfitCenters.push({ Code: profitCenter.Code });
});
}
if (viewModel.get('WorkCenters_FilterFlag')) {
$.each(viewModel.get('WorkCenters').data(), function (index, workCenter) {
saveData.Criteria.WorkCenters.push({ Code: workCenter.Code });
});
}
if (viewModel.get('ComponentLotNumbers_FilterFlag')) {
$.each(viewModel.get('ComponentLotNumbers').data(), function (index, componentLotNumber) {
saveData.Criteria.ComponentLots.push({ LotNumber: componentLotNumber.LotNumber, ItemNumber: componentLotNumber.ItemNumber });
});
}
if (viewModel.get('OperatorIDs_FilterFlag')) {
$.each(viewModel.get('OperatorIDs').data(), function (index, operator) {
saveData.Criteria.Operators.push({ AddressNumber: operator.AddressNumber, UserID: operator.UserID });
});
}
if (viewModel.get('PartOperations_FilterFlag')) {
$.each(viewModel.get('PartOperations').data(), function (index, partOperation) {
saveData.Criteria.PartOperations.push({ ItemNumber: partOperation.ItemNumber, OperationNumber: partOperation.OperationNumber, MisNumber: partOperation.MisNumber, MisRevision: partOperation.MisRevision });
});
}
//Post data back to server
$.ajax({
type: 'POST',
url: '@Url.Action("Save", "Search")',
data: JSON.stringify(saveData),
success: function (id) {
//Hide progress panel
kendo.ui.progress(editPanel, false);
clearTimeout(errorTimeout);
//Go to session edit page
window.location.search = 'id=' + id;
},
dataType: "json",
contentType: "application/json; charset=utf-8"
});
}
//Loads the search details from the server
function loadSearchDetails(id) {
//Set timeout
var errorTimeout = setTimeout(function () {
// Handle error accordingly
alert("Failed to load session details.");
kendo.ui.progress(editPanel, false);
}, 5000);
//Load session info
$.getJSON('@Url.Action("GetSearch", "Search")?id=' + id,
null,
function (results) {
viewModel.setData(results);
//Hide progress panel
kendo.ui.progress(editPanel, false);
clearTimeout(errorTimeout);
$('#copyBTN').click(function () {
window.location.href = '@Url.Action("Create", "Search")?copySearchID=' + id;
});
});
}
//Copys the search details from the server
function copySearchDetails(id) {
//Set timeout
var errorTimeout = setTimeout(function () {
// Handle error accordingly
alert("Failed to copy session details.");
kendo.ui.progress(editPanel, false);
}, 5000);
//Load session info
$.getJSON('@Url.Action("CopySearch", "Search")?id=' + id,
null,
function (results) {
results.ID = 0;
viewModel.setData(results);
//Hide progress panel
kendo.ui.progress(editPanel, false);
clearTimeout(errorTimeout);
});
}
//Extracts the given URL parameter value
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
</script>