Alpha 2, informes

This commit is contained in:
Juan Ferrer Toribio 2015-09-22 09:20:47 +02:00
parent a5f55b45a3
commit f4a2473428
36 changed files with 355 additions and 1523 deletions

View File

@ -1,42 +0,0 @@
<?php
session_start ();
$params = array
(
'name'
,'surname'
,'email'
,'message'
,'address'
,'pc'
,'city'
,'phone'
,'captcha'
);
$paramsOk = TRUE;
foreach ($params as $param)
if (!isset ($_POST[$param]) || $_POST[$param] == '')
{
$paramsOk = FALSE;
break;
}
header ('Content-Type: application/json');
if ($paramsOk && isset ($_SESSION['captcha'])
&& $_POST['captcha'] == $_SESSION['captcha'])
{
mail ('nuria@verdnatura.es', 'Verdnatura', print_r ($_POST, TRUE),
'From: Verdnatura <www-data@verdnatura.es>');
echo json_encode (TRUE);
}
else
echo json_encode (FALSE);
unset ($_SESSION['captcha']);
?>

View File

@ -0,0 +1,24 @@
Vn.Shelves = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('report-title').value = 'Anthuriums';
this.$('warehouse').value = 1;
this.$('date').value = new Date ();
this.$('shelf').value = 1;
this.$('reign').value = 1;
this.$('family').value = 2;
this.$('filter').value = 'Ant %';
this.$('max-amount').value = 50;
}
,onPreviewClick: function ()
{
var report = new ShelvesReport ();
report.showWindow ();
}
});

View File

@ -0,0 +1,45 @@
.shelves
{
padding: 1em;
}
.shelves .box
{
max-width: 40em;
padding: 2em;
}
.shelves .body
{
max-width: 20em;
margin: auto;
padding: 0;
}
.shelves .form-group
{
padding: 0.4em;
}
.shelves form label
{
display: block;
margin-bottom: 0.5em;
}
.shelves input,
.shelves select
{
margin: 0;
width: 100%;
}
/* Footer */
.shelves .footer
{
text-align: center;
margin-top: 1.5em;
}
.shelves .footer > button
{
margin: 0 .2em;
width: 5em;
}

73
web/forms/admin/shelves/ui.xml Executable file
View File

@ -0,0 +1,73 @@
<vn>
<div id="title">
<h1><t>Shelves</t></h1>
</div>
<div id="form" class="shelves">
<div class="box">
<div class="body">
<div class="form-group">
<label><t>Title</t></label>
<htk-entry id="report-title"/>
</div>
<div class="form-group">
<label><t>Store</t></label>
<htk-combo id="warehouse">
<db-model property="model" id="warehouses">
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Date</t></label>
<htk-date-chooser id="date"/>
</div>
<div class="form-group">
<label><t>Shelf</t></label>
<htk-combo id="shelf">
<db-model property="model" id="shelves">
SELECT id, name FROM vn2008.shelf
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Reign</t></label>
<htk-combo id="reign">
<db-model property="model" id="reigns">
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Family</t></label>
<htk-combo id="family">
<db-model property="model">
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #reign ORDER BY Tipo
<sql-batch property="batch">
<item name="reign" param="reign"/>
</sql-batch>
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Name filter</t></label>
<input type="text" id="filter"/>
</div>
<div class="form-group">
<label><t>Max amount</t></label>
<htk-entry id="max-amount"/>
</div>
</div>
<div class="footer">
<button class="flat">
<t>Save</t>
</button>
<button class="flat" on-click="onPreviewClick">
<t>Preview</t>
</button>
</div>
</div>
</div>
</vn>

View File

@ -24,6 +24,17 @@ Vn.Catalog = new Class
this.conn.execQuery (query, this.onBasketForGuest.bind (this));
}
}
,close: function ()
{
if (this.node)
{
this.gui.$('top-bar').style.backgroundColor = '';
Vn.Node.remove (this.$('right-panel'));
}
this.parent ();
}
,onBasketForGuest: function ()
{
@ -42,13 +53,38 @@ Vn.Catalog = new Class
this.popup = new Htk.Popup ();
this.popup.setChildNode (this.$('lots-popup'));
this.setView ('GRID');
}
,deactivate: function ()
,onSwitchViewClick: function ()
{
this.parent ();
this.gui.$('top-bar').style.backgroundColor = '';
Vn.Node.remove (this.$('right-panel'));
this.setView (this.view == 'LIST' ? 'GRID' : 'LIST');
}
,setView: function (view)
{
if (this.viewNode)
{
Vn.Node.remove (this.viewNode);
this.viewHolder.model = null;
}
if (view == 'GRID')
{
this.view = 'GRID';
this.viewNode = this.$('grid-view').getNode ();
this.viewHolder = this.$('grid-view');
}
else
{
this.view = 'LIST';
this.viewNode = this.$('list-view');
this.viewHolder = this.$('items-grid');
}
this.$('main').appendChild (this.viewNode);
this.viewHolder.model = this.$('items-model');
}
,typeRenderer: function (builder, form)

View File

@ -180,18 +180,18 @@ button.confirm > img
}
.items > tbody > tr
{
height: 6em;
height: 4em;
}
.items .icon
{
width: 6em;
padding: .2em;
padding-right: .5em;
width: 4em;
padding: 0;
}
.items .icon > img
{
max-height: 6em;
max-width: 6em;
max-height: 2.5em;
max-width: 2.5em;
border-radius: 50%;
}
td.second-category
{

View File

@ -70,9 +70,10 @@
<htk-button
image="image/dark/view.svg"
tip="_Switch view"
on-click="onBasketClick"
on-click="onSwitchViewClick"
showText="true"/>
<htk-button
id="a"
image="image/dark/basket.svg"
tip="_ShoppingBasket"
on-click="onBasketClick"
@ -83,82 +84,81 @@
</div>
<div id="form" class="catalog">
<div class="center">
<div class="main">
<!-- <div class="box list-view">
<htk-grid empty-message="_SelectSubtype" show-header="false" id="items-grid" class="items" model="items-model">
<htk-column-image
title="*"
class="icon"
column="Foto"
directory="catalog"
subdir="200x200"
show-full="true"
full-dir="900x900"
editable="true"/>
<vn-column-item title="_Name" column="Article" renderer="nameRenderer"/>
<htk-column-text title="_Cat" renderer="featuresRender"/>
<htk-column-spin title="_Aval" column="available"/>
<htk-column-text
title="_Price"
column="price"
format="_from %.2d€"
class="price"/>
<htk-column-button
column="id"
image="image/add.svg"
tip="_AddToBasket"
on-clicked="onAddItemClick"/>
</htk-grid>
<p class="footer-message">
<t>IndicativePhotos</t>
</p>
</div>
--> <htk-repeater id="grid-view" empty-message="_SelectSubtype" class="grid-view" form-id="item" model="items-model">
<template>
<div class="box item-box">
<div class="image">
<htk-image
directory="catalog"
subdir="200x200"
form="item"
column="Foto"
show-full="true"
full-dir="900x900"/>
</div>
<h2>
<htk-text form="item" column="Article"/>
</h2>
<p>
<htk-text form="item" column="producer"/>
</p>
<p>
<htk-text form="item" column="Medida"/>
<htk-text form="item" column="Categoria"/>
<htk-text form="item" column="Color"/>
<htk-text form="item" column="Tallos"/>
<htk-text form="item" column="Abreviatura"/>
</p>
<div class="aval-price">
<htk-text form="item" column="available"/>
<t>from</t>
<span class="price">
<htk-text form="item" column="price" format="%.2d€"/>
</span>
</div>
<htk-button
form="item"
column="id"
tip="_AddToBasket"
image="image/add.svg"
on-click="onGridAddItemClick"
class="add-button"/>
<div class="clear"/>
</div>
</template>
</htk-repeater>
</div>
<div id="main" class="main"/>
</div>
</div>
<div id="list-view" class="box list-view">
<htk-grid id="items-grid" class="items" empty-message="_SelectSubtype" show-header="false">
<htk-column-image
title="*"
class="icon"
column="Foto"
directory="catalog"
subdir="200x200"
show-full="true"
full-dir="900x900"
editable="true"/>
<vn-column-item title="_Name" column="Article" renderer="nameRenderer"/>
<htk-column-text title="_Cat" renderer="featuresRender"/>
<htk-column-spin title="_Aval" column="available"/>
<htk-column-text
title="_Price"
column="price"
format="_from %.2d€"
class="price"/>
<htk-column-button
column="id"
image="image/add.svg"
tip="_AddToBasket"
on-clicked="onAddItemClick"/>
</htk-grid>
<p class="footer-message">
<t>IndicativePhotos</t>
</p>
</div>
<htk-repeater id="grid-view" class="grid-view" empty-message="_SelectSubtype" form-id="item">
<template>
<div class="box item-box">
<div class="image">
<htk-image
directory="catalog"
subdir="200x200"
form="item"
column="Foto"
show-full="true"
full-dir="900x900"/>
</div>
<h2>
<htk-text form="item" column="Article"/>
</h2>
<p>
<htk-text form="item" column="producer"/>
</p>
<p>
<htk-text form="item" column="Medida"/>
<htk-text form="item" column="Categoria"/>
<htk-text form="item" column="Color"/>
<htk-text form="item" column="Tallos"/>
<htk-text form="item" column="Abreviatura"/>
</p>
<div class="aval-price">
<htk-text form="item" column="available"/>
<t>from</t>
<span class="price">
<htk-text form="item" column="price" format="%.2d€"/>
</span>
</div>
<htk-button
form="item"
column="id"
tip="_AddToBasket"
image="image/add.svg"
on-click="onGridAddItemClick"
class="add-button"/>
<div class="clear"/>
</div>
</template>
</htk-repeater>
<div id="right-panel" class="right-panel" on-click="onRightPanelClick">
<htk-repeater
model="realms-model"

View File

@ -104,7 +104,7 @@ Db.Conn.implement
this.signalEmit ('loading-changed', true);
var request = new Vn.HttpRequest ();
request.add ({'action': 'close'});
request.add ({'action': 'logout'});
request.send ('rest.php',
this.closed.bind (this, closeCallback));
}

View File

@ -13,6 +13,7 @@ Vn.includeLib ('hedera',
,'login'
,'gui'
,'module'
,'report'
,'app'
,'tpv'
]);

17
web/js/hedera/report.css Executable file
View File

@ -0,0 +1,17 @@
@font-face
{
font-family: 'Open Sans';
src: url('opensans.ttf') format('truetype');
}
body
{
position: absolute;
margin: 0;
height: 100%;
width: 100%;
z-index: -2;
background-color: #EEE;
}

14
web/js/hedera/report.html Executable file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no"/>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"/>
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/>
<link rel="stylesheet" type="text/css" href="js/hedera/report.css"/>
<title>Report</title>
</head>
<body></body>
</html>

View File

@ -1,18 +1,29 @@
Vn.Module = new Class
Vn.Report = new Class
({
Extends: Vn.Object
,initialize: function (gui, formInfo)
,initialize: function (props)
{
this.gui = gui;
this.conn = gui.conn;
this.hash = gui.hash;
this.formInfo = formInfo;
this.parent (props);
this.open ();
}
,showWindow: function ()
{
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 report = new Vn.Report (reportWindow.document.body);
return reportWindow;
}
/**
* Gets an object from the builder associated to this form.
* 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
@ -29,12 +40,10 @@ Vn.Module = new Class
* Called when the form is opened.
**/
,open: function ()
{
this.close ();
{
this.builder = new Vn.Builder ();
this.builder.signalData = this;
this.builder.loadXml (Vn.getXml ('forms/'+ this.formInfo.path +'/ui.xml'));
this.builder.loadXml (Vn.getXml ('reports/'+ this.reportPath +'/report.xml'));
this.node = this.builder.get ('form');
var models = this.builder.getObjects ('db-model');
@ -46,30 +55,25 @@ Vn.Module = new Class
for (var i = 0; i < queries.length; i++)
queries[i].conn = this.conn;
this.gui.formHolder.appendChild (this.node);
}
/**
* Called when the form is activated.
**/
,activate: function () {}
/**
* Called when the form is deactivated.
**/
,deactivate: function () {}
/**
* Called when the form is closed.
**/
,close: function ()
{
if (this.node)
{
Vn.Node.remove (this.node);
this.node = null;
}
if (this.builder)
{
this.builder.unref ();
this.builder = null;
}
this.builder.unref ();
this.builder = null;
}
,_destroy: function ()

View File

@ -45,7 +45,10 @@ Htk.FullImage = new Class
,show: function (src)
{
if (this.closed && this.src == src)
{
this.closed = false;
return;
}
this.cancelHide ();
this.loadingBox.style.left = this.getLeft (40);

View File

@ -151,7 +151,7 @@ Htk.Grid = new Class
,onUpdatableChange: function ()
{
if (this._model.updatable)
if (this._model && this._model.updatable)
{
if (!this.internalColumn)
{

View File

@ -55,10 +55,7 @@ Vn.Node =
,show: function (node)
{
var style = window.getComputedStyle (node);
if (style.display === 'none')
node.style.display = 'initial';
node.style.display = 'block';
}
};

View File

@ -1,9 +0,0 @@
{
"User": "Usuari"
,"Password": "Contrasenya"
,"NotCloseSession": "No tancar sessió"
,"IWantToKnowMore": "Vull saber-ne més!"
,"Enter": "Entrar"
,"LoginMail": "clientes@verdnatura.es"
,"LoginPhone": "+34 607 562 391"
}

View File

@ -1,4 +0,0 @@
{
"Welcome": "Benvingut/da"
,"Exit": "Eixir"
}

View File

@ -1,9 +0,0 @@
{
"User": "Usuario"
,"Password": "Contraseña"
,"NotCloseSession": "No cerrar sesión"
,"IWantToKnowMore": "¡Quiero saber más!"
,"Enter": "Entrar"
,"LoginMail": "clientes@verdnatura.es"
,"LoginPhone": "+34 963 242 100"
}

View File

@ -1,4 +0,0 @@
{
"Welcome": "Bienvenido/a"
,"Exit": "Salir"
}

View File

@ -1,9 +0,0 @@
{
"User": "Utilisateur"
,"Password": "Mot de passe"
,"NotCloseSession": "Garder ma session active"
,"IWantToKnowMore": "En savoir plus!"
,"Enter": "Entrer"
,"LoginMail": "ruben@verdnatura.es"
,"LoginPhone": "+33 781 533 900"
}

View File

@ -1,4 +0,0 @@
{
"Welcome": "Bienvenue"
,"Exit": "Sortir"
}

View File

@ -1,19 +0,0 @@
<?php
require_once ('global/metatags.php');
require_once ('js/vn/main.php');
use Vn\Hedera\Js;
Js::includeFile ('pages/login/login.js');
Js::includeCss ('global/style.css');
Js::includeCss ('pages/login/style.css');
if (Js::isMobile ())
{
Js::includeCss ('global/mobile.css');
Js::includeCss ('pages/login/mobile.css');
}
?>

View File

@ -1,67 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="user-scalable=no"/>
<?php include ('pages/login/head.php') ?>
<link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/>
<title>Login - Verdnatura</title>
</head>
<body>
<div id="header">
<div>
<a href="?page=web&amp;guest=true#!form=cms/about"><?=s('IWantToKnowMore')?></a>
</div>
</div>
<div id="body">
<div id="column">
<div id="login">
<form id="form" action="?page=login&amp;login" method="post">
<div id="logo">
<img src="image/logo.svg" alt=""/>
</div>
<div id="version-code">
</div>
<div id="form-inputs">
<div class="form-group">
<label for="user"><?=s('User')?></label>
<input type="text" id="user" name="user"/>
</div>
<div class="form-group">
<label for="pass"><?=s('Password')?></label>
<input type="password" id="pass" name="password"/>
</div>
</div>
<div id="bottom">
<input type="checkbox" id="remember" name="remember"/>
<label for="remember"><?=s("NotCloseSession")?></label>
</div>
<div>
<input type="submit" value="<?=s('Enter')?>"/>
</div>
<div id="info">
<p><?=s("LoginMail")?></p>
<p><?=s("LoginPhone")?></p>
</div>
<div id="links">
<a target="_blank" href="http://verdnaturacomunicacion.blogspot.com.es/">
<img alt="Blogger" src="image/blogger.svg" title="Blogger"/>
</a>
<a target="_blank" href="https://plus.google.com/u/0/107516577801959283883/posts">
<img alt="Google+" src="image/google-plus.svg" title="Google+"/>
</a>
<a target="_blank" href="http://www.facebook.com/verdnatura">
<img alt="Facebook" src="image/facebook.svg" title="Facebook"/>
</a>
<a target="_blank" href="http://www.youtube.com/user/verdnatura">
<img alt="YouTube" src="image/youtube.svg" title="YouTube"/>
</a>
</div>
</form>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,33 +0,0 @@
window.addEventListener ('load', function () {
var web = new Vn.Login ();
});
Vn.Login = new Class
({
Extends: Vn.Object
,initialize: function ()
{
Vn.Hash.initialize ();
switch (Vn.Hash.get ('error'))
{
case 'badLogin':
alert (_('InvalidLogin'));
break;
case 'sessionExpired':
alert (_('SessionExpired'));
break;
}
var userEntry = document.getElementById ('user');
if (Vn.Cookie.check ('vn_user'))
userEntry.value = Vn.Cookie.get ('vn_user');
userEntry.focus ();
userEntry.select ();
}
});

View File

@ -1,24 +0,0 @@
<?php
use Vn\Hedera\Web;
if (isset ($_GET['logout']))
try
{
Web::login ();
Web::logout ();
}
catch (Exception $e) {}
if (Web::login ())
{
header ('Location: ?page=web');
exit;
}
elseif (isset ($_GET['login']))
{
header ('Location: ?page=login#!error=badLogin');
exit;
}
?>

View File

@ -1,166 +0,0 @@
body
{
position: absolute;
margin: 0;
height: 100%;
width: 100%;
z-index: -2;
background-color: #EEE;
}
body,
label,
button,
input,
textarea,
p,
a
{
font-size: 1.2em;
font-weight: normal;
color: #333;
/* text-shadow: 0 0.2em 0.2em #AAA; */
}
/* Header */
#header
{
z-index: 10;
position: absolute;
background-color: #333;
width: 100%;
height: 3.5em;
}
#header div
{
margin-top: 1em;
text-align: center;
}
#header a
{
color: white;
}
/* Body */
#body
{
position: absolute;
top: 3.5em;
left: 0;
right: 0;
bottom: 0;
/* background-image: url("background.png");
background-repeat: repeat;
*/
}
#column
{
position: relative;
margin: 0 auto;
overflow: auto;
max-width: 40em;
height: 100%;
background-color: white;
box-shadow: 0 0.2em 0.2em #DDD;
}
/* Login */
#login
{
position: absolute;
margin-top: -17em;
padding: 1em;
max-width: 45em;
top: 50%;
left: 0;
right: 0;
}
#logo img
{
display: block;
margin: 0.5em auto;
min-width: 24em;
width: 75%;
}
#version-code
{
color: red;
text-align: right;
margin: 0.2em auto;
font-weight: bold;
height: 2em;
}
#form-inputs
{
margin: 0 auto;
max-width: 16em;
}
div.form-group label
{
display: block;
}
input
{
border-radius: 0.1em;
box-shadow: 0 0.1em 0.1em #AAA;
margin: 0.3em;
}
input[type=text],
input[type=password]
{
margin: 0.5em 0;
margin-bottom: 0.5em;
padding: 0.5em;
width: 100%;
border: 1px solid #AAA;
}
td.entry
{
text-align: left;
}
input[type=submit]
{
display: block;
margin: 0 auto;
background-color: #AD4;
border: 1px solid #8B2;
height: 2.4em;
width: 8em;
color: #250;
}
input[type=submit]:hover
{
background-color: #9C3;
}
#bottom
{
text-align: center;
padding: 1em;
}
/* Info */
#info
{
margin-top: 2.5em;
text-align: center;
}
#info p
{
margin: 0.5em;
}
#links
{
margin: 0 auto;
margin-top: 2em;
text-align: center;
}
#links img
{
height: 1.8em;
}

View File

@ -1,21 +0,0 @@
<?php
use Vn\Hedera\Js;
require_once ('global/metatags.php');
require_once ('js/htk/main.php');
Js::includeFile ('pages/web/web.js');
Js::includeFile ('pages/web/module.js');
Js::includeFile ('pages/web/tpv.js');
Js::includeCss ('global/style.css');
Js::includeCss ('pages/web/style.css');
if (Js::isMobile ())
{
Js::includeCss ('global/mobile.css');
Js::includeCss ('pages/web/mobile.css');
}
?>

View File

@ -1,59 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="user-scalable=no"/>
<!--<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"/>-->
<meta name="mobile-web-app-capable" content="yes">
<link rel="shortcut icon" type="image/x-icon" href="image/favicon.ico"/>
<title>Verdnatura</title>
<?php include ('pages/web/head.php') ?>
</head>
<body>
<div id="header">
<div id="header-bar">
<button id="menu-button">
<img src="image/dark/menu.svg" alt="<?=s('Menu')?>"/>
</button>
<a id="exit" href="?page=login&amp;logout">
<span id="exit-text"><?=s('Exit')?></span>
</a>
<img id="logo" src="image/dark/logo.svg" alt="Verdnatura"/>
<img id="loader" src="image/loader.gif" alt="Loading"/>
<div id="welcome">
<?=s('Welcome')?><span id="user-name"></span>
</div>
</div>
</div>
<div id="body">
<div id="content">
<div id="menu-box">
<div id="menu-overflow">
<a id="test-link" href="#"></a>
<ul id="menu"></ul>
</div>
<div id="links">
<a target="_blank" href="http://verdnaturacomunicacion.blogspot.com.es/">
<img alt="Blogger" src="image/blogger.svg" title="Blogger"/>
</a>
<a target="_blank" href="https://plus.google.com/u/0/107516577801959283883/posts">
<img alt="Google+" src="image/google-plus.svg" title="Google+"/>
</a>
<a target="_blank" href="http://www.facebook.com/verdnatura">
<img alt="Facebook" src="image/facebook.svg" title="Facebook"/>
</a>
<a target="_blank" href="http://www.youtube.com/user/verdnatura">
<img alt="YouTube" src="image/youtube.svg" title="YouTube"/>
</a>
</div>
</div>
<div id="background">
</div>
<div id="form-holder">
</div>
</div>
</div>
</body>
</html>

View File

@ -1,26 +0,0 @@
#menu-button
{
display: block;
}
#menu-box
{
display: none;
}
#form-holder
{
left: 0;
}
ul.submenu
{
display: block;
position: relative;
border: none;
border-radius: 0;
background-color: white;
box-shadow: none;
}
.htk-toast
{
margin-left: -11em;
}

View File

@ -1,282 +0,0 @@
body
{
position: absolute;
margin: 0;
height: 100%;
width: 100%;
background-color: #EEE;
}
/* Font */
#welcome,
#exit span,
#menu-title,
#menu a
{
font-size: 1.1em;
}
/* Header */
#header,
#exit
{
height: 4.2em;
}
#header
{
position: relative;
background-color: #333;
width: 100%;
z-index: 1;
}
#header *
{
color: white;
}
#header-bar
{
position: relative;
height: 100%;
overflow: hidden;
}
#logo
{
width: 16em;
float: left;
padding: 1em;
padding-top: 1.2em;
}
#loader
{
float: left;
margin-left: 0.4em;
margin-top: 1.4em;
visibility: hidden;
}
#welcome
{
float: right;
padding: 0 1.5em;
}
#welcome span
{
font-size: 1em;
}
#welcome,
#exit span
{
margin-top: 2em;
}
#exit
{
float: right;
background-color: #FC9900;
width: 4em;
text-align: center;
}
#exit:hover
{
background-color: #FCA910;
}
#exit span
{
display: block;
}
#header,
#content
{
margin: auto;
width: 100%;
}
/* Body */
#body
{
position: absolute;
top: 4.2em;
bottom: 0;
left: 0;
right: 0;
}
#content
{
position: relative;
height: 100%;
}
/* Top bar */
#top-bar
{
height: 3em;
overflow: hidden;
background-color: #CE8;
}
/* Left panel */
#menu-button
{
display: none;
float: left;
border: none;
background-color: transparent;
padding: 0;
margin: 0;
margin-left: 0.6em;
height: 4.2em;
}
#menu-button img
{
height: 2em;
}
#background
{
z-index: 10;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(10, 10, 10, 0.6);
display: none;
}
#menu-box,
#menu > li,
ul.submenu
{
width: 15em;
}
#menu-box
{
z-index: 20;
position: absolute;
left: 0;
bottom: 0;
top: 0;
background-color: white;
z-index: 20;
box-shadow: 0 0.2em 0.2em #AAA;
}
#menu-overflow
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 4em;
overflow: auto;
}
/* Test link */
#test-link
{
display: block;
margin: 1em auto;
max-width: 70%;
background-color: #3f51b5;
color: white;
padding: 0 1em;
line-height: 2em;
border-radius: 0.1em;
text-align: center;
}
#test-link:hover
{
background-color: #4f61c5;
}
/* Menu */
#menu
{
list-style-type: none;
padding: 0;
margin: 0;
}
#menu > li
{
display: block;
float: left;
clear: both;
padding: 0;
}
#menu > li > a
{
line-height: 2.8em;
width: 70%;
padding: 0 15%;
}
#menu a
{
float: left;
}
#menu a:hover
{
background-color: #DDD /* #AC6 */;
}
#menu a.selected
{
background-color: #EEE;
}
ul.submenu
{
display: none;
position: fixed;
border: none;
border-radius: 1px;
background-color: white;
box-shadow: 0 0.2em 0.2em #CCC;
z-index: 50;
list-style-type: none;
padding-left: 0;
}
ul.submenu a
{
width: 60%;
padding: 0.7em 20%;
}
/* Links */
#links
{
position: absolute;
bottom: 0;
right: 0;
padding: 0.8em;
}
#links a
{
padding: 0.1em;
display: block;
float: left;
max-width: 2.2em;
}
#links img
{
height: 1.8em;
}
/* Form holder */
#form-holder
{
position: absolute;
top: 0em;
bottom: 0;
right: 0;
left: 15em;
overflow: auto;
}
.htk-toast
{
margin-left: -3em;
}

View File

@ -1,124 +0,0 @@
Vn.Tpv =
{
check: function (conn)
{
var tpvStatus = Vn.Hash.get ('tpv_status');
if (tpvStatus)
{
var batch = new Sql.Batch ();
batch.addValue ('transaction', Vn.Hash.get ('tpv_order'));
batch.addValue ('status', tpvStatus);
var query = 'CALL transaction_end (#transaction, #status)';
conn.execQuery (query, null, batch);
}
}
,pay: function (conn, amount, company)
{
if (amount > 0)
{
var query = 'CALL transaction_start (#company, #amount)';
var batch = new Sql.Batch ();
batch.addValue ('company', company);
batch.addValue ('amount', parseInt (amount * 100));
conn.execQuery (query,
this._onTransactionStart.bind (this), batch);
}
else if (!isNaN (amount))
Htk.Toast.showError (_('AmountError'));
}
,_onTransactionStart: function (resultSet)
{
var res = resultSet.fetchResult ();
if (res && res.next ())
{
var form = document.createElement ('form');
form.method = 'post';
form.action = res.get ('url');
document.body.appendChild (form);
var fieldsMap =
{
'Ds_Merchant_Amount': 'amount'
,'Ds_Merchant_Order': 'ds_order'
,'Ds_Merchant_MerchantCode': 'id'
,'Ds_Merchant_Currency': 'currency'
,'Ds_Merchant_TransactionType': 'transaction_type'
,'Ds_Merchant_Terminal': 'terminal'
,'Ds_Merchant_MerchantURL': 'merchant_url'
,'Ds_Merchant_MerchantSignature': 'signature'
,'Ds_Merchant_UrlOK': null
,'Ds_Merchant_UrlKO': null
};
for (var field in fieldsMap)
{
var input = document.createElement ('input');
input.type = 'hidden';
input.name = field;
form.appendChild (input);
if (fieldsMap[field])
input.value = res.get (fieldsMap[field]);
}
var transactionId = res.get ('ds_order');
form['Ds_Merchant_UrlOK'].value = this._makeUrl ('ok', transactionId);
form['Ds_Merchant_UrlKO'].value = this._makeUrl ('ko', transactionId);
form.submit ();
}
else
Htk.Toast.showWarning (_('PayError'));
}
,_makeUrl: function (status, order)
{
var path = location.protocol +'//'+ location.host;
path += location.port ? ':'+ location.port : '';
path += location.pathname;
path += location.search ? location.search : '';
path += Vn.Hash.make ({
'form': 'ecomerce/orders',
'tpv_status': status,
'tpv_order': order
}, true);
return path;
}
};
Vn.BasketChecker =
{
check: function (conn, callback)
{
conn.execQuery ('CALL basket_check ()',
this._onBasketCheck.bind (this, callback));
}
,_onBasketCheck: function (callback, resultSet)
{
var status = resultSet.fetchValue ();
if (!status)
return;
var isOk = status == 'UPDATED' || status == 'OK';
if (status == 'UPDATED')
Htk.Toast.showWarning (_('OrderItemsUpdated'));
if (callback)
callback (isOk);
if (!isOk)
Vn.Hash.set ({'form': 'ecomerce/checkout'});
}
};

View File

@ -1,496 +0,0 @@
window.addEventListener ('load', function () {
var web = new Vn.Web ();
});
Vn.Web = new Class
({
Extends: Htk.Widget
,forms: {}
,activeForm: null
,activeCss: null
,requestedForm: null
,menuShown: false
,menuOptions: {}
,choosedOption: null
,initialize: function ()
{
window.onerror = function (message, file, line)
{
var error = new Error (message);
error.fileName = file;
error.lineNumber = line;
Htk.Toast.showError (_('InternalError'));
this.notifyError (error);
}.bind (this);
this.loadingCount = 0;
this.loader = $('loader');
this.formHolder = $('form-holder');
Vn.Hash.initialize ();
this.hash = Vn.Hash;
this.hashParam = new Vn.HashParam ({key: 'form'});
this.hashParam.on ('changed', this.onFormChange, this);
$('background').onclick = function () {};
$('menu-button').addEventListener ('click', function (event)
{
event.stopPropagation ();
if (!this.menuShown)
this.showMenu ();
else
this.hideMenu ();
}.bind (this));
$('menu-box').addEventListener ('click', function (event)
{
event.stopPropagation ();
});
if (!Vn.Cookie.check ('hedera_cookies'))
{
Vn.Cookie.set ('hedera_cookies', true);
Htk.Toast.showWarning (_('CookiesNotification'));
}
this.conn = new Db.Conn ();
this.conn.on ('error', this.onConnError, this);
this.conn.on ('loading-changed', this.onConnLoading, this);
// this.conn.open (null, null, null, this.connOpened.bind (this));
var sql = 'SELECT default_form, image_dir FROM config;'
+'SELECT production_domain, test_domain FROM config;'
+'SELECT name FROM customer_view;'
+'CALL form_list ();';
this.conn.execQuery (sql, this.onMainQueryDone.bind (this));
}
,showBackground: function ()
{
Vn.Node.show ($('background'));
}
,hideBackground: function ()
{
Vn.Node.hide ($('background'));
}
,showMenu: function ()
{
this.showBackground ();
Vn.Node.show ($('menu-box'));
this.menuShown = true;
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
this.hideBackground ();
Vn.Node.hide ($('menu-box'));
$('menu-button').style.display = 'initial';
this.menuShown = false;
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
}
,onMainQueryDone: function (resultSet)
{
// Retrieving configuration parameters
var res = resultSet.fetchResult ();
var columns = res.columns;
if (res.next ())
for (var i = 0; i < res.columns.length; i++)
Vn.Config[columns[i].name] = res.get (columns[i].name);
// Retrieving configuration parameters
var res = resultSet.fetchResult ();
if (res.next () && res.get ('test_domain'))
{
if (location.host != res.get ('production_domain'))
{
var linkText = 'ReturnToOldWebsite';
var linkField = 'production_domain';
}
else
{
var linkText = 'TestTheNewWebsite';
var linkField = 'test_domain';
}
Vn.Node.setText ($('test-link'), _(linkText));
$('test-link').href = '//'+ res.get (linkField);
}
else
Vn.Node.hide ($('test-link'));
// Retrieving the user name
var userName = resultSet.fetchValue ();
if (userName)
{
var span = $('user-name');
span.appendChild (document.createTextNode (', '+ userName));
}
// Retrieving menu sections
var res = resultSet.fetchResult ();
var sectionMap = {};
if (res)
for (var i = 0; res.next (); i++)
{
var parent = res.get ('parent');
if (!sectionMap[parent])
sectionMap[parent] = [];
sectionMap[parent].push (i);
}
this.createMenu (res, sectionMap, null, $('menu'));
// Loading the default form
this.onFormChange ();
}
,notifyError: function (error)
{
if (error instanceof Error)
{
var httpRequest = new Vn.HttpRequest ()
httpRequest.add
({
'file': error.fileName
,'line': error.lineNumber
,'message': error.message
,'stack': error.stack
});
httpRequest.send ('log.php');
}
}
,errorHandler: function (error)
{
if (error instanceof Vn.Error)
switch (error.domain)
{
case 'Auth':
this.unload ();
location.assign ('?page=login#!error='+ error.code);
break;
case 'Version':
this.newVersion (error);
break;
case 'User':
Htk.Toast.showError (error.message);
break;
default:
console.error (error.message);
Htk.Toast.showError (_('InternalError'));
}
else
{
console.error (error);
Htk.Toast.showError (_('InternalError'));
this.notifyError (error);
}
}
,onConnError: function (conn, error)
{
this.errorHandler (error);
}
,onConnLoading: function (conn, isLoading)
{
if (isLoading)
this.loaderPush ();
else
this.loaderPop ();
}
,loaderPush: function ()
{
this.loadingCount++;
if (this.loadingCount == 1)
this.loader.style.visibility = 'visible';
}
,loaderPop: function ()
{
if (this.loadingCount == 0)
return;
this.loadingCount--;
if (this.loadingCount == 0)
this.loader.style.visibility = 'hidden';
}
,newVersion: function (error)
{
if (this.newVersionBlock || this.skipVersion)
return;
this.newVersionBlock = true;
var reload;
var message = _('NewVersionAvailable') +"\n\n"+ error.message;
if (error.code == 'criticalVersion')
{
alert (message)
reload = true;
}
else
{
reload = confirm (message);
this.skipVersion = true;
}
if (reload)
{
this.unload ();
location.reload ();
}
this.newVersionBlock = false;
}
,createMenu: function (res, sectionMap, parent, ul)
{
var sections = sectionMap[parent];
for (var i = 0; i < sections.length; i++)
{
res.row = sections[i];
var li = document.createElement ('li');
ul.appendChild (li);
var a = document.createElement ('a');
a.href = Vn.Hash.make ({'form': res.get ('path')});
this.menuOptions[res.get ('path')] = a;
li.appendChild (a);
var text = document.createTextNode (_(res.get ('description')));
a.appendChild (text);
var formId = res.get ('id');
if (sectionMap[formId])
{
var submenu = document.createElement ('ul');
submenu.className = 'submenu';
li.appendChild (submenu);
li.addEventListener ('mouseover',
this.onLiMouseHover.bind (this, submenu, a));
li.addEventListener ('mouseout',
this.onLiMouseOut.bind (this));
this.createMenu (res, sectionMap, formId, submenu);
}
}
}
,onLiMouseHover: function (submenu, parent)
{
if (Vn.isMobile ())
return;
this.hideSubmenu ();
this.activeSubmenu = submenu;
var rect = parent.getBoundingClientRect ();
submenu.style.display = 'inline';
submenu.style.left = rect.right +'px';
submenu.style.top = rect.top +'px';
}
,onLiMouseOut: function ()
{
this.timeout = setTimeout (this.hideSubmenu.bind (this), 160);
}
,hideSubmenu: function ()
{
var submenu = this.activeSubmenu;
if (submenu)
{
submenu.style.display = 'none';
clearTimeout (this.timeout);
this.activeSubmenu = null;
this.timeout = 0;
}
}
,onFormChange: function ()
{
var formPath = this.hashParam.value;
this.openForm (formPath ? formPath : Vn.Config['default_form'], null);
}
,openForm: function (formPath, callback)
{
if (Vn.isMobile ())
this.hideMenu ();
this.loaderPush ();
this.requestedForm = formPath;
var formInfo = this.forms[formPath];
var path = 'forms/'+ formPath;
if (this.activeForm)
{
this.activeForm.close ();
this.activeForm.unref ();
this.activeForm = null;
}
if (this.activeCss)
{
Vn.excludeCss (this.activeCss +'/style.css');
if (Vn.isMobile ())
Vn.excludeCss (this.activeCss +'/mobile.css');
}
this.activeCss = path;
Vn.includeCss (this.activeCss +'/style.css');
if (Vn.isMobile ())
Vn.includeCss (this.activeCss +'/mobile.css');
if (!formInfo)
{
var aux = formPath.split ('/');
var formName = aux[aux.length - 1];
var klass = 'Vn.'+ formName.charAt (0).toUpperCase ();
klass += formName.substr (1).replace (/\w\-\w/g, function (token)
{
return token.charAt (0) + token.charAt (2).toUpperCase ();
});
formInfo = {
path: formPath
,klass: klass
,localeReady: false
,jsReady: false
,uiReady: false
,error: false
,ready: false
,callbacks: []
};
Vn.Locale.load (path,
this.onFormLocaleReady.bind (this, formInfo));
Vn.includeJs (path +'/'+ formName +'.js',
this.onFormJsReady.bind (this, formInfo));
Vn.loadXml ('forms/'+ formPath +'/ui.xml',
this.onFormUiReady.bind (this, formInfo));
this.forms[formPath] = formInfo;
}
var newChoosedOption = this.menuOptions[formInfo.path];
if (newChoosedOption)
{
if (this.choosedOption)
this.choosedOption.className = null;
newChoosedOption.className = 'selected';
this.choosedOption = newChoosedOption;
}
if (callback)
formInfo.callbacks.push (callback);
if (formInfo.ready)
this.onFormReady (formInfo);
}
,onFormLocaleReady: function (formInfo, success)
{
formInfo.localeReady = true;
this.onFormReady (formInfo);
}
,onFormJsReady: function (formInfo, success)
{
formInfo.jsReady = true;
formInfo.error = !success;
this.onFormReady (formInfo);
}
,onFormUiReady: function (formInfo, success)
{
formInfo.uiReady = true;
formInfo.error = !success;
this.onFormReady (formInfo);
}
,onFormReady: function (formInfo)
{
if (!(formInfo.localeReady && formInfo.jsReady && formInfo.uiReady))
return;
formInfo.ready = true;
if (!formInfo.error)
{
if (formInfo.path == this.requestedForm)
try {
var klass = eval (formInfo.klass);
this.activeForm = new klass (this, formInfo);
this.activeForm.open ();
this.activeForm.activate ();
}
catch (e) {
formInfo.error = true;
this.errorHandler (error);
}
}
else
Htk.Toast.showError (_('ErrorLoadingForm'));
var callbacks = formInfo.callbacks;
formInfo.callbacks = [];
for (var i = 0; i < callbacks.length; i++)
callbacks[i] (this.activeForm);
this.loaderPop ();
}
,unload: function ()
{
this.hashParam.unref ();
this.conn.disconnect ('error', this.onConnError, this);
this.conn.disconnect ('loading-changed', this.onConnLoading, this);
}
});

View File

@ -1,11 +0,0 @@
<?php
use Vn\Hedera\Web;
if (!Web::login ())
{
header ('Location: ?page=login#!error=sessionExpired');
exit;
}
?>

10
web/reports/shelves/report.xml Executable file
View File

@ -0,0 +1,10 @@
<vn>
<div id="report" class="shelves">
<h1>
<htk-text id="title"/>
</h1>
<div>
<htk-text id="page-number"/>
</div>
</div>
</vn>

11
web/reports/shelves/shelves.js Executable file
View File

@ -0,0 +1,11 @@
Vn.ShelvesReport = new Class
({
Extends: Vn.Report
,open: function ()
{
this.parent ();
Vn.Node.setText (this.$('title'), this.title);
}
});

6
web/reports/shelves/style.css Executable file
View File

@ -0,0 +1,6 @@
.shelves
{
padding: 1em;
}