Pedidos stepper #80
|
@ -1,123 +1,130 @@
|
|||
|
||||
var Result = require('./result');
|
||||
const Result = require('./result');
|
||||
|
||||
/**
|
||||
* This class stores the database results.
|
||||
*/
|
||||
module.exports = new Class({
|
||||
results: null
|
||||
,error: null
|
||||
results: null,
|
||||
error: null,
|
||||
|
||||
/**
|
||||
* Initilizes the resultset object.
|
||||
*/
|
||||
,initialize(results, error) {
|
||||
initialize(results, error) {
|
||||
this.results = results;
|
||||
this.error = error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the query error.
|
||||
*
|
||||
* @return {Db.Err} the error or null if no errors hapened
|
||||
*/
|
||||
,getError() {
|
||||
getError() {
|
||||
return this.error;
|
||||
}
|
||||
},
|
||||
|
||||
,fetch() {
|
||||
if (this.error)
|
||||
fetch() {
|
||||
if (this.error) {
|
||||
throw this.error;
|
||||
|
||||
if (this.results !== null
|
||||
&& this.results.length > 0)
|
||||
}
|
||||
console.log('this.results', this.results);
|
||||
if (this.results !== null && this.results.length > 0) {
|
||||
return this.results.shift();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetchs the next result from the resultset.
|
||||
*
|
||||
* @return {Db.Result} the result or %null if error or there are no more results
|
||||
*/
|
||||
,fetchResult() {
|
||||
var result = this.fetch();
|
||||
|
||||
fetchResult() {
|
||||
const result = this.fetch();
|
||||
console.log('test result', result);
|
||||
if (result !== null) {
|
||||
if (result.data instanceof Array)
|
||||
if (result.data instanceof Array) {
|
||||
return new Result(result);
|
||||
else
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetchs the first row object from the next resultset.
|
||||
*
|
||||
* @return {Array} the row if success, %null otherwise
|
||||
*/
|
||||
,fetchObject() {
|
||||
var result = this.fetch();
|
||||
fetchObject() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (result !== null
|
||||
&& result.data instanceof Array
|
||||
&& result.data.length > 0)
|
||||
if (
|
||||
result !== null &&
|
||||
result.data instanceof Array &&
|
||||
result.data.length > 0
|
||||
) {
|
||||
return result.data[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetchs data from the next resultset.
|
||||
*
|
||||
* @return {Array} the data
|
||||
*/
|
||||
,fetchData() {
|
||||
var result = this.fetch();
|
||||
fetchData() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (result !== null
|
||||
&& result.data instanceof Array)
|
||||
if (result !== null && result.data instanceof Array) {
|
||||
return result.data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetchs the first row and column value from the next resultset.
|
||||
*
|
||||
* @return {Object} the value if success, %null otherwise
|
||||
*/
|
||||
,fetchValue() {
|
||||
var row = this.fetchRow();
|
||||
fetchValue() {
|
||||
const row = this.fetchRow();
|
||||
|
||||
if (row instanceof Array && row.length > 0)
|
||||
if (row instanceof Array && row.length > 0) {
|
||||
return row[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetchs the first row from the next resultset.
|
||||
*
|
||||
* @return {Array} the row if success, %null otherwise
|
||||
*/
|
||||
,fetchRow() {
|
||||
var result = this.fetch();
|
||||
fetchRow() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (result !== null
|
||||
&& result.data instanceof Array
|
||||
&& result.data.length > 0) {
|
||||
var object = result.data[0];
|
||||
var row = new Array(result.columns.length);
|
||||
for(var i = 0; i < row.length; i++)
|
||||
if (
|
||||
result !== null &&
|
||||
result.data instanceof Array &&
|
||||
result.data.length > 0
|
||||
) {
|
||||
const object = result.data[0];
|
||||
const row = new Array(result.columns.length);
|
||||
for (let i = 0; i < row.length; i++) {
|
||||
row[i] = object[result.columns[i].name];
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -105,23 +105,18 @@ async function confirm() {
|
|||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
confirm: Confirm
|
||||
wantToContinue: Are you sure you want to continue?
|
||||
cancel: Cancel
|
||||
es-ES:
|
||||
confirm: Confirmar
|
||||
wantToContinue: ¿Seguro que quieres continuar?
|
||||
cancel: Cancelar
|
||||
ca-ES:
|
||||
confirm: Confirmar
|
||||
wantToContinue: Segur que vols continuar?
|
||||
cancel: Cancel·lar
|
||||
fr-FR:
|
||||
confirm: Confirmer
|
||||
wantToContinue: Êtes-vous sûr de vouloir continuer?
|
||||
cancel: Annuler
|
||||
pt-PT:
|
||||
confirm: Confirme
|
||||
wantToContinue: Tem a certeza de que deseja continuar?
|
||||
cancel: Cancelar
|
||||
</i18n>
|
||||
|
|
|
@ -97,6 +97,7 @@ const url = computed(() => {
|
|||
spinner-color="primary"
|
||||
:width="props.width"
|
||||
:height="props.height"
|
||||
draggable
|
||||
>
|
||||
<template #error>
|
||||
<div
|
||||
|
@ -115,6 +116,7 @@ const url = computed(() => {
|
|||
class="img_zoom"
|
||||
v-bind="$attrs"
|
||||
spinner-color="primary"
|
||||
draggable
|
||||
/>
|
||||
</QDialog>
|
||||
<QDialog v-if="props.editable" v-model="showEditForm">
|
||||
|
|
|
@ -26,6 +26,9 @@ a.link {
|
|||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
.default-radius {
|
||||
border-radius: 0.6em;
|
||||
}
|
||||
.q-card {
|
||||
border-radius: 0.6em !important;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
|
||||
|
|
|
@ -61,8 +61,13 @@ export default {
|
|||
adminNewsDetails: 'Afegir o editar notícia',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Comanda carregada a la cistella!',
|
||||
loadAnOrder:
|
||||
'Si us plau carrega una comanda pendent a la cistella o en comença una de nova',
|
||||
at: 'a les',
|
||||
back: 'Tornar',
|
||||
next: 'Següent',
|
||||
remove: 'Esborrar',
|
||||
noData: 'Sense dades'
|
||||
agency: 'Agència',
|
||||
noData: 'Sense dades',
|
||||
confirm: 'Confirmar'
|
||||
};
|
||||
|
|
|
@ -74,10 +74,14 @@ export default {
|
|||
adminNewsDetails: 'Add or edit new',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Order loaded into basket!',
|
||||
loadAnOrder: 'Please load a pending order to the cart or start a new one',
|
||||
at: 'at',
|
||||
back: 'Back',
|
||||
next: 'Next',
|
||||
remove: 'Remove',
|
||||
agency: 'Agency',
|
||||
noData: 'No data',
|
||||
confirm: 'Confirm',
|
||||
|
||||
orders: 'Orders',
|
||||
order: 'Pending order',
|
||||
|
|
|
@ -80,10 +80,15 @@ export default {
|
|||
adminNewsDetails: 'Añadir o editar noticia',
|
||||
//
|
||||
orderLoadedIntoBasket: '¡Pedido cargado en la cesta!',
|
||||
loadAnOrder:
|
||||
'Por favor carga un pedido pendiente en la cesta o empieza uno nuevo',
|
||||
at: 'a las',
|
||||
back: 'Volver',
|
||||
next: 'Siguiente',
|
||||
remove: 'Borrar',
|
||||
agency: 'Agencia',
|
||||
noData: 'Sin datos',
|
||||
confirm: 'Confirmar',
|
||||
|
||||
orders: 'Pedidos',
|
||||
order: 'Pedido pendiente',
|
||||
|
|
|
@ -61,8 +61,13 @@ export default {
|
|||
adminNewsDetails: 'Ajouter ou editer nouvelles',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Commande chargée dans le panier!',
|
||||
loadAnOrder:
|
||||
'Veuillez télécharger une commande en attente dans le panier ou en démarrer une nouvelle',
|
||||
at: 'à',
|
||||
back: 'Retour',
|
||||
next: 'Suivant',
|
||||
remove: 'Effacer',
|
||||
noData: 'Aucune donnée'
|
||||
agency: 'Agence',
|
||||
noData: 'Aucune donnée',
|
||||
confirm: 'Confirmer'
|
||||
};
|
||||
|
|
|
@ -62,8 +62,12 @@ export default {
|
|||
adminNewsDetails: 'Ajouter ou editer nouvelles',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Pedido carregado na cesta!',
|
||||
loadAnOrder: 'Carregue um pedido pendente no carrinho ou inicie um novo',
|
||||
at: 'às',
|
||||
back: 'Voltar',
|
||||
next: 'Seguinte',
|
||||
remove: 'Eliminar',
|
||||
noData: 'Sem dados'
|
||||
agency: 'Agência',
|
||||
noData: 'Sem dados',
|
||||
confirm: 'Confirme'
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { JsonConnection } from '../vn/json-connection'
|
||||
import { ResultSet } from './result-set'
|
||||
import { JsonConnection } from '../vn/json-connection';
|
||||
import { ResultSet } from './result-set';
|
||||
|
||||
/**
|
||||
* Simulates a connection to a database by making asynchronous requests to a
|
||||
|
@ -15,7 +15,7 @@ const Flag = {
|
|||
NOT_NULL: 1,
|
||||
PRI_KEY: 2,
|
||||
AI: 512 | 2 | 1
|
||||
}
|
||||
};
|
||||
|
||||
const Type = {
|
||||
BOOLEAN: 1,
|
||||
|
@ -24,11 +24,11 @@ const Type = {
|
|||
STRING: 5,
|
||||
DATE: 8,
|
||||
DATE_TIME: 9
|
||||
}
|
||||
};
|
||||
|
||||
export class Connection extends JsonConnection {
|
||||
static Flag = Flag
|
||||
static Type = Type
|
||||
static Flag = Flag;
|
||||
static Type = Type;
|
||||
|
||||
/**
|
||||
* Runs a SQL query on the database.
|
||||
|
@ -36,68 +36,70 @@ export class Connection extends JsonConnection {
|
|||
* @param {String} sql The SQL statement
|
||||
* @return {ResultSet} The result
|
||||
*/
|
||||
async execSql (sql) {
|
||||
const json = await this.send('core/query', { sql })
|
||||
const results = []
|
||||
let err
|
||||
async execSql(sql) {
|
||||
const json = await this.send('core/query', { sql });
|
||||
const results = [];
|
||||
let err;
|
||||
|
||||
if (json) {
|
||||
try {
|
||||
if (json && json instanceof Array) {
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
if (json[i] !== true) {
|
||||
const rows = json[i].data
|
||||
const columns = json[i].columns
|
||||
const rows = json[i].data;
|
||||
const columns = json[i].columns;
|
||||
|
||||
const data = new Array(rows.length)
|
||||
const data = new Array(rows.length);
|
||||
results.push({
|
||||
data,
|
||||
columns,
|
||||
tables: json[i].tables
|
||||
})
|
||||
});
|
||||
|
||||
for (let j = 0; j < rows.length; j++) {
|
||||
const row = (data[j] = {})
|
||||
const row = (data[j] = {});
|
||||
for (let k = 0; k < columns.length; k++) {
|
||||
row[columns[k].name] = rows[j][k]
|
||||
row[columns[k].name] = rows[j][k];
|
||||
}
|
||||
}
|
||||
|
||||
for (let j = 0; j < columns.length; j++) {
|
||||
let castFunc = null
|
||||
const col = columns[j]
|
||||
let castFunc = null;
|
||||
const col = columns[j];
|
||||
|
||||
switch (col.type) {
|
||||
case Type.DATE:
|
||||
case Type.DATE_TIME:
|
||||
case Type.TIMESTAMP:
|
||||
castFunc = this.valueToDate
|
||||
break
|
||||
castFunc = this.valueToDate;
|
||||
break;
|
||||
}
|
||||
|
||||
if (castFunc !== null) {
|
||||
if (col.def != null) {
|
||||
col.def = castFunc(col.def)
|
||||
col.def = castFunc(col.def);
|
||||
}
|
||||
|
||||
for (let k = 0; k < data.length; k++) {
|
||||
if (data[k][col.name] != null) {
|
||||
data[k][col.name] = castFunc(data[k][col.name])
|
||||
data[k][col.name] = castFunc(
|
||||
data[k][col.name]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results.push(json[i])
|
||||
results.push(json[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
err = e
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
|
||||
return new ResultSet(results, err)
|
||||
return new ResultSet(results, err);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,48 +109,48 @@ export class Connection extends JsonConnection {
|
|||
* @param {Object} params The query params
|
||||
* @return {ResultSet} The result
|
||||
*/
|
||||
async execQuery (query, params) {
|
||||
const sql = query.replace(/#\w+/g, (key) => {
|
||||
const value = params[key.substring(1)]
|
||||
return value ? this.renderValue(value) : key
|
||||
})
|
||||
async execQuery(query, params) {
|
||||
const sql = query.replace(/#\w+/g, key => {
|
||||
const value = params[key.substring(1)];
|
||||
return value ? this.renderValue(value) : key;
|
||||
});
|
||||
|
||||
return await this.execSql(sql)
|
||||
return await this.execSql(sql);
|
||||
}
|
||||
|
||||
async query (query, params) {
|
||||
const res = await this.execQuery(query, params)
|
||||
return res.fetchData()
|
||||
async query(query, params) {
|
||||
const res = await this.execQuery(query, params);
|
||||
return res.fetchData();
|
||||
}
|
||||
|
||||
async getObject (query, params) {
|
||||
const res = await this.execQuery(query, params)
|
||||
return res.fetchObject()
|
||||
async getObject(query, params) {
|
||||
const res = await this.execQuery(query, params);
|
||||
return res.fetchObject();
|
||||
}
|
||||
|
||||
async getValue (query, params) {
|
||||
const res = await this.execQuery(query, params)
|
||||
return res.fetchValue()
|
||||
async getValue(query, params) {
|
||||
const res = await this.execQuery(query, params);
|
||||
return res.fetchValue();
|
||||
}
|
||||
|
||||
renderValue (v) {
|
||||
renderValue(v) {
|
||||
switch (typeof v) {
|
||||
case 'number':
|
||||
return v
|
||||
return v;
|
||||
case 'boolean':
|
||||
return v ? 'TRUE' : 'FALSE'
|
||||
return v ? 'TRUE' : 'FALSE';
|
||||
case 'string':
|
||||
return "'" + v.replace(this.regexp, this.replaceFunc) + "'"
|
||||
return "'" + v.replace(this.regexp, this.replaceFunc) + "'";
|
||||
default:
|
||||
if (v instanceof Date) {
|
||||
if (!isNaN(v.getTime())) {
|
||||
const unixTime = parseInt(fixTz(v).getTime() / 1000)
|
||||
return 'DATE(FROM_UNIXTIME(' + unixTime + '))'
|
||||
const unixTime = parseInt(fixTz(v).getTime() / 1000);
|
||||
return 'DATE(FROM_UNIXTIME(' + unixTime + '))';
|
||||
} else {
|
||||
return '0000-00-00'
|
||||
return '0000-00-00';
|
||||
}
|
||||
} else {
|
||||
return 'NULL'
|
||||
return 'NULL';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,29 +158,30 @@ export class Connection extends JsonConnection {
|
|||
/*
|
||||
* Parses a value to date.
|
||||
*/
|
||||
valueToDate (value) {
|
||||
return fixTz(new Date(value))
|
||||
valueToDate(value) {
|
||||
return fixTz(new Date(value));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Read time zone from db configuration
|
||||
const tz = { timeZone: 'Europe/Madrid' }
|
||||
const isLocal = Intl.DateTimeFormat().resolvedOptions().timeZone === tz.timeZone
|
||||
const tz = { timeZone: 'Europe/Madrid' };
|
||||
const isLocal =
|
||||
Intl.DateTimeFormat().resolvedOptions().timeZone === tz.timeZone;
|
||||
|
||||
function fixTz (date) {
|
||||
if (isLocal) return date
|
||||
function fixTz(date) {
|
||||
if (isLocal) return date;
|
||||
|
||||
const localDate = new Date(date.toLocaleString('en-US', tz))
|
||||
const localDate = new Date(date.toLocaleString('en-US', tz));
|
||||
const hasTime =
|
||||
localDate.getHours() ||
|
||||
localDate.getMinutes() ||
|
||||
localDate.getSeconds() ||
|
||||
localDate.getMilliseconds()
|
||||
localDate.getMilliseconds();
|
||||
|
||||
if (!hasTime) {
|
||||
date.setHours(date.getHours() + 12)
|
||||
date.setHours(0, 0, 0, 0)
|
||||
date.setHours(date.getHours() + 12);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
return date
|
||||
return date;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import { Result } from './result'
|
||||
import { Result } from './result';
|
||||
|
||||
/**
|
||||
* This class stores the database results.
|
||||
*/
|
||||
export class ResultSet {
|
||||
results = null
|
||||
error = null
|
||||
results = null;
|
||||
error = null;
|
||||
|
||||
/**
|
||||
* Initilizes the resultset object.
|
||||
*/
|
||||
constructor (results, error) {
|
||||
this.results = results
|
||||
this.error = error
|
||||
constructor(results, error) {
|
||||
this.results = results;
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,20 +20,20 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Db.Err} the error or null if no errors hapened
|
||||
*/
|
||||
getError () {
|
||||
return this.error
|
||||
getError() {
|
||||
return this.error;
|
||||
}
|
||||
|
||||
fetch () {
|
||||
fetch() {
|
||||
if (this.error) {
|
||||
throw this.error
|
||||
throw this.error;
|
||||
}
|
||||
|
||||
if (this.results !== null && this.results.length > 0) {
|
||||
return this.results.shift()
|
||||
return this.results.shift();
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,18 +41,18 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Db.Result} the result or %null if error or there are no more results
|
||||
*/
|
||||
fetchResult () {
|
||||
const result = this.fetch()
|
||||
fetchResult() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (result !== null) {
|
||||
if (result.data instanceof Array) {
|
||||
return new Result(result)
|
||||
return new Result(result);
|
||||
} else {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,18 +60,18 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Array} the row if success, %null otherwise
|
||||
*/
|
||||
fetchObject () {
|
||||
const result = this.fetch()
|
||||
fetchObject() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (
|
||||
result !== null &&
|
||||
result.data instanceof Array &&
|
||||
result.data.length > 0
|
||||
) {
|
||||
return result.data[0]
|
||||
return result.data[0];
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,14 +79,14 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Array} the data
|
||||
*/
|
||||
fetchData () {
|
||||
const result = this.fetch()
|
||||
fetchData() {
|
||||
const result = this.fetch();
|
||||
|
||||
if (result !== null && result.data instanceof Array) {
|
||||
return result.data
|
||||
return result.data;
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,14 +94,13 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Object} the value if success, %null otherwise
|
||||
*/
|
||||
fetchValue () {
|
||||
const row = this.fetchRow()
|
||||
|
||||
fetchValue() {
|
||||
const row = this.fetchRow();
|
||||
if (row instanceof Array && row.length > 0) {
|
||||
return row[0]
|
||||
return row[0];
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,22 +108,21 @@ export class ResultSet {
|
|||
*
|
||||
* @return {Array} the row if success, %null otherwise
|
||||
*/
|
||||
fetchRow () {
|
||||
const result = this.fetch()
|
||||
|
||||
fetchRow() {
|
||||
const result = this.fetch();
|
||||
if (
|
||||
result !== null &&
|
||||
result.data instanceof Array &&
|
||||
result.data.length > 0
|
||||
) {
|
||||
const object = result.data[0]
|
||||
const row = new Array(result.columns.length)
|
||||
const object = result.data[0];
|
||||
const row = new Array(result.columns.length);
|
||||
for (let i = 0; i < row.length; i++) {
|
||||
row[i] = object[result.columns[i].name]
|
||||
row[i] = object[result.columns[i].name];
|
||||
}
|
||||
return row
|
||||
return row;
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { i18n } from 'src/boot/i18n';
|
||||
import { date as qdate, format } from 'quasar';
|
||||
const { pad } = format;
|
||||
import { useAppStore } from 'stores/app';
|
||||
|
||||
export function currency(val) {
|
||||
return typeof val === 'number' ? val.toFixed(2) + '€' : val;
|
||||
|
@ -16,14 +17,9 @@ export function date(val, format = 'YYYY-MM-DD') {
|
|||
|
||||
export const formatDate = (timeStamp, format = 'YYYY-MM-DD') => {
|
||||
if (!timeStamp) return '';
|
||||
const { messages, locale } = i18n.global;
|
||||
const appStore = useAppStore();
|
||||
|
||||
return qdate.formatDate(timeStamp, format, {
|
||||
days: messages.value[locale.value].date.days,
|
||||
months: messages.value[locale.value].date.months,
|
||||
daysShort: messages.value[locale.value].date.daysShort,
|
||||
monthsShort: messages.value[locale.value].date.monthsShort
|
||||
});
|
||||
return qdate.formatDate(timeStamp, format, appStore.localeDates);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,27 +66,22 @@ onMounted(() => getPackages());
|
|||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
agency: Agency
|
||||
bundles: Bundles
|
||||
expeditions: Exps.
|
||||
prevision: Prev.
|
||||
es-ES:
|
||||
agency: Agencia
|
||||
bundles: Bultos
|
||||
expeditions: Exps.
|
||||
prevision: Prev.
|
||||
ca-ES:
|
||||
agency: Agència
|
||||
bundles: Paquets
|
||||
expeditions: Exps.
|
||||
prevision: Prev.
|
||||
fr-FR:
|
||||
agency: Agence
|
||||
bundles: Cartons
|
||||
expeditions: Exps.
|
||||
prevision: Prev.
|
||||
pt-PT:
|
||||
agency: Agência
|
||||
bundles: Bultos
|
||||
expeditions: Exps.
|
||||
prevision: Prev.
|
||||
|
|
|
@ -1 +1,14 @@
|
|||
<template>Basket view</template>
|
||||
<script setup>
|
||||
import { onBeforeMount } from 'vue';
|
||||
|
||||
import { useAppStore } from 'stores/app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
onBeforeMount(() => {
|
||||
appStore.check();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div>basket view</div>
|
||||
</template>
|
||||
|
|
|
@ -37,7 +37,16 @@
|
|||
{{ $t('warehouse') }}
|
||||
{{ 'Algemesi' }}
|
||||
</p>
|
||||
<QBtn flat rounded no-caps>
|
||||
<QBtn
|
||||
flat
|
||||
rounded
|
||||
no-caps
|
||||
:to="{
|
||||
name: 'checkout',
|
||||
|
||||
params: { id: appStore.basketOrderId },
|
||||
query: { continue: 'catalog' }
|
||||
}"
|
||||
>
|
||||
{{ $t('modify') }}
|
||||
</QBtn>
|
||||
</div>
|
||||
|
@ -355,7 +364,7 @@ export default {
|
|||
setup() {
|
||||
const appStore = useAppStore();
|
||||
const { isHeaderMounted } = storeToRefs(appStore);
|
||||
return { isHeaderMounted };
|
||||
return { isHeaderMounted, appStore };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -417,6 +426,12 @@ export default {
|
|||
created() {
|
||||
this.$app.useRightDrawer = true;
|
||||
},
|
||||
async beforeMount() {
|
||||
const isGuest = false; // TODO: Integrate isGuest logic
|
||||
if (!isGuest) {
|
||||
this.appStore.check('catalog');
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.categories = await this.$jApi.query(
|
||||
`SELECT c.id, l.name, c.color, c.code
|
||||
|
|
|
@ -1 +1,572 @@
|
|||
<template>Checkout</template>
|
||||
<script setup>
|
||||
import { ref, onMounted, inject, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
|
||||
import { formatDateTitle, formatDate } from 'src/lib/filters.js';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { useAppStore } from 'stores/app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const jApi = inject('jApi');
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { notify } = useNotify();
|
||||
const appStore = useAppStore();
|
||||
const { localeDates } = storeToRefs(appStore);
|
||||
|
||||
const stepperRef = ref(null);
|
||||
|
||||
const loading = ref(false);
|
||||
const today = ref(null);
|
||||
const addresses = ref([]);
|
||||
const agencies = ref([]);
|
||||
const warehouses = ref([]);
|
||||
const currentStep = ref('method');
|
||||
const id = route.params.id;
|
||||
const orderForm = ref({
|
||||
method: 'AGENCY',
|
||||
date: '',
|
||||
address: ''
|
||||
});
|
||||
|
||||
const steps = {
|
||||
AGENCY: [
|
||||
{
|
||||
name: 'method',
|
||||
stepDone: false,
|
||||
validateStep: () =>
|
||||
validateStep('method', t('pleaseSelectAnOption'))
|
||||
},
|
||||
{
|
||||
name: 'date',
|
||||
stepDone: false,
|
||||
validateStep: () => validateStep('date', t('pleaseSelectADate'))
|
||||
},
|
||||
{
|
||||
name: 'address',
|
||||
validateStep: () =>
|
||||
validateStep('address', t('pleaseSelectAnAddress'))
|
||||
},
|
||||
{
|
||||
name: 'agency',
|
||||
onStepMounted: async () => {
|
||||
await getAgencies();
|
||||
},
|
||||
validateStep: () =>
|
||||
validateStep('agency', t('pleaseSelectAnAgency'))
|
||||
},
|
||||
{
|
||||
name: 'confirm',
|
||||
nextButtonLabel: t('confirm'),
|
||||
onBeforeNextStep: async () => {
|
||||
await submit();
|
||||
}
|
||||
}
|
||||
],
|
||||
PICKUP: [
|
||||
{
|
||||
name: 'method',
|
||||
validateStep: () =>
|
||||
validateStep('method', t('pleaseSelectAnOption'))
|
||||
},
|
||||
{
|
||||
name: 'date',
|
||||
validateStep: () => validateStep('date', t('pleaseSelectADate'))
|
||||
},
|
||||
{
|
||||
name: 'address',
|
||||
validateStep: () =>
|
||||
validateStep('address', t('pleaseSelectAnAddress'))
|
||||
},
|
||||
{
|
||||
name: 'pickup',
|
||||
validateStep: () =>
|
||||
validateStep('agency', t('pleaseSelectAWarehouse')),
|
||||
onStepMounted: async () => {
|
||||
await getWarehouses();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'confirm',
|
||||
nextButtonLabel: t('confirm'),
|
||||
onBeforeNextStep: async () => {
|
||||
await submit();
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const confirmArrivalText = computed(() => {
|
||||
const { method, agency, date } = orderForm.value;
|
||||
|
||||
if (!agency) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const arrivalType = method === 'AGENCY' ? t('arrival') : t('pickup');
|
||||
return `${arrivalType} ${formatDateTitle(date)}`;
|
||||
});
|
||||
|
||||
const confirmAddressText = computed(() => {
|
||||
if (!orderForm.value.address) return '';
|
||||
const address = addresses.value.find(
|
||||
address => address.id === orderForm.value.address
|
||||
);
|
||||
return address.street;
|
||||
});
|
||||
|
||||
const confirmPlaceText = computed(() => {
|
||||
jsegarra
commented
Ufff...si vamos bien de tiempo, arreglamos esta funcion:
Ufff...si vamos bien de tiempo, arreglamos esta funcion:
1. El método find hace lo mismo, solo cambia el origen de datos
2. La lógica del return hace lo mismo, solo cambia la etiqueta que quremos traducir
|
||||
const { agency, method } = orderForm.value;
|
||||
if (!agency) return '';
|
||||
|
||||
if (method === 'AGENCY') {
|
||||
const agencyItem = agencies.value.find(a => a.id === agency);
|
||||
return agencyItem ? `${t('agency')} ${agencyItem.description}` : '';
|
||||
}
|
||||
|
||||
if (method === 'PICKUP') {
|
||||
const warehouseItem = warehouses.value.find(w => w.id === agency);
|
||||
return warehouseItem
|
||||
? `${t('warehouse')} ${warehouseItem.description}`
|
||||
: '';
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
|
||||
const validateStep = (formField, errorMessage) => {
|
||||
const validation = !!orderForm.value[formField];
|
||||
if (!validation) {
|
||||
notify(errorMessage, 'negative');
|
||||
}
|
||||
return validation;
|
||||
};
|
||||
|
||||
const getAddresses = async () => {
|
||||
try {
|
||||
addresses.value = await jApi.query(
|
||||
`SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.name
|
||||
FROM myAddress a
|
||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||
JOIN vn.country c ON c.id = p.countryFk
|
||||
WHERE a.isActive`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error getting addresses:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const getAgencies = async () => {
|
||||
try {
|
||||
const { results } = await jApi.execQuery(
|
||||
`CALL vn.zone_getAgency(#address, #date);
|
||||
SELECT DISTINCT a.agencyModeFk id, a.description
|
||||
FROM tmp.zoneGetAgency a
|
||||
JOIN vn.deliveryMethod d
|
||||
ON d.id = a.deliveryMethodFk
|
||||
WHERE d.code IN ('AGENCY', 'DELIVERY')
|
||||
AND a.isVisible
|
||||
ORDER BY a.description;
|
||||
DROP TEMPORARY TABLE tmp.zoneGetAgency`,
|
||||
{
|
||||
address: orderForm.value.address,
|
||||
date: new Date(orderForm.value.date)
|
||||
}
|
||||
);
|
||||
agencies.value = results[1].data;
|
||||
} catch (error) {
|
||||
console.error('Error getting agencies:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const getWarehouses = async () => {
|
||||
try {
|
||||
const { results } = await jApi.execQuery(
|
||||
`CALL vn.zone_getAgency(#address, #date);
|
||||
SELECT DISTINCT a.agencyModeFk id, a.description
|
||||
FROM tmp.zoneGetAgency a
|
||||
JOIN vn.deliveryMethod d
|
||||
ON d.id = a.deliveryMethodFk
|
||||
WHERE d.code IN ('PICKUP')
|
||||
AND a.isVisible
|
||||
ORDER BY a.description;
|
||||
DROP TEMPORARY TABLE tmp.zoneGetAgency;`,
|
||||
{
|
||||
jsegarra marked this conversation as resolved
jsegarra
commented
Se que no está en dev, pero esta notificación se puede mostrar y que no cambie de paso, asi te permite escoger una dirección diferente sin hacer un click extra. Aunque lo ideal, si el mensaje dice que para esa fecha no hay, que te lleve directamente al paso de fecha. Se que no está en dev, pero esta notificación se puede mostrar y que no cambie de paso, asi te permite escoger una dirección diferente sin hacer un click extra. Aunque lo ideal, si el mensaje dice que para esa fecha no hay, que te lleve directamente al paso de fecha.
Lo anotaria como propuesta de mejora
wbuezas
commented
Lo podemos poner en la lista de propuestas para mejoras Lo podemos poner en la lista de propuestas para mejoras
jsegarra
commented
Anotado Anotado
|
||||
address: orderForm.value.address,
|
||||
date: new Date(orderForm.value.date)
|
||||
}
|
||||
);
|
||||
warehouses.value = results[1].data;
|
||||
|
||||
if (!warehouses.value || !warehouses.value.length) {
|
||||
notify(t('noWarehousesAvailableForDate'), 'negative');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error getting agencies:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const onNextStep = async stepIndex => {
|
||||
const currentStep = steps[orderForm.value.method][stepIndex];
|
||||
if (currentStep.onBeforeNextStep) {
|
||||
await currentStep.onBeforeNextStep();
|
||||
}
|
||||
|
||||
if (currentStep.validateStep && !currentStep.validateStep()) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentStep.stepDone = true;
|
||||
await stepperRef.value.next();
|
||||
|
||||
const nextStep = steps[orderForm.value.method][stepIndex + 1];
|
||||
if (nextStep && nextStep.onStepMounted) {
|
||||
await nextStep.onStepMounted();
|
||||
}
|
||||
};
|
||||
|
||||
const onPreviousStep = async stepIndex => {
|
||||
await stepperRef.value.previous();
|
||||
|
||||
const previousStep = steps[orderForm.value.method][stepIndex - 1];
|
||||
|
||||
if (previousStep.onStepMounted) {
|
||||
await previousStep.onStepMounted();
|
||||
}
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
loading.value = true;
|
||||
let query =
|
||||
'CALL myOrder_create(@orderId, #date, #method, #agency, #address); SELECT @orderId;';
|
||||
if (id) {
|
||||
orderForm.value.id = id;
|
||||
query =
|
||||
'CALL myOrder_configure(#id, #date, #method, #agency, #address)';
|
||||
}
|
||||
|
||||
let resultSet;
|
||||
try {
|
||||
const { date, ...restOfForm } = orderForm.value;
|
||||
const _date = new Date(date);
|
||||
resultSet = await jApi.execQuery(query, { ...restOfForm, date: _date });
|
||||
if (id) {
|
||||
notify(t('orderUpdated'), 'positive');
|
||||
if (route.query.continue === 'catalog') {
|
||||
router.push({ name: 'catalog' });
|
||||
} else {
|
||||
router.push({ name: 'basket', params: { id } });
|
||||
}
|
||||
} else {
|
||||
const orderId = resultSet.results[1].data[0]['@orderId'];
|
||||
appStore.loadIntoBasket(orderId);
|
||||
router.push({ name: 'catalog' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error submitting order:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
today.value = Date.vnNew();
|
||||
today.value.setHours(0, 0, 0, 0);
|
||||
|
||||
if (route.params.id) {
|
||||
const [order] = await jApi.query(
|
||||
`SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk
|
||||
FROM myOrder o
|
||||
JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
|
||||
WHERE o.id = #id`,
|
||||
{ id: route.params.id }
|
||||
);
|
||||
|
||||
if (order) {
|
||||
orderForm.value.method = order.deliveryMethod;
|
||||
orderForm.value.date = formatDate(order.sent, 'YYYY/MM/DD');
|
||||
orderForm.value.agency = order.agencyModeFk;
|
||||
orderForm.value.address = order.addressFk;
|
||||
}
|
||||
}
|
||||
|
||||
getAddresses();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="vn-w-sm">
|
||||
<QStepper
|
||||
v-if="steps[orderForm.method] && steps[orderForm.method].length"
|
||||
v-model="currentStep"
|
||||
ref="stepperRef"
|
||||
animated
|
||||
keep-alive
|
||||
contracted
|
||||
class="default-radius"
|
||||
>
|
||||
<QStep
|
||||
v-for="(step, stepIndex) in steps[orderForm.method]"
|
||||
:key="stepIndex"
|
||||
:name="step.name"
|
||||
:done="step.stepDone"
|
||||
done-color="accent"
|
||||
>
|
||||
<!-- Method step -->
|
||||
<div
|
||||
v-if="step.name === 'method'"
|
||||
class="column justify-center items-center"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{ t('receiveOrPickOrder') }}
|
||||
</span>
|
||||
<div class="column" style="max-width: max-content">
|
||||
<QRadio
|
||||
v-model="orderForm.method"
|
||||
val="AGENCY"
|
||||
:label="t('receiveOrder')"
|
||||
/>
|
||||
<QRadio
|
||||
v-model="orderForm.method"
|
||||
val="PICKUP"
|
||||
:label="t('pickupInStore')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Date step -->
|
||||
<div
|
||||
v-if="step.name === 'date'"
|
||||
class="flex justify-center items-center"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{ t('orderDateDelivery') }}
|
||||
</span>
|
||||
<QDate
|
||||
v-model="orderForm.date"
|
||||
class="margin-auto"
|
||||
color="accent"
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
La fecha está en inglés La fecha está en inglés
wbuezas
commented
Corregido. Commit: Corregido.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/020e0afc96427ca1bf6db03dba58e4b1f38b8b27
|
||||
:locale="localeDates"
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Empieza en domingo, a nivel de empresa podría servir, pero decara a un usuario final, puede llevar a confusión Empieza en domingo, a nivel de empresa podría servir, pero decara a un usuario final, puede llevar a confusión
wbuezas
commented
Agregado. Commit: Agregado.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/975495113d2d7b2c5257d3f9b3d9f7e17f1cb7a8
|
||||
first-day-of-week="1"
|
||||
:minimal="appStore.isMobile"
|
||||
flat
|
||||
/>
|
||||
</div>
|
||||
<!-- Address step -->
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Este step no tiene titulo? Este step no tiene titulo?
wbuezas
commented
Corregido. Commit: Corregido.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/f2bd3c2fa6f6db469205c772612d1b1b28cde459
|
||||
<QList
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Con el segundo metodo, he podido avvanzar sin seleccionar una dirección. Esto en los otros pasos no ocurre. Con el segundo metodo, he podido avvanzar sin seleccionar una dirección. Esto en los otros pasos no ocurre.
wbuezas
commented
Validación agregada. Commit: Validación agregada.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/3a21292030bc7b091de789e8771cd69114e09602
|
||||
v-if="step.name === 'address'"
|
||||
class="vn-w-xs q-gutter-y-sm column"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{
|
||||
t(
|
||||
orderForm.method === 'PICKUP'
|
||||
? 'addressStepQuestionPickup'
|
||||
: 'addressStepQuestion'
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<QItem
|
||||
v-for="(address, index) in addresses"
|
||||
:key="index"
|
||||
tag="label"
|
||||
v-ripple
|
||||
>
|
||||
<QItemSection avatar>
|
||||
<QRadio
|
||||
v-model="orderForm.address"
|
||||
:val="address.id"
|
||||
/>
|
||||
</QItemSection>
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Si selecciono "Recibir en mi tienda", me aparece el mismo titulo que seleccionar fecha Si selecciono "Recibir en mi tienda", me aparece el mismo titulo que seleccionar fecha
wbuezas
commented
Corregido. Commit: Corregido.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/6423ecfb05a63b0cd6b637e378e75da733591d5b
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ address.nickname }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ address.street }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<!-- Agency step (AGENCY) -->
|
||||
<div
|
||||
v-if="step.name === 'agency'"
|
||||
class="flex justify-center items-center"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{ t('howDoYouWantToReceive') }}
|
||||
</span>
|
||||
<VnSelect
|
||||
v-model="orderForm.agency"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
:options="agencies"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="step.name === 'pickup'"
|
||||
class="flex justify-center items-center"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{ t('pickupWarehouse') }}
|
||||
</span>
|
||||
<VnSelect
|
||||
v-model="orderForm.agency"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
:options="warehouses"
|
||||
/>
|
||||
</div>
|
||||
<!-- Confirm step -->
|
||||
<div
|
||||
v-if="step.name === 'confirm'"
|
||||
class="flex column justify-center items-center"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{ t('confirmData') }}
|
||||
</span>
|
||||
<div class="column vn-w-xs full-width">
|
||||
<span>{{ confirmArrivalText }}</span>
|
||||
<span v-if="orderForm.method === 'AGENCY'">
|
||||
{{ confirmAddressText }}
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
traducir traducir
wbuezas
commented
Traducido. Commit: Traducido.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/95e23c05fa8dbdb329fa72b7edd034faf0656ff5
|
||||
</span>
|
||||
<span>{{ confirmPlaceText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<QStepperNavigation class="flex justify-between">
|
||||
<QBtn
|
||||
flat
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
traducir traducir
wbuezas
commented
Traducido. Commit: Traducido.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/95e23c05fa8dbdb329fa72b7edd034faf0656ff5
|
||||
color="primary"
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
La label del botón en el ultimo paso debería ser confirmar, finalizar, guardar, confirmar con Javi La label del botón en el ultimo paso debería ser confirmar, finalizar, guardar, confirmar con Javi
wbuezas
commented
Agregado. Commit: Agregado.
Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/8e0f09cc0f73afda885f28991fb40689a1bf9e2e
|
||||
@click="onPreviousStep(stepIndex)"
|
||||
:label="step.backButtonLabel || t('back')"
|
||||
class="q-ml-sm"
|
||||
:class="{ invisible: currentStep === 'method' }"
|
||||
/>
|
||||
<QBtn
|
||||
@click="onNextStep(stepIndex)"
|
||||
color="primary"
|
||||
:label="step.nextButtonLabel || t('next')"
|
||||
/>
|
||||
</QStepperNavigation>
|
||||
</QStep>
|
||||
</QStepper>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.step-title {
|
||||
min-width: 100%;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
receiveOrPickOrder: Do you want to receive or pickup the order?
|
||||
receiveOrder: Receive in my store
|
||||
pickupInStore: Store pickup
|
||||
orderDateDelivery: What day you want to receive the order?
|
||||
howDoYouWantToReceive: How do you want to receive the order?
|
||||
confirmData: Confirm data
|
||||
arrival: Arrival
|
||||
orderUpdated: Order updated
|
||||
pleaseSelectAnOption: Please select an option
|
||||
pleaseSelectADate: Please select a date
|
||||
pleaseSelectAnAddress: Please select an address
|
||||
pleaseSelectAnAgency: Please select an agency
|
||||
pickupWarehouse: What store you want to pickup your order?
|
||||
noWarehousesAvailableForDate: There are no stores available for the selected date, check the date of order pickup and that selected address contains a correct province and zip code
|
||||
noAgeciesAvailableForDate: There are no agencies available for the selected date and consignee, check the date of the order and that selected address contains a correct province and zip code
|
||||
pleaseSelectAWarehouse: Please select a store
|
||||
warehouse: Warehouse
|
||||
pickup: Pickup
|
||||
addressStepQuestion: Where do you want to receive the order?
|
||||
addressStepQuestionPickup: To which address do you want to associate the order? (Optional)
|
||||
es-ES:
|
||||
receiveOrPickOrder: ¿Quieres recibir o recoger el pedido?
|
||||
receiveOrder: Recibir en mi tienda
|
||||
pickupInStore: Recoger en almacén
|
||||
orderDateDelivery: ¿Qué día quieres recibir el pedido?
|
||||
howDoYouWantToReceive: ¿Cómo quieres recibir el pedido?
|
||||
confirmData: Confirma los datos
|
||||
arrival: Llegada
|
||||
orderUpdated: Pedido actualizado
|
||||
pleaseSelectAnOption: Por favor, selecciona una opción
|
||||
pleaseSelectADate: Por favor, selecciona una fecha
|
||||
pleaseSelectAnAddress: Por favor, selecciona una dirección
|
||||
pleaseSelectAnAgency: Por favor, selecciona una agencia
|
||||
pickupWarehouse: ¿En qué almacén quieres recoger tu pedido?
|
||||
noWarehousesAvailableForDate: No hay almacenes disponibles para la fecha seleccionada, comprueba la fecha de recogida del pedido y que consignatario seleccionado contiene una provincia y código postal correctos
|
||||
noAgeciesAvailableForDate: No hay almacenes disponibles para la fecha seleccionada, comprueba la fecha de recogida del pedido y que consignatario seleccionado contiene una provincia y código postal correctos
|
||||
pleaseSelectAWarehouse: Por favor elige un almacén
|
||||
warehouse: Almacén
|
||||
pickup: Recogida
|
||||
addressStepQuestion: ¿Dónde quieres recibir el pedido?
|
||||
addressStepQuestionPickup: ¿A qué dirección quieres asociar el pedido? (Opcional)
|
||||
ca-ES:
|
||||
receiveOrPickOrder: Vols rebre o recollir la comanda?
|
||||
receiveOrder: Rebre en mi tenda
|
||||
pickupInStore: Recollir en magatzem
|
||||
orderDateDelivery: Quin dia vols rebre la comanda?
|
||||
howDoYouWantToReceive: Com vols rebre la comanda?
|
||||
confirmData: Confirma les dades
|
||||
arrival: Arribada
|
||||
orderUpdated: Comanda actualitzada
|
||||
pleaseSelectAnOption: Si us plau tria una opció
|
||||
pleaseSelectADate: Si us plau tria una data
|
||||
pleaseSelectAnAddress: Si us plau tria una adreça
|
||||
pleaseSelectAnAgency: Si us plau tria una agència
|
||||
pickupWarehouse: En quin magatzem vols recollir la comanda?
|
||||
noWarehousesAvailableForDate: No hi ha magatzems disponibles per a la data seleccionada, comprova la data de recollida de la comanda i que consignatari seleccionat conté una província i codi postal correctes
|
||||
noAgeciesAvailableForDate: No hi ha agències disponibles per a la data i el consignatari seleccionats, comprova la data de la comanda i que consignatari seleccionat conté una província i codi postal correctes
|
||||
pleaseSelectAWarehouse: Si us plau tria un magatzem
|
||||
warehouse: Magatzem
|
||||
pickup: Recollida
|
||||
addressStepQuestion: On vols rebre la comanda?
|
||||
addressStepQuestionPickup: A què direcció vols associar la comanda? (Opcional)
|
||||
fr-FR:
|
||||
receiveOrPickOrder: Voulez-vous recevoir ou récuperer l'ordre?
|
||||
receiveOrder: Livraison à la boutique
|
||||
pickupInStore: Récupérer en entrepôt
|
||||
orderDateDelivery: Date de livraison?
|
||||
howDoYouWantToReceive: Agence de livraison
|
||||
confirmData: Confirmez les coordonnées
|
||||
arrival: Arrivée
|
||||
orderUpdated: Mise à jour commande
|
||||
pleaseSelectAnOption: Veuillez choisir une option
|
||||
pleaseSelectADate: Veuillez choisir une date
|
||||
pleaseSelectAnAddress: Veuillez choisir une adresse
|
||||
pleaseSelectAnAgency: Veuillez choisir une agence
|
||||
pickupWarehouse: Dans quel magasin vuoulez-vous retirer votre commande?
|
||||
noWarehousesAvailableForDate: Pas de magasins disponibles à la date sélectionnée, changer la date de retrait et vérifier quel destinataire a été sélectionné contient une province et un code postal correct
|
||||
noAgeciesAvailableForDate: Aucune agence disponibles pour la date et le destinataire sélectionné, changer la date d'envoi de la commande et vérifier quel destinataire a été sélectionné contient une province et un code postal correct
|
||||
pleaseSelectAWarehouse: Veuillez choisir un entrepôt
|
||||
warehouse: Entrepôt
|
||||
pickup: Retrait
|
||||
addressStepQuestion: Adresse livraison?
|
||||
addressStepQuestionPickup: À quelle adresse voulez-vous associer la commande? (Optionnel)
|
||||
pt-PT:
|
||||
receiveOrPickOrder: Queres receber ou levantar a encomenda?
|
||||
receiveOrder: Receber na minha loja
|
||||
pickupInStore: Levantar no armazém
|
||||
orderDateDelivery: Como queres receber a encomenda?
|
||||
howDoYouWantToReceive: Como queres receber a encomenda?
|
||||
confirmData: Confirme os dados
|
||||
arrival: Chegada
|
||||
orderUpdated: Encomenda actualizada
|
||||
pleaseSelectAnOption: Por favor, escolha uma opção
|
||||
pleaseSelectADate: Por favor, escolha uma data
|
||||
pleaseSelectAnAddress: Por favor, escolha um endereço
|
||||
pleaseSelectAnAgency: Por favor, escolha uma agência
|
||||
pickupWarehouse: Em qual armazém queres levantar a encomenda?
|
||||
noWarehousesAvailableForDate: Não há armazéns disponíveis para a data seleccionada, modifique a data para levantar a encomenda e verifique qual destinatário selecionou contém uma província e código postal corretos
|
||||
noAgeciesAvailableForDate: Não há agências disponíveis para a data e o consignatario escolhido, modifique a data de envío do pedido e verifique qual destinatário selecionou contém uma província e código postal corretos
|
||||
pleaseSelectAWarehouse: Por favor, escolha um armazém
|
||||
warehouse: Armazém
|
||||
pickup: Recolhida
|
||||
addressStepQuestion: Onde queres receber a encomenda?
|
||||
addressStepQuestionPickup: Para qual endereço deseja associar o pedido? (Opcional)
|
||||
</i18n>
|
||||
|
|
|
@ -126,7 +126,6 @@ en-US:
|
|||
shippingInformation: Shipping Information
|
||||
preparation: Preparation
|
||||
delivery: Delivery
|
||||
agency: Agency
|
||||
warehouse: Store
|
||||
deliveryAddress: Delivery address
|
||||
total: Total
|
||||
|
@ -135,7 +134,6 @@ es-ES:
|
|||
shippingInformation: Datos de envío
|
||||
preparation: Preparación
|
||||
delivery: Entrega
|
||||
agency: Agencia
|
||||
warehouse: Almacén
|
||||
deliveryAddress: Dirección de entrega
|
||||
total: Total
|
||||
|
@ -144,7 +142,6 @@ ca-ES:
|
|||
shippingInformation: Dades d'enviament
|
||||
preparation: Preparació
|
||||
delivery: Lliurament
|
||||
agency: Agència
|
||||
warehouse: Magatzem
|
||||
deliveryAddress: Adreça de lliurament
|
||||
total: Total
|
||||
|
@ -161,7 +158,6 @@ pt-PT:
|
|||
shippingInformation: Dados de envio
|
||||
preparation: Preparação
|
||||
delivery: Entrega
|
||||
agency: Agência
|
||||
warehouse: Armazém
|
||||
deliveryAddress: Endereço de entrega
|
||||
total: Total
|
||||
|
|
|
@ -66,7 +66,7 @@ const routes = [
|
|||
},
|
||||
{
|
||||
name: 'checkout',
|
||||
path: '/ecomerce/checkout',
|
||||
path: '/ecomerce/checkout/:id?',
|
||||
component: () => import('pages/Ecomerce/CheckoutView.vue')
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import { jApi } from 'boot/axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { i18n } from 'src/boot/i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
const { notify } = useNotify();
|
||||
|
||||
|
@ -13,7 +15,13 @@ export const useAppStore = defineStore('hedera', {
|
|||
rightDrawerOpen: false,
|
||||
isHeaderMounted: false,
|
||||
menuEssentialLinks: [],
|
||||
basketOrderId: null
|
||||
basketOrderId: null,
|
||||
localeDates: {
|
||||
days: [],
|
||||
months: [],
|
||||
daysShort: [],
|
||||
monthsShort: []
|
||||
}
|
||||
}),
|
||||
|
||||
actions: {
|
||||
|
@ -48,8 +56,19 @@ export const useAppStore = defineStore('hedera', {
|
|||
this.$patch({ imageUrl });
|
||||
},
|
||||
|
||||
getLocaleDates() {
|
||||
const { messages, locale } = i18n.global;
|
||||
this.localeDates = {
|
||||
days: messages.value[locale.value].date.days,
|
||||
months: messages.value[locale.value].date.months,
|
||||
daysShort: messages.value[locale.value].date.daysShort,
|
||||
monthsShort: messages.value[locale.value].date.monthsShort
|
||||
};
|
||||
},
|
||||
|
||||
async init() {
|
||||
this.getBasketOrderId();
|
||||
this.getLocaleDates();
|
||||
},
|
||||
|
||||
getBasketOrderId() {
|
||||
|
@ -57,23 +76,70 @@ export const useAppStore = defineStore('hedera', {
|
|||
},
|
||||
|
||||
async checkOrder(orderId) {
|
||||
try {
|
||||
const resultSet = await jApi.execQuery(
|
||||
'CALL myOrder_checkConfig(#id)',
|
||||
{ id: orderId }
|
||||
);
|
||||
resultSet.fetchValue();
|
||||
},
|
||||
|
||||
async check(checkoutContinue) {
|
||||
if (this.basketOrderId) {
|
||||
return await this.checkRedirect(checkoutContinue);
|
||||
} else {
|
||||
this.redirect();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
async checkRedirect(checkoutContinue) {
|
||||
try {
|
||||
await this.checkOrder(this.basketOrderId);
|
||||
return true;
|
||||
} catch (err) {
|
||||
jsegarra
commented
What? What?
wbuezas
commented
Literal lo copie y pegue del viejo hedera, no se ni lo que es jajaja Literal lo copie y pegue del viejo hedera, no se ni lo que es jajaja
|
||||
console.error('Error checking order', err);
|
||||
if (err.exception === 'Vn.Lib.UserError') {
|
||||
switch (err.code) {
|
||||
case 'orderConfirmed':
|
||||
case 'orderNotOwnedByUser':
|
||||
await this.redirect();
|
||||
break;
|
||||
default:
|
||||
this.router.push({
|
||||
name: 'checkout',
|
||||
params: { id: this.basketOrderId },
|
||||
query: { continue: checkoutContinue }
|
||||
});
|
||||
notify(err.message, 'negative');
|
||||
}
|
||||
return false;
|
||||
} else throw err;
|
||||
}
|
||||
},
|
||||
|
||||
async redirect() {
|
||||
const resultSet = await jApi.execQuery(
|
||||
'SELECT COUNT(*) > 0 FROM myOrder'
|
||||
);
|
||||
if (resultSet.fetchValue()) {
|
||||
this.router.push({ name: 'pendingOrders' });
|
||||
notify('loadAnOrder', 'warning');
|
||||
} else {
|
||||
this.router.push({ name: 'checkout' });
|
||||
}
|
||||
},
|
||||
|
||||
loadIntoBasket(orderId) {
|
||||
if (this.basketOrderId !== orderId) {
|
||||
localStorage.setItem('hederaBasket', orderId);
|
||||
this.basketOrderId = orderId;
|
||||
jsegarra
commented
Porque no usamos pinia? Porque no usamos pinia?
|
||||
localStorage.setItem('hederaBasket', orderId);
|
||||
notify('orderLoadedIntoBasket', 'positive');
|
||||
}
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
isMobile() {
|
||||
const $q = useQuasar();
|
||||
return $q?.screen?.width <= 768;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Duda: en Lilium usamos UpperCamelCase, mientras que aquí usamos camelCase.
Ambos estándares son aceptables, pero como verias estandarizar en favor de "Lilium"
Si, coincido en estandarizar, pero en el proyecto ya lo venían haciendo así.
Consideré en hacer el cambio pero conllevaria también cambiar todos los namings de las traducciones de las secciones ya que aparentemente el
name
de la ruta se usa como título de la sección.