refs #5253 #22

Merged
juan merged 20 commits from test into master 2023-02-23 09:30:53 +00:00
23 changed files with 338 additions and 128 deletions
Showing only changes of commit 806c4cc3ad - Show all commits

View File

@ -5,8 +5,16 @@ export default new Class({
Template: require('./ui.xml'), Template: require('./ui.xml'),
async open() { async open() {
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash); await Hedera.Form.prototype.open.call(this);
if (isOk) await Hedera.Form.prototype.open.call(this);
let orderId = this.$.params.$.id;
if (!orderId)
orderId = localStorage.getItem('hederaBasket');
if (!orderId)
this.hash.setAll({form: 'ecomerce/pending'});
else
await Hedera.Basket.check(this.conn, this.hash);
this.$.params.set('id', orderId);
}, },
activate() { activate() {
@ -15,7 +23,17 @@ export default new Class({
onConfigureClick() { onConfigureClick() {
Htk.Toast.showWarning(_('RememberReconfiguringImpact')); Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
this.hash.setAll({form: 'ecomerce/checkout'}); this.hash.setAll({
form: 'ecomerce/checkout',
id: this.$.params.$.id
});
},
onConfirmClick() {
this.hash.setAll({
form: 'ecomerce/confirm',
id: this.$.params.$.id
});
}, },
onDeleteClick(form) { onDeleteClick(form) {

View File

@ -1,76 +1,94 @@
.basket .head { .hedera-basket {
border-bottom: 1px solid #DDD; .head {
} border-bottom: 1px solid #DDD;
.basket .head p {
font-weight: bold; & > div > div {
margin: 0; margin: 15px 0;
padding: 0; }
font-size: 1.4rem; & > div > div:first-child {
text-align: right; margin: 0;
} }
.basket .form > p { p {
margin: 0; margin: 3px 0;
font-size: 1.4rem;
color: white; &.important {
text-align: right; font-size: 1.2rem;
} font-weight: bold;
}
/* Lines */ }
.total {
.basket .line {
display: flex; font-weight: bold;
align-items: center; margin: 0;
gap: 12px; padding: 0;
margin: 10px 0; font-size: 1.4rem;
height: 80px; text-align: right;
} }
.basket .line:first-child { }
margin-top: 0; .form > p {
} margin: 0;
.basket .line:last-child { font-size: 1.4rem;
margin-bottom: 0; color: white;
} text-align: right;
.basket .line > .delete { }
margin: 0 -8px;
} /* Lines */
.basket .line > .photo {
flex: none; .line {
border-radius: 50%; display: flex;
width: 68px; align-items: center;
height: 68px; gap: 12px;
gap: 0; margin: 10px 0;
} height: 80px;
.basket .line > .info { }
flex: 1; .line:first-child {
overflow: hidden; margin-top: 0;
} }
.basket .line > .info > * { .line:last-child {
text-overflow: ellipsis; margin-bottom: 0;
white-space: nowrap; }
overflow: hidden; .line > .delete {
} margin: 0 -8px;
.basket .line > .info > h2 { }
font-size: 1rem; .line > .photo {
font-weight: normal; flex: none;
margin: 0; border-radius: 50%;
} width: 68px;
.basket .line > .info > p { height: 68px;
margin: 0; gap: 0;
} }
.basket .line > .info > .tags { .line > .info {
color: #777; flex: 1;
} overflow: hidden;
.basket .line .subtotal { }
float: right; .line > .info > * {
} text-overflow: ellipsis;
white-space: nowrap;
/* Fields */ overflow: hidden;
}
.basket td.available-exceeded input { .line > .info > h2 {
background-color: #FCC; font-size: 1rem;
} font-weight: normal;
.basket .icon > img { margin: 0;
border-radius: 50%; }
.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%;
}
} }

View File

@ -1,6 +1,9 @@
<vn> <vn>
<vn-lot-query id="params">
<vn-spec name="id" type="Number"/>
</vn-lot-query>
<div id="title"> <div id="title">
<h1><t>ShoppingBasket</t></h1> <h1>{{_(params.$.id ? 'Order' : 'ShoppingBasket')}}</h1>
</div> </div>
<div id="actions"> <div id="actions">
<htk-bar-button <htk-bar-button
@ -14,12 +17,33 @@
<htk-bar-button <htk-bar-button
icon="shopping_cart_checkout" icon="shopping_cart_checkout"
tip="_Checkout" tip="_Checkout"
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/> on-click="this.onConfirmClick()"/>
</div> </div>
<div id="form" class="basket"> <vn-group>
<db-form v-model="order">
<db-model property="model" lot="params">
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="box vn-w-sm vn-pa-lg">
<div class="head vn-pb-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> <t>Total</t>
<htk-text format="%.2d€"> <htk-text format="%.2d€">
<db-calc-sum property="param" func="subtotal" model="items"/> <db-calc-sum property="param" func="subtotal" model="items"/>
@ -28,15 +52,16 @@
</div> </div>
<div class="lines vn-pt-lg"> <div class="lines vn-pt-lg">
<htk-repeater form-id="iter"> <htk-repeater form-id="iter">
<db-model id="items" property="model" updatable="true"> <db-model id="items" property="model" lot="params" updatable="true">
SELECT bi.id, bi.amount, bi.price, i.longName item, SELECT bi.id, bi.amount, bi.price, i.longName item,
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7, i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
i.image, im.updated i.image, im.updated
FROM myBasketItem bi FROM myOrderRow bi
JOIN vn.item i ON i.id = bi.itemFk JOIN vn.item i ON i.id = bi.itemFk
LEFT JOIN image im LEFT JOIN image im
ON im.collectionFk = 'catalog' ON im.collectionFk = 'catalog'
AND im.name = i.image AND im.name = i.image
WHERE orderFk = #id
</db-model> </db-model>
<custom> <custom>
<div class="line"> <div class="line">

View File

@ -10,7 +10,7 @@ const Catalog = new Class({
let isOk = true; let isOk = true;
if (!localStorage.getItem('hederaGuest')) if (!localStorage.getItem('hederaGuest'))
isOk = await Hedera.BasketChecker.check(this.conn, this.hash); isOk = await Hedera.Basket.check(this.conn, this.hash);
else else
await this.conn.execQuery('CALL mybasket_configureForGuest'); await this.conn.execQuery('CALL mybasket_configureForGuest');

View File

@ -44,7 +44,7 @@ export default new Class({
} }
this.$.lot.assign({ this.$.lot.assign({
date: date, date,
method: row.deliveryMethod, method: row.deliveryMethod,
agency: row.agencyModeFk, agency: row.agencyModeFk,
address: row.addressFk address: row.addressFk
@ -59,11 +59,21 @@ export default new Class({
async onConfirmClick() { async onConfirmClick() {
this.disableButtons(true); this.disableButtons(true);
const query = 'CALL myBasket_configure(#date, #method, #agency, #address)'; const 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(@id, #date, #method, #agency, #address)';
}
let resultSet; let resultSet;
try { try {
resultSet = await this.conn.execQuery(query, this.$.lot.$); resultSet = await this.conn.execQuery(query, params);
} finally { } finally {
this.disableButtons(false); this.disableButtons(false);
} }
@ -71,7 +81,7 @@ export default new Class({
if (!resultSet.fetchResult()) if (!resultSet.fetchResult())
return; return;
if (this.$.orderForm.numRows > 0) if (id)
Htk.Toast.showMessage(_('OrderUpdated')); Htk.Toast.showMessage(_('OrderUpdated'));
else else
Htk.Toast.showMessage(_('OrderStarted')); Htk.Toast.showMessage(_('OrderStarted'));
@ -80,7 +90,7 @@ export default new Class({
}, },
onCancelClick() { onCancelClick() {
if (this.$.orderForm.numRows > 0) if (this.$.params.$.id)
window.history.back(); window.history.back();
else else
this.hash.setAll({form: 'ecomerce/orders'}); this.hash.setAll({form: 'ecomerce/orders'});

View File

@ -1,4 +1,7 @@
<vn> <vn>
<vn-lot-query id="params">
<vn-spec name="id" type="Number"/>
</vn-lot-query>
<vn-group> <vn-group>
<vn-lot id="lot" on-change="this.onAddressChange()"/> <vn-lot id="lot" on-change="this.onAddressChange()"/>
<db-form id="defaults" on-ready="onValuesReady"> <db-form id="defaults" on-ready="onValuesReady">
@ -8,10 +11,11 @@
</db-model> </db-model>
</db-form> </db-form>
<db-form id="order-form" on-ready="onValuesReady"> <db-form id="order-form" on-ready="onValuesReady">
<db-model property="model"> <db-model property="model" lot="params">
SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk 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 JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
WHERE o.id = #id
</db-model> </db-model>
</db-form> </db-form>
<db-model id="agencies" <db-model id="agencies"

View File

@ -5,7 +5,7 @@ export default new Class({
Template: require('./ui.xml'), Template: require('./ui.xml'),
async open() { async open() {
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash); const isOk = await Hedera.Basket.check(this.conn, this.hash);
if (isOk) await Hedera.Form.prototype.open.call(this); if (isOk) await Hedera.Form.prototype.open.call(this);
}, },
@ -116,15 +116,16 @@ export default new Class({
}, },
async onConfirmClick() { async onConfirmClick() {
this.disableButtons(true); Vn.Node.disableInputs(this.node);
await this.$.confirmQuery.execute(); try {
}, await this.conn.execQuery(
'CALL myOrder_confirm(#id)',
onConfirm(query, resultSet) { this.$.params.$
this.disableButtons(false); );
if (resultSet.fetchResult())
this.$.successDialog.show(); this.$.successDialog.show();
} finally {
Vn.Node.disableInputs(this.node, false);
}
}, },
async onDialogResponse() { async onDialogResponse() {

View File

@ -1,13 +1,16 @@
<vn> <vn>
<vn-lot-query id="params">
<vn-spec name="id" type="Number"/>
</vn-lot-query>
<vn-group> <vn-group>
<db-form v-model="order" on-ready="onOrderReady"> <db-form v-model="order" on-ready="onOrderReady">
<db-model property="model" result-index="1"> <db-model property="model" result-index="1" lot="params">
CALL myBasket_getTax; CALL myOrder_getTax(#id);
SELECT o.id, o.sent, o.notes, o.companyFk, SELECT o.id, o.sent, o.notes, o.companyFk,
ag.description agency, v.code method, ag.description agency, v.code method,
ad.nickname, ad.postalCode, ad.city, ad.street, ad.nickname, ad.postalCode, ad.city, ad.street,
t.*, c.credit, myClient_getDebt(NULL) debt t.*, c.credit, myClient_getDebt(NULL) debt
FROM myBasket o FROM myOrder o
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
LEFT JOIN myAddress ad ON ad.id = o.addressFk LEFT JOIN myAddress ad ON ad.id = o.addressFk
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
@ -17,7 +20,8 @@
IFNULL(SUM(taxableBase), 0) taxableBase, IFNULL(SUM(taxableBase), 0) taxableBase,
IFNULL(SUM(tax), 0) tax IFNULL(SUM(tax), 0) tax
FROM tmp.orderAmount FROM tmp.orderAmount
) t; ) t
WHERE o.id = #id;
DROP TEMPORARY TABLE DROP TEMPORARY TABLE
tmp.orderAmount, tmp.orderAmount,
tmp.orderTax; tmp.orderTax;
@ -37,7 +41,7 @@
<div class="delivery"> <div class="delivery">
<h6><t>ShippingInformation</t></h6> <h6><t>ShippingInformation</t></h6>
<p> <p>
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}} <t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
</p> </p>
<p> <p>
<span id="method"><t>Agency</t></span> {{order.agency}} <span id="method"><t>Agency</t></span> {{order.agency}}

View File

@ -36,4 +36,3 @@
.orders .htk-list .total { .orders .htk-list .total {
float: right; float: right;
} }

View File

@ -0,0 +1,21 @@
import './style.scss';
export default new Class({
Extends: Hedera.Form,
Template: require('./ui.xml'),
activate() {
this.$.orders.setInfo('o', 'myOrder', 'hedera', ['id'], 'id');
},
async onRemoveOrderClick(form) {
if (confirm(_('AreYouSureDeleteOrder')))
await form.deleteRow();
},
loadOrder(id) {
localStorage.setItem('hederaBasket', id);
this.hash.setAll({form: 'ecomerce/catalog'});
Htk.Toast.showMessage(_('OrderLoadedIntoBasket'));
}
});

View File

@ -0,0 +1 @@
Pending: Pendents

View File

@ -0,0 +1 @@
Pending: Pending

View File

@ -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!

View File

@ -0,0 +1 @@
Pending: Pendents

View File

@ -0,0 +1 @@
Pending: Pendientes

View File

View File

@ -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&amp;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>

View File

@ -70,7 +70,9 @@ export const routes = {
orders: orders:
() => import('ecomerce/orders'), () => import('ecomerce/orders'),
ticket: ticket:
() => import('ecomerce/ticket') () => import('ecomerce/ticket'),
pending:
() => import('ecomerce/pending')
}, },
news: { news: {
new: new:

View File

@ -9,6 +9,24 @@ module.exports = new Class({
,get() { ,get() {
return this._conn; 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() { ,showLogin() {
const login = this._login = new Login({ const login = this._login = new Login({
app: this,
conn: this._conn, conn: this._conn,
hash: this._hash hash: this._hash
}); });
@ -47,6 +66,7 @@ module.exports = new Class({
if (this._gui) return; if (this._gui) return;
const gui = this._gui = new Gui({ const gui = this._gui = new Gui({
app: this,
conn: this._conn, conn: this._conn,
hash: this._hash hash: this._hash
}); });

View File

@ -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;
}
};

42
js/hedera/basket.js Normal file
View File

@ -0,0 +1,42 @@
module.exports = class {
constructor(app) {
this.app = app;
let orderId = localStorage.getItem('hederaBasket');
if (orderId) orderId = parseInt(orderId);
this.orderId = orderId;
}
async check(conn, hash) {
this.hash = hash;
const orderId = localStorage.getItem('hederaBasket');
const resultSet = await this.app.conn.execQuery(
'CALL myOrder_check(#id)',
{id: orderId}
);
const status = resultSet.fetchValue();
if (!status) return;
const isOk = status == 'updated' || status == 'ok';
if (status == 'updated')
Htk.Toast.showWarning(_('Order items updated'));
if (!isOk) {
const params = {form: 'ecomerce/checkout'};
if (orderId) params.id = orderId;
this.hash.setAll(params);
}
return isOk;
}
async load(orderId) {
if (this.orderId != orderId) {
localStorage.setItem('hederaBasket', orderId);
this.orderId = orderId;
}
await this.check()
}
};

View File

@ -7,6 +7,7 @@ module.exports = new Class({
,initialize(gui) { ,initialize(gui) {
this.gui = gui; this.gui = gui;
this.app = gui.app;
this.conn = gui.conn; this.conn = gui.conn;
this.hash = gui.hash; this.hash = gui.hash;
} }

View File

@ -10,6 +10,6 @@ Hedera = module.exports = {
,Report : require('./report') ,Report : require('./report')
,App : require('./app') ,App : require('./app')
,Tpv : require('./tpv') ,Tpv : require('./tpv')
,BasketChecker : require('./basket-checker') ,Basket : require('./basket')
}; };