Vn.Builder: Soporte de eventos, Htk.Repeater: Más funcionalidad

This commit is contained in:
Juan Ferrer Toribio 2015-03-27 20:10:49 +01:00
parent 0a738a55d7
commit bf0e92c711
90 changed files with 1481 additions and 526 deletions

View File

@ -1,5 +1,5 @@
Package: hedera-web
Version: 1.0-43
Version: 1.0-44
Architecture: all
Maintainer: Juan Ferrer Toribio <juan@verdnatura.es>
Depends: apache2, php5-mysql, php-vn-web

View File

@ -5,10 +5,10 @@ Vn.Address = new Class
,activate: function ()
{
this.$('return').addEventListener ('click', this.onReturnClick.bind (this));
this.$('accept').addEventListener ('click', this.onAcceptClick.bind (this));
this.$('iter').on ('status-changed', this.onStatusChange, this);
this.$('model').on ('operations-done', this.onOperationsDone, this);
this.$('model').mode = Db.Model.Mode.ON_DEMAND;
this.$('model').setInfo ('a', 'address_view', 'hedera', ['id'], 'id');
this.$('model').setDefault ('customer_id', 'a',
new Sql.Func ({schema: 'account', name: 'user_get_id'}));
}
,onStatusChange: function (form)
@ -19,7 +19,7 @@ Vn.Address = new Class
,onOperationsDone: function ()
{
(new Htk.Toast ()).showMessage (_('ConsigneeChangedSuccessfully'));
(new Htk.Toast ()).showMessage (_('AddressChangedSuccessfully'));
this.onReturnClick ();
}

View File

@ -3,10 +3,10 @@
<vn-param id="address">
<vn-hash-link key="address"/>
</vn-param>
<db-form id="iter">
<db-model id="model">
<db-form id="iter" on-status-changed="onStatusChange">
<db-model id="model" updatable="true" on-operations-done="onOperationsDone">
SELECT id, name, consignee, city, zip_code, province_id
FROM address_view
FROM address_view a
WHERE active != FALSE AND id = #address
<sql-batch property="batch">
<item name="address" param="address"/>
@ -17,13 +17,13 @@
<div id="form" class="address">
<div class="box">
<div class="header">
<h1><t>EditConsignee</t></h1>
<h1><t>EditAddress</t></h1>
<div class="action-bar">
<button id="return">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button id="accept">
<button on-click="onAcceptClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>
@ -31,23 +31,23 @@
</div>
<div class="body">
<div class="form-group">
<label><t>Name:</t></label>
<label><t>Name</t></label>
<htk-entry column="consignee" form="iter"/>
</div>
<div class="form-group">
<label><t>Adress:</t></label>
<label><t>Address</t></label>
<htk-entry column="name" form="iter"/>
</div>
<div class="form-group">
<label><t>City:</t></label>
<label><t>City</t></label>
<htk-entry column="city" form="iter"/>
</div>
<div class="form-group">
<label><t>ZipCode:</t></label>
<label><t>ZipCode</t></label>
<htk-entry column="zip_code" form="iter"/>
</div>
<div class="form-group">
<label><t>Province:</t></label>
<label><t>Province</t></label>
<htk-combo column="province_id" form="iter">
<db-model property="model">
SELECT province_id, name FROM vn2008.province

View File

@ -5,23 +5,9 @@ Vn.Conf = new Class
,activate: function ()
{
var model = this.$('user-model');
model.setTableInfo ('u', 'user_view');
model.setTableInfo ('c', 'customer_view');
this.$('user-form').on ('iter-changed', this.onUserDataReady, this);
this.$('new-password').addEventListener ('change', this.onPasswordChange.bind (this));
this.$('repeat-password').addEventListener ('change', this.onPasswordChange.bind (this));
this.$('user-name').addEventListener ('change', this.onUserChange.bind (this));
this.$('add').addEventListener ('click', this.onAddClick.bind (this));
}
,onAddClick: function ()
{
this.hash.set ({
'form': 'account/address',
'address': 0
});
this.$('user-model').setInfo ('u', 'user_view', 'hedera');
this.$('user-model').setInfo ('c', 'customer_view', 'hedera');
this.$('addresses').setInfo ('a', 'address_view', 'hedera');
}
,onUserDataReady: function (form)
@ -90,5 +76,30 @@ Vn.Conf = new Class
,Vn.Cookie.check ('vn_pass')
);
}
,onAddAddressClick: function ()
{
this.hash.set ({
'form': 'account/address',
'address': 0
});
}
,onRemoveAddressClick: function (button, form)
{
if (confirm (_('AreYouSureDeleteAddress')))
{
form.set ('active', false);
form.refresh ();
}
}
,onEditAddressClick: function (button, form)
{
this.hash.set ({
'form': 'account/address',
'address': form.get ('id')
});
}
});

View File

@ -32,11 +32,15 @@
{
margin-bottom: 0.5em;
}
.consignee
.address
{
margin-bottom: 1em;
}
.consignee p
.address p
{
margin: 0.2em 0;
}
.address .actions
{
text-align: right;
}

View File

@ -1,15 +1,15 @@
<vn>
<vn-group>
<db-form id="user-form">
<db-model id="user-model">
SELECT id, u.name, email, mail, c.user_id
<db-form id="user-form" on-iter-changed="onUserDataReady">
<db-model id="user-model" updatable="true">
SELECT id, u.name, email, mail, c.user_id, c.default_address
FROM user_view u
LEFT JOIN customer_view c
ON u.id = c.user_id
</db-model>
</db-form>
<db-model id="consignees">
SELECT id, consignee, p.name province, zip_code, city, a.name
<db-model id="addresses" updatable="true">
SELECT id, consignee, p.name province, zip_code, city, a.name, active
FROM address_view a
JOIN vn2008.province p ON a.province_id = p.province_id
WHERE active != FALSE
@ -27,12 +27,23 @@
</div>
<div class="form-group">
<label for="user-name"><t>UserName</t></label>
<input type="text" id="user-name"/>
<input
id="user-name"
type="text"
on-change="onUserChange"/>
</div>
<div class="form-group">
<label for="user-pass"><t>Password</t></label>
<input type="password" id="new-password" placeholder="_NewPassword"/>
<input type="password" id="repeat-password" placeholder="_RepeatPassword"/>
<input
id="new-password"
type="password"
placeholder="_NewPassword"
on-change="onPasswordChange"/>
<input
id="repeat-password"
type="password"
placeholder="_RepeatPassword"
on-change="onPasswordChange"/>
</div>
<div class="form-group">
<label for="email"><t>Email</t></label>
@ -46,18 +57,29 @@
</div>
<div class="box">
<div class="header">
<h1><t>Consignees</t></h1>
<h1><t>Addresses</t></h1>
<div class="action-bar">
<button id="add">
<button on-click="onAddAddressClick">
<img src="image/dark/add.svg" alt=""/>
<t>Add</t>
<t>AddAddress</t>
</button>
</div>
</div>
<div class="form">
<htk-repeater model="consignees" form-id="iter">
<div class="consignee">
<h2><htk-text form="iter" column="consignee"/></h2>
<htk-radio-group
id="default-address"
column="default_address"
form="user-form"/>
<htk-repeater model="addresses" form-id="iter">
<div class="address">
<h2>
<htk-radio
form="iter"
column="id"
radio-group="default-address"
tip="_SetAsDefault"/>
<htk-text form="iter" column="consignee"/>
</h2>
<p>
<htk-text form="iter" column="name"/>
</p>
@ -68,6 +90,20 @@
<p>
<htk-text form="iter" column="province"/>
</p>
<div class="actions">
<htk-button
form="iter"
column="id"
tip="_RemoveAddress"
image="image/delete.svg"
on-click="onRemoveAddressClick"/>
<htk-button
form="iter"
column="id"
tip="_EditAddress"
image="image/edit.svg"
on-click="onEditAddressClick"/>
</div>
</div>
</htk-repeater>
</div>

View File

@ -2,15 +2,5 @@
Vn.AccessLog = new Class
({
Extends: Vn.Module
,activate: function ()
{
// this.$('return').on ('clicked', this.returnClicked.bind (this));
}
,returnClicked: function (column, value)
{
this.hash.set ({'module': 'admin/users'});
}
});

View File

@ -4,7 +4,7 @@
<vn-hash-link key="user"/>
</vn-param>
<db-form id="user-form">
<db-model updatable="false">
<db-model>
SELECT Id_Cliente, Cliente, Telefono, movil
FROM vn2008.Clientes WHERE Id_Cliente = #user
<sql-batch property="batch">
@ -25,7 +25,7 @@
<label><t>UserNumber:</t></label>
</td>
<td>
<htk-label column="Id_Cliente" form="user-form"/>
<htk-text column="Id_Cliente" form="user-form"/>
</td>
</tr>
<tr>
@ -33,7 +33,7 @@
<label><t>User:</t></label>
</td>
<td>
<htk-label column="Cliente" form="user-form"/>
<htk-text column="Cliente" form="user-form"/>
</td>
</tr>
<tr>
@ -41,7 +41,7 @@
<label><t>Phone:</t></label>
</td>
<td>
<htk-label column="Telefono" form="user-form"/>
<htk-text column="Telefono" form="user-form"/>
</td>
</tr>
<tr>
@ -49,14 +49,14 @@
<label><t>Mobile:</t></label>
</td>
<td>
<htk-label column="movil" form="user-form"/>
<htk-text column="movil" form="user-form"/>
</td>
</tr>
</tbody>
</table>
<div>
<htk-grid id="access">
<db-model updatable="false">
<htk-grid>
<db-model>
SELECT u.date_time, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visit_user u
JOIN visit_access c ON u.access_id = c.id

View File

@ -7,8 +7,6 @@ Vn.Photos = new Class
{
this.$('schema').value = 'catalog';
this.$('photo-size').value = 10 /* MB */ * 1048576;
this.$('photo-form').addEventListener ('submit', this.onFormSubmit.bind (this));
this.$('iframe').addEventListener ('load', this.onImageUpload.bind (this));
this.$('photo-id').focus ();
}
@ -19,7 +17,7 @@ Vn.Photos = new Class
this.gui.loaderPush ();
}
,onImageUpload: function (iframe)
,onImageUpload: function ()
{
var toast = new Htk.Toast ();

View File

@ -5,7 +5,12 @@
<h1><t>Photos</t></h1>
</div>
<div class="body">
<form action="rest.php?action=image" method="post" enctype="multipart/form-data" target="photos-iframe" id="photo-form">
<form
method="post"
enctype="multipart/form-data"
action="rest.php?action=image"
target="photos-iframe"
on-submit="onFormSubmit">
<div class="form-group">
<label><t>Id:</t></label>
<input type="number" name="id" id="photo-id"/>
@ -28,11 +33,14 @@
<input type="file" name="image"/>
<input type="hidden" name="MAX_FILE_SIZE" id="photo-size"/>
</div>
<button class="vn" id="submit">
<button class="button" id="submit">
<t>Upload</t>
</button>
</form>
<iframe name="photos-iframe" id="iframe"></iframe>
<iframe
id="iframe"
name="photos-iframe"
on-load="onImageUpload"/>
</div>
</div>
</div>

View File

@ -19,8 +19,8 @@
</tbody>
</table>
<div>
<htk-grid id="users-grid">
<db-model updatable="false">
<htk-grid>
<db-model>
SELECT u.id, u.name, c.Cliente
FROM account.user u
INNER JOIN vn2008.Clientes c ON u.id = c.Id_Cliente
@ -32,8 +32,16 @@
<item name="user" param="user-name"/>
</sql-batch>
</db-model>
<htk-column-button image="image/supplant.png" tip="_AccessAsUser" column="id" id="change-user"/>
<htk-column-button image="image/access-log.svg" tip="_AccessLog" column="id" id="access-log"/>
<htk-column-button
column="id"
image="image/supplant.png"
tip="_AccessAsUser"
on-clicked="onChangeUserClick"/>
<htk-column-button
column="id"
image="image/access-log.svg"
tip="_AccessLog"
on-clicked="onAccessLogClick"/>
<htk-column-spin title="_UserNumber" column="id"/>
<htk-column-text title="_UserName" column="name"/>
<htk-column-text title="_Alias" column="Cliente"/>

View File

@ -3,13 +3,7 @@ Vn.Users = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('change-user').on ('clicked', this.changeUserClicked.bind (this));
this.$('access-log').on ('clicked', this.accessLogClicked.bind (this));
}
,changeUserClicked: function (column, value)
,onChangeUserClick: function (column, value)
{
var batch = new Sql.Batch ();
batch.addValue ('user', value);
@ -18,7 +12,7 @@ Vn.Users = new Class
this.conn.execQuery (query, this.userChanged.bind (this), batch);
}
,accessLogClicked: function (column, value)
,onAccessLogClick: function (column, value)
{
this.hash.set ({
'form': 'admin/access-log'

View File

@ -4,15 +4,15 @@
<div class="header">
<h1><t>VisitsManagement</t></h1>
<div class="action-bar">
<button id="refresh">
<button on-click="onRefreshClick">
<img src="image/dark/refresh.svg" alt=""/>
<t>Refresh</t>
</button>
<button id="sessions-button">
<button on-click="onSessionsClick">
<img src="image/dark/user-info.svg" alt=""/>
<t>ActiveSessions</t>
</button>
<button id="visits-button">
<button on-click="onVisitsClick">
<img src="image/dark/graph.svg" alt=""/>
<t>VisitsQuery</t>
</button>
@ -45,7 +45,7 @@
</table>
<div>
<htk-grid>
<db-model updatable="false" id="sessions">
<db-model id="sessions">
SELECT s.id, c.Cliente, e.date_time login, is_new,
s.date_time last_activity, a.platform, a.browser, a.version
FROM user_session s

View File

@ -5,12 +5,9 @@ Vn.Visits = new Class
,activate: function ()
{
this.$('refresh').addEventListener ('click', this.refreshClicked.bind (this));
this.$('sessions-button').addEventListener ('click', this.sessionsClicked.bind (this));
this.$('visits-button').addEventListener ('click', this.visitsClicked.bind (this));
this.$('date-to').value = new Date ();
this.$('num-sessions').func = this.sessionsFunc;
this.sessionsClicked ();
this.onSessionsClick ();
}
,showStep: function (stepId)
@ -22,23 +19,23 @@ Vn.Visits = new Class
this.currentStep.style.display = 'inline';
}
,sessionsClicked: function ()
,onRefreshClick: function ()
{
this.model.refresh ();
}
,onSessionsClick: function ()
{
this.showStep ('sessions-step');
this.model = this.$('sessions');
}
,visitsClicked: function ()
,onVisitsClick: function ()
{
this.showStep ('visits-step');
this.model = this.$('visits');
}
,refreshClicked: function ()
{
this.model.refresh ();
}
,sessionsFunc: function ()
{
return 1;

View File

@ -3,11 +3,6 @@ Vn.Packages = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('column-show').on ('clicked', this.onShowClick, this);
}
,onShowClick: function (column, agencyId)
{
this.hash.set ({

View File

@ -8,7 +8,11 @@
<db-model property="model">
CALL vn2008.agencia_volume ()
</db-model>
<htk-column-button image="image/show.svg" tip="_ShowByProvince" column="agency_id" id="column-show"/>
<htk-column-button
column="agency_id"
image="image/show.svg"
tip="_ShowByProvince"
on-clicked="onShowClick"/>
<htk-column-text title="_Agency" column="Agencia"/>
<htk-column-spin title="_Exps" column="expediciones"/>
<htk-column-spin title="_Bundles" column="Bultos"/>

View File

@ -44,7 +44,7 @@
<p>
<t>AllFieldsMandatory</t>
</p>
<button class="vn">
<button class="button">
<t>Send</t>
</button>
</form>

View File

@ -7,11 +7,6 @@ Vn.Basket = new Class
,activate: function ()
{
// Connecting buttons events
this.$('go-catalog').addEventListener ('click', this.catalogClicked.bind (this));
this.$('checkout-button').addEventListener ('click', this.checkoutClicked.bind (this));
// Loading order
this.orderId = this.$('order-id');
@ -32,22 +27,19 @@ Vn.Basket = new Class
// Configuring columns
var amount = this.$('column-amount');
amount.on ('changed', this.amountChanged.bind (this));
amount.renderer = this.amountRender;
this.$('column-amount').renderer = this.amountRender;
this.$('column-subtotal').renderer = this.subtotalRender.bind (this);
this.$('stems').renderer = this.stemsRender.bind (this);
this.$('order-total').func = this.subtotal;
}
,catalogClicked: function ()
,onCatalogClick: function ()
{
Vn.Cookie.set ('order', this.orderId.value);
this.hash.set ({'form': 'ecomerce/catalog'});
}
,checkoutClicked: function ()
,onCheckoutClick: function ()
{
this.hash.set ({
'form': 'ecomerce/checkout',
@ -80,7 +72,7 @@ Vn.Basket = new Class
renderer.value = null;
}
,amountChanged: function (renderer, row, newValue)
,onAmountChange: function (renderer, row, newValue)
{
var model = this.$('order-rows');
model.set (row, 'amount', newValue * model.get (row, 'grouping'));

View File

@ -4,7 +4,7 @@
<vn-hash-link key="order"/>
</vn-param>
<db-form id="order-form">
<db-model>
<db-model updatable="true">
SELECT date_send, type_id, wh_id, note, insurance, address_id, id
FROM order_view WHERE id = #id
<sql-batch property="batch">
@ -21,11 +21,11 @@
<div class="header">
<h1><t>ShoppingBasket</t></h1>
<div class="action-bar">
<button id="go-catalog">
<button on-click="onCatalogClick">
<img src="image/dark/menu.svg" alt=""/>
<t>GoToCatalog</t>
</button>
<button id="checkout-button">
<button on-click="onCheckoutClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Checkout</t>
</button>
@ -78,7 +78,7 @@
</tbody>
</table>
<htk-grid>
<db-model result-index="1" id="order-rows">
<db-model result-index="1" id="order-rows" updatable="true">
CALL item (#warehouse, #date);
SELECT m.id, i.grouping, m.amount, available, Article, Categoria, Medida,
Tallos, Color, o.Abreviatura, price, discount, fixed, Foto
@ -95,7 +95,7 @@
</sql-batch>
</db-model>
<htk-column-image column="Foto" directory="catalog" subdir="30x30" show-full="true"/>
<htk-column-spin title="_Amount" editable="true" id="column-amount"/>
<htk-column-spin title="_Amount" editable="true" id="column-amount" on-changed="onAmountChange"/>
<htk-column-text title="_Pack" column="grouping" format="x%.0d"/>
<htk-column-spin title="_Stems" column="amount" id="stems" editable="true"/>
<htk-column-spin title="_Avail" column="available"/>

View File

@ -7,23 +7,12 @@ Vn.Catalog = new Class
,activate: function ()
{
var model = this.$('items-model');
model.setTableInfo ('m', 'order_row_view');
model.setFieldFlags ('id', Db.Conn.Flag.AI);
model.setFieldFlags ('Id_Article', Db.Conn.Flag.PRI_KEY);
this.$('items-model').setInfo ('m', 'order_row_view', 'hedera', ['id'], 'id');
this.$('price').renderer = this.priceRenderer;
this.$('type-column').renderer = this.typeRenderer.bind (this);
this.$('cat').renderer = this.catRenderer;
this.$('basket-button').addEventListener ('click', this.basketClicked.bind (this));
this.$('menu-button').addEventListener ('click', this.showMenu.bind (this));
this.$('menu').addEventListener ('click', this.onMenuClick.bind (this));
this.$('search-entry').addEventListener ('change', this.onSearch.bind (this));
this.$('realms-model').on ('status-changed', this.onRealmsReload.bind (this));
this.$('realms').on ('changed', this.onRealmChanged.bind (this));
this.$('types-model').on ('status-changed', this.onTypesReload.bind (this));
this.$('type').on ('changed', this.onTypeChanged.bind (this));
this.$('order-form').on ('status-changed', this.orderFormChanged.bind (this));
this.$('warehouse').value = 1;
this.$('date').value = new Date ();
@ -39,12 +28,12 @@ Vn.Catalog = new Class
{
if (status == Db.Model.Status.READY)
{
this.onRealmChanged ();
this.onTypeChanged ();
this.onRealmChange ();
this.onTypeChange ();
}
}
,onRealmChanged: function ()
,onRealmChange: function ()
{
var color;
var realms = this.$('realms-model');
@ -62,7 +51,7 @@ Vn.Catalog = new Class
this.refreshTitle ();
}
,onTypeChanged: function ()
,onTypeChange: function ()
{
if (Vn.isMobile ())
this.hideMenu ();
@ -126,7 +115,7 @@ Vn.Catalog = new Class
event.stopPropagation ();
}
,showMenu: function (event)
,onShowMenuClick: function (event)
{
event.stopPropagation ();
this.gui.showBackground ();
@ -188,13 +177,13 @@ Vn.Catalog = new Class
this.$('basket-button').disabled = false;
}
,orderFormChanged: function (form)
,onOrderFormChange: function (form)
{
if (form.ready)
this.configureView ();
}
,basketClicked: function ()
,onBasketClick: function ()
{
this.hash.set ({'form': 'ecomerce/basket'});
}

View File

@ -40,11 +40,9 @@
/* Topbar */
.catalog .topbar
.catalog .action-bar
{
float: right;
max-width: 15em;
margin: 0 auto;
}
.catalog .search
{

View File

@ -1,16 +1,16 @@
<vn>
<vn-group>
<vn-param id="type">
<vn-param id="type" on-changed="onTypeChange">
<vn-hash-link key="type"/>
</vn-param>
<vn-param id="order"/>
<vn-param id="search"/>
<db-model id="realms-model">
<db-model id="realms-model" on-status-changed="onRealmsReload">
SELECT id, reino, color FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</db-model>
<db-form id="order-form">
<db-model>
<db-form id="order-form" on-status-changed="onOrderFormChange">
<db-model updatable="true">
SELECT date_send, wh_id, id FROM order_view WHERE id = #order
<sql-batch property="batch" id="order-batch"/>
</db-model>
@ -25,7 +25,7 @@
<sql-search-tags param="search"/>
</sql-filter-item>
</sql-filter>
<db-model result-index="1" main-table="m" updatable="false" id="items-model">
<db-model result-index="1" main-table="m" id="items-model">
CALL item (#warehouse, #date);
SELECT i.grouping, m.amount, Foto, i.available, Article, Categoria,
Medida, Tallos, Color, o.Abreviatura, price, fixed, m.id, Id_Article
@ -51,18 +51,73 @@
<div class="main">
<div class="box">
<div id="header" class="header">
<button id="menu-button" class="menu">
<button class="menu" on-click="onShowMenuClick">
<img src="image/dark/menu.svg" alt="_Menu"/>
</button>
<h1 id="title"><t>Catalog</t></h1>
<div class="topbar">
<div class="action-bar">
<div class="search">
<img src="image/search.svg" alt="_Search" class="icon"/>
<input type="text" id="search-entry"/>
<input type="text" id="search-entry" on-change="onSearch"/>
</div>
</div>
</div>
<!-- <htk-repeater model="items-model" form-id="item">
<htk-grid empty-message="_SelectSubtype" id="items-grid" class="items" model="items-model">
<htk-column-image title="*" column="Foto" directory="catalog" subdir="200x200" show-full="true" editable="true"/>
<htk-column-text title="_Pack" column="grouping" format="x%.0d"/>
<htk-column-spin title="_Aval" column="available"/>
<htk-column-text title="_Name" column="Article"/>
<htk-column-text title="_Cat" column="Categoria" id="cat"/>
<htk-column-text title="_S1" column="Medida"/>
<htk-column-text title="_Color" column="Color"/>
<htk-column-text title="_Tallos" column="Tallos"/>
<htk-column-text title="_Origin" column="Abreviatura"/>
<htk-column-text title="_Price" column="price" digits="2" unit="€" id="price"/>
</htk-grid>
<p class="footer-message">
<t>IndicativePhotos</t>
</p>
</div>
</div>
</div>
<div id="menu" class="menu" on-click="onMenuClick">
<button disabled="true" id="basket-button" class="basket" on-click="onBasketClick">
<t>StartOrder</t>
</button>
<div class="form-group">
<htk-date-chooser>
<vn-param id="date"/>
</htk-date-chooser>
</div>
<div class="form-group">
<htk-combo>
<db-model property="model">
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</db-model>
<vn-param id="warehouse"/>
</htk-combo>
</div>
<htk-realm id="realms" model="realms-model" on-changed="onRealmChange">
<vn-param id="realm">
<vn-hash-link key="realm"/>
</vn-param>
</htk-realm>
<div class="types-box">
<htk-grid class="types" empty-message="_SelectFamily">
<db-model id="types-model" on-status-changed="onTypesReload">
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #realm AND Orden != 0 ORDER BY Orden DESC, Tipo
<sql-batch property="batch">
<item name="realm" param="realm"/>
</sql-batch>
</db-model>
<htk-column-link title="_Subtype" column="Tipo" id="type-column"/>
</htk-grid>
</div>
</div>
</div>
<htk-repeater id="grid-view" form-id="item">
<div class="item-box">
<div class="image">
<div>
@ -94,60 +149,5 @@
</p>
<div class="clear"/>
</div>
</htk-repeater>
--> <htk-grid empty-message="_SelectSubtype" id="items-grid" class="items" model="items-model">
<htk-column-image title="*" column="Foto" directory="catalog" subdir="200x200" show-full="true" editable="true"/>
<htk-column-text title="_Pack" column="grouping" format="x%.0d"/>
<htk-column-spin title="_Aval" column="available"/>
<htk-column-text title="_Name" column="Article"/>
<htk-column-text title="_Cat" column="Categoria" id="cat"/>
<htk-column-text title="_S1" column="Medida"/>
<htk-column-text title="_Color" column="Color"/>
<htk-column-text title="_Tallos" column="Tallos"/>
<htk-column-text title="_Origin" column="Abreviatura"/>
<htk-column-text title="_Price" column="price" digits="2" unit="€" id="price"/>
</htk-grid>
<p class="footer-message">
<t>IndicativePhotos</t>
</p>
</div>
</div>
</div>
<div id="menu" class="menu">
<button disabled="true" id="basket-button" class="basket">
<t>StartOrder</t>
</button>
<div class="form-group">
<htk-date-chooser>
<vn-param id="date"/>
</htk-date-chooser>
</div>
<div class="form-group">
<htk-combo>
<db-model property="model">
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</db-model>
<vn-param id="warehouse"/>
</htk-combo>
</div>
<htk-realm id="realms" model="realms-model">
<vn-param id="realm">
<vn-hash-link key="realm"/>
</vn-param>
</htk-realm>
<div class="types-box">
<htk-grid class="types" empty-message="_SelectFamily">
<db-model id="types-model">
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #realm AND Orden != 0 ORDER BY Orden DESC, Tipo
<sql-batch property="batch">
<item name="realm" param="realm"/>
</sql-batch>
</db-model>
<htk-column-link title="_Subtype" column="Tipo" id="type-column"/>
</htk-grid>
</div>
</div>
</div>
</htk-repeater>
</vn>

View File

@ -3,12 +3,6 @@ Vn.Checkout = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('go-basket').addEventListener ('click', this.goBasket.bind (this));
this.$('confirm-button').addEventListener ('click', this.confirmClicked.bind (this));
}
,goBasket: function ()
{
this.hash.set ({
@ -17,7 +11,7 @@ Vn.Checkout = new Class
});
}
,confirmClicked: function ()
,onConfirmClick: function ()
{
if (!confirm (_('SureConfirmOrder')))
return;
@ -42,5 +36,21 @@ Vn.Checkout = new Class
else
this.goBasket ();
}
,onAddAddressClick: function ()
{
this.hash.set ({
'form': 'account/address',
'address': 0
});
}
,onEditAddressClick: function (button, form)
{
this.hash.set ({
'form': 'account/address',
'address': form.get ('id')
});
}
});

View File

@ -1,7 +1,6 @@
.checkout
{
padding: 1em;
min-width: 50em;
}
.checkout .box
{
@ -9,10 +8,28 @@
margin: 0 auto;
}
/* Data */
.checkout td.label
table.form td.label
{
width: 10em;
width: 30%;
}
/* Addresses */
.addresses > .form
{
margin: 0 auto;
padding: 2em;
max-width: 25em;
}
.address
{
margin-bottom: 1em;
}
.address p
{
margin: 0.2em 0;
}
.address .actions
{
text-align: right;
}

View File

@ -4,7 +4,7 @@
<vn-hash-link key="order"/>
</vn-param>
<db-form id="order-form">
<db-model>
<db-model updatable="true">
SELECT type_id, note, insurance, address_id, id
FROM order_view WHERE id = #id
<sql-batch property="batch">
@ -15,17 +15,23 @@
<db-param column="wh_id" id="warehouse"/>
<db-param column="address_id" id="address"/>
</db-form>
<db-model id="addresses" updatable="true">
SELECT id, consignee, p.name province, zip_code, city, a.name, active
FROM address_view a
JOIN vn2008.province p ON a.province_id = p.province_id
WHERE active != FALSE
</db-model>
</vn-group>
<div id="form" class="checkout">
<div class="box">
<div class="header">
<h1><t>Checkout</t></h1>
<div class="action-bar">
<button id="go-basket">
<button on-click="goBasket">
<img src="image/dark/go-previous.svg" alt=""/>
<t>GoBasket</t>
</button>
<button id="confirm-button">
<button on-click="onConfirmClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Confirm</t>
</button>
@ -65,20 +71,53 @@
</tr>
</tbody>
</table>
<htk-grid>
<db-model updatable="false">
SELECT id, consignee, p.name province, zip_code, city, a.name
FROM address_view a
JOIN vn2008.province p ON a.province_id = p.province_id
WHERE active != FALSE
</db-model>
<htk-column-radio column="id" param="address"/>
<htk-column-text title="_Consignee" column="consignee"/>
<htk-column-text title="_Province" column="province"/>
<htk-column-text title="_PC" column="zip_code"/>
<htk-column-text title="_City" column="city"/>
<htk-column-text title="_Address" column="name"/>
</htk-grid>
</div>
</div>
<div class="box addresses">
<div class="header">
<h1><t>ShippingAddress</t></h1>
<div class="action-bar">
<button on-click="onAddAddressClick">
<img src="image/dark/add.svg" alt=""/>
<t>AddAddress</t>
</button>
</div>
</div>
<div class="form">
<htk-radio-group
id="default-address"
column="address_id"
form="order-form"/>
<htk-repeater model="addresses" form-id="iter">
<div class="address">
<h2>
<htk-radio
form="iter"
column="id"
radio-group="default-address"
tip="_SelectAddress"/>
<htk-text form="iter" column="consignee"/>
</h2>
<p>
<htk-text form="iter" column="name"/>
</p>
<p>
<htk-text form="iter" column="zip_code"/> -
<htk-text form="iter" column="city"/>
</p>
<p>
<htk-text form="iter" column="province"/>
</p>
<div class="actions">
<htk-button
form="iter"
column="id"
tip="_EditAddress"
image="image/edit.svg"
on-click="onEditAddressClick"/>
</div>
</div>
</htk-repeater>
</div>
</div>
</div>

View File

@ -5,17 +5,11 @@ Vn.Orders = new Class
,activate: function ()
{
this.$('pay-button').addEventListener ('click', this.onPayButtonClick.bind (this));
this.$('start-order').addEventListener ('click', this.onStartClick.bind (this));
this.$('company-pay').on ('clicked', this.onCompanyPayClick, this);
this.$('edit-order').on ('clicked', this.onContinueClick, this);
this.$('edit-ticket').on ('clicked', this.onShowClick, this);
this.$('ticket-pay').on ('clicked', this.onTicketPayClick, this);
this.$('ticket-pay').renderer = this.payRenderer;
this.$('debt-amount').conditionalFunc = this.debtConditionalFunc;
this.$('balance-amount').conditionalFunc = this.balanceConditionalFunc;
this.payPopup = new Htk.Popup ();
this.payPopup.setChildNode (this.$('debt-popup'));
this.payPopup.setChildNode (this.$('balance-popup'));
// Ends the transaction
@ -66,14 +60,14 @@ Vn.Orders = new Class
// TPV
,debtConditionalFunc: function (field, value)
,balanceConditionalFunc: function (field, value)
{
var className = 'debt-amount ';
var className = 'balance-amount ';
if (value > 0)
className += 'positive-debt';
className += 'positive-balance';
else
className += 'negative-debt';
className += 'negative-balance';
field.node.className = className;
}

View File

@ -36,40 +36,32 @@
/* Balance */
.debt
{
float: right;
}
.debt img
.balance img
{
vertical-align: middle;
padding-left: 0.3em;
cursor: pointer;
}
.pay-button
{
margin-left: 1.2em;
}
.debt-amount
.balance-amount
{
color: white;
padding: 0.3em;
}
.positive-debt
.positive-balance
{
background-color: #EF5350;
border-radius: 0.1em;
box-shadow: 0 0 0.4em #666;
}
.negative-debt
.negative-balance
{
color: white;
}
.debt-popup
.balance-popup
{
width: 25em;
}
.debt-grid
.balance-grid
{
width: 100%;
margin: auto;

View File

@ -4,7 +4,7 @@
<div class="header">
<h1><t>StartedOrdersDesc</t></h1>
<div class="action-bar">
<button id="start-order">
<button on-click="onStartClick">
<img src="image/dark/order.svg" alt=""/>
<t>StartOrder</t>
</button>
@ -12,12 +12,16 @@
</div>
<div>
<htk-grid>
<db-model>
<db-model updatable="true">
SELECT o.id, date_send, Agencia
FROM order_view o
JOIN vn2008.Agencias a ON o.type_id = a.Id_Agencia
</db-model>
<htk-column-button column="id" image="image/edit.svg" tip="_ContinueOrder" id="edit-order"/>
<htk-column-button
column="id"
image="image/edit.svg"
tip="_ContinueOrder"
on-clicked="onContinueClick"/>
<htk-column-spin title="_OrderNumber" column="id"/>
<htk-column-date title="_DateExit" column="date_send"/>
<htk-column-text title="_SendMethod" column="Agencia"/>
@ -27,13 +31,15 @@
<div class="box">
<div class="header">
<h1><t>ConfirmedOrdersDesc</t></h1>
<div class="debt">
<div class="action-bar">
<div id="balance">
<t>PendingBalance:</t>
<htk-label format="%.2d€" id="debt-amount">
<htk-label format="%.2d€" id="balance-amount">
<db-calc-sum model="balance" column-name="amount"/>
</htk-label>
<img src="image/dark/info.svg" title="_PaymentInfo" class="debt-info" alt="Info"/>
<button id="pay-button" class="pay-button" title="_MakePayment">
<img src="image/dark/info.svg" title="_PaymentInfo" class="balance-info" alt="Info"/>
</div>
<button id="pay-button" title="_MakePayment" on-click="onPayButtonClick">
<img src="image/dark/pay.svg" alt="_MakePayment"/>
</button>
</div>
@ -43,13 +49,21 @@
<db-model id="tickets">
CALL ticket_list ();
</db-model>
<htk-column-button column="ticket_id" image="image/show.svg" tip="_SeeOrder" id="edit-ticket"/>
<htk-column-button
column="ticket_id"
image="image/show.svg"
tip="_SeeOrder"
on-clicked="onShowClick"/>
<htk-column-spin title="_TicketNumber" column="ticket_id"/>
<htk-column-date title="_DateExit" column="date"/>
<htk-column-text title="_SendMethod" column="type"/>
<htk-column-text title="_SentAddress" column="consignee"/>
<htk-column-spin title="_TotalWithVAT" column="total" unit="€" digits="2"/>
<htk-column-button image="image/pay.svg" tip="_PayOrder" id="ticket-pay"/>
<htk-column-button
id="ticket-pay"
image="image/pay.svg"
tip="_PayOrder"
on-clicked="onTicketPayClick"/>
</htk-grid>
</div>
<form method="post" id="tpv-form">
@ -66,14 +80,14 @@
</form>
</div>
</div>
<div id="debt-popup" class="debt-popup">
<htk-grid class="debt-grid" updatable="false">
<div id="balance-popup" class="balance-popup">
<htk-grid class="balance-grid" updatable="false">
<db-model id="balance">
CALL customer_debt ();
</db-model>
<htk-column-text title="_Company" column="abbreviation"/>
<htk-column-spin title="_Pending" column="amount" unit="€" digits="2"/>
<htk-column-button title="_Pay" image="image/pay.svg" tip="Pay" id="company-pay"/>
<htk-column-button title="_Pay" image="image/pay.svg" tip="Pay" on-clicked="onCompanyPayClick"/>
</htk-grid>
</div>
</vn>

View File

@ -4,7 +4,7 @@
<vn-hash-link key="ticket"/>
</vn-param>
<db-form id="ticket">
<db-model id="ticket-data" updatable="false">
<db-model id="ticket-data">
SELECT t.id, date, a.Agencia, note, p.name province,
zip_code, city, c.name, consignee, invoice
FROM ticket_view t

View File

@ -5,16 +5,11 @@ Vn.New = new Class
,activate: function ()
{
this.$('html-editor').id = 'html-editor';
this.$('return').addEventListener ('click', this.onReturnClick.bind (this));
this.$('accept').addEventListener ('click', this.onAcceptClick.bind (this));
this.$('body').on ('changed', this.onBodyChange, this);
this.$('iter').on ('status-changed', this.onStatusChange, this);
this.$('model').on ('operations-done', this.onOperationsDone, this);
this.$('model').mode = Db.Model.Mode.ON_DEMAND;
this.$('model').setDefault ('user_id', 'news',
new Sql.Func ({schema: 'account', name: 'user_get_id'}));
this.$('html-editor').id = 'html-editor';
tinymce.init ({
mode : 'exact'
,elements : 'html-editor'

View File

@ -3,9 +3,9 @@
<vn-param id="new-id">
<vn-hash-link key="new"/>
</vn-param>
<db-form id="iter">
<db-param column="text" id="body"/>
<db-model id="model">
<db-form id="iter" on-status-changed="onStatusChange">
<db-param column="text" on-changed="onBodyChange"/>
<db-model id="model" updatable="true" on-operations-done="onOperationsDone">
SELECT id, title, text, tag
FROM news WHERE id = #new
<sql-batch property="batch">
@ -17,13 +17,13 @@
<div id="form" class="new">
<div class="box">
<div class="header">
<h1><t>AddNew</t></h1>
<h1><t>AddEditNew</t></h1>
<div class="action-bar">
<button id="return">
<button on-click="onReturnClick">
<img src="image/dark/go-previous.svg" alt=""/>
<t>Return</t>
</button>
<button id="accept">
<button on-click="onAcceptClick">
<img src="image/dark/ok.svg" alt=""/>
<t>Accept</t>
</button>

View File

@ -3,12 +3,6 @@ Vn.News = new Class
({
Extends: Vn.Module
,activate: function ()
{
this.$('edit-new').on ('clicked', this.onEditClick, this);
this.$('add-new').addEventListener ('click', this.onAddClick.bind (this));
}
,editNew: function (newId)
{
this.hash.set ({

View File

@ -4,22 +4,31 @@
<div class="header">
<h1><t>NewsManagement</t></h1>
<div class="action-bar">
<button id="add-new">
<button on-click="onAddClick">
<img src="image/dark/add.svg" alt=""/>
<t>AddNew</t>
</button>
</div>
</div>
<htk-grid>
<db-model id="news-model">
<db-model id="news-model" updatable="true">
SELECT n.id, c.Cliente, priority,
CONCAT(LEFT(n.title, 25), '...') title
FROM news n
JOIN vn2008.Clientes c ON n.user_id = c.Id_Cliente
ORDER BY priority, n.date_time DESC
</db-model>
<htk-column-button column="id" tip="_EditNew" image="image/edit.svg" id="edit-new"/>
<htk-column-image column="id" directory="news" subdir="30x30" show-full="true" editable="true"/>
<htk-column-button
column="id"
tip="_EditNew"
image="image/edit.svg"
on-clicked="onEditClick"/>
<htk-column-image
column="id"
directory="news"
subdir="30x30"
show-full="true"
editable="true"/>
<htk-column-text title="_Title" column="title"/>
<htk-column-text title="_Author" column="Cliente"/>
<htk-column-spin title="_Priority" column="priority"/>

View File

@ -140,7 +140,7 @@ input[type=submit],
input[type=button]
{
border: none;
background-color: #009688;
background-color: transparent;
color: white;
padding: 0.5em;
cursor: pointer;
@ -149,10 +149,10 @@ button:hover,
input[type=submit]:hover,
input[type=button]:hover
{
cursor: pointer;
background-color: #076;
background-color: #EEE;
}
button.vn
button.button,
input.button
{
border: none;
border-radius: 0.1em;
@ -160,7 +160,8 @@ button.vn
background-color: #AD4;
color: black;
}
button.vn:hover
button.button:hover,
input.button:hover
{
background-color: #9C3;
cursor: pointer;
@ -173,6 +174,13 @@ img.editable
cursor: pointer;
}
/* Button */
.htk-button img
{
height: 1.5em;
}
/* Date chooser */
.htk-date-chooser button
@ -231,19 +239,28 @@ div.action-bar
{
float: right;
padding: 0;
margin-top: 0.3em;
background-color: #009688;
}
div.action-bar button
div.action-bar > *
{
float: left;
padding: 0.4em;
border-left: 1px solid white;
}
div.action-bar button:first-child
div.action-bar > button
{
border-left: 1px solid white;
background-color: #009688;
}
div.action-bar > button:first-child
{
border-left: none;
}
div.action-bar img
div.action-bar > button:hover
{
background-color: #076;
}
div.action-bar > button > img
{
vertical-align: middle;
margin-right: 0.4em;

View File

@ -3,9 +3,9 @@
* updates, insertions and deletions on tables where the primary key is
* selected.
*
* Note that table names must be unique in the selection query, otherwise
* updates are not allowed. If two tables of different schemes
* have the same name, an alias should be used to solve this.
* Note that table and column names must be unique in the selection query,
* otherwise updates are not allowed on that table/column. If two tables or
* columns have the same name, an alias should be used to make it updatable.
**/
Db.Model = new Class ().extend
({
@ -129,7 +129,7 @@ Db.Model.implement
{
this._mainTable = null;
this.requestedMainTable = x;
this.refreshMainTable ();
this._refreshMainTable ();
}
,get: function ()
{
@ -146,7 +146,7 @@ Db.Model.implement
{
this._updatable = false;
this.requestedUpdatable = x;
this.refreshUpdatable ();
this._refreshUpdatable ();
}
,get: function ()
{
@ -199,26 +199,24 @@ Db.Model.implement
,tables: null
,columns: null
,columnMap: null
,_updatable: false
,sortColumn: -1
,sortWay: null
,requestedIndexes: {}
,indexes: []
,requestedUpdatable: false
,mode: Db.Model.Mode.ON_CHANGE
,operations: null
,operationsMap: null
,_insertedRow: -1
,defaults: []
,columnDefaults: []
,requestedMainTable: null
,requestedUpdatable: true
,initialize: function (props)
{
this.parent (props);
this._cleanData ();
this._resetOperations ();
this._setStatus (Db.Model.Status.CLEAN);
}
@ -232,6 +230,9 @@ Db.Model.implement
this.query = query;
}
/**
* Refresh the model data reexecuting the query on the database.
**/
,refresh: function ()
{
if (this._stmt && this._batch)
@ -268,9 +269,9 @@ Db.Model.implement
this.tables = dataResult.tables;
this.columns = dataResult.columns;
this.columnMap = dataResult.columnMap;
this.repairColumns (this.columns);
this._refreshRowIndexes ();
this.refreshMainTable ();
this._repairColumns ();
this._refreshRowIndexes (0);
this._refreshMainTable ();
for (column in this.requestedIndexes)
this._buildIndex (column);
@ -281,9 +282,9 @@ Db.Model.implement
this._setStatus (Db.Model.Status.ERROR);
}
,_refreshRowIndexes: function ()
,_refreshRowIndexes: function (start)
{
for (var i = 0; i < this.data.length; i++)
for (var i = start; i < this.data.length; i++)
this.data[i].index = i;
if (this.operationsMap)
@ -298,12 +299,14 @@ Db.Model.implement
,_cleanData: function (error)
{
this.data = null;
this.tables = null;
this.columns = null;
this.columnMap = null;
this.indexes = [];
this._resetOperations ();
}
,refreshUpdatable: function ()
,_refreshUpdatable: function ()
{
var oldValue = this._updatable;
this._updatable = this._mainTable !== null && this.requestedUpdatable;
@ -312,7 +315,7 @@ Db.Model.implement
this.signalEmit ('updatable-changed');
}
,refreshMainTable: function ()
,_refreshMainTable: function ()
{
var newMainTable = null;
var tables = this.tables;
@ -328,7 +331,7 @@ Db.Model.implement
}
this._mainTable = newMainTable;
this.refreshUpdatable ();
this._refreshUpdatable ();
}
/**
@ -391,7 +394,9 @@ Db.Model.implement
**/
,checkColExists: function (column)
{
return this.columns && column >= 0 && column < this.columns.length;
return this.columns
&& column >= 0
&& column < this.columns.length;
}
/**
@ -402,12 +407,22 @@ Db.Model.implement
**/
,checkRowExists: function (rowIndex)
{
return this.data && rowIndex >= 0 && rowIndex < this.data.length;
return this.data
&& rowIndex >= 0
&& rowIndex < this.data.length;
}
,checkRowUpdatable: function (rowIndex)
,_checkTableUpdatable: function (tableIndex)
{
return this.checkRowExists (rowIndex);
var tableUpdatable = this._updatable
&& tableIndex !== null
&& this.tables[tableIndex].pks.length > 0;
if (!tableUpdatable)
console.warn ("DbModel: Table %s is not updatable",
this.tables[tableIndex].name);
return tableUpdatable;
}
/**
@ -457,6 +472,8 @@ Db.Model.implement
if (index != -1)
this.setByIndex (rowIndex, index, value);
else
console.warn ('Db.Model: Column %s doesn\'t exist', columnName);
}
/**
@ -483,13 +500,13 @@ Db.Model.implement
**/
,setByIndex: function (rowIndex, col, value)
{
if (!(this.checkRowUpdatable (rowIndex) && this.checkColExists (col)))
if (!this.checkRowExists (rowIndex)
&& !this.checkColExists (col))
return;
var tableIndex = this.columns[col].table;
var pks = this.tables[tableIndex].pks;
if (pks.length == 0)
if (!this._checkTableUpdatable (tableIndex))
return;
var row = this.data[rowIndex];
@ -507,6 +524,7 @@ Db.Model.implement
if (!tableOp)
{
tableOp = Db.Model.Operation.UPDATE;
var pks = this.tables[tableIndex].pks;
for (var i = 0; i < pks.length; i++)
if (!row[pks[i]] && !op.oldValues[pks[i]])
@ -538,12 +556,42 @@ Db.Model.implement
**/
,deleteRow: function (rowIndex)
{
if (!this.checkRowUpdatable (rowIndex))
if (!this.checkRowExists (rowIndex)
|| !this._checkTableUpdatable (this._mainTable))
return;
var op = this._createOperation (rowIndex);
op.type |= Db.Model.Operation.DELETE;
if (!this.requestedMainTable)
{
this.signalEmit ('row-deleted-before', rowIndex);
this.data.splice (rowIndex, 1);
this.signalEmit ('row-deleted', rowIndex);
this._refreshRowIndexes (rowIndex);
}
else
{
this.signalEmit ('row-updated-before', rowIndex);
if (!op.oldValues)
op.oldValues = [];
var updatedCols = [];
for (var i = 0; i < this.columns.length; i++)
if (this.columns[i].table == this._mainTable)
{
if (op.oldValues[i] === undefined)
op.oldValues[i] = op.row[i];
op.row[i] = null;
updatedCols.push (i);
}
this.signalEmit ('row-updated', rowIndex, updatedCols);
}
if (this.mode === Db.Model.Mode.ON_CHANGE)
this.performOperations ();
}
@ -555,7 +603,7 @@ Db.Model.implement
**/
,insertRow: function ()
{
if (!this._updatable || this._insertedRow != -1)
if (!this._checkTableUpdatable (this._mainTable))
return -1;
var cols = this.columns;
@ -567,14 +615,15 @@ Db.Model.implement
else
newRow[i] = null;
this._insertedRow = this.data.push (newRow) - 1;
var rowIndex = this.data.push (newRow) - 1;
newRow.index = rowIndex;
var op = this._createOperation (this._insertedRow);
var op = this._createOperation (rowIndex);
op.type |= Db.Model.Operation.INSERT;
this.signalEmit ('row-inserted', this._insertedRow);
this.signalEmit ('row-inserted', rowIndex);
return this._insertedRow;
return rowIndex;
}
/**
@ -582,7 +631,9 @@ Db.Model.implement
**/
,performOperations: function ()
{
if (this.operations.length === 0)
var ops = this.operations;
if (ops.length === 0)
return;
var stmts = new Sql.MultiStmt ();
@ -590,10 +641,10 @@ Db.Model.implement
var query = new Sql.String ({query: 'START TRANSACTION'});
stmts.addStmt (query);
for (var i = 0; i < this.operations.length; i++)
for (var i = 0; i < ops.length; i++)
{
query = null;
var op = this.operations[i];
var op = ops[i];
if (op.type & Db.Model.Operation.DELETE)
{
@ -634,7 +685,9 @@ Db.Model.implement
stmts.addStmt (query);
this._conn.execStmt (stmts,
this._onOperationsDone.bind (this));
this._onOperationsDone.bind (this, ops));
this._resetOperations ();
}
,_createDmlQuery: function (op, tableIndex)
@ -650,14 +703,13 @@ Db.Model.implement
var select = new Sql.Select ({where: where});
select.addTarget (target);
var tableOp = op.tables[tableIndex];
var table = this.tables[tableIndex];
var row = op.row;
var cols = this.columns;
if (tableOp & Db.Model.Operation.INSERT)
if (op.tables[tableIndex] & Db.Model.Operation.INSERT)
{
var dmlQuery = new Sql.Insert ();
var table = this.tables[tableIndex];
for (var i = 0; i < this.defaults.length; i++)
{
@ -711,27 +763,34 @@ Db.Model.implement
return multiStmt;
}
,_onOperationsDone: function (resultSet)
,_onOperationsDone: function (ops, resultSet)
{
if (resultSet.getError ())
{
this.operations = this.operations.concat (ops);
for (var i = 0; i < ops.length; i++)
this.operationsMap[ops[i].row.index] = ops[i];
return;
}
var isOperation = false;
resultSet.fetchResult ();
for (var i = 0; i < this.operations.length; i++)
for (var i = 0; i < ops.length; i++)
{
var isOperation = true;
var op = this.operations[i];
var op = ops[i];
var row = op.row;
if (op.type & Db.Model.Operation.DELETE
&& op.type & Db.Model.Operation.INSERT)
isOperation = false;
if (!(op.type & Db.Model.Operation.DELETE
&& op.type & Db.Model.Operation.INSERT))
isOperation = true;
if (op.type & Db.Model.Operation.DELETE)
{
resultSet.fetchResult ();
this._performDelete (row);
}
else if (op.type & (Db.Model.Operation.INSERT | Db.Model.Operation.UPDATE))
{
@ -744,13 +803,11 @@ Db.Model.implement
{
var j = 0;
tableIndex = parseInt (tableIndex);
var tableOp = op.tables[tableIndex];
var table = this.tables[tableIndex];
resultSet.fetchResult ();
var newValues = resultSet.fetchRow ();
if (tableOp & Db.Model.Operation.INSERT)
if (op.tables[tableIndex] & Db.Model.Operation.INSERT)
{
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex)
@ -779,8 +836,6 @@ Db.Model.implement
if (isOperation)
this.signalEmit ('operations-done');
this._resetOperations ();
}
/**
@ -793,9 +848,11 @@ Db.Model.implement
var op = this.operations[i];
var row = op.row;
if (op.type & Db.Model.Operation.INSERT)
if (op.type & Db.Model.Operation.DELETE
&& !(op.type & Db.Model.Operation.INSERT))
{
this._performDelete (row);
this.data.splice (row.index, 0, row);
this.signalEmit ('row-inserted', row.index);
}
else if (op.type & Db.Model.Operation.UPDATE)
{
@ -816,6 +873,7 @@ Db.Model.implement
}
this._resetOperations ();
this._refreshRowIndexes (0);
}
,_resetOperations: function ()
@ -824,35 +882,10 @@ Db.Model.implement
this.operationsMap = {};
}
,_performDelete: function (row)
{
if (!this.requestedMainTable)
{
this.signalEmit ('row-deleted-before', row.index);
this.data.splice (row.index, 1);
this.signalEmit ('row-deleted', row.index);
}
else
{
this.signalEmit ('row-updated-before', row.index);
var updatedCols = [];
for (var i = 0; i < this.columns.length; i++)
if (this.columns[i].table == this._mainTable)
{
row[i] = null;
updatedCols.push (i);
}
this.signalEmit ('row-updated', row.index, updatedCols);
}
}
/*
* Function used to sort the model.
* Function used to sort the model ascending.
*/
,sortFunction: function (column, a, b)
,sortFunctionAsc: function (column, a, b)
{
if (a[column] < b[column])
return -1;
@ -862,10 +895,24 @@ Db.Model.implement
return 0;
}
/*
* Function used to sort the model descending.
*/
,sortFunctionDesc: function (column, a, b)
{
if (a[column] > b[column])
return -1;
else if (a[column] < b[column])
return 1;
return 0;
}
/**
* Orders the model by the specified column.
*
* @param {integer} column the column index
* @param {integer} column The column index
* @param {Db.Model.SortWay} way The sort way
**/
,sort: function (column, way)
{
@ -874,23 +921,31 @@ Db.Model.implement
this._setStatus (Db.Model.Status.LOADING);
if (column != this.sortColumn)
if (column !== this.sortColumn)
{
this.data.sort (this.sortFunction.bind (this, column));
this.sortColumn = column;
}
if (way === Db.Model.SortWay.DESC)
var sortFunction = this.sortFunctionDesc;
else
var sortFunction = this.sortFunctionAsc;
this.data.sort (sortFunction.bind (this, column));
}
else if (way !== this.sortWay)
this.data.reverse ();
this._refreshRowIndexes ();
this.sortColumn = column;
this.sortWay = way;
this._refreshRowIndexes (0);
this._setStatus (Db.Model.Status.READY);
}
/**
* Builds an internal hash index for the specified column, this speeds
* significantly searches on that column.
* Not implemented yet.
* significantly searches on that column, specially when model has a lot of
* rows.
*
* FIXME: Not fully implemented.
*
* @param {String} column The column name
**/
@ -898,7 +953,7 @@ Db.Model.implement
{
this.requestedIndexes[column] = true;
if (this._status == Db.Model.Status.READY)
if (this._status === Db.Model.Status.READY)
this._buildIndex (column);
}
@ -906,7 +961,7 @@ Db.Model.implement
{
var columnIndex = this.getColumnIndex (column);
if (columnIndex != -1)
if (columnIndex !== -1)
{
var index = {};
var data = this.data;
@ -931,6 +986,8 @@ Db.Model.implement
/**
* Searchs a value on the model and returns the row index of the first
* ocurrence.
* If an index have been built on that column, it will be used, for more
* information see the indexColumn() method.
*
* @param {String} column The column name
* @param {Object} value The value to search
@ -971,6 +1028,8 @@ Db.Model.implement
value = value.toString ();
}
// Searchs the value using an internal index.
var index = this.indexes[col];
if (index)
@ -981,6 +1040,8 @@ Db.Model.implement
return -1;
}
// Searchs the value using a loop.
var data = this.data;
switch (this.columns[col].type)
@ -1074,40 +1135,68 @@ Db.Model.implement
return op;
}
// Delete when MySQL FLAG and view orgname "bugs" are repaired:
,tableInfo: {}
,fieldFlags: {}
,setTableInfo: function (table, orgtable, db)
/**
* Overrides information about a table and its columns. If a parameter is
* not provided, the original will be preserved. This method should be used
* primarily to avoid the mysql bug that causes this information will not
* be set correctly.
* For more information see the following links:
* - https://bugs.mysql.com/bug.php?id=44660
* - https://bugs.mysql.com/bug.php?id=26894
*
* @param {String} table The table alias
* @param {String} orgtable The original table name
* @param {String} schema The original table schema
* @param {Array} pks Array with the names of primary keys
* @param {String} ai The autoincrement column name
**/
,setInfo: function (table, orgname, schema, pks, ai)
{
if (!this.tableInfo)
this.tableInfo = {};
this.tableInfo[table] =
({
orgtable: orgtable
,db: db
orgname: orgname,
schema: schema,
pks: pks,
ai: ai
});
this._repairColumns ();
}
,setFieldFlags: function (field, flags)
,_repairColumns: function ()
{
this.fieldFlags[field] = flags;
// Repairs wrong table info
if (this.tableInfo && this.tables)
for (var i = 0; i < this.tables.length; i++)
{
var table = this.tables[i];
var tableInfo = this.tableInfo[table.name];
if (!tableInfo)
continue;
table.orgname = tableInfo.orgname;
table.schema = tableInfo.shema;
if (tableInfo.pks)
{
table.pks = [];
for (var j = 0; j < tableInfo.pks.length; j++)
{
var colIndex = this.getColumnIndex (tableInfo.pks[j]);
table.pks.push (colIndex);
}
}
,repairColumns: function (columns)
if (tableInfo.ai)
{
for (var i = 0; i < columns.length; i++)
{
var newFlags = this.fieldFlags[columns[i].name];
if (newFlags)
columns[i].flags |= newFlags;
var tableInfo = this.tableInfo[columns[i].table];
if (tableInfo)
{
columns[i].orgtable = tableInfo.orgtable;
columns[i].db = tableInfo.db;
var colIndex = this.getColumnIndex (tableInfo.ai);
this.columns[colIndex].flags |= Db.Conn.Flag.AI;
}
}
}

View File

@ -0,0 +1,44 @@
Htk.Button = new Class
({
Extends: Htk.Field
,Tag: 'htk-button'
,Properties:
{
image:
{
type: String
,set: function (x)
{
this.img.src = x;
}
},
tip:
{
type: String
,set: function (x)
{
if (x)
{
this.node.title = _(x);
this.img.title = _(x);
}
}
}
}
,initialize: function (props)
{
this.parent (props);
this.createElement ('button');
this.node.className = 'htk-button';
this.node.addEventListener ('click', this.onClick.bind (this));
this.img = document.createElement ('img');
this.node.appendChild (this.img);
}
,onClick: function ()
{
this.signalEmit ('click', this._form);
}
});

View File

@ -8,10 +8,10 @@ Htk.Entry = new Class
this.parent (props);
this.createElement ('input');
this.node.type = 'text';
this.node.addEventListener ('change', this.changed.bind (this));
this.node.addEventListener ('change', this.onChange.bind (this));
}
,changed: function (event)
,onChange: function (event)
{
var newValue;

View File

@ -1,7 +1,7 @@
Htk.RadioGroup = new Class
({
Extends: Vn.Param
Extends: Htk.Field
,Tag: 'htk-radio-group'
,radioLock: false

View File

@ -1,57 +1,70 @@
Htk.Radio = new Class
({
Extends: Vn.Object,
Implements: Vn.Param
Extends: Htk.Field
,Tag: 'htk-radio'
,Properties:
{
tip:
{
type: String
,set: function (x)
{
if (x)
this.node.title = _(x);
}
},
radioGroup:
{
type: Htk.RadioGroup
,set: function (x)
{
this.link ({_radioGroup: x}, {'changed': this.onRadioGroupChange});
this.node.name = x.name
this.onRadioGroupChange ();
}
,get: function ()
{
return this._radioGroup;
}
}
}
,_radioGroup: null
,initialize: function (props)
{
this.parent (props);
this.rButton = new Array ();
this.uid = ++htkRadioUid;
var radio = Vn.Browser.createRadio ('');
radio.checked = false;
radio.addEventListener ('change', this.onChange.bind (this));
this.node = radio;
}
,newRadio: function (value)
,onChange: function ()
{
var radio;
var obj = this;
radio = createRadio (this.uid);
radio.value = value;
radio.checked = value == this.realValue;
radio.addEventListener ('change',
function () { obj.radioChanged (this._value); }, false);
this.rButton.push (radio);
return radio;
if (this.node.checked && this._radioGroup)
this._radioGroup.value = this.value;
}
,radioChanged: function (value)
,onRadioGroupChange: function ()
{
this.realValue = value;
this.signalEmit ('changed');
if (this._radioGroup.value == this.value)
this.node.checked = true;
else
this.node.checked = false;
}
,setRealValue: function (value)
,putValue: function (value)
{
var rButton = this.rButton;
for (var n = 0; n < rButton.length; n++)
{
if (rButton[n].value == value)
{
rButton[n].checked = true;
break;
}
}
if (!value)
this.node.value = '';
else
this.node.value = value;
}
,setEditable: function (editable)
{
var rButton = this.rButton;
for (var n = 0; n < rButton.length; n++)
rButton[n].disabled = !editable;
this.node.disabled = !editable;
}
});

View File

@ -3,14 +3,24 @@ Htk.ImageEditor = new Class
Extends: Htk.Widget
,Xml: 'js/htk/image-editor.xml'
,maxFileSize: 10 /* MB */ * 1048576
,initialize: function ()
{
this.builderInit (Htk.ImageEditor.Xml);
this.$('max-size').value = this.maxFileSize;
this.$('max-size').value = 10 /* MB */ * 1048576;
}
this.$('iframe').addEventListener ('load', function ()
,onNameChange: function ()
{
this.signalEmit ('name-changed', this.$('name').value);
}
,onFormSubmit: function ()
{
this.$('submit').disabled = true;
this.$('loader').style.visibility = 'visible';
}
,onIframeLoad: function ()
{
var toast = new Htk.Toast ();
@ -31,21 +41,6 @@ Htk.ImageEditor = new Class
}
catch (e) {}
}
.bind (this));
this.$('form').addEventListener ('submit', function ()
{
this.$('submit').disabled = true;
this.$('loader').style.visibility = 'visible';
}
.bind (this));
this.$('name').addEventListener ('change', function ()
{
this.signalEmit ('name-changed', this.$('name').value);
}
.bind (this));
}
,setData: function (image, directory)
{

View File

@ -1,10 +1,15 @@
<vn>
<div id="main" class="htk-image-editor">
<h2><t>UpdateImage</t></h2>
<form id="form" method="post" action="rest.php?action=image" target="image-editor" enctype="multipart/form-data">
<form
method="post"
action="rest.php?action=image"
target="image-editor"
enctype="multipart/form-data"
on-submit="onFormSubmit">
<div class="form-group">
<label for="name"><t>FileName</t></label>
<input id="name" type="text" name="name"/>
<input id="name" type="text" name="name" on-change="onNameChange"/>
</div>
<div class="form-group">
<label for="file"><t>File</t></label>
@ -12,11 +17,14 @@
</div>
<div class="footer">
<img id="loader" src="image/loader-black.gif" alt="Loading"/>
<input id="submit" type="submit"/>
<input id="submit" type="submit" class="button"/>
</div>
<input id="schema" type="hidden" name="schema"/>
<input id="max-size" type="hidden" name="MAX_FILE_SIZE"/>
</form>
<iframe id="iframe" name="image-editor"/>
<iframe
id="iframe"
name="image-editor"
on-load="onIframeLoad"/>
</div>
</vn>

View File

@ -9,13 +9,13 @@ Vn\Hedera\Js::includeLib ('htk'
,'toast'
,'repeater'
,'grid'
,'radio-group'
,'full-image'
,'image-editor'
,'field'
,'field/text'
,'field/html'
,'field/entry'
,'field/radio-group'
,'field/radio'
,'field/label'
,'field/text-area'
@ -25,6 +25,7 @@ Vn\Hedera\Js::includeLib ('htk'
,'field/calendar'
,'field/date-chooser'
,'field/image'
,'field/button'
,'field/table'
,'column'
,'column/button'

View File

@ -63,6 +63,7 @@ Htk.Repeater = new Class
,buildBox: function (index)
{
var builder = new Vn.Builder ();
builder.setParent (this.parentBuilder);
var form = new Db.Form ();
form.model = this._model;

View File

@ -24,6 +24,7 @@ Htk.Widget = new Class
,builderInit: function (path)
{
this.builder = new Vn.Builder ();
this.builder.signalData = this;
this.builder.loadXml (Vn.getXml (path));
this.node = this.builder.get ('main');
}

View File

@ -82,11 +82,24 @@ Vn.Builder = new Class
var a = node.attributes;
for (var i = 0; i < a.length; i++)
if (a[i].nodeName !== 'id')
htmlNode.setAttribute (a[i].nodeName,
this.translateValue (a[i].nodeValue));
{
var nodeName = a[i].nodeName;
var nodeValue = a[i].nodeValue;
this.registerObject (node, htmlNode);
if (/on-\w+/.test (nodeName))
{
var method = this.getMethod (nodeValue);
htmlNode.addEventListener (
nodeName.substr (3), method.bind (this.signalData));
}
else if (nodeName === 'id')
{
this.objectMap[nodeValue] = htmlNode;
}
else
htmlNode.setAttribute (nodeName,
this.translateValue (nodeValue));
}
var childs = node.childNodes;
@ -129,7 +142,10 @@ Vn.Builder = new Class
};
this.contexts.push (context);
this.registerObject (node, customNode);
var nodeId = node.getAttribute ('id');
if (nodeId)
this.objectMap[nodeId] = customNode;
var childs = node.childNodes;
@ -140,14 +156,6 @@ Vn.Builder = new Class
return customNode;
}
,registerObject: function (node, object)
{
var nodeId = node.getAttribute ('id');
if (nodeId)
this.objectMap[nodeId] = object;
}
,translateValue: function (value)
{
var chr = value.charAt (0);
@ -160,6 +168,16 @@ Vn.Builder = new Class
return value;
}
,getMethod: function (value)
{
if (this.signalData)
var methodName = 'this.signalData.'+ value;
else
var methodName = value;
return eval (methodName);
}
,replaceFunc: function (token)
{
return token.charAt(1).toUpperCase ();
@ -174,8 +192,19 @@ Vn.Builder = new Class
for (var j = 0; j < a.length; j++)
{
var prop = a[j].nodeName.replace (/-./g, this.replaceFunc);
this.setProperty (c, prop, a[j].nodeValue);
var nodeName = a[j].nodeName;
var nodeValue = a[j].nodeValue;
if (/on-\w+/.test (nodeName))
{
var method = this.getMethod (nodeValue);
c.object.on (nodeName.substr (3), method, this.signalData);
}
else
{
var prop = nodeName.replace (/-./g, this.replaceFunc);
this.setProperty (c, prop, nodeValue);
}
}
if (c.parent)
@ -232,9 +261,24 @@ Vn.Builder = new Class
c.object[propName] = value;
}
,setParent: function (parentBuilder)
{
this.parentBuilder = parentBuilder;
if (parentBuilder)
this.signalData = parentBuilder.signalData;
}
,get: function (objectId)
{
return this.objectMap[objectId];
var object = this.objectMap[objectId];
if (object)
return object;
if (this.parentBuilder)
return this.parentBuilder.get (objectId);
return null;
}
,getObjects: function (tagName)

View File

@ -0,0 +1,14 @@
{
"EditAddress": "Afegir / Modificar adreça"
,"Name": "Consignatari"
,"Address": "Direcció"
,"City": "Ciutat"
,"ZipCode": "Codi postal"
,"Province": "Província"
,"Return": "Tornar"
,"Accept": "Acceptar"
,"AddressChangedSuccessfully": "Adreça modificada correctament"
}

View File

@ -14,4 +14,12 @@
,"MustReloginIfChange": "Per canviar el nom d'usuari haurà de tornar a iniciar sessió"
,"PasswordsChanged": "Contrasenya modificada!"
,"PasswordsDoesntMatch": "Les contrasenyes no coincideixen!"
,"Addresses": "Adreces"
,"AddAddress": "Afegir adreça"
,"SetAsDefault": "Establir com a predeterminada"
,"RemoveAddress": "Esborrar direcció"
,"EditAddress": "Modificar direcció"
,"AreYouSureDeleteAddress": "Esteu segur que voleu esborrar la direcció?"
}

View File

@ -31,10 +31,17 @@
,"QuantityIntroduced": "La quantitat introduïda de"
,"IsHigherThan": "és major que la quantiat disponible, per tant s'afegirà el màxim disponible"
,"RoundedTo": "ha sigut arredonit, degut a que aquest artícle es ven per caixes"
,"NoOrderAfterHour": "No és possible realitzar encarrecs per a hui després de les" ,"NoOrderOnHolidays": "No és possible realitzar encarrecs per a Diumenges o festius"
,"NoOrderAfterHour": "No és possible realitzar encarrecs per a hui després de les"
,"NoOrderOnHolidays": "No és possible realitzar encarrecs per a Diumenges o festius"
,"DateLow": "La data d'enviament ha de ser igual o superior al dia d'avui"
,"DateHigh": "La data introduïda és massa gran"
,"DateUpdatedTo": "El dia d'enviament ha sigut actualitzat al"
,"CreditExceeded": "Ha excedit el seu crèdit màxim permés,si dessitja confirmar l'encàrrec igualment, marqui la casella Pagament Contrareemborsament/Contat o reduïsca l'import del seu encàrrec en "
,"InsuranceQuestion": "Les agencies de transport dispose d'un menor nombre de treballadors a l'estiu, per les vacances, motiu el qual pot ocasionar retards en el lliurament. A més a més, unït al calor, ha causat, en algunes ocasions, que la mercaderia no arribi en òptimes condicions. Ja que els nostres ports habituals no inclouen cap tipus d'assegurança, li oferim la possibilitat d'assegurar aquest enviament. El cost seria del 5% del valor de la mercaderia. Dessitja contracta-ho?"
,"ShippingAddress": "Adreça d'enviament"
,"AddAddress": "Afegir adreça"
,"SelectAddress": "Seleccionar adreça"
,"EditAddress": "Modificar direcció"
}

View File

@ -1,5 +1,5 @@
{
"AddNew": "Afegir/Editar notícia"
"AddEditNew": "Afegir / Editar notícia"
,"Title:": "Títol:"
,"NewBody:": "Cos:"

View File

@ -0,0 +1,14 @@
{
"EditAddress": "Añadir / Modificar dirección"
,"Name": "Consignatario"
,"Address": "Dirección"
,"City": "Ciudad"
,"ZipCode": "Código postal"
,"Province": "Provincia"
,"Return": "Volver"
,"Accept": "Aceptar"
,"AddressChangedSuccessfully": "Dirección modificada correctamente"
}

View File

@ -1,10 +1,10 @@
{
"Configuration": "Configuración"
,"UserNumber": "Nº usuario:"
,"UserName": "Nombre de usuario:"
,"Password": "Contraseña:"
,"Email": "Correo electrónico:"
,"UserNumber": "Nº usuario"
,"UserName": "Nombre de usuario"
,"Password": "Contraseña"
,"Email": "Correo electrónico"
,"Billing": "Facturación"
,"BillingByEmail": "Enviar facturas por correo electrónico:"
@ -14,4 +14,12 @@
,"MustReloginIfChange": "Para cambiar su nombre de usuario deberá volver a iniciar sesión"
,"PasswordsChanged": "¡Contraseña modificada!"
,"PasswordsDoesntMatch": "¡Las contraseñas no coinciden!"
,"Addresses": "Direcciones"
,"AddAddress": "Añadir dirección"
,"SetAsDefault": "Establecer como predeterminada"
,"RemoveAddress": "Borrar dirección"
,"EditAddress": "Modificar dirección"
,"AreYouSureDeleteAddress": "¿Está seguro de que desea borrar la dirección?"
}

View File

@ -38,4 +38,10 @@
,"DateUpdatedTo": "El día de envío ha sido actualizado a el"
,"CreditExceeded": "Ha excedido su crédito máximo permitido, si desea confimar el pedido de todas formas marque la casilla Pago Contrareembolso/Contado o reduzca el importe de su pedido en "
,"InsuranceQuestion": "Las agencias de transporte disponen de un menor número de trabajadores en verano, por las vacaciones, lo que puede ocasionar retrasos en la entrega. Esto, unido al calor, ha causado, en algunas ocasiones, que la mercancía no llegara en óptimas condiciones. Ya que nuestros portes habituales no incluyen ningún tipo de seguro, le ofrecemos la posibilidad de asegurar este envio. El coste sería de el 5% del valor de la mercancía. ¿Desea contratarlo?"
,"ShippingAddress": "Dirección de envío"
,"AddAddress": "Añadir dirección"
,"SelectAddress": "Seleccionar dirección"
,"EditAddress": "Modificar dirección"
}

View File

@ -1,5 +1,5 @@
{
"AddNew": "Añadir/Editar noticia"
"AddEditNew": "Añadir / Editar noticia"
,"Title:": "Título:"
,"NewBody:": "Cuerpo:"

View File

@ -0,0 +1,14 @@
{
"EditAddress": "Ajouter / Modifier l'adresse"
,"Name": "Destinataire"
,"Address": "Adresse De La Rue"
,"City": "Ville"
,"ZipCode": "Code postal"
,"Province": "Province"
,"Return": "Reviens"
,"Accept": "Accepter"
,"AddressChangedSuccessfully": "Adresse modifié avec succès"
}

View File

@ -14,4 +14,12 @@
,"MustReloginIfChange": "Pour changer votre nom d'utilisateur que vous devrez vous identifier"
,"PasswordsChanged": "Mot de passe modifié!"
,"PasswordsDoesntMatch": "Les mots de passe ne correspondent pas!"
,"Addresses": "Adresses"
,"AddAddress": "Ajouter une adresse"
,"SetAsDefault": "Définir par défaut"
,"RemoveAddress": "Supprimer l'adresse"
,"EditAddress": "Modifier l'adresse"
,"AreYouSureDeleteAddress": "Êtes-vous sûr de vouloir supprimer l'adresse?"
}

View File

@ -38,4 +38,10 @@
,"DateUpdatedTo": "Date d'envoi mise à jour a "
,"CreditExceeded": "Ha excedido su crédito máximo permitido, si desea confimar el pedido de todas formas marque la casilla Pago Contrareembolso/Contado o reduzca el importe de su pedido en "
,"InsuranceQuestion": "Las agencias de transporte disponen de un menor número de trabajadores en verano, por las vacaciones, lo que puede ocasionar retrasos en la entrega. Esto, unido al calor, ha causado, en algunas ocasiones, que la mercancía no llegara en óptimas condiciones. Ya que nuestros portes habituales no incluyen ningún tipo de seguro, le ofrecemos la posibilidad de asegurar este envio. El coste sería de el 5% del valor de la mercancía. ¿Desea contratarlo?"
,"ShippingAddress": "Adresse de livraison"
,"AddAddress": "Ajouter une adresse"
,"SelectAddress": "Sélectionnez adresse"
,"EditAddress": "Modifier l'adresse"
}

View File

@ -1,5 +1,5 @@
{
"AddNew": "Ajouter/Editer nouvelles"
"AddEditNew": "Ajouter / Editer nouvelles"
,"Title:": "Titre:"
,"NewBody:": "Corps:"

View File

@ -0,0 +1,12 @@
{
"EditAddress": "Añadir / Modificar dirección"
,"Name": "Consignatario"
,"Address": "Dirección"
,"City": "Ciudad"
,"ZipCode": "Código postal"
,"Province": "Provincia"
,"Return": "Volver"
,"Accept": "Aceptar"
}

View File

@ -0,0 +1,17 @@
{
"Configuration": "Configuración"
,"UserNumber": "Nº usuario:"
,"UserName": "Nombre de usuario:"
,"Password": "Contraseña:"
,"Email": "Correo electrónico:"
,"Billing": "Facturación"
,"BillingByEmail": "Enviar facturas por correo electrónico:"
,"NewPassword": "Nueva contraseña"
,"RepeatPassword": "Repetir contraseña"
,"MustReloginIfChange": "Para cambiar su nombre de usuario deberá volver a iniciar sesión"
,"PasswordsChanged": "¡Contraseña modificada!"
,"PasswordsDoesntMatch": "¡Las contraseñas no coinciden!"
}

View File

@ -0,0 +1,15 @@
{
"AccessLog": "Registro de accesos"
,"UserNumber:": "Nº usuario:"
,"User:": "Usuario:"
,"Phone:": "Teléfono:"
,"Mobile:": "Móvil:"
,"Access": "Acceso"
,"OS": "SO"
,"Browser": "Navegador"
,"Version": "Versión"
,"Javascript": "Javascript"
,"Cookies": "Cookies"
}

View File

@ -0,0 +1,6 @@
{
"ControlPanel": "Panel de control"
,"Module": "Módulo"
,"Description": "Descripción"
}

View File

@ -0,0 +1,12 @@
{
"Photos": "Fotos"
,"Schema:": "Esquema:"
,"ImageName:": "Nombre de la imagen:"
,"Id:": "Id:"
,"ImageFile:": "Archivo de imagen:"
,"Upload": "Enviar"
,"ImageUploaded": "Imagen subida correctamente"
}

View File

@ -0,0 +1,12 @@
{
"UserManagement": "Gestión de usuarios"
,"UserName:": "Nombre de usuario:"
,"UserNumber": "Nº usuario"
,"UserName": "Nombre de usuario"
,"Alias": "Alias"
,"AccessAsUser": "Suplantar usuario"
,"AccessLog": "Registro de accesos"
}

View File

@ -0,0 +1,31 @@
{
"Visits": "Visitas"
,"VisitsManagement": "Gestión de visitas"
,"ActiveSessions": "Usuarios conectados"
,"VisitsQuery": "Consulta de visitas"
,"Refresh": "Actualizar"
,"ActiveSessions:": "Usuarios conectados:"
,"NewVisitsTotal:": "Nuevas visitas:"
,"SessionNumber": "Nº sesión"
,"User": "Usuario"
,"Login": "Hora de acceso"
,"LastActivity": "Última actividad"
,"SO": "Sistema Operativo"
,"Version": "Versión"
,"NewVisit": "Nueva visita"
,"SelectDateInterval": "Seleccione un intérvalo de fechas"
,"FromDate:": "Desde el día:"
,"ToDate:": "Hasta el día:"
,"VisitsTotal:": "Total visitas:"
,"Browser": "Navegador"
,"MinVersion": "Versión mínima"
,"MaxVersion": "Versión máxima"
,"LastVisit": "Última visita"
,"NewVisits": "Nuevas visitas"
,"%a, %e %b %Y at %T": "%a, %e %b %Y a las %T"
}

View File

@ -0,0 +1,9 @@
{
"ListByAgency": "Bultos por agencia"
,"ShowByProvince": "Mostrar desglose por provincia"
,"Agency": "Agencia"
,"Exps": "Exps."
,"Bundles": "Bultos"
,"Prevision": "Prev."
}

View File

@ -0,0 +1,8 @@
{
"ByProvince": "Desglose por provincia"
,"SelectAgency": "Seleccione una agencia en el listado de la izquierda"
,"Province": "Provincia"
,"Expeditions": "Exps."
,"Left": "Faltan"
}

View File

@ -0,0 +1,47 @@
{
"QualityAndVariety": "Calidad, variedad y servicio"
,"MaximumFreshness": "Verdnatura te ofrece un producto con la máxima frescura garantizada, gracias a sus recepciones diarias de flor y planta procedentes de Holanda, Sudamérica, o desde el mismo productor."
,"SquareMeters": "Más de 13.000m de instalaciones"
,"AboutRealms": "Con flor cortada, verdes, artificial y complementos"
,"AboutLocation": "Asentados en Valencia, Madrid, Barcelona, Holanda y Francia, ofrecemos venta directa en nuestras instalaciones y reparto a toda España mediante servicio propio o agencia."
,"PurchaseThroughWeb": "Compra a través de nuestra web y recibe tu pedido cómodamente en tu floristería. ¡En menos de 24 horas!"
,"WhatMakeUsDifferent": "¿Que nos hace diferentes?"
,"DesignVariety": "La variedad en el diseño, la calidad de los materiales utilizados y nuestro servicio de reparto, te garantizan un muestrario de género dinámico, siempre fresco y atractivo."
,"AdaptToYourNeeds": "Verdnatura se adapta a las necesidades de cada cliente ofreciéndole un amplio abanico de productos, garantizado siempre."
,"TheBestQuality": "La mejor calidad al mejor precio. Sin olvidar nunca el diseño."
,"AtYourService": "Estamos a tu servicio"
,"BuyersAndTraders": "9 compradores especializados y nuestros 20 comerciales te asesorarán en todo lo que necesites."
,"Training": "Verdnatura formación"
,"GoodTraining": "En Verdnatura sabemos que una buena formación es imprescindible para el desarrollo óptimo de cualquier actividad, y cómo no, también la de florista."
,"SpecialTrainingPrices": "Para que el presupuesto de una escuela no repercuta en la calidad de su formación, colaboramos con una política de precios especiales para todas aquellas escuelas que lo soliciten realizar cursos en nuestras instalaciones de Verdnatura Silla."
,"YoutubeChannel": "Y no te pierdas los vídeos de Canal Verdnatura en Youtube. Donde encontrarás un montón de consejos muy interesantes sobre el manejo de la flor."
,"HowWeWork": "¿Cómo trabajamos?"
,"FirstQualityControl": "1º control de calidad"
,"SecondQualityControl": "2º control de calidad"
,"ThirdQualityControl": "3º control de calidad"
,"FourthQualityControl": "4º control de calidad"
,"AalsmeerAuction": "Alas 5:00h, nuestros responsables de compras adquieren, en la subasta de Aalsmeer y Noaldwijk, el género que el productor ha cosechado el día anterior."
,"BeforeAuction": "Tras su compra, este género entra rápidamente en Verdnatura Holland BV, nuestra empresa de Flora Holland, en Aalsmeer."
,"DirectlyFromProviders": "Además de comprar a través de la subasta Holandesa, también compramos directamente a productores de Colombia, Ecuador, Thailandia, Malasia, África y Australia. Estos productos son supervisados directamente por nuestros delegados de compra ubicados en cada zona. Esta mercancía viajará a Amsterdam, sometida a un proceso de Vaacum y en menos de dos horas desde su aterrizaje, estará en nuestras instalaciones de Aalsmeer."
,"GoodsDischarge": "A las 7:00h nuestros compañeros de Aalsmeer empiezan a recibir la mercancía comprada, pasando un primer control de calidad, y dándola de alta en nuestro stock. Ya está disponible para nuestros clientes en la web."
,"GoodsTravel": "La mercancía viaja durante día y medio en camiones con compartimentos estancos a temperaturas diferentes, de manera que no se rompa la cadena de frío y viaje en las mejores condiciones."
,"GoodsReception": "A la recepción de la mercancía el responsable de su compra revisa el estado en el que llega, aceptándola o rechazándola según el caso, se descarga en frío y rápidamente entra en nuestra cámara."
,"CustomerOrders": "Nuestros clientes pueden hacer sus pedidos a través de la web, por teléfono o viniendo directamente a nuestras instalaciones. Tenemos un equipo de comerciales especializados que te asesorará en tu compra y que te informará de las novedades y artículos que puedan ser de tu interés, de forma que tu compra se ajuste a tus necesidades y quedes totalmente satisfecho."
,"AfterOrder": "Una vez realizado el pedido, pasa al departamento de producción. Durante la preparación de este se realiza un nuevo control de calidad (el tercero) en el que se desechará la mercancía deficiente."
,"BuyerControl": "En cuanto se finaliza la preparación, se realiza un nuevo control (el cuarto) donde un especialista cuenta y revisa el estado de los productos. En caso de que estos no cumplan con los estándares de calidad exigidos los rechaza y los sustituye por los adecuados."
,"EmbeddedSection": "Seguidamente se lleva a la sección de encajado, donde el pedido es acondicionado para su correcta entrega. Cada tipo de entrega requiere un método de encajado adecuado para que el género viaje protegido y llegue al cliente en perfectas condiciones."
,"AfterEmbedAgency": "En cuanto el producto ha sido encajado se almacena de nuevo en la cámara hasta su salida por agencia o por reparto propio, recibiéndolo el cliente, en 24h en el caso de la agencia o el mismo día en el caso del reparto, cómodamente en su domicilio."
,"FreshnessGuaranteed": "Esta forma de trabajo garantiza la mayor frescura por la rapidez los procesos y por el mantenimiento de la cadena de frío desde compra hasta su recepción por nuestro cliente."
,"AboutSummary": "75 personas repartidas por casi todo el mundo para que nuestro cliente tenga el más amplio catálogo del sector, la flor más fresca, la planta más novedosa, los complementos más actuales, y el servicio más rápido posible."
}

View File

@ -0,0 +1,20 @@
{
"IWantCustomer": "¡Quiero ser cliente!"
,"FillFormData": "Rellene el formulario con sus datos y en breve nos pondremos en contacto con usted."
,"OrCallUs": "O si lo prefiere llámenos al 963 242 100."
,"AllFieldsMandatory": "* Todos los campos son obligatorios."
,"Name:": "Nombre:"
,"Surname:": "Apellidos:"
,"EMail:": "Correo electrónico:"
,"Message:": "Mensaje:"
,"Address:": "Dirección:"
,"PC:": "Código postal:"
,"City:": "Ciudad:"
,"Phone:": "Teléfono:"
,"Send": "Enviar datos"
,"DataSentSuccess": "Sus datos han sido enviados correctamente. En breve nos pondremos en contacto con usted."
,"ErrorSendingData": "Error al enviar sus datos. Por favor, compruebe que ha rellenado todos los campos y que ha introducido el código anti-spam correctamente."
}

View File

@ -0,0 +1,13 @@
{
"Sent": "Enviado"
,"Author": "Autor"
,"votes": "votos"
,"NoAnswerSelected": "No ha seleccionado ninguna respuesta"
,"ThanksForVote": "¡Gracias por su voto!"
,"Vote": "Votar"
,"Total": "Total"
,"BrownserRecommend":
"Verdnatura le recomienda utilizar el navegador web Mozilla Firefox para obtener toda la funcionalidad de nuestra página web."
,"PressHere": "Pulse aquí para descargar Firefox"
}

View File

@ -0,0 +1,3 @@
{
"ShowMap": "Mostrar Mapa"
}

View File

@ -0,0 +1,4 @@
{
"Author": "Autor"
}

View File

@ -0,0 +1,25 @@
{
"AboutCompany": "¿Por qué Verdnatura?"
,"StorePhoto": "Foto Almacén"
,"BecauseOurBigCatalog": "Porque tenemos el catálogo más grande del sector, renovado diariamente."
,"BecauseThisWeb": "Por esta página web, con stock en tiempo real siempre a tu disposición."
,"BecauseOurShoppingDep": "Por nuestro departamento de compras con 9 compradores especializados."
,"BecauseOrderIsEasy": "Porque es muy fácil hacer tu pedido por web, por teléfono o viniendo."
,"BecauseOurPlant": "Por nuestras instalaciones, ven y visítanos. Te encantarán."
,"BecauseOurSalesDep": "Por nuestro departamento comercial, con profesionales que siempre encontrarán una solución a tus necesidades."
,"BecauseOurWorkShop": "Porque tenemos un taller de confección para ayudarte."
,"BecauseWeHaveWhatYouNeed": "Porque tenemos lo que necesitas cuando lo necesitas..."
,"AboutDesc":
"Somos una empresa dedicada a la venta mayorista y distribución de una amplia gama de complementos, verdes y flores naturales a floristerías u otros mayoristas."
,"AboutService":
"Disponemos de servicio de reparto a domicilio con nuestros vehículos por toda la provincia de Valencia y áreas limitadas de Castellón, Alicante, Murcia, Albacete y Madrid enviamos al resto de la península mediante agencias de transporte con servicio 24/48 horas (Zeleris, Viaexpress). También realizamos venta directa a floristas en cualquiera de nuestras instalaciones."
,"AboutDisp":
"Nuestra empresa dispone de más de 50 trabajadores y varias sucursales. La principal se encuentra situada en Valencia y cuenta con más de 8000 m2. También disponemos de un almacén situado en Mercaflor - Mercavalencia (Valencia) en el que únicamente realizamos venta directa."
,"AboutOrder":
"Puede realizar sus pedidos y reservas por teléfono llamando al 96 324 21 00, por Internet a través de nuestra página web o bien directamente en nuestras instalaciones."
}

View File

@ -0,0 +1,26 @@
{
"ShoppingBasket": "Cesta de la compra"
,"Delete": "Borrar pedido"
,"GoToCatalog": "Ir al catálogo"
,"Checkout": "Tramitar pedido"
,"OrderNumber:": "Nº pedido:"
,"DateExit:": "Fecha de salida:"
,"Warehouse:": "Almacén:"
,"OrderTotal:": "Total pedido:"
,"VATNotIncluded": "(IVA y transporte no incluídos)"
,"Amount": "Cant"
,"Pack": "Pack"
,"Stems": "Tallos"
,"Avail": "Disp"
,"Item": "Artículo"
,"Cat": "Cat"
,"S1": "Med"
,"Color": "Color"
,"Origin": "Origen"
,"Price": "Precio"
,"Disc": "Desc"
,"Subtotal": "Subtotal"
}

View File

@ -0,0 +1,32 @@
{
"Catalog": "Catálogo"
,"SearchResults": "Resultados de búsqueda"
,"SelectFamily": "Seleccione familia"
,"SelectSubtype": "Por favor, seleccione el subtipo en el menú de la derecha"
,"ArticleNotFound": "Artículo no encontrado"
,"ArticleNotAvailable": "Artículo no disponible"
,"StartOrder": "Empezar pedido"
,"ShoppingBasket": "Cesta de la compra"
,"Realm": "Familia"
,"Subtype": "Subtipo"
,"Date:": "Fecha:"
,"Warehouse:": "Almacén:"
,"Search:": "Buscar:"
,"GeneralSearch": "Búsqueda general"
,"Amount": "Cant"
,"Aval": "Disp"
,"Name": "Nombre"
,"S1": "Med"
,"S2": "S2"
,"Stems": "Tallos"
,"Cat": "Cat"
,"Pack": "Pack"
,"Origin": "Origen"
,"Price": "Precio"
,"IndicativePhotos": "* Las fotos son orientativas"
}

View File

@ -0,0 +1,41 @@
{
"Checkout": "Tramitar pedido"
,"GoBasket": "Volver a la cesta"
,"Confirm": "Confirmar"
,"PayCash": "Contrareembolso/Contado"
,"PayMethod:": "Forma de pago:"
,"Notes:": "Notas:"
,"SendMethod:": "Forma de envío:"
,"Insurance": "Asegurar mercancía: 5% del importe del pedido (Solo para envíos por agencia)"
,"Consignee": "Consignatario"
,"Province": "Provincia"
,"PC": "Código postal"
,"City": "Ciudad"
,"Address": "Domicilio"
,"SureDelOrder": "¿Está seguro de eliminar el pedido?"
,"SureConfirmOrder": "¿Desea confirmar su pedido?"
,"OrderConfirmed": "Su pedido ha sido procesado y confirmado correctamente"
,"ClientAcceptCash": "El cliente accepta pagar Contrareembolso/Contado"
,"InetOrder": "Pedido realizado por Internet"
,"NoOrderFound": "No se ha encontrado ningún pedido"
,"NoArticleAdded": "No ha agregado ningún artículo a su pedido"
,"OrderExceeded": "Ha excedido el numero maximo de pedidos por confirmar, por favor elimine o confirme los pedidos iniciados"
,"HighQuantity": "Algunos artículos ya no están disponibles o hay mas cantidad de la disponible, revise los recuadros en rojo"
,"NoArticleAdded": "No ha seleccionado ningun artículo"
,"IsertOrderType": "Introduzca el tipo de pedido que desea"
,"QuantityIntroduced": "La cantidad introducida de"
,"IsHigherThan": "es mayor que la cantidad disponible, por lo tanto se agregará el máximo disponible"
,"RoundedTo": "ha sido redondeada debido a que este artículo se vende por cajas"
,"NoOrderAfterHour": "No es posible realizar pedidos para hoy despues de las"
,"NoOrderOnHolidays": "No es posible realizar pedidos para Domingos o festivos"
,"DateLow": "La fecha de envío debe de ser igual o superior al día de hoy"
,"DateHigh": "La fecha introducida es demasiado grande"
,"DateUpdatedTo": "El día de envío ha sido actualizado a el"
,"CreditExceeded": "Ha excedido su crédito máximo permitido, si desea confimar el pedido de todas formas marque la casilla Pago Contrareembolso/Contado o reduzca el importe de su pedido en "
,"InsuranceQuestion": "Las agencias de transporte disponen de un menor número de trabajadores en verano, por las vacaciones, lo que puede ocasionar retrasos en la entrega. Esto, unido al calor, ha causado, en algunas ocasiones, que la mercancía no llegara en óptimas condiciones. Ya que nuestros portes habituales no incluyen ningún tipo de seguro, le ofrecemos la posibilidad de asegurar este envio. El coste sería de el 5% del valor de la mercancía. ¿Desea contratarlo?"
}

View File

@ -0,0 +1,34 @@
{
"StartedOrdersDesc":
"Pedidos pendientes de confirmar"
,"StartOrder": "Empezar pedido"
,"ContinueOrder": "Continuar pedido"
,"OrderNumber": "Nº pedido"
,"DateMake": "Fecha de creación"
,"DateExit": "Fecha de salida"
,"SendMethod": "Forma de envío"
,"ConfirmedOrdersDesc":
"Pedidos confirmados más recientes"
,"PendingBalance:": "Saldo pendiente:"
,"PaymentInfo": "Para realizar una entrega a cuenta pulse en el botón de la derecha y haga el pago en la empresa correspondiente. La cantidad que aparece es el saldo pendiente a día de hoy, no tiene en cuenta pedidos del futuro. Puede realizar una entrega a cuenta de la cantidad que desee. Si desea pagar un pedido en concreto puede pulsar directamente en el botón de pago del pedido."
,"MakePayment": "Realizar pago"
,"Company": "Empresa"
,"Pending": "Pendiente"
,"Pay": "Pagar"
,"SeeOrder": "Mostrar detalle del pedido"
,"TicketNumber": "Nº ticket"
,"SentAddress": "Dirección de envío"
,"Consignee": "Consignatario"
,"Boxes": "Bultos"
,"TotalWithVAT": "Total con IVA"
,"Pending": "Pendiente"
,"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"
}

View File

@ -0,0 +1,30 @@
{
"OrderDetail": "Detalle del pedido"
,"Print": "Imprimir albarán"
,"TicketNumber:": "Nº ticket:"
,"DateExit:": "Fecha de envío:"
,"SendMethod:": "Forma de envío:"
,"Notes:": "Notas:"
,"TicketTotal:": "Total pedido:"
,"(VATIncluded)": "(IVA incluído)"
,"PC": "Código postal"
,"City": "Ciudad"
,"Province": "Provincia"
,"Address": "Domicilio"
,"Consignee": "Consignatario"
,"ItemNumber": "Nº artículo"
,"Amount": "Cant"
,"Item": "Artículo"
,"Category": "Categoría"
,"S1": "Med"
,"Stems": "Tallos"
,"Color": "Color"
,"Origin": "Origen"
,"Price": "Precio"
,"Disc": "Desc"
,"Subtotal": "Subtotal"
}

View File

@ -0,0 +1,11 @@
{
"AddEditNew": "Añadir / Editar noticia"
,"Title:": "Título:"
,"NewBody:": "Cuerpo:"
,"Return": "Volver"
,"Accept": "Aceptar"
,"NewChangedSuccessfully": "Noticia modificada correctamente"
}

View File

@ -0,0 +1,12 @@
{
"NewsManagement": "Gestión de noticias"
,"AddNew": "Añadir noticia"
,"EditNew": "Editar noticia"
,"NewNum": "Nº noticia"
,"Date": "Fecha"
,"Author": "Autor"
,"Title": "Título"
,"Priority": "Prioridad"
}

View File

@ -0,0 +1,9 @@
Vn.Locale.add
({
"ConnError": "Error en la conexión"
,"InternalError": "Se ha producido un error interno"
,"BadServerReply": "Respuesta del servidor incorrecta"
,"ModelNotUpdatable": "Este modelo no es actualizable"
,"RowNotExists": "El registro no existe o a sido borrado"
,"ColNotExists": "La columna no existe"
});

View File

@ -0,0 +1,25 @@
Vn.Locale.add
({
"True": "Si"
,"False": "No"
,"Null": "Nulo"
,"ChangeDate": "Cambiar Fecha"
,"Sort": "Ordenar"
,"At": "a las"
,"Of": "de"
,"OfThe": "del"
,"Remove": "Borrar"
,"Loading": "Cargando"
,"ReallyDelete": "¿Realmente desea borrar la línea?"
,"EmptyList": "Lista vacía"
,"NoData": "Sin datos"
,"ErrorLoadingData": "Error"
,"Error": "Error"
,"Image": "Imagen"
,"File": "Archivo"
,"FileName": "Nombre"
,"UpdateImage": "Añadir / Actualizar Imagen"
,"UploadFile": "Subir archivo"
,"ImageAdded": "Imagen añadida correctamente"
,"Close": "Cerrar"
});

View File

@ -0,0 +1,77 @@
Vn.Locale.add
({
"Sunday": "Domingo"
,"Monday": "Lunes"
,"Tuesday": "Martes"
,"Wednesday": "Miercoles"
,"Thursday": "Jueves"
,"Friday": "Viernes"
,"Saturday": "Sábado"
,"Su": "Do"
,"Mo": "Lu"
,"Tu": "Ma"
,"We": "Mi"
,"Th": "Ju"
,"Fr": "Vi"
,"Sa": "Sa"
,"January": "Enero"
,"February": "Febrero"
,"March": "Marzo"
,"April": "Abril"
,"May": "Mayo"
,"June": "Junio"
,"July": "Julio"
,"August": "Agosto"
,"September": "Septiembre"
,"October": "Octubre"
,"November": "Noviembre"
,"December": "Diciembre"
,"Jan": "Ene"
,"Feb": "Feb"
,"Mar": "Mar"
,"Apr": "Abr"
,"May": "May"
,"Jun": "Jun"
,"Jul": "Jul"
,"Ago": "Ago"
,"Sep": "Sep"
,"Oct": "Oct"
,"Nov": "Nov"
,"Dec": "Dic"
,"AppName": "Verdnatura"
,"Beta": "Beta"
,"User": "Usuario"
,"Password": "Contraseña"
,"Remember": "Recordar"
,"Enter": "Entrar"
,"Exit": "Salir"
,"Menu": "Menú"
,"ErrorLoadingForm": "Error al cargar formulario"
,"YoureVisitor": "¿Solo estás de visita?"
,"NewVersionAvailable": "Existe una nueva versión de la página web, ¿Desea actualizar?"
,"ChangeLog": "Cambios recientes"
,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis."
,"Home": "Inicio"
,"Orders": "Pedidos"
,"Catalog": "Catálogo"
,"Training": "Formación"
,"Configuration": "Configuración"
,"About": "Conócenos"
,"Why": "¿Por qué?"
,"Location": "Localización"
,"Administration": "Administración"
,"Users": "Usuarios"
,"Visits": "Visitas"
,"Photos": "Fotos"
,"Agencies": "Agencias"
,"News": "Noticias"
,"Contact": "Quiero ser cliente"
,"SessionExpired": "Ha estado demasiado tiempo inactivo y su sesión ha expirado."
,"InvalidLogin": "Usuario o contraseña incorrectos. Recuerde que se hace distinción entre mayúsculas y minúsculas."
});

View File

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

View File

@ -0,0 +1,4 @@
{
"PaymentComplete": "Pago terminado, ya puede volver a nuestra página web."
,"ReturnToWeb": "Volver a Verdnatura"
}

View File

@ -0,0 +1,4 @@
{
"UpdateYourBrowser": "Actualice su navegador"
,"ContinueAnyway": "Continuar de todos modos"
}

View File

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

View File

@ -0,0 +1,11 @@
{
"BadFileFormat": "Formato de archivo no reconocido"
,"FileNotChoosed": "No ha seleccionado ningún archivo"
,"PermissionDenied": "No tiene permiso para subir el fichero"
,"FileUploadError": "Error al subir el fichero, compruebe que su tamaño no sea demasiado grande"
,"FileSaveError": "Error al guardar el fichero: %s"
,"FileSizeError": "El fichero no debe ocupar mas de %.2f MB"
,"BadFileName": "Solo es posible utilizar letras minúsculas, dígitos o el caráter '_' en el nombre del archivo"
,"ComError": "Error en la comunicación con el servidor"
,"ImageOpenError": "Error al abrir el archivo de imagen"
}

View File

@ -0,0 +1,5 @@
{
"InvalidAction": "Acción inválida"
,"EmptyQuery": "Consulta vacia"
}

View File

@ -9,6 +9,7 @@ Vn.Module = new Class
this.formInfo = formInfo;
this.builder = new Vn.Builder ();
this.builder.signalData = this;
this.builder.loadXml (Vn.getXml ('forms/'+ formInfo.path +'/ui.xml'));
this.node = this.builder.get ('form');