Navbar autohidded on scroll on mobile debices, login bugs solved, more intuitive catalog style

This commit is contained in:
Juan Ferrer Toribio 2015-12-19 16:42:38 +01:00
parent 776b69f3ea
commit 971a5261ff
26 changed files with 432 additions and 219 deletions

2
debian/control vendored
View File

@ -9,7 +9,7 @@ Vcs-Git: git://www.verdnatura.es/var/git/hedera-web
Package: hedera-web Package: hedera-web
Architecture: all Architecture: all
Depends: apache2, php5-mysql, php-vn-web Depends: apache2, php5-mysql, php5-mcrypt, php-vn-web
Suggests: php-text-captcha, php5-imap, vn-image, tinymce Suggests: php-text-captcha, php5-imap, vn-image, tinymce
Section: misc Section: misc
Priority: optional Priority: optional

View File

@ -131,9 +131,9 @@ class Web
} }
} }
try {
Auth::getCredentials (); Auth::getCredentials ();
try {
self::$conn = new Conn (); self::$conn = new Conn ();
self::$conn->open ( self::$conn->open (
$conf['db']['host'] $conf['db']['host']
@ -145,17 +145,17 @@ class Web
self::$conn->query ('CALL user_session_start (#)', [session_id ()]); self::$conn->query ('CALL user_session_start (#)', [session_id ()]);
self::$conn->query ('SET @lang = #', [\Vn\Lib\Locale::get ()]); self::$conn->query ('SET @lang = #', [\Vn\Lib\Locale::get ()]);
Auth::login ($useCookies); Auth::login (TRUE, $useCookies);
} }
catch (\Exception $e) catch (\Exception $e)
{ {
self::$conn = NULL; self::$conn = NULL;
$success = FALSE; Auth::login (FALSE);
} }
// Registering the user access // Registering the user access
if ($success && !$wasLoged) if (!$wasLoged)
unset ($_SESSION['visitUser']); unset ($_SESSION['visitUser']);
if (isset ($_SESSION['access']) if (isset ($_SESSION['access'])
@ -175,8 +175,6 @@ class Web
if (!isset ($_SESSION['visitUnknown']) && !$success) if (!isset ($_SESSION['visitUnknown']) && !$success)
$_SESSION['visitUnknown'] = $_SESSION['visitUser']; $_SESSION['visitUnknown'] = $_SESSION['visitUser'];
} }
return $success;
} }
static function deinit () static function deinit ()

View File

@ -214,6 +214,45 @@ class Tpv
return FALSE; return FALSE;
} }
static function transactionStart ($conn, $amount, $urlOk, $urlKo, $companyId, &$url, &$signature)
{
$row = $conn->getRow ('CALL transaction_start_sha256 (#, #)',
[$amount, $companyId]);
if (!isset($row))
throw new Exception ('Transaction error');
$transactionId = str_pad ($row['transaction_id'], 12, '0', STR_PAD_LEFT);
$urlOk = empty ($urlOk) ? '' : sprintf ($urlOk, $transactionId);
$urlKo = empty ($urlKo) ? '' : sprintf ($urlKo, $transactionId);
$merchantUrl = $row['merchant_url'] ? $row['merchant_url'] : '';
$params = [
'Ds_Merchant_Amount' => $amount
,'Ds_Merchant_Order' => $transactionId
,'Ds_Merchant_MerchantCode' => $row['merchant']
,'Ds_Merchant_Currency' => $row['currency']
,'Ds_Merchant_TransactionType' => $row['transaction_type']
,'Ds_Merchant_Terminal' => $row['terminal']
,'Ds_Merchant_MerchantURL' => $merchantUrl
,'Ds_Merchant_UrlOK' => $urlOk
,'Ds_Merchant_UrlKO' => $urlKo
];
$encodedParams = base64_encode (json_encode ($params));
$key = base64_decode ($row['secret_key']);
$bytes = array (0, 0, 0, 0, 0, 0, 0, 0);
$iv = implode (array_map ("chr", $bytes));
$key = mcrypt_encrypt (MCRYPT_3DES, $key, $transactionId, MCRYPT_MODE_CBC, $iv);
$signature = base64_encode (hash_hmac ('sha256', $encodedParams, $key, TRUE));
$url = $row['url'];
return $encodedParams;
}
/** /**
* Tests the confirmation process. The corresponding record * Tests the confirmation process. The corresponding record
* must exist in the `tpv_transaction` table. * must exist in the `tpv_transaction` table.

View File

@ -32,7 +32,7 @@
right: 0; right: 0;
width: 17em; width: 17em;
background-color: white; background-color: white;
box-shadow: 0 0.2em 0.2em rgba(1, 1, 1, 0.4); box-shadow: 0 0 .2em rgba(1, 1, 1, 0.4);
overflow: auto; overflow: auto;
} }
.right-panel > .body .right-panel > .body
@ -53,7 +53,7 @@
{ {
background-color: #00acc1; background-color: #00acc1;
color: white; color: white;
box-shadow: 0 0.1em 0.1em rgba(1, 1, 1, 0.3); box-shadow: 0 .1em .1em rgba(1, 1, 1, 0.3);
} }
.right-panel .basket-info > button .right-panel .basket-info > button
{ {
@ -94,10 +94,10 @@
margin: 0; margin: 0;
margin-top: .4em; margin-top: .4em;
line-height: 2em; line-height: 2em;
max-width: 85%;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
max-width: 85%;
} }
.vn-filter li > button .vn-filter li > button
{ {
@ -205,16 +205,16 @@ td.third-category
display: inline-block; display: inline-block;
text-align: left; text-align: left;
position: relative; position: relative;
width: 22em; width: 23em;
padding: .8em; /* padding: .8em;*/
margin: .4em; margin: .4em;
margin-bottom: .1em; margin-bottom: .1em;
height: 9em; height: 10em;
overflow: hidden; overflow: hidden;
} }
.item-box > .image .item-box > .image
{ {
width: 9em; width: 10em;
height: 100%; height: 100%;
float: left; float: left;
margin-right: 1em; margin-right: 1em;
@ -225,35 +225,46 @@ td.third-category
height: 100%; height: 100%;
display: block; display: block;
margin: 0 auto; margin: 0 auto;
border-radius: .3em; /* border-radius: .3em;*/
} }
.item-box > p .item-box > p
{ {
margin: 0; margin: 0;
padding: 0; padding: 0;
font-size: .9em; color: #777;
font-size: .8em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
} }
.item-box > .producer .item-box > .producer
{ {
text-transform: uppercase; text-transform: uppercase;
font-size: 1em;
} }
.item-box > h2 .item-box > h2
{ {
font-size: 1.1em; font-size: 1.2em;
font-weight: normal; font-weight: normal;
padding-top: .6em;
} }
.item-box > .aval-price .item-box > .aval-price
{ {
position: absolute; position: absolute;
bottom: 1em; bottom: .6em;
right: 4em; right: 3.5em;
}
.item-box .from
{
font-size: .8em;
font-style: italic;
} }
.item-box > .add-button .item-box > .add-button
{ {
position: absolute; position: absolute;
bottom: .5em; bottom: .2em;
right: .5em; right: .3em;
padding: .3em;
} }
.item-box > .info-button .item-box > .info-button
{ {
@ -282,8 +293,8 @@ td.third-category
top: 0; top: 0;
right: -17em; right: -17em;
z-index: 20; z-index: 20;
transition: 200ms ease-out all; transition: transform 200ms ease-out;
-webkit-transition: 200ms ease-out all; -webkit-transition: transform 200ms ease-out;
} }
.right-panel.show .right-panel.show
{ {

View File

@ -61,7 +61,7 @@
CALL bionic_calc (); CALL bionic_calc ();
SELECT a.Id_Article item_id, a.description, b.available, b.price, SELECT a.Id_Article item_id, a.description, b.available, b.price,
p.name producer, a.Foto, a.Article, a.Categoria, a.Medida, p.name producer, a.Foto, a.Article, a.Categoria, a.Medida,
a.Tallos, c.str color, o.str origin IF(a.Tallos > 1, a.Tallos, NULL) Tallos, c.str color, o.str origin
FROM tmp.bionic_item b FROM tmp.bionic_item b
JOIN vn2008.Articles a ON a.Id_Article = b.item_id JOIN vn2008.Articles a ON a.Id_Article = b.item_id
LEFT JOIN vn2008.producer p ON p.producer_id = a.producer_id LEFT JOIN vn2008.producer p ON p.producer_id = a.producer_id
@ -200,6 +200,17 @@
<p class="producer"> <p class="producer">
<htk-text form="item" column="producer"/> <htk-text form="item" column="producer"/>
</p> </p>
<p>
<t>Size</t> <htk-text form="item" column="Medida"/>,
<t>Category</t> <htk-text form="item" column="Categoria"/>
</p>
<p>
<t>Color</t> <htk-text form="item" column="color"/>
<htk-text form="item" column="Tallos" format=", %.0d Units"/>
</p>
<!-- <p>
<t>Origin</t> <htk-text form="item" column="origin"/>
</p>
<p> <p>
<htk-text form="item" column="Medida"/> <htk-text form="item" column="Medida"/>
<htk-text form="item" column="Categoria"/> <htk-text form="item" column="Categoria"/>
@ -209,9 +220,11 @@
<htk-text form="item" column="origin"/> <htk-text form="item" column="origin"/>
<htk-text form="item" column="Tallos" format="%.0d Units"/> <htk-text form="item" column="Tallos" format="%.0d Units"/>
</p> </p>
<div class="aval-price"> --> <div class="aval-price">
<htk-text form="item" column="available"/> <htk-text form="item" column="available"/>
<span class="from">
<t>from</t> <t>from</t>
</span>
<span class="price"> <span class="price">
<htk-text form="item" column="price" format="%.2d€"/> <htk-text form="item" column="price" format="%.2d€"/>
</span> </span>

View File

@ -33,7 +33,6 @@ Vn.Orders = new Class
,onPayButtonClick: function () ,onPayButtonClick: function ()
{ {
var company = 442;
var amount = -this.$('debt').value; var amount = -this.$('debt').value;
amount = amount <= 0 ? null : amount; amount = amount <= 0 ? null : amount;
@ -45,7 +44,7 @@ Vn.Orders = new Class
var amount = parseFloat (prompt (_('AmountToPay:'), defaultAmountStr)); var amount = parseFloat (prompt (_('AmountToPay:'), defaultAmountStr));
Vn.Tpv.pay (this.conn, amount, company); Vn.Tpv.pay (this.conn, amount, null);
} }
}); });

View File

@ -75,14 +75,24 @@ Db.Conn.implement
*/ */
,opened: function (request, openCallback, success) ,opened: function (request, openCallback, success)
{ {
var error = null;
var openSuccess = false; var openSuccess = false;
if (success) if (success)
try { try {
var json = request.getJson (); var json = request.getJson ();
openSuccess = json.data == true; openSuccess = json.data == true;
if (json.error)
error = new Vn.Error (
json.error.domain,
json.error.code,
json.error.message);
}
catch (e)
{
error = e;
} }
catch (e) {}
if (openSuccess) if (openSuccess)
{ {
@ -93,7 +103,7 @@ Db.Conn.implement
this.signalEmit ('loading-changed', false); this.signalEmit ('loading-changed', false);
if (openCallback) if (openCallback)
openCallback (this, openSuccess); openCallback (this, openSuccess, error);
} }
/** /**

View File

@ -3,8 +3,6 @@ Vn.App = new Class
({ ({
Extends: Vn.Object Extends: Vn.Object
,_guestLogged: false
,initialize: function () ,initialize: function ()
{ {
window.onerror = this._onWindowError.bind (this); window.onerror = this._onWindowError.bind (this);
@ -26,6 +24,9 @@ Vn.App = new Class
{ {
var guest = Vn.Cookie.check ('hedera_guest'); var guest = Vn.Cookie.check ('hedera_guest');
if (guest)
Vn.Cookie.unset ('hedera_guest');
if (Vn.Cookie.check ('vn_pass')) if (Vn.Cookie.check ('vn_pass'))
{ {
this._conn.open (null, null, null, this._conn.open (null, null, null,
@ -41,9 +42,6 @@ Vn.App = new Class
login.on ('login', this._onLogin, this); login.on ('login', this._onLogin, this);
login.show (); login.show ();
} }
if (guest)
Vn.Cookie.unset ('hedera_guest');
} }
,_onGuestChange: function () ,_onGuestChange: function ()
@ -65,17 +63,15 @@ Vn.App = new Class
,_onGuestLogin: function (conn, success) ,_onGuestLogin: function (conn, success)
{ {
if (!success) this._isGuest.value = undefined;
if (success)
{ {
this._isGuest.value = false;
this.run ();
}
else
{
this._guestLogged = true;
Vn.Cookie.set ('hedera_guest', true); Vn.Cookie.set ('hedera_guest', true);
this._onLogin (); this._onLogin ();
} }
else
this.run ();
} }
,_onAutoLogin: function (success) ,_onAutoLogin: function (success)
@ -101,10 +97,8 @@ Vn.App = new Class
,_onLogout: function (gui) ,_onLogout: function (gui)
{ {
this._freeGui (); this._freeGui ();
this._guestLogged = false;
Vn.Cookie.unset ('hedera_guest'); Vn.Cookie.unset ('hedera_guest');
Vn.Cookie.unset ('vn_pass'); Vn.Cookie.unset ('vn_pass');
Vn.Hash.set (null);
this.run (); this.run ();
} }

View File

@ -16,11 +16,6 @@
/* Navigation bar */ /* Navigation bar */
.vn-gui .navbar,
.vn-gui .exit
{
height: 3.9em;
}
.vn-gui .navbar .vn-gui .navbar
{ {
position: fixed; position: fixed;
@ -31,10 +26,15 @@
z-index: 1; z-index: 1;
overflow: hidden; overflow: hidden;
box-shadow: 0 0.1em 0.1em rgba(1, 1, 1, 0.3); box-shadow: 0 0.1em 0.1em rgba(1, 1, 1, 0.3);
} height: 3.9em;
.vn-gui .navbar
{
color: white; color: white;
/*
transition-property: left, background-color, transform;
transition-duration: 200ms;
transition-timing-function: linear;
*/
transition: transform 200ms ease-in-out;
-webkit-transition: transform 200ms ease-in-out;
} }
.vn-gui .menu-button .vn-gui .menu-button
{ {
@ -156,6 +156,16 @@
background-color: white; background-color: white;
z-index: 20; z-index: 20;
box-shadow: 0 0.2em 0.2em rgba(1, 1, 1, 0.4); box-shadow: 0 0.2em 0.2em rgba(1, 1, 1, 0.4);
width: 15em;
}
.vn-gui .menu-overflow
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 4em;
overflow: auto;
} }
.vn-gui .menu-header .vn-gui .menu-header
{ {
@ -194,21 +204,6 @@
float: right; float: right;
padding: .2em; padding: .2em;
} }
.vn-gui .left-panel,
.vn-gui .main-menu > li,
.vn-gui ul.submenu
{
width: 15em;
}
.vn-gui .menu-overflow
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 4em;
overflow: auto;
}
/* Test link */ /* Test link */
@ -243,6 +238,8 @@
float: left; float: left;
clear: both; clear: both;
padding: 0; padding: 0;
margin: 0;
width: 100%;
} }
.vn-gui .main-menu > li > a .vn-gui .main-menu > li > a
{ {
@ -273,6 +270,7 @@
z-index: 50; z-index: 50;
list-style-type: none; list-style-type: none;
padding-left: 0; padding-left: 0;
width: 15em;
} }
.vn-gui ul.submenu a .vn-gui ul.submenu a
{ {
@ -310,32 +308,27 @@
height: inherit; height: inherit;
box-sizing: border-box; box-sizing: border-box;
height: inherit; height: inherit;
transition-property: margin-left, margin-right;
transition-duration: 200ms;
} }
.vn-gui .form-holder .vn-gui .form-holder
{ {
position: relative; position: relative;
height: inherit; height: inherit;
opacity: 0; opacity: 0;
transform: translateZ(0) translateX(-2em); transform: translateZ(0) translateX(-2em);
-webkit-transform: translateZ(0) translateX(0em);
} }
.vn-gui .form-holder.show .vn-gui .form-holder.show
{ {
transition: 250ms ease-out all; transition: all 250ms ease-out;
-webkittransition: all 250ms ease-out;
opacity: 1; opacity: 1;
transform: translateZ(0) translateX(0em); transform: translateZ(0) translateX(0em);
} -webkit-transform: translateZ(0) translateX(0em);
/* Transitions */
.vn-gui > .body
{
transition-property: margin-left, margin-right;
transition-duration: 200ms;
}
.vn-gui >.navbar
{
transition-property: left, background-color;
transition-duration: 200ms;
} }
/* Desktop */ /* Desktop */
@ -378,8 +371,9 @@
top: 0; top: 0;
left: -15em; left: -15em;
box-shadow: 0 0.2em 0.2em #333; box-shadow: 0 0.2em 0.2em #333;
transition: 200ms ease-out all;
-webkit-transition: 200ms ease-out all; transition: transform 200ms ease-out;
-webkit-transition: transform 200ms ease-out;
} }
.vn-gui .left-panel.show .vn-gui .left-panel.show
{ {
@ -398,6 +392,7 @@
border-radius: 0; border-radius: 0;
background-color: white; background-color: white;
box-shadow: none; box-shadow: none;
width: auto;
} }
.htk-toast .htk-toast
{ {

View File

@ -38,18 +38,16 @@ Vn.Gui = new Class
,menuShown: false ,menuShown: false
,menuOptions: {} ,menuOptions: {}
,choosedOption: null ,choosedOption: null
,_shown: false
,_scrollTimeout: null
,_navbarVisible: true
,initialize: function (props) ,initialize: function (props)
{ {
Vn.includeCss ('js/hedera/gui.css');
this.builderInit ('js/hedera/gui.xml'); this.builderInit ('js/hedera/gui.xml');
this.loadingCount = 0; this.loadingCount = 0;
this.hash = Vn.Hash;
this.hashParam = new Vn.HashParam ({key: 'form'});
this.hashParam.on ('changed', this._onFormChange, this);
this.$('background').onclick = function () {}; this.$('background').onclick = function () {};
this.$('menu-button').addEventListener ('click', function (event) this.$('menu-button').addEventListener ('click', function (event)
@ -63,25 +61,51 @@ Vn.Gui = new Class
event.stopPropagation (); event.stopPropagation ();
}); });
if (!Vn.Cookie.check ('hedera_cookies'))
{
Vn.Cookie.set ('hedera_cookies', true);
Htk.Toast.showWarning (_('By using this site you accept cookies'));
}
this.parent (props); this.parent (props);
} }
,show: function () ,show: function ()
{ {
if (this._shown)
return;
this._shown = true;
Vn.includeCss ('js/hedera/gui.css');
document.body.appendChild (this.node); document.body.appendChild (this.node);
if (Vn.isMobile ())
{
this._onScrollHandler = this._onScroll.bind (this);
window.addEventListener ('scroll', this._onScrollHandler );
}
this.hash = Vn.Hash;
this.formParam = new Vn.HashParam ({key: 'form'});
this.formParam.on ('changed', this._onFormChange, this);
if (!Vn.Cookie.check ('hedera_cookies'))
{
Vn.Cookie.set ('hedera_cookies', true);
Htk.Toast.showWarning (_('By using this site you accept cookies'));
}
} }
,hide: function () ,hide: function ()
{ {
if (!this._shown)
return;
this._shown = false;
if (Vn.isMobile ())
window.removeEventListener ('scroll', this._onScrollHandler);
this.formParam.unref ();
this.closeForm (); this.closeForm ();
this.hideMenu (); this.hideMenu ();
Vn.Node.remove (this.node); Vn.Node.remove (this.node);
Vn.excludeCss ('js/hedera/gui.css');
} }
,logout: function () ,logout: function ()
@ -91,45 +115,20 @@ Vn.Gui = new Class
,onLogoutClick: function () ,onLogoutClick: function ()
{ {
this._conn.close (this.onConnClose.bind (this)); this._conn.close (this._onConnClose.bind (this));
} }
,onConnClose: function () ,_onConnClose: function ()
{ {
this.signalEmit ('logout'); this.signalEmit ('logout');
} }
,showBackground: function () ,_onConnLoadChange: function (conn, isLoading)
{ {
Vn.Node.addClass (this.$('background'), 'show'); if (isLoading)
} this.loaderPush ();
else
,hideBackground: function () this.loaderPop ();
{
Vn.Node.removeClass (this.$('background'), 'show');
}
,showMenu: function ()
{
this.showBackground ();
Vn.Node.addClass (this.$('left-panel'), 'show');
this.menuShown = true;
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
if (!this.menuShown)
return;
this.hideBackground ();
Vn.Node.removeClass (this.$('left-panel'), 'show');
this.menuShown = false;
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
} }
,onMainQueryDone: function (resultSet) ,onMainQueryDone: function (resultSet)
@ -199,14 +198,79 @@ Vn.Gui = new Class
this._onFormChange (); this._onFormChange ();
} }
,_onConnLoadChange: function (conn, isLoading) //++++++++++++++++++++++++++++++++++++++++++++++++++++++ Navigation bar
,_onScroll: function ()
{ {
if (isLoading) if (this._scrollTimeout === null)
this.loaderPush (); this._scrollTimeout = setTimeout (
else this._scrollTimeoutFunc.bind (this), 300);
this.loaderPop ();
} }
,_scrollTimeoutFunc: function ()
{
if (!this._shown)
return;
var navbar = this.$('top-bar');
var yOffset = Vn.Browser.getPageYOffset ();
var showNavbar = this._lastYOffset > yOffset || yOffset < navbar.offsetHeight;
if (showNavbar !== this._navbarVisible)
{
if (showNavbar)
var translateY = 0;
else
var translateY = -navbar.offsetHeight;
navbar.style.transform =
'translateZ(0) translateY('+ translateY +'px)';
}
this._navbarVisible = showNavbar;
this._lastYOffset = yOffset;
this._scrollTimeout = null;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Background
,showBackground: function ()
{
Vn.Node.addClass (this.$('background'), 'show');
}
,hideBackground: function ()
{
Vn.Node.removeClass (this.$('background'), 'show');
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Menu
,showMenu: function ()
{
this.showBackground ();
Vn.Node.addClass (this.$('left-panel'), 'show');
this.menuShown = true;
this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback);
}
,hideMenu: function ()
{
if (!this.menuShown)
return;
this.hideBackground ();
Vn.Node.removeClass (this.$('left-panel'), 'show');
this.menuShown = false;
document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Spinner
,loaderPush: function () ,loaderPush: function ()
{ {
this.loadingCount++; this.loadingCount++;
@ -303,7 +367,7 @@ Vn.Gui = new Class
,_onFormChange: function () ,_onFormChange: function ()
{ {
var formPath = this.hashParam.value; var formPath = this.formParam.value;
if (!formPath) if (!formPath)
formPath = Vn.Config['default_form']; formPath = Vn.Config['default_form'];
@ -489,9 +553,7 @@ Vn.Gui = new Class
,_destroy: function () ,_destroy: function ()
{ {
Vn.excludeCss ('js/hedera/gui.css');
this.hide (); this.hide ();
this.hashParam.unref ();
this.parent (); this.parent ();
} }
}); });

View File

@ -85,14 +85,15 @@ Vn.Login = new Class
); );
} }
,_onConnOpen: function (conn, success) ,_onConnOpen: function (conn, success, error)
{ {
this.$('pass').value = ''; this.$('pass').value = '';
if (!success) if (success)
Htk.Toast.showError (_('Invalid login'));
else
this.signalEmit ('login'); this.signalEmit ('login');
else
if (error instanceof Vn.Error && error.domain === 'Auth')
Htk.Toast.showError (_('Invalid login'));
this._focusUserInput (); this._focusUserInput ();
} }

View File

@ -1,25 +1,40 @@
/* Responsive */ /* Responsive */
/* Standard */
@media screen @media screen
{ {
body { font-size: 11pt; } body { font-size: 11pt; }
} }
/* Desktop - Laptop 1360x768 */
@media (max-resolution: 119dpi) and (min-device-width: 1340px) @media (max-resolution: 119dpi) and (min-device-width: 1340px)
{ {
body { font-size: 12pt; } body { font-size: 12pt; }
} }
/* Desktop - FHD 1920x1080 */
@media (max-resolution: 119dpi) and (min-device-width: 1900px) @media (max-resolution: 119dpi) and (min-device-width: 1900px)
{ {
body { font-size: 13pt; } body { font-size: 13pt; }
} }
@media (min-resolution: 120dpi) and (orientation: portrait)
/* Mobile - HD 720x1280 */ /* 384/640 */
@media
(min-resolution: 120dpi) and (orientation: portrait) and (min-device-width: 360px),
(min-resolution: 120dpi) and (orientation: landscape) and (min-device-width: 635px)
{ {
body { font-size: 11pt; } body { font-size: 11pt; }
} }
@media (min-resolution: 120dpi) and (orientation: landscape)
/* Mobile - Lower than HD */
@media
(min-resolution: 120dpi) and (orientation: portrait) and (max-device-width: 359px),
(min-resolution: 120dpi) and (orientation: landscape) and (max-device-width: 634px)
{ {
body { font-size: 11pt; } body { font-size: 9pt; }
} }
/* Global */ /* Global */

View File

@ -21,42 +21,56 @@ Vn.Tpv =
{ {
if (amount > 0) if (amount > 0)
{ {
var query = 'CALL transaction_start (#company, #amount)'; var request = new Vn.HttpRequest ();
request.add
({
'action': 'tpv'
,'amount': parseInt (amount * 100)
,'urlOk': this._makeUrl ('ok')
,'urlKo': this._makeUrl ('ko')
,'company': company
});
var batch = new Sql.Batch (); request.send ('rest.php',
batch.addValue ('company', company); this._onTransactionStart.bind (this, request));
batch.addValue ('amount', parseInt (amount * 100));
conn.execQuery (query,
this._onTransactionStart.bind (this), batch);
} }
else if (!isNaN (amount)) else if (!isNaN (amount))
Htk.Toast.showError (_('AmountError')); Htk.Toast.showError (_('AmountError'));
} }
,_onTransactionStart: function (resultSet) ,_onTransactionStart: function (request, success)
{ {
var res = resultSet.fetchResult (); var data = null;
var error = null;
if (res && res.next ()) if (success)
try {
var json = request.getJson ();
var data = json.data;
if (json.error)
error = new Vn.Error (
json.error.domain,
json.error.code,
json.error.message);
}
catch (e)
{
error = e;
}
if (success && data)
{ {
var form = document.createElement ('form'); var form = document.createElement ('form');
form.method = 'post'; form.method = 'post';
form.action = res.get ('url'); form.action = data.url;
document.body.appendChild (form); document.body.appendChild (form);
var fieldsMap = var fieldsMap =
{ {
'Ds_Merchant_Amount': 'amount' 'Ds_SignatureVersion': 'HMAC_SHA256_V1'
,'Ds_Merchant_Order': 'ds_order' ,'Ds_MerchantParameters': data.params
,'Ds_Merchant_MerchantCode': 'id' ,'Ds_Signature': data.signature
,'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) for (var field in fieldsMap)
@ -67,13 +81,9 @@ Vn.Tpv =
form.appendChild (input); form.appendChild (input);
if (fieldsMap[field]) if (fieldsMap[field])
input.value = res.get (fieldsMap[field]); input.value = 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 (); form.submit ();
} }
else else
@ -89,7 +99,7 @@ Vn.Tpv =
path += Vn.Hash.make ({ path += Vn.Hash.make ({
'form': 'ecomerce/orders', 'form': 'ecomerce/orders',
'tpv_status': status, 'tpv_status': status,
'tpv_order': order 'tpv_order': '%s'
}, true); }, true);
return path; return path;

View File

@ -3,7 +3,8 @@ Vn.resource ('js/htk/image-editor.xml');
Vn.define (function () { Vn.define (function () {
/** /**
* A form to handle the image database, it allows to add new images or replace it * A form to handle the image database, it allows to add new images or
* replace it.
**/ **/
Htk.ImageEditor = new Class Htk.ImageEditor = new Class
({ ({

View File

@ -112,7 +112,7 @@ Htk.Popup = new Class
this._isOpen = true; this._isOpen = true;
document.body.appendChild (this.node); document.body.appendChild (this.node);
this.reset (); this.reset ();
setTimeout (this._onResetTimeout.bind (this), 200); setTimeout (this._onResetTimeout.bind (this), 0);
} }
,_onOpacityTimeout: function () ,_onOpacityTimeout: function ()

View File

@ -295,11 +295,8 @@ td.cell-image img
background-color: #FFF; background-color: #FFF;
text-align: center; text-align: center;
box-shadow: 0 0 0.4em #666; box-shadow: 0 0 0.4em #666;
}
.htk-full-image,
.htk-full-image > img
{
border-radius: .2em; border-radius: .2em;
overflow: hidden;
} }
.htk-full-image-loader .htk-full-image-loader
{ {
@ -314,6 +311,7 @@ td.cell-image img
box-shadow: 0 0 0.4em #666; box-shadow: 0 0 0.4em #666;
height: 1.8em; height: 1.8em;
border-radius: 50%; border-radius: 50%;
overflow: hidden;
} }
/* Toast */ /* Toast */

View File

@ -37,7 +37,7 @@ Vn.HashParam = new Class
type: Object type: Object
,set: function (x) ,set: function (x)
{ {
this._value = x; this._setValue (x, true);
} }
,get: function () ,get: function ()
{ {
@ -59,7 +59,8 @@ Vn.HashParam = new Class
} }
} }
,_lock: false ,_hashLock: false
,_paramLock: false
,_value: undefined ,_value: undefined
,_key: null ,_key: null
,_type: null ,_type: null
@ -74,12 +75,15 @@ Vn.HashParam = new Class
,_onHashChange: function () ,_onHashChange: function ()
{ {
if (!this._key || !this._listener) if (this._hashLock || !this._key || !this._listener)
return; return;
var newValue = Vn.Hash.get (this._key); var newValue = Vn.Hash.get (this._key);
if (this._type) if (newValue === '')
newValue = null;
if (this._type && newValue !== undefined && newValue !== null)
switch (this._type) switch (this._type)
{ {
case Boolean: case Boolean:
@ -90,35 +94,53 @@ Vn.HashParam = new Class
break; break;
} }
if (this._value != newValue) this._hashLock = true;
{ this._setValue (newValue, true);
this._value = newValue; this._hashLock = false;
this.signalEmit ('changed');
this._refreshParam ();
} }
,_setValue: function (newValue, signal)
{
if (newValue == this._value)
return;
this._value = newValue;
if (this._key && !this._hashLock)
{
this._hashLock = true;
var map = {};
map[this._key] = newValue;
Vn.Hash.add (map);
this._hashLock = false;
}
this._refreshParam ();
if (signal)
this.signalEmit ('changed');
} }
,_refreshParam: function () ,_refreshParam: function ()
{ {
if (this._param && !this._lock) if (this._param && !this._paramLock)
{ {
this._lock = true; this._paramLock = true;
this._param.value = this._value; this._param.value = this._value;
this._lock = false; this._paramLock = false;
} }
} }
,_onParamChange: function () ,_onParamChange: function ()
{ {
if (this._lock) if (this._paramLock)
return; return;
var map = {}; this._paramLock = true;
map[this.key] = this._param.value; this._setValue (this._param.value);
this._paramLock = false;
this._lock = true;
Vn.Hash.add (map);
this._lock = false;
} }
}); });

View File

@ -63,8 +63,10 @@ Vn.Url =
if (post.length > 2) if (post.length > 2)
post += '&'; post += '&';
if (value === null || value === undefined)
continue;
if (typeof value == 'boolean') if (typeof value == 'boolean')
value = new Number (value); value = value ? '1' : '0';
post += key +'='+ encodeURIComponent (value); post += key +'='+ encodeURIComponent (value);
} }

View File

@ -9,8 +9,8 @@ Vn.Locale.add
,"Login mail": "clientes@verdnatura.es" ,"Login mail": "clientes@verdnatura.es"
,"Login phone": "+34 607 562 391" ,"Login phone": "+34 607 562 391"
,"You've been too idle": "Has estat massa temps inactiu i la sessió ha expirat." ,"You've been too idle": "Has estat massa temps inactiu i la sessió ha expirat"
,"Invalid login": "Usuari o contrasenya incorrectes. Recorda que s'hi distingeix entre majúscula i minúscula." ,"Invalid login": "Usuari o contrasenya incorrectes, recorda que s'hi distingeix entre majúscula i minúscula"
,"There was an internal error": "S'ha produït un error intern" ,"There was an internal error": "S'ha produït un error intern"
,"Menu": "Menú" ,"Menu": "Menú"

View File

@ -9,8 +9,8 @@ Vn.Locale.add
,"Login mail": "clientes@verdnatura.es" ,"Login mail": "clientes@verdnatura.es"
,"Login phone": "+34 607 562 391" ,"Login phone": "+34 607 562 391"
,"You've been too idle": "You have been idle too long and your session has expired." ,"You've been too idle": "You have been idle too long and your session has expired"
,"Invalid login": "Username or password incorrect. Remember that it is case-sensitive." ,"Invalid login": "Username or password incorrect, remember that it is case-sensitive"
,"There was an internal error": "There was an internal error" ,"There was an internal error": "There was an internal error"
,"Menu": "Menu" ,"Menu": "Menu"

View File

@ -9,8 +9,8 @@ Vn.Locale.add
,"Login mail": "clientes@verdnatura.es" ,"Login mail": "clientes@verdnatura.es"
,"Login phone": "+34 963 242 100" ,"Login phone": "+34 963 242 100"
,"You've been too idle": "Has estado demasiado tiempo inactivo y la sesión ha expirado." ,"You've been too idle": "Has estado demasiado tiempo inactivo y la sesión ha expirado"
,"Invalid login": "Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas." ,"Invalid login": "Usuario o contraseña incorrectos, recuerda que se hace distinción entre mayúsculas y minúsculas"
,"There was an internal error": "Se ha producido un error interno" ,"There was an internal error": "Se ha producido un error interno"
,"Menu": "Menú" ,"Menu": "Menú"

View File

@ -9,8 +9,8 @@ Vn.Locale.add
,"Login mail": "ruben@verdnatura.es" ,"Login mail": "ruben@verdnatura.es"
,"Login phone": "+33 781 533 900" ,"Login phone": "+33 781 533 900"
,"You've been too idle": "Il a eu le temps de trop paresseux et votre session a expiré." ,"You've been too idle": "Il a eu le temps de trop paresseux et votre session a expiré"
,"Invalid login": "Utilisateur ou mot de passe incorrect. N'oubliez pas de distinction entre majuscules et minuscules." ,"Invalid login": "Utilisateur ou mot de passe incorrect, n'oubliez pas de distinction entre majuscules et minuscules"
,"There was an internal error": "Il ya eu une erreur interne" ,"There was an internal error": "Il ya eu une erreur interne"
,"Menu": "Menu" ,"Menu": "Menu"

View File

@ -9,8 +9,8 @@ Vn.Locale.add
,"Login mail": "clientes@verdnatura.es" ,"Login mail": "clientes@verdnatura.es"
,"Login phone": "+34 607 562 391" ,"Login phone": "+34 607 562 391"
,"You've been too idle": "Та нар ч бас зогссон байсан, чуулган хугацаа дууссан байна." ,"You've been too idle": "Та нар ч бас зогссон байсан, чуулган хугацаа дууссан байна"
,"Invalid login": "Хэрэглэгчийн нэр эсвэл нууц үг буруу. Тэр хэргийг мэдрэмтгий гэдгийг санаарай." ,"Invalid login": "Хэрэглэгчийн нэр эсвэл нууц үг буруу, Тэр хэргийг мэдрэмтгий гэдгийг санаарай"
,"There was an internal error": "Дотоод алдаа гарлаа" ,"There was an internal error": "Дотоод алдаа гарлаа"
,"Menu": "Цэс" ,"Menu": "Цэс"

View File

@ -10,7 +10,7 @@ Vn.Locale.add
,"Login phone": "+34 963 242 100" ,"Login phone": "+34 963 242 100"
,"You've been too idle": "Muito tempo de inatividade, a sessão foi finalizada" ,"You've been too idle": "Muito tempo de inatividade, a sessão foi finalizada"
,"Invalid login": "Usuário ou Palavra-Passe incorreto. Lembre-se de diferenciar maiusculas e minusculas." ,"Invalid login": "Usuário ou Palavra-Passe incorreto, lembre-se de diferenciar maiusculas e minusculas"
,"There was an internal error": "Houve um erro interno" ,"There was an internal error": "Houve um erro interno"
,"Menu": "Menú" ,"Menu": "Menú"

View File

@ -56,9 +56,7 @@ Rest\Service::init ();
try { try {
Web::init (); Web::init ();
Web::login ();
if (!Web::login ())
throw new Rest\Exception ('Auth', 'sessionExpired', s('SessionExpired'));
// Checking the client version // Checking the client version
@ -100,9 +98,17 @@ try {
Rest\Service::setData ($module->run ()); Rest\Service::setData ($module->run ());
} }
else else
throw new Rest\Exception ('Rest', 'invalidAction', s('InvalidAction')); throw new Rest\Exception ('Rest', 'invalidAction', s('Invalid action'));
} }
} }
catch (Vn\Web\SessionExpiredException $e)
{
Rest\Service::setError ('Auth', 'sessionExpired', s('The session has expired'));
}
catch (Vn\Web\BadLoginException $e)
{
Rest\Service::setError ('Auth', 'badLogin', s('Invalid login'));
}
catch (Rest\Exception $e) catch (Rest\Exception $e)
{ {
Rest\Service::setError ($e->getDomain (), $e->getCode (), $e->getMessage ()); Rest\Service::setError ($e->getDomain (), $e->getCode (), $e->getMessage ());

37
web/rest/tpv.php Executable file
View File

@ -0,0 +1,37 @@
<?php
require_once ('vn/tpv/tpv.php');
use Vn\Rest;
use Vn\Tpv;
class RestMod extends Rest\Module
{
function run ()
{
if (empty ($_REQUEST['amount']))
throw new Rest\Exception ('Tpv', 'badRequest', s('Bad request'));
$params = Tpv::transactionStart (
$this->conn
,(int) $_REQUEST['amount']
,empty ($_REQUEST['urlOk']) ? NULL : $_REQUEST['urlOk']
,empty ($_REQUEST['urlKo']) ? NULL : $_REQUEST['urlKo']
,empty ($_REQUEST['company']) ? NULL : $_REQUEST['company']
,$url
,$signature
);
$result = [
'url' => $url
,'params' => $params
,'signature' => $signature
];
trigger_error (print_r ($result, TRUE));
return $result;
}
}
?>