// Sub Filter Service
app.service('SubFilterService', function($http, $q, $timeout) {
var that = this;
// Shared data
this.filter = {
type: "",
value: "-1",
primaryFilters: {
pipeline: ['shipper','point','agent', 'rate_schedule', 'contract'],
shipper: ['point','agent', 'rate_schedule']
}
};
// Helper function to search collection
// Returns only those records whose field(field_name) matched field_value
// Params
// - collection: a list to search
// - field_name: string representing the field being checked
// - field_Value: string representing the value of the field for the match
function search(collection, field_name, field_value) {
// console.trace('search me', field_name, field_value)
var matches = [];
console.log('collection', collection)
collection.forEach(function(data) {
// If the field's value matches to the field_value, push it into the matches list
// console.log('data', {data:data, field_value: field_value, field_name: field_name})
// if (data[field_name] === field_value) {
matches.push(data);
// }
});
return matches;
}
// Helper function to calculate aggregate information for each name in the list
// Returns a unique list of objects, each having a unique name_field value
// Params:
// - list: a list of all records whose aggregate information is collected based on names
// - name_field: string representing the field by which the records are aggregated
// - quant_field: string, either "contract" or "point". Point is due to agent points having point_storage_msq
// - defer: promise object via which the result of the aggregation is returned, necessary to prevent the screen from freezing
function collectAggregateData(list, name_field, quant_field, defer) {
var unique_names = [];
var aggregate_data = [];
var contract_storage_msq = quant_field + "_storage_msq"
var contract_transport_mdq = quant_field + "_transport_mdq"
// Loop through the list
list.forEach(function(data) {
var name = data[name_field];
// If record by name_field doesnt exist in unique_names
if (unique_names.indexOf(name) == -1) {
unique_names.push(name);
}
});
// For each unique name
unique_names.forEach(function(name) {
// Object representing the aggregate information
var info = {
name: name,
contract_storage: 0,
volume_storage: 0,
contract_transport: 0,
volume_transport: 0
}
// Loop though all the records
list.forEach(function(data) {
// If the record name matches the unique name
if (data[name_field] === name) {
// In case contract_storage_msq is null
data[contract_storage_msq] = data[contract_storage_msq] || '';
// If the contract_storage_msq is not empty
if (data[contract_storage_msq] && data[contract_storage_msq].trim() !== "") {
info.contract_storage += 1 // Add 1 to the appropriate contract number
info.volume_storage += parseInt(data[contract_storage_msq].trim()); // Add the quantity to the appropriate quantity
}
// Same as above but for contract_transport_mdq
if (data[contract_transport_mdq] && data[contract_transport_mdq].trim() !== "") {
info.contract_transport += 1
info.volume_transport += parseInt(data[contract_transport_mdq].trim());
}
}
});
// Push the aggregate information into main list
aggregate_data.push(info);
});
// Resolve promise
defer.resolve(aggregate_data);
};
// Helper function that creates a promise to be resolved by the aggregated data
// Params
// - data_source: function to be executed to get a list of records to be aggregated
// - name_field: string representing the field that holds the name identifier of the records
// - quant_field: string, "contract" or "point"
// - scope: directive's scope object, used to assign an aggregated records list to the scope.aggregated_data
function promiseHelper(data_source, name_field, quant_field, scope) {
// Set the scope.predicate for table sort
// Create a promise
var defer = $q.defer();
// When the promise gets resolved
defer.promise.then(function(records) {
scope.total = records.length;
// scope.aggregate_data = records.slice(scope.start, scope.end);
scope.aggregate_data = records
});
// Delay execution of aggregate data
$timeout(function() {
// Code to search for relevent records and aggregate by name_field
collectAggregateData(
data_source,
name_field,
quant_field,
defer
);
}, 100);
}
// Extract the dataset needed to populate the primary filter table
// Params
// - records: string identifying the collection needed from filter.quarterData
// - fields: array of fields to be extracted from each record
function getDataset(scope, records, fields, start, end) {
var dataset = [];
var quarterData = scope.primaryFilter.quarterData;
quarterData[records].slice(start,end).forEach(function(record) {
var data = [];
fields.forEach(function(field) {
if(field == 'agent_name_clean' && record.agents[0]) {
data.push(record.agents[0].agent_name_clean)
}
else data.push(record[field]);
})
//If record is a pipeline
if(record.pipeline_name_clean) {
data.push(record.pipeline_name_clean);
}
// If record is an agent
if(record.agent_name_clean) {
data.push(record.agent_name_clean);
}
// If records is a shipper
// else if (record.agents) {
// console.log('record.agents',record.agents)
// var agents = "";
// record.agents.forEach(function(agent) {
// agents += agent.agent_name_clean + ",";
// });
//
// data.push(agents.substr(0,agents.length -1));
// }
// If record is a point
// else {
// var agents = ""
// that.filter.quarterData.agents.forEach(function(agent) {
// agent.points.forEach(function(point) {
// if (record.point_name === point.point_name) {
// agents += agent.agent_name + ","
// }
// });
// });
// data.push(agents.substr(0,agents.length -1));
// }
dataset.push(data)
});
return dataset;
}
function getTableData(scope, filterType, start, end, defer) {
console.log('getTableData filterType', filterType)
// if (filterType === "pipeline") {
// var headers = ["Shipper Name", "Affiliate", "Rate Schedule",
// "Contract No.", "MDQ", "MSQ", "Start Date",
// "End Date", "Negotiated Rate", "Agents"];
//
// var fields = ["shipper_name_clean","shipper_affiliate_ind","rate_schedule","contract_number",
// "contract_transport_mdq","contract_storage_msq","start_date","end_date",
// "negotiated_rate_ind"];
//
// var dataset = getDataset("shippers", fields, start, end);
// defer.resolve({headers: headers, dataset: dataset, total: that.filter.quarterData.pipelines.length});
// }
if (filterType === "shipper") {
var headers = ["Shipper Name", "Affiliate","Rate Schedule",
"Contract No.", "MDQ", "MSQ", "Start Date",
"End Date","Agents","Points" ];
var fields = ["shipper_name_clean","shipper_affiliate_ind","rate_schedule","contract_number",
"contract_transport_mdq","contract_storage_msq","start_date","end_date",
"agent_name_clean", "point_count"];
var dataset = getDataset(scope, "shippers", fields, start, end);
defer.resolve({headers: headers, dataset: dataset, total: scope.primaryFilter.quarterData.shippers.length});
}
// - Agent Name
// - Affiliate
// - Shippers
// - Transport Contracts
// - Total MDQ
// - Storage Contracts
// - Total MSQ
// - Rate Schedule(s)
// - Negotiated Rate
// - Points
// - First Start Date
// - Last End Date
else if (filterType === "agent") {
var headers = ["Agent Name","Shipper Name", "Affiliate", "Rate Schedule",
"Contract No.", "MDQ", "MSQ", "Start Date",
"End Date", "Negotiated Rate", "Agents"];
var fields = ["pipeline_name_clean","shipper_name_clean","shipper_affiliate_ind","rate_schedule","contract_number",
"contract_transport_mdq","contract_storage_msq","start_date","end_date",
"negotiated_rate_ind"];
var dataset = getDataset(scope, "agents", fields, start, end);
defer.resolve({headers: headers, dataset: dataset, total: scope.primaryFilter.quarterData.agents.length});
}
else if (filterType === "point") {
var headers = ["Point Name","Shipper Name", "Affiliate", "Rate Schedule",
"Contract No.", "MDQ", "MSQ", "Start Date",
"End Date", "Negotiated Rate", "Agents"];
var fields = ["point_name_clean","shipper_name_clean","shipper_affiliate_ind","rate_schedule","contract_number",
"contract_transport_mdq","contract_storage_msq","start_date","end_date",
"negotiated_rate_ind"];
var dataset = getDataset(scope, "points", fields, start, end);
defer.resolve({headers: headers, dataset: dataset, total: scope.primaryFilter.quarterData.points.length});
}
// - Rate Schedule
// - Shippers
// - Agents
// - Transport Contracts
// - Total MDQ
// - Storage Contracts
// - Total MSQ
// - Negotiated Rate
// - Points
// - First Start Date
// - Last End Date
else if (filterType === "rate_schedule") {
var headers = ["Rate Schedule","Shipper Name", "Agents",
"Contract No.", "MDQ", "MSQ", "Negotiated Rate", "Start Date","End Date" ];
var fields = ["rate_schedule","shipper_name_clean","agent_count","contract_number",
"contract_transport_mdq","contract_storage_msq","negotiated_rate_ind","start_date","end_date"];
var dataset = getDataset(scope, "shippers", fields, start, end);
defer.resolve({headers: headers, dataset: dataset, total: scope.primaryFilter.quarterData.shippers.length});
}
}
function filterQuarterData(data, filter) {
var totalList = {
pipelines: [],
shippers: [],
agents: [],
points: []
};
data.pipelines.forEach(function(item){
if(item.pipe_id == filter) {
totalList.pipelines.push(item);
item.shippers.forEach(function(shipper){
totalList.shippers.push(shipper);
totalList.agents = totalList.agents.concat(shipper.agents)
totalList.points = totalList.points.concat(shipper.points)
});
}
});
// data.agents.forEach(function(item){
// if(item.parent_pipeline_id == filter) totalList.agents.push(item);
// });
// data.points.forEach(function(item){
// if(item.parent_pipeline_id == filter) totalList.points.push(item);
// });
return totalList;
}
// Main ugly function that checks the primay and sub filter and popluates the sub filter tables based on them
// Params:
// - scope: direcitve's scope, used to set the directive scope.aggregate_data value
// - element: direcitve's angular element, used to empty the element's table's body
this.getFilterValue = function(scope, element) {
that.filter.value = scope.filter.value;
}
this.getFilterData = function(scope, element) {
var quarterData;
var primaryFilter = scope.primaryFilter.type;
var subFilter = that.filter.type;
if (this.filter.value === "-1")
quarterData = scope.primaryFilter.quarterData;
else {
quarterData = filterQuarterData(scope.primaryFilter.quarterData, this.filter.value);
console.log('else')
}
// console.log('sub quarterData a', quarterData)
// console.log('scope.primaryFilter.value',scope.primaryFilter.value)
var schema = {
pipeline: {
field: "pipe_id"
},
shipper: {
field: "shipper_name_clean"
}
}
var subfilterPromise = $http.get('/' + subFilter + '/search?' + schema[primaryFilter].field + '=' + scope.primaryFilter.value);
subfilterPromise.then(function(records) {
// console.log('arguments', arguments)
});
// var agentPromise = $http.get('/agent/search?quarter=' + quarter);
var tbody = element.find('tbody');
tbody.find('td').remove();
// Primary filter is PIPELINE
if(primaryFilter === 'pipeline') {
// Sub filter is SHIPPER
if (subFilter === 'shipper') {
promiseHelper(search(quarterData.shippers, "shipper_name_clean", scope.primaryFilter.value), "shipper_name_clean", "contract", scope);
}
// Sub filter is AGENT
else if (subFilter === 'agent') {
promiseHelper(search(quarterData.agents, "shipper_name_clean", scope.primaryFilter.value), "agent_name_clean", "contract", scope);
}
// Sub filter is POINT
else if (subFilter === 'point') {
promiseHelper(search(quarterData.points, "shipper_name_clean", scope.primaryFilter.value), "point_name_clean", "point", scope);
}
else if (subFilter === 'rate_schedule') {
promiseHelper(search(quarterData.shippers, "shipper_name_clean", scope.primaryFilter.value), "rate_schedule", "contract", scope);
}
else if (subFilter === 'contract') {
promiseHelper(search(quarterData.shippers, "shipper_name_clean", scope.primaryFilter.value), "contract_number", "contract", scope);
}
}
// Primary filter is SHIPPER
else if(primaryFilter === 'shipper') {
// Sub filter is AGENT
if (subFilter === 'agent') {
promiseHelper(search(quarterData.shippers, "shipper_name_clean", scope.primaryFilter.value), "shipper_name_clean", "contract", scope);
}
// Sub filter is POINT
else if (subFilter === 'point') {
promiseHelper(search(quarterData.points, "point_name_clean", scope.primaryFilter.value), "point_name_clean", "point", scope);
}
}
}
this.redrawTable = function(element,scope) {
var filterType = that.filter.type;
var defer = $q.defer();
defer.promise.then(function(data) {
// console.log('data in table', data)
scope.length = data.total;
if(data.total != 0 && scope.isBigTable){
scope.isShow = true;
scope.countOfPages = Math.ceil(data.total/10);
}
// Populate table header
var headers = data.headers;
var header_tags = "<tr>";
var pointHeaders = ["Shipper Name", "Point Type","Point Name",
"Point ID", "Point ID type", "Point Zone", "Point MDQ",
"Point MSQ"];
headers.forEach(function(header) {
header_tags += "<th>" + header + "</th>";
});
header_tags += "</tr>"
//element.find("thead").html(header_tags);
scope.headers = headers;
scope.pointHeaders = pointHeaders;
// Populate table rows
var row_tags = ""
var dataset = data.dataset;
dataset.forEach(function(data) {
var row = "<tr>";
data.forEach(function(field) {
row += "<td>" + field + "</td>";
});
row += "</tr>";
row_tags += row;
});
scope.rows = dataset
//element.find("tbody").html(row_tags);
});
$timeout(function() {
getTableData(scope ,filterType, scope.start, scope.end, defer);
}, 100);
}
this.getQuarterData = function(scope, element) {
$(".loading-quarter-message").html("Loading quarter .... ");
}
});