diff --git a/web/forms/admin/shelves/shelves.js b/web/forms/admin/shelves/shelves.js index 818cc849..d5dc9d9c 100755 --- a/web/forms/admin/shelves/shelves.js +++ b/web/forms/admin/shelves/shelves.js @@ -6,7 +6,7 @@ Vn.Shelves = new Class ,activate: function () { this.$('report-title').value = 'Anthuriums'; - this.$('warehouse').value = 1; + this.$('warehouse').value = 44; this.$('date').value = new Date (); this.$('shelf').value = 1; this.$('reign').value = 1; @@ -17,8 +17,291 @@ Vn.Shelves = new Class ,onPreviewClick: function () { - var report = new ShelvesReport (); - report.showWindow (); + var report = new Vn.ShelvesReport ({conn: this.conn}); + report.setParams ( + this.$('report-title').value, + this.$('warehouse').value, + this.$('date').value, + this.$('family').value, + this.$('filter').value, + this.$('max-amount').value, + this.$('shelf').value + ); + report.open (); } }); +Vn.ShelvesReport = new Class +({ + Extends: Vn.Report + + ,nItem: -1 + ,nColors: 4 + + ,setParams: function (title, warehouse, date, type, filter, maxAmount, shelf) + { + this.title = title; + this.maxAmount = maxAmount; + + var batch = new Sql.Batch (); + batch.addValue ('shelf', shelf); + batch.addValue ('wh', warehouse); + batch.addValue ('date', date); + batch.addValue ('type', type); + batch.addValue ('filter', filter); + this.batch = batch; + } + + ,open: function () + { + var query = + 'SELECT id, name, width, height, max_height, tray_height, '+ + 'first_tray_elevation, tray_density, vspacing, hspacing '+ + 'FROM vn2008.shelf WHERE id = #shelf; '+ + 'CALL item_organizer (#wh, #date, #type, #filter)'; + + this.conn.execQuery (query, this.onQueryExec.bind (this), this.batch); + } + + ,onQueryExec: function (resultSet) + { + // Fetch query data + + var res = resultSet.fetchResult (); + res.next (); + + var scale = 0.08; + + var shelf = this.shelf = + { + width: res.get ('width') * scale + ,height: res.get ('height') * scale + ,maxHeight: res.get ('max_height') * scale + ,trayHeight: res.get ('tray_height') * scale + ,firstTrayElevation: res.get ('first_tray_elevation') * scale + ,trayDensity: res.get ('tray_density') * scale + ,vspacing: res.get ('vspacing') * scale + ,hspacing: res.get ('hspacing') * scale + }; + + var items = []; + var res = resultSet.fetchResult (); + + while (res.next ()) + items.push ({ + name: res.get ('Article') +' x'+ res.get ('Medida') + ,boxHeight: res.get ('z') * 10 * scale + ,boxWidth: res.get ('x') * 10 * scale + ,amount: res.get ('etiquetas') + }); + + // Intializes the allocator + + alloc = new Vn.Allocator (); + alloc.items = items; + alloc.maxAmount = this.maxAmount; + alloc.shelfFunc = this.drawShelf.bind (this); + alloc.boxFunc = this.drawBox.bind (this); + + alloc.nTrays = Math.ceil ( + (shelf.height - shelf.firstTrayElevation) / + (shelf.trayHeight + shelf.trayDensity) + ); + alloc.trayWidth = shelf.width - shelf.hspacing * 2; + alloc.trayHeight = shelf.trayHeight - shelf.vspacing; + alloc.topTrayHeight = shelf.maxHeight - shelf.vspacing + - shelf.firstTrayElevation - (alloc.nTrays - 1) * shelf.trayHeight; + + // Opens the report + + this.createWindow ('shelves'); + alloc.run (); + } + + ,drawShelf: function (allocator) + { + var shelf = this.shelf; + + var sheet = this.doc.createElement ('div'); + sheet.className = 'sheet'; +/* sheet.style.top = (allocator.currentShelf * 297) +'mm'; +*/ this.doc.body.appendChild (sheet); + + // Draws the title + + var title = this.doc.createElement ('h1'); + title.className = 'title'; + title.appendChild (this.doc.createTextNode (this.title)); + sheet.appendChild (title); + + var pageNumber = this.doc.createElement ('h1'); + pageNumber.className = 'page-number'; + pageNumber.appendChild (this.doc.createTextNode (allocator.currentShelf + 1)); + sheet.appendChild (pageNumber); + + // Draws the shelf + + var shelfDiv = this.shelfDiv = this.doc.createElement ('div'); + shelfDiv.className = 'shelf'; + shelfDiv.style.width = this.shelf.width +'mm'; + shelfDiv.style.height = this.shelf.maxHeight +'mm'; + sheet.appendChild (shelfDiv); + + this.drawEdge ().style.left = 0; + this.drawEdge ().style.right = 0; + + // Draws trays + + var lastTrayY = shelf.firstTrayElevation; + + if (shelf.trayHeight > 0) + while (lastTrayY + shelf.trayDensity < shelf.height) + { + var tray = this.doc.createElement ('div'); + tray.className = 'tray'; + tray.style.width = this.shelf.width +'mm'; + tray.style.height = '1mm'; + tray.style.bottom = lastTrayY +'mm'; + shelfDiv.appendChild (tray); + + lastTrayY += shelf.trayHeight + shelf.trayDensity; + } + } + + ,drawEdge: function (shelfDiv) + { + var edge = this.doc.createElement ('div'); + edge.className = 'edge'; + edge.style.width = '1mm'; + edge.style.height = this.shelf.height +'mm'; + edge.style.bottom = 0; + this.shelfDiv.appendChild (edge); + return edge; + } + + ,drawBox: function (allocator, item, amount) + { + if (item.boxWidth == 0 || item.boxHeight == 0) + return; + + var shelf = this.shelf; + + var x = allocator.trayX + shelf.hspacing; + var y = allocator.trayY + + shelf.firstTrayElevation + shelf.trayDensity + + allocator.currentTray * (shelf.trayHeight + shelf.trayDensity); + + var box = this.doc.createElement ('div'); + box.className = 'box'; + this.shelfDiv.appendChild (box); + + box.style.left = x +'mm'; + box.style.bottom = y +'mm'; + box.style.width = item.boxWidth +'mm'; + box.style.height = item.boxHeight +'mm'; + + 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 ('span'); + box.appendChild (boxLabel); + + var text = this.doc.createTextNode (item.name); + boxLabel.appendChild (text); + } + } +}); + +Vn.Allocator = new Class +({ + addShelf: function () + { + this.currentShelf++; + this.firstShelfBox = true; + + if (this.shelfFunc) + this.shelfFunc (this); + } + + ,addTray: function () + { + if (this.currentTray <= 0) + { + this.addShelf (); + this.currentTray = this.nTrays - 1; + } + else + this.currentTray--; + + this.trayX = 0; + } + + ,addColumn: function (width) + { + if (this.trayX + this.columnWidth + width > this.trayWidth + || this.currentTray == -1) + this.addTray (); + else + this.trayX += this.columnWidth; + + this.trayY = 0; + this.columnWidth = width; + this.lastBoxWidth = width; + } + + ,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.addColumn (item.boxWidth); + + 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; + + for (var i = 0; i < this.items.length; i++) + { + var item = this.items[i]; + + for (var amount = 0; amount < item.amount; amount++) + { + if (amount == 0 + && this.maxAmount > 0 + && item.amount > this.maxAmount) + break; + + this.addBox (item, amount); + this.firstShelfBox = false; + } + } + + return this.currentShelf + 1; + } + +}); + diff --git a/web/forms/admin/shelves/style.css b/web/forms/admin/shelves/style.css index 4a0d36a3..635d0571 100755 --- a/web/forms/admin/shelves/style.css +++ b/web/forms/admin/shelves/style.css @@ -40,6 +40,5 @@ .shelves .footer > button { margin: 0 .2em; - width: 5em; } diff --git a/web/forms/admin/shelves/ui.xml b/web/forms/admin/shelves/ui.xml index feacf5a8..b3b1879d 100755 --- a/web/forms/admin/shelves/ui.xml +++ b/web/forms/admin/shelves/ui.xml @@ -61,10 +61,7 @@ diff --git a/web/forms/ecomerce/catalog/catalog.js b/web/forms/ecomerce/catalog/catalog.js index 8a585edf..8de34492 100755 --- a/web/forms/ecomerce/catalog/catalog.js +++ b/web/forms/ecomerce/catalog/catalog.js @@ -282,18 +282,22 @@ Vn.Catalog = new Class var model = this.$('item-lots'); var grouping = model.get (row, 'grouping'); var warehouse = model.get (row, 'warehouse_id'); + var available = model.get (row, 'available'); var lotAmount = this.items[warehouse]; - + if (lotAmount === undefined) lotAmount = 0; - - lotAmount += grouping; - if (lotAmount <= model.get (row, 'available')) + if (lotAmount < available) { - this.items[warehouse] = lotAmount; - this.$('amount').value += grouping; + var newAmount = lotAmount + grouping; + + if (newAmount > available) + newAmount = available; + + this.items[warehouse] = newAmount; + this.$('amount').value += newAmount - lotAmount; } else Htk.Toast.showError (_('NoMoreAmountAvailable')); diff --git a/web/forms/ecomerce/catalog/ui.xml b/web/forms/ecomerce/catalog/ui.xml index 3c2072bd..3ea5d480 100755 --- a/web/forms/ecomerce/catalog/ui.xml +++ b/web/forms/ecomerce/catalog/ui.xml @@ -71,18 +71,10 @@ CALL bionic_from_item (#item); - SELECT p.warehouse_id, p.grouping, p.price, p.rate, - t.amount, l.available - IFNULL(t.amount, 0) available + SELECT p.warehouse_id, p.grouping, p.price, p.rate, l.available FROM tmp.bionic_lot l JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id - LEFT JOIN ( - SELECT warehouse_id, SUM(amount) amount - FROM basket_item - WHERE item_id = #item - GROUP BY warehouse_id - ) t - ON t.warehouse_id = l.warehouse_id ORDER BY warehouse_id, grouping; diff --git a/web/js/hedera/report.css b/web/js/hedera/report.css index fcbd6f1c..9f33ac9d 100755 --- a/web/js/hedera/report.css +++ b/web/js/hedera/report.css @@ -4,14 +4,72 @@ font-family: 'Open Sans'; src: url('opensans.ttf') format('truetype'); } - +@media print +{ + body + { + -webkit-print-color-adjust: exact; + } + .sheet + { + width: 100%; + page-break-after: always; + } + .print-button + { + display: none; + } +} +@media screen +{ + body + { + background-color: #EEE; + } + .sheet + { + width: 210mm; + height: 297mm; + background-color: white; + margin: 10mm auto; + box-shadow: 0 1mm 1mm #CCC; + padding: 15mm; + } + .print-button + { + position: fixed; + top: 6mm; + right: 6mm; + border-radius: 2px; + background-color: #009688; + color: white; + padding: 2mm; + z-index: 100; + border: none; + cursor: pointer; + box-shadow: 0 1mm 1mm #AAA; + } + .print-button:hover + { + background-color: #00796B; + } +} +* +{ + font-family: 'Droid Sans', 'Sans'; +} body { - position: absolute; + position: relative; margin: 0; - height: 100%; width: 100%; z-index: -2; - background-color: #EEE; +} +.sheet +{ + position: relative; + overflow: hidden; + box-sizing: padding-box; +/* page-break-after: always;*/ } diff --git a/web/js/hedera/report.html b/web/js/hedera/report.html index 477f1b9c..951db928 100755 --- a/web/js/hedera/report.html +++ b/web/js/hedera/report.html @@ -7,7 +7,7 @@ - + Report diff --git a/web/js/hedera/report.js b/web/js/hedera/report.js index 8142c43c..7a331a28 100755 --- a/web/js/hedera/report.js +++ b/web/js/hedera/report.js @@ -3,83 +3,54 @@ Vn.Report = new Class ({ Extends: Vn.Object - ,initialize: function (props) + ,open: function () {} + + ,print: function () { - this.parent (props); - this.open (); + this.window.print (); } - ,showWindow: function () + ,includeCss: function (path) { - var reportWindow = window.open ('js/hedera/report.html', reportPath, - 'resizable=yes,height=600,width=750,scrollbars=yes,menubar=no'); - //report.print (); - - Vn.includeCss ('reports/'+ reportPath +'/style.css'); - window.document.body.appendChild (this.node); + var basePath = location.protocol +'//'+ location.host; + basePath += location.port ? ':'+ location.port : ''; + basePath += location.pathname.substring (0, + location.pathname.lastIndexOf ('/')); + + var link = this.doc.createElement ('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = basePath +'/'+ path + Vn.getVersion (); + + var head = this.doc.getElementsByTagName ('head')[0]; + head.appendChild (link); + } + + ,createWindow: function (reportPath) + { + var reportWindow = window.open (''/*'js/hedera/report.html'*/, '_blank'/*reportPath*/, + 'resizable=yes,height=900,width=900,scrollbars=yes,menubar=true'); + + if (!reportWindow) + { + Htk.Toast.showError ( + _('Can\'t open the report, please unlock popup block and try again')); + return; + } + + this.window = reportWindow; + this.doc = reportWindow.document + + this.includeCss ('js/hedera/report.css'); + this.includeCss ('reports/'+ reportPath +'/style.css'); + + var printButton = this.doc.createElement ('button'); + printButton.className = 'print-button'; + printButton.appendChild (this.doc.createTextNode (_('Print'))); + printButton.addEventListener ('click', this.print.bind (this)); + this.doc.body.appendChild (printButton); - var report = new Vn.Report (reportWindow.document.body); return reportWindow; } - - /** - * Gets an object from the builder associated to this report. - * - * @param {string} objectId The object identifier - * @return {Object} The object, or %null if not found - **/ - ,$: function (objectId) - { - if (this.builder) - return this.builder.get (objectId); - - return null; - } - - /** - * Called when the form is opened. - **/ - ,open: function () - { - this.builder = new Vn.Builder (); - this.builder.signalData = this; - this.builder.loadXml (Vn.getXml ('reports/'+ this.reportPath +'/report.xml')); - this.node = this.builder.get ('form'); - - var models = this.builder.getObjects ('db-model'); - - for (var i = 0; i < models.length; i++) - models[i].conn = this.conn; - - var queries = this.builder.getObjects ('db-query'); - - for (var i = 0; i < queries.length; i++) - queries[i].conn = this.conn; - } - - /** - * Called when the form is activated. - **/ - ,activate: function () {} - - /** - * Called when the form is deactivated. - **/ - ,deactivate: function () {} - - /** - * Called when the form is closed. - **/ - ,close: function () - { - this.builder.unref (); - this.builder = null; - } - - ,_destroy: function () - { - this.close (); - this.parent (); - } }); diff --git a/web/locale/ca/forms/admin/shelves.json b/web/locale/ca/forms/admin/shelves.json new file mode 100644 index 00000000..d5f65f95 --- /dev/null +++ b/web/locale/ca/forms/admin/shelves.json @@ -0,0 +1,11 @@ +{ + "Title": "Título" + ,"Store": "Almacén" + ,"Date": "Fecha" + ,"Shelf": "Estantería" + ,"Reign": "Reino" + ,"Family": "Familia" + ,"Name filter": "Filtro por nombre" + ,"Max amount": "Cantidad máxima" + ,"Preview": "Mostrar" +} diff --git a/web/locale/ca/js/hedera.js b/web/locale/ca/js/hedera.js index 5dfbe023..98988b31 100755 --- a/web/locale/ca/js/hedera.js +++ b/web/locale/ca/js/hedera.js @@ -17,6 +17,7 @@ Vn.Locale.add ,"TestTheNewWebsite": "Prova la nova web!" ,"ReturnToOldWebsite": "Web antiga" ,"ChangeLog": "Canvis recents" + ,"Print": "Imprimir" ,"ErrorLoadingForm": "Error al carregar formulari" ,"CookiesNotification": "En utilitzar aquest lloc web acceptes l'ús de cookies per a la personalització de continguts i anàlisi." @@ -40,6 +41,7 @@ Vn.Locale.add ,"Visits": "Visites" ,"News": "Noticies" ,"Photos": "Fotos" + ,"Shelves": "Estanterías" ,"Contact": "Vull ser client" ,"Training": "Formació" ,"Agencies": "Agències" diff --git a/web/locale/es/forms/admin/shelves.json b/web/locale/es/forms/admin/shelves.json new file mode 100644 index 00000000..d5f65f95 --- /dev/null +++ b/web/locale/es/forms/admin/shelves.json @@ -0,0 +1,11 @@ +{ + "Title": "Título" + ,"Store": "Almacén" + ,"Date": "Fecha" + ,"Shelf": "Estantería" + ,"Reign": "Reino" + ,"Family": "Familia" + ,"Name filter": "Filtro por nombre" + ,"Max amount": "Cantidad máxima" + ,"Preview": "Mostrar" +} diff --git a/web/locale/es/js/hedera.js b/web/locale/es/js/hedera.js index baa952e8..f0bdf697 100755 --- a/web/locale/es/js/hedera.js +++ b/web/locale/es/js/hedera.js @@ -17,6 +17,7 @@ Vn.Locale.add ,"TestTheNewWebsite": "¡Prueba la nueva web!" ,"ReturnToOldWebsite": "Web antigua" ,"ChangeLog": "Cambios recientes" + ,"Print": "Imprimir" ,"ErrorLoadingForm": "Error al cargar formulario" ,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis." @@ -40,6 +41,7 @@ Vn.Locale.add ,"Visits": "Visitas" ,"News": "Noticias" ,"Photos": "Fotos" + ,"Shelves": "Estanterías" ,"Contact": "Quiero ser cliente" ,"Training": "Formación" ,"Agencies": "Agencias" diff --git a/web/locale/fr/forms/admin/shelves.json b/web/locale/fr/forms/admin/shelves.json new file mode 100644 index 00000000..d5f65f95 --- /dev/null +++ b/web/locale/fr/forms/admin/shelves.json @@ -0,0 +1,11 @@ +{ + "Title": "Título" + ,"Store": "Almacén" + ,"Date": "Fecha" + ,"Shelf": "Estantería" + ,"Reign": "Reino" + ,"Family": "Familia" + ,"Name filter": "Filtro por nombre" + ,"Max amount": "Cantidad máxima" + ,"Preview": "Mostrar" +} diff --git a/web/locale/fr/js/hedera.js b/web/locale/fr/js/hedera.js index 7220fdaa..afca6268 100755 --- a/web/locale/fr/js/hedera.js +++ b/web/locale/fr/js/hedera.js @@ -17,6 +17,7 @@ Vn.Locale.add ,"TestTheNewWebsite": "Testez le nouveau site!" ,"ReturnToOldWebsite": "Ancien site web" ,"ChangeLog": "Modifications récentes" + ,"Print": "Imprimir" ,"ErrorLoadingForm": "Forme erreur de chargement" ,"CookiesNotification": "En utilisant ce site, vous acceptez l'utilisation de cookies pour personnaliser le contenu et l'analyse." @@ -40,6 +41,7 @@ Vn.Locale.add ,"Visits": "Visites" ,"News": "Nouvelles" ,"Photos": "Photos" + ,"Shelves": "Estanterías" ,"Contact": "Je veux être client" ,"Training": "Formation" ,"Agencies": "Agences" diff --git a/web/reports/shelves/shelves.js b/web/reports/shelves/shelves.js index e7cf88ae..5344cde6 100755 --- a/web/reports/shelves/shelves.js +++ b/web/reports/shelves/shelves.js @@ -2,10 +2,4 @@ Vn.ShelvesReport = new Class ({ Extends: Vn.Report - - ,open: function () - { - this.parent (); - Vn.Node.setText (this.$('title'), this.title); - } }); diff --git a/web/reports/shelves/style.css b/web/reports/shelves/style.css old mode 100755 new mode 100644 index 014dd922..dc0e7764 --- a/web/reports/shelves/style.css +++ b/web/reports/shelves/style.css @@ -1,6 +1,60 @@ -.shelves -{ - padding: 1em; +h1 +{ + font-weight: normal; + font-size: 15mm; + margin: 0; +} +h1.title +{ + float: left; +} +h1.page-number +{ + float: right; + text-align: right; +} +.shelf +{ + position: relative; + margin: 0 auto; + padding-top: 40mm; +} +.edge, +.tray +{ + position: absolute; + border: 1px solid black; + box-sizing: border-box; +} +.box +{ + position: absolute; + border: 1px solid black; + text-align: center; +} +.box > span +{ + font-size: 70%; + text-align: center; + margin: 5%; + display: inline-block; + line-height: 100%; + vertical-align: middle; +} +.color0 +{ + background-color: #ECC !important; +} +.color1 +{ + background-color: #CEC !important; +} +.color2 +{ + background-color: #CCE !important; +} +.color3 +{ + background-color: #ECE !important; } -