hedera-web/forms/ecomerce/catalog/catalog.js

535 lines
10 KiB
JavaScript

(function () {
var maxFilters = 5;
var View = {
LIST: 0,
GRID: 1
};
var orderBy = [
{way: 'DESC', id: 'relevancy', name: 'Relevancy'},
{way: 'ASC', id: 'name', name: 'Name'},
{way: 'ASC', id: 'price', name: 'Lower price'},
{way: 'DESC', id: 'price', name: 'Higher price'},
{way: 'ASC', id: 'available', name: 'Available'},
{way: 'ASC', id: 'size', name: 'Lower size'},
{way: 'DESC', id: 'size', name: 'Higher size'},
{way: 'ASC', id: 'color', name: 'Color'},
{way: 'ASC', id: 'producer', name: 'Producer'},
{way: 'ASC', id: 'origin', name: 'Origin'},
{way: 'ASC', id: 'category', name: 'Category'}
];
Hedera.Catalog = new Class
({
Extends: Hedera.Form
,_menuShown: false
,open: function ()
{
this.close ();
this.isOpen = true;
if (!localStorage.getItem ('hederaGuest'))
{
Hedera.BasketChecker.check (this.conn, this.hash,
this.onBasketCheck.bind (this));
}
else
{
var query = 'CALL basketConfigureForGuest';
this.conn.execQuery (query, this.loadUi.bind (this));
}
}
,onBasketCheck: function (isOk)
{
if (isOk)
this.loadUi ();
}
,activate: function ()
{
this.$.items.setInfo ('i', 'item', 'vn', ['id']);
document.body.appendChild (this.$.rightPanel);
if (localStorage.getItem ('hederaView'))
this.setView (parseInt (localStorage.getItem ('hederaView')));
else
this.setView (View.GRID);
this.$.orderBy.model = new Vn.Model ({
data: orderBy
});
this.onCategoryChange ();
this.refreshTitle ();
this.onParamsChange ();
}
,deactivate: function ()
{
this.hideMenu ();
this.gui.$.navbar.style.backgroundColor = '';
Vn.Node.remove (this.$.rightPanel);
}
,setView: function (view)
{
if (view === View.GRID)
{
this.$.viewButton.setProperties ({
icon: 'view-list',
tip: _('List view')
});
var className = 'grid-view';
}
else
{
this.$.viewButton.setProperties ({
icon: 'view-grid',
tip: _('Grid view')
});
var className = 'list-view';
}
this.view = view;
var node = this.$.gridView.node;
node.className = className;
localStorage.setItem ('hederaView', this.view);
}
,onSwitchViewClick: function ()
{
this.setView (this.view === View.GRID ?
View.LIST : View.GRID);
}
,onBasketReady: function (form)
{
if (form.$.method != 'PICKUP')
Vn.Node.setText (this.$.method, _('Agency'));
else
Vn.Node.setText (this.$.method, _('Store'));
}
,onOrderChange: function (combo)
{
var sortField = combo.$.id;
var sortWay = combo.$.way === 'ASC' ?
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField)
this.$.items.sort (sortField, sortWay);
this.hideMenu ();
}
,onParamsChange: function ()
{
var params = this.params.$;
var shouldRefresh = params.search ||
params.category && params.type;
Vn.Node.removeChilds (this.$.suggestedFilters);
if (shouldRefresh)
{
this.$.items.query = this.buildQuery ('CALL catalogGetItems');
this.$.items.refresh ();
var nTags = maxFilters - this.nFilters;
if (nTags > 0)
{
var tagsQuery = this.buildQuery (
'CALL catalogGetTags (#nTags)', {nTags: nTags});
this.conn.execQuery (tagsQuery, this.onTagsReady.bind (this));
}
this.hideMenu ();
}
else
this.$.items.clean ();
this.showFilters (params.search || params.category);
}
,showFilters: function (show)
{
this.$.filters.style.display = show ? 'block' : 'none';
this.$.categoryMsg.style.display = show ? 'none' : 'block';
}
,onRemoveFiltersClick: function ()
{
this.params.$ = {};
this.tagFilter = {};
}
,filters: {}
,nFilters: 0
,buildQuery: function (query, params, excludeTag)
{
var query = new Sql.MultiStmt ({
stmts: [
this.$.preQuery,
new Sql.String ({query: query}),
this.$.postQuery
]
});
var qParams = {
joins: this.buildTagFilter (excludeTag),
filter: this.buildMainFilter ()
};
Object.assign (qParams, params);
return this.conn.renderStmt (query, qParams)
}
,buildMainFilter: function ()
{
var filterSql = this.$.filter.render (this.params.$);
return new Sql.String ({query: filterSql});
}
,buildTagFilter: function (excludeTag)
{
var Type = Sql.Operation.Type;
var join = new Sql.Join ({
target: new Sql.Table ({
schema: 'vn',
name: 'item',
alias: 'i'
})
});
join.push (new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'itemType',
alias: 't'
}),
condition: new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: 't',
name: 'id'
}),
new Sql.Field ({
target: 'i',
name: 'typeFk'
})
]
})
}));
var i = -1;
for (var tagId in this.filters)
{
var tagId = parseInt (tagId);
var tagValue = this.filters[tagId].field.value;
if (tagId === excludeTag)
continue;
i++;
var tAlias = 'it'+ i;
var joinItem = new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'itemTag',
alias: tAlias
}),
condition: new Sql.Operation ({
type: Type.AND
})
});
join.push (joinItem);
joinItem.condition.exprs = [
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'itemFk'
}),
new Sql.Field ({
target: 'i',
name: 'id'
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'tagFk'
}),
new Sql.Value ({
value: tagId
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'value'
}),
new Sql.Value ({
value: tagValue
})
]
})
];
}
return join;
}
,onTagsReady: function (resultSet)
{
var tags = resultSet.results[2].data;
tags.forEach (function (tag) {
if (this.filters[tag.id] !== undefined)
return;
var query = this.buildQuery (
'CALL catalogGetTagValues (#tag)', {tag: tag.id}, tag.id);
var filter = this.createElement ('div');
this.$.suggestedFilters.appendChild (filter);
var label = this.createElement ('label');
label.appendChild (this.createTextNode (tag.name));
filter.appendChild (label);
var combo = new Htk.Combo ({
valueField: 'value',
showField: 'value'
});
filter.appendChild (combo.node);
var model = new Db.Model ({
autoLoad: false,
resultIndex: 2,
query: query,
conn: this.conn
});
combo.model = model;
var filterData = {
filter: filter,
tagId: tag.id,
field: combo,
model: model
};
combo.on ('changed',
this.onComboChange.bind (this, filterData), this);
}, this);
}
,onComboChange: function (filterData, _, value)
{
var filter = filterData.filter;
var tagId = filterData.tagId;
if (value == null)
{
this.$.currentFilters.removeChild (filter);
delete this.filters[tagId];
this.nFilters--;
}
else if (this.filters[tagId] === undefined)
{
this.nFilters++;
this.filters[tagId] = filterData;
this.$.suggestedFilters.removeChild (filter);
this.$.currentFilters.appendChild (filter);
}
for (var tid in this.filters)
if (parseInt (tid) !== tagId)
{
var query = this.buildQuery (
'CALL catalogGetTagValues (#tag)', {tag: tid}, tid);
this.filters[tid].model.query = query;
}
this.onParamsChange ();
}
,onCategoryChange: function ()
{
this.refreshTitleColor ();
}
,refreshTitleColor: function ()
{
var categories = this.$.categories;
var category = this.params.$.category;
var color = null;
if (category)
{
var row = categories.search ('id', category);
if (row != -1)
color = '#'+ categories.get (row, 'color');
}
this.gui.$.navbar.style.backgroundColor = color;
}
,refreshTitle: function ()
{
var type = this.$.type.$.name;
var title = type ? type : _('Catalog');
Vn.Node.setText (this.$.title, title);
}
,onRightPanelClick: function (event)
{
event.stopPropagation ();
}
,onShowMenuClick: function (event)
{
this._menuShown = true;
event.stopPropagation ();
this.gui.showBackground ();
Vn.Node.addClass (this.$.rightPanel, 'show');
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
if (!this._menuShown)
return;
this.gui.hideBackground ();
Vn.Node.removeClass (this.$.rightPanel, 'show');
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
}
,isGuest: function ()
{
if (localStorage.getItem ('hederaGuest'))
{
Htk.Toast.showError (_('YouMustBeLoggedIn'));
return true;
}
return false;
}
,onBasketClick: function ()
{
if (this.isGuest ())
return;
this.hash.$ = {form: 'ecomerce/basket'};
}
,onConfigureClick: function ()
{
if (this.isGuest ())
return;
this.hash.$ = {form: 'ecomerce/checkout'};
}
,onAddItemClick: function (button)
{
if (this.isGuest ())
return;
this.onEraseClick ();
var lot = button.lot;
this.$.card.row = lot.row;
this.$.cardLot.assign ({item: lot.$.id});
this.$.cardPopup.show ();
}
,onAddLotClick: function (column, value, rowIndex)
{
var row = this.$.itemLots.getObject (rowIndex);
var lotAmount = this.items[row.warehouse_id];
if (lotAmount === undefined)
lotAmount = 0;
if (lotAmount < row.available)
{
var newAmount = lotAmount + row.grouping;
if (newAmount > row.available)
newAmount = row.available;
this.items[row.warehouse_id] = newAmount;
this.$.amount.value += newAmount - lotAmount;
}
else
Htk.Toast.showError (_('NoMoreAmountAvailable'));
}
,onConfirmClick: function ()
{
var sql = '';
var query = 'CALL basketAddItem (#warehouse, #item, #amount);';
var amountSum = 0;
for (var warehouse in this.items)
{
var amount = this.items[warehouse];
amountSum += amount;
var params = {
item: this.$.cardLot.$.item,
warehouse: parseInt (warehouse),
amount: amount
};
sql += this.conn.renderQuery (query, params);
}
if (amountSum > 0)
{
this.conn.execQuery (sql);
var itemName = this.$.card.$.name;
Htk.Toast.showMessage (
Vn.Value.sprintf (_('Added%dOf%s'), amountSum, itemName));
}
this.$.cardPopup.hide ();
}
,onEraseClick: function ()
{
this.$.amount.value = 0;
this.items = {};
}
,onPopupClose: function ()
{
this.onEraseClick ();
this.$.card.row = -1;
this.$.cardLot.assign ({item: undefined});
}
});
})();