Compare commits
No commits in common. "dev" and "5122-multipleBasket" have entirely different histories.
dev
...
5122-multi
|
@ -1,6 +1,5 @@
|
|||
node_modules
|
||||
build/
|
||||
dist/
|
||||
config.my.php
|
||||
.vscode/
|
||||
.quasar
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Not using buster because of bug: https://bugs.php.net/bug.php?id=78870
|
||||
FROM debian:bookworm-slim
|
||||
FROM debian:stretch-slim
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
@ -23,13 +23,13 @@ RUN a2dissite 000-default
|
|||
|
||||
# NodeJs
|
||||
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs
|
||||
|
||||
# Hedera
|
||||
|
||||
RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | tee /etc/apt/trusted.gpg.d/verdnatura.gpg \
|
||||
&& echo "deb http://apt.verdnatura.es/ bookworm main" \
|
||||
RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
|
||||
&& echo "deb http://apt.verdnatura.es/ stretch main" \
|
||||
> /etc/apt/sources.list.d/vn.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
#!/usr/bin/env groovy
|
||||
|
||||
def BRANCH_ENV = [
|
||||
test: 'test',
|
||||
master: 'production'
|
||||
]
|
||||
def remote = [:]
|
||||
|
||||
node {
|
||||
stage('Setup') {
|
||||
env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev'
|
||||
|
||||
echo "NODE_NAME: ${env.NODE_NAME}"
|
||||
echo "WORKSPACE: ${env.WORKSPACE}"
|
||||
}
|
||||
}
|
||||
pipeline {
|
||||
agent any
|
||||
environment {
|
||||
PROJECT_NAME = 'hedera-web'
|
||||
STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}"
|
||||
}
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
script {
|
||||
def packageJson = readJSON file: 'package.json'
|
||||
env.VERSION = packageJson.version
|
||||
|
||||
switch (env.BRANCH_NAME) {
|
||||
case 'master':
|
||||
env.NODE_ENV = 'production'
|
||||
env.MAIN_REPLICAS = 3
|
||||
env.CRON_REPLICAS = 1
|
||||
break
|
||||
case 'test':
|
||||
env.NODE_ENV = 'test'
|
||||
env.MAIN_REPLICAS = 1
|
||||
env.CRON_REPLICAS = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
setEnv()
|
||||
}
|
||||
}
|
||||
stage('Debuild') {
|
||||
when {
|
||||
anyOf {
|
||||
|
@ -29,29 +38,32 @@ pipeline {
|
|||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'registry.verdnatura.es/verdnatura/debuild:2.23.4-vn7'
|
||||
image 'registry.verdnatura.es/debuild:2.21.3-vn2'
|
||||
registryUrl 'https://registry.verdnatura.es/'
|
||||
registryCredentialsId 'docker-registry'
|
||||
args '-v /mnt/appdata/reprepro:/reprepro'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'debuild -us -uc -b'
|
||||
sh 'mkdir -p debuild'
|
||||
sh 'mv ../hedera-web_* debuild'
|
||||
|
||||
script {
|
||||
def files = findFiles(glob: 'debuild/*.changes')
|
||||
files.each { file -> env.CHANGES_FILE = file.name }
|
||||
}
|
||||
|
||||
configFileProvider([
|
||||
configFile(fileId: "dput.cf", variable: 'DPUT_CONFIG')
|
||||
]) {
|
||||
sshagent(credentials: ['jenkins-agent']) {
|
||||
sh 'dput --config "$DPUT_CONFIG" verdnatura "debuild/$CHANGES_FILE"'
|
||||
}
|
||||
sh 'vn-includedeb stretch'
|
||||
}
|
||||
}
|
||||
stage('Container') {
|
||||
when {
|
||||
anyOf {
|
||||
branch 'master'
|
||||
branch 'test'
|
||||
}
|
||||
}
|
||||
environment {
|
||||
CREDS = credentials('docker-registry')
|
||||
}
|
||||
steps {
|
||||
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
||||
sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel'
|
||||
sh 'docker-compose push'
|
||||
}
|
||||
}
|
||||
stage('Deploy') {
|
||||
when {
|
||||
|
@ -61,41 +73,15 @@ pipeline {
|
|||
}
|
||||
}
|
||||
environment {
|
||||
CREDS = credentials('docker-registry')
|
||||
IMAGE = "$REGISTRY/verdnatura/hedera-web"
|
||||
DOCKER_HOST = "${env.SWARM_HOST}"
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
def packageJson = readJSON file: 'package.json'
|
||||
env.VERSION = "${packageJson.version}"
|
||||
env.TAG = "${packageJson.version}-build${env.BUILD_ID}"
|
||||
}
|
||||
|
||||
sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel'
|
||||
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
||||
sh 'docker push $IMAGE:$TAG'
|
||||
|
||||
script {
|
||||
if (env.BRANCH_NAME == 'master') {
|
||||
sh 'docker tag $IMAGE:$TAG $IMAGE:latest'
|
||||
sh 'docker push $IMAGE:latest'
|
||||
}
|
||||
}
|
||||
|
||||
withKubeConfig([
|
||||
serverUrl: "$KUBERNETES_API",
|
||||
credentialsId: 'kubernetes',
|
||||
namespace: 'salix'
|
||||
]) {
|
||||
sh 'kubectl set image deployment/hedera-web-$BRANCH_NAME hedera-web-$BRANCH_NAME=$IMAGE:$TAG'
|
||||
sh 'kubectl set image deployment/hedera-web-cron-$BRANCH_NAME hedera-web-cron-$BRANCH_NAME=$IMAGE:$TAG'
|
||||
}
|
||||
sh "docker stack deploy --with-registry-auth --compose-file docker-compose.yml ${env.STACK_NAME}"
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
unsuccessful {
|
||||
setEnv()
|
||||
sendEmail()
|
||||
}
|
||||
}
|
||||
|
|
47
README.md
47
README.md
|
@ -1,49 +1,18 @@
|
|||
# Hedera
|
||||
|
||||
Hedera is the main web shop page for Verdnatura.
|
||||
Hedera is the main web page for Verdnatura.
|
||||
|
||||
## Prerequisites
|
||||
## Getting Started
|
||||
|
||||
Required applications.
|
||||
* PHP >= 8.4
|
||||
* Node.js >= 20.0
|
||||
Required dependencies.
|
||||
* PHP >= 7.0
|
||||
* Node.js >= 8.0
|
||||
|
||||
Take a look to *debian/control* file to see additional dependencies.
|
||||
|
||||
Copy config.php to *config.my.php* and place your DB config there.
|
||||
|
||||
### Installing dependencies and launching
|
||||
|
||||
Pull from repository.
|
||||
|
||||
Run this commands on project root directory to install Node dependencies.
|
||||
Launch application for development.
|
||||
```
|
||||
$ npm install
|
||||
$ npm run dev
|
||||
```
|
||||
|
||||
Install project dependences (debian/control).
|
||||
|
||||
Pull from repository [php-vn-lib](https://gitea.verdnatura.es/verdnatura/php-vn-lib) and install [dependences](https://gitea.verdnatura.es/verdnatura/php-vn-lib/src/branch/master/debian/control) of this project.
|
||||
|
||||
Configure config.php file.
|
||||
|
||||
Launch project fronted.
|
||||
```
|
||||
$ npm run front
|
||||
```
|
||||
|
||||
Launch salix backend.
|
||||
```
|
||||
$ npm run db
|
||||
$ npm run back
|
||||
```
|
||||
Launch project backend.
|
||||
```
|
||||
$ php -S 127.0.0.1:3001 -t . index.php
|
||||
```
|
||||
|
||||
### Command line
|
||||
|
||||
Run server side method from command line.
|
||||
```
|
||||
$ php hedera-web.php -m method_path
|
||||
|
@ -51,8 +20,6 @@ $ php hedera-web.php -m method_path
|
|||
|
||||
## Built with
|
||||
|
||||
* [nodejs](https://nodejs.org/)
|
||||
* [php](https://www.php.net/)
|
||||
* [Webpack](https://webpack.js.org/)
|
||||
* [MooTools](https://mootools.net/)
|
||||
* [TinyMCE](https://www.tinymce.com/)
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
*
|
||||
* - http://www.mydomain.org -> config.www.php
|
||||
* - http://test.mydomain.org -> config.test.php
|
||||
*
|
||||
* Put the password in base64.
|
||||
*/
|
||||
return [
|
||||
/**
|
||||
|
@ -24,7 +22,7 @@ return [
|
|||
,'port' => 3306
|
||||
,'schema' => 'hedera'
|
||||
,'user' => 'hedera-web'
|
||||
,'pass' => '' // base64 encoded
|
||||
,'pass' => ''
|
||||
,'tz' => 'Europe/madrid'
|
||||
]
|
||||
];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
hedera-web (25.4.4) stable; urgency=low
|
||||
hedera-web (22.48.10) stable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ MAILTO=webmaster
|
|||
*/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
|
||||
0 5 * * * root hedera-web.php -m misc/exchange-rate
|
||||
0 0 * * * root hedera-web.php -m image/sync
|
||||
0 1 * * * root /usr/share/hedera-web/utils/image-clean.sh > /dev/null
|
||||
0 */1 * * * root /usr/share/hedera-web/utils/update-browscap.sh > /dev/null
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
usr/share/hedera-web/hedera-web.php usr/bin/hedera-web.php
|
||||
etc/hedera-web/apache.conf etc/apache2/conf-available/hedera-web.conf
|
||||
etc/hedera-web/php.ini etc/php/8.2/apache2/conf.d/99-hedera-web.ini
|
||||
etc/hedera-web/php.ini etc/php/7.0/apache2/conf.d/99-hedera-web.ini
|
|
@ -1,9 +1,41 @@
|
|||
version: '3.7'
|
||||
services:
|
||||
main:
|
||||
image: registry.verdnatura.es/verdnatura/hedera-web:${TAG:?}
|
||||
image: registry.verdnatura.es/hedera-web:${BRANCH_NAME:?}
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- VERSION=${VERSION:?}
|
||||
ports:
|
||||
- 80
|
||||
configs:
|
||||
- source: config
|
||||
target: /etc/hedera-web/config.my.php
|
||||
volumes:
|
||||
- /mnt/appdata:/mnt/storage
|
||||
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
||||
- /mnt/appdata/vn-access:/var/lib/hedera-web/vn-access
|
||||
deploy:
|
||||
replicas: ${MAIN_REPLICAS:?}
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == worker
|
||||
cron:
|
||||
image: registry.verdnatura.es/hedera-web:${BRANCH_NAME:?}
|
||||
command: 'cron -f'
|
||||
configs:
|
||||
- source: config
|
||||
target: /etc/hedera-web/config.my.php
|
||||
volumes:
|
||||
- /mnt/appdata:/mnt/storage
|
||||
- /mnt/appdata/image:/var/lib/hedera-web/image-db
|
||||
deploy:
|
||||
replicas: ${CRON_REPLICAS:?}
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == worker
|
||||
configs:
|
||||
config:
|
||||
external: true
|
||||
name: ${PROJECT_NAME:?}-${BRANCH_NAME:?}
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
one-way="true"
|
||||
one-time="true">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM vn.country
|
||||
ORDER BY name
|
||||
SELECT id, country FROM vn.country
|
||||
ORDER BY country
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,79 @@ export default new Class({
|
|||
activate() {
|
||||
this.$.userModel.setInfo('c', 'myClient', 'hedera');
|
||||
this.$.userModel.setInfo('u', 'myUser', 'account');
|
||||
this.$.changePassword.conn = this.conn
|
||||
this.$.changePassword.user = this.gui.user
|
||||
|
||||
if (this.hash.$.verificationToken)
|
||||
this.onPassChangeClick();
|
||||
}
|
||||
});
|
||||
|
||||
,onPassChangeClick() {
|
||||
this.$.oldPassword.value = '';
|
||||
this.$.newPassword.value = '';
|
||||
this.$.repeatPassword.value = '';
|
||||
|
||||
var verificationToken = this.hash.$.verificationToken;
|
||||
this.$.oldPassword.style.display = verificationToken ? 'none' : 'block';
|
||||
this.$.changePassword.show();
|
||||
|
||||
if (verificationToken)
|
||||
this.$.newPassword.focus();
|
||||
else
|
||||
this.$.oldPassword.focus();
|
||||
}
|
||||
|
||||
,async onPassModifyClick() {
|
||||
const form = this.$.changePassword.node;
|
||||
Vn.Node.disableInputs(form);
|
||||
try {
|
||||
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);
|
||||
}
|
||||
|
||||
const verificationToken = this.hash.$.verificationToken;
|
||||
const params = {newPassword};
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Htk.Toast.showMessage(_('Password changed!'));
|
||||
}
|
||||
|
||||
,onPassInfoClick() {
|
||||
this.$.passwordInfo.show();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<vn>
|
||||
<vn-group>
|
||||
<db-form v-model="passwordForm">
|
||||
<db-model property="model">
|
||||
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
||||
FROM account.userPassword
|
||||
</db-model>
|
||||
</db-form>
|
||||
<db-form id="user-form">
|
||||
<db-model property="model" id="user-model" updatable="true">
|
||||
SELECT u.id, u.name, u.email, u.nickname,
|
||||
|
@ -21,7 +27,7 @@
|
|||
<htk-bar-button
|
||||
icon="lock_reset"
|
||||
tip="_Change password"
|
||||
on-click="this.$.changePassword.open()"/>
|
||||
on-click="this.onPassChangeClick()"/>
|
||||
</div>
|
||||
<div id="form" class="conf">
|
||||
<div class="form box vn-w-sm vn-pa-lg">
|
||||
|
@ -68,5 +74,64 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<htk-change-password id="change-password"/>
|
||||
<htk-popup
|
||||
id="change-password"
|
||||
modal="true">
|
||||
<div property="child-node" class="htk-dialog vn-w-xs vn-pa-lg">
|
||||
<div class="form">
|
||||
<h5 class="vn-mb-md">
|
||||
<t>Change password</t>
|
||||
</h5>
|
||||
<input
|
||||
id="old-password"
|
||||
type="password"
|
||||
placeholder="_Old password"/>
|
||||
<input
|
||||
id="new-password"
|
||||
type="password"
|
||||
placeholder="_New password"
|
||||
autocomplete="new-password"/>
|
||||
<input
|
||||
id="repeat-password"
|
||||
type="password"
|
||||
placeholder="_Repeat password"
|
||||
autocomplete="new-password"/>
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<button class="thin" on-click="this.onPassModifyClick()">
|
||||
<t>Modify</t>
|
||||
</button>
|
||||
<button class="thin" on-click="this.onPassInfoClick()">
|
||||
<t>Requirements</t>
|
||||
</button>
|
||||
<div class="clear"/>
|
||||
</div>
|
||||
</div>
|
||||
</htk-popup>
|
||||
<htk-popup
|
||||
id="password-info"
|
||||
modal="true">
|
||||
<div property="child-node" class="htk-dialog pass-info vn-w-xs vn-pa-lg">
|
||||
<h5 class="vn-mb-md">
|
||||
<t>Password requirements</t>
|
||||
</h5>
|
||||
<ul>
|
||||
<li>
|
||||
{{passwordForm.length}} <t>characters long</t>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordForm.nAlpha}} <t>alphabetic characters</t>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordForm.nUpper}} <t>capital letters</t>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordForm.nDigits}} <t>digits</t>
|
||||
</li>
|
||||
<li>
|
||||
{{passwordForm.nPunct}} <t>symbols</t>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</htk-popup>
|
||||
</vn>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
LEFT JOIN image im
|
||||
ON im.collectionFk = 'catalog'
|
||||
AND im.name = i.image
|
||||
WHERE i.isActive
|
||||
AND (i.longName LIKE CONCAT('%', #search, '%') OR i.id = #search)
|
||||
WHERE i.longName LIKE CONCAT('%', #search, '%')
|
||||
OR i.id = #search
|
||||
ORDER BY i.longName LIMIT 50
|
||||
</db-model>
|
||||
<custom>
|
||||
|
|
|
@ -7,8 +7,8 @@ export default new Class({
|
|||
,activate() {
|
||||
if (!this.hash.$.to)
|
||||
this.hash.assign({
|
||||
from: Date.vnNew(),
|
||||
to: Date.vnNew()
|
||||
from: new Date(),
|
||||
to: new Date()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,5 +3,12 @@ import './style.scss';
|
|||
export default new Class({
|
||||
Extends: Hedera.Form,
|
||||
Template: require('./ui.xml'),
|
||||
|
||||
onShowClick(column, agencyId) {
|
||||
this.hash.setAll({
|
||||
form: 'agencies/provinces',
|
||||
agency: agencyId
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ListByAgency: Paquets per agència
|
||||
ShowByProvince: Mostrar desglose per província
|
||||
Agency: Agència
|
||||
Exps: Exps.
|
||||
Bundles: Paquets
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ListByAgency: Bundles by agency
|
||||
ShowByProvince: Show breakdown by province
|
||||
Agency: Agency
|
||||
Exps: Exps.
|
||||
Bundles: Bundles
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ListByAgency: Bultos por agencia
|
||||
ShowByProvince: Mostrar desglose por provincia
|
||||
Agency: Agencia
|
||||
Exps: Exps.
|
||||
Bundles: Bultos
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ListByAgency: Liste par agence
|
||||
ShowByProvince: Montrer par province
|
||||
Agency: Agence
|
||||
Exps: Expéditeur
|
||||
Bundles: Cartons
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ListByAgency: Bultos por agencia
|
||||
ShowByProvince: Mostrar desglosse por Distrito
|
||||
Agency: Agencia
|
||||
Exps: Exps.
|
||||
Bundles: Bultos
|
||||
|
|
|
@ -7,9 +7,14 @@
|
|||
<htk-grid>
|
||||
<db-model property="model">
|
||||
<custom>
|
||||
CALL vn.agencyVolume()
|
||||
CALL vn2008.agencia_volume ()
|
||||
</custom>
|
||||
</db-model>
|
||||
<htk-column-button
|
||||
column="agency_id"
|
||||
icon="search"
|
||||
tip="_ShowByProvince"
|
||||
on-clicked="onShowClick"/>
|
||||
<htk-column-text title="_Agency" column="Agencia"/>
|
||||
<htk-column-spin title="_Exps" column="expediciones"/>
|
||||
<htk-column-spin title="_Bundles" column="Bultos"/>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import './style.scss';
|
||||
|
||||
export default new Class({
|
||||
Extends: Hedera.Form,
|
||||
Template: require('./ui.xml')
|
||||
});
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
ByProvince: Desglose per província
|
||||
Return: Tornar
|
||||
SelectAgency: Selecciona una agència al llistat de l'esquerra
|
||||
Province: Província
|
||||
Expeditions: Exps.
|
||||
Left: Falten
|
|
@ -0,0 +1,6 @@
|
|||
ByProvince: Breakdown by province
|
||||
Return: Return
|
||||
SelectAgency: Select an agency
|
||||
Province: Province
|
||||
Expeditions: Exps.
|
||||
Left: Left
|
|
@ -0,0 +1,6 @@
|
|||
ByProvince: Desglose por provincia
|
||||
Return: Volver
|
||||
SelectAgency: Selecciona una agencia
|
||||
Province: Provincia
|
||||
Expeditions: Exps.
|
||||
Left: Faltan
|
|
@ -0,0 +1,6 @@
|
|||
ByProvince: Par province
|
||||
Return: Retour
|
||||
SelectAgency: Sélectionnez une agence
|
||||
Province: Province
|
||||
Expeditions: Expéditions
|
||||
Left: Restant
|
|
@ -0,0 +1,6 @@
|
|||
ByProvince: Desglosse por Distritos
|
||||
Return: Voltar
|
||||
SelectAgency: Seleccione uma agência
|
||||
Province: Distrito
|
||||
Expeditions: Exps.
|
||||
Left: Faltam
|
|
@ -0,0 +1,18 @@
|
|||
<vn>
|
||||
<div id="title">
|
||||
<h1><t>ByProvince</t></h1>
|
||||
</div>
|
||||
<div id="form" class="provinces vn-w-sm">
|
||||
<div class="box">
|
||||
<htk-grid>
|
||||
<db-model property="model" lot="hash">
|
||||
CALL vn2008.desglose_volume(#agency)
|
||||
</db-model>
|
||||
<htk-column-text title="_Province" column="Provincia"/>
|
||||
<htk-column-spin title="_Expeditions" column="expediciones"/>
|
||||
<htk-column-spin title="_Bundles" column="Bultos"/>
|
||||
<htk-column-spin title="_Left" column="Prevision"/>
|
||||
</htk-grid>
|
||||
</div>
|
||||
</div>
|
||||
</vn>
|
|
@ -14,7 +14,7 @@ export default new Class({
|
|||
,refreshCaptcha() {
|
||||
params = {
|
||||
srv: 'rest:misc/captcha',
|
||||
stamp: Date.vnNew().getTime()
|
||||
stamp: new Date().getTime()
|
||||
};
|
||||
this.$.captchaImg.src = '?'+ Vn.Url.makeUri(params);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,7 @@ BecauseOurSalesDep: >-
|
|||
Pour nos professionnels de service commercial qui sera toujours de trouver une
|
||||
solution à vos besoins.
|
||||
BecauseOurWorkShop: Parce que nous avons un atelier de couture pour aider.
|
||||
BecauseWeHaveWhatYouNeed: >-
|
||||
Parce que nous avons ce que vous avez besoin quand vous en avez besoin ...
|
||||
BecauseWeHaveWhatYouNeed: Parce que nous avons ce que vous avez besoin quand vous en avez besoin ...
|
||||
AboutDesc: >-
|
||||
Nous sommes une société spécialisée dans le commerce de gros et de la
|
||||
distribution d'une large gamme d'accessoires, des verts et des fleurs à des
|
||||
|
@ -32,6 +31,6 @@ AboutDisp: >-
|
|||
Mercaflor - Mercavalencia (Valencia) qui effectuent des ventes directes
|
||||
seulement.
|
||||
AboutOrder: >-
|
||||
Vous pouvez faire vos commandes et réservations par téléphone au +33 783 285
|
||||
437, en ligne grâce à notre site Internet ou directement dans nos
|
||||
Vous pouvez faire vos commandes et réservations par téléphone au +33 781 533
|
||||
900, en ligne grâce à notre site Internet ou directement dans nos
|
||||
installations.
|
||||
|
|
|
@ -5,46 +5,20 @@ export default new Class({
|
|||
Template: require('./ui.xml'),
|
||||
|
||||
async open() {
|
||||
await this.loadOrder();
|
||||
if (this.orderId) {
|
||||
await Hedera.Form.prototype.open.call(this);
|
||||
this.$.lot.assign({id: this.orderId});
|
||||
}
|
||||
},
|
||||
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', 'myOrderRow', 'hedera');
|
||||
},
|
||||
|
||||
async onHashChange() {
|
||||
if (!this.isOpen) return;
|
||||
await this.loadOrder();
|
||||
if (this.orderId)
|
||||
this.$.lot.assign({id: this.orderId});
|
||||
},
|
||||
|
||||
async loadOrder() {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
if (this.hash.$.id) {
|
||||
this.orderId = this.hash.$.id;
|
||||
} else if (await basket.check()) {
|
||||
this.orderId = basket.orderId;
|
||||
}
|
||||
},
|
||||
|
||||
onOrderReady(form) {
|
||||
if (form.row < 0)
|
||||
return;
|
||||
|
||||
if (form.$.method != 'PICKUP') {
|
||||
Vn.Node.show(this.$.address);
|
||||
Vn.Node.setText(this.$.method, _('Agency'));
|
||||
} else {
|
||||
Vn.Node.hide(this.$.address);
|
||||
Vn.Node.setText(this.$.method, _('Warehouse'));
|
||||
}
|
||||
},
|
||||
|
||||
onConfigureClick() {
|
||||
Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
|
||||
this.hash.setAll({
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
ShoppingBasket: Cistella de la compra
|
||||
Order: Encàrrec
|
||||
ShippingInformation: Dades d'enviament
|
||||
DeliveryAddress: Adreça de lliurament
|
||||
Delivery at: Lliurament el
|
||||
Agency: Agència
|
||||
Warehouse: Magatzem
|
||||
Delete: Borrar encàrrec
|
||||
GoToCatalog: Anar al catàleg
|
||||
ConfigureOrder: Configurar encàrrec
|
||||
Checkout: Tramitar encàrrec
|
||||
OrderNumber: N encàrec
|
||||
DateExit: Data d'eixida
|
||||
Warehouse: Magatzem
|
||||
OrderTotal: Total encàrrec
|
||||
Amount: Quant
|
||||
Pack: Pack
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
ShoppingBasket: Shopping basket
|
||||
Order: Order
|
||||
ShippingInformation: Shipping information
|
||||
DeliveryAddress: Delivery address
|
||||
Delivery at: Delivery at
|
||||
Agency: Agency
|
||||
Warehouse: Store
|
||||
Delete: Delete order
|
||||
GoToCatalog: Go to catalog
|
||||
ConfigureOrder: Configure order
|
||||
Checkout: Checkout
|
||||
OrderNumber: Order number
|
||||
DateExit: Shipping date
|
||||
Warehouse: Store
|
||||
OrderTotal: Total
|
||||
Amount: Amount
|
||||
Pack: Pack
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
ShoppingBasket: Cesta de la compra
|
||||
Order: Pedido
|
||||
ShippingInformation: Datos de envío
|
||||
DeliveryAddress: Dirección de entrega
|
||||
Delivery at: Entrega el
|
||||
Agency: Agencia
|
||||
Warehouse: Almacén
|
||||
Delete: Borrar pedido
|
||||
GoToCatalog: Ir al catálogo
|
||||
ConfigureOrder: Configurar pedido
|
||||
Checkout: Finalizar pedido
|
||||
OrderNumber: Nº pedido
|
||||
DateExit: Fecha de salida
|
||||
Warehouse: Almacén
|
||||
OrderTotal: Total
|
||||
Amount: Cantidad
|
||||
Pack: Pack
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
ShoppingBasket: Panier
|
||||
Order: Commande
|
||||
ShippingInformation: Informations sur la livraison
|
||||
DeliveryAddress: Addresse de livraison
|
||||
Delivery at: Livraison à
|
||||
Agency: Agence
|
||||
Warehouse: Entrepôt
|
||||
Delete: Effacer
|
||||
GoToCatalog: Aller au catalogue
|
||||
ConfigureOrder: Définissez l'ordre
|
||||
Checkout: Caisse
|
||||
OrderNumber: Numéro de commande
|
||||
DateExit: Date de sortie
|
||||
Warehouse: Magasin
|
||||
OrderTotal: Total commande
|
||||
Amount: Quant
|
||||
Pack: Pack
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
ShoppingBasket: Cesta da compra
|
||||
Order: Encomenda
|
||||
ShippingInformation: Dados de envio
|
||||
DeliveryAddress: Endereço de entrega
|
||||
Delivery at: Entrega na
|
||||
Agency: Agência
|
||||
Warehouse: Armazém
|
||||
Delete: Eliminar encomenda
|
||||
GoToCatalog: Ir ao catálogo
|
||||
ConfigureOrder: Configurar encomenda
|
||||
Checkout: Finalizar encomenda
|
||||
OrderNumber: Nº encomenda
|
||||
DateExit: Data de saída
|
||||
Warehouse: Armazém
|
||||
OrderTotal: Total
|
||||
Amount: Quantidade
|
||||
Pack: Pack
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="id" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<div id="title">
|
||||
<h1>{{_(params.$.id ? 'Order' : 'ShoppingBasket')}}</h1>
|
||||
</div>
|
||||
|
@ -8,7 +11,7 @@
|
|||
tip="_ConfigureOrder"
|
||||
on-click="this.onConfigureClick()"/>
|
||||
<htk-bar-button
|
||||
icon="shopping_bag"
|
||||
icon="local_florist"
|
||||
tip="_Catalog"
|
||||
on-click="this.onCatalogClick()"/>
|
||||
<htk-bar-button
|
||||
|
@ -17,18 +20,14 @@
|
|||
on-click="this.onConfirmClick()"/>
|
||||
</div>
|
||||
<vn-group>
|
||||
<vn-lot-query id="params" on-change="this.onHashChange()">
|
||||
<vn-spec name="id" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<vn-lot id="lot"/>
|
||||
<db-form v-model="order" on-ready="onOrderReady">
|
||||
<db-form v-model="order">
|
||||
<db-model property="model" lot="lot">
|
||||
SELECT o.id, o.sent,
|
||||
ag.description agency, v.code method,
|
||||
ad.nickname, ad.postalCode, ad.city, ad.street
|
||||
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.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>
|
||||
|
@ -38,20 +37,12 @@
|
|||
<div class="box vn-w-sm vn-pa-lg">
|
||||
<div class="head vn-pb-lg">
|
||||
<h5>#{{order.id}}</h5>
|
||||
<div class="delivery">
|
||||
<div class="vn-mt-md">
|
||||
<h6><t>ShippingInformation</t></h6>
|
||||
<p>{{order.nickname}}</p>
|
||||
<p>
|
||||
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
||||
</p>
|
||||
<p>
|
||||
<span id="method"><t>Agency</t></span> {{order.agency}}
|
||||
</p>
|
||||
</div>
|
||||
<div id="address" class="address vn-mt-md">
|
||||
<h6><t>DeliveryAddress</t></h6>
|
||||
<p>{{order.street}}</p>
|
||||
<p>{{order.postalCode}}, {{order.city}}</p>
|
||||
<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>
|
||||
|
|
|
@ -7,11 +7,15 @@ const Catalog = new Class({
|
|||
,_menuShown: false
|
||||
|
||||
,async open() {
|
||||
let isOk = true;
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
this.orderId = basket.orderId;
|
||||
|
||||
if (!localStorage.getItem('hederaGuest')) {
|
||||
if (await basket.check('catalog'))
|
||||
this.orderId = basket.orderId;
|
||||
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;');
|
||||
|
@ -20,8 +24,7 @@ const Catalog = new Class({
|
|||
this.orderId = resultSet.fetchValue();
|
||||
}
|
||||
|
||||
if (this.orderId)
|
||||
await Hedera.Form.prototype.open.call(this);
|
||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
||||
}
|
||||
|
||||
,activate() {
|
||||
|
@ -202,12 +205,6 @@ const Catalog = new Class({
|
|||
|
||||
this.hideMenu();
|
||||
}
|
||||
|
||||
,itemRenderer(builder, form) {
|
||||
var minQuantity = builder.$.minQuantity;
|
||||
minQuantity.style.display = form.$.minQuantity
|
||||
? 'block' : 'hidden';
|
||||
}
|
||||
|
||||
,realmRenderer(builder, form) {
|
||||
var link = builder.$.link;
|
||||
|
@ -279,8 +276,6 @@ const Catalog = new Class({
|
|||
orderId: this.orderId
|
||||
});
|
||||
this.$.cardPopup.show(event.currentTarget);
|
||||
this.$.cardMinQuantity.style.display = form.$.minQuantity
|
||||
? 'block' : 'none';
|
||||
}
|
||||
|
||||
,onAddLotClick(column, value, row) {
|
||||
|
@ -325,7 +320,7 @@ const Catalog = new Class({
|
|||
}
|
||||
|
||||
if (amountSum > 0) {
|
||||
await this.conn.execQuery(sql);
|
||||
this.conn.execQuery(sql);
|
||||
|
||||
var itemName = this.$.$card.get('item');
|
||||
Htk.Toast.showMessage(
|
||||
|
|
|
@ -46,4 +46,3 @@ NoMoreAmountAvailable: No hi ha més quantitat disponible
|
|||
MinimalGrouping: Empaquetat mínim
|
||||
Available: Disponible
|
||||
GroupingPrice: Preu per grup
|
||||
MinimalQuantity: Quantitat mínima
|
||||
|
|
|
@ -46,4 +46,3 @@ NoMoreAmountAvailable: No more amount available
|
|||
MinimalGrouping: Minimal packing
|
||||
Available: Available
|
||||
GroupingPrice: Price per group
|
||||
MinimalQuantity: Minimal quantity
|
||||
|
|
|
@ -46,4 +46,3 @@ NoMoreAmountAvailable: No hay más cantidad disponible
|
|||
MinimalGrouping: Empaquetado mínimo
|
||||
Available: Disponible
|
||||
GroupingPrice: Precio per grupo
|
||||
MinimalQuantity: Cantidad mínima
|
||||
|
|
|
@ -46,4 +46,3 @@ NoMoreAmountAvailable: Pas plus disponible
|
|||
MinimalGrouping: Emballage minimal
|
||||
Available: Disponible
|
||||
GroupingPrice: Prix par groupe
|
||||
MinimalQuantity: Quantité minimum
|
||||
|
|
|
@ -46,4 +46,3 @@ NoMoreAmountAvailable: Não há mais quantidade disponível
|
|||
MinimalGrouping: Embalagem mínima
|
||||
Available: Disponível
|
||||
GroupingPrice: Preço por grupo
|
||||
MinimalQuantity: Quantidade mínima
|
||||
|
|
|
@ -192,25 +192,6 @@
|
|||
margin: 0;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
& > .min-quantity {
|
||||
bottom: 32px;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.min-quantity {
|
||||
position: absolute;
|
||||
display: none;
|
||||
bottom: 30px;
|
||||
right: 0;
|
||||
font-size: .8rem;
|
||||
color: #a44;
|
||||
cursor: pointer;
|
||||
|
||||
& > span {
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
|
@ -275,7 +256,7 @@
|
|||
}
|
||||
& > .htk-image {
|
||||
width: 100%;
|
||||
height: 210px;
|
||||
height: 180px;
|
||||
|
||||
& > img {
|
||||
height: initial;
|
||||
|
@ -285,7 +266,7 @@
|
|||
flex: auto;
|
||||
overflow: hidden;
|
||||
margin: 10px;
|
||||
height: 185px;
|
||||
height: 170px;
|
||||
|
||||
& > h2 {
|
||||
max-height: 3rem;
|
||||
|
@ -370,7 +351,6 @@
|
|||
|
||||
& > .top {
|
||||
padding: 14px;
|
||||
position: relative;
|
||||
|
||||
& > .item-info {
|
||||
margin-left: 126px;
|
||||
|
@ -391,11 +371,6 @@
|
|||
margin-top: 15px 0;
|
||||
font-size: .9rem;
|
||||
}
|
||||
& > .min-quantity {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 14px;
|
||||
}
|
||||
}
|
||||
& > .lots-grid {
|
||||
border-top: 1px solid #DDD;
|
||||
|
|
|
@ -94,9 +94,10 @@
|
|||
<vn-lot id="order-lot"/>
|
||||
<db-form v-model="basket">
|
||||
<db-model property="model" lot="order-lot">
|
||||
SELECT o.id, o.sent, ad.nickname
|
||||
SELECT o.id, o.sent, a.description agency, m.code method
|
||||
FROM myOrder o
|
||||
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||
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>
|
||||
|
@ -115,9 +116,8 @@
|
|||
WHERE #filter;
|
||||
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.tag8, i.value8,
|
||||
i.relevancy, i.size, i.category, b.minQuantity,
|
||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
||||
i.relevancy, i.size, i.category,
|
||||
k.name ink, p.name producer, o.name origin,
|
||||
b.available, b.price, b.`grouping`,
|
||||
i.image, im.updated
|
||||
|
@ -126,13 +126,19 @@
|
|||
LEFT JOIN vn.ink k ON k.id = i.inkFk
|
||||
LEFT JOIN vn.producer p ON p.id = i.producerFk
|
||||
LEFT JOIN vn.origin o ON o.id = i.originFk
|
||||
LEFT JOIN image im ON im.collectionFk = 'catalog'
|
||||
LEFT JOIN image im
|
||||
ON im.collectionFk = 'catalog'
|
||||
AND im.name = i.image
|
||||
WHERE b.available > 0
|
||||
ORDER BY i.relevancy DESC, i.name, i.size
|
||||
LIMIT 5000;
|
||||
DROP TEMPORARY TABLE tmp.item;
|
||||
CALL vn.ticketCalculatePurge();
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.item,
|
||||
tmp.ticketCalculateItem,
|
||||
tmp.ticketComponentPrice,
|
||||
tmp.ticketComponent,
|
||||
tmp.ticketLot,
|
||||
tmp.zoneGetShipped;
|
||||
</db-model>
|
||||
<db-form id="$card" v-model="card" model="items"/>
|
||||
<vn-lot id="card-lot"/>
|
||||
|
@ -143,8 +149,7 @@
|
|||
id="grid-view"
|
||||
empty-message="_Choose filter from right menu"
|
||||
form-id="item"
|
||||
model="items"
|
||||
renderer="itemRenderer">
|
||||
model="items">
|
||||
<custom>
|
||||
<div
|
||||
id="item-box"
|
||||
|
@ -182,10 +187,6 @@
|
|||
<td>{{item.tag7}}</td>
|
||||
<td>{{item.value7}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{item.tag8}}</td>
|
||||
<td>{{item.value8}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="available-price">
|
||||
<span class="grouping" title="_MinimalGrouping">
|
||||
|
@ -198,12 +199,6 @@
|
|||
{{Vn.Value.format(item.price, '%.02d€')}}
|
||||
</span>
|
||||
</div>
|
||||
<div id="min-quantity" class="min-quantity" title="_MinimalQuantity">
|
||||
<span class="htk-icon material-symbols-rounded">
|
||||
production_quantity_limits
|
||||
</span>
|
||||
{{item.minQuantity}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</custom>
|
||||
|
@ -212,8 +207,11 @@
|
|||
</div>
|
||||
<div id="right-panel" class="catalog-panel right-panel side-panel" on-click="onRightPanelClick">
|
||||
<div class="basket-info">
|
||||
<p>{{basket.nickname}}</p>
|
||||
<p>{{Vn.Value.format(basket.sent, '%D')}}</p>
|
||||
<p>
|
||||
{{_(basket.method != 'PICKUP' ? 'Agency' : 'Warehouse')}}
|
||||
{{basket.agency}}
|
||||
</p>
|
||||
<button class="thin" on-click="this.onConfigureClick()">
|
||||
<t>Modify</t>
|
||||
</button>
|
||||
|
@ -462,12 +460,6 @@
|
|||
</tr>
|
||||
</custom>
|
||||
</htk-repeater>
|
||||
<div id="card-min-quantity" class="min-quantity" title="_MinimalQuantity">
|
||||
<span class="htk-icon material-symbols-rounded">
|
||||
production_quantity_limits
|
||||
</span>
|
||||
{{card.minQuantity}}
|
||||
</div>
|
||||
</div>
|
||||
<htk-grid class="lots-grid" show-header="false">
|
||||
<db-model
|
||||
|
|
|
@ -8,7 +8,7 @@ export default new Class({
|
|||
this.autoStepLocked = true;
|
||||
this.$.assistant.stepsIndex = this.agencySteps;
|
||||
|
||||
this.today = Date.vnNew();
|
||||
this.today = new Date();
|
||||
this.today.setHours(0, 0, 0, 0);
|
||||
},
|
||||
|
||||
|
@ -22,8 +22,8 @@ export default new Class({
|
|||
let date;
|
||||
const row = orderForm.$ || defaultsForm.$ || {};
|
||||
|
||||
if (!date || date.getTime() < (Date.vnNew()).getTime()) {
|
||||
date = Date.vnNew();
|
||||
if (!date || date.getTime() < (new Date()).getTime()) {
|
||||
date = new Date();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
let addDays = 0;
|
||||
|
@ -81,27 +81,21 @@ export default new Class({
|
|||
if (!resultSet.fetchResult())
|
||||
return;
|
||||
|
||||
let redirect;
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
|
||||
if (id) {
|
||||
Htk.Toast.showMessage(_('OrderUpdated'));
|
||||
|
||||
switch(this.hash.$.continue) {
|
||||
case 'catalog':
|
||||
redirect = {form: 'ecomerce/catalog'};
|
||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
||||
break;
|
||||
default:
|
||||
redirect = {form: 'ecomerce/basket'};
|
||||
if (id !== basket.orderId)
|
||||
redirect.id = id;
|
||||
this.hash.setAll({form: 'ecomerce/basket', id});
|
||||
}
|
||||
} else {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
basket.loadIntoBasket(resultSet.fetchValue());
|
||||
redirect = {form: 'ecomerce/catalog'};
|
||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
||||
}
|
||||
|
||||
this.hash.setAll(redirect);
|
||||
},
|
||||
|
||||
onCancelClick() {
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
form-id="iter"
|
||||
on-change="onAddressChange">
|
||||
<db-model property="model" id="addresses">
|
||||
SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.name
|
||||
SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.country
|
||||
FROM myAddress a
|
||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||
JOIN vn.country c ON c.id = p.countryFk
|
||||
|
|
|
@ -7,7 +7,7 @@ export default new Class({
|
|||
async open() {
|
||||
const basket = new Hedera.Basket(this.app);
|
||||
try {
|
||||
await basket.checkOrder(this.hash.$.id);
|
||||
await basket.check(this.hash.$.id);
|
||||
} catch (err) {
|
||||
Htk.Toast.showError(err.message);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export default new Class({
|
|||
methods = ['balance'];
|
||||
selectedMethod = 'BALANCE';
|
||||
} else {
|
||||
methods = ['card'];
|
||||
methods = ['card', 'transfer', 'later'];
|
||||
|
||||
if (!creditExceededCond) {
|
||||
methods.push('credit');
|
||||
|
@ -98,6 +98,9 @@ export default new Class({
|
|||
case 'CARD':
|
||||
id = 'cardMethod';
|
||||
break;
|
||||
case 'TRANSFER':
|
||||
id = 'transferMethod';
|
||||
break;
|
||||
default:
|
||||
id = null;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
<db-form v-model="order" on-ready="onOrderReady">
|
||||
<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,
|
||||
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 myOrder o
|
||||
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
||||
|
@ -35,10 +35,8 @@
|
|||
<div class="vn-w-sm">
|
||||
<div class="box vn-pa-lg summary">
|
||||
<div>
|
||||
<h5>#{{order.id}}</h5>
|
||||
<div class="delivery">
|
||||
<h6><t>ShippingInformation</t></h6>
|
||||
<p>{{order.nickname}}</p>
|
||||
<p>
|
||||
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
||||
</p>
|
||||
|
@ -48,6 +46,7 @@
|
|||
</div>
|
||||
<div id="address" class="address vn-mt-md">
|
||||
<h6><t>DeliveryAddress</t></h6>
|
||||
<p>{{order.nickname}}</p>
|
||||
<p>{{order.street}}</p>
|
||||
<p>{{order.postalCode}}, {{order.city}}</p>
|
||||
</div>
|
||||
|
@ -162,6 +161,32 @@
|
|||
<t>You will be redirected to the payment.</t>
|
||||
</div>
|
||||
</div>
|
||||
<div id="transfer-method">
|
||||
<label>
|
||||
<htk-radio radio-group="pay-method" value="TRANSFER"/>
|
||||
<t>Bank Transfer</t>
|
||||
</label>
|
||||
<div>
|
||||
<t>Make a transfer to one account.</t>
|
||||
<htk-repeater form-id="iter">
|
||||
<db-model property="model">
|
||||
SELECT name, iban FROM mainAccountBank
|
||||
</db-model>
|
||||
<custom>
|
||||
<div class="transfer-account">
|
||||
<p>{{iter.name}}</p>
|
||||
<p>{{iter.iban}}</p>
|
||||
</div>
|
||||
</custom>
|
||||
</htk-repeater>
|
||||
</div>
|
||||
</div>
|
||||
<div id="later-method">
|
||||
<label>
|
||||
<htk-radio radio-group="pay-method" value="LATER"/>
|
||||
<t>Pay later</t>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="button-bar vn-mt-md">
|
||||
|
|
|
@ -3,17 +3,30 @@ import './style.scss';
|
|||
export default new Class({
|
||||
Extends: Hedera.Form,
|
||||
Template: require('./ui.xml'),
|
||||
|
||||
donwloadRenderer(column, invoice) {
|
||||
var invoiceId = invoice.$.id;
|
||||
|
||||
onDownloadClick(column, value, row) {
|
||||
var model = this.$.invoices;
|
||||
var hasPdf = model.get(row, 'hasPdf');
|
||||
var id = model.get(row, 'id');
|
||||
if (invoice.$.hasPdf && invoiceId) {
|
||||
var params = {
|
||||
srv: 'rest:dms/invoice',
|
||||
invoice: invoiceId,
|
||||
access_token: this.conn.token
|
||||
};
|
||||
|
||||
if (hasPdf && id) {
|
||||
let params = Vn.Url.makeUri({ access_token: this.conn.token });
|
||||
window.open(`/api/InvoiceOuts/${id}/download?${params}`);
|
||||
Object.assign(column, {
|
||||
tip: _('Download PDF'),
|
||||
disabled: false,
|
||||
icon: 'download',
|
||||
href: '?'+ Vn.Url.makeUri(params)
|
||||
});
|
||||
} else
|
||||
Htk.Toast.showWarning(_('Request the invoice to your salesperson'));
|
||||
Object.assign(column, {
|
||||
tip: _('Request the invoice to your salesperson'),
|
||||
disabled: true,
|
||||
icon: 'warning',
|
||||
href: null
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<htk-grid
|
||||
class="box vn-w-sm"
|
||||
show-header="false">
|
||||
<db-model property="model" id="invoices">
|
||||
<db-model property="model" id="tickets">
|
||||
SELECT id, ref, issued, amount, hasPdf
|
||||
FROM myInvoice
|
||||
ORDER BY issued DESC
|
||||
|
@ -16,9 +16,8 @@
|
|||
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
|
||||
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
|
||||
<htk-column-button
|
||||
icon="download"
|
||||
tip="_Download PDF"
|
||||
on-clicked="onDownloadClick"/>
|
||||
renderer="donwloadRenderer"
|
||||
target="_blank"/>
|
||||
</htk-grid>
|
||||
</div>
|
||||
</vn>
|
||||
|
|
|
@ -1,8 +1 @@
|
|||
Pending: Pendents
|
||||
PendingOrders: Comandes pendents
|
||||
NewOrder: Nova comanda
|
||||
ViewOrder: Veure comanda
|
||||
RemoveOrder: Eliminar comanda
|
||||
LoadOrderIntoCart: Carregar comanda a la cistella
|
||||
AreYouSureDeleteOrder: Segur que vols esborrar la comanda?
|
||||
OrderLoadedIntoBasket: Comanda carregada a la cistella!
|
||||
|
|
|
@ -1,8 +1 @@
|
|||
Pending: Pending
|
||||
PendingOrders: Pending orders
|
||||
NewOrder: New order
|
||||
ViewOrder: View order
|
||||
RemoveOrder: Delete order
|
||||
LoadOrderIntoCart: Load order into cart
|
||||
AreYouSureDeleteOrder: Are you sure you want to delete the order?
|
||||
OrderLoadedIntoBasket: Order loaded into basket!
|
||||
|
|
|
@ -5,4 +5,4 @@ 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!
|
||||
OrderLoadedIntoBasket: ¡Pedido cargado en la cesta!
|
|
@ -1,8 +1 @@
|
|||
Pending: En attente
|
||||
PendingOrders: Commandes en attente
|
||||
NewOrder: Nouvelle commande
|
||||
ViewOrder: Afficher la commande
|
||||
RemoveOrder: Supprimer la commande
|
||||
LoadOrderIntoCart: Charger la commande dans le panier
|
||||
AreYouSureDeleteOrder: Êtes-vous sûr de vouloir supprimer la commande?
|
||||
OrderLoadedIntoBasket: Commande chargée dans le panier!
|
||||
Pending: Pendents
|
||||
|
|
|
@ -1,8 +1 @@
|
|||
Pending: Pendentes
|
||||
PendingOrders: Pedidos pendentes
|
||||
NewOrder: Novo pedido
|
||||
ViewOrder: Ver pedido
|
||||
RemoveOrder: Excluir pedido
|
||||
LoadOrderIntoCart: Carrega o pedido no carrinho
|
||||
AreYouSureDeleteOrder: Tem certeza de que deseja excluir o pedido?
|
||||
OrderLoadedIntoBasket: Pedido carregado na cesta!
|
||||
Pending: Pendientes
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
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.taxableBase,
|
||||
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
|
||||
|
@ -33,7 +33,7 @@
|
|||
<p>#{{iter.id}}</p>
|
||||
<p>{{iter.nickname}}</p>
|
||||
<p>{{iter.agency}}</p>
|
||||
<p>{{Vn.Value.format(iter.taxableBase, '%.2d€')}}</p>
|
||||
<p>{{Vn.Value.format(iter.total, '%.2d€')}}</p>
|
||||
</div>
|
||||
<div
|
||||
class="actions"
|
||||
|
|
|
@ -1,44 +1,42 @@
|
|||
<vn>
|
||||
<vn-lot id="lot"/>
|
||||
<div id="title">
|
||||
<h1><t>Item list</t></h1>
|
||||
</div>
|
||||
<div id="actions" class="action-bar">
|
||||
<htk-bar-button
|
||||
icon="print"
|
||||
tip="_Preview"
|
||||
on-click="this.onPreviewClick()"/>
|
||||
</div>
|
||||
<div id="form" class="items">
|
||||
<div class="form box vn-w-sm vn-pa-lg">
|
||||
<div class="form-group">
|
||||
<label><t>Store</t></label>
|
||||
<htk-combo form="lot" column="warehouse">
|
||||
<db-model property="model">
|
||||
SELECT id, name
|
||||
FROM vn.warehouse
|
||||
WHERE hasAvailable
|
||||
ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Realm</t></label>
|
||||
<htk-combo form="lot" column="realm" not-null="false">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM vn.itemCategory
|
||||
WHERE display ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Rate</t></label>
|
||||
<select id="rate">
|
||||
<option>3</option>
|
||||
<option>2</option>
|
||||
<option>1</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn>
|
||||
<vn>
|
||||
<vn-lot id="lot"/>
|
||||
<div id="title">
|
||||
<h1><t>Item list</t></h1>
|
||||
</div>
|
||||
<div id="actions" class="action-bar">
|
||||
<htk-bar-button
|
||||
icon="print"
|
||||
tip="_Preview"
|
||||
on-click="this.onPreviewClick()"/>
|
||||
</div>
|
||||
<div id="form" class="items">
|
||||
<div class="form box vn-w-sm vn-pa-lg">
|
||||
<div class="form-group">
|
||||
<label><t>Store</t></label>
|
||||
<htk-combo form="lot" column="warehouse">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM vn2008.warehouse
|
||||
WHERE reserve ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Realm</t></label>
|
||||
<htk-combo form="lot" column="realm" not-null="false">
|
||||
<db-model property="model">
|
||||
SELECT id, reino FROM vn2008.reinos
|
||||
WHERE display != FALSE ORDER BY reino
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Rate</t></label>
|
||||
<select id="rate">
|
||||
<option>3</option>
|
||||
<option>2</option>
|
||||
<option>1</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn>
|
||||
|
|
|
@ -6,7 +6,7 @@ export default new Class({
|
|||
|
||||
activate() {
|
||||
this.$.lot.assign({
|
||||
date: Date.vnNew(),
|
||||
date: new Date(),
|
||||
useIds: false
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,107 +1,105 @@
|
|||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="config" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<vn-lot id="lot"/>
|
||||
<div id="title">
|
||||
<h1><t>Shelves</t></h1>
|
||||
</div>
|
||||
<div id="actions" class="action-bar">
|
||||
<htk-bar-button
|
||||
icon="print"
|
||||
tip="_Preview"
|
||||
on-click="this.onPreviewClick()"/>
|
||||
</div>
|
||||
<div id="form" class="shelves">
|
||||
<div class="form box vn-w-sm vn-pa-lg">
|
||||
<div class="form-group">
|
||||
<label><t>Configuration</t></label>
|
||||
<htk-combo
|
||||
id="config"
|
||||
placeholder="_Select config"
|
||||
form="params"
|
||||
column="config"
|
||||
on-changed="this.onConfigChange()"
|
||||
on-ready="this.onConfigChange()">
|
||||
<db-model property="model">
|
||||
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
|
||||
c.shelf, c.maxAmount, c.showPacking, c.stack, it.categoryFk realm
|
||||
FROM shelfMultiConfig c
|
||||
JOIN vn.itemType it ON it.id = c.family
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Date</t></label>
|
||||
<htk-date-chooser form="lot" name="date"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Reign</t></label>
|
||||
<htk-combo form="lot" name="realm">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM vn.itemCategory
|
||||
WHERE display ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Family</t></label>
|
||||
<htk-combo form="lot" name="family">
|
||||
<db-model property="model" lot="lot">
|
||||
SELECT id, name FROM vn.itemType
|
||||
WHERE categoryFk = #realm ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Store</t></label>
|
||||
<htk-combo form="lot">
|
||||
<db-model property="model">
|
||||
SELECT id, name
|
||||
FROM vn.warehouse
|
||||
WHERE hasAvailable
|
||||
ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Shelf</t></label>
|
||||
<htk-combo form="lot" name="shelf">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM shelf
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Name prefix</t></label>
|
||||
<htk-entry form="lot" name="namePrefix"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Limit amount per item</t></label>
|
||||
<htk-entry form="lot" name="maxAmount"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Title</t></label>
|
||||
<htk-entry form="lot" name="reportTitle"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="showPacking"/>
|
||||
<t>Show packing</t>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="stack"/>
|
||||
<t>Stack different items</t>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="useIds"/>
|
||||
<t>Use ids instead of names</t>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn>
|
||||
<vn>
|
||||
<vn-lot-query id="params">
|
||||
<vn-spec name="config" type="Number"/>
|
||||
</vn-lot-query>
|
||||
<vn-lot id="lot"/>
|
||||
<div id="title">
|
||||
<h1><t>Shelves</t></h1>
|
||||
</div>
|
||||
<div id="actions" class="action-bar">
|
||||
<htk-bar-button
|
||||
icon="print"
|
||||
tip="_Preview"
|
||||
on-click="this.onPreviewClick()"/>
|
||||
</div>
|
||||
<div id="form" class="shelves">
|
||||
<div class="form box vn-w-sm vn-pa-lg">
|
||||
<div class="form-group">
|
||||
<label><t>Configuration</t></label>
|
||||
<htk-combo
|
||||
id="config"
|
||||
placeholder="_Select config"
|
||||
form="params"
|
||||
column="config"
|
||||
on-changed="this.onConfigChange()"
|
||||
on-ready="this.onConfigChange()">
|
||||
<db-model property="model">
|
||||
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
|
||||
c.shelf, c.maxAmount, c.showPacking, c.stack, t.reino_id realm
|
||||
FROM shelfConfig c
|
||||
JOIN vn2008.Tipos t ON t.tipo_id = c.family
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Date</t></label>
|
||||
<htk-date-chooser form="lot" name="date"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Reign</t></label>
|
||||
<htk-combo form="lot" name="realm">
|
||||
<db-model property="model">
|
||||
SELECT id, reino FROM vn2008.reinos
|
||||
WHERE display != FALSE ORDER BY reino
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Family</t></label>
|
||||
<htk-combo form="lot" name="family">
|
||||
<db-model property="model" lot="lot">
|
||||
SELECT tipo_id, Tipo FROM vn2008.Tipos
|
||||
WHERE reino_id = #realm ORDER BY Tipo
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Store</t></label>
|
||||
<htk-combo form="lot">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM vn2008.warehouse
|
||||
WHERE reserve ORDER BY name
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Shelf</t></label>
|
||||
<htk-combo form="lot" name="shelf">
|
||||
<db-model property="model">
|
||||
SELECT id, name FROM shelf
|
||||
</db-model>
|
||||
</htk-combo>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Name prefix</t></label>
|
||||
<htk-entry form="lot" name="namePrefix"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Limit amount per item</t></label>
|
||||
<htk-entry form="lot" name="maxAmount"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><t>Title</t></label>
|
||||
<htk-entry form="lot" name="reportTitle"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="showPacking"/>
|
||||
<t>Show packing</t>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="stack"/>
|
||||
<t>Stack different items</t>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<htk-check form="lot" name="useIds"/>
|
||||
<t>Use ids instead of names</t>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn>
|
||||
|
|
|
@ -40,7 +40,9 @@ export const routes = {
|
|||
},
|
||||
agencies: {
|
||||
packages:
|
||||
() => import('agencies/packages')
|
||||
() => import('agencies/packages'),
|
||||
provinces:
|
||||
() => import('agencies/provinces')
|
||||
},
|
||||
cms: {
|
||||
about:
|
||||
|
|
|
@ -238,10 +238,9 @@ module.exports = new Class({
|
|||
if (err instanceof Vn.JsonException) {
|
||||
const statusCode = err.statusCode;
|
||||
if (statusCode >= 400 && statusCode < 500) {
|
||||
if (err.statusCode == 403) {
|
||||
Htk.Toast.showError(err.message ||
|
||||
_('You don\'t have enough privileges'));
|
||||
} else {
|
||||
if (err.statusCode == 403)
|
||||
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
||||
else {
|
||||
switch (err.exception) {
|
||||
case 'UserDisabledError':
|
||||
case 'OutdatedVersionError':
|
||||
|
|
|
@ -6,62 +6,33 @@ module.exports = class {
|
|||
if (orderId) orderId = parseInt(orderId);
|
||||
this.orderId = orderId;
|
||||
}
|
||||
async checkOrder(orderId) {
|
||||
async check(orderId) {
|
||||
const resultSet = await this.app.conn.execQuery(
|
||||
'CALL myOrder_checkConfig(#id)',
|
||||
{id: orderId}
|
||||
);
|
||||
resultSet.fetchValue();
|
||||
}
|
||||
async check(checkoutContinue) {
|
||||
if (this.orderId) {
|
||||
return await this.checkRedirect(checkoutContinue);
|
||||
} else {
|
||||
this.redirect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async checkRedirect(checkoutContinue) {
|
||||
async checkRedirect(orderId) {
|
||||
try {
|
||||
await this.checkOrder(this.orderId);
|
||||
await this.check(orderId);
|
||||
return true;
|
||||
} catch(err) {
|
||||
if (err.exception == 'Vn.Lib.UserError') {
|
||||
switch(err.code) {
|
||||
case 'orderConfirmed':
|
||||
case 'orderNotOwnedByUser':
|
||||
this.constructor.unload();
|
||||
await this.redirect();
|
||||
break;
|
||||
default:
|
||||
this.app.hash.setAll({
|
||||
form: 'ecomerce/checkout',
|
||||
id: this.orderId,
|
||||
continue: checkoutContinue
|
||||
});
|
||||
Htk.Toast.showError(err.message);
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async redirect() {
|
||||
const resultSet = await this.app.conn.execQuery(
|
||||
'SELECT COUNT(*) > 0 FROM myOrder');
|
||||
if (resultSet.fetchValue()) {
|
||||
this.app.hash.setAll({form: 'ecomerce/pending'});
|
||||
Htk.Toast.showMessage(_('Load an order'));
|
||||
} else {
|
||||
this.app.hash.setAll({form: 'ecomerce/checkout'});
|
||||
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('catalog'))
|
||||
this.app.hash.setAll({
|
||||
form: 'ecomerce/catalog'
|
||||
});
|
||||
if (!await this.checkRedirect(orderId)) return;
|
||||
this.app.hash.setAll({
|
||||
form: 'ecomerce/catalog'
|
||||
});
|
||||
}
|
||||
loadIntoBasket(orderId) {
|
||||
if (this.orderId != orderId) {
|
||||
|
|
|
@ -63,22 +63,3 @@ Agencies: Agències
|
|||
Configuration: Configuració
|
||||
Account: Compte
|
||||
Addresses: Adreces
|
||||
|
||||
Load an order: Si us plau carrega una comanda pendent a la cistella o en comença una de nova
|
||||
|
||||
Old password: Contrasenya antiga
|
||||
New password: Nova contrasenya
|
||||
Repeat password: Repetir contrasenya
|
||||
Requirements: Requisits
|
||||
Modify: Modificar
|
||||
Password requirements: Requisits de contrasenya
|
||||
characters long: caràcters de longitud
|
||||
alphabetic characters: caràcters alfabètics
|
||||
capital letters: majúscules
|
||||
digits: dígits
|
||||
symbols: símbols
|
||||
Password changed!: Contrasenya modificada!
|
||||
Password doesn't meet the requirements: ''
|
||||
Passwords doesn't match: Les contrasenyes no coincideixen!
|
||||
Passwords empty: Les contrasenyes en blanc
|
||||
Change password: Canvia la contrasenya
|
|
@ -59,5 +59,3 @@ Agencies: Agencies
|
|||
Configuration: Configuration
|
||||
Account: Account
|
||||
Addresses: Addresses
|
||||
|
||||
Load an order: Please load a pending order to the cart or start a new one
|
||||
|
|
|
@ -63,24 +63,3 @@ Agencies: Agencias
|
|||
Configuration: Configuración
|
||||
Account: Cuenta
|
||||
Addresses: Direcciones
|
||||
|
||||
Load an order: Por favor carga un pedido pendiente en la cesta o empieza uno nuevo
|
||||
|
||||
Old password: Contaseña antigua
|
||||
New password: Nueva contraseña
|
||||
Repeat password: Repetir contraseña
|
||||
Requirements: Requisitos
|
||||
Modify: Modificar
|
||||
Password requirements: Requisitos de constraseña
|
||||
characters long: carácteres de longitud
|
||||
alphabetic characters: carácteres alfabéticos
|
||||
capital letters: letras mayúsculas
|
||||
digits: dígitos
|
||||
symbols: 'símbolos. Ej: $%&.'
|
||||
Password changed!: ¡Contraseña modificada!
|
||||
Password doesn't meet the requirements: >-
|
||||
La nueva contraseña no reune los requisitos de seguridad necesarios, pulsa en
|
||||
info para más detalle
|
||||
Passwords doesn't match: ¡Las contraseñas no coinciden!
|
||||
Passwords empty: Contraseña vacía
|
||||
Change password: Cambiar contraseña
|
|
@ -5,7 +5,7 @@ Remind me: Retenir mon mot de passe
|
|||
Log in as guest: Entrez en tant qu'invité
|
||||
Login: Se connecter
|
||||
Login mail: info@verdnatura.es
|
||||
Login phone: +33 783 285 437
|
||||
Login phone: +33 781 533 900
|
||||
Password forgotten? Push here: Vous avez oublié votre mot de passe?
|
||||
Yet you are not a customer?: Vous n'êtes pas encore client?
|
||||
Sign up: S'inscrire
|
||||
|
@ -63,22 +63,3 @@ Agencies: Agences
|
|||
Configuration: Configuration
|
||||
Account: Compte
|
||||
Addresses: Adresses
|
||||
|
||||
Load an order: Veuillez télécharger une commande en attente dans le panier ou en démarrer une nouvelle
|
||||
|
||||
Old password: Ancien mot de passe
|
||||
New password: Nouveau mot de passe
|
||||
Repeat password: Répéter le mot de passe
|
||||
Requirements: Exigences
|
||||
Modify: Modifier
|
||||
Password requirements: Mot de passe exigences
|
||||
characters long: Longs caractères
|
||||
alphabetic characters: les caractères alphabétiques
|
||||
capital letters: lettres majuscules
|
||||
digits: chiffres
|
||||
symbols: 'symboles. Ej: $%&.'
|
||||
Password changed!: Mot de passe modifié!
|
||||
Password doesn't meet the requirements: ''
|
||||
Passwords doesn't match: Les mots de passe ne correspondent pas!
|
||||
Passwords empty: ''
|
||||
Change password: Changer le mot de passe
|
|
@ -61,22 +61,3 @@ Agencies: Agências
|
|||
Configuration: Configuração
|
||||
Account: Conta
|
||||
Addresses: Moradas
|
||||
|
||||
Load an order: Carregue um pedido pendente no carrinho ou inicie um novo
|
||||
|
||||
Old password: Palavra-passe antiga
|
||||
New password: Nova Palavra-passe
|
||||
Repeat password: Repetir Palavra-passe
|
||||
Requirements: Requisitos
|
||||
Modify: Modificar
|
||||
Password requirements: Requisitos de Palavra-passe
|
||||
characters long: caracteres
|
||||
alphabetic characters: caracteres alfabéticos
|
||||
capital letters: letras maiúsculas
|
||||
digits: dígitos
|
||||
symbols: 'símbolos. Ej: $%&.'
|
||||
Password changed!: Palavra-passe Modificada!
|
||||
Password doesn't meet the requirements: Palavra-passe não atende aos requisitos
|
||||
Passwords doesn't match: As Palavras-Passe não coincidem!
|
||||
Passwords empty: Palavra-passe vazia
|
||||
Change password: Mudar Palavra-passe
|
|
@ -26,12 +26,6 @@ module.exports = new Class({
|
|||
self._onSubmit();
|
||||
return false;
|
||||
};
|
||||
|
||||
if(this.hash.$.verificationToken){
|
||||
this.$.changePassword.conn = this.conn;
|
||||
this.$.changePassword.token = this.hash.$.verificationToken;
|
||||
this.$.changePassword.open();
|
||||
}
|
||||
}
|
||||
|
||||
,_onConnLoadChange(conn, isLoading) {
|
||||
|
@ -100,11 +94,7 @@ module.exports = new Class({
|
|||
return;
|
||||
}
|
||||
|
||||
await this.conn.post('VnUsers/recoverPassword', {
|
||||
user: recoverUser,
|
||||
app: 'hedera'
|
||||
});
|
||||
|
||||
await this._conn.send('user/recover-password', {recoverUser});
|
||||
Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password'));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -54,5 +54,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<htk-change-password id="change-password"/>
|
||||
</vn>
|
||||
|
|
|
@ -141,7 +141,7 @@ module.exports = new Class({
|
|||
}
|
||||
|
||||
,goToCurrentMonth() {
|
||||
var date = Date.vnNew();
|
||||
var date = new Date();
|
||||
this.goToMonth(date.getFullYear(), date.getMonth());
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ module.exports = new Class({
|
|||
|
||||
// Marks the current day
|
||||
|
||||
var today = Date.vnNew();
|
||||
var today = new Date();
|
||||
|
||||
if (this.year == today.getFullYear()
|
||||
&& this.month == today.getMonth()) {
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
var Component = require('vn/component');
|
||||
var Toast = require('../toast');
|
||||
var Tpl = require('./ui.xml').default;
|
||||
|
||||
/**
|
||||
* A change password popup.
|
||||
*/
|
||||
module.exports = new Class({
|
||||
Extends: Component,
|
||||
Tag: 'htk-change-password',
|
||||
Properties: {
|
||||
/**
|
||||
* The token url.
|
||||
*/
|
||||
token: {
|
||||
type: String
|
||||
,set(value) {
|
||||
this._token = value;
|
||||
}
|
||||
,get() {
|
||||
return this._token;
|
||||
}
|
||||
},
|
||||
conn: {
|
||||
type: Db.Connection
|
||||
,set(x) {
|
||||
this._conn = x
|
||||
}
|
||||
,get() {
|
||||
return this._conn;
|
||||
}
|
||||
},
|
||||
user: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
|
||||
initialize(props) {
|
||||
Component.prototype.initialize.call(this, props);
|
||||
},
|
||||
|
||||
async open() {
|
||||
this.passwordForm = await this.conn.get('UserPasswords/findOne')
|
||||
this.loadTemplateFromString(Tpl);
|
||||
|
||||
this.$.oldPassword.value = '';
|
||||
this.$.newPassword.value = '';
|
||||
this.$.repeatPassword.value = '';
|
||||
|
||||
this.$.oldPassword.style.display = this.token ? 'none' : 'block';
|
||||
this.$.changePassword.open();
|
||||
|
||||
if (this.token)
|
||||
this.$.newPassword.focus();
|
||||
else
|
||||
this.$.oldPassword.focus();
|
||||
},
|
||||
|
||||
async onPassModifyClick() {
|
||||
const form = this.$.changePassword.node;
|
||||
Vn.Node.disableInputs(form);
|
||||
try {
|
||||
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 Toast.showError(err.message);
|
||||
}
|
||||
|
||||
const params = {newPassword};
|
||||
|
||||
|
||||
try {
|
||||
if (this.token) {
|
||||
const headers = {
|
||||
Authorization: this.token
|
||||
};
|
||||
await this.conn.post('VnUsers/reset-password', params, {headers});
|
||||
} else {
|
||||
params.userId = this.user.id;
|
||||
params.oldPassword = oldPassword;
|
||||
|
||||
await this.conn.patch(`Accounts/change-password`, params);
|
||||
}
|
||||
} catch(err) {
|
||||
Toast.showError(err.message);
|
||||
|
||||
if (this.token)
|
||||
this.$.newPassword.select();
|
||||
else
|
||||
this.$.oldPassword.select();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.user)
|
||||
await this.conn.open(this.user.name, newPassword);
|
||||
this.$.changePassword.hide();
|
||||
} finally {
|
||||
Vn.Node.disableInputs(form, false);
|
||||
}
|
||||
|
||||
Toast.showMessage(_('Password changed!'));
|
||||
}
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
<vn>
|
||||
<htk-popup
|
||||
id="change-password"
|
||||
modal="true">
|
||||
<div property="child-node" class="htk-dialog vn-w-xs vn-pa-lg">
|
||||
<div class="form">
|
||||
<h5 class="vn-mb-md">
|
||||
<t>Change password</t>
|
||||
</h5>
|
||||
<input
|
||||
id="old-password"
|
||||
type="password"
|
||||
placeholder="_Old password"/>
|
||||
<input
|
||||
id="new-password"
|
||||
type="password"
|
||||
placeholder="_New password"
|
||||
autocomplete="new-password"/>
|
||||
<input
|
||||
id="repeat-password"
|
||||
type="password"
|
||||
placeholder="_Repeat password"
|
||||
autocomplete="new-password"/>
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<button class="thin" on-click="this.onPassModifyClick()">
|
||||
<t>Modify</t>
|
||||
</button>
|
||||
<button class="thin" on-click="this.$.passwordInfo.show()">
|
||||
<t>Requirements</t>
|
||||
</button>
|
||||
<div class="clear"/>
|
||||
</div>
|
||||
</div>
|
||||
</htk-popup>
|
||||
<htk-popup
|
||||
id="password-info"
|
||||
modal="true">
|
||||
<div property="child-node" class="htk-dialog pass-info vn-w-xs vn-pa-lg">
|
||||
<h5 class="vn-mb-md">
|
||||
<t>Password requirements</t>
|
||||
</h5>
|
||||
<ul>
|
||||
<li>
|
||||
{{this.passwordForm.length}} <t>characters long</t>
|
||||
</li>
|
||||
<li>
|
||||
{{this.passwordForm.nAlpha}} <t>alphabetic characters</t>
|
||||
</li>
|
||||
<li>
|
||||
{{this.passwordForm.nUpper}} <t>capital letters</t>
|
||||
</li>
|
||||
<li>
|
||||
{{this.passwordForm.nDigits}} <t>digits</t>
|
||||
</li>
|
||||
<li>
|
||||
{{this.passwordForm.nPunct}} <t>symbols</t>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</htk-popup>
|
||||
</vn>
|
|
@ -3,23 +3,22 @@ require('db/db');
|
|||
require('./style/index.scss');
|
||||
|
||||
Htk = module.exports = {
|
||||
Popup : require('./popup')
|
||||
,Dialog : require('./dialog')
|
||||
,Toast : require('./toast')
|
||||
,Repeater : require('./repeater')
|
||||
,Grid : require('./grid')
|
||||
,Spinner : require('./spinner')
|
||||
,Icon : require('./icon')
|
||||
,FullImage : require('./full-image')
|
||||
,ImageEditor : require('./image-editor')
|
||||
,Assistant : require('./assistant')
|
||||
,AssistantBar : require('./assistant-bar')
|
||||
,Step : require('./step')
|
||||
,Loader : require('./loader')
|
||||
,List : require('./list')
|
||||
,Field : require('./field')
|
||||
,Column : require('./column')
|
||||
,ChangePassword : require('./change-password')
|
||||
Popup : require('./popup')
|
||||
,Dialog : require('./dialog')
|
||||
,Toast : require('./toast')
|
||||
,Repeater : require('./repeater')
|
||||
,Grid : require('./grid')
|
||||
,Spinner : require('./spinner')
|
||||
,Icon : require('./icon')
|
||||
,FullImage : require('./full-image')
|
||||
,ImageEditor : require('./image-editor')
|
||||
,Assistant : require('./assistant')
|
||||
,AssistantBar : require('./assistant-bar')
|
||||
,Step : require('./step')
|
||||
,Loader : require('./loader')
|
||||
,List : require('./list')
|
||||
,Field : require('./field')
|
||||
,Column : require('./column')
|
||||
};
|
||||
|
||||
var Fields = {
|
||||
|
|
|
@ -192,7 +192,7 @@ module.exports = new Class({
|
|||
}
|
||||
|
||||
,_onFileUpload(cell) {
|
||||
this._stamp = Date.vnNew().getTime();
|
||||
this._stamp = new Date().getTime();
|
||||
this._refreshSrc(cell);
|
||||
this.popup.hide();
|
||||
}
|
||||
|
|
|
@ -3,61 +3,69 @@
|
|||
*/
|
||||
module.exports =
|
||||
{
|
||||
set: function(key, value, days) {
|
||||
set: function (key, value, days)
|
||||
{
|
||||
var strCookie = key + '=' + value + ';';
|
||||
|
||||
if (days != undefined) {
|
||||
var date = Date.vnNew();
|
||||
date.setTime(date.getTime() + days * 86400000);
|
||||
strCookie += 'expires=' + date.toGMTString();
|
||||
if (days != undefined)
|
||||
{
|
||||
var date = new Date ();
|
||||
date.setTime (date.getTime () + days * 86400000);
|
||||
strCookie += 'expires=' + date.toGMTString ();
|
||||
}
|
||||
|
||||
document.cookie = strCookie;
|
||||
}
|
||||
|
||||
,unset: function(key) {
|
||||
this.set(key, '', -1);
|
||||
,unset: function (key)
|
||||
{
|
||||
this.set (key, '', -1);
|
||||
}
|
||||
|
||||
,get: function(key) {
|
||||
var cookie = new String(document.cookie);
|
||||
var start = cookie.indexOf(key + '=');
|
||||
,get: function (key)
|
||||
{
|
||||
var cookie = new String (document.cookie);
|
||||
var start = cookie.indexOf (key + '=');
|
||||
|
||||
if (start != -1) {
|
||||
if (start != -1)
|
||||
{
|
||||
var end;
|
||||
|
||||
start += key.length + 1;
|
||||
end = cookie.indexOf(';', start);
|
||||
end = cookie.indexOf (';', start);
|
||||
|
||||
if (end > 0)
|
||||
return cookie.substring(start, end);
|
||||
return cookie.substring (start, end);
|
||||
else
|
||||
return cookie.substring(start);
|
||||
return cookie.substring (start);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
,getInt: function(key) {
|
||||
var value = this.get(key);
|
||||
,getInt: function (key)
|
||||
{
|
||||
var value = this.get (key);
|
||||
|
||||
if (value != null)
|
||||
return parseInt(value);
|
||||
return parseInt (value);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
,getFloat: function(key) {
|
||||
var value = this.get(key);
|
||||
,getFloat: function (key)
|
||||
{
|
||||
var value = this.get (key);
|
||||
|
||||
if (value != null)
|
||||
return parseFloat(value);
|
||||
return parseFloat (value);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
,check: function(key) {
|
||||
return this.get(key) != null;
|
||||
,check: function (key)
|
||||
{
|
||||
return this.get (key) != null;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -6,22 +6,6 @@ Date.prototype.clone = function() {
|
|||
return new Date(this.getTime());
|
||||
}
|
||||
|
||||
Date.vnUTC = () => {
|
||||
const env = process.env.NODE_ENV;
|
||||
if (!env || env === 'development')
|
||||
return new Date(Date.UTC(2001, 0, 1, 11));
|
||||
|
||||
return new Date();
|
||||
};
|
||||
|
||||
Date.vnNew = () => {
|
||||
return new Date(Date.vnUTC());
|
||||
};
|
||||
|
||||
Date.vnNow = () => {
|
||||
return new Date(Date.vnUTC()).getTime();
|
||||
};
|
||||
|
||||
module.exports =
|
||||
{
|
||||
WDays: [
|
||||
|
@ -71,7 +55,7 @@ module.exports =
|
|||
,'Dec'
|
||||
]
|
||||
|
||||
,tokenD: '%A, %B %e %Y'
|
||||
,tokenD: '%A, %B %e'
|
||||
|
||||
,regexp: new RegExp('%[a-zA-Z]', 'g')
|
||||
|
||||
|
@ -117,7 +101,7 @@ module.exports =
|
|||
// Year with 4 digits
|
||||
case 'Y': return d.getFullYear();
|
||||
|
||||
// Complete date
|
||||
// Complete date without year
|
||||
case 'D': return _(this.tokenD).replace(this.regexp, this.regexpFunc.bind(this, d));
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,6 @@ module.exports = new Class({
|
|||
const config = {
|
||||
headers: {'Authorization': token}
|
||||
};
|
||||
await this.send('user/logout', null, config);
|
||||
await this.post('Accounts/logout', null, config);
|
||||
}
|
||||
},
|
||||
|
@ -140,16 +139,15 @@ module.exports = new Class({
|
|||
/*
|
||||
* Called when REST response is received.
|
||||
*/
|
||||
async sendWithUrl(method, url, params, config) {
|
||||
config = Object.assign({}, config, {
|
||||
async sendWithUrl(method, url, params) {
|
||||
return this.request({
|
||||
method,
|
||||
url,
|
||||
data: Vn.Url.makeUri(params)
|
||||
data: Vn.Url.makeUri(params),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
});
|
||||
config.headers = Object.assign({}, config.headers, {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
});
|
||||
return this.request(config);
|
||||
},
|
||||
|
||||
async get(url, config) {
|
||||
|
|
|
@ -36,7 +36,7 @@ Sep: Set
|
|||
Oct: Oct
|
||||
Nov: Nov
|
||||
Dec: Des
|
||||
'%A, %B %e %Y': '%A, %e de %B de %Y'
|
||||
'%A, %B %e': '%A, %e de %B'
|
||||
Something went wrong: Alguna cosa ha anat malament
|
||||
'The server does not respond, please check your Internet connection': 'El servidor no respon, si us plau comprova la teva connexió a Internet'
|
||||
Accept: Acceptar
|
||||
|
|
|
@ -36,6 +36,6 @@ Sep: Sep
|
|||
Oct: Oct
|
||||
Nov: Nov
|
||||
Dec: Dic
|
||||
'%A, %B %e %Y': '%A, %B %e %Y'
|
||||
'%A, %B %e': '%A, %B %e'
|
||||
Something went wrong: Something went wrong
|
||||
'The server does not respond, please check your Internet connection': 'The server does not respond, please check you Internet connection'
|
||||
|
|
|
@ -36,7 +36,7 @@ Sep: Sep
|
|||
Oct: Oct
|
||||
Nov: Nov
|
||||
Dec: Dic
|
||||
'%A, %B %e %Y': '%A, %e de %B de %Y'
|
||||
'%A, %B %e': '%A, %e de %B'
|
||||
Something went wrong: Algo salió mal
|
||||
'The server does not respond, please check your Internet connection': 'El servidor no responde, por favor comprueba tu conexión a Internet'
|
||||
Accept: Aceptar
|
||||
|
|
|
@ -36,7 +36,7 @@ Sep: Sep
|
|||
Oct: Oct
|
||||
Nov: Nov
|
||||
Dec: Déc
|
||||
'%A, %B %e %Y': '%A, %B %e %Y'
|
||||
'%A, %B %e': '%A, %B %e'
|
||||
Something went wrong: Quelque-chose s'est mal passé
|
||||
'The server does not respond, please check your Internet connection': 'Le serveur ne répond pas, s''il vous plaît vérifier votre connexion Internet'
|
||||
Accept: Accepter
|
||||
|
|
|
@ -36,6 +36,6 @@ Sep: Есд
|
|||
Oct: Ара
|
||||
Nov: Арв
|
||||
Dec: Арв
|
||||
'%A, %B %e %Y': '%A, %B %e %Y'
|
||||
'%A, %B %e': '%A, %B %e'
|
||||
Something went wrong: Something went wrong
|
||||
'The server does not respond, please check your Internet connection': 'The server does not respond, please check you Internet connection'
|
||||
|
|
|
@ -36,7 +36,7 @@ Sep: Set
|
|||
Oct: Out
|
||||
Nov: Nov
|
||||
Dec: Dez
|
||||
'%A, %B %e %Y': '%A, %B %e %Y'
|
||||
'%A, %B %e': '%A, %B %e'
|
||||
Something went wrong: Algo deu errado
|
||||
'The server does not respond, please check your Internet connection': 'O servidor não responde, por favor, verifique sua conexão com a Internet'
|
||||
Accept: Aceitar
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hedera-web",
|
||||
"version": "25.4.4",
|
||||
"version": "22.48.10",
|
||||
"description": "Verdnatura web page",
|
||||
"license": "GPL-3.0",
|
||||
"repository": {
|
||||
|
@ -21,9 +21,9 @@
|
|||
"html-webpack-plugin": "^5.5.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"mini-css-extract-plugin": "^2.7.0",
|
||||
"node-sass": "^9.0.0",
|
||||
"node-sass": "^7.0.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"sass-loader": "^13.3.2",
|
||||
"sass-loader": "^12.6.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.75.0",
|
||||
|
@ -42,8 +42,7 @@
|
|||
"scripts": {
|
||||
"front": "webpack serve --open",
|
||||
"back": "cd ../salix && gulp backOnly",
|
||||
"php": "php -S 127.0.0.1:3001 -t . index.php",
|
||||
"db": "cd ../vn-database && myt run",
|
||||
"db": "cd ../vn-database && myvc run",
|
||||
"build": "rm -rf build/ ; webpack",
|
||||
"clean": "rm -rf build/"
|
||||
}
|
||||
|
|
|
@ -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,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Vn\Lib;
|
||||
use Vn\Lib\Locale;
|
||||
use Vn\Web\Security;
|
||||
use Vn\Lib\Type;
|
||||
|
||||
|
@ -37,17 +36,13 @@ class Query extends Vn\Web\JsonRequest {
|
|||
while ($db->moreResults() && $db->nextResult());
|
||||
|
||||
if ($db->checkWarnings()
|
||||
&& ($result = $db->query('SHOW WARNINGS'))) {
|
||||
$sql =
|
||||
'SELECT IFNULL(i.`description`, m.`description`) `description`, @warn `code`
|
||||
FROM `message` m
|
||||
LEFT JOIN `messageI18n` i
|
||||
ON i.`code` = m.`code` AND i.lang = #
|
||||
WHERE m.`code` = @warn';
|
||||
&&($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, [Locale::get()])))
|
||||
&&($warning = $db->getObject($sql)))
|
||||
trigger_error("{$warning->code}: {$warning->description}", E_USER_WARNING);
|
||||
else
|
||||
trigger_error("{$row->Code}: {$row->Message}", E_USER_WARNING);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use Vn\Web\Security;
|
||||
use Vn\Web\Util;
|
||||
use Vn\Lib;
|
||||
|
||||
class Invoice extends Vn\Web\RestRequest {
|
||||
const PARAMS = ['invoice'];
|
||||
const SECURITY = Security::INVOKER;
|
||||
|
||||
function run($db) {
|
||||
$pdfPath = $db->getValueFromFile(__DIR__ .'/invoice',
|
||||
['invoice' =>(int) $_GET['invoice']]);
|
||||
|
||||
if (!$pdfPath)
|
||||
throw new Lib\UserException(s('Invoice id not found'));
|
||||
|
||||
Util::printFile($pdfPath);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
SELECT CONCAT_WS('/', c.pdfsDir, vn.invoiceOut_getPath(#invoice))
|
||||
FROM config c
|
||||
JOIN myInvoice i
|
||||
WHERE i.id = #invoice
|
|
@ -8,7 +8,7 @@ class Clean extends Edi\Method {
|
|||
|
||||
$cleanPeriod = $db->getValue(
|
||||
"SELECT ic.cleanPeriod
|
||||
FROM imapMultiConfig ic
|
||||
FROM imapConfig ic
|
||||
JOIN util.config c ON c.environment = ic.environment");
|
||||
|
||||
$deleted = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@ abstract class Method extends \Vn\Lib\Method {
|
|||
|
||||
$imapConf = $db->getRow(
|
||||
"SELECT ic.host, ic.user, ic.pass, ic.successFolder, ic.errorFolder
|
||||
FROM imapMultiConfig ic
|
||||
FROM imapConfig ic
|
||||
JOIN util.config c ON c.environment = ic.environment");
|
||||
|
||||
$this->mailbox = sprintf('{%s/imap/ssl/novalidate-cert}',
|
||||
|
|
|
@ -39,31 +39,31 @@ class Upload extends Vn\Web\JsonRequest {
|
|||
|
||||
if ($_FILES['image']['error'] != 0) {
|
||||
switch ($_FILES['image']['error']) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
$message = 'ErrIniSize';
|
||||
break;
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
$message = 'ErrFormSize';
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$message = 'ErrPartial';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
$message = 'ErrNoFile';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
$message = 'ErrNoTmpDir';
|
||||
break;
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
$message = 'ErrCantWrite';
|
||||
break;
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
$message = 'ErrExtension';
|
||||
break;
|
||||
default:
|
||||
$message = 'ErrDefault';
|
||||
break;
|
||||
}
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
$message = 'ErrIniSize';
|
||||
break;
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
$message = 'ErrFormSize';
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$message = 'ErrPartial';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
$message = 'ErrNoFile';
|
||||
break;
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
$message = 'ErrNoTmpDir';
|
||||
break;
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
$message = 'ErrCantWrite';
|
||||
break;
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
$message = 'ErrExtension';
|
||||
break;
|
||||
default:
|
||||
$message = 'ErrDefault';
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Lib\Exception(s($message));
|
||||
}
|
||||
|
@ -101,6 +101,12 @@ class Upload extends Vn\Web\JsonRequest {
|
|||
$symbolicSrc = "../full/$fileName";
|
||||
|
||||
$image = Image::create($tmpName);
|
||||
Image::resizeSave($image, $fullFile, $info['maxHeight'], $info['maxWidth']);
|
||||
|
||||
foreach ($info['sizes'] as $size => $i) {
|
||||
$dstFile = "$collectionPath/$size/$fileName";
|
||||
Image::resizeSave($image, $dstFile, $i['height'], $i['width'], $i['crop'], $symbolicSrc);
|
||||
}
|
||||
|
||||
$query =
|
||||
"INSERT INTO `image`
|
||||
|
@ -115,13 +121,6 @@ class Upload extends Vn\Web\JsonRequest {
|
|||
'name' => $name
|
||||
]);
|
||||
|
||||
Image::resizeSave($image, $fullFile, $info['maxHeight'], $info['maxWidth']);
|
||||
|
||||
foreach ($info['sizes'] as $size => $i) {
|
||||
$dstFile = "$collectionPath/$size/$fileName";
|
||||
Image::resizeSave($image, $dstFile, $i['height'], $i['width'], $i['crop'], $symbolicSrc);
|
||||
}
|
||||
|
||||
imagedestroy($image);
|
||||
unlink($tmpName);
|
||||
return TRUE;
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Ejemplo:
|
||||
* <Cube><Cube time="2010-12-10"><Cube currency="USD" rate="1.3244"/>
|
||||
*/
|
||||
class ExchangeRate extends Vn\Lib\Method {
|
||||
function run($db) {
|
||||
$db->selectDb('vn2008');
|
||||
|
||||
// Indica la URL del archivo
|
||||
|
||||
$xml = new SimpleXMLElement(
|
||||
'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml', 0, TRUE);
|
||||
|
||||
$date = $db->getValue("SELECT MAX(date) fecha FROM reference_rate");
|
||||
$maxDate = $date ? DateTime::createFromFormat('Y-m-d', $date) : NULL;
|
||||
|
||||
foreach ($xml->Cube[0]->Cube as $cube) {
|
||||
$xmlDate = new DateTime($cube['time']);
|
||||
|
||||
// Si existen datos más recientes de la máxima fecha los añade
|
||||
|
||||
if ($maxDate <= $xmlDate)
|
||||
foreach ($cube->Cube as $subCube)
|
||||
if ($subCube['currency'] == 'USD') {
|
||||
$params = [
|
||||
'date' => $xmlDate,
|
||||
'rate' => $subCube['rate']
|
||||
];
|
||||
$db->query(
|
||||
'REPLACE INTO reference_rate(moneda_id, date, rate)
|
||||
VALUES(2, #date, #rate)',
|
||||
$params
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$db->queryFromFile(__DIR__.'/exrate-add');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
INSERT INTO reference_rate (moneda_id, date, rate)
|
||||
SELECT 2, TIMESTAMPADD (DAY, 1, r1.date), r1.rate
|
||||
FROM reference_rate r1
|
||||
LEFT JOIN reference_rate r2
|
||||
ON TIMESTAMPADD(DAY, 1, r1.date) = r2.date
|
||||
WHERE r2.date IS NULL AND r1.date < TIMESTAMPADD (DAY, -2, CURDATE())
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
class Account {
|
||||
static function trySync($db, $userName, $password = NULL) {
|
||||
$sync = $db->getValue(
|
||||
'SELECT COUNT(*) > 0 FROM account.userSync WHERE name = #',
|
||||
[$userName]
|
||||
);
|
||||
|
||||
if ($sync)
|
||||
self::sync($db, $userName, $password);
|
||||
}
|
||||
|
||||
static function sync($db, $userName, $password = NULL) {
|
||||
$bcryptPassword = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
$userId = $db->getValue(
|
||||
'SELECT id FROM account.user WHERE `name` = #',
|
||||
[$userName]
|
||||
);
|
||||
$db->query(
|
||||
'UPDATE account.user SET
|
||||
bcryptPassword = #
|
||||
WHERE id = #',
|
||||
[$bcryptPassword, $userId]
|
||||
);
|
||||
|
||||
$hasAccount = $db->getValue(
|
||||
'SELECT COUNT(*) > 0
|
||||
FROM account.user u
|
||||
JOIN account.account a ON u.id = a.id
|
||||
WHERE u.name = #',
|
||||
[$userName]
|
||||
);
|
||||
if (!$hasAccount)
|
||||
$db->query('DELETE FROM account.userSync WHERE name = #',
|
||||
[$userName]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
class Logout extends Vn\Web\JsonRequest {
|
||||
function run($db) {
|
||||
$_SESSION['user'] = null;
|
||||
}
|
||||
}
|
|
@ -48,13 +48,13 @@ class JsonService extends RestService {
|
|||
|
||||
$json = new JsonException();
|
||||
|
||||
if (_ENABLE_DEBUG || $errno & $eUser) {
|
||||
if (_ENABLE_DEBUG || $errno & $eUser)
|
||||
$json->message = $message;
|
||||
$json->code = $errno;
|
||||
} else
|
||||
else
|
||||
$json->message = s('Something went wrong');
|
||||
|
||||
if (_ENABLE_DEBUG) {
|
||||
$json->code = $errno;
|
||||
$json->file = $file;
|
||||
$json->line = $line;
|
||||
}
|
||||
|
@ -79,13 +79,13 @@ class JsonService extends RestService {
|
|||
if (_ENABLE_DEBUG || $e instanceof Lib\UserException) {
|
||||
$json->exception = get_class($e);
|
||||
$json->message = $e->getMessage();
|
||||
$json->code = $e->getCode();
|
||||
} else {
|
||||
$json->exception = 'Exception';
|
||||
$json->message = s('Something went wrong');
|
||||
}
|
||||
|
||||
if (_ENABLE_DEBUG) {
|
||||
$json->code = $e->getCode();
|
||||
$json->file = $e->getFile();
|
||||
$json->line = $e->getLine();
|
||||
$json->trace = $e->getTrace();
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace Vn\Web;
|
|||
require_once 'libphp-phpmailer/autoload.php';
|
||||
|
||||
use Vn\Lib\UserException;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
|
||||
class Mailer {
|
||||
private $conf;
|
||||
|
@ -20,7 +19,7 @@ class Mailer {
|
|||
function createObject($mailTo, $body, $subject) {
|
||||
$conf = $this->conf;
|
||||
|
||||
$mail = new PHPMailer();
|
||||
$mail = new \PHPMailer();
|
||||
$mail->isSMTP();
|
||||
$mail->Host = $conf->host;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue