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
FROM myClient c
</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,59 +33,48 @@
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>
<div class="form-group"> <label>_Address</label>
<label><t>Address</t></label> <htk-entry lot="iter" name="street"/>
<htk-entry column="street" form="iter"/> </div>
</div> <div>
<div class="form-group"> <label>_City</label>
<label><t>City</t></label> <htk-entry lot="iter" name="city"/>
<htk-entry column="city" form="iter"/> </div>
</div> <div>
<div class="form-group"> <label>_ZipCode</label>
<label><t>ZipCode</t></label> <htk-entry lot="iter" name="postalCode"/>
<htk-entry column="postalCode" form="iter"/> </div>
</div> <div>
<div class="form-group"> <label>_Country</label>
<label><t>Country</t></label> <htk-combo>
<htk-combo> <vn-param
<db-param id="country"
id="country" property="param"
property="param" lot="iter"
form="iter" name="country"
column="countryFk" one-way="true"/>
one-way="true"/> <db-model property="model">
<db-model property="model"> SELECT id, country FROM vn.country
<custom> ORDER BY country
SELECT id, country FROM vn.country </db-model>
ORDER BY country </htk-combo>
</custom> </div>
</db-model> <div>
</htk-combo> <label>_Province</label>
</div> <htk-combo lot="iter" name="province_id">
<div class="form-group"> <db-model property="model" lot="iter">
<label><t>Province</t></label> SELECT id, name FROM vn.province
<htk-combo column="provinceFk" form="iter"> WHERE countryFk = #country
<db-model property="model"> ORDER BY name
<custom> </db-model>
SELECT id, name FROM vn.province </htk-combo>
WHERE countryFk = #country
ORDER BY name
</custom>
<sql-batch property="batch">
<custom>
<item name="country" param="country"/>
</custom>
</sql-batch>
</db-model>
</htk-combo>
</div>
</div> </div>
</div> </div>
</div> </div>

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"> SELECT length, nAlpha, nUpper, nDigits, nPunct
<custom> FROM account.userPassword
SELECT length, nAlpha, nUpper, nDigits, nPunct </db-lot>
FROM account.userPassword <db-form id="user">
</custom>
</db-model>
</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>
<div class="form-group"> <label for="email">_Email</label>
<label for="email"><t>Email</t></label> <htk-entry lot="user" name="email"></htk-entry>
<htk-entry form="user-form" column="email"></htk-entry> </div>
</div> <div>
<div class="form-group"> <label for="nickname">_Display name</label>
<label for="nickname"><t>Display name</t></label> <htk-entry lot="user" name="nickname"/>
<htk-entry form="user-form" column="nickname"/> </div>
</div> <div>
<div class="form-group"> <label for="lang">_Language</label>
<label for="lang"><t>Language</t></label> <htk-combo lot="user" name="lang"
<htk-combo form="user-form" column="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 </db-model>
</custom> </htk-combo>
</db-model> </div>
</htk-combo> <div>
</div> <span>
<div class="form-group"> <htk-check id="mail" lot="user" name="isToBeMailed"/>
<label for="mail"><t>Receive invoices by email</t></label> <label for="mail">_Receive invoices by email</label>
<htk-check form="user-form" column="isToBeMailed"/> </span>
</div>
</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,69 +1,49 @@
<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"> SELECT Id_Cliente, Cliente, Telefono, movil
<db-model property="model"> FROM vn2008.Clientes WHERE Id_Cliente = #user
<custom>
SELECT Id_Cliente, Cliente, Telefono, movil
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> {{client.Id_Cliente}}
<htk-text form="user-form" column="Id_Cliente"/> </p>
</p> <p>
<p> {{client.Cliente}}
<htk-text form="user-form" column="Cliente"/> </p>
</p> <p>
<p> {{client.Telefono}}
<htk-text form="user-form" column="Telefono"/> </p>
</p> <p>
<p> {{client.movil}}
<htk-text form="user-form" column="movil"/> </p>
</p>
</div>
</div> </div>
<div class="list box"> <div class="card">
<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 JOIN visitAgent a ON a.id = c.agent
JOIN visitAgent a ON a.id = c.agent 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,52 +14,46 @@
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 JOIN visitUser vu ON vu.id = s.userVisit
JOIN visitUser vu ON vu.id = s.userVisit JOIN visitAccess ac ON ac.id = vu.access
JOIN visitAccess ac ON ac.id = vu.access JOIN visitAgent a ON a.id = ac.agent
JOIN visitAgent a ON a.id = ac.agent 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}}"
<htk-button class="list-row"
form="iter" title="_Access log">
column="id" <div class="actions">
tip="_Supplant user" <htk-button
icon="incognito" lot="iter"
on-click="onChangeUserClick"/> name="id"
<htk-button tip="_Supplant user"
form="iter" icon="incognito"
column="id" on-click="onChangeUserClick"/>
tip="_Access log" </div>
icon="gnome"
on-click="onAccessLogClick"/>
<p class="important"> <p class="important">
<htk-text form="iter" column="nickname"/> {{nickname}}
</p> </p>
<p> <p>
<htk-text form="iter" column="stamp" format="%a, %T"/> - <htk-text lot="iter" name="stamp" format="%a, %T"/> -
<htk-text form="iter" column="lastUpdate" format="%T"/> <htk-text lot="iter" name="lastUpdate" format="%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> </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('%', #search, '%')
WHERE Article LIKE CONCAT('%', #filter, '%') OR Id_Article = #search
OR Id_Article = #filter 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
<htk-button </span>
id="impersonate" <htk-button
form="iter" id="impersonate"
column="id" value="{{id}}"
tip="_Impersonate user" tip="_AccessAsUser"
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> </div>
<vn-param property="param" id="from"/> <div>
</htk-date-chooser> <label>_To</label>
</div> <htk-date-chooser lot="params" name="to"/>
<div class="form-group">
<label><t>To</t></label>
<htk-date-chooser>
<vn-param property="param" id="to"/>
</htk-date-chooser>
</div>
</div> </div>
</div> </div>
<div class="summary box"> <div class="summary card form">
<p> <p>
<htk-text> <htk-text>
<db-calc-sum <db-calc-sum
@ -37,55 +35,43 @@
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 ,MAX(c.stamp) lastVisit
,MAX(c.stamp) lastVisit ,COUNT(DISTINCT c.id) visits
,COUNT(DISTINCT c.id) visits ,SUM(a.firstAccess = c.id AND v.firstAgent = a.id) newVisits
,SUM(a.firstAccess = c.id AND v.firstAgent = a.id) newVisits FROM visitUser e
FROM visitUser e
JOIN visitAccess c ON e.access = c.id JOIN visitAccess c ON e.access = c.id
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,12 +56,12 @@
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
{ {
margin: 1em 0; margin: 1em 0;
} }
.about p.summary .about p.summary
{ {
@ -74,7 +71,7 @@
padding: 1em; padding: 1em;
border-radius: 0.1em; border-radius: 0.1em;
box-shadow: 0 0.2em 0.2em #AAA; box-shadow: 0 0.2em 0.2em #AAA;
margin: 1.5em auto; margin: 1.5em auto;
} }
/* Images */ /* Images */
@ -83,26 +80,27 @@
{ {
max-width: 90%; max-width: 90%;
text-align: center; text-align: center;
padding: 1em; display: block;
display: block; margin: 1em auto;
margin: 0 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> </h1>
<div id="form" class="about"> <div id="main" class="about">
<div class="cols"> <div class="cols">
<div class="box"> <div class="card">
<h1> <h1>
<t>QualityAndVariety</t> _QualityAndVariety
</h1> </h1>
<p><t>MaximumFreshness</t></p> <p>_MaximumFreshness</p>
<h3><t>SquareMeters</t></h3> <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"> <form
<div class="form"> id="contact-form">
<p> <input type="hidden" name="srv" value="json:misc/contact"/>
<t>FillFormData</t> <div class="card form">
</p> <p>
<p> _FillFormData
<t>OrCallUs</t> </p>
</p> <p>
<form _OrCallUs
id="contact-form"> </p>
<input type="hidden" name="srv" value="json:misc/contact"/> <div>
<div class="form-group"> <label>_Name</label>
<label><t>Name</t></label> <input type="text" name="name"/>
<input type="text" name="name"/>
</div>
<div class="form-group">
<label><t>City</t></label>
<input type="text" name="city"/>
</div>
<div class="form-group">
<label><t>PC</t></label>
<input type="text" name="pc"/>
</div>
<div class="form-group">
<label><t>Phone</t></label>
<input type="text" name="phone"/>
</div>
<div class="form-group">
<label><t>EMail</t></label>
<input type="text" name="email"/>
</div>
<div class="form-group">
<label><t>Message</t></label>
<textarea name="message"/>
</div>
<div class="form-group captcha">
<label><t>Anti-Spam</t></label>
<input type="text" name="captcha"/>
<img alt="Captcha" id="captcha-img"/>
</div>
<p class="mandatory-message">
<t>AllFieldsMandatory</t>
</p>
<button class="thin">
<t>Send</t>
</button>
</form>
</div> </div>
<div>
<label>_City</label>
<input type="text" name="city"/>
</div>
<div>
<label>_PC</label>
<input type="text" name="pc"/>
</div>
<div>
<label>_Phone</label>
<input type="text" name="phone"/>
</div>
<div>
<label>_EMail</label>
<input type="text" name="email"/>
</div>
<div>
<label>_Message</label>
<textarea name="message"/>
</div>
<div class="form-group captcha">
<label>_Anti-Spam</label>
<input type="text" name="captcha"/>
<img alt="Captcha" id="captcha-img"/>
</div>
<p class="mandatory-message">
_AllFieldsMandatory
</p>
<button class="thin">
_Send
</button>
</div> </div>
</form>
</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 </db-model>
LEFT JOIN vn2008.Origen o ON a.id_origen = o.id <custom>
</custom> <div class="line">
</db-model> <htk-button
<custom> lot="iter"
<div class="line"> class="delete"
<htk-button tip="_Remove"
form="iter" icon="delete"
column="ticket_id" on-click="onDeleteClick"/>
class="delete" <htk-image
tip="_Remove" value="{{image}}"
icon="delete" class="photo"
on-click="onDeleteClick"/> directory="catalog"
<htk-image subdir="200x200"
form="iter" full-dir="900x900"/>
column="Foto" <p class="concept">
class="photo" {{name}} {{size}} {{category}}
directory="catalog" </p>
subdir="200x200" <p class="amount">
full-dir="900x900"/> <span id="row">{{amount}}</span> x
<p class="concept"> <htk-text lot="iter" name="price" format="%.2d€"/>
<htk-text form="iter" column="Article"/> <span class="subtotal">
<htk-text form="iter" column="Medida"/> <htk-text id="subtotal" format="%.2d€"/>
<htk-text form="iter" column="Categoria"/> </span>
</p> </p>
<p class="amount"> <span id="available">
<htk-text form="iter" column="amount"/> x {{available}} <span>_availables</span>
<htk-text form="iter" column="price" format="%.2d€"/> </span>
<span class="subtotal"> <div class="clear"/>
<htk-text id="subtotal" format="%.2d€"/> </div>
</span> </custom>
</p> </htk-repeater>
<div class="clear"/>
</div>
</custom>
</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.$;
this.hideMenu (); var shouldRefresh = params.search ||
} params.category && params.type;
,realmRenderer: function (builder, form) Vn.Node.removeChilds (this.$.suggestedFilters);
{
var link = builder.$('link');
link.href = this.hash.make ({
'form': this.hash.get ('form'),
'realm': form.get ('id')
});
var img = builder.$('image'); if (shouldRefresh)
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.$.items.query = this.buildQuery ('CALL catalogGetItems');
this.$('realm-msg').style.display = 'none'; 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 ();
} }
else else
this.$.items.clean ();
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)
{ {
this.$('filters').style.display = 'none'; var tagId = parseInt (tagId);
this.$('realm-msg').style.display = 'block'; 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-filter>
<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-string id="pre-query">
<db-model property="model"> DROP TEMPORARY TABLE IF EXISTS tItems;
<custom> CREATE TEMPORARY TABLE tItems
SELECT o.id, o.date_send, ag.description agency, v.code method (INDEX (id))
FROM basket o ENGINE = MEMORY
JOIN vn2008.Agencias ag ON ag.Id_Agencia = o.agency_id SELECT i.id
JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id FROM #joins
</custom> WHERE #filter
</db-model> </sql-string>
</db-form> <sql-string id="post-query">
<db-query id="basket-lines"> DROP TEMPORARY TABLE tItems
<custom> </sql-string>
SELECT item_id, warehouse_id, SUM(amount) amount
FROM basket_item
GROUP BY warehouse_id
</custom>
</db-query>
<db-model <db-model
id="items-model" id="items"
result-index="2" result-index="2"
on-status-changed="onItemsChange"> auto-load="false">
<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-model>
<db-form id="card" model="items-model"/> <db-lot id="basket" on-ready="onBasketReady">
<sql-batch id="card-batch"> SELECT o.id, o.date_send, ag.description agency, v.code method
<custom> FROM basket o
<item name="item" param="card-item"/> JOIN vn.agencyMode ag ON ag.id = o.agency_id
</custom> JOIN vn2008.Vistas v ON v.vista_id = o.delivery_method_id
</sql-batch> </db-lot>
<db-form id="card-extend"> <db-lot id="card-extend" lot="card-lot">
<db-model SELECT i.description
property="model" FROM vn.item i WHERE i.id = #item
batch="card-batch" </db-lot>
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"> CALL bionic_from_item (#item);
<custom> SELECT p.warehouse_id, w.name warehouse, p.grouping, p.price, p.rate, l.available
CALL bionic_from_item (#item); FROM tmp.bionic_lot l
SELECT p.warehouse_id, w.name warehouse, p.grouping, p.price, p.rate, l.available JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id
FROM tmp.bionic_lot l JOIN vn2008.warehouse w ON w.id = p.warehouse_id
JOIN tmp.bionic_price p ON p.warehouse_id = l.warehouse_id ORDER BY warehouse_id, grouping;
JOIN vn2008.warehouse w ON w.id = p.warehouse_id
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,269 +79,131 @@
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>
</div> </div>
</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"
<db-model on-change="onOrderChange"
id="types-model" value="relevancy"
property="model" not-null="true"/>
conn="conn" <label>_Family</label>
result-index="1" <htk-combo
on-status-changed="refreshTitle"> id="type"
<custom> name="type"
CALL item_available (); on-change="refreshTitle"
SELECT DISTINCT t.tipo_id, l.name lot="params">
FROM vn2008.Tipos t <db-model
JOIN vn2008.Articles a ON a.tipo_id = t.tipo_id id="types"
JOIN tmp.item_available i ON i.item_id = a.Id_Article property="model"
JOIN vn.itemTypeL10n l ON l.id = t.tipo_id lot="params"
WHERE #filter result-index="1">
CALL itemGetAvailable;
SELECT DISTINCT t.id, l.name
FROM vn.itemType t
JOIN vn.item i ON i.typeFk = t.id
JOIN tmp.itemAvailable a ON a.id = i.id
JOIN vn.itemTypeL10n l ON l.id = t.id
WHERE t.categoryFk = #category
ORDER BY name ORDER BY name
</custom> </db-model>
</db-model> </htk-combo>
<sql-filter property="filter" type="AND"> </div>
<sql-filter-item type="EQUAL"> <div id="current-filters"/>
<sql-field name="reino_id" target="t"/> <div id="suggested-filters"/>
<sql-value param="realm"/> <button on-click="onRemoveFiltersClick" class="thin">
</sql-filter-item> _Remove filters
</sql-filter> </button>
</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 id="order" class="order">
<h2><t>Order by</t></h2>
<select on-change="onOrderChange">
<option value="D|relevancy" selected="true">
<t>Relevancy</t>
</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>
{{name}} {{value}}
</p>
</custom>
</htk-repeater>
<p> <p>
@<htk-text form="card" column="item_id"/> <htk-text lot="card" name="Tallos" format="_, %.0d Units"/>
</p>
<p>
<t>Size</t> <htk-text form="card" column="Medida"/>,
<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,82 +1,84 @@
<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 vn.deliveryMethod d ON d.id = o.delivery_method_id
JOIN vn2008.Vistas v ON o.delivery_method_id = v.vista_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 JOIN vn.agencyMode m
JOIN vn.agencyMode m ON m.agencyFk = a.agencyFk
ON m.agencyFk = a.agencyFk JOIN vn.deliveryMethod d
JOIN vn.deliveryMethod d ON d.id = m.deliveryMethodFk
ON d.id = m.deliveryMethodFk 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 JOIN vn.agencyMode m
JOIN vn.agencyMode m ON m.agencyFk = a.agencyFk
ON m.agencyFk = a.agencyFk JOIN vn.deliveryMethod d
JOIN vn.deliveryMethod d ON d.id = m.deliveryMethodFk
ON d.id = m.deliveryMethodFk 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">
<div class="answers target"> <h2 id="date-question"/>
<htk-combo <div class="answers">
id="agency-combo" <htk-calendar
param="agency" id="calendar"
on-changed="onFieldChange" class="thin-calendar"
model="agencies"/> lot="lot"
</div> name="date"
restrict-func="calendarRestrict"
on-pick="onFieldChange"/>
</div> </div>
<div id="pickup-step"> <<<<<<< HEAD
<h2><t>PickupWarehouseQuestion</t></h2> </htk-step>
<div class="answers target"> <htk-step name="address">
<htk-combo <h2>_AddressQuestion</h2>
id="warehouse-combo" <div class="answers target">
param="agency" <htk-repeater
on-changed="onFieldChange" id="repeater"
model="warehouses"/> form-id="iter"
</div> 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> </div>
</htk-step>
<htk-step name="delivery">
<h2 id="wh-question"/>
<div class="answers target">
<htk-combo
id="agency"
lot="lot"
name="agency"
not-null="true"
placeholder="_Select agency"
show-field="description"
on-changed="onFieldChange"
model="agencies"/>
=======
<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">
<div class="answers target"> <h2>_ConfirmToAccessCatalog</h2>
<p> <div class="answers target">
<t>Pickup</t> <p>
<htk-text format="%D" param="date"/> _Arrival <htk-text format="%D" lot="lot" name="date"/>
</p> </p>
<p> <p>
<t>Warehouse</t> {{addressForm.name}}
<htk-text form="warehouse-combo" column="description"/> </p>
</p> <p id="agency-text">
<button id="confirm-pickup" class="thin" on-click="onConfirmClick"> <span>_Agency</span> {{agency.description}}
<t>Confirm</t> </p>
</button> <p id="delivery-text">
<div class="clear"/> _ReceiveThroughtRoute
</div> </p>
<p id="pickup-text">
<span>_Warehouse</span> {{agency.description}}
</p>
<button id="confirm-button" class="thin" on-click="onConfirmClick">
_Confirm
</button>
<div class="clear"/>
</div> </div>
</div> </htk-step>
<htk-assistant-bar assistant="assistant"/> </htk-assistant>
</div> <htk-assistant-bar assistant="assistant"/>
</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,114 +1,109 @@
<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, ad.nickname, ad.postalCode, ad.city, ad.street,
ad.nickname, ad.postalCode, ad.city, ad.street, t.*, c.credit, myClientGetDebt(NULL) debt
t.*, c.credit, myClientGetDebt(NULL) debt FROM basket o
FROM basket o JOIN vn.agencyMode ag ON ag.id = o.agency_id
JOIN vn.agencyMode ag ON ag.id = o.agency_id LEFT JOIN myAddress ad ON ad.id = o.address_id
LEFT JOIN myAddress ad ON ad.id = o.address_id JOIN vn.deliveryMethod v ON v.id = o.delivery_method_id
JOIN vn.deliveryMethod v ON v.id = o.delivery_method_id JOIN myClient c
JOIN myClient c JOIN (
JOIN ( SELECT
SELECT IFNULL(SUM(taxBase), 0) taxBase,
IFNULL(SUM(taxBase), 0) taxBase, IFNULL(SUM(tax + equalizationTax), 0) tax
IFNULL(SUM(tax + equalizationTax), 0) tax 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,29 +1,34 @@
<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
<div> </h1>
<htk-grid show-header="false"> <div id="main" class="invoices">
<db-model property="model" id="tickets"> <div class="card form">
<custom> <div>
<label>_Show invoices from</label>
<htk-date-chooser lot="params" name="from"/>
</div>
</div>
<div class="card">
<htk-grid show-header="false">
<db-model property="model" lot="params">
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 </db-model>
</custom> <htk-column-text title="_Serial" column="serial_num"/>
</db-model> <htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
<htk-column-text title="_Serial" column="serial_num"/> <htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/> <htk-column-button
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/> column="invoice_id"
<htk-column-button icon="download"
column="invoice_id" tip="_Download PDF"
icon="download" on-clicked="onDownloadClick"/>
tip="_Download PDF" </htk-grid>
on-clicked="onDownloadClick"/>
</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> CALL myTicketGet(#ticket)
<item name="ticket" param="ticket-id"/> </db-lot>
</custom> <h1 id="title">
</sql-batch> _OrderDetail
<db-form id="ticket" on-ready="onTicketReady"> </h1>
<db-model id="ticket-data" property="model" batch="batch">
<custom>
CALL myTicketGet (#ticket)
</custom>
</db-model>
</db-form>
</vn-group>
<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" CALL myTicketGetRows(#ticket)
id="movements"
batch="batch">
<custom>
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> <htk-text id="subtotal" format="%.2d€"/>
<p class="subtotal"> </span>
<htk-text id="subtotal" format="%.2d€"/>
</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,13 +24,13 @@ 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"
+"| bullist numlist outdent indent" +" | bullist numlist outdent indent"
+"| styleselect | fontselect fontsizeselect" +" | styleselect | fontselect fontsizeselect"
+"| forecolor backcolor" +" | forecolor backcolor"
,image_advtab: true ,image_advtab: true
,init_instance_callback : this._onEditorInit.bind (this) ,init_instance_callback : this._onEditorInit.bind (this)
}); });
@ -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,32 +26,28 @@
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>
<div class="form-group"> <label>_Tag</label>
<label><t>Tag</t></label> <htk-combo lot="iter" name="tag">
<htk-combo form="iter" column="tag"> <db-model property="model">
<db-model property="model"> SELECT name, description FROM newsTag
<custom> ORDER BY description
SELECT name, description FROM newsTag </db-model>
ORDER BY description </htk-combo>
</custom> </div>
</db-model> <div>
</htk-combo> <label>_Priority</label>
</div> <htk-entry lot="iter" name="priority"/>
<div class="form-group"> </div>
<label><t>Priority</t></label> <div>
<htk-entry form="iter" column="priority"/> <label>_NewBody</label>
</div> <textarea id="html-editor"/>
<div class="form-group">
<label><t>NewBody</t></label>
<textarea id="html-editor"/>
</div>
</div> </div>
</div> </div>
</div> </div>

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">
<htk-button <div class="actions">
form="iter" <htk-button
column="id" lot="iter"
tip="_EditNew" tip="_Remove"
icon="edit" icon="delete"
on-click="onEditClick"/> on-click="onDeleteClick"/>
<htk-button </div>
form="iter"
column="id"
tip="_Remove"
icon="delete"
on-click="onDeleteClick"/>
<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