forked from verdnatura/hedera-web
Compare commits
25 Commits
4922-vueMi
...
5122-multi
Author | SHA1 | Date |
---|---|---|
|
18cdb4cc1b | |
|
ca5f80f6c3 | |
|
d1ff6889af | |
|
a632a15242 | |
|
67b6f77b12 | |
|
e8eab29887 | |
|
326aeee127 | |
|
bbb0089b59 | |
|
406b2f8300 | |
|
efc7342359 | |
|
806c4cc3ad | |
|
c463e967ca | |
|
be43a38b38 | |
|
59ed61ae9b | |
|
17e54cfc60 | |
|
baa9bb7cdf | |
|
87d75be910 | |
|
ac629dc97b | |
|
ff3320d590 | |
|
e8b727ab6c | |
|
5934ee3832 | |
|
4f09574697 | |
|
6d95dfb999 | |
|
1fa9b1e8b0 | |
|
327508c3ee |
|
@ -2,3 +2,4 @@ node_modules
|
|||
build/
|
||||
config.my.php
|
||||
.vscode/
|
||||
.quasar
|
||||
|
|
|
@ -33,9 +33,9 @@ RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
|
|||
> /etc/apt/sources.list.d/vn.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
php-apcu \
|
||||
php-image-text \
|
||||
php-text-captcha \
|
||||
php-apcu \
|
||||
php-zip \
|
||||
hedera-web \
|
||||
cron
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
hedera-web (22.48.2) stable; urgency=low
|
||||
hedera-web (22.48.10) stable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Vcs-Git: https://gitea.verdnatura.es/verdnatura/hedera-web
|
|||
Package: hedera-web
|
||||
Architecture: all
|
||||
Depends: apache2 | httpd, nodejs, php-cli, php-vn-lib, php-apcu, php-imap, php-soap, libphp-phpmailer, php-gd, php-pear
|
||||
Suggests: php-text-captcha, php-zip, cron
|
||||
Suggests: php-image-text, php-text-captcha, php-zip, cron
|
||||
Section: misc
|
||||
Priority: optional
|
||||
Description: Verdnatura's web page
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
MAILTO=webmaster
|
||||
*/1 * * * * root hedera-web.php -m misc/mail
|
||||
*/4 * * * * root hedera-web.php -m tpv/confirm-mail
|
||||
*/2 * * * * root hedera-web.php -m edi/load
|
||||
0 23 * * * root hedera-web.php -m edi/clean
|
||||
0 5 * * * root hedera-web.php -m edi/update
|
||||
|
|
|
@ -28,45 +28,54 @@ export default new Class({
|
|||
}
|
||||
|
||||
,async onPassModifyClick() {
|
||||
var oldPassword = this.$.oldPassword.value;
|
||||
var newPassword = this.$.newPassword.value;
|
||||
var repeatedPassword = this.$.repeatPassword.value;
|
||||
|
||||
if (newPassword == '' && repeatedPassword == '')
|
||||
throw new Error(_('Passwords empty'));
|
||||
if (newPassword !== repeatedPassword)
|
||||
throw new Error(_('Passwords doesn\'t match'));
|
||||
|
||||
var verificationToken = this.hash.$.verificationToken;
|
||||
var params = {newPassword};
|
||||
|
||||
let err;
|
||||
const form = this.$.changePassword.node;
|
||||
Vn.Node.disableInputs(form);
|
||||
try {
|
||||
if (verificationToken) {
|
||||
params.verificationToken = verificationToken;
|
||||
await this.conn.send('user/restore-password', params);
|
||||
} else {
|
||||
let userId = this.gui.user.id;
|
||||
params.oldPassword = oldPassword;
|
||||
await this.conn.patch(
|
||||
`Accounts/${userId}/changePassword`, params);
|
||||
const oldPassword = this.$.oldPassword.value;
|
||||
const newPassword = this.$.newPassword.value;
|
||||
const repeatedPassword = this.$.repeatPassword.value;
|
||||
|
||||
try {
|
||||
if (newPassword == '' && repeatedPassword == '')
|
||||
throw new Error(_('Passwords empty'));
|
||||
if (newPassword !== repeatedPassword)
|
||||
throw new Error(_('Passwords doesn\'t match'));
|
||||
} catch (err) {
|
||||
return Htk.Toast.showError(err.message);
|
||||
}
|
||||
} catch(e) {
|
||||
err = e;
|
||||
Htk.Toast.showError(err.message);
|
||||
|
||||
const verificationToken = this.hash.$.verificationToken;
|
||||
const params = {newPassword};
|
||||
|
||||
if (this.hash.$.verificationToken)
|
||||
this.$.newPassword.select();
|
||||
else
|
||||
this.$.oldPassword.select();
|
||||
try {
|
||||
if (verificationToken) {
|
||||
params.verificationToken = verificationToken;
|
||||
await this.conn.send('user/restore-password', params);
|
||||
} else {
|
||||
let userId = this.gui.user.id;
|
||||
params.oldPassword = oldPassword;
|
||||
await this.conn.patch(
|
||||
`Accounts/${userId}/changePassword`, params);
|
||||
}
|
||||
} catch(err) {
|
||||
Htk.Toast.showError(err.message);
|
||||
|
||||
return;
|
||||
if (verificationToken)
|
||||
this.$.newPassword.select();
|
||||
else
|
||||
this.$.oldPassword.select();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.hash.unset('verificationToken');
|
||||
await this.conn.open(this.gui.user.name, newPassword);
|
||||
this.$.changePassword.hide();
|
||||
} finally {
|
||||
Vn.Node.disableInputs(form, false);
|
||||
}
|
||||
|
||||
this.$.changePassword.hide();
|
||||
this.hash.unset('verificationToken');
|
||||
|
||||
Htk.Toast.showMessage(_('Password changed!'));
|
||||
this.$.userForm.refresh();
|
||||
}
|
||||
|
||||
,onPassInfoClick() {
|
||||
|
|
|
@ -89,11 +89,13 @@
|
|||
<input
|
||||
id="new-password"
|
||||
type="password"
|
||||
placeholder="_New password"/>
|
||||
placeholder="_New password"
|
||||
autocomplete="new-password"/>
|
||||
<input
|
||||
id="repeat-password"
|
||||
type="password"
|
||||
placeholder="_Repeat password"/>
|
||||
placeholder="_Repeat password"
|
||||
autocomplete="new-password"/>
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<button class="thin" on-click="this.onPassModifyClick()">
|
||||
|
|
|
@ -5,17 +5,38 @@ export default new Class({
|
|||
Template: require('./ui.xml'),
|
||||
|
||||
async open() {
|
||||
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
||||
await Hedera.Form.prototype.open.call(this);
|
||||
this.basket = new Hedera.Basket(this.app);
|
||||
|
||||
this.orderId = this.$.params.$.id || this.basket.orderId;
|
||||
if (!this.orderId)
|
||||
return this.hash.setAll({form: 'ecomerce/checkout'});
|
||||
|
||||
this.$.lot.assign({id: this.orderId});
|
||||
},
|
||||
|
||||
activate() {
|
||||
this.$.items.setInfo('bi', 'myBasketItem', 'hedera');
|
||||
activate() {
|
||||
this.$.items.setInfo('bi', 'myOrderRow', 'hedera');
|
||||
},
|
||||
|
||||
onConfigureClick() {
|
||||
Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
|
||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
||||
this.hash.setAll({
|
||||
form: 'ecomerce/checkout',
|
||||
id: this.orderId
|
||||
});
|
||||
},
|
||||
|
||||
async onCatalogClick() {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
await basket.load(this.orderId);
|
||||
},
|
||||
|
||||
onConfirmClick() {
|
||||
this.hash.setAll({
|
||||
form: 'ecomerce/confirm',
|
||||
id: this.orderId
|
||||
});
|
||||
},
|
||||
|
||||
onDeleteClick(form) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
ShoppingBasket: Cistella de la compra
|
||||
Order: Encàrrec
|
||||
ShippingInformation: Dades d'enviament
|
||||
Delete: Borrar encàrrec
|
||||
GoToCatalog: Anar al catàleg
|
||||
ConfigureOrder: Configurar encàrrec
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
ShoppingBasket: Shopping basket
|
||||
Order: Order
|
||||
ShippingInformation: Shipping information
|
||||
Delete: Delete order
|
||||
GoToCatalog: Go to catalog
|
||||
ConfigureOrder: Configure order
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
ShoppingBasket: Cesta de la compra
|
||||
Order: Pedido
|
||||
ShippingInformation: Datos de envío
|
||||
Delete: Borrar pedido
|
||||
GoToCatalog: Ir al catálogo
|
||||
ConfigureOrder: Configurar pedido
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
ShoppingBasket: Panier
|
||||
Order: Commande
|
||||
ShippingInformation: Informations sur la livraison
|
||||
Delete: Effacer
|
||||
GoToCatalog: Aller au catalogue
|
||||
ConfigureOrder: Définissez l'ordre
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
ShoppingBasket: Cesta da compra
|
||||
Order: Encomenda
|
||||
ShippingInformation: Dados de envio
|
||||
Delete: Eliminar encomenda
|
||||
GoToCatalog: Ir ao catálogo
|
||||
ConfigureOrder: Configurar encomenda
|
||||
|
|
|
@ -1,76 +1,93 @@
|
|||
|
||||
.basket .head {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.basket .head p {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 1.4rem;
|
||||
text-align: right;
|
||||
}
|
||||
.basket .form > p {
|
||||
margin: 0;
|
||||
font-size: 1.4rem;
|
||||
color: white;
|
||||
text-align: right;
|
||||
}
|
||||
.hedera-basket {
|
||||
.head {
|
||||
border-bottom: 1px solid #DDD;
|
||||
|
||||
/* Lines */
|
||||
& > div > div {
|
||||
margin: 15px 0;
|
||||
}
|
||||
& > div > div:first-child {
|
||||
margin: 0;
|
||||
}
|
||||
p {
|
||||
margin: 3px 0;
|
||||
|
||||
.basket .line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 10px 0;
|
||||
height: 80px;
|
||||
}
|
||||
.basket .line:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.basket .line:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.basket .line > .delete {
|
||||
margin: 0 -8px;
|
||||
}
|
||||
.basket .line > .photo {
|
||||
flex: none;
|
||||
border-radius: 50%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
gap: 0;
|
||||
}
|
||||
.basket .line > .info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.basket .line > .info > * {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.basket .line > .info > h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
.basket .line > .info > p {
|
||||
margin: 0;
|
||||
}
|
||||
.basket .line > .info > .tags {
|
||||
color: #777;
|
||||
}
|
||||
.basket .line .subtotal {
|
||||
float: right;
|
||||
}
|
||||
&.important {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.total {
|
||||
|
||||
/* Fields */
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 1.4rem;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.form > p {
|
||||
margin: 0;
|
||||
font-size: 1.4rem;
|
||||
color: white;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.basket td.available-exceeded input {
|
||||
background-color: #FCC;
|
||||
}
|
||||
.basket .icon > img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
/* Lines */
|
||||
|
||||
.line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 10px 0;
|
||||
height: 80px;
|
||||
}
|
||||
.line:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.line:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.line > .delete {
|
||||
margin: 0 -8px;
|
||||
}
|
||||
.line > .photo {
|
||||
flex: none;
|
||||
border-radius: 50%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
gap: 0;
|
||||
}
|
||||
.line > .info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.line > .info > * {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.line > .info > h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
.line > .info > p {
|
||||
margin: 0;
|
||||
}
|
||||
.line > .info > .tags {
|
||||
color: #777;
|
||||
}
|
||||
.line .subtotal {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Fields */
|
||||
|
||||
td.available-exceeded input {
|
||||
background-color: #FCC;
|
||||
}
|
||||
.icon > img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="id" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<div id="title">
|
||||
<h1><t>ShoppingBasket</t></h1>
|
||||
<h1>{{_(params.$.id ? 'Order' : 'ShoppingBasket')}}</h1>
|
||||
</div>
|
||||
<div id="actions">
|
||||
<htk-bar-button
|
||||
|
@ -10,16 +13,38 @@
|
|||
<htk-bar-button
|
||||
icon="local_florist"
|
||||
tip="_Catalog"
|
||||
on-click="this.hash.setAll({form: 'ecomerce/catalog'})"/>
|
||||
on-click="this.onCatalogClick()"/>
|
||||
<htk-bar-button
|
||||
icon="shopping_cart_checkout"
|
||||
tip="_Checkout"
|
||||
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/>
|
||||
on-click="this.onConfirmClick()"/>
|
||||
</div>
|
||||
<div id="form" class="basket">
|
||||
<vn-group>
|
||||
<vn-lot id="lot"/>
|
||||
<db-form v-model="order">
|
||||
<db-model property="model" lot="lot">
|
||||
SELECT o.id, o.sent,
|
||||
ag.description agency, v.code method, ad.nickname
|
||||
FROM myOrder o
|
||||
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
||||
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
|
||||
WHERE o.id = #id;
|
||||
</db-model>
|
||||
</db-form>
|
||||
</vn-group>
|
||||
<div id="form" class="hedera-basket">
|
||||
<div class="box vn-w-sm vn-pa-lg">
|
||||
<div class="head vn-pb-lg">
|
||||
<p>
|
||||
<h5>#{{order.id}}</h5>
|
||||
<div class="vn-mt-md">
|
||||
<h6><t>ShippingInformation</t></h6>
|
||||
<p></p>
|
||||
<p><t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}</p>
|
||||
<p><span id="method"><t>Agency</t></span> {{order.agency}}</p>
|
||||
<p>{{order.nickname}}</p>
|
||||
</div>
|
||||
<p class="total">
|
||||
<t>Total</t>
|
||||
<htk-text format="%.2d€">
|
||||
<db-calc-sum property="param" func="subtotal" model="items"/>
|
||||
|
@ -28,15 +53,16 @@
|
|||
</div>
|
||||
<div class="lines vn-pt-lg">
|
||||
<htk-repeater form-id="iter">
|
||||
<db-model id="items" property="model" updatable="true">
|
||||
<db-model id="items" property="model" lot="lot" updatable="true">
|
||||
SELECT bi.id, bi.amount, bi.price, i.longName item,
|
||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
||||
i.image, im.updated
|
||||
FROM myBasketItem bi
|
||||
FROM myOrderRow bi
|
||||
JOIN vn.item i ON i.id = bi.itemFk
|
||||
LEFT JOIN image im
|
||||
ON im.collectionFk = 'catalog'
|
||||
AND im.name = i.image
|
||||
WHERE orderFk = #id
|
||||
</db-model>
|
||||
<custom>
|
||||
<div class="line">
|
||||
|
|
|
@ -8,18 +8,29 @@ const Catalog = new Class({
|
|||
|
||||
,async open() {
|
||||
let isOk = true;
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
this.orderId = basket.orderId;
|
||||
|
||||
if (!localStorage.getItem('hederaGuest'))
|
||||
isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
||||
else
|
||||
await this.conn.execQuery('CALL mybasket_configureForGuest');
|
||||
if (!localStorage.getItem('hederaGuest')) {
|
||||
if (!this.orderId)
|
||||
return this.hash.setAll({form: 'ecomerce/checkout'});
|
||||
else
|
||||
isOk = await basket.checkRedirect(this.orderId);
|
||||
} else {
|
||||
const resultSet = await this.conn.execQuery(
|
||||
'CALL myOrder_configureForGuest(@orderId); SELECT @orderId;');
|
||||
|
||||
resultSet.fetchResult();
|
||||
this.orderId = resultSet.fetchValue();
|
||||
}
|
||||
|
||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
||||
}
|
||||
|
||||
|
||||
,activate() {
|
||||
document.body.appendChild(this.$.rightPanel);
|
||||
this.$.items.setInfo('i', 'item', 'vn', ['id']);
|
||||
this.$.orderLot.assign({orderId: this.orderId});
|
||||
|
||||
if (localStorage.getItem('hederaView'))
|
||||
this.setView(parseInt(localStorage.getItem('hederaView')));
|
||||
|
@ -98,6 +109,7 @@ const Catalog = new Class({
|
|||
break;
|
||||
}
|
||||
|
||||
params.orderId = this.orderId;
|
||||
const refreshItems = hasTagFilter
|
||||
|| params.search != null
|
||||
|| params.type != null;
|
||||
|
@ -245,7 +257,11 @@ const Catalog = new Class({
|
|||
if (this.isGuest())
|
||||
return;
|
||||
|
||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
||||
this.hash.setAll({
|
||||
form: 'ecomerce/checkout',
|
||||
id: this.orderId,
|
||||
continue: 'catalog'
|
||||
});
|
||||
}
|
||||
|
||||
,onAddItemClick(event, form) {
|
||||
|
@ -255,7 +271,10 @@ const Catalog = new Class({
|
|||
|
||||
this.onEraseClick();
|
||||
this.$.$card.row = form.row;
|
||||
this.$.cardLot.assign({item: form.$.id});
|
||||
this.$.cardLot.assign({
|
||||
item: form.$.id,
|
||||
orderId: this.orderId
|
||||
});
|
||||
this.$.cardPopup.show(event.currentTarget);
|
||||
}
|
||||
|
||||
|
@ -284,7 +303,7 @@ const Catalog = new Class({
|
|||
|
||||
,async onConfirmClick() {
|
||||
var sql = '';
|
||||
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
|
||||
var query = new Sql.String({query: 'CALL myOrder_addItem(#orderId, #warehouse, #item, #amount);'});
|
||||
var amountSum = 0;
|
||||
|
||||
for (var warehouse in this.items) {
|
||||
|
@ -292,6 +311,7 @@ const Catalog = new Class({
|
|||
amountSum += amount;
|
||||
|
||||
const params = {
|
||||
orderId: this.orderId,
|
||||
warehouse: warehouse,
|
||||
item: this.$.cardLot.$.item,
|
||||
amount: amount
|
||||
|
|
|
@ -91,12 +91,14 @@
|
|||
param="producer"/>
|
||||
</vn-group>
|
||||
<vn-group>
|
||||
<vn-lot id="order-lot"/>
|
||||
<db-form v-model="basket">
|
||||
<db-model property="model">
|
||||
SELECT b.id, b.sent, a.description agency, m.code method
|
||||
FROM myBasket b
|
||||
JOIN vn.agencyMode a ON a.id = b.agencyModeFk
|
||||
JOIN vn.deliveryMethod m ON m.id = b.deliveryMethodFk
|
||||
<db-model property="model" lot="order-lot">
|
||||
SELECT o.id, o.sent, a.description agency, m.code method
|
||||
FROM myOrder o
|
||||
JOIN vn.agencyMode a ON a.id = o.agencyModeFk
|
||||
JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
|
||||
WHERE o.id = #orderId
|
||||
</db-model>
|
||||
</db-form>
|
||||
<db-model
|
||||
|
@ -112,7 +114,7 @@
|
|||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
WHERE #filter;
|
||||
CALL myBasket_calcCatalogFull;
|
||||
CALL myOrder_calcCatalogFull(#orderId);
|
||||
SELECT i.id, i.longName item, i.subName,
|
||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
||||
i.relevancy, i.size, i.category,
|
||||
|
@ -261,7 +263,7 @@
|
|||
lot="params"
|
||||
result-index="1"
|
||||
on-status-changed="refreshTitle">
|
||||
CALL myBasket_getAvailable;
|
||||
CALL myOrder_getAvailable(#orderId);
|
||||
SELECT DISTINCT t.id, l.name
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
|
@ -283,7 +285,7 @@
|
|||
property="model"
|
||||
auto-load="false"
|
||||
result-index="1">
|
||||
CALL myBasket_getAvailable;
|
||||
CALL myOrder_getAvailable(#orderId);
|
||||
SELECT DISTINCT l.id, l.name
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
|
@ -304,7 +306,7 @@
|
|||
property="model"
|
||||
auto-load="false"
|
||||
result-index="1">
|
||||
CALL myBasket_getAvailable;
|
||||
CALL myOrder_getAvailable(#orderId);
|
||||
SELECT DISTINCT p.id, p.name
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
|
@ -325,7 +327,7 @@
|
|||
property="model"
|
||||
auto-load="false"
|
||||
result-index="1">
|
||||
CALL myBasket_getAvailable;
|
||||
CALL myOrder_getAvailable(#orderId);
|
||||
SELECT DISTINCT o.id, l.name, o.code
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
|
@ -347,7 +349,7 @@
|
|||
property="model"
|
||||
auto-load="false"
|
||||
result-index="1">
|
||||
CALL myBasket_getAvailable;
|
||||
CALL myOrder_getAvailable(#orderId);
|
||||
SELECT DISTINCT i.category, i.category
|
||||
FROM vn.item i
|
||||
JOIN vn.itemType t ON t.id = i.typeFk
|
||||
|
@ -466,7 +468,7 @@
|
|||
result-index="1"
|
||||
on-status-changed-after="onCardLoad"
|
||||
lot="card-lot">
|
||||
CALL myBasket_calcCatalogFromItem(#item);
|
||||
CALL myOrder_calcCatalogFromItem(#orderId, #item);
|
||||
SELECT l.warehouseFk, w.name warehouse, p.`grouping`,
|
||||
p.price, p.priceKg, p.rate, l.available
|
||||
FROM tmp.ticketLot l
|
||||
|
|
|
@ -44,7 +44,7 @@ export default new Class({
|
|||
}
|
||||
|
||||
this.$.lot.assign({
|
||||
date: date,
|
||||
date,
|
||||
method: row.deliveryMethod,
|
||||
agency: row.agencyModeFk,
|
||||
address: row.addressFk
|
||||
|
@ -59,11 +59,21 @@ export default new Class({
|
|||
async onConfirmClick() {
|
||||
this.disableButtons(true);
|
||||
|
||||
const query = 'CALL myBasket_configure(#date, #method, #agency, #address)';
|
||||
let id = this.$.params.$.id;
|
||||
const params = Object.assign({}, this.$.lot.$);
|
||||
|
||||
let query;
|
||||
if (id) {
|
||||
params.id = id;
|
||||
query = 'CALL myOrder_configure(#id, #date, #method, #agency, #address)';
|
||||
} else {
|
||||
query = 'CALL myOrder_create(@orderId, #date, #method, #agency, #address); SELECT @orderId;';
|
||||
}
|
||||
|
||||
let resultSet;
|
||||
|
||||
try {
|
||||
resultSet = await this.conn.execQuery(query, this.$.lot.$);
|
||||
resultSet = await this.conn.execQuery(query, params);
|
||||
} finally {
|
||||
this.disableButtons(false);
|
||||
}
|
||||
|
@ -71,16 +81,25 @@ export default new Class({
|
|||
if (!resultSet.fetchResult())
|
||||
return;
|
||||
|
||||
if (this.$.orderForm.numRows > 0)
|
||||
if (id) {
|
||||
Htk.Toast.showMessage(_('OrderUpdated'));
|
||||
else
|
||||
Htk.Toast.showMessage(_('OrderStarted'));
|
||||
|
||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
||||
switch(this.hash.$.continue) {
|
||||
case 'catalog':
|
||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
||||
break;
|
||||
default:
|
||||
this.hash.setAll({form: 'ecomerce/basket', id});
|
||||
}
|
||||
} else {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
basket.loadIntoBasket(resultSet.fetchValue());
|
||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
||||
}
|
||||
},
|
||||
|
||||
onCancelClick() {
|
||||
if (this.$.orderForm.numRows > 0)
|
||||
if (this.$.params.$.id)
|
||||
window.history.back();
|
||||
else
|
||||
this.hash.setAll({form: 'ecomerce/orders'});
|
||||
|
@ -150,13 +169,9 @@ export default new Class({
|
|||
this.$.assistant.moveNext();
|
||||
},
|
||||
|
||||
goNextStep() {
|
||||
this.$.assistant.moveNext();
|
||||
},
|
||||
|
||||
onAddressClick(addressId) {
|
||||
this.$.lot.set('address', addressId);
|
||||
this.goNextStep();
|
||||
this.$.assistant.moveNext();
|
||||
},
|
||||
|
||||
onAddressChange() {
|
||||
|
@ -192,9 +207,9 @@ export default new Class({
|
|||
|
||||
const defaults = this.$.defaults.$ || {};
|
||||
if (defaults.agencyModeFk)
|
||||
defaults.push(defaults.agencyModeFk);
|
||||
agencies.push(defaults.agencyModeFk);
|
||||
if (defaults.defaultAgencyFk)
|
||||
defaults.push(defaults.defaultAgencyFk);
|
||||
agencies.push(defaults.defaultAgencyFk);
|
||||
|
||||
for (const agency of agencies)
|
||||
if (model.search('id', agency) !== -1) {
|
||||
|
|
|
@ -1,54 +1,55 @@
|
|||
|
||||
.checkout .bar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hedera-checkout {
|
||||
.bar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Step */
|
||||
/* Step */
|
||||
|
||||
.answers button,
|
||||
.answers p,
|
||||
.radio > div {
|
||||
font-size: 1.2rem;
|
||||
.answers button,
|
||||
.answers p,
|
||||
.radio > div {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.answers .htk-select {
|
||||
max-width: 15em;
|
||||
margin: 0 auto;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
.answers p {
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
.target {
|
||||
max-width: 28em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.address {
|
||||
border-radius: 0.1em;
|
||||
padding: 0.6em 1.4em;
|
||||
}
|
||||
.address.selected {
|
||||
background-color: rgba(1, 1, 1, .1);
|
||||
}
|
||||
.address:hover {
|
||||
cursor: pointer;
|
||||
background-color: rgba(1, 1, 1, .05);
|
||||
}
|
||||
.address p.consignee {
|
||||
font-weight: bold;
|
||||
}
|
||||
.radio {
|
||||
max-width: 20em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.radio > div {
|
||||
padding: 0.5em;
|
||||
}
|
||||
.thin-calendar {
|
||||
max-width: 24em;
|
||||
margin: 0 auto;
|
||||
box-shadow: none;
|
||||
}
|
||||
.htk-assistant .thin {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.answers .htk-select {
|
||||
max-width: 15em;
|
||||
margin: 0 auto;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
.answers p {
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
.target {
|
||||
max-width: 28em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.address {
|
||||
border-radius: 0.1em;
|
||||
padding: 0.6em 1.4em;
|
||||
}
|
||||
.address.selected {
|
||||
background-color: rgba(1, 1, 1, .1);
|
||||
}
|
||||
.address:hover {
|
||||
cursor: pointer;
|
||||
background-color: rgba(1, 1, 1, .05);
|
||||
}
|
||||
.address p.consignee {
|
||||
font-weight: bold;
|
||||
}
|
||||
.radio {
|
||||
max-width: 20em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.radio > div {
|
||||
padding: 0.5em;
|
||||
}
|
||||
.thin-calendar {
|
||||
max-width: 24em;
|
||||
margin: 0 auto;
|
||||
box-shadow: none;
|
||||
}
|
||||
.htk-assistant .thin {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="id" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<vn-group>
|
||||
<vn-lot id="lot" on-change="this.onAddressChange()"/>
|
||||
<db-form id="defaults" on-ready="onValuesReady">
|
||||
|
@ -8,10 +11,11 @@
|
|||
</db-model>
|
||||
</db-form>
|
||||
<db-form id="order-form" on-ready="onValuesReady">
|
||||
<db-model property="model">
|
||||
<db-model property="model" lot="params">
|
||||
SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk
|
||||
FROM myBasket o
|
||||
FROM myOrder o
|
||||
JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
|
||||
WHERE o.id = #id
|
||||
</db-model>
|
||||
</db-form>
|
||||
<db-model id="agencies"
|
||||
|
@ -54,7 +58,7 @@
|
|||
tip="_Cancel"
|
||||
on-click="onCancelClick"/>
|
||||
</div>
|
||||
<div id="form" class="checkout">
|
||||
<div id="form" class="hedera-checkout">
|
||||
<div class="vn-w-sm">
|
||||
<div class="box bar">
|
||||
<htk-assistant-bar
|
||||
|
|
|
@ -5,8 +5,13 @@ export default new Class({
|
|||
Template: require('./ui.xml'),
|
||||
|
||||
async open() {
|
||||
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
try {
|
||||
await basket.check(this.hash.$.id);
|
||||
} catch (err) {
|
||||
Htk.Toast.showError(err.message);
|
||||
}
|
||||
await Hedera.Form.prototype.open.call(this);
|
||||
},
|
||||
|
||||
onOrderReady(form) {
|
||||
|
@ -106,25 +111,22 @@ export default new Class({
|
|||
Vn.Node.addClass(this.$[id], 'selected');
|
||||
},
|
||||
|
||||
disableButtons(disable) {
|
||||
this.$.modify.disabled = disable;
|
||||
this.$.confirm.disabled = disable;
|
||||
},
|
||||
|
||||
onModifyClick() {
|
||||
window.history.back();
|
||||
},
|
||||
|
||||
async onConfirmClick() {
|
||||
this.disableButtons(true);
|
||||
await this.$.confirmQuery.execute();
|
||||
},
|
||||
|
||||
onConfirm(query, resultSet) {
|
||||
this.disableButtons(false);
|
||||
|
||||
if (resultSet.fetchResult())
|
||||
Vn.Node.disableInputs(this.node);
|
||||
try {
|
||||
await this.conn.execQuery(
|
||||
'CALL myOrder_confirm(#id)',
|
||||
this.$.params.$
|
||||
);
|
||||
Hedera.Basket.unload();
|
||||
this.$.successDialog.show();
|
||||
} finally {
|
||||
Vn.Node.disableInputs(this.node, false);
|
||||
}
|
||||
},
|
||||
|
||||
async onDialogResponse() {
|
||||
|
|
|
@ -1,93 +1,95 @@
|
|||
|
||||
.confirm .summary {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.confirm p {
|
||||
margin: .2em 0;
|
||||
}
|
||||
.hedera-confirm {
|
||||
.summary {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
p {
|
||||
margin: .2em 0;
|
||||
}
|
||||
|
||||
/* Table */
|
||||
/* Table */
|
||||
|
||||
.confirm .debt-info {
|
||||
padding: 0;
|
||||
}
|
||||
.confirm .debt-info > table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.confirm td {
|
||||
padding: .15em 0;
|
||||
}
|
||||
.confirm .sum-total > td {
|
||||
border-top: solid 1px #DDD;
|
||||
font-weight: bold;
|
||||
}
|
||||
.confirm .currency {
|
||||
text-align: right;
|
||||
}
|
||||
.confirm .credit-info {
|
||||
display: none;
|
||||
}
|
||||
.confirm .exceeded-info {
|
||||
display: none;
|
||||
color: #E53935;
|
||||
}
|
||||
.debt-info {
|
||||
padding: 0;
|
||||
}
|
||||
.debt-info > table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td {
|
||||
padding: .15em 0;
|
||||
}
|
||||
.sum-total > td {
|
||||
border-top: solid 1px #DDD;
|
||||
font-weight: bold;
|
||||
}
|
||||
.currency {
|
||||
text-align: right;
|
||||
}
|
||||
.credit-info {
|
||||
display: none;
|
||||
}
|
||||
.exceeded-info {
|
||||
display: none;
|
||||
color: #E53935;
|
||||
}
|
||||
|
||||
/* Pay */
|
||||
/* Pay */
|
||||
|
||||
.confirm .amount-selector,
|
||||
.confirm .pay-methods > div {
|
||||
display: none;
|
||||
}
|
||||
.confirm .pay-methods > div {
|
||||
margin: .3em 0;
|
||||
}
|
||||
.confirm .pay-methods > div > label > input[type=radio] {
|
||||
margin: 0;
|
||||
margin-right: .5em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.confirm .pay-methods > div > div {
|
||||
padding: .5em 1.5em;
|
||||
display: none;
|
||||
}
|
||||
.confirm .pay-methods > div.selected > div {
|
||||
display: block;
|
||||
}
|
||||
.confirm .transfer-account {
|
||||
margin-top: .5em;
|
||||
}
|
||||
.confirm .transfer-account > p {
|
||||
margin: .1em 0;
|
||||
}
|
||||
.amount-selector,
|
||||
.pay-methods > div {
|
||||
display: none;
|
||||
}
|
||||
.pay-methods > div {
|
||||
margin: .3em 0;
|
||||
}
|
||||
.pay-methods > div > label > input[type=radio] {
|
||||
margin: 0;
|
||||
margin-right: .5em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.pay-methods > div > div {
|
||||
padding: .5em 1.5em;
|
||||
display: none;
|
||||
}
|
||||
.pay-methods > div.selected > div {
|
||||
display: block;
|
||||
}
|
||||
.transfer-account {
|
||||
margin-top: .5em;
|
||||
}
|
||||
.transfer-account > p {
|
||||
margin: .1em 0;
|
||||
}
|
||||
|
||||
.confirm .payment > div {
|
||||
margin-bottom: 1.4em;
|
||||
.payment > div {
|
||||
margin-bottom: 1.4em;
|
||||
}
|
||||
.payment > .button-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.payment > .button-bar button{
|
||||
font-size: 1.2rem;
|
||||
border-radius: 2rem;
|
||||
padding: .5rem 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
.modify-order {
|
||||
border: 1px solid #1a1a1a;
|
||||
}
|
||||
.modify-order:hover {
|
||||
color: white;
|
||||
background-color: #1a1a1a;
|
||||
}
|
||||
.confirm-order {
|
||||
border: 1px solid #8cc63f;
|
||||
background-color: #8cc63f;
|
||||
color: white;
|
||||
}
|
||||
.confirm-order:hover {
|
||||
background-color: transparent;
|
||||
color: #6b5;
|
||||
}
|
||||
}
|
||||
.confirm .payment > .button-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0;
|
||||
margin-top: 32px;
|
||||
}
|
||||
.confirm .payment > .button-bar button{
|
||||
font-size: 1.2rem;
|
||||
border-radius: 2rem;
|
||||
padding: .5rem 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
.confirm .modify-order {
|
||||
border: 1px solid #1a1a1a;
|
||||
}
|
||||
.confirm .modify-order:hover {
|
||||
color: white;
|
||||
background-color: #1a1a1a;
|
||||
}
|
||||
.confirm .confirm-order {
|
||||
border: 1px solid #8cc63f;
|
||||
background-color: #8cc63f;
|
||||
color: white;
|
||||
}
|
||||
.confirm .confirm-order:hover {
|
||||
background-color: transparent;
|
||||
color: #6b5;
|
||||
}
|
|
@ -1,13 +1,16 @@
|
|||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="id" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<vn-group>
|
||||
<db-form v-model="order" on-ready="onOrderReady">
|
||||
<db-model property="model" result-index="1">
|
||||
CALL myBasket_getTax;
|
||||
<db-model property="model" result-index="1" lot="params">
|
||||
CALL myOrder_getTax(#id);
|
||||
SELECT o.id, o.sent, o.notes, o.companyFk,
|
||||
ag.description agency, v.code method,
|
||||
ad.nickname, ad.postalCode, ad.city, ad.street,
|
||||
t.*, c.credit, myClient_getDebt(NULL) debt
|
||||
FROM myBasket o
|
||||
FROM myOrder o
|
||||
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
||||
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
|
||||
|
@ -17,27 +20,25 @@
|
|||
IFNULL(SUM(taxableBase), 0) taxableBase,
|
||||
IFNULL(SUM(tax), 0) tax
|
||||
FROM tmp.orderAmount
|
||||
) t;
|
||||
) t
|
||||
WHERE o.id = #id;
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.orderAmount,
|
||||
tmp.orderTax;
|
||||
</db-model>
|
||||
</db-form>
|
||||
<db-query id="confirm-query" on-ready="onConfirm">
|
||||
CALL myBasket_confirm
|
||||
</db-query>
|
||||
</vn-group>
|
||||
<div id="title">
|
||||
<h1><t>Order summary</t></h1>
|
||||
</div>
|
||||
<div id="form" class="confirm">
|
||||
<div id="form" class="hedera-confirm">
|
||||
<div class="vn-w-sm">
|
||||
<div class="box vn-pa-lg summary">
|
||||
<div>
|
||||
<div class="delivery">
|
||||
<h6><t>ShippingInformation</t></h6>
|
||||
<p>
|
||||
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
||||
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
||||
</p>
|
||||
<p>
|
||||
<span id="method"><t>Agency</t></span> {{order.agency}}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div id="title">
|
||||
<h1><t>Invoices</t></h1>
|
||||
</div>
|
||||
<div id="form" class="invoices">
|
||||
<div id="form" class="hedera-invoices">
|
||||
<htk-grid
|
||||
class="box vn-w-sm"
|
||||
show-header="false">
|
||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: N encàrrec
|
|||
DateMake: Data de creació
|
||||
DateExit: Data d'eixida
|
||||
SendMethod: Forma d'enviament
|
||||
LastOrders: Últimes comandes
|
||||
LastOrders: Comandes confirmades
|
||||
'Balance:': 'Saldo:'
|
||||
PaymentInfo: >-
|
||||
La quantitat mostrada és el teu saldo pendent (negatiu) o favorable a dia
|
||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Order number
|
|||
DateMake: Creation date
|
||||
DateExit: Shipping date
|
||||
SendMethod: Delivery method
|
||||
LastOrders: Last orders
|
||||
LastOrders: Confirmed orders
|
||||
'Balance:': 'Balance:'
|
||||
PaymentInfo: >-
|
||||
The amount shown is your slope (negative) or favorable balance today, it
|
||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Nº pedido
|
|||
DateMake: Fecha de creación
|
||||
DateExit: Fecha de salida
|
||||
SendMethod: Forma de envío
|
||||
LastOrders: Últimos pedidos
|
||||
LastOrders: Pedidos confirmados
|
||||
'Balance:': 'Saldo:'
|
||||
PaymentInfo: >-
|
||||
La cantidad mostrada es tu saldo pendiente (negativa) o favorable a día de
|
||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Numéro de commande
|
|||
DateMake: Date de creation
|
||||
DateExit: Date de sortie
|
||||
SendMethod: Typo
|
||||
LastOrders: Les dernières commandes
|
||||
LastOrders: Commandes confirmées
|
||||
'Balance:': 'Balance:'
|
||||
PaymentInfo: >-
|
||||
Le montant indiqué est votre pente (négative) ou balance favorable
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
OpenOrders: Open orders
|
||||
StartOrder: Start order
|
||||
ContinueOrder: Continue order
|
||||
OrderNumber: Order number
|
||||
DateMake: Creation date
|
||||
DateExit: Shipping date
|
||||
SendMethod: Delivery method
|
||||
LastOrders: Last orders
|
||||
'Balance:': 'Balance:'
|
||||
PaymentInfo: >-
|
||||
Үзүүлсэн хэмжээ цаашид захиалга эзэлж биш, таны налуу (сөрөг), эсвэл
|
||||
тааламжтай тэнцвэр нь өнөөдөр юм. Хэрэв та дүн арилгаж гэж хэлж байсан нь доош
|
||||
нь төлбөр хийж, өөрийн хүссэн хэмжээгээр орж хүсэж байгаа бол таны захиалга
|
||||
ирдэг бол авах, энэ хэмжээ тэнцүү буюу 0-ээс их байх ёстой.
|
||||
MakePayment: Make payment
|
||||
Company: Company
|
||||
Pending: Pending
|
||||
Pay: Pay
|
||||
Basket: Basket
|
||||
ShoppingBasket: Shopping basket
|
||||
SeeOrder: Show details of the order
|
||||
Delivery: Delivery
|
||||
TicketNumber: Ticket number
|
||||
SentAddress: Delivery address
|
||||
Consignee: Consignee
|
||||
Boxes: Bundles
|
||||
TotalWithVAT: Total with VAT
|
||||
PayOrder: Pay order
|
||||
'AmountToPay:': 'Amount to pay (€):'
|
||||
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
|
||||
Accept: Accept
|
|
@ -5,7 +5,7 @@ OrderNumber: Nº pedido
|
|||
DateMake: Data de criação
|
||||
DateExit: Data de saída
|
||||
SendMethod: Forma de envío
|
||||
LastOrders: Últimas encomendas
|
||||
LastOrders: Encomendas confirmadas
|
||||
'Balance:': 'Saldo:'
|
||||
PaymentInfo: >-
|
||||
A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
/* List */
|
||||
|
||||
.orders .htk-list .total {
|
||||
.hedera-orders .htk-list .total {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
tip="_ShoppingBasket"
|
||||
on-click="onBasketClick"/>
|
||||
</div>
|
||||
<div id="form" class="orders">
|
||||
<div id="form" class="hedera-orders">
|
||||
<htk-repeater
|
||||
class="htk-list box confirmed vn-w-sm"
|
||||
form-id="iter"
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import './style.scss';
|
||||
|
||||
export default new Class({
|
||||
Extends: Hedera.Form,
|
||||
Template: require('./ui.xml'),
|
||||
|
||||
activate() {
|
||||
this.basket = new Hedera.Basket(this.app);
|
||||
this.$.orders.setInfo('o', 'myOrder', 'hedera', ['id'], 'id');
|
||||
},
|
||||
|
||||
async onRemoveOrderClick(form) {
|
||||
if (confirm(_('AreYouSureDeleteOrder')))
|
||||
await form.deleteRow();
|
||||
},
|
||||
|
||||
async loadOrder(id) {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
await basket.load(id);
|
||||
}
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
Pending: Pendents
|
|
@ -0,0 +1 @@
|
|||
Pending: Pending
|
|
@ -0,0 +1,8 @@
|
|||
Pending: Pendientes
|
||||
PendingOrders: Pedidos pendientes
|
||||
NewOrder: Nuevo pedido
|
||||
ViewOrder: Ver pedido
|
||||
RemoveOrder: Eliminar pedido
|
||||
LoadOrderIntoCart: Cargar pedido en la cesta
|
||||
AreYouSureDeleteOrder: ¿Seguro que quieres borrar el pedido?
|
||||
OrderLoadedIntoBasket: ¡Pedido cargado en la cesta!
|
|
@ -0,0 +1 @@
|
|||
Pending: Pendents
|
|
@ -0,0 +1 @@
|
|||
Pending: Pendientes
|
|
@ -0,0 +1,54 @@
|
|||
<vn>
|
||||
<div id="title">
|
||||
<h1><t>PendingOrders</t></h1>
|
||||
</div>
|
||||
<div id="actions">
|
||||
<htk-bar-button
|
||||
class="start-order"
|
||||
icon="add_shopping_cart"
|
||||
tip="_NewOrder"
|
||||
on-click="hash.setAll({form: 'ecomerce/checkout'})"/>
|
||||
</div>
|
||||
<div id="form" class="hedera-pending">
|
||||
<htk-repeater
|
||||
class="htk-list box confirmed vn-w-sm"
|
||||
form-id="iter">
|
||||
<db-model property="model" id="orders">
|
||||
SELECT o.id, o.sent, o.deliveryMethodFk, o.total,
|
||||
a.nickname, am.description agency
|
||||
FROM myOrder o
|
||||
JOIN myAddress a ON a.id = o.addressFk
|
||||
JOIN vn.agencyMode am ON am.id = o.agencyModeFk
|
||||
WHERE NOT o.isConfirmed
|
||||
ORDER BY o.sent DESC
|
||||
</db-model>
|
||||
<custom>
|
||||
<a class="item"
|
||||
title="{{_('ViewOrder')}}"
|
||||
href="{{'#!form=ecomerce/basket&id='+iter.id}}">
|
||||
<div class="content">
|
||||
<p class="important">
|
||||
{{Vn.Value.format(iter.sent, '%D')}}
|
||||
</p>
|
||||
<p>#{{iter.id}}</p>
|
||||
<p>{{iter.nickname}}</p>
|
||||
<p>{{iter.agency}}</p>
|
||||
<p>{{Vn.Value.format(iter.total, '%.2d€')}}</p>
|
||||
</div>
|
||||
<div
|
||||
class="actions"
|
||||
on-click="$event.preventDefault()">
|
||||
<htk-button
|
||||
icon="delete"
|
||||
tip="_RemoveOrder"
|
||||
on-click="this.onRemoveOrderClick($iter)"/>
|
||||
<htk-button
|
||||
icon="shopping_bag"
|
||||
tip="_LoadOrderIntoCart"
|
||||
on-click="this.loadOrder(iter.id)"/>
|
||||
</div>
|
||||
</a>
|
||||
</custom>
|
||||
</htk-repeater>
|
||||
</div>
|
||||
</vn>
|
|
@ -1,78 +1,79 @@
|
|||
|
||||
/* Header */
|
||||
.hedera-ticket {
|
||||
/* Header */
|
||||
|
||||
.ticket .head {
|
||||
padding: 0;
|
||||
padding-bottom: 3px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.ticket .head > div > div {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.ticket .head > div > div:first-child {
|
||||
margin: 0;
|
||||
}
|
||||
.ticket .head p {
|
||||
margin: 3px 0;
|
||||
}
|
||||
.ticket .head p.important {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ticket .total {
|
||||
text-align: right;
|
||||
}
|
||||
.ticket .packages {
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #DDD;
|
||||
display: block;
|
||||
}
|
||||
.head {
|
||||
padding: 0;
|
||||
padding-bottom: 3px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.head > div > div {
|
||||
margin: 15px 0;
|
||||
}
|
||||
.head > div > div:first-child {
|
||||
margin: 0;
|
||||
}
|
||||
.head p {
|
||||
margin: 3px 0;
|
||||
}
|
||||
.head p.important {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.total {
|
||||
text-align: right;
|
||||
}
|
||||
.packages {
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #DDD;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Lines */
|
||||
/* Lines */
|
||||
|
||||
.ticket .line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 10px 0;
|
||||
height: 80px;
|
||||
.line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin: 10px 0;
|
||||
height: 80px;
|
||||
}
|
||||
.line:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.line > .photo {
|
||||
flex: none;
|
||||
border-radius: 50%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
gap: 0;
|
||||
}
|
||||
.line > .info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.line > .info > * {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.line > .info > h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.line > .info > p {
|
||||
margin: 0;
|
||||
}
|
||||
.line > .info > .tags {
|
||||
color: #777;
|
||||
}
|
||||
.line > .info .discount {
|
||||
color: green;
|
||||
}
|
||||
.line > .info > .subtotal {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.ticket .line:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.ticket .line > .photo {
|
||||
flex: none;
|
||||
border-radius: 50%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
gap: 0;
|
||||
}
|
||||
.ticket .line > .info {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ticket .line > .info > * {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ticket .line > .info > h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.ticket .line > .info > p {
|
||||
margin: 0;
|
||||
}
|
||||
.ticket .line > .info > .tags {
|
||||
color: #777;
|
||||
}
|
||||
.ticket .line > .info .discount {
|
||||
color: green;
|
||||
}
|
||||
.ticket .line > .info > .subtotal {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
tip="_Print delivery note"
|
||||
on-click="this.onPrintClick()"/>
|
||||
</div>
|
||||
<div id="form" class="ticket">
|
||||
<div id="form" class="hedera-ticket">
|
||||
<div class="box vn-w-sm vn-pa-lg">
|
||||
<htk-loader class="head" form="ticket-form">
|
||||
<h5>#{{ticket.id}}</h5>
|
||||
|
|
|
@ -70,7 +70,9 @@ export const routes = {
|
|||
orders:
|
||||
() => import('ecomerce/orders'),
|
||||
ticket:
|
||||
() => import('ecomerce/ticket')
|
||||
() => import('ecomerce/ticket'),
|
||||
pending:
|
||||
() => import('ecomerce/pending')
|
||||
},
|
||||
news: {
|
||||
new:
|
||||
|
|
|
@ -9,6 +9,24 @@ module.exports = new Class({
|
|||
,get() {
|
||||
return this._conn;
|
||||
}
|
||||
},
|
||||
hash: {
|
||||
type: Vn.Hash
|
||||
,get() {
|
||||
return this._hash;
|
||||
}
|
||||
},
|
||||
gui: {
|
||||
type: Gui
|
||||
,get() {
|
||||
return this._gui;
|
||||
}
|
||||
},
|
||||
login: {
|
||||
type: Login
|
||||
,get() {
|
||||
return this._login;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +53,7 @@ module.exports = new Class({
|
|||
|
||||
,showLogin() {
|
||||
const login = this._login = new Login({
|
||||
app: this,
|
||||
conn: this._conn,
|
||||
hash: this._hash
|
||||
});
|
||||
|
@ -47,6 +66,7 @@ module.exports = new Class({
|
|||
if (this._gui) return;
|
||||
|
||||
const gui = this._gui = new Gui({
|
||||
app: this,
|
||||
conn: this._conn,
|
||||
hash: this._hash
|
||||
});
|
||||
|
@ -198,11 +218,11 @@ module.exports = new Class({
|
|||
,async _onConnError(conn, err) {
|
||||
if (!(err instanceof Vn.JsonException)) return;
|
||||
switch (err.exception) {
|
||||
case 'UserDisabled':
|
||||
case 'UserDisabledError':
|
||||
Htk.Toast.showError(_('User disabled'));
|
||||
await this._logout();
|
||||
return;
|
||||
case 'OutdatedVersion':
|
||||
case 'OutdatedVersionError':
|
||||
this._newVersion();
|
||||
return;
|
||||
}
|
||||
|
@ -222,8 +242,8 @@ module.exports = new Class({
|
|||
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
||||
else {
|
||||
switch (err.exception) {
|
||||
case 'UserDisabled':
|
||||
case 'OutdatedVersion':
|
||||
case 'UserDisabledError':
|
||||
case 'OutdatedVersionError':
|
||||
return;
|
||||
}
|
||||
if (err.statusCode == 401)
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
module.exports = {
|
||||
async check(conn, hash) {
|
||||
this.hash = hash;
|
||||
const resultSet = await conn.execQuery('CALL myBasket_check');
|
||||
|
||||
const status = resultSet.fetchValue();
|
||||
if (!status) return;
|
||||
|
||||
const isOk = status == 'UPDATED' || status == 'OK';
|
||||
|
||||
if (status == 'UPDATED')
|
||||
Htk.Toast.showWarning(_('Order items updated'));
|
||||
|
||||
if (!isOk)
|
||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
||||
|
||||
return isOk;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
module.exports = class {
|
||||
constructor(app) {
|
||||
this.app = app;
|
||||
let orderId = localStorage.getItem('hederaBasket');
|
||||
if (orderId) orderId = parseInt(orderId);
|
||||
this.orderId = orderId;
|
||||
}
|
||||
async check(orderId) {
|
||||
const resultSet = await this.app.conn.execQuery(
|
||||
'CALL myOrder_checkConfig(#id)',
|
||||
{id: orderId}
|
||||
);
|
||||
resultSet.fetchValue();
|
||||
}
|
||||
async checkRedirect(orderId) {
|
||||
try {
|
||||
await this.check(orderId);
|
||||
return true;
|
||||
} catch(err) {
|
||||
Htk.Toast.showError(err.message);
|
||||
this.app.hash.setAll({
|
||||
form: 'ecomerce/checkout',
|
||||
id: orderId,
|
||||
continue: 'catalog'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async load(orderId) {
|
||||
this.loadIntoBasket(orderId);
|
||||
if (!await this.checkRedirect(orderId)) return;
|
||||
this.app.hash.setAll({
|
||||
form: 'ecomerce/catalog'
|
||||
});
|
||||
}
|
||||
loadIntoBasket(orderId) {
|
||||
if (this.orderId != orderId) {
|
||||
localStorage.setItem('hederaBasket', orderId);
|
||||
this.orderId = orderId;
|
||||
Htk.Toast.showMessage(_('OrderLoadedIntoBasket'));
|
||||
}
|
||||
}
|
||||
static unload() {
|
||||
localStorage.removeItem('hederaBasket');
|
||||
}
|
||||
};
|
||||
|
|
@ -7,6 +7,7 @@ module.exports = new Class({
|
|||
|
||||
,initialize(gui) {
|
||||
this.gui = gui;
|
||||
this.app = gui.app;
|
||||
this.conn = gui.conn;
|
||||
this.hash = gui.hash;
|
||||
}
|
||||
|
|
|
@ -50,19 +50,16 @@ module.exports = new Class({
|
|||
this.doc.body.appendChild(this.node);
|
||||
Htk.Toast.pushTop(this.$.formHolder);
|
||||
|
||||
await this.refreshUserData();
|
||||
Vn.Node.setText(this.$.userName, this.user.nickname);
|
||||
|
||||
const resultSet = await this._conn.execQuery(
|
||||
'SELECT id, name, nickname FROM account.myUser;'
|
||||
+'SELECT defaultForm FROM config;'
|
||||
'SELECT defaultForm FROM config;'
|
||||
+'SELECT url FROM imageConfig;'
|
||||
+'SELECT dbproduccion FROM vn.config;'
|
||||
+'SELECT productionDomain, testDomain FROM config;'
|
||||
);
|
||||
|
||||
// Retrieving the user name
|
||||
|
||||
this.user = resultSet.fetchObject();
|
||||
Vn.Node.setText(this.$.userName, this.user.nickname);
|
||||
|
||||
// Retrieving configuration parameters
|
||||
|
||||
Vn.Config.defaultForm = resultSet.fetchValue();
|
||||
|
@ -119,6 +116,12 @@ module.exports = new Class({
|
|||
Htk.Toast.showWarning(_('By using this site you accept cookies'));
|
||||
}
|
||||
}
|
||||
|
||||
,async refreshUserData() {
|
||||
const resultSet = await this._conn.execQuery(
|
||||
'SELECT id, name, nickname FROM account.myUser');
|
||||
this.user = resultSet.fetchObject();
|
||||
}
|
||||
|
||||
,async hide() {
|
||||
if (!this._shown)
|
||||
|
@ -463,29 +466,41 @@ module.exports = new Class({
|
|||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
|
||||
|
||||
/**
|
||||
* Supplants another user.
|
||||
*
|
||||
* @param {String} supplantUser The user name
|
||||
*/
|
||||
,async supplantUser(supplantUser) {
|
||||
const json = await this._conn.send('client/supplant', {supplantUser});
|
||||
this._conn.token = json;
|
||||
sessionStorage.setItem('supplantUser', supplantUser);
|
||||
|
||||
await this.refreshUserData();
|
||||
Vn.Node.setText(this.$.supplanted, this.user.nickname);
|
||||
this.$.supplant.classList.toggle('show', true);
|
||||
await this.loadMenu();
|
||||
}
|
||||
|
||||
/*
|
||||
* Ends the user supplanting and restores the original login.
|
||||
*/
|
||||
,async onSupplantExitClick() {
|
||||
this._conn.post('Accounts/logout');
|
||||
this._conn.fetchToken();
|
||||
sessionStorage.removeItem('supplantUser');
|
||||
|
||||
this.$.supplant.classList.toggle('show', false);
|
||||
await this.refreshUserData();
|
||||
await this.loadMenu();
|
||||
this._onFormChange();
|
||||
}
|
||||
|
||||
,async supplantInit() {
|
||||
var user = sessionStorage.getItem('supplantUser');
|
||||
if (user == null) return;
|
||||
|
||||
await this._conn.supplantUser(user);
|
||||
sessionStorage.setItem('supplantUser', user);
|
||||
await this.loadMenu();
|
||||
|
||||
const res = await this._conn.execQuery(
|
||||
'SELECT nickname FROM account.myUser');
|
||||
|
||||
const userName = res.fetchValue();
|
||||
Vn.Node.setText(this.$.supplanted, userName);
|
||||
this.$.supplant.classList.toggle('show', true);
|
||||
}
|
||||
|
||||
,async onSupplantExitClick() {
|
||||
this.$.supplant.classList.toggle('show', false);
|
||||
await this._conn.supplantEnd();
|
||||
sessionStorage.removeItem('supplantUser');
|
||||
await this.loadMenu();
|
||||
this._onFormChange();
|
||||
await this.supplantUser(user);
|
||||
}
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Destroy
|
||||
|
|
|
@ -10,6 +10,6 @@ Hedera = module.exports = {
|
|||
,Report : require('./report')
|
||||
,App : require('./app')
|
||||
,Tpv : require('./tpv')
|
||||
,BasketChecker : require('./basket-checker')
|
||||
,Basket : require('./basket')
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
|||
Home: Inici
|
||||
Orders: Encàrrecs
|
||||
Basket: Cistella
|
||||
Last orders: Últims comandes
|
||||
Pending orders: Pendents
|
||||
Last orders: Confirmades
|
||||
Invoices: Factures
|
||||
Catalog: Catàleg
|
||||
About: Coneix-nos
|
||||
|
|
|
@ -34,7 +34,8 @@ AppName: Verdnatura
|
|||
Home: Home
|
||||
Orders: Orders
|
||||
Basket: Basket
|
||||
Last orders: Last orders
|
||||
Pending orders: Pending
|
||||
Last orders: Confirmed
|
||||
Invoices: Invoices
|
||||
Catalog: Catalog
|
||||
About: About
|
||||
|
|
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
|||
Home: Inicio
|
||||
Orders: Pedidos
|
||||
Basket: Cesta
|
||||
Last orders: Últimos pedidos
|
||||
Pending orders: Pendientes
|
||||
Last orders: Confirmados
|
||||
Invoices: Facturas
|
||||
Catalog: Catálogo
|
||||
About: Conócenos
|
||||
|
|
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
|||
Home: Accueil
|
||||
Orders: Commandes
|
||||
Basket: Panier
|
||||
Last orders: Dernières commandes
|
||||
Pending orders: En attente
|
||||
Last orders: Confirmées
|
||||
Invoices: Facturas
|
||||
Catalog: Catalogue
|
||||
About: Nous
|
||||
|
|
|
@ -36,7 +36,8 @@ AppName: VerdNatura
|
|||
Home: Principio
|
||||
Orders: Encomendas
|
||||
Basket: Cesta
|
||||
Last orders: Últimas encomendas
|
||||
Pending orders: Pendentes
|
||||
Last orders: Confirmados
|
||||
Invoices: Facturas
|
||||
Catalog: Catálogo
|
||||
About: Conheça-nos
|
||||
|
|
|
@ -9,11 +9,10 @@ module.exports = new Class({
|
|||
this.tpvStatus = this.hash.$.tpvStatus;
|
||||
|
||||
if (this.tpvStatus) {
|
||||
const query = 'CALL myTpvTransaction_end(#transaction, #status)';
|
||||
this.conn.execQuery(query, {
|
||||
transaction: this.tpvOrder,
|
||||
this.conn.post('TpvTransactions/end', {
|
||||
orderId: this.tpvOrder,
|
||||
status: this.tpvStatus
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return this.tpvStatus;
|
||||
|
@ -24,22 +23,18 @@ module.exports = new Class({
|
|||
}
|
||||
|
||||
,async _realPay(amount, company) {
|
||||
if (!isNumeric(amount) || amount <= 0)
|
||||
throw new UserError(_('AmountError'));
|
||||
|
||||
let json;
|
||||
|
||||
try {
|
||||
json = await this.conn.send('tpv/transaction', {
|
||||
amount: parseInt(amount)
|
||||
,urlOk: this._makeUrl('ok')
|
||||
,urlKo: this._makeUrl('ko')
|
||||
,company: company
|
||||
});
|
||||
} catch(err) {
|
||||
throw new UserError(_('PayError'));
|
||||
if (!isNumeric(amount) || amount <= 0) {
|
||||
Htk.Toast.showError(_('AmountError'));
|
||||
return;
|
||||
}
|
||||
|
||||
const json = await this.conn.post('TpvTransactions/start', {
|
||||
amount: parseInt(amount),
|
||||
urlOk: this._makeUrl('ok'),
|
||||
urlKo: this._makeUrl('ko'),
|
||||
company
|
||||
});
|
||||
|
||||
const postValues = json.postValues;
|
||||
|
||||
const form = document.createElement('form');
|
||||
|
|
|
@ -10,15 +10,7 @@ module.exports = new Class({
|
|||
value: {
|
||||
type: String
|
||||
,set(x) {
|
||||
if (Vn.Value.compare(x, this._value))
|
||||
return;
|
||||
|
||||
if (x instanceof Date)
|
||||
x = x.clone();
|
||||
|
||||
this.valueChanged(x);
|
||||
this.putValue(x);
|
||||
this._notifyChanges();
|
||||
this._setValue(x);
|
||||
}
|
||||
,get() {
|
||||
return this._value;
|
||||
|
@ -109,11 +101,11 @@ module.exports = new Class({
|
|||
,_lockField: false
|
||||
|
||||
,_setValue(newValue) {
|
||||
if (!this._putValue(newValue))
|
||||
return;
|
||||
|
||||
if (!this._putValue(newValue)) return;
|
||||
newValue = this._value;
|
||||
|
||||
if (!this._lockField)
|
||||
this.putValue(newValue);
|
||||
this.putValue(this._value);
|
||||
|
||||
if (this.conditionalFunc)
|
||||
this.conditionalFunc(this, newValue);
|
||||
|
|
|
@ -54,7 +54,7 @@ module.exports = new Class({
|
|||
,render() {
|
||||
var radio = Vn.Browser.createRadio('', this.doc);
|
||||
radio.checked = false;
|
||||
radio.addEventListener('change', this._onChange.bind(this));
|
||||
radio.addEventListener('change', () => this._onChange());
|
||||
this._node = radio;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ var htkRadioGroupUid = 0;
|
|||
module.exports = new Class({
|
||||
Extends: Htk.Field
|
||||
,Tag: 'htk-radio-group'
|
||||
|
||||
,radioLock: false
|
||||
|
||||
,initialize(props) {
|
||||
this.clear();
|
||||
|
|
|
@ -50,9 +50,8 @@ module.exports = new Class({
|
|||
|
||||
if (user !== null && user !== undefined) {
|
||||
params = {
|
||||
user: user,
|
||||
password: pass,
|
||||
remember: remember
|
||||
user,
|
||||
password: pass
|
||||
};
|
||||
} else
|
||||
params = null;
|
||||
|
@ -96,24 +95,6 @@ module.exports = new Class({
|
|||
this.clearToken();
|
||||
},
|
||||
|
||||
/**
|
||||
* Supplants another user.
|
||||
*
|
||||
* @param {String} supplantUser The user name
|
||||
*/
|
||||
async supplantUser(supplantUser) {
|
||||
const json = await this.send('client/supplant', {supplantUser});
|
||||
this.token = json;
|
||||
},
|
||||
|
||||
/**
|
||||
* Ends the user supplanting and restores the last login.
|
||||
*/
|
||||
async supplantEnd() {
|
||||
await this.post('Accounts/logout');
|
||||
this.fetchToken();
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes the specified REST service with the given params and calls
|
||||
* the callback when response is received.
|
||||
|
@ -279,7 +260,7 @@ module.exports = new Class({
|
|||
if (exception) {
|
||||
exception = exception
|
||||
.replace(/\\/g, '.')
|
||||
.replace(/Exception$/, '')
|
||||
.replace(/Exception$/, 'Error')
|
||||
.replace(/^Vn\.Web\./, '');
|
||||
|
||||
err.exception = exception;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/**
|
||||
* Holds a plain key-value javascript object and monitorizes changes over it.
|
||||
*/
|
||||
|
@ -10,14 +9,14 @@ module.exports = new Class({
|
|||
*/
|
||||
params: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Shortcut for params property.
|
||||
*/
|
||||
,$: {
|
||||
$: {
|
||||
type: Object
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a value from the lot.
|
||||
|
@ -25,9 +24,9 @@ module.exports = new Class({
|
|||
* @param {string} field The field name
|
||||
* @return {*} The field value
|
||||
*/
|
||||
,get(field) {
|
||||
return this.params[field];
|
||||
}
|
||||
get(field) {
|
||||
return this.params[field];
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a value on the lot.
|
||||
|
@ -35,49 +34,51 @@ module.exports = new Class({
|
|||
* @param {string} field The field name
|
||||
* @param {*} value The new field value
|
||||
*/
|
||||
,set(field, value) {
|
||||
var params = {};
|
||||
params[field] = value;
|
||||
this.assign(params);
|
||||
}
|
||||
|
||||
set(field, value) {
|
||||
this.assign({[field]: value});
|
||||
},
|
||||
|
||||
unset(field) {
|
||||
this.assign({[field]: undefined});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array with the lot keys.
|
||||
*
|
||||
* @return {Array} The lot keys
|
||||
*/
|
||||
,keys() {}
|
||||
keys() {},
|
||||
|
||||
/**
|
||||
* Emits the 'change' signal on the lot.
|
||||
*
|
||||
* @param {Object} changes The changed params and its values
|
||||
*/
|
||||
,changed(changes) {
|
||||
this.emit('change', changes);
|
||||
}
|
||||
changed(changes) {
|
||||
this.emit('change', changes);
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies all values from another lot.
|
||||
*
|
||||
* @param {Object} object The source object
|
||||
*/
|
||||
,assign() {}
|
||||
assign() {},
|
||||
|
||||
/**
|
||||
* Copies all values from another lot.
|
||||
*
|
||||
* @param {LotIface} lot The source lot
|
||||
*/
|
||||
,assignLot(lot) {
|
||||
this.assign(lot.$);
|
||||
}
|
||||
assignLot(lot) {
|
||||
this.assign(lot.$);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets all values.
|
||||
*/
|
||||
,reset() {
|
||||
this.params = {};
|
||||
}
|
||||
reset() {
|
||||
this.params = {};
|
||||
}
|
||||
});
|
||||
|
|
@ -1,66 +1,63 @@
|
|||
|
||||
module.exports =
|
||||
{
|
||||
removeChilds: function (node)
|
||||
{
|
||||
module.exports = {
|
||||
removeChilds(node) {
|
||||
var childs = node.childNodes;
|
||||
|
||||
if (childs)
|
||||
while (childs.length > 0)
|
||||
node.removeChild (childs[0]);
|
||||
}
|
||||
node.removeChild(childs[0]);
|
||||
},
|
||||
|
||||
,remove: function (node)
|
||||
{
|
||||
remove(node) {
|
||||
if (node.parentNode)
|
||||
node.parentNode.removeChild (node);
|
||||
}
|
||||
node.parentNode.removeChild(node);
|
||||
},
|
||||
|
||||
,setText: function (node, text)
|
||||
{
|
||||
Vn.Node.removeChilds (node);
|
||||
setText(node, text) {
|
||||
Vn.Node.removeChilds(node);
|
||||
|
||||
if (text)
|
||||
node.appendChild (
|
||||
node.ownerDocument.createTextNode (text));
|
||||
}
|
||||
node.appendChild(
|
||||
node.ownerDocument.createTextNode(text));
|
||||
},
|
||||
|
||||
,addClass: function (node, className)
|
||||
{
|
||||
/* var classes = node.className.split (' ');
|
||||
addClass(node, className) {
|
||||
/* var classes = node.className.split(' ');
|
||||
|
||||
if (classes.split (' ').indexOf (className) == -1)
|
||||
if (classes.split(' ').indexOf(className) == -1)
|
||||
*/ node.className = className +' '+ node.className;
|
||||
}
|
||||
},
|
||||
|
||||
,removeClass: function (node, className)
|
||||
{
|
||||
removeClass(node, className) {
|
||||
var index = 0;
|
||||
var found = false;
|
||||
var classes = node.className.split (' ');
|
||||
var classes = node.className.split(' ');
|
||||
|
||||
while ((index = classes.indexOf (className, index)) != -1)
|
||||
{
|
||||
classes.splice (index, 1);
|
||||
while ((index = classes.indexOf(className, index)) != -1) {
|
||||
classes.splice(index, 1);
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found)
|
||||
node.className = classes.join (' ');
|
||||
}
|
||||
node.className = classes.join(' ');
|
||||
},
|
||||
|
||||
,hide: function (node)
|
||||
{
|
||||
hide: function(node) {
|
||||
node.style.display = 'none';
|
||||
}
|
||||
},
|
||||
|
||||
,show: function (node)
|
||||
{
|
||||
show: function(node) {
|
||||
node.style.display = 'block';
|
||||
},
|
||||
|
||||
disableInputs(formNode, disable = true) {
|
||||
const inputs = formNode
|
||||
.querySelectorAll('input, textarea, button, select');
|
||||
for (const input of inputs)
|
||||
input.disabled = disable;
|
||||
}
|
||||
};
|
||||
|
||||
$ = function (id)
|
||||
{
|
||||
return document.getElementById (id);
|
||||
$ = function(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
|
|
@ -140,52 +140,33 @@ function sprintf(formatString) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
regexpNumber: /%\.([0-9]+)d/g
|
||||
,regexpString: /%s/g
|
||||
function format(value, format) {
|
||||
if (value === null || value === undefined)
|
||||
return '';
|
||||
|
||||
,equals
|
||||
,diff
|
||||
,partialDiff
|
||||
,kvClone
|
||||
,simpleClone
|
||||
,simpleEquals
|
||||
,sprintf
|
||||
|
||||
,compare(a, b) {
|
||||
if (a === b)
|
||||
return true;
|
||||
if (a instanceof Date && b instanceof Date)
|
||||
return a.getTime() === b.getTime();
|
||||
|
||||
return false;
|
||||
if (format)
|
||||
switch (typeof value) {
|
||||
case 'number':
|
||||
return format.replace(/%\.([0-9]+)d/g,
|
||||
(_, digits) => new Number(value).toFixed(parseInt(digits)));
|
||||
case 'string':
|
||||
return format.replace(/%s/g,
|
||||
() => value);
|
||||
case 'object':
|
||||
if (value instanceof Date)
|
||||
return VnDate.strftime(value, format);
|
||||
}
|
||||
|
||||
,format(value, format) {
|
||||
if (value === null || value === undefined)
|
||||
return '';
|
||||
|
||||
if (format)
|
||||
switch (typeof value) {
|
||||
case 'number':
|
||||
return format.replace(this.regexpNumber,
|
||||
this.replaceNumber.bind(null, value));
|
||||
case 'string':
|
||||
return format.replace(this.regexpString,
|
||||
this.replaceString.bind(null, value));
|
||||
case 'object':
|
||||
if (value instanceof Date)
|
||||
return VnDate.strftime(value, format);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
,replaceNumber(value, token, digits) {
|
||||
return new Number(value).toFixed(parseInt(digits));
|
||||
}
|
||||
|
||||
,replaceString(value) {
|
||||
return value;
|
||||
}
|
||||
module.exports = {
|
||||
equals,
|
||||
diff,
|
||||
partialDiff,
|
||||
kvClone,
|
||||
simpleClone,
|
||||
simpleEquals,
|
||||
sprintf,
|
||||
format,
|
||||
};
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "hedera-web",
|
||||
"version": "22.46.19",
|
||||
"version": "22.48.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "hedera-web",
|
||||
"version": "22.46.19",
|
||||
"version": "22.48.4",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"js-yaml": "^3.12.1",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hedera-web",
|
||||
"version": "22.48.2",
|
||||
"version": "22.48.10",
|
||||
"description": "Verdnatura web page",
|
||||
"license": "GPL-3.0",
|
||||
"repository": {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
|
@ -1,2 +1,4 @@
|
|||
UpdateYourBrowser: Actualitza el teu navegador
|
||||
ContinueAnyway: Continuar igualment
|
||||
BrowserVersionNotCompatible: El vostre navegador no és compatible amb aquesta versió de la pàgina web
|
||||
PushHereToInstallFirefox: Clica aquí per instal·lar Firefox
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
UpdateYourBrowser: Upgrade your browser
|
||||
ContinueAnyway: Continue anyway
|
||||
BrowserVersionNotCompatible: Your browser is not compatible with this version of the website
|
||||
PushHereToInstallFirefox: Click here to install Firefox
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
UpdateYourBrowser: Actualiza tu navegador
|
||||
ContinueAnyway: Continuar de todos modos
|
||||
BrowserVersionNotCompatible: Tu navegador no es compatible con esta versión de la página web
|
||||
PushHereToInstallFirefox: Pulsa aquí para instalar Firefox
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
UpdateYourBrowser: Mettez à jour votre navigateur
|
||||
ContinueAnyway: Continuer
|
||||
BrowserVersionNotCompatible: Votre navigateur n'est pas compatible avec cette version du site
|
||||
PushHereToInstallFirefox: Cliquez ici pour installer Firefox
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
UpdateYourBrowser: Upgrade your browser
|
||||
ContinueAnyway: Continue anyway
|
|
@ -1,2 +1,4 @@
|
|||
UpdateYourBrowser: Atualize seu navegador
|
||||
ContinueAnyway: Continuar de todas maneiras
|
||||
BrowserVersionNotCompatible: Seu navegador não é compatível com esta versão do site
|
||||
PushHereToInstallFirefox: Clique aqui para instalar o Firefox
|
||||
|
|
|
@ -1,26 +1,53 @@
|
|||
*
|
||||
{
|
||||
* {
|
||||
font-family: 'Roboto';
|
||||
}
|
||||
img
|
||||
{
|
||||
position: absolute;
|
||||
margin-top: -200px;
|
||||
margin-left: -200px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
.box {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
max-width: 380px;
|
||||
padding: 40px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
#continue
|
||||
{
|
||||
position: absolute;
|
||||
.logo {
|
||||
padding: 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 22px;
|
||||
}
|
||||
.browser-logo {
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
height: 120px;
|
||||
}
|
||||
.download {
|
||||
display: block;
|
||||
}
|
||||
.bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 1em;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
a
|
||||
{
|
||||
color: #444;
|
||||
.continue {
|
||||
color: white;
|
||||
background-color: #8cc63f;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.continue:hover {
|
||||
text-decoration: none;
|
||||
background-color: #7eb239;
|
||||
}
|
||||
a {
|
||||
color: #6a1;
|
||||
border-width: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
|
|
@ -2,20 +2,35 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="user-scalable=no"/>
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=no"/>
|
||||
<meta name="content-language" content="<?=$lang?>"/>
|
||||
<link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css"/>
|
||||
<?=css("$dir/style")?>
|
||||
<title>Verdnatura</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<a href="http://www.mozilla.org/es-ES/firefox/new/" target="_blank">
|
||||
<img src="<?=$dir?>/update-browser.png" alt="<?=s('UpdateYourBrowser')?>"></img>
|
||||
<div class="box">
|
||||
<img
|
||||
class="logo"
|
||||
src="image/logo.png"
|
||||
alt="VerdNatura">
|
||||
</img>
|
||||
<h2><?=s('BrowserVersionNotCompatible')?></h2>
|
||||
<a
|
||||
class="download"
|
||||
href="http://www.mozilla.org/firefox/new/"
|
||||
target="_blank">
|
||||
<img
|
||||
class="browser-logo"
|
||||
src="<?=$dir?>/firefox.png"
|
||||
alt="Firefox">
|
||||
</img>
|
||||
<?=s('PushHereToInstallFirefox')?>
|
||||
</a>
|
||||
</div>
|
||||
<div id="continue">
|
||||
<a href="?skipBrowser=true">
|
||||
<div class="bottom">
|
||||
<a class="continue"
|
||||
href="?skipBrowser=true">
|
||||
<?=s('ContinueAnyway')?>
|
||||
</a>
|
||||
</div>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB |
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Recover password": "Recover password",
|
||||
"Press on the following link to change your password.": "Press on the following link to change your password."
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
recoverPassword: Recover password
|
||||
pressLinkToRecoverPassword: Press on the following link to change your password.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Recover password": "Restaurar contraseña",
|
||||
"Press on the following link to change your password.": "Pulsa en el siguiente link para cambiar tu contraseña."
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
recoverPassword: Restaurar contraseña
|
||||
pressLinkToRecoverPassword: Pulsa en el siguiente link para cambiar tu contraseña.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Recover password": "Réinitialisation du mot de passe",
|
||||
"Press on the following link to change your password.": "Appuyez sur le lien suivant pour changer votre mot de passe."
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
recoverPassword: Réinitialisation du mot de passe
|
||||
pressLinkToRecoverPassword: Appuyez sur le lien suivant pour changer votre mot de passe.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Recover password": "Recuperar palavra-passe",
|
||||
"Press on the following link to change your password.": "Pressione o botão para modificar sua palavra-passe."
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
recoverPassword: Recuperar palavra-passe
|
||||
pressLinkToRecoverPassword: Pressione o botão para modificar sua palavra-passe.
|
|
@ -1,7 +1,7 @@
|
|||
<?php $title = s('Recover password') ?>
|
||||
<?php $title = s('recoverPassword') ?>
|
||||
<p>
|
||||
<?=s('Press on the following link to change your password.')?>
|
||||
<?=s('pressLinkToRecoverPassword')?>
|
||||
</p>
|
||||
<a href="<?=$url?>">
|
||||
<?=s('Recover password')?>
|
||||
<?=s('recoverPassword')?>
|
||||
</a>
|
||||
|
|
|
@ -10,7 +10,7 @@ class Supplant extends Vn\Web\JsonRequest {
|
|||
'SELECT id FROM account.user WHERE `name` = #',
|
||||
[$_REQUEST['supplantUser']]
|
||||
);
|
||||
|
||||
/*
|
||||
$isClient = $db->getValue(
|
||||
'SELECT COUNT(*) > 0 FROM vn.client WHERE id = #',
|
||||
[$userId]
|
||||
|
@ -24,7 +24,7 @@ class Supplant extends Vn\Web\JsonRequest {
|
|||
);
|
||||
if ($hasAccount)
|
||||
throw new Web\ForbiddenException(s('The user is not impersonable'));
|
||||
|
||||
*/
|
||||
return $this->service->createToken($_REQUEST['supplantUser']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"InvalidAction": "Acció invàlida"
|
||||
|
||||
,"EmptyQuery": "Consulta buida"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidAction: Acció invàlida
|
||||
EmptyQuery: Consulta buida
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"InvalidAction": "Invalid action"
|
||||
|
||||
,"EmptyQuery": "Empty query"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidAction: Invalid action
|
||||
EmptyQuery: Empty query
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"InvalidAction": "Acción inválida"
|
||||
,"EmptyQuery": "Consulta vacía"
|
||||
,"Invalid password": "Contraseña inválida"
|
||||
,"Password does not meet requirements":
|
||||
"La nueva contraseña no reune los requisitos de seguridad necesarios"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidAction: Acción inválida
|
||||
EmptyQuery: Consulta vacía
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"InvalidAction": "Action non valide"
|
||||
|
||||
,"EmptyQuery": "Requête vide"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidAction: Action non valide
|
||||
EmptyQuery: Requête vide
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"InvalidAction": "Ação Inválida"
|
||||
|
||||
,"EmptyQuery": "Consulta vazía"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidAction: Ação Inválida
|
||||
EmptyQuery: Consulta vazía
|
|
@ -22,53 +22,34 @@ class Query extends Vn\Web\JsonRequest {
|
|||
|
||||
function run($db) {
|
||||
$results = [];
|
||||
$db->multiQuery($_REQUEST['sql']);
|
||||
|
||||
try {
|
||||
$db->multiQuery($_REQUEST['sql']);
|
||||
do {
|
||||
$result = $db->storeResult();
|
||||
|
||||
do {
|
||||
$result = $db->storeResult();
|
||||
if ($result !== FALSE) {
|
||||
$results[] = $this->transformResult($result);
|
||||
$result->free();
|
||||
} else
|
||||
$results[] = TRUE;
|
||||
}
|
||||
while ($db->moreResults() && $db->nextResult());
|
||||
|
||||
if ($result !== FALSE) {
|
||||
$results[] = $this->transformResult($result);
|
||||
$result->free();
|
||||
} else
|
||||
$results[] = TRUE;
|
||||
if ($db->checkWarnings()
|
||||
&&($result = $db->query('SHOW WARNINGS'))) {
|
||||
$sql = 'SELECT `description`, @warn `code`
|
||||
FROM `message` WHERE `code` = @warn';
|
||||
|
||||
while ($row = $result->fetch_object()) {
|
||||
if ($row->Code == 1265
|
||||
&&($warning = $db->getObject($sql)))
|
||||
trigger_error("{$warning->code}: {$warning->description}", E_USER_WARNING);
|
||||
else
|
||||
trigger_error("{$row->Code}: {$row->Message}", E_USER_WARNING);
|
||||
}
|
||||
while ($db->moreResults() && $db->nextResult());
|
||||
|
||||
// Checks for warnings
|
||||
|
||||
if ($db->checkWarnings()
|
||||
&&($result = $db->query('SHOW WARNINGS'))) {
|
||||
$sql = 'SELECT `description`, @warn `code`
|
||||
FROM `message` WHERE `code` = @warn';
|
||||
|
||||
while ($row = $result->fetch_object()) {
|
||||
if ($row->Code == 1265
|
||||
&&($warning = $db->getObject($sql)))
|
||||
trigger_error("{$warning->code}: {$warning->description}", E_USER_WARNING);
|
||||
else
|
||||
trigger_error("{$row->Code}: {$row->Message}", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks for errors
|
||||
|
||||
$db->checkError();
|
||||
} catch (Vn\Db\Exception $e) {
|
||||
if ($e->getCode() == 1644) {
|
||||
$dbMessage = $e->getMessage();
|
||||
$sql = 'SELECT `description` FROM `message` WHERE `code` = #';
|
||||
$message = $db->getValue($sql, [$dbMessage]);
|
||||
|
||||
if ($message)
|
||||
throw new Lib\UserException($message, $dbMessage);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$db->checkError();
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"Cant lock cache": "The cache could not be blocked"
|
||||
,"Bad file format": "Unrecognized file format"
|
||||
,"File not choosed": "You have not selected any file"
|
||||
,"Permission denied": "You are not allowed to upload the file"
|
||||
,"File upload error": "Failed to upload the file, check that size is not too large"
|
||||
,"File save error": "Failed to save the file: %s"
|
||||
,"File size error": "The file must be no longer than %.2f MB"
|
||||
,"Bad file name": "The file name must contain only lowercase letters, digits or the '_' character"
|
||||
,"Bad collection name": "Invalid collection name"
|
||||
,"Collection not exists": "Collection does not exist"
|
||||
,"Unreferenced file": "The file is not referenced by the database"
|
||||
,"Cannot update matching id": "Cannot update matching id"
|
||||
,"Com error": "Error communicating with the server"
|
||||
,"Image open error": "Error opening the image file"
|
||||
,"Operation disabled": "Operation disabled for security"
|
||||
,"Image added": "Image added correctly"
|
||||
|
||||
,"ErrIniSize": "File exceeds the upload_max_filesize directive in php.ini"
|
||||
,"ErrFormSize": "File exceeds the MAX_FILE_SIZE specified in the HTML form"
|
||||
,"ErrPartial": "File was partially uploaded"
|
||||
,"ErrNoFile": "No file was uploaded"
|
||||
,"ErrNoTmpDir": "Missing a temporary folder"
|
||||
,"ErrCantWrite": "Failed to write file to disk"
|
||||
,"ErrExtension": "File upload stopped by extension"
|
||||
,"ErrDefault": "Unknown upload error"
|
||||
|
||||
,"Sync complete": "Synchronization complete"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
Cant lock cache: The cache could not be blocked
|
||||
Bad file format: Unrecognized file format
|
||||
File not choosed: You have not selected any file
|
||||
Permission denied: You are not allowed to upload the file
|
||||
File upload error: Failed to upload the file, check that size is not too large
|
||||
File save error: 'Failed to save the file: %s'
|
||||
File size error: The file must be no longer than %.2f MB
|
||||
Bad file name: 'The file name must contain only lowercase letters, digits or the ''_'' character'
|
||||
Bad collection name: Invalid collection name
|
||||
Collection not exists: Collection does not exist
|
||||
Unreferenced file: The file is not referenced by the database
|
||||
Cannot update matching id: Cannot update matching id
|
||||
Com error: Error communicating with the server
|
||||
Image open error: Error opening the image file
|
||||
Operation disabled: Operation disabled for security
|
||||
Image added: Image added correctly
|
||||
|
||||
ErrIniSize: File exceeds the upload_max_filesize directive in php.ini
|
||||
ErrFormSize: File exceeds the MAX_FILE_SIZE specified in the HTML form
|
||||
ErrPartial: File was partially uploaded
|
||||
ErrNoFile: No file was uploaded
|
||||
ErrNoTmpDir: Missing a temporary folder
|
||||
ErrCantWrite: Failed to write file to disk
|
||||
ErrExtension: File upload stopped by extension
|
||||
ErrDefault: Unknown upload error
|
||||
|
||||
Sync complete: Synchronization complete
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"Cant lock cache": "La caché no pudo ser bloqueada"
|
||||
,"Bad file format": "Formato de archivo no reconocido"
|
||||
,"File not choosed": "No has seleccionado ningún archivo"
|
||||
,"Permission denied": "No tienes permiso para subir el fichero"
|
||||
,"File upload error": "Error al subir el fichero, comprueba que su tamaño no sea demasiado grande"
|
||||
,"File save error": "Error al guardar el fichero: %s"
|
||||
,"File size error": "El fichero no debe ocupar más de %.2f MB"
|
||||
,"Bad file name": "El nombre del archivo solo debe contener letras minúsculas, dígitos o el carácter '_'"
|
||||
,"Bad collection name": "Nombre de colección no válido"
|
||||
,"Collection not exists": "La colección no existe"
|
||||
,"Unreferenced file": "El archivo no está referenciado por la base de datos"
|
||||
,"Cannot update matching id": "No es posible actualizar los ítems con id coincidente"
|
||||
,"Com error": "Error en la comunicación con el servidor"
|
||||
,"Image open error": "Error al abrir el archivo de imagen"
|
||||
,"Operation disabled": "Operación deshabilitada por seguridad"
|
||||
,"Image added": "Imagen añadida correctamente"
|
||||
|
||||
,"ErrIniSize": "File exceeds the upload_max_filesize directive in php.ini"
|
||||
,"ErrFormSize": "File exceeds the MAX_FILE_SIZE specified in the HTML form"
|
||||
,"ErrPartial": "File was partially uploaded"
|
||||
,"ErrNoFile": "No file was uploaded"
|
||||
,"ErrNoTmpDir": "Missing a temporary folder"
|
||||
,"ErrCantWrite": "Failed to write file to disk"
|
||||
,"ErrExtension": "File upload stopped by extension"
|
||||
,"ErrDefault": "Unknown upload error"
|
||||
|
||||
,"Sync complete": "Sincronización completada"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
Cant lock cache: La caché no pudo ser bloqueada
|
||||
Bad file format: Formato de archivo no reconocido
|
||||
File not choosed: No has seleccionado ningún archivo
|
||||
Permission denied: No tienes permiso para subir el fichero
|
||||
File upload error: Error al subir el fichero, comprueba que su tamaño no sea demasiado grande
|
||||
File save error: 'Error al guardar el fichero: %s'
|
||||
File size error: El fichero no debe ocupar más de %.2f MB
|
||||
Bad file name: 'El nombre del archivo solo debe contener letras minúsculas, dígitos o el carácter ''_'''
|
||||
Bad collection name: Nombre de colección no válido
|
||||
Collection not exists: La colección no existe
|
||||
Unreferenced file: El archivo no está referenciado por la base de datos
|
||||
Cannot update matching id: No es posible actualizar los ítems con id coincidente
|
||||
Com error: Error en la comunicación con el servidor
|
||||
Image open error: Error al abrir el archivo de imagen
|
||||
Operation disabled: Operación deshabilitada por seguridad
|
||||
Image added: Imagen añadida correctamente
|
||||
|
||||
ErrIniSize: File exceeds the upload_max_filesize directive in php.ini
|
||||
ErrFormSize: File exceeds the MAX_FILE_SIZE specified in the HTML form
|
||||
ErrPartial: File was partially uploaded
|
||||
ErrNoFile: No file was uploaded
|
||||
ErrNoTmpDir: Missing a temporary folder
|
||||
ErrCantWrite: Failed to write file to disk
|
||||
ErrExtension: File upload stopped by extension
|
||||
ErrDefault: Unknown upload error
|
||||
|
||||
Sync complete: Sincronización completada
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"Cant lock cache": "O cache não pôde ser bloqueado"
|
||||
,"Bad file format": "Formato de arquivo inválido"
|
||||
,"File not choosed": "Não selecionastes nenhum arquivo"
|
||||
,"Permission denied": "Não estas autorizado a subir o arquivo"
|
||||
,"File upload error": "Erro ao subir o arquivo, verifique o tamanho"
|
||||
,"File save error": "Erro ao salvar o arquivo: %s"
|
||||
,"File size error": "O arquivo não deve ser maior que: %.2f MB"
|
||||
,"Bad file name": "O nome do arquivo deve conter somente letras minusculas, numeros ou '_' "
|
||||
,"Bad collection name": "Nome de coleção inválido"
|
||||
,"Collection not exists": "Coleção não existe"
|
||||
,"Unreferenced file": "O arquivo não é referenciado pelo banco de dados"
|
||||
,"Cannot update matching id": "Não é possível atualizar os itens com id coincidente"
|
||||
,"Com error": "Erro de comunicação com o servidor"
|
||||
,"Image open error": "Erro ao abrir a imagem"
|
||||
,"Operation disabled": "Operação desativada por segurança"
|
||||
,"Image added": "Imagem adicionada corretamente"
|
||||
|
||||
,"ErrIniSize": "Arquivo supera o tamanho maximo de protocolo em php.ini"
|
||||
,"ErrFormSize": "Arquivo supera o tamanho maximo de protocolo em HTML form"
|
||||
,"ErrPartial": "Arquivo subido parcialmente"
|
||||
,"ErrNoFile": "Nenhum arquivo subido"
|
||||
,"ErrNoTmpDir": "Falta a pasta de arquivo temporal"
|
||||
,"ErrCantWrite": "Erro ao gravar arquivo no disco"
|
||||
,"ErrExtension": "Erro de extensão do arquivo"
|
||||
,"ErrDefault": "Erro desconhecido ao subir arquivo"
|
||||
|
||||
,"Sync complete": "Sincronização completa"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue