0
1
Fork 0

Compare commits

...

66 Commits

Author SHA1 Message Date
Juan Ferrer f7d58c8546 gitignore 2020-01-17 13:09:16 +01:00
Juan Ferrer Toribio 85bd397b83 Merge 2018-02-19 18:24:49 +01:00
Juan Ferrer Toribio 5d26b6cc3f Merge 2018-02-19 18:24:40 +01:00
Juan Ferrer Toribio 2ca8a09acd CSS class inherithed in components, bugs solved 2018-01-16 09:10:44 +01:00
Juan Ferrer Toribio 6666304332 Merge 2018-01-15 09:38:13 +01:00
Juan Ferrer Toribio 479ad20fa9 Webpack updated 2018-01-04 10:23:08 +01:00
Juan Ferrer Toribio 17d3a4457e Merge with master 2018-01-03 16:52:45 +01:00
Juan Ferrer Toribio e458987f67 Merge with master 2018-01-03 16:51:59 +01:00
Juan Ferrer Toribio cae37d5d6a Merge 2018-01-02 16:54:47 +01:00
Juan Ferrer Toribio a341f17ee5 Merge 2018-01-02 16:54:40 +01:00
Juan Ferrer Toribio 6829bb5a83 Merge with master 2017-11-29 11:29:08 +01:00
Juan Ferrer Toribio 2b9c28bc76 CSS bug 2017-11-27 16:51:40 +01:00
Juan Ferrer Toribio a5225fbb5c Merge with master 2017-11-27 16:41:08 +01:00
Juan Ferrer Toribio 42b5662b23 Merge with master 2017-11-24 12:38:07 +01:00
Juan Ferrer Toribio b9c14883c4 Backup 2017-11-23 17:06:28 +01:00
Juan Ferrer Toribio 7b54145da6 Refactor, Component improved 2017-11-22 13:25:19 +01:00
Juan Ferrer Toribio 23715816ce Tags Alpha v2 2017-11-21 12:50:55 +01:00
Juan Ferrer Toribio 857e46ce4d Tags alpha, bugs combo 2017-11-20 19:01:14 +01:00
Juan Ferrer Toribio ce167066f4 Refactor 2017-11-20 13:15:01 +01:00
Juan Ferrer Toribio 7658a5680d Tags, errores solucionados 2017-11-16 15:53:20 +01:00
Juan Ferrer Toribio f9c002f08a backup 2017-11-13 17:36:30 +01:00
Juan Ferrer Toribio 1cec1b4cd6 Backup 2017-11-06 16:00:14 +01:00
Juan Ferrer Toribio c3c7c77b65 Push test 2017-11-02 10:45:04 +01:00
Juan Ferrer Toribio 3aaf1298ee Various fixes 2017-11-02 09:23:55 +01:00
Juan Ferrer Toribio 37236b6bb0 Various fixes 2017-10-28 17:13:00 +02:00
Juan Ferrer Toribio fe68eb5ce0 Vn.Model v1 2017-10-25 09:47:32 +02:00
Juan Ferrer Toribio 4d8bd4ad95 Interpolate v2 2017-10-22 02:25:57 +02:00
Juan Ferrer Toribio f0dcd47baf Bugs solved 2017-10-20 19:45:11 +02:00
Juan Ferrer Toribio c1cf88e44d Bugs solved, refactor 2017-10-20 19:22:24 +02:00
Juan Ferrer Toribio 60a1d7cf9e interpolate v1, camelCase htmlId 2017-10-20 19:09:06 +02:00
Juan Ferrer Toribio 63158d335e New mark for translatable TextNode, bugs in builder solved, 4 spaces replaced by tabs 2017-10-20 16:24:49 +02:00
Juan Ferrer Toribio 2e9ea7ac33 Refactorización Vn.Builder 2017-10-20 14:06:16 +02:00
Juan Ferrer Toribio f6603ccc13 Backup 2017-10-18 18:01:21 +02:00
Juan Ferrer Toribio e178c74f25 Backup 2017-10-16 09:58:12 +02:00
Juan Ferrer Toribio 125686307f Backup 2017-10-10 13:58:25 +02:00
Juan Ferrer Toribio a8b6dd4c1a Backup 2017-09-12 13:31:15 +02:00
Juan Ferrer Toribio b8c83df08f Backup 2017-08-21 12:20:36 +02:00
Juan Ferrer Toribio fab5253406 Merge 2017-07-14 07:37:10 +02:00
Juan Ferrer Toribio c1175122d0 Backup 2017-07-05 11:50:42 +02:00
Juan Ferrer Toribio 942772ec03 Errores merge solucionados 2017-07-04 09:13:06 +02:00
Juan Ferrer Toribio 13e45afc77 Merge with master 2017-07-04 08:51:41 +02:00
Juan Ferrer Toribio d327be4780 Backup 2017-05-22 09:08:21 +02:00
Juan Ferrer Toribio ff0b899fa2 Errores solucionados 2017-05-11 17:38:31 +02:00
Juan Ferrer Toribio 06bd47bf91 Merge with master 2017-05-10 08:38:26 +02:00
Juan Ferrer Toribio 45f5cc3deb Merge with master 2017-05-09 15:33:02 +02:00
Juan Ferrer Toribio 25e9b37b75 Merge con master 2017-05-02 15:48:47 +02:00
Juan Ferrer Toribio b7bdef4bf9 Merge with master fixes 2017-04-27 10:39:37 +02:00
Juan Ferrer Toribio 28b2302d78 Backup 2017-04-25 19:56:39 +02:00
Juan Ferrer Toribio 1e43aead46 backup 2017-04-24 09:47:56 +02:00
Juan Ferrer Toribio adb651fe69 Backup 2017-04-21 12:53:15 +02:00
Juan Ferrer Toribio 234566b6af Backup 2017-04-19 08:16:37 +02:00
Juan Ferrer Toribio 73b2fed910 Backup 2017-04-10 18:23:40 +02:00
Juan Ferrer Toribio 22ee7e5020 Backup 2017-04-10 17:17:56 +02:00
Juan Ferrer Toribio 403845bf2b Backup 2017-04-08 13:42:27 +02:00
Juan Ferrer Toribio 0be33631ca Backup 2017-04-07 13:00:33 +02:00
Juan Ferrer Toribio 944a955068 Backup 2017-04-05 16:06:07 +02:00
Juan Ferrer Toribio efdde01e19 Backup 2017-03-30 13:44:53 +02:00
Juan Ferrer Toribio a5854290e9 Backup 2017-03-23 17:20:51 +01:00
Juan Ferrer Toribio 5640951c80 Backup 2017-03-22 17:57:21 +01:00
Juan Ferrer Toribio 86a19925d8 Backup 2017-03-17 13:42:10 +01:00
Juan Ferrer Toribio 043c11a4ed backup 2017-03-09 13:30:39 +01:00
Juan Ferrer Toribio b7ec06ffdc Webpack caching 2017-03-02 11:01:29 +01:00
Juan Ferrer Toribio 1a5bcf2bd2 Deteccion idioma del navedor mejorada 2017-01-18 13:11:23 +01:00
Juan Ferrer Toribio 969f58981e Estilo beta 2017-01-18 12:50:07 +01:00
Juan Ferrer Toribio 2c6c51865f Estilos CSS depurados 2016-12-23 09:57:49 +01:00
Juan Ferrer Toribio 63d75a7ff6 Js doc asteriscos 2016-12-20 10:32:17 +01:00
308 changed files with 9305 additions and 7429 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
node_modules node_modules
build/ build/
config.my.php
.vscode/

View File

@ -17,7 +17,7 @@ return [
/** /**
* Database parameters. * Database parameters.
**/ */
'db' => [ 'db' => [
'host' => 'localhost' 'host' => 'localhost'
,'port' => 3306 ,'port' => 3306

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (1.405.78) stable; urgency=low hedera-web (2.0.4) stable; urgency=low
* Initial Release. * Initial Release.

4
debian/control vendored
View File

@ -9,8 +9,8 @@ Vcs-Git: https://git.verdnatura.es/hedera-web
Package: hedera-web Package: hedera-web
Architecture: all Architecture: all
Depends: apache2 | httpd, nodejs, php5-cli, php5-mysql, php5-mcrypt, php5-ldap, php5-ssh2, php-vn-lib Depends: apache2 | httpd, nodejs, php5-cli, php5-mysql, php5-mcrypt, php5-ldap, php5-ssh2, php5-apcu, php-vn-lib
Suggests: php-text-captcha, php5-imap, tinymce Suggests: php-text-captcha, php5-imap
Section: misc Section: misc
Priority: optional Priority: optional
Description: Verdnatura's web page Description: Verdnatura's web page

1
debian/install vendored
View File

@ -13,3 +13,4 @@ package.json usr/share/hedera-web
build usr/share/hedera-web build usr/share/hedera-web
README.md usr/share/hedera-web README.md usr/share/hedera-web
webpack.config.json usr/share/hedera-web webpack.config.json usr/share/hedera-web
build usr/share/hedera-web

2
debian/rules vendored
View File

@ -6,7 +6,7 @@
dh $@ dh $@
clean: clean:
npm --production run clean npm run clean
dh_clean $@ dh_clean $@
build: build:

View File

@ -5,13 +5,13 @@ Hedera.AddressList = new Class
,activate: function () ,activate: function ()
{ {
this.$('user-model').setInfo ('c', 'myClient', 'hedera'); this.$.userModel.setInfo ('c', 'myClient', 'hedera');
this.$('addresses').setInfo ('a', 'myAddress', 'hedera'); this.$.addresses.setInfo ('a', 'myAddress', 'hedera');
} }
,onAddAddressClick: function () ,onAddAddressClick: function ()
{ {
this.hash.set ({ this.hash.setAll ({
form: 'account/address', form: 'account/address',
address: 0 address: 0
}); });
@ -22,21 +22,13 @@ Hedera.AddressList = new Class
window.history.back(); window.history.back();
} }
,onRemoveAddressClick: function (button, form) ,onRemoveAddressClick: function (button)
{ {
if (confirm (_('AreYouSureDeleteAddress'))) if (confirm (_('AreYouSureDeleteAddress')))
{ {
form.set ('isActive', false); button.lot.set ('isActive', false);
form.refresh (); button.lot.refresh ();
} }
} }
,onEditAddressClick: function (button, form)
{
this.hash.set ({
form: 'account/address',
address: form.get ('id')
});
}
}); });

View File

@ -1,48 +1 @@
.address-list
{
padding: 1em;
}
.address-list .box
{
max-width: 30em;
}
.address-list .form
{
margin: 0 auto;
max-width: 25em;
padding: 2em;
}
.address
{
padding: 1em;
border-bottom: 1px solid #DDD;
}
.address p
{
margin: 0.2em 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.address p.important
{
font-size: 1.2em;
}
.address .actions
{
float: right;
}
.address .actions > .htk-button
{
margin: 0;
}
.address .actions > *
{
display: inline-block;
vertical-align: middle;
}
.address .actions > input
{
margin: .6em;
}

View File

@ -2,71 +2,63 @@
<vn-group> <vn-group>
<db-form id="user-form"> <db-form id="user-form">
<db-model property="model" id="user-model" updatable="true"> <db-model property="model" id="user-model" updatable="true">
<custom>
SELECT id, defaultAddressFk SELECT id, defaultAddressFk
FROM myClient c FROM myClient
</custom>
</db-model> </db-model>
</db-form> </db-form>
<db-model id="addresses" updatable="true"> <db-model id="addresses" updatable="true">
<custom>
SELECT a.id, a.nickname, p.name province, a.postalCode, SELECT a.id, a.nickname, p.name province, a.postalCode,
a.city, a.street, a.isActive, c.country a.city, a.street, a.isActive, c.country
FROM myAddress a FROM myAddress a
LEFT JOIN vn.province p ON p.id = a.provinceFk LEFT JOIN vn.province p ON p.id = a.provinceFk
JOIN vn.country c ON c.id = p.countryFk JOIN vn.country c ON c.id = p.countryFk
WHERE a.isActive WHERE a.isActive
</custom>
</db-model> </db-model>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>Addresses</t></h1> _Addresses
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="add" icon="add"
tip="_AddAddress" tip="_AddAddress"
on-click="onAddAddressClick"/> on-click="onAddAddressClick"/>
</div> </div>
<div id="form" class="address-list"> <div id="main" class="address-list">
<div class="box"> <div class="card list">
<htk-radio-group <htk-radio-group
id="default-address" id="default-address"
column="defaultAddressFk" lot="user-form"
form="user-form"/> name="defaultAddressFk"/>
<htk-repeater model="addresses" form-id="iter"> <htk-repeater model="addresses">
<custom> <custom>
<div class="address"> <a
class="list-row"
href="#!form=account/address&amp;address={{id}}"
title="_EditAddress">
<div class="actions"> <div class="actions">
<htk-radio <htk-radio
form="iter" lot="iter"
column="id" name="id"
radio-group="default-address" radio-group="default-address"
tip="_SetAsDefault"/> tip="_SetAsDefault"/>
<htk-button <htk-button
form="iter" lot="iter"
column="id" name="id"
tip="_RemoveAddress" tip="_RemoveAddress"
icon="delete" icon="delete"
on-click="onRemoveAddressClick"/> on-click="onRemoveAddressClick"/>
<htk-button
form="iter"
column="id"
tip="_EditAddress"
icon="edit"
on-click="onEditAddressClick"/>
</div> </div>
<p class="important"> <p class="important">
<htk-text form="iter" column="nickname"/> {{nickname}}
</p> </p>
<p> <p>
<htk-text form="iter" column="street"/> {{street}}
</p> </p>
<p> <p>
<htk-text form="iter" column="postalCode"/>, {{postalCode}}, {{city}}
<htk-text form="iter" column="city"/>
</p> </p>
</div> </a>
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>

View File

@ -5,14 +5,14 @@ Hedera.Address = new Class
,activate: function () ,activate: function ()
{ {
this.$('model').setInfo ('a', 'myAddress', 'hedera', ['id'], 'id'); this.$.model.setInfo ('a', 'myAddress', 'hedera', ['id'], 'id');
this.$('model').setDefault ('clientFk', 'a', this.$.model.setDefault ('clientFk', 'a',
new Sql.Function ({schema: 'account', name: 'userGetId'})); new Sql.Function ({schema: 'account', name: 'userGetId'}));
} }
,onStatusChange: function (form) ,onStatusChange: function (form)
{ {
if (form.ready && this.$('address').value == 0) if (form.ready && this.$.params.$.address == 0)
form.insertRow (); form.insertRow ();
} }
@ -24,7 +24,7 @@ Hedera.Address = new Class
,onAcceptClick: function () ,onAcceptClick: function ()
{ {
this.$('iter').performOperations (); this.$.iter.performOperations ();
} }
,onReturnClick: function () ,onReturnClick: function ()

View File

@ -1,16 +1 @@
.address
{
padding: 1em;
}
.address .box
{
max-width: 30em;
padding: 2em;
}
.address .form
{
margin: 0 auto;
max-width: 25em;
}

View File

@ -1,33 +1,28 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="address"/> <vn-lot-query id="params">
<vn-hash-param key="address" param="address"/> <vn-spec name="address" type="Number"/>
</vn-lot-query>
<db-form id="iter" on-status-changed="onStatusChange"> <db-form id="iter" on-status-changed="onStatusChange">
<db-model <db-model
id="model" id="model"
property="model" property="model"
updatable="true" updatable="true"
mode="ON_DEMAND" mode="ON_DEMAND"
lot="params"
on-operations-done="onOperationsDone"> on-operations-done="onOperationsDone">
<custom>
SELECT a.id, a.street, a.nickname, a.city, SELECT a.id, a.street, a.nickname, a.city,
a.postalCode, a.provinceFk, c.id countryFk a.postalCode, a.provinceFk, c.id countryFk
FROM myAddress a FROM myAddress a
LEFT JOIN vn.province p ON p.id = a.provinceFk LEFT JOIN vn.province p ON p.id = a.provinceFk
JOIN vn.country c ON c.id = p.countryFk JOIN vn.country c ON c.id = p.countryFk
WHERE a.id = #address WHERE a.id = #address
</custom>
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
</custom>
</sql-batch>
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>AddEditAddress</t></h1> _AddEditAddress
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="ok" icon="ok"
@ -38,60 +33,49 @@
tip="_Return" tip="_Return"
on-click="onReturnClick"/> on-click="onReturnClick"/>
</div> </div>
<div id="form" class="address"> <div id="main" class="address">
<div class="box"> <div class="card form">
<div class="form"> <div>
<div class="form-group"> <label>_Name</label>
<label><t>Name</t></label> <htk-entry lot="iter" name="nickname"/>
<htk-entry column="nickname" form="iter"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Address</t></label> <label>_Address</label>
<htk-entry column="street" form="iter"/> <htk-entry lot="iter" name="street"/>
</div> </div>
<div class="form-group"> <div>
<label><t>City</t></label> <label>_City</label>
<htk-entry column="city" form="iter"/> <htk-entry lot="iter" name="city"/>
</div> </div>
<div class="form-group"> <div>
<label><t>ZipCode</t></label> <label>_ZipCode</label>
<htk-entry column="postalCode" form="iter"/> <htk-entry lot="iter" name="postalCode"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Country</t></label> <label>_Country</label>
<htk-combo> <htk-combo>
<db-param <vn-param
id="country" id="country"
property="param" property="param"
form="iter" lot="iter"
column="countryFk" name="country"
one-way="true"/> one-way="true"/>
<db-model property="model"> <db-model property="model">
<custom>
SELECT id, country FROM vn.country SELECT id, country FROM vn.country
ORDER BY country ORDER BY country
</custom>
</db-model> </db-model>
</htk-combo> </htk-combo>
</div> </div>
<div class="form-group"> <div>
<label><t>Province</t></label> <label>_Province</label>
<htk-combo column="provinceFk" form="iter"> <htk-combo lot="iter" name="province_id">
<db-model property="model"> <db-model property="model" lot="iter">
<custom>
SELECT id, name FROM vn.province SELECT id, name FROM vn.province
WHERE countryFk = #country WHERE countryFk = #country
ORDER BY name ORDER BY name
</custom>
<sql-batch property="batch">
<custom>
<item name="country" param="country"/>
</custom>
</sql-batch>
</db-model> </db-model>
</htk-combo> </htk-combo>
</div> </div>
</div> </div>
</div> </div>
</div>
</vn> </vn>

View File

@ -5,31 +5,49 @@ Hedera.Conf = new Class
,activate: function () ,activate: function ()
{ {
this.$('user-model').setInfo ('c', 'myClient', 'hedera'); this.$.userModel.setInfo ('c', 'myClient', 'hedera');
if (this.hash.$.changePass)
this.onPassChangeClick ();
}
,onChangePassOpen: function ()
{
this.hash.assign ({changePass: true});
}
,onChangePassClose: function ()
{
this.hash.assign ({changePass: undefined});
} }
,onPassChangeClick: function () ,onPassChangeClick: function ()
{ {
this.$('old-password').value = ''; this.$.oldPassword.value = '';
this.$('new-password').value = ''; this.$.newPassword.value = '';
this.$('repeat-password').value = ''; this.$.repeatPassword.value = '';
var recoverPass = this.$('user-form').get ('recoverPass'); var recoverPass = this.$.user.get ('recoverPass');
this.$('old-password').style.display = recoverPass ? 'none' : 'block'; this.$.oldPassword.style.display = recoverPass ? 'none' : 'block';
this.$('change-password').show (); this.$.changePassword.show ();
var focusInput;
if (recoverPass) if (recoverPass)
this.$('new-password').focus (); focusInput = this.$.newPassword;
else else
this.$('old-password').focus (); focusInput = this.$.oldPassword;
focusInput.focus ();
focusInput.select ();
} }
,onPassModifyClick: function () ,onPassModifyClick: function ()
{ {
try { try {
var oldPassword = this.$('old-password').value; var oldPassword = this.$.oldPassword.value;
var newPassword = this.$('new-password').value; var newPassword = this.$.newPassword.value;
var repeatedPassword = this.$('repeat-password').value; var repeatedPassword = this.$.repeatPassword.value;
if (newPassword == '' && repeatedPassword == '') if (newPassword == '' && repeatedPassword == '')
throw new Error (_('Passwords empty')); throw new Error (_('Passwords empty'));
@ -53,25 +71,25 @@ Hedera.Conf = new Class
{ {
if (json) if (json)
{ {
this.$('change-password').hide (); this.$.changePassword.hide ();
Htk.Toast.showMessage (_('Password changed!')); Htk.Toast.showMessage (_('Password changed!'));
this.$('user-form').refresh (); this.$.user.refresh ();
} }
else else
{ {
Htk.Toast.showError (error.message); Htk.Toast.showError (error.message);
this.$('old-password').select (); this.$.oldPassword.select ();
} }
} }
,onPassInfoClick: function () ,onPassInfoClick: function ()
{ {
this.$('password-info').show (); this.$.passwordInfo.show ();
} }
,onAddressesClick: function () ,onAddressesClick: function ()
{ {
this.hash.set ({form: 'account/address-list'}); this.hash.setAll ({form: 'account/address-list'});
} }
}); });

View File

@ -1,18 +1,4 @@
.conf
{
padding: 1em;
}
.conf .box
{
max-width: 30em;
padding: 2em;
}
.conf .form
{
margin: 0 auto;
max-width: 25em;
}
.conf .form-group input[type=password] .conf .form-group input[type=password]
{ {
margin-bottom: 0.5em; margin-bottom: 0.5em;
@ -25,9 +11,10 @@
.pass-info .pass-info
{ {
width: 15em; max-width: 17em;
} }
.pass-info ul .pass-info ul
{ {
list-style-type: none; list-style-type: none;
padding-left: 1.5em;
} }

View File

@ -1,28 +1,22 @@
<vn> <vn>
<vn-group> <vn-group>
<db-form id="password-form"> <db-lot id="password-form">
<db-model property="model">
<custom>
SELECT length, nAlpha, nUpper, nDigits, nPunct SELECT length, nAlpha, nUpper, nDigits, nPunct
FROM account.userPassword FROM account.userPassword
</custom> </db-lot>
</db-model> <db-form id="user">
</db-form>
<db-form id="user-form">
<db-model property="model" id="user-model" updatable="true"> <db-model property="model" id="user-model" updatable="true">
<custom>
SELECT u.id, u.name, u.email, u.recoverPass, SELECT u.id, u.name, u.email, u.recoverPass,
u.nickname, u.lang, c.isToBeMailed, c.id clientFk u.nickname, u.lang, c.isToBeMailed, c.id clientFk
FROM account.userView u FROM account.userView u
LEFT JOIN myClient c LEFT JOIN myClient c
ON u.id = c.id ON u.id = c.id
</custom>
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>Configuration</t></h1> _Configuration
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="place" icon="place"
@ -33,40 +27,41 @@
tip="_Change password" tip="_Change password"
on-click="onPassChangeClick"/> on-click="onPassChangeClick"/>
</div> </div>
<div id="form" class="conf"> <div id="main" class="conf">
<div class="box"> <div class="card form">
<div class="form"> <div>
<div class="form-group"> <label for="user-name">_Username</label>
<label for="user-name"><t>Username</t></label> <htk-text lot="user" name="name"/>
<htk-text form="user-form" column="name"/>
</div> </div>
<div class="form-group"> <div>
<label for="email"><t>Email</t></label> <label for="email">_Email</label>
<htk-entry form="user-form" column="email"></htk-entry> <htk-entry lot="user" name="email"></htk-entry>
</div> </div>
<div class="form-group"> <div>
<label for="nickname"><t>Display name</t></label> <label for="nickname">_Display name</label>
<htk-entry form="user-form" column="nickname"/> <htk-entry lot="user" name="nickname"/>
</div> </div>
<div class="form-group"> <div>
<label for="lang"><t>Language</t></label> <label for="lang">_Language</label>
<htk-combo form="user-form" column="lang"> <htk-combo lot="user" name="lang"
value-field="code">
<db-model property="model"> <db-model property="model">
<custom> SELECT code, name FROM language WHERE active
SELECT code, name FROM language WHERE isActive
</custom>
</db-model> </db-model>
</htk-combo> </htk-combo>
</div> </div>
<div class="form-group"> <div>
<label for="mail"><t>Receive invoices by email</t></label> <span>
<htk-check form="user-form" column="isToBeMailed"/> <htk-check id="mail" lot="user" name="isToBeMailed"/>
</div> <label for="mail">_Receive invoices by email</label>
</span>
</div> </div>
</div> </div>
</div> </div>
<htk-popup <htk-popup
id="change-password" id="change-password"
on-open="onChangePassOpen"
on-closed="onChangePassClose"
modal="true"> modal="true">
<div property="child-node" class="htk-dialog pass-change"> <div property="child-node" class="htk-dialog pass-change">
<div> <div>
@ -85,10 +80,10 @@
</div> </div>
<div class="button-bar"> <div class="button-bar">
<button class="thin" on-click="onPassModifyClick"> <button class="thin" on-click="onPassModifyClick">
<t>Modify</t> _Modify
</button> </button>
<button class="thin" on-click="onPassInfoClick"> <button class="thin" on-click="onPassInfoClick">
<t>Info</t> _Info
</button> </button>
<div class="clear"/> <div class="clear"/>
</div> </div>
@ -99,28 +94,23 @@
modal="true"> modal="true">
<div property="child-node" class="htk-dialog pass-info"> <div property="child-node" class="htk-dialog pass-info">
<h3> <h3>
<t>Password requirements</t> _Password requirements
</h3> </h3>
<ul> <ul>
<li> <li>
<htk-text form="password-form" column="length"/> {{passwordForm.length}} <span>_characters long</span>
<t>characters long</t>
</li> </li>
<li> <li>
<htk-text form="password-form" column="nAlpha"/> {{passwordForm.nAlpha}} <span>_alphabetic characters</span>
<t>alphabetic characters</t>
</li> </li>
<li> <li>
<htk-text form="password-form" column="nUpper"/> {{passwordForm.nUpper}} <span>_capital letters</span>
<t>capital letters</t>
</li> </li>
<li> <li>
<htk-text form="password-form" column="nDigits"/> {{passwordForm.nDigits}} <span>_digits</span>
<t>digits</t>
</li> </li>
<li> <li>
<htk-text form="password-form" column="nPunct"/> {{passwordForm.nPunct}} <span>_symbols</span>
<t>symbols</t>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,36 +1,12 @@
.access-log
.access-log .card
{ {
padding: 1em; max-width: 28em;
}
.access-log .box
{
max-width: 25em;
margin: 0 auto;
}
.access-log .form
{
padding: 2em;
} }
.access-log .form > p .access-log .form > p
{ {
font-size: 1.2em; font-size: 1.2em;
margin: .1em 0; margin: .1em 0;
} }
/* List */
.access-log .list
{
margin-top: 1em;
}
.access-log .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.access-log .item > p
{
margin: .1em 0;
}

View File

@ -1,46 +1,34 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="user"/> <db-form id="client">
<vn-hash-param key="user" param="user"/> <db-model property="model" lot="hash">
<db-form id="user-form">
<db-model property="model">
<custom>
SELECT Id_Cliente, Cliente, Telefono, movil SELECT Id_Cliente, Cliente, Telefono, movil
FROM vn2008.Clientes WHERE Id_Cliente = #user FROM vn2008.Clientes WHERE Id_Cliente = #user
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
</db-model> </db-model>
</db-form> </db-form>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>AccessLog</t></h1> _AccessLog
</div> </h1>
<div id="form" class="access-log"> <div id="main" class="access-log">
<div class="box"> <div class="card form">
<div class="form">
<p> <p>
<htk-text form="user-form" column="Id_Cliente"/> {{client.Id_Cliente}}
</p> </p>
<p> <p>
<htk-text form="user-form" column="Cliente"/> {{client.Cliente}}
</p> </p>
<p> <p>
<htk-text form="user-form" column="Telefono"/> {{client.Telefono}}
</p> </p>
<p> <p>
<htk-text form="user-form" column="movil"/> {{client.movil}}
</p> </p>
</div> </div>
</div> <div class="card">
<div class="list box">
<div> <div>
<htk-repeater form-id="iter"> <htk-repeater>
<db-model property="model"> <db-model property="model" lot="hash">
<custom>
SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visitUser u FROM visitUser u
JOIN visitAccess c ON c.id = u.access JOIN visitAccess c ON c.id = u.access
@ -48,22 +36,14 @@
WHERE u.user = #user WHERE u.user = #user
ORDER BY u.stamp DESC ORDER BY u.stamp DESC
LIMIT 8 LIMIT 8
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
</db-model> </db-model>
<custom> <custom>
<div class="item"> <div class="list-row">
<p> <p>
<htk-text form="iter" column="stamp" format="_%a, %e %b %Y at %T"/> <htk-text lot="iter" name="stamp" format="_%a, %e %b %Y at %T"/>
</p> </p>
<p> <p>
<htk-text form="iter" column="platform"/> - {{platform}} - {{browser}} {{version}}
<htk-text form="iter" column="browser"/>
<htk-text form="iter" column="version"/>
</p> </p>
</div> </div>
</custom> </custom>

View File

@ -5,7 +5,7 @@ Hedera.Connections = new Class
,_timeoutId: null ,_timeoutId: null
,onModelStatusChange: function (model, status) ,onModelStatusChange: function (model)
{ {
if (!model.ready) if (!model.ready)
return; return;
@ -23,15 +23,7 @@ Hedera.Connections = new Class
,onRefreshClick: function () ,onRefreshClick: function ()
{ {
this.$('sessions').refresh (); this.$.sessions.refresh ();
}
,onAccessLogClick: function (button, form)
{
this.hash.set ({
'form': 'admin/access-log'
,'user': form.get ('userId')
});
} }
,onChangeUserClick: function (button, form) ,onChangeUserClick: function (button, form)
@ -40,9 +32,9 @@ Hedera.Connections = new Class
this._onUserSupplant.bind (this)); this._onUserSupplant.bind (this));
} }
,_onUserSupplant: function (userName) ,_onUserSupplant: function ()
{ {
this.hash.set ({'form': 'ecomerce/orders'}); this.hash.setAll ({form: 'ecomerce/orders'});
} }
,sessionsFunc: function () ,sessionsFunc: function ()

View File

@ -1,12 +1,4 @@
.connections
{
padding: 1em;
}
.connections .box
{
max-width: 25em;
margin: 0 auto;
}
.action-bar .connections-sum .action-bar .connections-sum
{ {
padding: .4em; padding: .4em;
@ -16,29 +8,3 @@
border-radius: 0.1em; border-radius: 0.1em;
box-shadow: 0 0 0.4em #666; box-shadow: 0 0 0.4em #666;
} }
/* List */
.connections .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.connections .item > button
{
float: right;
margin: 0;
}
.connections .item > p
{
margin: .1em 0;
}
.connections .item > p.important
{
font-size: 1.2em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

View File

@ -1,7 +1,7 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Connections</t></h1> _Connections
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="refresh" icon="refresh"
@ -14,14 +14,13 @@
model="sessions" model="sessions"
func="sessionsFunc"/> func="sessionsFunc"/>
</htk-text> </htk-text>
<t>connections</t> _connections
</div> </div>
</div> </div>
<div id="form" class="connections"> <div id="main" class="connections">
<div class="box"> <div class="card list">
<htk-repeater form-id="iter"> <htk-repeater>
<db-model property="model" id="sessions" on-status-changed="onModelStatusChange"> <db-model property="model" id="sessions" on-status-changed="onModelStatusChange">
<custom>
SELECT vu.user userId, vu.stamp, u.nickname, s.lastUpdate, SELECT vu.user userId, vu.stamp, u.nickname, s.lastUpdate,
a.platform, a.browser, a.version, u.name user a.platform, a.browser, a.version, u.name user
FROM userSession s FROM userSession s
@ -31,35 +30,30 @@
JOIN visit v ON v.id = a.visit JOIN visit v ON v.id = a.visit
JOIN account.user u ON u.id = vu.user JOIN account.user u ON u.id = vu.user
ORDER BY lastUpdate DESC ORDER BY lastUpdate DESC
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="item"> <a href="#!form=admin/access-log&amp;user={{userId}}"
class="list-row"
title="_Access log">
<div class="actions">
<htk-button <htk-button
form="iter" lot="iter"
column="id" name="id"
tip="_Supplant user" tip="_Supplant user"
icon="incognito" icon="incognito"
on-click="onChangeUserClick"/> on-click="onChangeUserClick"/>
<htk-button
form="iter"
column="id"
tip="_Access log"
icon="gnome"
on-click="onAccessLogClick"/>
<p class="important">
<htk-text form="iter" column="nickname"/>
</p>
<p>
<htk-text form="iter" column="stamp" format="%a, %T"/> -
<htk-text form="iter" column="lastUpdate" format="%T"/>
</p>
<p>
<htk-text form="iter" column="platform"/> -
<htk-text form="iter" column="browser"/>
<htk-text form="iter" column="version"/>
</p>
</div> </div>
<p class="important">
{{nickname}}
</p>
<p>
<htk-text lot="iter" name="stamp" format="%a, %T"/> -
<htk-text lot="iter" name="lastUpdate" format="%T"/>
</p>
<p>
{{platform}} - {{browser}} {{version}}
</p>
</a>
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>

View File

@ -1,21 +1,7 @@
.items
{
padding: 1em;
}
.items .box
{
max-width: 25em;
margin: 0 auto;
}
/* Row */ /* Row */
.items .row .items .list-row > .photo
{
padding: 1em;
border-bottom: 1px solid #DDD;
}
.items .row > .photo
{ {
margin-right: 1em; margin-right: 1em;
float: left; float: left;
@ -23,15 +9,11 @@
height: 3.2em; height: 3.2em;
width: 3.2em; width: 3.2em;
} }
.items .row > p .items .list-row > p
{ {
margin: .1em 0; margin: .1em 0;
margin-left: 5em; margin-left: 5em;
} }
.items .row > p.important
{
font-size: 1.2em;
}
/* Topbar */ /* Topbar */
@ -39,4 +21,3 @@
{ {
margin: .8em .6em; margin: .8em .6em;
} }

View File

@ -1,37 +1,25 @@
<vn> <vn>
<vn-group> <h1 id="title">
<vn-param id="filter"/> _Items
<vn-hash-param key="filter" param="filter"/> </h1>
</vn-group>
<div id="title">
<h1><t>Items</t></h1>
</div>
<div id="actions"> <div id="actions">
<htk-search-entry <htk-search-entry lot="hash" name="search"/>
param="filter"/>
</div> </div>
<div id="form" class="items"> <div id="main" class="items">
<div class="rows box"> <div class="card list">
<htk-repeater form-id="iter" empty-message="_Enter a search term"> <htk-repeater empty-message="_Enter a search term">
<db-model property="model"> <db-model property="model" lot="hash">
<custom>
SELECT Id_Article, Article, Medida, Categoria, Foto SELECT Id_Article, Article, Medida, Categoria, Foto
FROM vn2008.Articles FROM vn2008.Articles
WHERE Article LIKE CONCAT('%', #filter, '%') WHERE Article LIKE CONCAT('%', #search, '%')
OR Id_Article = #filter OR Id_Article = #search
ORDER BY Article LIMIT 50 ORDER BY Article LIMIT 50
</custom>
<sql-batch property="batch">
<custom>
<item name="filter" param="filter"/>
</custom>
</sql-batch>
</db-model> </db-model>
<custom> <custom>
<div class="row"> <div class="list-row">
<htk-image <htk-image
form="iter" lot="iter"
column="Foto" name="Foto"
class="photo" class="photo"
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
@ -39,15 +27,13 @@
editable="true" editable="true"
conn="conn"/> conn="conn"/>
<p class="concept"> <p class="concept">
<htk-text form="iter" column="Article"/> {{Article}} {{Medida}} {{Categoria}}
<htk-text form="iter" column="Medida"/>
<htk-text form="iter" column="Categoria"/>
</p> </p>
<p> <p>
<htk-text form="iter" column="Id_Article"/> @{{Id_Article}}
</p> </p>
<p> <p>
<htk-text form="iter" column="Foto"/> {{Foto}}
</p> </p>
<div class="clear"/> <div class="clear"/>
</div> </div>

View File

@ -2,10 +2,5 @@
Hedera.Links = new Class Hedera.Links = new Class
({ ({
Extends: Hedera.Form Extends: Hedera.Form
,repeaterFunc: function (res, form)
{
res.$('link').href = form.get ('link');
}
}); });

View File

@ -1,38 +1,13 @@
.cpanel .cpanel .list-row:hover
{
padding: 1em;
}
.cpanel .box
{
max-width: 30em;
}
/* Items */
.cpanel .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.cpanel .item:hover
{ {
background-color: rgba(1, 1, 1, 0.05); background-color: rgba(1, 1, 1, 0.05);
} }
.cpanel .item > .htk-image .cpanel .list-row > .htk-image
{ {
margin: 0; margin: 0;
margin-right: 1em; margin-right: 1em;
float: left; float: left;
max-height: 2.8em; height: 2.8em;
max-width: 2.8em; width: 2.8em;
}
.cpanel .item > p
{
margin: .1em 0;
}
.cpanel .item > p.important
{
font-size: 1.2em;
} }

View File

@ -1,28 +1,25 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>ControlPanel</t></h1> _ControlPanel
</div> </h1>
<div id="form" class="cpanel"> <div id="main" class="cpanel">
<div class="box"> <div class="card list">
<htk-repeater form-id="iter" renderer="repeaterFunc"> <htk-repeater>
<db-model property="model"> <db-model property="model">
<custom>
SELECT image, name, description, link FROM link SELECT image, name, description, link FROM link
ORDER BY name ORDER BY name
</custom>
</db-model> </db-model>
<custom> <custom>
<a id="link" class="item" target="_blank"> <a class="list-row" href="{{link}}" target="_blank">
<htk-image <htk-image
form="iter" value="{{image}}"
column="image"
directory="link" directory="link"
subdir="full"/> subdir="full"/>
<p class="important"> <p class="important">
<htk-text form="iter" column="name"/> {{name}}
</p> </p>
<p> <p>
<htk-text form="iter" column="description"/> {{description}}
</p> </p>
</a> </a>
</custom> </custom>

View File

@ -18,7 +18,7 @@ Hedera.Photos = new Class
,activate: function () ,activate: function ()
{ {
this.$('schema').value = 'catalog'; this.$.schema.value = 'catalog';
} }
,addFiles: function (files) ,addFiles: function (files)
@ -70,7 +70,7 @@ Hedera.Photos = new Class
this.filesData.push (fileData); this.filesData.push (fileData);
button.value = fileData; button.value = fileData;
this.$('file-list').appendChild (div); this.$.fileList.appendChild (div);
} }
,onUploadClick: function () ,onUploadClick: function ()
@ -112,7 +112,7 @@ Hedera.Photos = new Class
var formData = new FormData(); var formData = new FormData();
formData.append ('image', fileData.file); formData.append ('image', fileData.file);
formData.append ('name', fileData.name.value); formData.append ('name', fileData.name.value);
formData.append ('schema', this.$('schema').value); formData.append ('schema', this.$.schema.value);
formData.append ('srv', 'json:image/upload'); formData.append ('srv', 'json:image/upload');
this.conn.sendFormData (formData, this.conn.sendFormData (formData,
this.onFileUpload.bind (this, fileData)); this.onFileUpload.bind (this, fileData));
@ -163,7 +163,7 @@ Hedera.Photos = new Class
,onFileRemove: function (button) ,onFileRemove: function (button)
{ {
var fileData = button.value; var fileData = button.value;
this.$('file-list').removeChild (fileData.div); this.$.fileList.removeChild (fileData.div);
for (var i = 0; i < this.filesData.length; i++) for (var i = 0; i < this.filesData.length; i++)
if (this.filesData[i] === fileData) if (this.filesData[i] === fileData)
@ -176,27 +176,27 @@ Hedera.Photos = new Class
,onClearClick: function () ,onClearClick: function ()
{ {
this.filesData = []; this.filesData = [];
Vn.Node.removeChilds (this.$('file-list')); Vn.Node.removeChilds (this.$.fileList);
} }
,onDropzoneClick: function () ,onDropzoneClick: function ()
{ {
this.$('file').click (); this.$.file.click ();
} }
,onFileChange: function () ,onFileChange: function ()
{ {
this.addFiles (this.$('file').files); this.addFiles (this.$.file.files);
} }
,onDragEnter: function (event) ,onDragEnter: function ()
{ {
Vn.Node.addClass (this.$('dropzone'), 'dragover'); Vn.Node.addClass (this.$.dropzone, 'dragover');
} }
,onDragLeave: function (event) ,onDragLeave: function ()
{ {
Vn.Node.removeClass (this.$('dropzone'), 'dragover'); Vn.Node.removeClass (this.$.dropzone, 'dragover');
} }
,onDragOver: function (event) ,onDragOver: function (event)
@ -206,7 +206,7 @@ Hedera.Photos = new Class
,onDragEnd: function (event) ,onDragEnd: function (event)
{ {
Vn.Node.removeClass (this.$('dropzone'), 'dragover'); Vn.Node.removeClass (this.$.dropzone, 'dragover');
event.dataTransfer.clearData (); event.dataTransfer.clearData ();
} }

View File

@ -1,14 +1,4 @@
.photos
{
padding: 1em;
}
.photos .box
{
max-width: 25em;
padding: 2em;
}
/* Dropzone */ /* Dropzone */
.photos .dropzone .photos .dropzone

View File

@ -1,16 +1,14 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Images</t></h1> _Images
</div> </h1>
<div id="form" class="photos"> <div id="main" class="photos">
<div class="box"> <div class="card form">
<div class="form-group"> <div class="form-group">
<label><t>Collection</t></label> <label>_Collection</label>
<htk-combo id="schema"> <htk-combo id="schema">
<db-model property="model"> <db-model property="model">
<custom>
SELECT name, `desc` FROM imageCollection ORDER BY `desc` SELECT name, `desc` FROM imageCollection ORDER BY `desc`
</custom>
</db-model> </db-model>
</htk-combo> </htk-combo>
</div> </div>
@ -22,7 +20,7 @@
on-drop="onDrop" on-drop="onDrop"
on-dragend="onDragEnd" on-dragend="onDragEnd"
on-click="onDropzoneClick"> on-click="onDropzoneClick">
<t>Click or drop files here</t> _Click or drop files here
</div> </div>
<input <input
id="file" id="file"
@ -33,10 +31,10 @@
<div id="file-list" class="file-list"/> <div id="file-list" class="file-list"/>
<div class="footer"> <div class="footer">
<button class="thin" on-click="onClearClick"> <button class="thin" on-click="onClearClick">
<t>Clear all</t> _Clear all
</button> </button>
<button class="thin" on-click="onUploadClick"> <button class="thin" on-click="onUploadClick">
<t>Upload files</t> _Upload files
</button> </button>
</div> </div>
</div> </div>

View File

@ -5,14 +5,14 @@ Hedera.Queries = new Class
,activate: function () ,activate: function ()
{ {
this.$('result-index').value = 0; this.$.resultIndex.value = 0;
} }
,clean: function () ,clean: function ()
{ {
if (this._grid) if (this._grid)
{ {
this.$('grid-holder').removeChild (this._grid.node); this.$.gridHolder.removeChild (this._grid.node);
this._grid.unref (); this._grid.unref ();
this._grid = null; this._grid = null;
} }
@ -24,9 +24,9 @@ Hedera.Queries = new Class
var model = new Db.Model ({ var model = new Db.Model ({
conn: this.conn, conn: this.conn,
query: this.$('sql').value, query: this.$.sql.value,
resultIndex: this.$('result-index').value, resultIndex: this.$.resultIndex.value,
updatable: this.$('updatable').value updatable: this.$.updatable.value
}); });
model.on ('status-changed', this._onModelChange, this); model.on ('status-changed', this._onModelChange, this);
} }
@ -49,7 +49,7 @@ Hedera.Queries = new Class
Htk.Toast.showMessage (_('Query executed!')); Htk.Toast.showMessage (_('Query executed!'));
var gridHolder = this.$('grid-holder'); var gridHolder = this.$.gridHolder;
if (gridHolder.firstChild) if (gridHolder.firstChild)
gridHolder.removeChilds (gridHolder.firstChild); gridHolder.removeChilds (gridHolder.firstChild);
@ -86,7 +86,7 @@ Hedera.Queries = new Class
column.setProperties ({ column.setProperties ({
title: c.name, title: c.name,
editable: this.$('updatable').value, editable: this.$.updatable.value,
columnIndex: i columnIndex: i
}); });

View File

@ -1,16 +1,7 @@
.queries
{ .queries .card
padding: 1em;
}
.queries .box
{ {
max-width: 40em; max-width: 40em;
margin: 0 auto;
}
.queries .form
{
box-sizing: border-box;
padding: 2em;
} }
.queries textarea .queries textarea
{ {

View File

@ -1,7 +1,7 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Queries</t></h1> _Queries
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="ok" icon="ok"
@ -12,26 +12,26 @@
tip="_Clean" tip="_Clean"
on-click="_onCleanClick"/> on-click="_onCleanClick"/>
</div> </div>
<div id="form" class="queries"> <div id="main" class="queries">
<div class="box form"> <div class="card form">
<div class="form-group"> <div>
<label><t>SQL query</t></label> <label>_SQL query</label>
<textarea <textarea
id="sql" id="sql"
autocorrect="off" autocorrect="off"
autocapitalize="off" autocapitalize="off"
spellcheck="false"/> spellcheck="false"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Result index</t></label> <label>_Result index</label>
<htk-spin id="result-index"/> <htk-spin id="result-index"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Updatable</t></label> <label>_Updatable</label>
<htk-check id="updatable"/> <htk-check id="updatable"/>
</div> </div>
</div> </div>
<div class="box result"> <div class="card result">
<div id="grid-holder"/> <div id="grid-holder"/>
</div> </div>
</div> </div>

View File

@ -1,45 +1,14 @@
.users
.users ._disabled
{ {
padding: 1em;
}
.users .box
{
max-width: 30em;
margin: 0 auto;
}
.users-box
{
padding: 1em;
border-bottom: 1px solid #DDD;
}
.users-box > button
{
float: right;
margin: 0;
}
.users-box > p
{
margin: .2em 0;
}
.users-box > p.important
{
font-size: 1.2em;
}
.users-box > .disabled
{
float: right;
color: white; color: white;
background-color: #F66; background-color: #F66;
border-radius: .2em; border-radius: .2em;
padding: .2em; padding: .3em;
margin: .3em;
font-size: .8em; font-size: .8em;
} }
/* Topbar */
.action-bar .htk-search-entry .action-bar .htk-search-entry
{ {
margin: .8em .6em; margin: .8em;
} }

View File

@ -1,60 +1,44 @@
<vn> <vn>
<vn-group> <h1 id="title">
<vn-param id="user-name"/> _User management
<vn-hash-param key="user" param="user-name"/> </h1>
</vn-group>
<div id="title">
<h1><t>User management</t></h1>
</div>
<div id="actions"> <div id="actions">
<htk-search-entry <htk-search-entry lot="hash" name="user"/>
param="user-name"/>
</div> </div>
<div id="form" class="users"> <div id="main" class="users">
<div class="box"> <div class="card list">
<htk-repeater form-id="iter" renderer="rendererFunc"> <htk-repeater renderer="rendererFunc">
<db-model property="model"> <db-model property="model" lot="hash">
<custom>
SELECT u.id, u.name, u.nickname, u.active SELECT u.id, u.name, u.nickname, u.active
FROM account.user u FROM account.user u
WHERE u.name LIKE CONCAT('%', #user, '%') WHERE u.name LIKE CONCAT('%', #user, '%')
OR u.nickname LIKE CONCAT('%', #user, '%') OR u.nickname LIKE CONCAT('%', #user, '%')
OR u.id = #user OR u.id = #user
ORDER BY u.name LIMIT 200 ORDER BY u.name LIMIT 200
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user-name"/>
</custom>
</sql-batch>
</db-model> </db-model>
<custom> <custom>
<div class="users-box"> <a
<htk-button class="list-row"
form="iter" href="#!form=admin/access-log&amp;user={{id}}"
column="id" title="_AccessLog">
tip="_Access log" <div class="actions">
icon="gnome" <span id="disabled">
on-click="onAccessLogClick"/> _Disabled
</span>
<htk-button <htk-button
id="impersonate" id="impersonate"
form="iter" value="{{id}}"
column="id" tip="_AccessAsUser"
tip="_Impersonate user"
icon="incognito" icon="incognito"
on-click="onChangeUserClick"/> on-click="onChangeUserClick"/>
<span id="disabled" class="disabled"> </div>
<t>Disabled</t>
</span>
<p class="important"> <p class="important">
<htk-text form="iter" column="nickname"/> {{nickname}}
</p> </p>
<p> <p>
@<htk-text form="iter" column="id"/> - @{{id}} - {{name}}
<htk-text form="iter" column="name"/>
</p> </p>
<div class="clear"/> </a>
</div>
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>

View File

@ -3,32 +3,24 @@ Hedera.Users = new Class
({ ({
Extends: Hedera.Form Extends: Hedera.Form
,onAccessLogClick: function (button, form) ,rendererFunc: function (scope, lot)
{ {
this.hash.set ({ var isEnabled = lot.$.active;
'form': 'admin/access-log' scope.$.disabled.style.display = isEnabled ?
,'user': form.get ('id')
});
}
,rendererFunc: function (scope, form)
{
var isEnabled = form.get('active')
scope.$('disabled').style.display = isEnabled ?
'none' : 'block'; 'none' : 'block';
scope.$('impersonate').node.style.display = isEnabled ? scope.$.impersonate.node.style.display = isEnabled ?
'block' : 'none'; 'block' : 'none';
} }
,onChangeUserClick: function (button, form) ,onChangeUserClick: function (button)
{ {
this.gui.supplantUser (form.get ('name'), this.gui.supplantUser (button.value,
this.onUserSupplant.bind (this)); this.onUserSupplant.bind (this));
} }
,onUserSupplant: function () ,onUserSupplant: function ()
{ {
this.hash.set ({form: 'ecomerce/orders'}); this.hash.setAll ({form: 'ecomerce/orders'});
} }
}); });

View File

@ -1,46 +1,13 @@
.visits
.visits .card
{ {
padding: 1em; max-width: 28em;
}
.visits .box
{
max-width: 25em;
margin: 0 auto;
}
.visits .form
{
padding: 1.5em;
max-width: 20em;
}
.visits .summary
{
margin-top: 1em;
} }
.visits .summary p .visits .summary p
{ {
padding: 1.5em; margin: 0;
font-size: 1.4em; font-size: 1.4em;
text-align: right; text-align: right;
} }
/* List */
.visits .list
{
margin-top: 1em;
}
.visits .item
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.visits .item > p
{
margin: .1em 0;
}
.visits .item > p.important
{
font-size: 1.2em;
}

View File

@ -1,7 +1,11 @@
<vn> <vn>
<div id="title"> <vn-lot-query id="params">
<h1><t>Visits</t></h1> <vn-spec name="from" type="Date"/>
</div> <vn-spec name="to" type="Date"/>
</vn-lot-query>
<h1 id="title">
_Visits
</h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="refresh" icon="refresh"
@ -12,24 +16,18 @@
tip="_Connections" tip="_Connections"
on-click="onSessionsClick"/> on-click="onSessionsClick"/>
</div> </div>
<div id="form" class="visits"> <div id="main" class="visits">
<div class="box"> <div class="card form">
<div class="form"> <div>
<div class="form-group"> <label>_From</label>
<label><t>From</t></label> <htk-date-chooser lot="params" name="from"/>
<htk-date-chooser>
<vn-param property="param" id="from"/>
</htk-date-chooser>
</div> </div>
<div class="form-group"> <div>
<label><t>To</t></label> <label>_To</label>
<htk-date-chooser> <htk-date-chooser lot="params" name="to"/>
<vn-param property="param" id="to"/>
</htk-date-chooser>
</div> </div>
</div> </div>
</div> <div class="summary card form">
<div class="summary box">
<p> <p>
<htk-text> <htk-text>
<db-calc-sum <db-calc-sum
@ -37,20 +35,19 @@
model="visits" model="visits"
column-name="visits"/> column-name="visits"/>
</htk-text> </htk-text>
<t>visits</t>, <span>_visits</span>,
<htk-text> <htk-text>
<db-calc-sum <db-calc-sum
property="param" property="param"
model="visits" model="visits"
column-name="newVisits"/> column-name="newVisits"/>
</htk-text> </htk-text>
<t>news</t> <span>_news</span>
</p> </p>
</div> </div>
<div class="list box"> <div class="card list ">
<htk-repeater form-id="iter" empty-message="_Select date interval"> <htk-repeater empty-message="_Select date interval">
<db-model property="model" id="visits"> <db-model property="model" id="visits" lot="params">
<custom>
SELECT browser SELECT browser
,MIN(CAST(version AS DECIMAL(4,1))) minVersion ,MIN(CAST(version AS DECIMAL(4,1))) minVersion
,MAX(CAST(version AS DECIMAL(4,1))) maxVersion ,MAX(CAST(version AS DECIMAL(4,1))) maxVersion
@ -62,30 +59,19 @@
JOIN visitAgent a ON c.agent = a.id JOIN visitAgent a ON c.agent = a.id
JOIN visit v ON a.visit = v.id JOIN visit v ON a.visit = v.id
WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59') WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
GROUP BY browser ORDER BY visits DESC GROUP BY browser
</custom> ORDER BY visits DESC
<sql-batch property="batch">
<custom>
<item name="from" param="from"/>
<item name="to" param="to"/>
</custom>
</sql-batch>
</db-model> </db-model>
<custom> <custom>
<div class="item"> <div class="list-row">
<p class="important"> <p class="important">
<htk-text form="iter" column="browser"/> {{browser}} {{minVersion}} - {{maxVersion}}
<htk-text form="iter" column="minVersion"/> -
<htk-text form="iter" column="maxVersion"/>
</p> </p>
<p> <p>
<htk-text form="iter" column="visits"/> {{visits}} <span>_visits</span>, {{newVisits}} <span>_news</span>
<t>visits</t>,
<htk-text form="iter" column="newVisits"/>
<t>news</t>
</p> </p>
<p> <p>
<htk-text form="iter" column="lastVisit" format="_%a, %e %b %Y at %T"/> <htk-text lot="iter" name="lastVisit" format="_%a, %e %b %Y at %T"/>
</p> </p>
</div> </div>
</custom> </custom>

View File

@ -5,18 +5,21 @@ Hedera.Visits = new Class
,activate: function () ,activate: function ()
{ {
this.$('from').value = new Date (); if (!this.hash.$.to)
this.$('to').value = new Date (); this.hash.assign ({
from: new Date (),
to: new Date ()
});
} }
,onRefreshClick: function () ,onRefreshClick: function ()
{ {
this.$('visits').refresh (); this.$.visits.refresh ();
} }
,onSessionsClick: function () ,onSessionsClick: function ()
{ {
this.hash.set ({'form': 'admin/connections'}); this.hash.setAll ({form: 'admin/connections'});
} }
}); });

View File

@ -5,9 +5,9 @@ Hedera.Packages = new Class
,onShowClick: function (column, agencyId) ,onShowClick: function (column, agencyId)
{ {
this.hash.set ({ this.hash.setAll ({
'form': 'agencies/provinces', form: 'agencies/provinces',
'agency': agencyId agency: agencyId
}); });
} }
}); });

View File

@ -1,9 +1,4 @@
.packages .packages .card
{ {
padding: 1em; max-width: 35em;
}
.packages .box
{
max-width: 40em;
margin: 0 auto;
} }

View File

@ -1,14 +1,12 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>ListByAgency</t></h1> _ListByAgency
</div> </h1>
<div id="form" class="packages"> <div id="main" class="packages">
<div class="box"> <div class="card">
<htk-grid> <htk-grid>
<db-model property="model"> <db-model property="model">
<custom>
CALL vn2008.agencia_volume () CALL vn2008.agencia_volume ()
</custom>
</db-model> </db-model>
<htk-column-button <htk-column-button
column="agency_id" column="agency_id"

View File

@ -1,9 +1,4 @@
.provinces .provinces .card
{ {
padding: 1em; max-width: 35em;
}
.provinces .box
{
max-width: 40em;
margin: 0 auto;
} }

View File

@ -1,23 +1,12 @@
<vn> <vn>
<vn-group> <h1 id="title">
<vn-param id="agency"/> _ByProvince
<vn-hash-param key="agency" param="agency"/> </h1>
</vn-group> <div id="main" class="provinces">
<div id="title"> <div class="card">
<h1><t>ByProvince</t></h1>
</div>
<div id="form" class="provinces">
<div class="box">
<htk-grid> <htk-grid>
<db-model property="model"> <db-model property="model" lot="hash">
<custom>
CALL vn2008.desglose_volume (#agency) CALL vn2008.desglose_volume (#agency)
</custom>
<sql-batch property="batch">
<custom>
<item name="agency" param="agency"/>
</custom>
</sql-batch>
</db-model> </db-model>
<htk-column-text title="_Province" column="Provincia"/> <htk-column-text title="_Province" column="Provincia"/>
<htk-column-spin title="_Expeditions" column="expediciones"/> <htk-column-spin title="_Expeditions" column="expediciones"/>

View File

@ -8,7 +8,7 @@
max-width: 85em; max-width: 85em;
margin: 0 auto; margin: 0 auto;
} }
@media screen and (min-width: 1000px) /* and (max-width: 1399px) */ @media screen and (min-width: 1000px)
{ {
.about .cols .about .cols
{ {
@ -16,34 +16,31 @@
-moz-column-count: 2; -moz-column-count: 2;
-webkit-column-count: 2; -webkit-column-count: 2;
} }
}/*
@media screen and (min-width: 1400px)
{
.about .cols
{
column-count: 3;
-moz-column-count: 3;
-webkit-column-count: 3;
} }
}
@media screen and (min-width: 2000px) .about .card
{
.about .cols
{
column-count: 4;
-moz-column-count: 4;
-webkit-column-count: 4;
}
}*/
.about .box
{ {
margin: 0;
max-width: none;
margin-bottom: 1em; margin-bottom: 1em;
padding: 2em; padding: 2em;
} }
.about h1 .about .card > :first-child
{
margin-top: 0;
}
.about .card > :last-child
{
margin-bottom: 0;
}
.about h1,
.about h2,
.about h3
{ {
padding: 0; padding: 0;
margin: 0; }
.about h1
{
font-weight: normal; font-weight: normal;
font-size: 1.6em; font-size: 1.6em;
} }
@ -59,7 +56,7 @@
text-align: center; text-align: center;
font-size: 1.2em; font-size: 1.2em;
font-weight: normal; font-weight: normal;
padding: 1em; margin: 1em;
color: #00796B; color: #00796B;
} }
.about p .about p
@ -83,26 +80,27 @@
{ {
max-width: 90%; max-width: 90%;
text-align: center; text-align: center;
padding: 1em;
display: block; display: block;
margin: 0 auto; margin: 1em auto;
} }
.about img[alt="producers"], .about img[alt="producers"],
.about img[alt="4_control"], .about img[alt="4_control"],
.about img[alt="dealer"], .about img[alt="dealer"],
.about img[alt="goods_transport"] .about img[alt="goods_transport"]
{ {
margin: 1em;
float: right; float: right;
} }
.about img[alt="2_control"] .about img[alt="2_control"]
{ {
margin: 1em;
float: left; float: left;
} }
.about img[alt="glass"] .about img[alt="glass"]
{ {
display: inline; display: inline;
padding: 0; margin: 0;
padding-left: 0.9em; margin-left: .9em;
vertical-align: middle; vertical-align: middle;
} }

View File

@ -1,95 +1,95 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>About</t></h1> _About
</div>
<div id="form" class="about">
<div class="cols">
<div class="box">
<h1>
<t>QualityAndVariety</t>
</h1> </h1>
<p><t>MaximumFreshness</t></p> <div id="main" class="about">
<h3><t>SquareMeters</t></h3> <div class="cols">
<div class="card">
<h1>
_QualityAndVariety
</h1>
<p>_MaximumFreshness</p>
<h3>_SquareMeters</h3>
<img src="forms/cms/about/image/store.png" alt="store"/> <img src="forms/cms/about/image/store.png" alt="store"/>
<h3><t>AboutRealms</t></h3> <h3>_AboutRealms</h3>
<p><t>AboutLocation</t></p> <p>_AboutLocation</p>
<img src="forms/cms/about/image/trailer.png" alt="trailer"/> <img src="forms/cms/about/image/trailer.png" alt="trailer"/>
<p> <p>
<img src="forms/cms/about/image/dealer.png" alt="dealer"/> <img src="forms/cms/about/image/dealer.png" alt="dealer"/>
<t>PurchaseThroughWeb</t> _PurchaseThroughWeb
</p> </p>
<img src="forms/cms/about/image/palletizing.png" alt="palletizing"/> <img src="forms/cms/about/image/palletizing.png" alt="palletizing"/>
</div> </div>
<div class="box"> <div class="card">
<h1> <h1>
<t>WhatMakeUsDifferent</t> _WhatMakeUsDifferent
</h1> </h1>
<p><t>DesignVariety</t></p> <p>_DesignVariety</p>
<img src="forms/cms/about/image/differentiates_us.png" alt="differentiates_us"/> <img src="forms/cms/about/image/differentiates_us.png" alt="differentiates_us"/>
<p><t>AdaptToYourNeeds</t></p> <p>_AdaptToYourNeeds</p>
<h3><t>TheBestQuality</t></h3> <h3>_TheBestQuality</h3>
</div> </div>
<div class="box"> <div class="card">
<h1> <h1>
<t>AtYourService</t> _AtYourService
</h1> </h1>
<h2><t>BuyersAndTraders</t></h2> <h2>_BuyersAndTraders</h2>
<img src="forms/cms/about/image/commercial.png" alt="commercial"/> <img src="forms/cms/about/image/commercial.png" alt="commercial"/>
</div> </div>
<div class="box"> <div class="card">
<h1> <h1>
<t>Verdnatura training</t> _Verdnatura training
</h1> </h1>
<p><t>GoodTraining</t></p> <p>_GoodTraining</p>
<img src="forms/cms/about/image/training.png" alt="training"/> <img src="forms/cms/about/image/training.png" alt="training"/>
<p><t>SpecialTrainingPrices</t></p> <p>_SpecialTrainingPrices</p>
<img src="forms/cms/about/image/courses.png" alt="courses"/> <img src="forms/cms/about/image/courses.png" alt="courses"/>
<h2><t>YoutubeChannel</t></h2> <h2>_YoutubeChannel</h2>
<img src="forms/cms/about/image/youtube.png" alt="youtube"/> <img src="forms/cms/about/image/youtube.png" alt="youtube"/>
</div> </div>
<div class="box"> <div class="card">
<h1> <h1>
<t>HowWeWork</t> _HowWeWork
</h1> </h1>
<p><t>AalsmeerAuction</t></p> <p>_AalsmeerAuction</p>
<img src="forms/cms/about/image/auction.png" alt="auction"/> <img src="forms/cms/about/image/auction.png" alt="auction"/>
<p><t>BeforeAuction</t></p> <p>_BeforeAuction</p>
<img src="forms/cms/about/image/producers.png" alt="producers"/> <img src="forms/cms/about/image/producers.png" alt="producers"/>
<p><t>DirectlyFromProviders</t></p> <p>_DirectlyFromProviders</p>
<p><t>GoodsDischarge</t></p> <p>_GoodsDischarge</p>
<img src="forms/cms/about/image/goods_transport.png" alt="goods_transport"/> <img src="forms/cms/about/image/goods_transport.png" alt="goods_transport"/>
<h2> <h2>
<t>FirstQualityControl</t> _FirstQualityControl
<img src="forms/cms/about/image/glass.png" alt="glass"/> <img src="forms/cms/about/image/glass.png" alt="glass"/>
</h2> </h2>
<img src="forms/cms/about/image/goods_receive.png" alt="goods_receive"/> <img src="forms/cms/about/image/goods_receive.png" alt="goods_receive"/>
<p><t>GoodsTravel</t></p> <p>_GoodsTravel</p>
<img src="forms/cms/about/image/2_control.png" alt="2_control"/> <img src="forms/cms/about/image/2_control.png" alt="2_control"/>
<p><t>GoodsReception</t></p> <p>_GoodsReception</p>
<h2> <h2>
<t>SecondQualityControl</t> _SecondQualityControl
<img src="forms/cms/about/image/glass.png" alt="glass"/> <img src="forms/cms/about/image/glass.png" alt="glass"/>
</h2> </h2>
<p><t>CustomerOrders</t></p> <p>_CustomerOrders</p>
<img src="forms/cms/about/image/web.png" alt="web"/> <img src="forms/cms/about/image/web.png" alt="web"/>
<p><t>AfterOrder</t></p> <p>_AfterOrder</p>
<img src="forms/cms/about/image/4_control.png" alt="4_control"/> <img src="forms/cms/about/image/4_control.png" alt="4_control"/>
<h2> <h2>
<t>ThirdQualityControl</t> _ThirdQualityControl
<img src="forms/cms/about/image/glass.png" alt="glass"/> <img src="forms/cms/about/image/glass.png" alt="glass"/>
</h2> </h2>
<p><t>BuyerControl</t></p> <p>_BuyerControl</p>
<h2> <h2>
<t>FourthQualityControl</t> _FourthQualityControl
<img src="forms/cms/about/image/glass.png" alt="glass"/> <img src="forms/cms/about/image/glass.png" alt="glass"/>
</h2> </h2>
<p><t>EmbeddedSection</t></p> <p>_EmbeddedSection</p>
<img src="forms/cms/about/image/fit.png" alt="fit"/> <img src="forms/cms/about/image/fit.png" alt="fit"/>
<p><t>AfterEmbedAgency</t></p> <p>_AfterEmbedAgency</p>
<img src="forms/cms/about/image/agencies.png" alt="agencies"/> <img src="forms/cms/about/image/agencies.png" alt="agencies"/>
<p><t>FreshnessGuaranteed</t></p> <p>_FreshnessGuaranteed</p>
<p class="summary"> <p class="summary">
<t>AboutSummary</t> _AboutSummary
<img src="image/logo.svg" alt="Verdnatura"/> <img src="image/logo.svg" alt="Verdnatura"/>
</p> </p>
</div> </div>

View File

@ -6,7 +6,7 @@ Hedera.Contact = new Class
,activate: function () ,activate: function ()
{ {
var self = this; var self = this;
this.$('contact-form').onsubmit = function () this.$.contactForm.onsubmit = function ()
{ self._onSubmit (); return false; }; { self._onSubmit (); return false; };
this.refreshCaptcha (); this.refreshCaptcha ();
@ -15,21 +15,21 @@ Hedera.Contact = new Class
,refreshCaptcha: function () ,refreshCaptcha: function ()
{ {
params = { params = {
'srv': 'rest:core/captcha', srv: 'rest:core/captcha',
'stamp': new Date ().getTime () stamp: new Date ().getTime ()
}; };
this.$('captcha-img').src = '?'+ Vn.Url.makeUri (params); this.$.captchaImg.src = '?'+ Vn.Url.makeUri (params);
} }
,_onSubmit: function () ,_onSubmit: function ()
{ {
this.conn.sendForm (this.$('contact-form'), this.conn.sendForm (this.$.contactForm,
this._onResponse.bind (this)); this._onResponse.bind (this));
} }
,_onResponse: function (json, error) ,_onResponse: function (json)
{ {
var form = this.$('contact-form'); var form = this.$.contactForm;
if (json) if (json)
{ {

View File

@ -1,29 +1,8 @@
.contact
{
padding: 1em;
}
.contact .box
{
max-width: 30em;
padding: 2em;
}
.contact .form
{
position: relative;
text-align: left;
max-width: 25em;
margin: 0 auto;
}
.contact form
{
margin: 0 auto;
}
.contact form p .contact form p
{ {
margin: 1em auto; margin: 0;
display: block; margin-bottom: 1em;
margin-top: 2em;
} }
.contact textarea .contact textarea
{ {
@ -32,7 +11,8 @@
.contact button .contact button
{ {
display: block; display: block;
margin: 0 auto; margin-right: auto;
margin-left: auto;
margin-top: 1em; margin-top: 1em;
padding: 0.6em; padding: 0.6em;
} }

View File

@ -1,56 +1,54 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>IWantCustomer</t></h1> _IWantCustomer
</div> </h1>
<div id="form" class="contact"> <div id="main" class="contact">
<div class="box">
<div class="form">
<p>
<t>FillFormData</t>
</p>
<p>
<t>OrCallUs</t>
</p>
<form <form
id="contact-form"> id="contact-form">
<input type="hidden" name="srv" value="json:misc/contact"/> <input type="hidden" name="srv" value="json:misc/contact"/>
<div class="form-group"> <div class="card form">
<label><t>Name</t></label> <p>
_FillFormData
</p>
<p>
_OrCallUs
</p>
<div>
<label>_Name</label>
<input type="text" name="name"/> <input type="text" name="name"/>
</div> </div>
<div class="form-group"> <div>
<label><t>City</t></label> <label>_City</label>
<input type="text" name="city"/> <input type="text" name="city"/>
</div> </div>
<div class="form-group"> <div>
<label><t>PC</t></label> <label>_PC</label>
<input type="text" name="pc"/> <input type="text" name="pc"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Phone</t></label> <label>_Phone</label>
<input type="text" name="phone"/> <input type="text" name="phone"/>
</div> </div>
<div class="form-group"> <div>
<label><t>EMail</t></label> <label>_EMail</label>
<input type="text" name="email"/> <input type="text" name="email"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Message</t></label> <label>_Message</label>
<textarea name="message"/> <textarea name="message"/>
</div> </div>
<div class="form-group captcha"> <div class="form-group captcha">
<label><t>Anti-Spam</t></label> <label>_Anti-Spam</label>
<input type="text" name="captcha"/> <input type="text" name="captcha"/>
<img alt="Captcha" id="captcha-img"/> <img alt="Captcha" id="captcha-img"/>
</div> </div>
<p class="mandatory-message"> <p class="mandatory-message">
<t>AllFieldsMandatory</t> _AllFieldsMandatory
</p> </p>
<button class="thin"> <button class="thin">
<t>Send</t> _Send
</button> </button>
</div>
</form> </form>
</div> </div>
</div>
</div>
</vn> </vn>

View File

@ -1,3 +1,4 @@
(function () {
Hedera.Home = new Class Hedera.Home = new Class
({ ({
@ -5,7 +6,8 @@ Hedera.Home = new Class
,onStartOrderClick: function () ,onStartOrderClick: function ()
{ {
this.hash.set ({'form': 'ecomerce/catalog'}); this.hash.setAll ({form: 'ecomerce/catalog'});
} }
}); });
})();

View File

@ -6,14 +6,14 @@
margin: .5em; margin: .5em;
max-width: 120em; max-width: 120em;
} }
.action-bar button.start-order .catalog-actions ._start-order
{ {
background-color: #EF5350; background-color: #EF5350;
margin: .7em; margin: .7em;
padding: .5em; padding: .5em;
box-shadow: 0 0 0.4em rgba(1, 1, 1, 0.4); box-shadow: 0 0 0.4em rgba(1, 1, 1, 0.4);
} }
.action-bar button.start-order:hover .catalog-actions ._start-order:hover
{ {
background-color: #F44336; background-color: #F44336;
} }
@ -55,8 +55,7 @@
} }
.new-text a .new-text a
{ {
color: blue; color: #2962FF;
text-decoration: underline;
} }
.new-text li .new-text li
{ {

View File

@ -1,38 +1,35 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Home</t></h1> _Home
</div> </h1>
<div id="actions" class="catalog-actions"> <div id="actions" class="catalog-actions">
<htk-bar-button <htk-bar-button
class="start-order" id="start-order"
icon="new-order" icon="new-order"
tip="_Start order" tip="_Start order"
on-click="onStartOrderClick"/> on-click="onStartOrderClick"/>
</div> </div>
<div id="form" class="home"> <div id="main" class="home">
<div class="column mansonry" id="news-column"> <div class="column mansonry">
<htk-repeater form-id="new"> <htk-repeater>
<db-model property="model"> <db-model property="model">
<custom>
SELECT title, text, image, id FROM news SELECT title, text, image, id FROM news
WHERE tag != 'course' WHERE tag != 'course'
ORDER BY priority, created DESC ORDER BY priority, created DESC
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="masonry-box"> <div class="masonry-box">
<div class="new"> <div class="new">
<div class="top"> <div class="top">
<h2><htk-text form="new" column="title"/></h2> <h2>{{title}}</h2>
<div class="new-text"> <div class="new-text">
<htk-html form="new" column="text"/> <htk-html value="{{text}}"/>
</div> </div>
</div> </div>
<htk-image <htk-image
directory="news" directory="news"
subdir="full" subdir="full"
form="new" value="{{image}}"
column="image"
editable="false" editable="false"
full-dir="full"/> full-dir="full"/>
</div> </div>

View File

@ -0,0 +1,15 @@
<div>
<h3 class="marker">{{title}}</h3>
<p>
{{address}}
</p>
<p>
{{postcode}} {{city}}
</p>
<p>
{{province}}
</p>
<p>
{{phone}}
</p>
</div>

View File

@ -1,5 +1,8 @@
var infoTpl = require (__dirname +'/info.xml');
var gmapsIsLoaded = false; var gmapsIsLoaded = false;
var gmapsLoadedCallback;
Hedera.Location = new Class Hedera.Location = new Class
({ ({
@ -11,6 +14,9 @@ Hedera.Location = new Class
{ {
this.gui.loaderPush (); this.gui.loaderPush ();
this.infoBuilder = new Vn.Builder();
this.infoBuilder.compileString (infoTpl);
var sql = 'SELECT lat, lng, title, address, postcode, city, province, phone, language FROM location'; var sql = 'SELECT lat, lng, title, address, postcode, city, province, phone, language FROM location';
this.conn.execQuery (sql, this.onLocationsDone.bind (this)); this.conn.execQuery (sql, this.onLocationsDone.bind (this));
@ -26,7 +32,7 @@ Hedera.Location = new Class
,onLocationsDone: function (resultSet) ,onLocationsDone: function (resultSet)
{ {
this.locations = resultSet.fetchResult (); this.locations = resultSet.fetchArray ();
this.allLoaded (); this.allLoaded ();
} }
@ -48,42 +54,22 @@ Hedera.Location = new Class
,center: new google.maps.LatLng (46.0, 4.0) ,center: new google.maps.LatLng (46.0, 4.0)
}; };
var div = this.$('form'); var div = this.$.form;
var gmap = new google.maps.Map (div, options); var gmap = new google.maps.Map (div, options);
if (this.locations) locations.forEach (function (location) {
while (this.locations.next ()) this.createMarker (location, gmap);
this.createMarker (this.locations, gmap); }, this);
} }
,createMarker: function (location, gmap) ,createMarker: function (location, gmap)
{ {
var div = document.createElement ('div'); var scope = this.infoBuilder.load (this.doc, this, null, null, location);
div.className = 'marker'; var div = scope.getMain ();
var h = document.createElement ('h3');
h.appendChild (document.createTextNode (location.get ('title')));
div.appendChild (h);
var p = document.createElement ('p');
p.appendChild (document.createTextNode (location.get ('address')));
div.appendChild (p);
var p = document.createElement ('p');
p.appendChild (document.createTextNode (location.get ('postcode') +' '+ location.get ('city')));
div.appendChild (p);
var p = document.createElement ('p');
p.appendChild (document.createTextNode (location.get ('province')));
div.appendChild (p);
var p = document.createElement ('p');
p.appendChild (document.createTextNode (location.get ('phone')));
div.appendChild (p);
var lat = new google.maps.LatLng ( var lat = new google.maps.LatLng (
location.get ('lat'), location.lat,
location.get ('lng') location.lng
); );
var marker = new google.maps.Marker ({ var marker = new google.maps.Marker ({
@ -100,7 +86,7 @@ Hedera.Location = new Class
this.openInfoWindow.bind (this, infoWindow, gmap, marker)); this.openInfoWindow.bind (this, infoWindow, gmap, marker));
if (Vn.Locale.language if (Vn.Locale.language
&& Vn.Locale.language == location.get ('language')) && Vn.Locale.language == location.language)
this.openInfoWindow (infoWindow, gmap, marker); this.openInfoWindow (infoWindow, gmap, marker);
} }

View File

@ -1,6 +1,6 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Location</t></h1> _Location
</div> </h1>
<div id="form" class="location"/> <div id="main" class="location"/>
</vn> </vn>

View File

@ -1 +1,22 @@
{} {
"Configuration": "Configuration"
,"Select config": "Select config"
,"Reign": "Reign"
,"Family": "Family"
,"Store": "Store"
,"Date": "Date"
,"Shelf": "Shelf"
,"Name prefix": "Name prefix"
,"Limit amount per item": "Limit amount per item"
,"Title": "Title"
,"Show packing": "Show packing"
,"Stack different items": "Stack different items"
,"Use ids instead of names": "Use ids instead of names"
,"Show": "Show"
,"Pallets": "Pallets"
,"No items found, check that all fields are correct":
"No items found, check that all fields are correct"
}

View File

@ -44,8 +44,7 @@
} }
.new-text a .new-text a
{ {
color: blue; color: #2962FF;
text-decoration: underline;
} }
.new-text li .new-text li
{ {

View File

@ -1,34 +1,31 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>Training</t></h1> _Training
</div> </h1>
<div id="form" class="training"> <div id="main" class="training">
<div class="column mansonry" id="news-column"> <div class="column mansonry" id="news-column">
<htk-repeater form-id="new"> <htk-repeater form-id="new">
<db-model property="model"> <db-model property="model">
<custom>
SELECT title, created, text, image, id FROM news SELECT title, created, text, image, id FROM news
WHERE tag = 'course' WHERE tag = 'course'
ORDER BY priority, created DESC ORDER BY priority, created DESC
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="masonry-box"> <div class="masonry-box">
<div class="new"> <div class="new">
<div class="top"> <div class="top">
<h2><htk-text form="new" column="title"/></h2> <h2>{{title}}</h2>
<p class="new-info"> <p class="new-info">
<htk-text format="_%a, %e %b %Y" form="new" column="created"/> <htk-text format="_%a, %e %b %Y" lot="new" name="created"/>
</p> </p>
<div class="new-text"> <div class="new-text">
<htk-html form="new" column="text"/> <htk-html value="{{text}}"/>
</div> </div>
</div> </div>
<htk-image <htk-image
directory="news" directory="news"
subdir="full" subdir="full"
form="new" value="{{image}}"
column="image"
editable="false" editable="false"
full-dir="full"/> full-dir="full"/>
</div> </div>

View File

@ -1,24 +1,19 @@
.why .why .card
{ {
padding: 1em; max-width: 35em;
}
.why .box
{
max-width: 40em;
margin: 0 auto;
} }
.why ul .why ul
{ {
list-style-type: none; list-style-type: none;
padding: 0 1em; padding: 0;
padding-bottom: 1em;
max-width: 36em; max-width: 36em;
margin: 0 auto; margin: 0 auto;
} }
.why li .why li
{ {
padding: 0.5em 0; padding: 0;
margin-bottom: 1em;
} }
.why img .why img
{ {

View File

@ -1,19 +1,19 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>AboutCompany</t></h1> _AboutCompany
</div> </h1>
<div id="form" class="why"> <div id="main" class="why">
<div class="box"> <div class="card">
<div class="body"> <div class="body">
<ul> <ul>
<li><t>BecauseOurBigCatalog</t></li> <li>_BecauseOurBigCatalog</li>
<li><t>BecauseThisWeb</t></li> <li>_BecauseThisWeb</li>
<li><t>BecauseOurShoppingDep</t></li> <li>_BecauseOurShoppingDep</li>
<li><t>BecauseOrderIsEasy</t></li> <li>_BecauseOrderIsEasy</li>
<li><t>BecauseOurPlant</t></li> <li>_BecauseOurPlant</li>
<li><t>BecauseOurSalesDep</t></li> <li>_BecauseOurSalesDep</li>
<li><t>BecauseOurWorkShop</t></li> <li>_BecauseOurWorkShop</li>
<li><t>BecauseWeHaveWhatYouNeed</t></li> <li>_BecauseWeHaveWhatYouNeed</li>
</ul> </ul>
<img src="forms/cms/why/store.png" alt="Store photo"/> <img src="forms/cms/why/store.png" alt="Store photo"/>
</div> </div>

View File

@ -8,7 +8,7 @@ Hedera.Basket = new Class
this.close (); this.close ();
this.isOpen = true; this.isOpen = true;
Hedera.BasketChecker.check (this.conn, Hedera.BasketChecker.check (this.conn, this.hash,
this.onBasketCheck.bind (this)); this.onBasketCheck.bind (this));
} }
@ -20,39 +20,48 @@ Hedera.Basket = new Class
,activate: function () ,activate: function ()
{ {
this.$('items').setInfo ('i', 'basket_item', 'hedera'); this.$.items.setInfo ('i', 'basket_item', 'hedera');
} }
,onConfigureClick: function () ,onConfigureClick: function ()
{ {
Htk.Toast.showWarning (_('RememberReconfiguringImpact')); Htk.Toast.showWarning (_('RememberReconfiguringImpact'));
this.hash.set ({'form': 'ecomerce/checkout'}); this.hash.setAll ({form: 'ecomerce/checkout'});
} }
,onCatalogClick: function () ,onCatalogClick: function ()
{ {
this.hash.set ({'form': 'ecomerce/catalog'}); this.hash.setAll ({form: 'ecomerce/catalog'});
} }
,onCheckoutClick: function () ,onCheckoutClick: function ()
{ {
this.hash.set ({'form': 'ecomerce/confirm'}); this.hash.setAll ({form: 'ecomerce/confirm'});
} }
,repeaterFunc: function (res, form) ,repeaterFunc: function (scope, lot)
{ {
res.$('subtotal').value = this.subtotal (form); var $ = lot.$;
scope.$.subtotal.value = this.subtotal (lot);
if ($.available <= 0)
text = _('Not available');
else
text = $.available +' '+ _('availables');
Vn.Node.setText (scope.$.available, text);
Vn.Node.setVisible (scope.$.available, $.available < $.amount);
} }
,onDeleteClick: function (button, form) ,onDeleteClick: function (button)
{ {
if (confirm (_('ReallyDelete'))) if (confirm (_('ReallyDelete')))
form.deleteRow (); button.lot.deleteRow ();
} }
,subtotal: function (form) ,subtotal: function (lot)
{ {
return form.get ('amount') * form.get ('price'); return lot.$.amount * lot.$.price;
} }
}); });

View File

@ -1,13 +1,4 @@
.basket
{
padding: 1em;
}
.basket .box
{
max-width: 30em;
margin: 0 auto;
padding: 0 2em;
}
.basket .form > p .basket .form > p
{ {
margin: 0; margin: 0;
@ -17,9 +8,10 @@
} }
.basket .head .basket .head
{ {
padding: 1.8em 0; padding: 0;
margin: 0; padding-bottom: 2em;
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
margin-bottom: 1em;
} }
.basket .head p .basket .head p
{ {
@ -31,13 +23,9 @@
/* Lines */ /* Lines */
.basket .lines
{
padding: .8em 0;
}
.basket .line .basket .line
{ {
padding: 1em 0; padding: .5em 0;
} }
.basket .line > .delete .basket .line > .delete
{ {
@ -57,7 +45,7 @@
.basket .line > p .basket .line > p
{ {
margin: .1em 0; margin: .1em 0;
margin-left: 7.5em; margin-left: 6em;
} }
.basket .line .subtotal .basket .line .subtotal
{ {
@ -66,12 +54,12 @@
/* Fields */ /* Fields */
.basket td.available-exceeded input .basket ._available
{ {
background-color: #FCC; color: red;
visibility: hidden;
} }
.basket .icon > img .basket .icon > img
{ {
border-radius: 50%; border-radius: 50%;
} }

View File

@ -1,7 +1,7 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>ShoppingBasket</t></h1> _ShoppingBasket
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="ok" icon="ok"
@ -16,60 +16,55 @@
tip="_ConfigureOrder" tip="_ConfigureOrder"
on-click="onConfigureClick"/> on-click="onConfigureClick"/>
</div> </div>
<div id="form" class="basket"> <div id="main" class="basket">
<div class="box"> <div class="card form">
<div class="head"> <div class="head">
<p> <p>
<t>Total</t> _Total
<htk-text format="%.2d€"> <htk-text format="%.2d€">
<db-calc-sum property="param" func="subtotal" model="items"/> <db-calc-sum property="param" func="subtotal" model="items"/>
</htk-text> </htk-text>
</p> </p>
</div> </div>
<div class="lines"> <htk-repeater renderer="repeaterFunc">
<htk-repeater form-id="iter" renderer="repeaterFunc"> <db-model id="items" property="model" updatable="true" result-index="1">
<db-model id="items" property="model" updatable="true"> SET @a = -8;
<custom> SELECT r.id, r.amount, r.price, @a := @a + 4 available,
SELECT i.id, i.amount, i.price, a.Article, a.Categoria, i.name, i.size, i.category, i.image
a.Medida, a.Tallos, a.Color, o.Abreviatura, a.Foto FROM basket_item r
FROM basket_item i JOIN vn.item i ON i.id = r.item_id
JOIN vn2008.Articles a ON a.Id_Article = i.item_id
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="line"> <div class="line">
<htk-button <htk-button
form="iter" lot="iter"
column="ticket_id"
class="delete" class="delete"
tip="_Remove" tip="_Remove"
icon="delete" icon="delete"
on-click="onDeleteClick"/> on-click="onDeleteClick"/>
<htk-image <htk-image
form="iter" value="{{image}}"
column="Foto"
class="photo" class="photo"
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
full-dir="900x900"/> full-dir="900x900"/>
<p class="concept"> <p class="concept">
<htk-text form="iter" column="Article"/> {{name}} {{size}} {{category}}
<htk-text form="iter" column="Medida"/>
<htk-text form="iter" column="Categoria"/>
</p> </p>
<p class="amount"> <p class="amount">
<htk-text form="iter" column="amount"/> x <span id="row">{{amount}}</span> x
<htk-text form="iter" column="price" format="%.2d€"/> <htk-text lot="iter" name="price" format="%.2d€"/>
<span class="subtotal"> <span class="subtotal">
<htk-text id="subtotal" format="%.2d€"/> <htk-text id="subtotal" format="%.2d€"/>
</span> </span>
</p> </p>
<span id="available">
{{available}} <span>_availables</span>
</span>
<div class="clear"/> <div class="clear"/>
</div> </div>
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>
</div> </div>
</div>
</vn> </vn>

View File

@ -1,3 +1,25 @@
(function () {
var maxFilters = 5;
var View = {
LIST: 0,
GRID: 1
};
var orderBy = [
{way: 'DESC', id: 'relevancy', name: 'Relevancy'},
{way: 'ASC', id: 'name', name: 'Name'},
{way: 'ASC', id: 'price', name: 'Lower price'},
{way: 'DESC', id: 'price', name: 'Higher price'},
{way: 'ASC', id: 'available', name: 'Available'},
{way: 'ASC', id: 'size', name: 'Lower size'},
{way: 'DESC', id: 'size', name: 'Higher size'},
{way: 'ASC', id: 'color', name: 'Color'},
{way: 'ASC', id: 'producer', name: 'Producer'},
{way: 'ASC', id: 'origin', name: 'Origin'},
{way: 'ASC', id: 'category', name: 'Category'}
];
Hedera.Catalog = new Class Hedera.Catalog = new Class
({ ({
@ -12,7 +34,7 @@ Hedera.Catalog = new Class
if (!localStorage.getItem ('hederaGuest')) if (!localStorage.getItem ('hederaGuest'))
{ {
Hedera.BasketChecker.check (this.conn, Hedera.BasketChecker.check (this.conn, this.hash,
this.onBasketCheck.bind (this)); this.onBasketCheck.bind (this));
} }
else else
@ -30,183 +52,351 @@ Hedera.Catalog = new Class
,activate: function () ,activate: function ()
{ {
document.body.appendChild (this.$('right-panel')); this.$.items.setInfo ('i', 'item', 'vn', ['id']);
document.body.appendChild (this.$.rightPanel);
this.$('items-model').setInfo ('a', 'Articles', 'vn2008', ['item_id']);
if (localStorage.getItem ('hederaView')) if (localStorage.getItem ('hederaView'))
this.setView (parseInt (localStorage.getItem ('hederaView'))); this.setView (parseInt (localStorage.getItem ('hederaView')));
else else
this.setView (Hedera.Catalog.View.GRID); this.setView (View.GRID);
this.$.orderBy.model = new Vn.Model ({
data: orderBy
});
this.onCategoryChange ();
this.refreshTitle ();
this.onParamsChange ();
} }
,deactivate: function () ,deactivate: function ()
{ {
this.hideMenu (); this.hideMenu ();
this.gui.$('top-bar').style.backgroundColor = ''; this.gui.$.navbar.style.backgroundColor = '';
Vn.Node.remove (this.$('right-panel')); Vn.Node.remove (this.$.rightPanel);
} }
,setView: function (view) ,setView: function (view)
{ {
if (view === Hedera.Catalog.View.GRID) if (view === View.GRID)
{ {
this.$('view-button').setProperties ({ this.$.viewButton.setProperties ({
icon: 'view-list', icon: 'view-list',
tip: _('List view') tip: _('List view')
}); });
this.view = Hedera.Catalog.View.GRID;
var className = 'grid-view'; var className = 'grid-view';
} }
else else
{ {
this.$('view-button').setProperties ({ this.$.viewButton.setProperties ({
icon: 'view-grid', icon: 'view-grid',
tip: _('Grid view') tip: _('Grid view')
}); });
this.view = Hedera.Catalog.View.LIST;
var className = 'list-view'; var className = 'list-view';
} }
var node = this.$('grid-view').node; this.view = view;
var node = this.$.gridView.node;
node.className = className; node.className = className;
localStorage.setItem ('hederaView', this.view); localStorage.setItem ('hederaView', this.view);
} }
,onSwitchViewClick: function () ,onSwitchViewClick: function ()
{ {
this.setView (this.view === Hedera.Catalog.View.LIST ? this.setView (this.view === View.GRID ?
Hedera.Catalog.View.GRID : Hedera.Catalog.View.LIST); View.LIST : View.GRID);
} }
,onBasketReady: function (form) ,onBasketReady: function (form)
{ {
if (form.get ('method') != 'PICKUP') if (form.$.method != 'PICKUP')
Vn.Node.setText (this.$('method'), _('Agency')); Vn.Node.setText (this.$.method, _('Agency'));
else else
Vn.Node.setText (this.$('method'), _('Warehouse')); Vn.Node.setText (this.$.method, _('Store'));
} }
,onItemsChange: function (model, status) ,onOrderChange: function (combo)
{ {
if (status !== Db.Model.Status.CLEAN) var sortField = combo.$.id;
this.$('order').style.display = 'block'; var sortWay = combo.$.way === 'ASC' ?
else
this.$('order').style.display = 'none';
}
,onOrderChange: function (e)
{
var value = e.target.value;
var sortField = value.substr (2);
var sortWay = value.charAt (0) === 'A' ?
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC; Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField) if (sortField)
this.$('items-model').sortByName (sortField, sortWay); this.$.items.sort (sortField, sortWay);
this.hideMenu (); this.hideMenu ();
} }
,onFilterChange: function (param, newValue) ,onParamsChange: function ()
{ {
if (newValue) var params = this.params.$;
var shouldRefresh = params.search ||
params.category && params.type;
Vn.Node.removeChilds (this.$.suggestedFilters);
if (shouldRefresh)
{
this.$.items.query = this.buildQuery ('CALL catalogGetItems');
this.$.items.refresh ();
var nTags = maxFilters - this.nFilters;
if (nTags > 0)
{
var tagsQuery = this.buildQuery (
'CALL catalogGetTags (#nTags)', {nTags: nTags});
this.conn.execQuery (tagsQuery, this.onTagsReady.bind (this));
}
this.hideMenu (); this.hideMenu ();
} }
,realmRenderer: function (builder, form)
{
var link = builder.$('link');
link.href = this.hash.make ({
'form': this.hash.get ('form'),
'realm': form.get ('id')
});
var img = builder.$('image');
img.src = 'image/family/light/'+ form.get ('id') +'.svg';
img.title = form.get ('name');
img.alt = img.title;
}
,onRealmChange: function (param, newValue)
{
if (newValue)
{
this.$('filters').style.display = 'block';
this.$('realm-msg').style.display = 'none';
}
else else
{ this.$.items.clean ();
this.$('filters').style.display = 'none';
this.$('realm-msg').style.display = 'block'; this.showFilters (params.search || params.category);
} }
,showFilters: function (show)
{
this.$.filters.style.display = show ? 'block' : 'none';
this.$.categoryMsg.style.display = show ? 'none' : 'block';
}
,onRemoveFiltersClick: function ()
{
this.params.$ = {};
this.tagFilter = {};
}
,filters: {}
,nFilters: 0
,buildQuery: function (query, params, excludeTag)
{
var query = new Sql.MultiStmt ({
stmts: [
this.$.preQuery,
new Sql.String ({query: query}),
this.$.postQuery
]
});
var qParams = {
joins: this.buildTagFilter (excludeTag),
filter: this.buildMainFilter ()
};
Object.assign (qParams, params);
return this.conn.renderStmt (query, qParams)
}
,buildMainFilter: function ()
{
var filterSql = this.$.filter.render (this.params.$);
return new Sql.String ({query: filterSql});
}
,buildTagFilter: function (excludeTag)
{
var Type = Sql.Operation.Type;
var join = new Sql.Join ({
target: new Sql.Table ({
schema: 'vn',
name: 'item',
alias: 'i'
})
});
join.push (new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'itemType',
alias: 't'
}),
condition: new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: 't',
name: 'id'
}),
new Sql.Field ({
target: 'i',
name: 'typeFk'
})
]
})
}));
var i = -1;
for (var tagId in this.filters)
{
var tagId = parseInt (tagId);
var tagValue = this.filters[tagId].field.value;
if (tagId === excludeTag)
continue;
i++;
var tAlias = 'it'+ i;
var joinItem = new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'itemTag',
alias: tAlias
}),
condition: new Sql.Operation ({
type: Type.AND
})
});
join.push (joinItem);
joinItem.condition.exprs = [
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'itemFk'
}),
new Sql.Field ({
target: 'i',
name: 'id'
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'tagFk'
}),
new Sql.Value ({
value: tagId
})
]
}),
new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: tAlias,
name: 'value'
}),
new Sql.Value ({
value: tagValue
})
]
})
];
}
return join;
}
,onTagsReady: function (resultSet)
{
var tags = resultSet.results[2].data;
tags.forEach (function (tag) {
if (this.filters[tag.id] !== undefined)
return;
var query = this.buildQuery (
'CALL catalogGetTagValues (#tag)', {tag: tag.id}, tag.id);
var filter = this.createElement ('div');
this.$.suggestedFilters.appendChild (filter);
var label = this.createElement ('label');
label.appendChild (this.createTextNode (tag.name));
filter.appendChild (label);
var combo = new Htk.Combo ({
valueField: 'value',
showField: 'value'
});
filter.appendChild (combo.node);
var model = new Db.Model ({
autoLoad: false,
resultIndex: 2,
query: query,
conn: this.conn
});
combo.model = model;
var filterData = {
filter: filter,
tagId: tag.id,
field: combo,
model: model
};
combo.on ('changed',
this.onComboChange.bind (this, filterData), this);
}, this);
}
,onComboChange: function (filterData, _, value)
{
var filter = filterData.filter;
var tagId = filterData.tagId;
if (value == null)
{
this.$.currentFilters.removeChild (filter);
delete this.filters[tagId];
this.nFilters--;
}
else if (this.filters[tagId] === undefined)
{
this.nFilters++;
this.filters[tagId] = filterData;
this.$.suggestedFilters.removeChild (filter);
this.$.currentFilters.appendChild (filter);
}
for (var tid in this.filters)
if (parseInt (tid) !== tagId)
{
var query = this.buildQuery (
'CALL catalogGetTagValues (#tag)', {tag: tid}, tid);
this.filters[tid].model.query = query;
}
this.onParamsChange ();
}
,onCategoryChange: function ()
{
this.refreshTitleColor (); this.refreshTitleColor ();
this.refreshFilter (newValue, undefined);
}
,onTypeChange: function (param, newValue)
{
this.onFilterChange (param, newValue);
this.refreshTitle ();
this.refreshFilter (undefined, newValue);
}
,refreshFilter: function (realm, type)
{
var batch = this.$('filter-batch');
batch.block ();
this.$('realm-value').value = realm;
this.$('type-value').value = type;
this.$('search').value = undefined;
this.$('color').value = undefined;
this.$('origin').value = undefined;
this.$('category').value = undefined;
this.$('producer').value = undefined;
batch.unblock ();
batch.changed ();
} }
,refreshTitleColor: function () ,refreshTitleColor: function ()
{ {
var realms = this.$('realms-model'); var categories = this.$.categories;
var category = this.params.$.category;
if (!realms.ready)
return;
var color = null; var color = null;
var realm = this.$('realm').value;
if (realm) if (category)
{ {
var row = realms.search ('id', realm); var row = categories.search ('id', category);
if (row != -1) if (row != -1)
color = '#'+ realms.get (row, 'color'); color = '#'+ categories.get (row, 'color');
} }
this.gui.$('top-bar').style.backgroundColor = color; this.gui.$.navbar.style.backgroundColor = color;
} }
,refreshTitle: function () ,refreshTitle: function ()
{ {
var types = this.$('types-model'); var type = this.$.type.$.name;
var title = type ? type : _('Catalog');
if (!types.ready) Vn.Node.setText (this.$.title, title);
return;
var title = _('Catalog');
var type = this.$('type').value;
if (type)
{
var row = types.search ('tipo_id', type);
if (row != -1)
title = types.get (row, 'name');
}
Vn.Node.setText (this.$('title-text'), title);
} }
,onRightPanelClick: function (event) ,onRightPanelClick: function (event)
@ -219,7 +409,7 @@ Hedera.Catalog = new Class
this._menuShown = true; this._menuShown = true;
event.stopPropagation (); event.stopPropagation ();
this.gui.showBackground (); this.gui.showBackground ();
Vn.Node.addClass (this.$('right-panel'), 'show'); Vn.Node.addClass (this.$.rightPanel, 'show');
this.hideMenuCallback = this.hideMenu.bind (this); this.hideMenuCallback = this.hideMenu.bind (this);
document.addEventListener ('click', this.hideMenuCallback); document.addEventListener ('click', this.hideMenuCallback);
} }
@ -230,7 +420,7 @@ Hedera.Catalog = new Class
return; return;
this.gui.hideBackground (); this.gui.hideBackground ();
Vn.Node.removeClass (this.$('right-panel'), 'show'); Vn.Node.removeClass (this.$.rightPanel, 'show');
document.removeEventListener ('click', this.hideMenuCallback); document.removeEventListener ('click', this.hideMenuCallback);
this.hideMenuCallback = null; this.hideMenuCallback = null;
} }
@ -251,7 +441,7 @@ Hedera.Catalog = new Class
if (this.isGuest ()) if (this.isGuest ())
return; return;
this.hash.set ({'form': 'ecomerce/basket'}); this.hash.$ = {form: 'ecomerce/basket'};
} }
,onConfigureClick: function () ,onConfigureClick: function ()
@ -259,41 +449,38 @@ Hedera.Catalog = new Class
if (this.isGuest ()) if (this.isGuest ())
return; return;
this.hash.set ({'form': 'ecomerce/checkout'}); this.hash.$ = {form: 'ecomerce/checkout'};
} }
,onAddItemClick: function (button, form) ,onAddItemClick: function (button)
{ {
if (this.isGuest ()) if (this.isGuest ())
return; return;
this.onEraseClick (); this.onEraseClick ();
this.$('card').row = form.row; var lot = button.lot;
this.$('card-item').value = form.get ('item_id'); this.$.card.row = lot.row;
this.$('card-popup').show (button.node); this.$.cardLot.assign ({item: lot.$.id});
this.$.cardPopup.show ();
} }
,onAddLotClick: function (column, value, row, button) ,onAddLotClick: function (column, value, rowIndex)
{ {
var model = this.$('item-lots'); var row = this.$.itemLots.getObject (rowIndex);
var grouping = model.get (row, 'grouping'); var lotAmount = this.items[row.warehouse_id];
var warehouse = model.get (row, 'warehouse_id');
var available = model.get (row, 'available');
var lotAmount = this.items[warehouse];
if (lotAmount === undefined) if (lotAmount === undefined)
lotAmount = 0; lotAmount = 0;
if (lotAmount < available) if (lotAmount < row.available)
{ {
var newAmount = lotAmount + grouping; var newAmount = lotAmount + row.grouping;
if (newAmount > available) if (newAmount > row.available)
newAmount = available; newAmount = row.available;
this.items[warehouse] = newAmount; this.items[row.warehouse_id] = newAmount;
this.$('amount').value += newAmount - lotAmount; this.$.amount.value += newAmount - lotAmount;
} }
else else
Htk.Toast.showError (_('NoMoreAmountAvailable')); Htk.Toast.showError (_('NoMoreAmountAvailable'));
@ -302,8 +489,7 @@ Hedera.Catalog = new Class
,onConfirmClick: function () ,onConfirmClick: function ()
{ {
var sql = ''; var sql = '';
var batch = new Sql.Batch (); var query = 'CALL basketAddItem (#warehouse, #item, #amount);';
var query = new Sql.String ({query: 'CALL basketAddItem (#warehouse, #item, #amount);'});
var amountSum = 0; var amountSum = 0;
for (var warehouse in this.items) for (var warehouse in this.items)
@ -311,227 +497,38 @@ Hedera.Catalog = new Class
var amount = this.items[warehouse]; var amount = this.items[warehouse];
amountSum += amount; amountSum += amount;
batch.addValue ('warehouse', warehouse); var params = {
batch.addValue ('item', this.$('card-item').value); item: this.$.cardLot.$.item,
batch.addValue ('amount', amount); warehouse: parseInt (warehouse),
sql += query.render (batch); amount: amount
};
sql += this.conn.renderQuery (query, params);
} }
if (amountSum > 0) if (amountSum > 0)
{ {
this.conn.execQuery (sql); this.conn.execQuery (sql);
var itemName = this.$('card').get ('Article'); var itemName = this.$.card.$.name;
Htk.Toast.showMessage ( Htk.Toast.showMessage (
sprintf (_('Added%dOf%s'), amountSum, itemName)); Vn.Value.sprintf (_('Added%dOf%s'), amountSum, itemName));
} }
this.$('card-popup').hide (); this.$.cardPopup.hide ();
} }
,onEraseClick: function () ,onEraseClick: function ()
{ {
this.$('amount').value = 0; this.$.amount.value = 0;
this.items = {}; this.items = {};
} }
,onPopupClose: function () ,onPopupClose: function ()
{ {
this.onEraseClick (); this.onEraseClick ();
this.$('card').row = -1; this.$.card.row = -1;
this.$('card-item').value = undefined; this.$.cardLot.assign ({item: undefined});
}
,onStatusChange: function (model)
{
this.$('card-popup').reset ();
}
});
Hedera.Catalog.extend
({
View: {
LIST: 0,
GRID: 1
}
});
Vn.Filter = new Class
({
Extends: Htk.Field
,Tag: 'vn-filter'
,Child: 'model'
,Properties:
{
model:
{
type: Db.Model
,set: function (x)
{
x.batch = this._batch;
this._model = x;
this._select.model = x;
}
,get: function ()
{
return this._model;
}
},
placeholder:
{
type: String
,set: function (x)
{
this._select.placeholder = x;
this._placeholder = x;
}
,get: function ()
{
return this._placeholder;
}
},
filter:
{
type: Sql.Filter
,set: function (x)
{
this._filter = x;
this._batch.addObject ('filter', x);
}
,get: function ()
{
return this._filter;
}
},
}
,_valueColumnIndex: 0
,_showColumnIndex: 1
,initialize: function (props)
{
var node = this.createRoot ('div');
node.className = 'vn-filter';
this._select = new Htk.Select ();
this._select.on ('mousedown', this._onMouseDown, this);
this._select.on ('changed', this._onChange, this);
this._select.on ('ready', this._onReady, this);
this.node.appendChild (this._select.node);
this._ul = this.createElement ('ul');
this.node.appendChild (this._ul);
this._batch = new Sql.Batch ();
this.parent (props);
}
,_onMouseDown: function (e)
{
if (this._model && this._model.status === Db.Model.Status.CLEAN)
this._model.refresh ();
}
,_onCloseClick: function (li)
{
this._removeSelectionNode ();
this._changeValue (undefined);
}
,_removeSelectionNode: function ()
{
if (this._lastLi)
{
Vn.Node.remove (this._lastLi);
this._lastLi = null;
this._label = null;
}
}
,_onChange: function ()
{
if (this._select.value === null
|| this._select.value === undefined)
return;
this._realSetValue (this._select.value);
}
,_onReady: function ()
{
if (this._emptyLabel)
this._refreshLabel ();
}
,_changeValue: function (newValue)
{
this._batch.block ();
this.value = newValue;
this._batch.unblock ();
}
,_onTimeout: function ()
{
this._select.value = null;
}
,putValue: function (value)
{
this._onMouseDown ();
this._realSetValue (value);
}
,_realSetValue: function (value)
{
this._removeSelectionNode ();
if (value === null || value === undefined)
return;
var li = this._lastLi = this.createElement ('li');
this._ul.appendChild (li);
var button = this.createElement ('button');
button.addEventListener ('click',
this._onCloseClick.bind (this, li));
li.appendChild (button);
var icon = new Htk.Icon ({
icon: 'close',
alt: _('Close')
});
button.appendChild (icon.node);
var text = this._label = this.createTextNode ('');
li.appendChild (text);
setTimeout (this._onTimeout.bind (this));
this._changeValue (value);
this._refreshLabel ();
}
,_refreshLabel: function ()
{
if (!this._label)
return;
var row = -1;
if (this._model.ready)
row = this._model.searchByIndex (this._valueColumnIndex, this._value);
if (row != -1)
{
var label = this._model.getByIndex (row, this._showColumnIndex);
this._label.nodeValue = label;
this._emptyLabel = false;
}
else
{
this._emptyLabel = true;
this._label.nodeValue = _('Loading...');
}
} }
}); });
})();

View File

@ -52,89 +52,38 @@
{ {
padding: 1em 1.8em; padding: 1em 1.8em;
} }
.right-panel .filters, .right-panel .categories
.right-panel .order
{
display: none;
}
.right-panel .realm-msg
{
margin-top: 1em;
/* box-shadow: 0 0 .3em rgba(1, 1, 1, .5);
border-radius: 50%;
overflow: hidden;*/
}
.right-panel .realm-msg > h1
{
font-weight: normal;
text-align: center;
padding: 2.5em 0;
color: #777;
/* background-color: #009688;
color: white;*/
}
.right-panel h2
{
font-weight: normal;
padding: .4em 0;
color: #777;
font-size: 1.1em;
}
.right-panel .realms
{ {
width: 95%; width: 95%;
margin: .2em auto; margin: .2em auto;
} }
.right-panel .realms a .right-panel .categories a
{ {
display: block; display: block;
float: left; float: left;
width: 33.33%; width: 33.33%;
}
.right-panel .realms a:hover
{
background-color: rgba(1, 1, 1, .05);
border-radius: .1em; border-radius: .1em;
} }
.right-panel .realms a > img .right-panel .categories a > img
{ {
display: block; display: block;
padding: 0; padding: 0;
width: 100%; width: 100%;
} }
.right-panel .vn-filter, .right-panel .category-msg
.right-panel select
{ {
margin: 0 auto; margin-top: 1em;
margin-bottom: .7em;
width: 90%;
display: block;
} }
.vn-filter > ul .right-panel .category-msg > h1
{ {
margin: 0; font-weight: normal;
list-style-type: none;
text-align: left;
color: #666;
padding-left: .8em;
}
.vn-filter li
{
margin: 0;
margin-top: .3em;
line-height: 2em;
max-width: 90%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.vn-filter li > button
{
vertical-align: middle;
text-align: center; text-align: center;
padding: .2em; padding: 2.5em 0;
margin: 0; color: #777;
margin-right: .2em; }
.right-panel .filters
{
display: none;
} }
.right-panel .filters > button .right-panel .filters > button
{ {
@ -142,6 +91,13 @@
margin: 0 auto; margin: 0 auto;
margin-top: 1em; margin-top: 1em;
} }
.right-panel .filters label
{
font-size: .9em;
color: #666;
padding-top: .7em;
display: block;
}
/* Items */ /* Items */
@ -189,7 +145,6 @@
.item-info .producer .item-info .producer
{ {
text-transform: uppercase; text-transform: uppercase;
font-weight: bold;
padding: 0; padding: 0;
padding-bottom: .2em; padding-bottom: .2em;
font-size: 1em; font-size: 1em;
@ -211,11 +166,6 @@
/* Card */ /* Card */
.card-popup
{
overflow: auto;
}
.item-card .item-card
{ {
font-size: .9em; font-size: .9em;
@ -290,15 +240,15 @@
position: relative; position: relative;
width: 100%; width: 100%;
margin: 0; margin: 0;
height: 5.5em; height: 6.5em;
overflow: visible; overflow: visible;
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
} }
.list-view .item-box > .htk-image .list-view .item-box > .htk-image
{ {
margin: 1em; margin: 1em;
width: 3.5em; width: 4.5em;
height: 3.5em; height: 4.5em;
float: left; float: left;
overflow: hidden; overflow: hidden;
} }
@ -309,7 +259,7 @@
.list-view .item-info .list-view .item-info
{ {
position: absolute; position: absolute;
left: 5.5em; left: 6.5em;
right: 0; right: 0;
top: 0; top: 0;
bottom: 0; bottom: 0;

View File

@ -1,129 +1,71 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="card-item"/> <vn-lot-query id="params" on-change="onParamsChange">
<vn-param id="realm" on-changed="onRealmChange"/> <vn-spec name="search" type="String"/>
<vn-param id="type" on-changed="onTypeChange"/> <vn-spec name="itemId" type="Number"/>
<vn-param id="search" on-changed="onFilterChange"/> <vn-spec name="category" type="Number"/>
<vn-param id="color" on-changed="onFilterChange"/> <vn-spec name="type" type="Number"/>
<vn-param id="origin" on-changed="onFilterChange"/> </vn-lot-query>
<vn-param id="category" on-changed="onFilterChange"/>
<vn-param id="producer" on-changed="onFilterChange"/>
<vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/>
<sql-filter type="AND" id="filter"> <sql-filter type="AND" id="filter">
<sql-filter-item type="EQUAL" primary="false" id="op-realm"> <sql-filter-item type="EQUAL"
<sql-field name="reino_id" target="t"/> target="i" field="typeFk"
<sql-value id="realm-value"/> param="type"/>
</sql-filter-item> <sql-filter type="OR">
<sql-filter-item type="EQUAL" id="op-type"> <sql-filter-item type="LIKE"
<sql-field name="tipo_id" target="a"/> target="i" field="name"
<sql-value id="type-value"/> param="search"/>
</sql-filter-item> <sql-filter-item type="EQUAL"
<sql-filter-item type="LIKE" id="op-name"> target="i" field="id"
<sql-field name="Article"/> param="search"/>
<sql-search-tags param="search"/> <sql-filter-item type="EQUAL"
</sql-filter-item> target="i" field="id"
<sql-filter-item type="EQUAL" id="op-color"> param="itemId"/>
<sql-field name="Color"/>
<sql-value param="color"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-origin">
<sql-field name="id_origen"/>
<sql-value param="origin"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-category">
<sql-field name="Categoria"/>
<sql-value param="category"/>
</sql-filter-item>
<sql-filter-item type="EQUAL" id="op-producer">
<sql-field name="producer_id"/>
<sql-value param="producer"/>
</sql-filter-item>
</sql-filter> </sql-filter>
<db-form id="basket" on-ready="onBasketReady"> </sql-filter>
<db-model property="model"> <sql-string id="pre-query">
<custom> DROP TEMPORARY TABLE IF EXISTS tItems;
CREATE TEMPORARY TABLE tItems
(INDEX (id))
ENGINE = MEMORY
SELECT i.id
FROM #joins
WHERE #filter
</sql-string>
<sql-string id="post-query">
DROP TEMPORARY TABLE tItems
</sql-string>
<db-model
id="items"
result-index="2"
auto-load="false">
</db-model>
<db-lot id="basket" on-ready="onBasketReady">
SELECT o.id, o.date_send, ag.description agency, v.code method SELECT o.id, o.date_send, ag.description agency, v.code method
FROM basket o FROM basket o
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id JOIN vn.agencyMode ag ON ag.id = o.agency_id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
</custom> </db-lot>
</db-model> <db-lot id="card-extend" lot="card-lot">
</db-form> SELECT i.description
<db-query id="basket-lines"> FROM vn.item i WHERE i.id = #item
<custom> </db-lot>
SELECT item_id, warehouse_id, SUM(amount) amount
FROM basket_item
GROUP BY warehouse_id
</custom>
</db-query>
<db-model
id="items-model"
result-index="2"
on-status-changed="onItemsChange">
<custom>
CREATE TEMPORARY TABLE tmp.bionic_calc
(INDEX (item_id))
ENGINE=MEMORY
SELECT a.Id_Article item_id FROM vn2008.Articles a
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
WHERE #filter;
CALL bionic_calc ();
SELECT a.Id_Article item_id, a.description, b.available, b.price,
b.producer, a.Foto, a.Article, a.Categoria, a.Medida,
IF(a.Tallos > 1, a.Tallos, NULL) Tallos, c.name color
FROM tmp.bionic_item b
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 vn.inkL10n c ON c.id = a.Color
LEFT JOIN vn.originL10n o ON o.id = a.id_origen
WHERE b.available > 0
ORDER BY a.relevancy DESC, a.Article, a.Medida
LIMIT 400;
</custom>
<sql-batch property="batch" id="filter-batch">
<custom>
<item name="filter" object="filter"/>
</custom>
</sql-batch>
</db-model>
<db-form id="card" model="items-model"/>
<sql-batch id="card-batch">
<custom>
<item name="item" param="card-item"/>
</custom>
</sql-batch>
<db-form id="card-extend">
<db-model
property="model"
batch="card-batch"
on-status-changed-after="onStatusChange">
<custom>
SELECT a.description, o.name origin
FROM vn2008.Articles a
LEFT JOIN vn.originL10n o ON o.id = a.id_origen
WHERE a.Id_Article = #item
</custom>
</db-model>
</db-form>
<db-model <db-model
id="item-lots" id="item-lots"
result-index="1" result-index="1"
on-status-changed-after="onStatusChange" lot="card-lot">
batch="card-batch">
<custom>
CALL bionic_from_item (#item); CALL bionic_from_item (#item);
SELECT p.warehouse_id, w.name warehouse, p.grouping, p.price, p.rate, l.available SELECT p.warehouse_id, w.name warehouse, p.grouping, p.price, p.rate, l.available
FROM tmp.bionic_lot l FROM tmp.bionic_lot l
JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id
JOIN vn2008.warehouse w ON w.id = p.warehouse_id JOIN vn2008.warehouse w ON w.id = p.warehouse_id
ORDER BY warehouse_id, grouping; ORDER BY warehouse_id, grouping;
</custom>
</db-model> </db-model>
<vn-lot id="card-lot"/>
<vn-param lot="params" name="category" on-changed="onCategoryChange"/>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1 id="title-text"><t>Catalog</t></h1> _Catalog
</div> </h1>
<div id="actions" class="catalog-actions"> <div id="actions" class="catalog-actions">
<button class="menu" on-click="onShowMenuClick"> <button class="menu" on-click="onShowMenuClick">
<img src="image/icon/dark/menu.svg" alt="_Menu"/> <img src="image/icon/dark/menu.svg" alt="_Menu"/>
@ -137,52 +79,46 @@
tip="_Switch view" tip="_Switch view"
on-click="onSwitchViewClick"/> on-click="onSwitchViewClick"/>
<htk-search-entry <htk-search-entry
param="search"/> lot="params"
name="search"/>
</div> </div>
<div id="form" class="catalog"> <div id="main" class="catalog">
<div id="main" class="main">
<htk-repeater <htk-repeater
id="grid-view" id="grid-view"
empty-message="_Choose filter from right menu" empty-message="_Choose filter from right menu"
form-id="item" form-id="item"
model="items-model"> model="items">
<custom> <custom>
<div class="box item-box"> <div class="card item-box">
<htk-image <htk-image
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
form="item" value="{{image}}"
column="Foto"
full-dir="900x900"/> full-dir="900x900"/>
<div class="item-info"> <div class="item-info">
<htk-button <htk-button
form="item" lot="item"
column="id" value="{{id}}"
tip="_AddToBasket" tip="_AddToBasket"
icon="add" icon="add"
on-click="onAddItemClick" on-click="onAddItemClick"
class="add-button"/> class="add-button"/>
<h2> <h2>{{name}}</h2>
<htk-text form="item" column="Article"/>
</h2>
<p class="producer"> <p class="producer">
<htk-text form="item" column="producer"/> {{producer}}
</p> </p>
<p> <p>
<t>Size</t> <htk-text form="item" column="Medida"/>, {{tag1}} {{val1}}, {{tag2}} {{val2}}
<t>Category</t> <htk-text form="item" column="Categoria"/>
</p> </p>
<p class="color"> <p>
<t>Color</t> <htk-text form="item" column="color"/> {{tag3}} {{val3}}
<htk-text form="item" column="Tallos" format="_, %.0d Units"/> <htk-text lot="item" name="stems" format="_, %.0d Units"/>
</p> </p>
<div class="aval-price"> <div class="aval-price">
<htk-text form="item" column="available"/> {{available}}
<span class="from"> <span class="from">_from</span>
<t>from</t>
</span>
<span class="price"> <span class="price">
<htk-text form="item" column="price" format="%.2d€"/> <htk-text lot="item" name="price" format="%.2d€"/>
</span> </span>
</div> </div>
</div> </div>
@ -190,216 +126,84 @@
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>
</div>
<div id="right-panel" class="right-panel" on-click="onRightPanelClick"> <div id="right-panel" class="right-panel" on-click="onRightPanelClick">
<div class="basket-info"> <div class="basket-info">
<p> <p>
<htk-text form="basket" column="date_send" format="%D"/> <htk-text lot="basket" name="date_send" format="%D"/>
</p> </p>
<p> <p>
<span id="method"/> <span id="method"/>
<htk-text form="basket" column="agency"/> <htk-text lot="basket" name="agency"/>
</p> </p>
<button class="thin" on-click="onConfigureClick"> <button class="thin" on-click="onConfigureClick">
<t>Change</t> _Change
</button> </button>
</div> </div>
<div class="filter"> <div class="filter">
<div class="categories"> <div class="categories">
<div class="realms"> <div class="categories">
<htk-repeater <htk-repeater
model="realms-model" class="categories-box">
form-id="realm-form"
renderer="realmRenderer"
class="realms-box">
<db-model <db-model
id="realms-model" id="categories"
property="model" property="model"
on-status-changed="refreshTitleColor"> on-status-changed="refreshTitleColor">
<custom> SELECT c.id, l.name, c.color
SELECT r.id, l.name, r.color FROM vn.itemCategory c
FROM vn2008.reinos r JOIN vn.itemCategoryL10n l ON l.id = c.id
JOIN vn.itemCategoryL10n l ON l.id = r.id WHERE c.display > 0
WHERE r.display != FALSE ORDER BY l.name
ORDER BY name
</custom>
</db-model> </db-model>
<custom> <custom>
<a id="link"> <a class="clickable" href="#!form={{hash.form}}&amp;category={{id}}">
<img id="image"/> <img
src="image/family/light/{{id}}.svg"
title="{{name}}"
alt="{{name}}"/>
</a> </a>
</custom> </custom>
</htk-repeater> </htk-repeater>
<div class="clear"/> <div class="clear"/>
</div> </div>
</div> </div>
<div id="realm-msg" class="realm-msg"> <div id="category-msg" class="category-msg">
<h1><t>Choose a realm</t></h1> <h1>_Choose a category</h1>
</div> </div>
<div id="filters" class="filters"> <div id="filters" class="filters">
<h2><t>Filter by</t></h2> <div>
<vn-filter <label>_Order by</label>
placeholder="_Family" <htk-combo
param="type"> id="order-by"
on-change="onOrderChange"
value="relevancy"
not-null="true"/>
<label>_Family</label>
<htk-combo
id="type"
name="type"
on-change="refreshTitle"
lot="params">
<db-model <db-model
id="types-model" id="types"
property="model" property="model"
conn="conn" lot="params"
result-index="1" result-index="1">
on-status-changed="refreshTitle"> CALL itemGetAvailable;
<custom> SELECT DISTINCT t.id, l.name
CALL item_available (); FROM vn.itemType t
SELECT DISTINCT t.tipo_id, l.name JOIN vn.item i ON i.typeFk = t.id
FROM vn2008.Tipos t JOIN tmp.itemAvailable a ON a.id = i.id
JOIN vn2008.Articles a ON a.tipo_id = t.tipo_id JOIN vn.itemTypeL10n l ON l.id = t.id
JOIN tmp.item_available i ON i.item_id = a.Id_Article WHERE t.categoryFk = #category
JOIN vn.itemTypeL10n l ON l.id = t.tipo_id
WHERE #filter
ORDER BY name ORDER BY name
</custom>
</db-model> </db-model>
<sql-filter property="filter" type="AND"> </htk-combo>
<sql-filter-item type="EQUAL">
<sql-field name="reino_id" target="t"/>
<sql-value param="realm"/>
</sql-filter-item>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Color"
param="color">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT c.Id_Tinta, l.name
FROM vn2008.Tintas c
JOIN vn2008.Articles a ON a.Color = c.Id_Tinta
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN vn.inkL10n l ON l.id = c.Id_Tinta
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Producer"
param="producer">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT p.producer_id, p.name
FROM vn2008.producer p
JOIN vn2008.Articles a ON a.producer_id = p.producer_id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Origin"
param="origin">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT o.id, l.name, o.Abreviatura
FROM vn2008.Origen o
JOIN vn2008.Articles a ON a.id_origen = o.id
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN vn.originL10n l ON l.id = o.id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY name
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
<vn-filter
placeholder="_Category"
param="category">
<db-model property="model" auto-load="false" result-index="1">
<custom>
CALL item_available ();
SELECT DISTINCT a.Categoria, a.Categoria category
FROM vn2008.Articles a
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE #filter
ORDER BY a.Categoria
</custom>
</db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-origin"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter>
</div> </div>
<div id="order" class="order"> <div id="current-filters"/>
<h2><t>Order by</t></h2> <div id="suggested-filters"/>
<select on-change="onOrderChange"> <button on-click="onRemoveFiltersClick" class="thin">
<option value="D|relevancy" selected="true"> _Remove filters
<t>Relevancy</t> </button>
</option>
<option value="A|Article">
<t>Name</t>
</option>
<option value="A|price">
<t>Lower price</t>
</option>
<option value="D|price">
<t>Higher price</t>
</option>
<option value="A|available">
<t>Available</t>
</option>
<option value="A|Medida">
<t>Lower size</t>
</option>
<option value="D|Medida">
<t>Higher size</t>
</option>
<option value="A|color">
<t>Color</t>
</option>
<option value="A|producer">
<t>Producer</t>
</option>
<option value="A|Abreviatura">
<t>Origin</t>
</option>
<option value="A|Categoria">
<t>Category</t>
</option>
</select>
</div> </div>
</div> </div>
</div> </div>
@ -411,43 +215,49 @@
</htk-popup> </htk-popup>
<htk-popup <htk-popup
id="card-popup" id="card-popup"
class="card-popup"
modal="true" modal="true"
on-closed="onPopupClose"> on-closed="onPopupClose">
<db-form id="card" model="items"/>
<div property="child-node" class="item-card"> <div property="child-node" class="item-card">
<div class="top"> <div class="top">
<htk-image <htk-image
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
form="card" lot="card"
column="Foto" name="image"
full-dir="900x900" full-dir="900x900"
conn="conn" conn="conn"
editable="true"/> editable="true"/>
<div class="item-info"> <div class="item-info">
<h2> <h2>
<htk-text form="card" column="Article"/> {{card.name}}
</h2> </h2>
<p>
@{{card.id}}
</p>
<p class="producer"> <p class="producer">
<htk-text form="card" column="producer"/> {{card.producer}}
</p> </p>
<htk-repeater>
<db-lot property="model" lot="card-lot">
SELECT t.name, it.value
FROM vn.itemTag it
JOIN vn.tag t ON t.id = it.tagFk
WHERE it.id = #item
ORDER BY it.priority
</db-lot>
<custom>
<p> <p>
@<htk-text form="card" column="item_id"/> {{name}} {{value}}
</p> </p>
</custom>
</htk-repeater>
<p> <p>
<t>Size</t> <htk-text form="card" column="Medida"/>, <htk-text lot="card" name="Tallos" format="_, %.0d Units"/>
<t>Category</t> <htk-text form="card" column="Categoria"/>
</p>
<p class="color">
<t>Color</t> <htk-text form="card" column="color"/>
<htk-text form="card" column="Tallos" format="_, %.0d Units"/>
</p>
<p>
<t>Origin</t> <htk-text form="card-extend" column="origin"/>
</p> </p>
</div> </div>
<p class="desc"> <p class="desc">
<htk-text form="card-extend" column="description" id="desc"/> {{cardExtend.description}}
</p> </p>
</div> </div>
<htk-grid class="lots-grid" model="item-lots" show-header="false"> <htk-grid class="lots-grid" model="item-lots" show-header="false">

View File

@ -1,20 +1,43 @@
(function () {
var methodsData = {
AGENCY: {
steps: ['method', 'date', 'address', 'delivery', 'confirm'],
isDelivery: true,
textId: 'agencyText'
},
DELIVERY: {
steps: ['method', 'date', 'address', null, 'confirm'],
isDelivery: true,
textId: 'deliveryText'
},
PICKUP: {
steps: ['method', 'date', 'address', 'delivery', 'confirm'],
isDelivery: false,
textId: 'pickupText'
}
};
Hedera.Checkout = new Class Hedera.Checkout = new Class
({ ({
Extends: Hedera.Form Extends: Hedera.Form
,initialize: function (props)
{
this.today = new Date ();
this.today.setHours (0, 0, 0, 0);
this.parent (props);
}
,activate: function () ,activate: function ()
{ {
this.autoStepLocked = true; this.autoStepLocked = true;
this.today = new Date ();
this.today.setHours (0,0,0,0);
} }
,onValuesReady: function () ,onValuesReady: function ()
{ {
var orderForm = this.$('order-form'); var orderForm = this.$.orderForm;
var defaultsForm = this.$('defaults'); var defaultsForm = this.$.defaults;
if (!(orderForm.ready && defaultsForm.ready)) if (!(orderForm.ready && defaultsForm.ready))
return; return;
@ -24,7 +47,7 @@ Hedera.Checkout = new Class
if (orderForm.numRows > 0) if (orderForm.numRows > 0)
{ {
var i = orderForm; var i = orderForm;
date = i.get ('date_send'); date = i.$.date_send;
} }
else else
var i = defaultsForm; var i = defaultsForm;
@ -33,23 +56,24 @@ Hedera.Checkout = new Class
{ {
date = new Date (); date = new Date ();
if (i.get('delivery_method') != 'PICKUP') if (i.$.delivery_method != 'PICKUP')
date.setTime (date.getTime () + 86400000); date.setDate (date.getDate () + 1);
date.setHours (0, 0, 0, 0);
} }
this.$('date').value = date; this.$.lot.assign ({
this.$('method').value = i.get ('delivery_method'); date: date,
this.$('agency').value = i.get ('agency_id'); method: i.$.delivery_method,
this.$('address').value = i.get ('address_id'); agency: i.$.agency_id,
address: i.$.address_id
});
this.autoStepLocked = false; this.autoStepLocked = false;
} }
,disableButtons: function (disable) ,disableButtons: function (disable)
{ {
this.$('confirm-agency').disabled = disable; this.$.confirmButton.disabled = disable;
this.$('confirm-delivery').disabled = disable;
this.$('confirm-pickup').disabled = disable;
} }
,onConfirmClick: function () ,onConfirmClick: function ()
@ -57,15 +81,8 @@ Hedera.Checkout = new Class
this.disableButtons (true); this.disableButtons (true);
var query = 'CALL basketConfigure (#date, #method, #agency, #address)'; var query = 'CALL basketConfigure (#date, #method, #agency, #address)';
var batch = new Sql.Batch ();
batch.addParam ('method', this.$('method'));
batch.addParam ('date', this.$('date'));
batch.addParam ('agency', this.$('agency'));
batch.addParam ('address', this.$('address'));
this.conn.execQuery (query, this.conn.execQuery (query,
this.onBasketConfigured.bind (this), batch); this.onBasketConfigured.bind (this), this.$.lot.params);
} }
,onBasketConfigured: function (resultSet) ,onBasketConfigured: function (resultSet)
@ -75,20 +92,18 @@ Hedera.Checkout = new Class
if (!resultSet.fetchResult ()) if (!resultSet.fetchResult ())
return; return;
if (this.$('order-form').numRows > 0) var isUpdated = this.$.orderForm.numRows > 0;
Htk.Toast.showMessage (_('OrderUpdated')); Htk.Toast.showMessage (_(isUpdated ? 'OrderUpdated' : 'OrderStarted'));
else
Htk.Toast.showMessage (_('OrderStarted'));
this.hash.set ({form: 'ecomerce/catalog'}); this.hash.setAll ({form: 'ecomerce/catalog'});
} }
,onCancelClick: function () ,onCancelClick: function ()
{ {
if (this.$('order-form').numRows > 0) if (this.$.orderForm.numRows > 0)
window.history.back(); window.history.back();
else else
this.hash.set ({'form': 'ecomerce/orders'}); this.hash.setAll ({form: 'ecomerce/orders'});
} }
,agencySteps: ['method', 'date', 'address', 'agency', 'confirm-agency'] ,agencySteps: ['method', 'date', 'address', 'agency', 'confirm-agency']
@ -96,57 +111,56 @@ Hedera.Checkout = new Class
,stepFunc: function (stepIndex) ,stepFunc: function (stepIndex)
{ {
var isDelivery = this.$('rg-method').value == 'AGENCY'; var isDelivery = this.$.rgMethod.value == 'AGENCY';
var steps = isDelivery ? this.agencySteps : this.pickupSteps; var steps = isDelivery ? this.agencySteps : this.pickupSteps;
var stepId = steps[stepIndex]; var stepId = steps[stepIndex];
if (!stepId) if (!stepId)
return null; return null;
switch (stepId) switch (stepName)
{ {
case 'date': case 'date':
Vn.Node.setText (this.$('date-question'), isDelivery ? var dateQuestion = methodData.isDelivery ?
_('OrderDateDeliveryQuestion'): 'OrderDateDeliveryQuestion' : 'OrderDatePickupQuestion';
_('OrderDatePickupQuestion')); Vn.Node.setText (this.$.dateQuestion, _(dateQuestion));
this.$('calendar').goToSelectedMonth (); this.$.calendar.goToSelectedMonth ();
break; break;
case 'address': case 'address':
Vn.Node.setText (this.$('address-question'), isDelivery ? Vn.Node.setText (this.$.addressQuestion, isDelivery ?
_('AddressQuestion'): _('AddressQuestion'):
_('AddressQuestionPickup')); _('AddressQuestionPickup'));
break; break;
case 'agency': case 'agency':
this.$('agencies').refresh (); this.$.agencies.refresh ();
break; break;
case 'pickup': case 'confirm':
this.$('warehouses').refresh (); for (var myMethod in methodsData)
{
var display = myMethod == method ? 'block': 'none';
this.$[methodsData[myMethod].textId].style.display = display;
}
break; break;
} }
return this.$(stepId +'-step'); return stepName;
} }
,onFieldChange: function () ,onFieldChange: function (_, value)
{ {
if (!this.autoStepLocked) if (!this.autoStepLocked)
this.$('assistant').moveNext (); this.$.assistant.moveNext ();
}
,goNextStep: function ()
{
this.$('assistant').moveNext ();
} }
,addressRenderer: function (builder, form) ,addressRenderer: function (builder, form)
{ {
builder.$('address').addEventListener ('click', builder.$.address.addEventListener ('click',
this.onAddressClick.bind (this, form.get ('id'))); this.onAddressClick.bind (this, form.$.id));
} }
,onAddressClick: function (addressId) ,onAddressClick: function (addressId)
{ {
this.$('address').value = addressId; this.$.lot.set ('address', addressId);
this.goNextStep (); this.goNextStep ();
} }
@ -155,17 +169,17 @@ Hedera.Checkout = new Class
if (this.selectedNode) if (this.selectedNode)
Vn.Node.removeClass (this.selectedNode, 'selected'); Vn.Node.removeClass (this.selectedNode, 'selected');
var row = this.$('addresses').search ('id', this.$('address').value); var row = this.$.addresses.search ('id', this.$.lot.$.address);
if (row != -1) if (row != -1)
{ {
var builder = this.$('repeater').getBuilder (row); var builder = this.$.repeater.getScope (row);
this.selectedNode = builder.$('address'); this.selectedNode = builder.$.address;
Vn.Node.addClass (this.selectedNode, 'selected'); Vn.Node.addClass (this.selectedNode, 'selected');
} }
this.$('address-form').row = row; this.$.addressForm.row = row;
} }
,onAgenciesReady: function (model) ,onAgenciesReady: function (model)
@ -186,3 +200,4 @@ Hedera.Checkout = new Class
} }
}); });
})();

View File

@ -1,44 +1,44 @@
.checkout
{
padding: 1em;
max-width: 40em;
margin: 0 auto;
}
.checkout .form .checkout .form
{ {
max-width: 40em; max-width: 38em;
padding: 3em; padding: 2.5em;
}
.checkout .htk-assistant-bar
{
margin-top: 1.8em;
} }
/* Step */ /* Step */
.answers button, .answers
.answers p,
.radio > div
{ {
font-size: 1.4em; font-size: 1.3em;
} }
.answers .htk-select .answers .htk-combo
{ {
max-width: 8em; max-width: 10em;
display: block; display: block;
margin: 0 auto; margin: 0 auto;
font-size: 1.6em;
height: 1.8em;
} }
.answers p .answers p
{ {
margin: 0.3em 0; margin: .3em 0;
} }
.target .target
{ {
max-width: 28em; max-width: 18em;
margin: 0 auto; margin: 0 auto;
} }
.address .address
{ {
border-radius: 0.1em; border-radius: .1em;
padding: 0.6em 1.4em; padding: .8em;
}
.address p
{
margin: 0;
} }
.address.selected .address.selected
{ {
@ -52,10 +52,11 @@
.address p.consignee .address p.consignee
{ {
font-weight: bold; font-weight: bold;
margin-bottom: .2em;
} }
.radio .radio
{ {
max-width: 20em; max-width: 13em;
margin: 0 auto; margin: 0 auto;
} }
.radio > div .radio > div
@ -70,13 +71,10 @@
.thin-calendar .thin-calendar
{ {
width: inherit; width: inherit;
max-width: 24em; max-width: 22em;
margin: 0 auto; margin: 0 auto;
box-shadow: 0 0.1em 0.3em #ccc; box-shadow: 0 0.1em 0.3em #ccc;
} font-size: .7em;
.thin-calendar tr > th
{
color: white;
} }
.htk-assistant .thin .htk-assistant .thin
{ {

View File

@ -1,31 +1,24 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="method"/> <vn-lot id="lot" on-change="onAddressChange"/>
<vn-param id="date"/>
<vn-param id="agency"/>
<vn-param id="address" on-changed="onAddressChange"/>
<db-form id="defaults" on-ready="onValuesReady"> <db-form id="defaults" on-ready="onValuesReady">
<db-model property="model"> <db-model property="model">
<custom>
SELECT delivery_method, agency_id, address_id SELECT delivery_method, agency_id, address_id
FROM basket_defaults FROM basket_defaults
</custom>
</db-model> </db-model>
</db-form> </db-form>
<db-form id="order-form" on-ready="onValuesReady"> <db-form id="order-form" on-ready="onValuesReady">
<db-model property="model"> <db-model property="model">
<custom> SELECT d.code delivery_method, o.date_send, o.agency_id, o.address_id
SELECT v.code delivery_method, o.date_send, o.agency_id, o.address_id
FROM basket o FROM basket o
JOIN vn2008.Vistas v ON o.delivery_method_id = v.vista_id JOIN vn.deliveryMethod d ON d.id = o.delivery_method_id
</custom>
</db-model> </db-model>
</db-form> </db-form>
<db-model id="agencies" <db-model id="agencies"
auto-load="false" auto-load="false"
lot="lot"
result-index="1" result-index="1"
on-status-changed="onAgenciesReady"> on-status-changed="onAgenciesReady">
<custom>
CALL vn.agencyListAvailable (#date, #address); CALL vn.agencyListAvailable (#date, #address);
SELECT DISTINCT m.id, m.description SELECT DISTINCT m.id, m.description
FROM tmp.agencyAvailable a FROM tmp.agencyAvailable a
@ -36,19 +29,12 @@
WHERE d.code IN ('AGENCY', 'DELIVERY') WHERE d.code IN ('AGENCY', 'DELIVERY')
ORDER BY m.description; ORDER BY m.description;
DROP TEMPORARY TABLE tmp.agencyAvailable; DROP TEMPORARY TABLE tmp.agencyAvailable;
</custom>
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model> </db-model>
<db-model id="warehouses" <db-model id="warehouses"
auto-load="false" auto-load="false"
lot="lot"
result-index="1" result-index="1"
on-status-changed="onWarehousesReady"> on-status-changed="onWarehousesReady">
<custom>
CALL vn.agencyListAvailable (#date, #address); CALL vn.agencyListAvailable (#date, #address);
SELECT DISTINCT m.id, m.description SELECT DISTINCT m.id, m.description
FROM tmp.agencyAvailable a FROM tmp.agencyAvailable a
@ -59,24 +45,40 @@
WHERE d.code IN ('PICKUP') WHERE d.code IN ('PICKUP')
ORDER BY m.description; ORDER BY m.description;
DROP TEMPORARY TABLE tmp.agencyAvailable; DROP TEMPORARY TABLE tmp.agencyAvailable;
</custom>
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model> </db-model>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>ConfigureOrder</t></h1> _ConfigureOrder
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="close" icon="close"
tip="_Cancel" tip="_Cancel"
on-click="onCancelClick"/> on-click="onCancelClick"/>
</div> </div>
<<<<<<< HEAD
<div id="main" class="checkout">
<div class="card form">
<htk-assistant
id="assistant"
step-count="5"
step-func="stepFunc">
<htk-step name="method">
<h2>_DeliveryOrPickupQuestion</h2>
<div class="answers radio">
<htk-radio-group
id="rg-method"
lot="lot"
name="method"
on-changed="onFieldChange"/>
<div>
<htk-radio radio-group="rg-method" id="r-agency" value="AGENCY"/>
<label for="r-agency">_ReceiveThroughtAgency</label>
</div>
<div>
<htk-radio radio-group="rg-method" id="r-delivery" value="DELIVERY"/>
<label for="r-delivery">_ReceiveThroughtRoute</label>
=======
<div id="form" class="checkout"> <div id="form" class="checkout">
<div class="box"> <div class="box">
<div class="form"> <div class="form">
@ -143,28 +145,62 @@
</div> </div>
</custom> </custom>
</htk-repeater> </htk-repeater>
>>>>>>> master
</div>
<div>
<htk-radio radio-group="rg-method" id="r-pickup" value="PICKUP"/>
<label for="r-pickup">_PickupInStore</label>
</div> </div>
</div> </div>
<div id="agency-step"> </htk-step>
<h2><t>AgencyQuestion</t></h2> <htk-step name="date">
<h2 id="date-question"/>
<div class="answers">
<htk-calendar
id="calendar"
class="thin-calendar"
lot="lot"
name="date"
restrict-func="calendarRestrict"
on-pick="onFieldChange"/>
</div>
<<<<<<< HEAD
</htk-step>
<htk-step name="address">
<h2>_AddressQuestion</h2>
<div class="answers target">
<htk-repeater
id="repeater"
form-id="iter"
on-change="onAddressChange"
renderer="addressRenderer"
model="addresses">
<custom>
<div class="address" id="address">
<p class="consignee">
{{consignee}}
</p>
<p>
{{name}}
</p>
</div>
</custom>
</htk-repeater>
</div>
</htk-step>
<htk-step name="delivery">
<h2 id="wh-question"/>
<div class="answers target"> <div class="answers target">
<htk-combo <htk-combo
id="agency-combo" id="agency"
param="agency" lot="lot"
name="agency"
not-null="true"
placeholder="_Select agency"
show-field="description"
on-changed="onFieldChange" on-changed="onFieldChange"
model="agencies"/> model="agencies"/>
</div> =======
</div>
<div id="pickup-step">
<h2><t>PickupWarehouseQuestion</t></h2>
<div class="answers target">
<htk-combo
id="warehouse-combo"
param="agency"
on-changed="onFieldChange"
model="warehouses"/>
</div>
</div>
<div id="confirm-agency-step" class="confirm"> <div id="confirm-agency-step" class="confirm">
<h2><t>ConfirmToAccessCatalog</t></h2> <h2><t>ConfirmToAccessCatalog</t></h2>
<div class="answers target"> <div class="answers target">
@ -203,27 +239,35 @@
</button> </button>
<div class="clear"/> <div class="clear"/>
</div> </div>
>>>>>>> master
</div> </div>
<div id="confirm-pickup-step" class="confirm"> </htk-step>
<h2><t>ConfirmToAccessCatalog</t></h2> <htk-step name="confirm" class="confirm">
<h2>_ConfirmToAccessCatalog</h2>
<div class="answers target"> <div class="answers target">
<p> <p>
<t>Pickup</t> _Arrival <htk-text format="%D" lot="lot" name="date"/>
<htk-text format="%D" param="date"/>
</p> </p>
<p> <p>
<t>Warehouse</t> {{addressForm.name}}
<htk-text form="warehouse-combo" column="description"/>
</p> </p>
<button id="confirm-pickup" class="thin" on-click="onConfirmClick"> <p id="agency-text">
<t>Confirm</t> <span>_Agency</span> {{agency.description}}
</p>
<p id="delivery-text">
_ReceiveThroughtRoute
</p>
<p id="pickup-text">
<span>_Warehouse</span> {{agency.description}}
</p>
<button id="confirm-button" class="thin" on-click="onConfirmClick">
_Confirm
</button> </button>
<div class="clear"/> <div class="clear"/>
</div> </div>
</div> </htk-step>
</div> </htk-assistant>
<htk-assistant-bar assistant="assistant"/> <htk-assistant-bar assistant="assistant"/>
</div> </div>
</div> </div>
</div>
</vn> </vn>

View File

@ -8,7 +8,7 @@ Hedera.Confirm = new Class
this.close (); this.close ();
this.isOpen = true; this.isOpen = true;
Hedera.BasketChecker.check (this.conn, Hedera.BasketChecker.check (this.conn, this.hash,
this.onBasketCheck.bind (this)); this.onBasketCheck.bind (this));
} }
@ -23,50 +23,40 @@ Hedera.Confirm = new Class
if (form.row < 0) if (form.row < 0)
return; return;
if (form.get ('method') != 'PICKUP') var order = form.params;
{
Vn.Node.show (this.$('address'));
Vn.Node.setText (this.$('method'), _('Agency'));
}
else
{
Vn.Node.hide (this.$('address'));
Vn.Node.setText (this.$('method'), _('Warehouse'));
}
var total = form.get ('taxBase') + form.get ('tax'); var isPickup = order.method == 'PICKUP';
Vn.Node.display (this.$.address, !isPickup);
Vn.Node.setText (this.$.address, _(isPickup ? 'Warehouse' : 'Agency'));
var total = order.taxBase + order.tax;
if (total === null) if (total === null)
total = 0; total = 0;
var credit = form.get ('credit'); var totalDebt = order.debt + total;
var debt = form.get ('debt'); var exceededCredit = totalDebt - order.credit;
var totalDebt = debt + total;
var exceededCredit = totalDebt - credit;
var creditExceededCond = exceededCredit > 0; var creditExceededCond = exceededCredit > 0;
if (creditExceededCond) if (creditExceededCond)
Htk.Toast.showWarning ( Htk.Toast.showWarning (
_('You have exceeded your credit.')); _('You have exceeded your credit.'));
this.$('debt').value = debt; var lot = {
this.$('total-debt').value = totalDebt; totalDebt: totalDebt,
this.$('total-amount').value = totalDebt; exceededCredit: exceededCredit,
this.$('credit-excess').value = exceededCredit; payAmount: 'ALL'
this.$('excess-amount').value = exceededCredit; };
this.$('pay-amount').value = 'ALL'; if (order.credit > 0)
if (credit > 0)
{ {
this.$('credit-info').style.display = 'table-row'; this.$.creditInfo.style.display = 'table-row';
if (creditExceededCond) if (creditExceededCond)
{ {
this.$('amount-selector').style.display = 'block'; this.$.amountSelector.style.display = 'block';
this.$('exceeded-info').style.display = 'table-row'; this.$.exceededInfo.style.display = 'table-row';
this.$('pay-amount').value = 'EXCEEDED'; lot.payAmount = 'EXCEEDED';
} }
} }
@ -75,7 +65,7 @@ Hedera.Confirm = new Class
if (totalDebt <= 0) if (totalDebt <= 0)
{ {
methods = ['balance']; methods = ['balance'];
selectedMethod = 'BALANCE'; lot.payMethod = 'BALANCE';
} }
else else
{ {
@ -84,16 +74,16 @@ Hedera.Confirm = new Class
if (!creditExceededCond) if (!creditExceededCond)
{ {
methods.push ('credit'); methods.push ('credit');
selectedMethod = 'CREDIT'; lot.payMethod = 'CREDIT';
} }
else else
selectedMethod = 'CARD'; lot.payMethod = 'CARD';
} }
for (var i = 0; i < methods.length; i++) for (var i = 0; i < methods.length; i++)
this.$(methods[i] +'-method').style.display = 'block'; this.$[methods[i] +'Method'].style.display = 'block';
this.$('pay-method').value = selectedMethod; this.$.lot.assign (lot);
} }
,onPayMethodChange: function (payMethod) ,onPayMethodChange: function (payMethod)
@ -101,21 +91,21 @@ Hedera.Confirm = new Class
var id = this.displayedInfo; var id = this.displayedInfo;
if (id) if (id)
Vn.Node.removeClass (this.$(id), 'selected'); Vn.Node.removeClass (this.$[id], 'selected');
switch (payMethod.value) switch (payMethod.value)
{ {
case 'BALANCE': case 'BALANCE':
id = 'balance-method'; id = 'balanceMethod';
break; break;
case 'CREDIT': case 'CREDIT':
id = 'credit-method'; id = 'creditMethod';
break; break;
case 'CARD': case 'CARD':
id = 'card-method'; id = 'cardMethod';
break; break;
case 'TRANSFER': case 'TRANSFER':
id = 'transfer-method'; id = 'transferMethod';
break; break;
default: default:
id = null; id = null;
@ -124,13 +114,13 @@ Hedera.Confirm = new Class
this.displayedInfo = id; this.displayedInfo = id;
if (id) if (id)
Vn.Node.addClass (this.$(id), 'selected'); Vn.Node.addClass (this.$[id], 'selected');
} }
,disableButtons: function (disable) ,disableButtons: function (disable)
{ {
this.$('modify').disabled = disable; this.$.modify.disabled = disable;
this.$('confirm').disabled = disable; this.$.confirm.disabled = disable;
} }
,onModifyClick: function () ,onModifyClick: function ()
@ -141,7 +131,7 @@ Hedera.Confirm = new Class
,onConfirmClick: function () ,onConfirmClick: function ()
{ {
this.disableButtons (true); this.disableButtons (true);
this.$('confirm-query').execute (); this.$.confirmQuery.execute ();
} }
,onConfirm: function (query, resultSet) ,onConfirm: function (query, resultSet)
@ -149,23 +139,28 @@ Hedera.Confirm = new Class
this.disableButtons (false); this.disableButtons (false);
if (resultSet.fetchResult ()) if (resultSet.fetchResult ())
this.$('success-dialog').show (); this.$.successDialog.show ();
} }
,onDialogResponse: function () ,onDialogResponse: function ()
{ {
if (this.$('pay-method').value === 'CARD') var lot = this.$.lot.params;
{
if (this.$('pay-amount').value === 'EXCEEDED')
var payAmount = this.$('excess-amount').value;
else
var payAmount = this.$('total-amount').value;
var tpv = new Hedera.Tpv ({conn: this.conn}); if (this.$.payMethod.value === 'CARD')
tpv.pay (payAmount, this.$('order-form').get ('company_id')); {
if (this.$.payAmount.value === 'EXCEEDED')
var payAmount = lot.exceededCredit;
else
var payAmount = lot.totalDebt;
var tpv = new Hedera.Tpv ({
conn: this.conn,
hash: this.hash
});
tpv.pay (payAmount, this.$.order.get ('company'));
} }
else else
this.hash.set ({'form': 'ecomerce/orders'}); this.hash.params = {form: 'ecomerce/orders'};
} }
}); });

View File

@ -1,18 +1,7 @@
.confirm .confirm
{ {
padding: 1em;
max-width: 30em;
margin: 0 auto;
color: #555; color: #555;
} }
.confirm .box
{
padding: 2.2em 2.5em;
}
.confirm .summary
{
margin-bottom: 1em;
}
.confirm .address .confirm .address
{ {
margin-top: .8em; margin-top: .8em;
@ -122,4 +111,3 @@
{ {
margin: .1em 0; margin: .1em 0;
} }

View File

@ -1,8 +1,8 @@
<vn> <vn>
<vn-group> <vn-group>
<db-form id="order-form" on-ready="onOrderReady"> <vn-lot id="lot"/>
<db-form id="order" on-ready="onOrderReady">
<db-model property="model" result-index="1"> <db-model property="model" result-index="1">
<custom>
CALL basketGetTax; CALL basketGetTax;
SELECT o.id, o.date_send, o.note, o.company_id, SELECT o.id, o.date_send, o.note, o.company_id,
ag.description agency, v.code method, ag.description agency, v.code method,
@ -20,95 +20,90 @@
FROM tmp.orderTax FROM tmp.orderTax
) t; ) t;
DROP TEMPORARY TABLE tmp.orderTax; DROP TEMPORARY TABLE tmp.orderTax;
</custom>
</db-model> </db-model>
</db-form> </db-form>
<db-query id="confirm-query" on-ready="onConfirm"> <db-query id="confirm-query" on-ready="onConfirm">
<custom>
CALL basketConfirm CALL basketConfirm
</custom>
</db-query> </db-query>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>Order summary</t></h1> _Order summary
</div> </h1>
<div id="form" class="confirm"> <div id="main" class="confirm">
<div class="box summary"> <div class="summary form card">
<div> <div>
<div class="delivery"> <div class="delivery">
<p> <p>
<t>Delivery at</t> _Delivery at
<htk-text format="%D" form="order-form" column="date_send"/> <htk-text format="%D" lot="order" name="sendDate"/>
</p> </p>
<p> <p>
<span id="method"><t>Agency</t></span> <span id="method">_Agency</span> {{order.agency}}
<htk-text form="order-form" column="agency"/>
</p> </p>
</div> </div>
<div id="address" class="address"> <div id="address" class="address">
<p> <p>
<htk-text form="order-form" column="nickname"/> {{order.nickname}}
</p> </p>
<p> <p>
<htk-text form="order-form" column="street"/> {{order.street}}
</p> </p>
<p> <p>
<htk-text form="order-form" column="postalCode"/>, {{order.postalCode}}, {{order.city}}
<htk-text form="order-form" column="city"/>
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div class="box payment"> <div class="payment form card">
<div> <div>
<table class="debt-info"> <table class="debt-info">
<tbody> <tbody>
<tr> <tr>
<td> <td>
<t>Previous balance</t> _Previous balance
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" id="debt"/> <htk-text format="%.2d€" lot="order" name="debt"/>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<t>Order total</t> _Order total
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" form="order-form" column="taxBase"/> <htk-text format="%.2d€" lot="order" name="taxBase"/>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<t>Order VAT</t> _Order VAT
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" form="order-form" column="tax"/> <htk-text format="%.2d€" lot="order" name="tax"/>
</td> </td>
</tr> </tr>
<tr class="total-debt sum-total"> <tr class="total-debt sum-total">
<td> <td>
<t>Total debt</t> _Total debt
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" id="total-debt"/> <htk-text format="%.2d€" lot="lot" name="totalDebt"/>
</td> </td>
</tr> </tr>
<tr id="credit-info" class="credit-info"> <tr id="credit-info" class="credit-info">
<td> <td>
<t>Credit</t> _Credit
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" form="order-form" column="credit"/> <htk-text format="%.2d€" lot="order" name="credit"/>
</td> </td>
</tr> </tr>
<tr id="exceeded-info" class="exceeded-info sum-total"> <tr id="exceeded-info" class="exceeded-info sum-total">
<td> <td>
<t>Exceeded credit</t> _Exceeded credit
</td> </td>
<td class="currency"> <td class="currency">
<htk-text format="%.2d€" id="credit-excess"/> <htk-text format="%.2d€" lot="lot" name="exceededCredit"/>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -116,79 +111,79 @@
</div> </div>
<div id="amount-selector" class="amount-selector"> <div id="amount-selector" class="amount-selector">
<h2> <h2>
<t>Amount to pay</t> _Amount to pay
</h2> </h2>
<div class="radio"> <div class="radio">
<htk-radio-group <htk-radio-group
id="pay-amount"/> id="pay-amount"
lot="lot"
name="payAmount"/>
<div> <div>
<htk-radio radio-group="pay-amount" value="ALL"/> <htk-radio radio-group="pay-amount" value="ALL"/>
<label> <label>
<t>Total debt</t>, _Total debt,
<htk-text format="%.2d€" id="total-amount"/> <htk-text format="%.2d€" lot="lot" name="totalDebt"/>
</label> </label>
</div> </div>
<div> <div>
<htk-radio radio-group="pay-amount" value="EXCEEDED"/> <htk-radio radio-group="pay-amount" value="EXCEEDED"/>
<label> <label>
<t>Exceeded credit</t>, _Exceeded credit,
<htk-text format="%.2d€" id="excess-amount"/> <htk-text format="%.2d€" lot="lot" name="exceededCredit"/>
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div> <div>
<h2> <h2>
<t>Pay method</t> _Pay method
</h2> </h2>
<div class="pay-methods radio"> <div class="pay-methods radio">
<htk-radio-group <htk-radio-group
lot="lot"
id="pay-method" id="pay-method"
name="payMethod"
on-changed="onPayMethodChange"/> on-changed="onPayMethodChange"/>
<div id="balance-method"> <div id="balance-method">
<htk-radio radio-group="pay-method" value="BALANCE"/> <htk-radio id="r-balance" radio-group="pay-method" value="BALANCE"/>
<label><t>Use my balance</t></label> <label for="r-balance">_Use my balance</label>
<div class="pay-info"> <div class="pay-info">
<t>You have a favorable balance.</t> _You have a favorable balance.
</div> </div>
</div> </div>
<div id="credit-method"> <div id="credit-method">
<htk-radio radio-group="pay-method" value="CREDIT"/> <htk-radio id="r-credit" radio-group="pay-method" value="CREDIT"/>
<label><t>Use my credit</t></label> <label for="r-credit">_Use my credit</label>
<div class="pay-info"> <div class="pay-info">
<t>You have a favorable credit.</t> _You have a favorable credit.
</div> </div>
</div> </div>
<div id="card-method"> <div id="card-method">
<htk-radio radio-group="pay-method" value="CARD"/> <htk-radio id="r-card" radio-group="pay-method" value="CARD"/>
<label><t>Credit card</t></label> <label for="r-card">_Credit card</label>
<div class="pay-info"> <div class="pay-info">
<t>You will be redirected to the payment.</t> _You will be redirected to the payment.
</div> </div>
</div> </div>
<div id="transfer-method"> <div id="transfer-method">
<htk-radio radio-group="pay-method" value="TRANSFER"/> <htk-radio id="r-transfer" radio-group="pay-method" value="TRANSFER"/>
<label><t>Bank Transfer</t></label> <label for="r-transfer">_Bank Transfer</label>
<div class="pay-info"> <div class="pay-info">
<t>Make a transfer to one account.</t> _Make a transfer to one account.
<htk-repeater form-id="iter"> <htk-repeater>
<db-model property="model"> <db-model property="model">
<custom>
SELECT description, iban, entity_id, office, dc, number SELECT description, iban, entity_id, office, dc, number
FROM vn2008.account_customer c FROM vn2008.account_customer c
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="transfer-account"> <div class="transfer-account">
<p> <p>
<htk-text form="iter" column="description"/> {{description}}
</p> </p>
<p> <p>
<htk-text form="iter" column="iban"/> {{iban}}
<htk-text form="iter" column="entity_id"/> <htk-text lot="iter" name="entity_id" format="%.4d"/>
<htk-text form="iter" column="office"/> {{office}} {{dc}} {{number}}
<htk-text form="iter" column="dc"/>
<htk-text form="iter" column="number"/>
</p> </p>
</div> </div>
</custom> </custom>
@ -196,17 +191,17 @@
</div> </div>
</div> </div>
<div id="later-method"> <div id="later-method">
<htk-radio radio-group="pay-method" value="LATER"/> <htk-radio id="r-later" radio-group="pay-method" value="LATER"/>
<label><t>Pay later</t></label> <label for="r-later">_Pay later</label>
</div> </div>
</div> </div>
</div> </div>
<div class="button-bar"> <div class="button-bar">
<button on-click="onModifyClick" id="modify" class="thin modify-order"> <button on-click="onModifyClick" id="modify" class="thin modify-order">
<t>Modify</t> _Modify
</button> </button>
<button on-click="onConfirmClick" id="confirm" class="thin confirm-order"> <button on-click="onConfirmClick" id="confirm" class="thin confirm-order">
<t>Confirm</t> _Confirm
</button> </button>
<div class="clear"/> <div class="clear"/>
</div> </div>

View File

@ -3,15 +3,28 @@ Hedera.Invoices = new Class
({ ({
Extends: Hedera.Form Extends: Hedera.Form
,activate: function ()
{
var params = this.params;
if (!params.$.from)
{
var from = new Date ();
from.setDate (from.getDate () - 30);
from.setHours (0, 0, 0, 0);
params.assign ({from: from});
}
}
,onDownloadClick: function (column, invoiceId) ,onDownloadClick: function (column, invoiceId)
{ {
if (!invoiceId) if (!invoiceId)
return; return;
var params = { var params = {
'srv': 'rest:dms/invoice' srv: 'rest:dms/invoice'
,'invoice': invoiceId ,invoice: invoiceId
,'token': this.conn.token ,token: this.conn.token
}; };
var url = '?'+ Vn.Url.makeUri (params); var url = '?'+ Vn.Url.makeUri (params);

View File

@ -1,4 +1,5 @@
Invoices: Factures Invoices: Factures
Show invoices from: Mostra factures desde
Serial: Sèrie Serial: Sèrie
Date: Data Date: Data
Import: Import Import: Import

View File

@ -1,4 +1,5 @@
Invoices: Invoices Invoices: Invoices
Show invoices from: Show invoices from
Serial: Serial Serial: Serial
Date: Date Date: Date
Import: Import Import: Import

View File

@ -1,4 +1,5 @@
Invoices: Facturas Invoices: Facturas
Show invoices from: Mostrar facturas desde
Serial: Serie Serial: Serie
Date: Fecha Date: Fecha
Import: Importe Import: Importe

View File

@ -1,4 +1,5 @@
Invoices: Factures Invoices: Factures
Show invoices from: Afficher les factures de
Serial: Série Serial: Série
Date: Date Date: Date
Import: Montant Import: Montant

View File

@ -1,4 +1,5 @@
Invoices: Factura Invoices: Factura
Show invoices from: Mostrar facturas de
Serial: Serie Serial: Serie
Date: Data Date: Data
Import: Importe Import: Importe

View File

@ -1,10 +1,7 @@
.invoices
.invoices .card
{ {
padding: 1em; max-width: 32em;
}
.invoices .box
{
max-width: 40em;
} }
.invoices .box > .header, .invoices .box > .header,
.invoices .htk-grid > thead > tr .invoices .htk-grid > thead > tr

View File

@ -1,18 +1,24 @@
<vn> <vn>
<div id="title"> <vn-lot-query id="params">
<h1><t>Invoices</t></h1> <vn-spec name="from" type="Date"/>
</div> </vn-lot-query>
<div id="form" class="invoices"> <h1 id="title">
<div class="box"> _Invoices
</h1>
<div id="main" class="invoices">
<div class="card form">
<div> <div>
<label>_Show invoices from</label>
<htk-date-chooser lot="params" name="from"/>
</div>
</div>
<div class="card">
<htk-grid show-header="false"> <htk-grid show-header="false">
<db-model property="model" id="tickets"> <db-model property="model" lot="params">
<custom>
SELECT invoice_id, serial_num, issued, amount SELECT invoice_id, serial_num, issued, amount
FROM invoice_view FROM invoice_view
WHERE issued >= #from
ORDER BY issued DESC ORDER BY issued DESC
LIMIT 100
</custom>
</db-model> </db-model>
<htk-column-text title="_Serial" column="serial_num"/> <htk-column-text title="_Serial" column="serial_num"/>
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/> <htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
@ -25,5 +31,4 @@
</htk-grid> </htk-grid>
</div> </div>
</div> </div>
</div>
</vn> </vn>

View File

@ -6,6 +6,7 @@ DateMake: Data de creació
DateExit: Data d'eixida DateExit: Data d'eixida
SendMethod: Forma d'enviament SendMethod: Forma d'enviament
LastOrders: Últimes comandes LastOrders: Últimes comandes
Show orders from: Mostra comandes desde
'Balance:': 'Saldo:' 'Balance:': 'Saldo:'
PaymentInfo: >- PaymentInfo: >-
La quantitat mostrada és el teu saldo pendent (negatiu) o favorable a dia La quantitat mostrada és el teu saldo pendent (negatiu) o favorable a dia
@ -27,10 +28,6 @@ Consignee: Consignatari
Boxes: Caixes Boxes: Caixes
TotalWithVAT: Total amb IVA TotalWithVAT: Total amb IVA
PayOrder: Pagar encàrrec PayOrder: Pagar encàrrec
'AmountToPay:': 'Quantitat a pagar (€):'
AmountError: >-
La quantitat ha de ser un nombre positiu i inferior o igual a l'import pendent
PayError: Error al realitzar el pagament
An error has been in the payment: Sembla que hi ha hagut un error en el pagament An error has been in the payment: Sembla que hi ha hagut un error en el pagament
Retry: Reintenta Retry: Reintenta
Accept: Acceptar Accept: Acceptar

View File

@ -6,6 +6,7 @@ DateMake: Creation date
DateExit: Shipping date DateExit: Shipping date
SendMethod: Delivery method SendMethod: Delivery method
LastOrders: Last orders LastOrders: Last orders
Show orders from: Show orders from
'Balance:': 'Balance:' 'Balance:': 'Balance:'
PaymentInfo: >- PaymentInfo: >-
The amount shown is your slope (negative) or favorable balance today, it The amount shown is your slope (negative) or favorable balance today, it
@ -26,12 +27,6 @@ Consignee: Consignee
Boxes: Bundles Boxes: Bundles
TotalWithVAT: Total with VAT TotalWithVAT: Total with VAT
PayOrder: Pay order PayOrder: Pay order
'AmountToPay:': 'Amount to pay (€):' An error has been in the payment: It seems that there has been an error in the payment
AmountError: >-
The amount must be a positive number less than or equal to the outstanding
amount
PayError: Failed to make the payment
An error has been in the payment: >-
It seems that there has been an error in the payment
Retry: Retry Retry: Retry
Accept: Accept Accept: Accept

View File

@ -6,6 +6,7 @@ DateMake: Fecha de creación
DateExit: Fecha de salida DateExit: Fecha de salida
SendMethod: Forma de envío SendMethod: Forma de envío
LastOrders: Últimos pedidos LastOrders: Últimos pedidos
Show orders from: Mostrar pedidos desde
'Balance:': 'Saldo:' 'Balance:': 'Saldo:'
PaymentInfo: >- PaymentInfo: >-
La cantidad mostrada es tu saldo pendiente (negativa) o favorable a día de La cantidad mostrada es tu saldo pendiente (negativa) o favorable a día de
@ -27,11 +28,6 @@ Consignee: Consignatario
Boxes: Bultos Boxes: Bultos
TotalWithVAT: Total con IVA TotalWithVAT: Total con IVA
PayOrder: Pagar pedido PayOrder: Pagar pedido
'AmountToPay:': 'Cantidad a pagar (€):'
AmountError: >-
La cantidad debe ser un número positivo e inferior o igual al importe
pendiente
PayError: Error al realizar el pago
An error has been in the payment: Parece que ha habido un error en el pago An error has been in the payment: Parece que ha habido un error en el pago
Retry: Reintentar Retry: Reintentar
Accept: Aceptar Accept: Aceptar

View File

@ -6,6 +6,7 @@ DateMake: Date de creation
DateExit: Date de sortie DateExit: Date de sortie
SendMethod: Typo SendMethod: Typo
LastOrders: Les dernières commandes LastOrders: Les dernières commandes
Show orders from: Afficher les commandes de
'Balance:': 'Balance:' 'Balance:': 'Balance:'
PaymentInfo: >- PaymentInfo: >-
Le montant indiqué est votre pente (négative) ou balance favorable Le montant indiqué est votre pente (négative) ou balance favorable
@ -27,12 +28,6 @@ Consignee: Destinataire
Boxes: Colis Boxes: Colis
TotalWithVAT: Total avec TVA TotalWithVAT: Total avec TVA
PayOrder: Payer la commande PayOrder: Payer la commande
'AmountToPay:': 'Montant à payer (€):' An error has been in the payment: Il semble qu'il ya eu une erreur dans le paiement
AmountError: >-
La quantité doit être un neméro positif et inférieur ou égal à la somme
restant à payer
PayError: Impossible d'effectuer le paiement
An error has been in the payment: >-
Il semble qu'il ya eu une erreur dans le paiement
Retry: Réessayez Retry: Réessayez
Accept: Accepter Accept: Accepter

View File

@ -6,6 +6,7 @@ DateMake: Creation date
DateExit: Shipping date DateExit: Shipping date
SendMethod: Delivery method SendMethod: Delivery method
LastOrders: Last orders LastOrders: Last orders
Show orders from: '-Аас харуулах захиалга'
'Balance:': 'Balance:' 'Balance:': 'Balance:'
PaymentInfo: >- PaymentInfo: >-
Үзүүлсэн хэмжээ цаашид захиалга эзэлж биш, таны налуу (сөрөг), эсвэл Үзүүлсэн хэмжээ цаашид захиалга эзэлж биш, таны налуу (сөрөг), эсвэл
@ -26,12 +27,6 @@ Consignee: Consignee
Boxes: Bundles Boxes: Bundles
TotalWithVAT: Total with VAT TotalWithVAT: Total with VAT
PayOrder: Pay order PayOrder: Pay order
'AmountToPay:': 'Amount to pay (€):' An error has been in the payment: It seems that there has been an error in the payment
AmountError: >-
The amount must be a positive number less than or equal to the outstanding
amount
PayError: Failed to make the payment
An error has been in the payment: >-
It seems that there has been an error in the payment
Retry: Retry Retry: Retry
Accept: Accept Accept: Accept

View File

@ -6,6 +6,7 @@ DateMake: Data de criação
DateExit: Data de saída DateExit: Data de saída
SendMethod: Forma de envío SendMethod: Forma de envío
LastOrders: Últimas encomendas LastOrders: Últimas encomendas
Show orders from: Mostrar ordens de
'Balance:': 'Saldo:' 'Balance:': 'Saldo:'
PaymentInfo: >- PaymentInfo: >-
A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de
@ -27,11 +28,6 @@ Consignee: Consignatario
Boxes: Bultos Boxes: Bultos
TotalWithVAT: Total com IVA TotalWithVAT: Total com IVA
PayOrder: Pagar encomenda PayOrder: Pagar encomenda
'AmountToPay:': 'Quantidade a pagar (€):'
AmountError: >-
A quantidade deve ser um número positivo e inferior ou igual ao importe
pendiente
PayError: Erro ao realizar o pagamento
An error has been in the payment: Parece que houve um erro no pagamento An error has been in the payment: Parece que houve um erro no pagamento
Retry: Tentar novamente Retry: Tentar novamente
Accept: Aceitar Accept: Aceitar

View File

@ -5,27 +5,32 @@ Hedera.Orders = new Class
,activate: function () ,activate: function ()
{ {
this.tpv = new Hedera.Tpv ({conn: this.conn}); this.tpv = new Hedera.Tpv ({
conn: this.conn,
hash: this.hash
});
this.tpv.check (this._onTpvCheck.bind (this)); this.tpv.check (this._onTpvCheck.bind (this));
var params = this.params;
if (!params.$.from)
{
var from = new Date ();
from.setDate (from.getDate () - 30);
from.setHours (0, 0, 0, 0);
params.assign ({from: from});
}
} }
,_onTpvCheck: function (tpv, tpvOrder, tpvStatus) ,_onTpvCheck: function (tpv, tpvOrder, tpvStatus)
{ {
if (tpvStatus === 'ko') if (tpvStatus === 'ko')
this.$('error-dialog').show (); this.$.errorDialog.show ();
} }
,onBasketClick: function () ,onBasketClick: function ()
{ {
this.hash.set ({form: 'ecomerce/basket'}); this.hash.setAll ({form: 'ecomerce/basket'});
}
,repeaterFunc: function (res, form)
{
res.$('link').href = this.hash.make ({
form: 'ecomerce/ticket',
ticket: form.get ('id')
});
} }
// TPV // TPV
@ -33,14 +38,15 @@ Hedera.Orders = new Class
,balanceConditionalFunc: function (field, value) ,balanceConditionalFunc: function (field, value)
{ {
if (value >= 0) if (value >= 0)
Vn.Node.removeClass (this.$('balance'), 'negative'); Vn.Node.removeClass (this.$.balance, 'negative');
else else
Vn.Node.addClass (this.$('balance'), 'negative'); Vn.Node.addClass (this.$.balance, 'negative');
} }
,onPayButtonClick: function () ,onPayButtonClick: function ()
{ {
var amount = -this.$('debt').value; var amount = -this.$.debt.value;
amount = amount <= 0 ? null : amount; amount = amount <= 0 ? null : amount;
var defaultAmountStr = ''; var defaultAmountStr = '';

View File

@ -1,10 +1,7 @@
.orders
.orders .card
{ {
padding: 1em; max-width: 28em;
}
.orders .box
{
max-width: 25em;
} }
/* Balance */ /* Balance */
@ -12,7 +9,6 @@
.balance .balance
{ {
margin-top: 1.2em; margin-top: 1.2em;
margin-right: .5em;
} }
.balance > * .balance > *
{ {
@ -29,6 +25,7 @@
cursor: pointer; cursor: pointer;
height: 1.2em; height: 1.2em;
cursor: pointer; cursor: pointer;
margin: 0 .3em;
} }
.balance > .negative .balance > .negative
{ {
@ -48,25 +45,7 @@
/* List */ /* List */
.orders .item .orders .list-row > p.total
{
display: block;
padding: 1em;
border-bottom: 1px solid #DDD;
}
.orders .item:hover
{
background-color: rgba(1, 1, 1, 0.05);
}
.orders .item > p
{
margin: .1em 0;
}
.orders .item > p.important
{
font-size: 1.2em;
}
.orders .item > p.total
{ {
float: right; float: right;
} }

View File

@ -1,7 +1,10 @@
<vn> <vn>
<div id="title"> <vn-lot-query id="params">
<h1><t>LastOrders</t></h1> <vn-spec name="from" type="Date"/>
</div> </vn-lot-query>
<h1 id="title">
_LastOrders
</h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="basket" icon="basket"
@ -16,18 +19,17 @@
on-click="onPayButtonClick"/> on-click="onPayButtonClick"/>
<div class="balance"> <div class="balance">
<span class="label"> <span class="label">
<t>Balance:</t> _Balance:
</span> </span>
<span class="amount" id="balance"> <span class="amount" id="balance">
<htk-text id="debt" <htk-text
lot="debt"
name="debt"
format="%.2d€" format="%.2d€"
conditional-func="balanceConditionalFunc" conditional-func="balanceConditionalFunc">
column="debt"> <db-form id="debt">
<db-form property="form">
<db-model property="model"> <db-model property="model">
<custom>
SELECT -myClientGetDebt(NULL) debt SELECT -myClientGetDebt(NULL) debt
</custom>
</db-model> </db-model>
</db-form> </db-form>
</htk-text> </htk-text>
@ -39,32 +41,31 @@
alt="Info"/> alt="Info"/>
</div> </div>
</div> </div>
<div id="form" class="orders"> <div id="main" class="orders">
<div class="box confirmed"> <div class="card form">
<htk-repeater form-id="iter" renderer="repeaterFunc"> <div>
<db-model property="model" id="tickets"> <label>_Show orders from</label>
<custom> <htk-date-chooser lot="params" name="from"/>
CALL myTicketList (NULL, NULL); </div>
</custom> </div>
<div class="card list">
<htk-repeater form-id="iter">
<db-model property="model" lot="params">
CALL myTicketList (#from, NULL)
</db-model> </db-model>
<custom> <custom>
<a id="link" class="item" title="_SeeOrder"> <a href="#!form=ecomerce/ticket&amp;ticket={{id}}"
class="list-row"
title="_SeeOrder">
<p class="important total"> <p class="important total">
<htk-text form="iter" column="total" format="%.2d€"/> <htk-text lot="iter" name="total" format="%.2d€"/>
</p> </p>
<p class="important"> <p class="important">
<htk-text form="iter" column="landed" format="%D"/> <htk-text lot="iter" name="landed" format="%D"/>
</p> </p>
<p> <p>@{{id}}</p>
@<htk-text form="iter" column="id"/> <p>{{nickname}}</p>
</p> <p>{{agency}}</p>
<p>
<htk-text form="iter" column="nickname"/>
</p>
<p>
<htk-text form="iter" column="agency"/>
</p>
<div class="clear"/>
</a> </a>
</custom> </custom>
</htk-repeater> </htk-repeater>

View File

@ -1,14 +1,3 @@
.ticket
{
padding: 1em;
}
.ticket .box
{
max-width: 30em;
margin: 0 auto;
padding: 2em;
color: #333;
}
/* Header */ /* Header */
@ -62,13 +51,18 @@
{ {
padding: .5em 0; padding: .5em 0;
} }
.ticket .line > .photo
{
margin-right: 1em;
float: left;
border-radius: 50%;
height: 3.2em;
width: 3.2em;
}
.ticket .line p .ticket .line p
{ {
margin: .1em 0; margin: .1em 0;
} margin-left: 4em;
.ticket .amount
{
float: left;
} }
.ticket .subtotal .ticket .subtotal
{ {

View File

@ -8,9 +8,8 @@ Hedera.Ticket = new Class
if (!ticket.value) if (!ticket.value)
return; return;
var batch = new Sql.Batch (); var params = {ticket: ticket.value};
batch.addValue ('ticket', ticket.value); this.conn.execQuery ('CALL myTicketLogAccess (#ticket)', params);
this.conn.execQuery ('CALL myTicketLogAccess (#ticket)', null, batch);
} }
,onTicketReady: function (form) ,onTicketReady: function (form)
@ -23,9 +22,8 @@ Hedera.Ticket = new Class
,onPrintClick: function () ,onPrintClick: function ()
{ {
var batch = new Sql.Batch (); var params = {ticket: this.hash.get ('ticket')};
batch.addValue ('ticket', this.$('ticket-id').value); this.gui.openReport ('delivery-note', params);
this.gui.openReport ('delivery-note', batch);
} }
,subtotalRenderer: function (column, form) ,subtotalRenderer: function (column, form)
@ -33,21 +31,20 @@ Hedera.Ticket = new Class
column.value = this.subtotal (form); column.value = this.subtotal (form);
} }
,repeaterFunc: function (res, form) ,repeaterFunc: function (scope, form)
{ {
res.$('subtotal').value = this.subtotal (form); scope.$.subtotal.value = this.subtotal (form);
} }
,subtotal: function (form) ,subtotal: function (form)
{ {
var price = form.get ('price'); var row = form.$;
var discount = form.get ('discount'); return row.quantity * row.price * ((100 - row.discount) / 100);
return form.get ('quantity') * price * ((100 - discount) / 100);
} }
,onPackagesChanged: function (model) ,onPackagesChanged: function (model)
{ {
this.$('packages').node.style.display = this.$.packages.node.style.display =
model.numRows > 0 ? 'block' : 'none'; model.numRows > 0 ? 'block' : 'none';
} }
}); });

View File

@ -1,96 +1,75 @@
<vn> <vn>
<vn-group> <vn-lot-query id="params">
<vn-param id="ticket-id" on-changed="onTicketChange"/> <vn-spec name="ticket" type="Number"/>
<vn-hash-param key="ticket" param="ticket-id"/> </vn-lot-query>
<sql-batch id="batch"> <db-lot id="ticket" lot="params" on-ready="onTicketReady">
<custom>
<item name="ticket" param="ticket-id"/>
</custom>
</sql-batch>
<db-form id="ticket" on-ready="onTicketReady">
<db-model id="ticket-data" property="model" batch="batch">
<custom>
CALL myTicketGet(#ticket) CALL myTicketGet(#ticket)
</custom> </db-lot>
</db-model> <h1 id="title">
</db-form> _OrderDetail
</vn-group> </h1>
<div id="title">
<h1><t>OrderDetail</t></h1>
</div>
<div id="actions" class="action-bar"> <div id="actions" class="action-bar">
<htk-bar-button <htk-bar-button
icon="print" icon="receipt"
tip="_Print delivery note" tip="_Delivery note"
on-click="onPrintClick"/> on-click="onPrintClick"/>
</div> </div>
<div id="form" class="ticket"> <div id="main" class="ticket">
<div class="box"> <div class="card form">
<htk-loader class="head" form="ticket"> <htk-loader class="head" form="ticket">
<div> <div>
<p class="important ticket-id"> <p class="important ticket-id">
@<htk-text column="id" form="ticket"/> @{{ticket.id}}
</p> </p>
<p> <p>
<htk-text form="ticket" column="landed" format="%D"/> <htk-text lot="ticket" name="landed" format="%D"/>
</p> </p>
<p> <p>
<span id="method"></span> <htk-text form="ticket" column="agency"/> <span id="method"/> {{ticket.agency}}
</p> </p>
</div> </div>
<div class="address"> <div class="address">
<p> <p>
<htk-text form="ticket" column="nickname"/> {{ticket.nickname}}
</p> </p>
<p> <p>
<htk-text form="ticket" column="street"/> {{ticket.street}}
</p> </p>
<p> <p>
<htk-text form="ticket" column="postalCode"/> {{ticket.postalCode}} {{ticket.city}} ({{ticket.province}})
<htk-text form="ticket" column="city"/>
(<htk-text form="ticket" column="province"/>)
</p> </p>
</div> </div>
<div class="total"> <div class="total">
<p class="important total"> <p class="important total">
<t>Total</t> _Total
<htk-text format="%.2d€" form="ticket" column="taxBase"/> <htk-text lot="ticket" name="taxBase" format="%.2d€"/>
</p> </p>
<p class="important total"> <p class="important total">
<t>Total + tax</t> _Total + tax
<htk-text format="%.2d€" form="ticket" column="total"/> <htk-text lot="ticket" name="total" format="%.2d€"/>
</p> </p>
</div> </div>
</htk-loader> </htk-loader>
<htk-repeater form-id="iter" renderer="repeaterFunc"> <htk-repeater renderer="repeaterFunc">
<db-model <db-model property="model" id="movements" lot="params">
property="model"
id="movements"
batch="batch">
<custom>
CALL myTicketGetRows(#ticket) CALL myTicketGetRows(#ticket)
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="line"> <div class="line">
<htk-image <htk-image
form="iter" value="{{image}}"
column="image"
class="photo" class="photo"
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
full-dir="900x900"/> full-dir="900x900"/>
<p class="concept"> <p class="concept">
<htk-text form="iter" column="concept"/> {{concept}} {{size}} {{category}}
<htk-text form="iter" column="size"/>
<htk-text form="iter" column="category"/>
</p> </p>
<p class="amount"> <p class="amount">
<htk-text form="iter" column="quantity"/> x {{quantity}} x <htk-text lot="iter" name="price" format="%.2d€"/>
<htk-text form="iter" column="price" format="%.2d€"/> <span class="subtotal">
</p>
<p class="subtotal">
<htk-text id="subtotal" format="%.2d€"/> <htk-text id="subtotal" format="%.2d€"/>
</span>
</p> </p>
<div class="clear"/> <div class="clear"/>
</div> </div>
@ -100,28 +79,25 @@
<db-model <db-model
property="model" property="model"
on-status-changed="onPackagesChanged" on-status-changed="onPackagesChanged"
batch="batch"> lot="params">
<custom>
CALL myTicketGetPackages (#ticket) CALL myTicketGetPackages (#ticket)
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="line"> <div class="line">
<htk-image <htk-image
form="iter" value="{{image}}"
column="image"
class="photo" class="photo"
directory="catalog" directory="catalog"
subdir="200x200" subdir="200x200"
full-dir="900x900"/> full-dir="900x900"/>
<p class="subtotal"> <p class="subtotal">
<htk-text form="iter" column="quantity"/> {{quantity}}
</p> </p>
<p class="concept"> <p class="concept">
<htk-text form="iter" column="name"/> {{name}}
</p> </p>
<p class="amount"> <p class="amount">
@<htk-text form="iter" column="id"/> {{id}}
</p> </p>
<div class="clear"/> <div class="clear"/>
</div> </div>

View File

@ -10,13 +10,13 @@ Hedera.New = new Class
,activate: function () ,activate: function ()
{ {
this.$('model').mode = Db.Model.Mode.ON_DEMAND; this.$.model.mode = Db.Model.Mode.ON_DEMAND;
this.$('model').setDefault ('userFk', 'news', this.$.model.setDefault ('userFk', 'news',
new Sql.Function ({schema: 'account', name: 'userGetId'})); new Sql.Function ({schema: 'account', name: 'userGetId'}));
tinymce.init ({ tinymce.init ({
mode : 'exact' mode : 'exact'
,target: this.$('html-editor') ,target: this.$.htmlEditor
,plugins: [ ,plugins: [
"advlist autolink lists link image charmap print preview hr" "advlist autolink lists link image charmap print preview hr"
,"anchor pagebreak searchreplace wordcount visualblocks" ,"anchor pagebreak searchreplace wordcount visualblocks"
@ -24,7 +24,7 @@ Hedera.New = new Class
,"save table contextmenu directionality emoticons template" ,"save table contextmenu directionality emoticons template"
,"paste textcolor" ,"paste textcolor"
] ]
,toolbar1: ,toolbar:
" print preview | link image media emoticons blockquote" " print preview | link image media emoticons blockquote"
+" | insertfile undo redo | bold italic" +" | insertfile undo redo | bold italic"
+" | alignleft aligncenter alignright alignjustify" +" | alignleft aligncenter alignright alignjustify"
@ -53,7 +53,7 @@ Hedera.New = new Class
if (!this.editor) if (!this.editor)
return; return;
var newHtml = this.$('iter').get ('text'); var newHtml = this.$.iter.get ('text');
if (!newHtml) if (!newHtml)
newHtml = ''; newHtml = '';
@ -63,7 +63,7 @@ Hedera.New = new Class
,onStatusChange: function (form) ,onStatusChange: function (form)
{ {
if (this.$('new-id').value == 0) if (this.hash.get('new') == 0)
form.insertRow (); form.insertRow ();
} }
@ -80,13 +80,13 @@ Hedera.New = new Class
,onAcceptClick: function () ,onAcceptClick: function ()
{ {
this.$('iter').set ('text', this.editor.getContent ()); this.$.iter.set ('text', this.editor.getContent ());
this.$('iter').performOperations (); this.$.iter.performOperations ();
} }
,onReturnClick: function () ,onReturnClick: function ()
{ {
this.hash.set ({'form': 'news/news'}); this.hash.setAll ({'form': 'news/news'});
} }
}); });

View File

@ -1,12 +1,7 @@
.new .new .card
{
padding: 1em;
}
.new .box
{ {
max-width: 38em; max-width: 38em;
padding: 2em;
} }
/* Form */ /* Form */

View File

@ -1,29 +1,21 @@
<vn> <vn>
<vn-group> <vn-group>
<vn-param id="new-id"/>
<vn-hash-param key="new" param="new-id"/>
<db-form id="iter" on-status-changed="onStatusChange"> <db-form id="iter" on-status-changed="onStatusChange">
<db-model <db-model
id="model" id="model"
property="model" property="model"
updatable="true" updatable="true"
lot="hash"
on-operations-done="onOperationsDone"> on-operations-done="onOperationsDone">
<custom>
SELECT id, title, text, tag, priority SELECT id, title, text, tag, priority
FROM news WHERE id = #new FROM news WHERE id = #new
</custom>
<sql-batch property="batch">
<custom>
<item name="new" param="new-id"/>
</custom>
</sql-batch>
</db-model> </db-model>
</db-form> </db-form>
<db-param form="iter" column="text" on-changed="onBodyChange"/> <vn-param lot="iter" name="text" on-changed="onBodyChange"/>
</vn-group> </vn-group>
<div id="title"> <h1 id="title">
<h1><t>AddEditNew</t></h1> _AddEditNew
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="ok" icon="ok"
@ -34,33 +26,29 @@
tip="_Return" tip="_Return"
on-click="onReturnClick"/> on-click="onReturnClick"/>
</div> </div>
<div id="form" class="new"> <div id="main" class="new">
<div class="box"> <div class="card form">
<div class="form"> <div>
<div class="form-group"> <label>_Title</label>
<label><t>Title</t></label> <htk-entry lot="iter" name="title"/>
<htk-entry form="iter" column="title"/>
</div> </div>
<div class="form-group"> <div>
<label><t>Tag</t></label> <label>_Tag</label>
<htk-combo form="iter" column="tag"> <htk-combo lot="iter" name="tag">
<db-model property="model"> <db-model property="model">
<custom>
SELECT name, description FROM newsTag SELECT name, description FROM newsTag
ORDER BY description ORDER BY description
</custom>
</db-model> </db-model>
</htk-combo> </htk-combo>
</div> </div>
<div class="form-group"> <div>
<label><t>Priority</t></label> <label>_Priority</label>
<htk-entry form="iter" column="priority"/> <htk-entry lot="iter" name="priority"/>
</div> </div>
<div class="form-group"> <div>
<label><t>NewBody</t></label> <label>_NewBody</label>
<textarea id="html-editor"/> <textarea id="html-editor"/>
</div> </div>
</div> </div>
</div> </div>
</div>
</vn> </vn>

View File

@ -3,28 +3,26 @@ Hedera.News = new Class
({ ({
Extends: Hedera.Form Extends: Hedera.Form
,editNew: function (newId) ,onDeleteClick: function (button)
{
this.hash.set ({
'form': 'news/new'
,'new': newId
});
}
,onEditClick: function (button, form)
{
this.editNew (button.value);
}
,onDeleteClick: function (button, form)
{ {
if (confirm (_('ReallyDelete'))) if (confirm (_('ReallyDelete')))
form.deleteRow (); button.lot.deleteRow ();
}
,repeaterFunc: function (res, lot)
{
res.$.link.href = this.hash.make ({
form: 'news/new',
new: lot.$.id
});
} }
,onAddClick: function () ,onAddClick: function ()
{ {
this.editNew (0); this.hash.setAll ({
form: 'news/new',
new: 0
});
} }
}); });

View File

@ -1,32 +1,12 @@
.news
.news .card
{ {
padding: 1em; max-width: 30em;
}
.news .box
{
max-width: 35em;
margin: 0 auto;
} }
/* Items */ /* Items */
.news .item .news .list-row > .photo
{
padding: 1em;
border-bottom: 1px solid #DDD;
}
.news .item > p
{
margin: .1em 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.news .item > p.important
{
font-size: 1.2em;
}
.news .item > .photo
{ {
float: left; float: left;
margin-right: 1em; margin-right: 1em;
@ -34,8 +14,3 @@
width: 4.2em; width: 4.2em;
border-radius: .3em; border-radius: .3em;
} }
.news .item > button
{
float: right;
margin: 0;
}

View File

@ -1,41 +1,34 @@
<vn> <vn>
<div id="title"> <h1 id="title">
<h1><t>NewsManagement</t></h1> _NewsManagement
</div> </h1>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
icon="add" icon="add"
tip="_AddNew" tip="_AddNew"
on-click="onAddClick"/> on-click="onAddClick"/>
</div> </div>
<div id="form" class="news"> <div id="main" class="news">
<div class="box"> <div class="card">
<htk-repeater form-id="iter"> <htk-repeater form-id="iter" renderer="repeaterFunc">
<db-model property="model" id="news-model" updatable="true"> <db-model property="model" id="news-model" updatable="true">
<custom>
SELECT n.id, u.nickname, priority, image, title SELECT n.id, u.nickname, priority, image, title
FROM news n FROM news n
JOIN account.user u ON u.id = n.userFk JOIN account.user u ON u.id = n.userFk
ORDER BY priority, n.created DESC ORDER BY priority, n.created DESC
</custom>
</db-model> </db-model>
<custom> <custom>
<div class="item"> <a id="link" class="list-row" title="_EditNew">
<div class="actions">
<htk-button <htk-button
form="iter" lot="iter"
column="id"
tip="_EditNew"
icon="edit"
on-click="onEditClick"/>
<htk-button
form="iter"
column="id"
tip="_Remove" tip="_Remove"
icon="delete" icon="delete"
on-click="onDeleteClick"/> on-click="onDeleteClick"/>
</div>
<htk-image <htk-image
form="iter" lot="iter"
column="image" name="image"
class="photo" class="photo"
directory="news" directory="news"
subdir="200x200" subdir="200x200"
@ -43,16 +36,15 @@
editable="true" editable="true"
conn="conn"/> conn="conn"/>
<p class="important"> <p class="important">
<htk-text form="iter" column="title"/> {{title}}
</p> </p>
<p> <p>
<htk-text form="iter" column="nickname"/> {{nickname}}
</p> </p>
<p> <p>
<t>Priority</t> <span>_Priority</span> {{priority}}
<htk-text form="iter" column="priority"/>
</p> </p>
</div> </a>
</custom> </custom>
</htk-repeater> </htk-repeater>
</div> </div>

View File

@ -0,0 +1,3 @@
Report: Informe
Preview: Visualització prèvia
Print: Imprimir

View File

@ -0,0 +1,3 @@
Report: Report
Preview: Preview
Print: Print

View File

@ -0,0 +1,3 @@
Report: Informe
Preview: Vista preliminar
Print: Imprimir

View File

@ -0,0 +1,3 @@
Report: Rapport
Preview: Avant-première
Print: Imprimer

Some files were not shown because too many files have changed in this diff Show More