Skip to content

Instantly share code, notes, and snippets.

@VirtuosiMedia
Created April 6, 2016 23:00
Show Gist options
  • Save VirtuosiMedia/174e78101f3a8ec91735063b60c9390c to your computer and use it in GitHub Desktop.
Save VirtuosiMedia/174e78101f3a8ec91735063b60c9390c to your computer and use it in GitHub Desktop.
/**
* Renders the trade center screen.
* Copyright Virtuosi Media, Inc.
*/
jg.templates.commercial.tradeCenter = function(){
return {
updateManager: function(){
},
/**
* Renders the purchase tab panel in the trade center.
* @param - object goodsCategories - The alphabetized list categories for goods.
* @return - The rendered tab panel as an HTML object.
*/
renderPurchaseTab: function(goodsCategories){
var template = _.f();
var purchaseSelect = jg.ui.forms.select(goodsCategories, jg.data.state.commercial.trade.purchaseCategory, {
'id': 'purchaseCategory',
'data-change': 'templates.commercial.tradeCenter.setPurchaseCategory'
});
var header = _.e('div.card.small');
header.adopt(purchaseSelect);
header.inject(template);
_.e('div#tradeCenterPurchaseTable').inject(template);
_.action.delay(this.renderPurchaseTable, 100);
return template;
},
/**
* Renders the purchase table in the trade center.
*/
renderPurchaseTable: function(){
var self = jg.templates.commercial.tradeCenter();
var goods = self.getPurchaseGoods();
var template = _.f();
var table = jg.ui.table({id: 'purchaseTable'});
table.setHeaders({
'name': 'name',
'average': 'averagePrice',
'price': 'price',
'quantity': 'quantity',
'type': 'bidType',
'action': 'action'
}, jg.data.state.commercial.trade.purchaseTableSort, jg.data.state.commercial.trade.purchaseTableSortDirection, 'templates.commercial.tradeCenter.setPurchaseSort');
//Render each table row
goods.each(function(good){
if (good.category === 'component'){
var name = _.e('button#' + good.id + 'Info', {text: good.name, 'data-modal': 'item', 'data-id': good.id});
} else {
var name = _.e('button#' + good.id + 'Info', {text: good.name, 'data-modal': 'resource', 'data-id': good.id});
}
if (good.price){ // This indicates a purchase bid exists for this good
var price = _.e('span.numericAlign', {text: _.text.formatNumber(good.price, 2)});
var quantity = _.e('span.numericAlign', {text: _.text.formatNumber(good.quantity)});
var orderType = _.e('span', {text: _.translate(good.orderType)});
} else {
var price = _.e('input.priceInput', {
'id': 'purchasePrice-' + good.id,
'type': 'text',
'data-good': good.id
});
var quantity = _.e('input.quantityInput', {
'id': 'purchaseQuantity-' + good.id,
'type': 'text',
'data-good': good.id
});
var orderTypes = {
'order': _.translate('order'),
'trade': _.translate('trade')
};
var orderType = jg.ui.forms.select(orderTypes, 'order', {
'id': 'orderType-' + good.id,
'class': 'orderType',
'data-good': good.id
});
}
if (good.action === 'bid'){
var action = _.e('button.lockedButton.button.primary', {
text: _.translate(good.action),
'data-good': good.id,
'data-goodCategory': good.category,
'data-action': 'purchase',
'data-click': 'templates.commercial.tradeCenter.placeBid'
});
} else {
var action = _.e('button.unlockedButton.button.secondary', {
text: _.translate(good.action),
'data-good': good.id,
'data-action': 'purchase',
'data-click': 'templates.commercial.tradeCenter.cancelBid'
});
}
table.addRow([
name,
_.e('span.numericAlign', {text: _.text.formatNumber(good.average)}),
price,
quantity,
orderType,
action
]);
});
table.render().inject(template);
_.$('tradeCenterPurchaseTable').empty().adopt(template);
},
/**
* Gets a sorted purchase order goods list for the selected category of goods.
* @return {array} The sorted list of goods objects.
*/
getPurchaseGoods: function(){
//Get all goods that should be rendered
var trade = jg.calculate.trade;
var holding = jg.data.state.holding;
var resources = _.container(_.language.getDataSet('resources'));
var components = _.container(_.language.getDataSet('items'));
var orders = jg.data.holdings[holding].data.economic.trade.orders;
var category = jg.data.state.commercial.trade.purchaseCategory;
var goods = _.list();
if ((category === 'resources') || (category === 'all')){
resources.each(function(resource){
goods.push({
'id': resource.id,
'name': resource.name,
'description': resource.description,
'category': 'resource',
'average': trade.getAverageGoodSalesPrice(holding, resource.id),
'price': trade.getGoodOrderPrice(holding, resource.id),
'quantity': trade.getGoodOrderQuantity(holding, resource.id),
'orderType': trade.getGoodOrderType(holding, resource.id),
'action': trade.getGoodOrderAction(holding, resource.id)
});
});
}
if (category !== 'resources'){
components.each(function(component){
if ((category === component.category) || (category === 'all')){
goods.push({
'id': component.id,
'name': component.name,
'description': component.description,
'category': 'component',
'average': trade.getAverageGoodSalesPrice(holding, component.id),
'price': trade.getGoodOrderPrice(holding, component.id),
'quantity': trade.getGoodOrderQuantity(holding, component.id),
'orderType': trade.getGoodOrderType(holding, component.id),
'action': trade.getGoodOrderAction(holding, component.id)
});
}
});
}
goods.sortByKey(jg.data.state.commercial.trade.purchaseTableSort, (jg.data.state.commercial.trade.purchaseTableSortDirection === 'desc'));
return goods;
},
/**
* Sets the trade center purchasing category.
* @param {HTMLObject} target An HTML select object.
*/
setPurchaseCategory: function(target){
if (jg.data.state.commercial.trade.purchaseCategory !== target.value){
jg.data.state.commercial.trade.purchaseCategory = target.value;
var self = jg.templates.commercial.tradeCenter();
self.renderPurchaseTable();
}
},
/**
* Sets the purchase table sort column and direction.
* @param {HTMLObject} target The triggered header column.
*/
setPurchaseSort: function(target){
jg.data.state.commercial.trade.purchaseTableSortDirection = (jg.data.state.commercial.trade.purchaseTableSortDirection === 'asc') ? 'desc' : 'asc';
jg.data.state.commercial.trade.purchaseTableSort = target.get('data-column');
var template = jg.templates.commercial.tradeCenter();
template.renderPurchaseTable();
},
/**
* Unlocks a purchase bid, canceling it and rerendering the table and the resource panel.
* @param {HTMLObject} target The unlock button.
*/
cancelBid: function(target){
var good = target.get('data-good');
var holding = jg.data.state.holding;
var template = jg.templates.commercial.tradeCenter();
jg.calculate.trade.cancelTradeOrder(holding, good);
jg.templates.load.interface()['update' + jg.data.state.panel + 'Panel']();
template.renderPurchaseTable();
},
/**
* Locks in a purchase bid, but checks for errors first then rerenders the table and the resource panel.
* @param {HTMLObject} target The lock button.
*/
placeBid: function(target){
var good = target.get('data-good');
var goodCategory = target.get('data-goodCategory');
var priceInput = _.$('purchasePrice-' + good);
var quantityInput = _.$('purchaseQuantity-' + good);
var price = parseFloat(priceInput.value);
var quantity = parseInt(quantityInput.value);
var orderType = _.$('orderType-' + good).value;
var canOrder = true;
if ((!price) || (price <= 0)){
priceInput.addClass('error');
canOrder = false;
} else {
priceInput.removeClass('error');
}
if ((!quantity) || (quantity <= 0)){
quantityInput.addClass('error');
canOrder = false;
} else {
quantityInput.removeClass('error');
}
if (canOrder){
var orderPlaced = jg.calculate.trade.placeTradeOrder(jg.data.state.holding, good, goodCategory, price, quantity, orderType);
if (orderPlaced){
var template = jg.templates.commercial.tradeCenter();
template.renderPurchaseTable();
jg.templates.load.interface()['update' + jg.data.state.panel + 'Panel']();
} else {
var title = _.translate('insufficientCreditsOrderTitle');
var text = _.translate('insufficientCreditsOrderDescription');
jg.templates.load.interface().triggerErrorModal(title, text);
}
}
},
/**
* Renders the sell table in the trade center.
* @param - object goodsCategories - The alphabetized list categories for goods.
* @return - The rendered column as an HTML object.
*/
renderSellTab: function(goodsCategories){
var template = _.f();
var sellSelect = jg.ui.forms.select(goodsCategories, jg.data.state.commercial.trade.sellCategory, {
'id': 'sellCategory',
'data-change': 'templates.commercial.tradeCenter.setSellCategory'
});
var header = _.e('div.card.small');
header.adopt(sellSelect);
header.inject(template);
_.e('div#tradeCenterSellTable').inject(template);
_.action.delay(this.renderSellTable, 100);
return template;
},
/**
* Renders the sell table in the trade center.
*/
renderSellTable: function(){
var self = jg.templates.commercial.tradeCenter();
var goods = self.getSalableGoods();
var template = _.f();
var table = jg.ui.table({id: 'purchaseTable'});
table.setHeaders({
'name': 'name',
'average': 'averagePrice',
'price': 'price',
'quantity': 'quantity',
'type': 'saleType',
'action': 'action'
}, jg.data.state.commercial.trade.purchaseTableSort, jg.data.state.commercial.trade.purchaseTableSortDirection, 'templates.commercial.tradeCenter.setPurchaseSort');
//Add each table row
goods.each(function(good){
if (good.category === 'component'){
var name = _.e('button#' + good.id + 'Info', {text: good.name, 'data-modal': 'item', 'data-id': good.id});
} else {
var name = _.e('button#' + good.id + 'Info', {text: good.name, 'data-modal': 'resource', 'data-id': good.id});
}
if (good.price){ // This indicates a sales proposal exists for this good
var price = _.e('span.numericAlign', {text: _.text.formatNumber(good.price, 2)});
var quantityContainer = _.e('span.numericAlign', {text: _.text.formatNumber(good.quantity)});
var orderType = _.e('span', {text: _.translate(good.orderType)});
} else {
var price = _.e('input.priceInput', {
'id': 'salesPrice-' + good.id,
'type': 'text',
'data-good': good.id
});
var quantity = _.e('input.quantityInput.salesQuantity', {
'id': 'salesQuantity-' + good.id,
'type': 'text',
'data-good': good.id
});
var inventory = _.e('span.goodInventory', {
'id': 'salesQuantityInventory-' + good.id,
text: ' /' + _.text.formatNumber(good.quantity)
});
var quantityContainer = _.e('div').adopt(quantity).adopt(inventory);
var orderTypes = {
'sale': _.translate('sale'),
'trade': _.translate('trade')
};
var orderType = jg.ui.forms.select(orderTypes, 'order', {
'id': 'salesOrderType-' + good.id,
'class': 'orderType',
'data-good': good.id
});
}
if (good.action === 'sell'){
var action = _.e('button.button.primary', {
text: _.translate(good.action),
'data-good': good.id,
'data-goodCategory': good.category,
'data-action': 'purchase',
'data-click': 'templates.commercial.tradeCenter.placeSalesProposal'
});
} else {
var action = _.e('button.button.secondary', {
text: _.translate(good.action),
'data-good': good.id,
'data-action': 'purchase',
'data-click': 'templates.commercial.tradeCenter.cancelSalesProposal'
});
}
table.addRow([
name,
_.e('span.numericAlign', {text: _.text.formatNumber(good.average)}),
price,
quantityContainer,
orderType,
action
]);
});
table.setEmptyMessage('noGoodsInCategory');
table.render().inject(template);
_.$('tradeCenterSellTable').empty().adopt(template);
},
/**
* Gets a sorted goods list for all goods in inventory in the selected category of goods.
* @return {array} The sorted list of goods objects.
*/
getSalableGoods: function(){
//Get all goods that should be rendered
var trade = jg.calculate.trade;
var holdingId = jg.data.state.holding;
var holding = jg.data.holdings[holdingId];
var resources = _.container(_.language.getDataSet('resources'));
var components = _.container(_.language.getDataSet('items'));
var orders = holding.data.economic.trade.orders;
var category = jg.data.state.commercial.trade.sellCategory;
var goods = _.list();
if ((category === 'resources') || (category === 'all')){
resources.each(function(resource){
if (holding.resources.supply[resource.id] > 0){
goods.push({
'id': resource.id,
'name': resource.name,
'description': resource.description,
'category': 'resource',
'average': trade.getAverageGoodBidPrice(holdingId, resource.id),
'price': trade.getGoodSalesProposalPrice(holdingId, resource.id),
'quantity': trade.getGoodSalesProposalQuantity(holdingId, resource.id),
'orderType': trade.getGoodSalesProposalType(holdingId, resource.id),
'action': trade.getGoodSalesProposalAction(holdingId, resource.id)
});
}
});
}
if (category !== 'resources'){
components.each(function(component){
if ((category === component.category) || (category === 'all')){
if ((holding.inventory.hasOwnProperty(component.id)) && (holding.inventory[component.id] > 0)){
goods.push({
'id': component.id,
'name': component.name,
'description': component.description,
'category': 'component',
'average': trade.getAverageGoodBidPrice(holdingId, component.id),
'price': trade.getGoodSalesProposalPrice(holdingId, component.id),
'quantity': trade.getGoodSalesProposalQuantity(holdingId, component.id),
'orderType': trade.getGoodSalesProposalType(holdingId, component.id),
'action': trade.getGoodSalesProposalAction(holdingId, component.id)
});
}
}
});
}
goods.sortByKey(jg.data.state.commercial.trade.sellTableSort, (jg.data.state.commercial.trade.sellTableSortDirection === 'desc'));
return goods;
},
/**
* Sets the trade center sell category.
* @param {HTMLObject} target An HTML select object.
*/
setSellCategory: function(target){
if (jg.data.state.commercial.trade.sellCategory !== target.value){
jg.data.state.commercial.trade.sellCategory = target.value;
var self = jg.templates.commercial.tradeCenter();
self.renderSellTable();
}
},
/**
* Unlocks a purchase bid, canceling it and rerendering the table and the resource panel.
* @param {HTMLObject} target The unlock button.
*/
cancelSalesProposal: function(target){
var good = target.get('data-good');
var holding = jg.data.state.holding;
var template = jg.templates.commercial.tradeCenter();
jg.calculate.trade.cancelTradeSalesProposal(holding, good);
jg.templates.load.interface()['update' + jg.data.state.panel + 'Panel']();
template.renderSellTable();
},
/**
* Locks in a purchase bid, but checks for errors first then rerenders the table and the resource panel.
* @param {HTMLObject} target The lock button.
*/
placeSalesProposal: function(target){
var holdingId = jg.data.state.holding;
var holding = jg.data.holdings[holding];
var good = target.get('data-good');
var goodCategory = target.get('data-goodCategory');
var priceInput = _.$('salesPrice-' + good);
var quantityInput = _.$('salesQuantity-' + good);
var price = parseFloat(priceInput.value);
var quantity = parseInt(quantityInput.value);
var orderType = _.$('salesOrderType-' + good).value;
var canSell = true;
if ((!price) || (price <= 0)){
priceInput.addClass('error');
canSell = false;
} else {
priceInput.removeClass('error');
}
if ((!quantity) || (quantity <= 0)){
quantityInput.addClass('error');
canSell = false;
} else {
quantityInput.removeClass('error');
}
if (canSell){
var proposalPlaced = jg.calculate.trade.placeTradeSalesProposal(holdingId, good, goodCategory, price, quantity, orderType);
if (proposalPlaced){
var template = jg.templates.commercial.tradeCenter();
template.renderSellTable();
jg.templates.load.interface()['update' + jg.data.state.panel + 'Panel']();
} else {
var title = _.translate('insufficientGoodsProposalTitle');
var text = _.translate('insufficientGoodsProposalDescription');
jg.templates.load.interface().triggerErrorModal(title, text);
}
}
},
setTab: function(target){
var active = target.get('data-tab');
if (active !== jg.data.state.commercial.trade.tradeCenterActiveTab){
jg.data.state.commercial.trade.tradeCenterActiveTab = active;
_.$$('.displayTabs button').each(function(tab){
tab.removeClass('active');
});
_.$$('.tabPanel').each(function(panel){
panel.removeClass('active');
});
target.addClass('active');
_.$('tradeCenter' + _.text.capitalize(active) + 'TabPanel').addClass('active');
}
},
/**
* Renders the main container for the trade center.
*/
render: function(){
var template = _.f();
var header = _.e('div.header');
var breadcrumb = jg.ui.breadcrumb({'commercial': 'commercial.overview', 'tradeCenter': null}).inject(header);
header.inject(template);
var pageMenu = jg.ui.list('ul#tradeCenterMenu.pageMenu');
//TODO: Make these unlockable.
pageMenu.addItem(_.e('button#priceCenterLink', {'data-template': 'commercial.tradeIndex', text: _.translate('index')}));
pageMenu.addItem(_.e('button#portLink', {'data-template': 'commercial.port', text: _.translate('port')}));
pageMenu.addItem(_.e('button#inventoryLink', {'data-template': 'station.inventory', text: _.translate('inventory')}));
pageMenu.render().inject(template);
//Make list of component types for select boxes
var goodsCategories = _.container({
all: _.translate('all'),
resources: _.translate('resources')
});
_.container(_.language.getDataSet('items')).each(function(component){
if (!goodsCategories.hasKey(component.category)){
goodsCategories[component.category] = _.translate(component.category);
}
});
goodsCategories.sort();
//Render the display with tabs
var display = _.e('div#tradeCenterDisplay.display');
display.adopt(_.e('p', {text: _.translate('tradeCenterDescription')}));
var tabs = jg.ui.list('ul#tradeCenterTabs.displayTabs');
if (jg.data.state.commercial.trade.tradeCenterActiveTab === 'purchase'){
tabs.addItem(_.e('button.active', {
'data-click': 'templates.commercial.tradeCenter.setTab',
'data-tab': 'purchase',
text: _.translate('purchaseGoods')
}));
tabs.addItem(_.e('button', {
'data-click': 'templates.commercial.tradeCenter.setTab',
'data-tab': 'sell',
text: _.translate('sellGoods')
}));
var purchase = _.e('div#tradeCenterPurchaseTabPanel.active.tabPanel').adopt(this.renderPurchaseTab(goodsCategories));
var sell = _.e('div#tradeCenterSellTabPanel.tabPanel').adopt(this.renderSellTab(goodsCategories));
} else {
tabs.addItem(_.e('button', {
'data-click': 'templates.commercial.tradeCenter.setTab',
'data-tab': 'purchase',
text: _.translate('purchaseGoods')
}));
tabs.addItem(_.e('button.active', {
'data-click': 'templates.commercial.tradeCenter.setTab',
'data-tab': 'sell',
text: _.translate('sellGoods')
}));
var purchase = _.e('div#tradeCenterPurchaseTabPanel.tabPanel').adopt(this.renderPurchaseTab(goodsCategories));
var sell = _.e('div#tradeCenterSellTabPanel.active.tabPanel').adopt(this.renderSellTab(goodsCategories));
}
tabs.render().inject(display);
display.inject(template);
//Render the tab panels
var tradeCenterTables = _.e('div#tradeCenterTables').adopt(purchase).adopt(sell).inject(template);
return template;
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment