Hedera.ShelvesReport = new Class ({ Extends: Hedera.Report ,nItem: -1 ,nColors: 5 ,trayThickness: 2 ,trayMargin: 5 ,activate: function (lot) { var params = lot.params; Object.assign (this, { title: params.reportTitle, maxAmount: params.maxAmount, showPacking: params.showPacking, stack: params.stack, useIds: params.useIds }); var query = 'SELECT id, name, nTrays, topTrayHeight, trayHeight, width, depth '+ 'FROM shelf WHERE id = #shelf; '+ 'CALL itemAllocator (#warehouse, #date, #family, #namePrefix, #useIds)'; this.conn.execQuery (query, this.onQueryExec.bind (this), params); } ,onQueryExec: function (resultSet) { // Fetch query data var row = resultSet.fetchObject (); // Calculates the scale var maxWidth = 160; var maxHeight = 160; var shelfWidth = row.width; var shelfHeight = row.trayHeight * (row.nTrays - 1) + row.topTrayHeight; var scale = maxWidth / shelfWidth; if (shelfHeight * scale > maxHeight) scale = maxHeight / shelfHeight; // Calculates the shelf dimensions var shelf = this.shelf = { nTrays: row.nTrays ,trayHeight: row.trayHeight * scale ,topTrayHeight: row.topTrayHeight * scale ,width: row.width * scale ,depth: row.depth * scale }; // Gets the items var items = this.items = []; var remainings = this.remainings = []; var res = resultSet.fetchResult (); if (res.data.length == 0) { Htk.Toast.showError (_('No items found, check that all fields are correct')); return; } var boxScale = scale * 10; while (row = res.fetchObject ()) if (!this.maxAmount || row.etiquetas <= this.maxAmount) { items.push ({ id: row.Id_Article ,name: row.Article ,packing: row.packing ,amount: row.etiquetas ,boxHeight: row.z * boxScale ,boxWidth: row.x * boxScale ,boxDepth: row.y * boxScale }); } else { remainings.push ({ id: row.Id_Article ,name: row.Article ,packing: row.packing ,amount: row.etiquetas }); } // Intializes the allocator alloc = this.alloc = new Vn.Allocator (); Object.assign (alloc, { items: items, shelfFunc: this.drawShelf.bind (this), boxFunc: this.drawBox.bind (this), stack: this.stack, nTrays: shelf.nTrays, width: shelf.width, depth: shelf.depth, trayHeight: shelf.trayHeight, topTrayHeight: shelf.topTrayHeight, }); // Opens the report this.renderReport (); } ,renderReport: function () { // Remaining amount var remainings = this.remainings; if (remainings.length > 0) { var sheet = this.doc.createElement ('div'); sheet.className = 'sheet remaining'; this.body.appendChild (sheet); var title = this.doc.createElement ('h1'); title.className = 'title'; title.appendChild (this.doc.createTextNode (this.title)); sheet.appendChild (title); var subtitle = this.doc.createElement ('h2'); subtitle.className = 'subtitle'; subtitle.appendChild (this.doc.createTextNode (_('Pallets'))); sheet.appendChild (subtitle); var ul = this.doc.createElement ('table'); sheet.appendChild (ul); for (var i = 0; i < remainings.length; i++) { var li = this.doc.createElement ('tr'); ul.appendChild (li); var span = this.doc.createElement ('td'); span.className = 'item-id'; span.appendChild (this.doc.createTextNode (remainings[i].id.toLocaleString ())); li.appendChild (span); var span = this.doc.createElement ('td'); span.className = 'item'; span.appendChild (this.doc.createTextNode (remainings[i].name)); li.appendChild (span); if (this.showPacking) span.appendChild (this.doc.createTextNode (' '+ remainings[i].packing)); var span = this.doc.createElement ('td'); span.className = 'amount'; span.appendChild (this.doc.createTextNode (remainings[i].amount)); li.appendChild (span); } } // Draws the shelves this.alloc.run (); this.drawShelfRange (this.lastItem, false); } ,drawShelf: function (allocator, item) { var shelf = this.shelf; var sheet = this.doc.createElement ('div'); sheet.className = 'sheet'; this.body.appendChild (sheet); // Draws the title var pageNumber = this.doc.createElement ('h1'); pageNumber.className = 'page-number'; pageNumber.appendChild (this.doc.createTextNode (allocator.currentShelf + 1)); sheet.appendChild (pageNumber); var title = this.doc.createElement ('h1'); title.className = 'title'; title.appendChild (this.doc.createTextNode (this.title)); sheet.appendChild (title); if (this.subtitles) this.drawShelfRange (this.lastItem, false); this.subtitles = this.doc.createElement ('div'); sheet.appendChild (this.subtitles); this.drawShelfRange (item, true); this.lastSubtitles = this.subtitles; // Draws the shelf var trayWidth = shelf.width + this.trayMargin * 2; var shelfHeight = shelf.trayHeight * (shelf.nTrays - 1) + shelf.topTrayHeight + (this.trayThickness + this.trayMargin) * shelf.nTrays; var shelfDiv = this.shelfDiv = this.doc.createElement ('div'); shelfDiv.className = 'shelf'; shelfDiv.style.width = this.mm (trayWidth); shelfDiv.style.height = this.mm (shelfHeight); sheet.appendChild (shelfDiv); // Draws trays for (var i = 0; i < shelf.nTrays; i++) { var tray = this.doc.createElement ('div'); tray.className = 'tray'; tray.style.bottom = this.mm ((shelf.trayHeight + this.trayThickness + this.trayMargin) * i); tray.style.width = this.mm (trayWidth); tray.style.height = this.mm (this.trayThickness); shelfDiv.appendChild (tray); } } ,drawShelfRange: function (item, isFirst) { var labelText = isFirst ? _('Start') : _('End'); var label = this.doc.createElement ('label'); label.className = 'range-label'; label.appendChild (this.doc.createTextNode (labelText)); this.subtitles.appendChild (label); var subtitle = this.doc.createElement ('h2'); subtitle.className = 'subtitle'; subtitle.appendChild (this.doc.createTextNode (this.getItemLabel (item))); this.subtitles.appendChild (subtitle); } ,getItemLabel: function (item) { if (!this.useIds) { var packing = this.showPacking ? (' x'+ item.packing) : ''; return item.name + packing; } else return item.id.toLocaleString (); } ,mm: function (size) { size *= 0.24; return size.toFixed (2) +'em'; } ,drawBox: function (allocator, item, amount) { if (item.boxWidth == 0 || item.boxHeight == 0) return; var shelf = this.shelf; var x = allocator.trayX + this.trayMargin; var y = allocator.trayY + this.trayThickness + this.trayMargin * allocator.currentTray + allocator.currentTray * (shelf.trayHeight + this.trayThickness); var box = this.doc.createElement ('div'); box.className = 'box'; this.shelfDiv.appendChild (box); box.style.left = this.mm (x); box.style.bottom = this.mm (y); box.style.width = this.mm (item.boxWidth); box.style.height = this.mm (item.boxHeight); if (amount == 0) this.nItem++; var nColor = this.nItem % this.nColors; Vn.Node.addClass (box, 'color'+ nColor); if (amount == 0 || allocator.firstShelfBox) { var boxLabel = this.doc.createElement ('div'); if (this.useIds) { var fontSize = item.boxWidth / 5.2; if (fontSize > item.boxHeight - 1) fontSize = item.boxHeight - 1; boxLabel.style.fontSize = this.mm (fontSize); var cssClass = 'id'; } else var cssClass = 'name'; boxLabel.className = 'box-label '+ cssClass; var labelText = this.doc.createTextNode (this.getItemLabel (item)); boxLabel.appendChild (labelText); box.appendChild (boxLabel); } this.lastItem = item; } }); Vn.Allocator = new Class ({ addShelf: function (item) { this.currentShelf++; this.firstShelfBox = true; if (this.shelfFunc) this.shelfFunc (this, item); } ,addTray: function (item) { if (this.currentTray <= 0) { this.addShelf (item); this.currentTray = this.nTrays - 1; } else this.currentTray--; this.trayX = 0; } ,addColumn: function (item) { if (this.trayX + this.columnWidth + item.boxWidth > this.width || this.currentTray == -1) this.addTray (item); else this.trayX += this.columnWidth; this.trayY = 0; this.columnWidth = item.boxWidth; this.lastBoxWidth = item.boxWidth; } ,addBox: function (item, amount) { var trayHeight = this.trayHeight; if (this.currentTray == this.nTrays - 1) trayHeight = this.topTrayHeight; if (this.trayY + item.boxHeight > trayHeight || item.boxWidth > this.lastBoxWidth || (!this.stack && amount == 0)) this.addColumn (item); if (this.boxFunc) this.boxFunc (this, item, amount); this.trayY += item.boxHeight; if (item.boxWidth < this.lastBoxWidth) this.lastBoxWidth = item.boxWidth; } ,run: function () { this.firstShelfBox = false; this.currentShelf = -1; this.currentTray = -1; this.columnWidth = 0; this.lastBoxWidth = 0; this.trayX = 0; this.trayY = 0; this.remaining = false; for (var i = 0; i < this.items.length; i++) { var item = this.items[i]; var boxIncrement = Math.floor (this.depth / item.boxDepth); if (boxIncrement < 1) boxIncrement = 1; for (var amount = 0; amount < item.amount; amount += boxIncrement) { this.addBox (item, amount); this.firstShelfBox = false; } } return this.currentShelf + 1; } });