forked from verdnatura/hedera-web
Compare commits
153 Commits
4922-vueMi
...
dev
Author | SHA1 | Date |
---|---|---|
Guillermo Bonet | f57967cd17 | |
Guillermo Bonet | 1c54922692 | |
Guillermo Bonet | 8929f8c55a | |
Guillermo Bonet | 7f2c645682 | |
Guillermo Bonet | 099f494101 | |
Guillermo Bonet | 61fac85554 | |
Guillermo Bonet | 3a714debfc | |
Guillermo Bonet | 647dd09013 | |
Guillermo Bonet | 05c71c7425 | |
Guillermo Bonet | 90e2b0abb5 | |
Guillermo Bonet | bcbbee411f | |
Guillermo Bonet | 961ff02053 | |
Guillermo Bonet | e7eb2a01fe | |
Juan Ferrer | 98cefc8f0f | |
Juan Ferrer | e40a28b649 | |
Guillermo Bonet | f869e7413c | |
Guillermo Bonet | 29e800ea30 | |
Robert Ferrús | 1eb98b772a | |
Guillermo Bonet | 1fe6816c08 | |
Javi Gallego | 5bbc342471 | |
Javi Gallego | d808fa71d1 | |
Juan Ferrer | ac226205b0 | |
Guillermo Bonet | 87f17409f7 | |
Javi Gallego | ae70cbaaf4 | |
Guillermo Bonet | 6e1613a26c | |
Guillermo Bonet | 359ddb5d18 | |
Guillermo Bonet | d75fe3fc00 | |
Guillermo Bonet | e6cd88ee82 | |
Guillermo Bonet | a405cba00b | |
Guillermo Bonet | e4f55ca9e9 | |
Robert Ferrús | d8ea9134d4 | |
Guillermo Bonet | a96859b6bb | |
Guillermo Bonet | e210a09f6b | |
Guillermo Bonet | 5304a77f94 | |
Guillermo Bonet | 3f63da06f1 | |
Guillermo Bonet | 7d120598bc | |
Juan Ferrer | 4cf91140f7 | |
Jorge Penadés | 06554b7dee | |
Juan Ferrer | 83c6886ee6 | |
Jorge Penadés | 4765bc78de | |
Jorge Penadés | 0a9635feb2 | |
Jorge Penadés | 00c8e4b1e3 | |
Guillermo Bonet | 1414b6c96e | |
Guillermo Bonet | 244b3f939e | |
Guillermo Bonet | 1d2f9061c5 | |
Guillermo Bonet | a121750fa7 | |
Guillermo Bonet | 73ba16634e | |
Juan Ferrer | 2515cbcee7 | |
Juan Ferrer | d1cdba800d | |
Juan Ferrer | 02ddc87755 | |
Juan Ferrer | 7689be689f | |
Juan Ferrer | 33778629e6 | |
Juan Ferrer | 7f1d8ebb8e | |
Juan Ferrer | 4d8a67f499 | |
Guillermo Bonet | c6120af93b | |
Guillermo Bonet | 95f819c22f | |
Juan Ferrer | 496061fb3c | |
Juan Ferrer | 0b85c1230a | |
Juan Ferrer | 3ed871cb4c | |
Juan Ferrer | c7159a1e13 | |
Juan Ferrer | fba880fb33 | |
Juan Ferrer | 1535a557a8 | |
Juan Ferrer | 4a09fe39a8 | |
Juan Ferrer | 3977b258d3 | |
Juan Ferrer | 6915e06c71 | |
Juan Ferrer | a474f9df05 | |
Juan Ferrer | 620bd53262 | |
Juan Ferrer | 8f98597ea2 | |
Alex Moreno | a2cd8a711e | |
Alex Moreno | 08b4a3437c | |
Juan Ferrer | a59c44fb3a | |
Juan Ferrer | 2adfd2299a | |
Juan Ferrer | f929e67d76 | |
Juan Ferrer | d37493b081 | |
Alex Moreno | 0f3ddb1a99 | |
Juan Ferrer | bb4e348d0c | |
Juan Ferrer | 754b8cd6c4 | |
Alex Moreno | 7bb067223a | |
Alex Moreno | 9363cdf5a4 | |
Alex Moreno | d17bc6115f | |
Javi Gallego | 9475c26663 | |
Alex Moreno | 607513452f | |
Alex Moreno | 86be0278a6 | |
Alex Moreno | a8f98d62ab | |
Alex Moreno | 2af5851066 | |
Javi Gallego | 1470e77572 | |
Alex Moreno | 32cc865290 | |
Javi Gallego | 8bcfe9f50c | |
Alex Moreno | f638143e3e | |
Javi Gallego | 07bde10609 | |
Alex Moreno | 4231365e4f | |
Juan Ferrer | fa56a4e540 | |
Juan Ferrer | 5bcfd5897c | |
Juan Ferrer | 572d4b7b83 | |
Juan Ferrer | bbeb70eb6b | |
Juan Ferrer | 2905a6ab57 | |
Juan Ferrer | 5b84671d57 | |
Carlos Andrés | 9146d28db5 | |
Carlos Andrés | 59242daa79 | |
Juan Ferrer | fd32b3f15a | |
Juan Ferrer | 56395aa91b | |
Carlos Andrés | 2610448e79 | |
Carlos Andrés | 9eba09ddf7 | |
Juan Ferrer | 74980fbdd7 | |
Juan Ferrer | 01326dc91c | |
Juan Ferrer | 5ce2f46842 | |
Juan Ferrer | 42f682739e | |
Juan Ferrer | bbe7f2ea14 | |
Juan Ferrer | cdafea824e | |
Juan Ferrer | 5fce203252 | |
Juan Ferrer | 9945c8f1b6 | |
Juan Ferrer | 1ef0d48ba7 | |
Juan Ferrer | 197758f2bc | |
Juan Ferrer | 511e925467 | |
Juan Ferrer | f47e7e07a7 | |
Juan Ferrer | b32be540f3 | |
Juan Ferrer | 4190aad94e | |
Juan Ferrer | 9bfd42eaf8 | |
Juan Ferrer | dd7185d5dd | |
Juan Ferrer | 10d8128133 | |
Juan Ferrer | b357c4a451 | |
Juan Ferrer | e5941266ed | |
Juan Ferrer | 592f79fcbd | |
Juan Ferrer | 0abc6bdc23 | |
Juan Ferrer | 210b7e7806 | |
Juan Ferrer | 92a4bc458c | |
Juan Ferrer | 520e0c1eff | |
Juan Ferrer | afd23e08b7 | |
Juan Ferrer | 18cdb4cc1b | |
Juan Ferrer | ca5f80f6c3 | |
Juan Ferrer | d1ff6889af | |
Juan Ferrer | a632a15242 | |
Juan Ferrer | 67b6f77b12 | |
Juan Ferrer | e8eab29887 | |
Juan Ferrer | 326aeee127 | |
Juan Ferrer | bbb0089b59 | |
Juan Ferrer | 406b2f8300 | |
Juan Ferrer | efc7342359 | |
Juan Ferrer | 806c4cc3ad | |
Juan Ferrer | c463e967ca | |
Juan Ferrer | be43a38b38 | |
Juan Ferrer | 59ed61ae9b | |
Juan Ferrer | 17e54cfc60 | |
Juan Ferrer | baa9bb7cdf | |
Juan Ferrer | 87d75be910 | |
Juan Ferrer | ac629dc97b | |
Juan Ferrer | ff3320d590 | |
Juan Ferrer | e8b727ab6c | |
Juan Ferrer | 5934ee3832 | |
Juan Ferrer | 4f09574697 | |
Juan Ferrer | 6d95dfb999 | |
Juan Ferrer | 1fa9b1e8b0 | |
Juan Ferrer | 327508c3ee |
|
@ -2,3 +2,4 @@ node_modules
|
||||||
build/
|
build/
|
||||||
config.my.php
|
config.my.php
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.quasar
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Not using buster because of bug: https://bugs.php.net/bug.php?id=78870
|
# Not using buster because of bug: https://bugs.php.net/bug.php?id=78870
|
||||||
FROM debian:stretch-slim
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
@ -23,19 +23,19 @@ RUN a2dissite 000-default
|
||||||
|
|
||||||
# NodeJs
|
# NodeJs
|
||||||
|
|
||||||
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - \
|
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||||
&& apt-get install -y --no-install-recommends nodejs
|
&& apt-get install -y --no-install-recommends nodejs
|
||||||
|
|
||||||
# Hedera
|
# Hedera
|
||||||
|
|
||||||
RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
|
RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
|
||||||
&& echo "deb http://apt.verdnatura.es/ stretch main" \
|
&& echo "deb http://apt.verdnatura.es/ bookworm main" \
|
||||||
> /etc/apt/sources.list.d/vn.list \
|
> /etc/apt/sources.list.d/vn.list \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
php-apcu \
|
||||||
php-image-text \
|
php-image-text \
|
||||||
php-text-captcha \
|
php-text-captcha \
|
||||||
php-apcu \
|
|
||||||
php-zip \
|
php-zip \
|
||||||
hedera-web \
|
hedera-web \
|
||||||
cron
|
cron
|
||||||
|
|
|
@ -1,34 +1,24 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
|
|
||||||
|
def BRANCH_ENV = [
|
||||||
|
test: 'test',
|
||||||
|
master: 'production'
|
||||||
|
]
|
||||||
|
|
||||||
|
node {
|
||||||
|
stage('Setup') {
|
||||||
|
env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev'
|
||||||
|
|
||||||
|
echo "NODE_NAME: ${env.NODE_NAME}"
|
||||||
|
echo "WORKSPACE: ${env.WORKSPACE}"
|
||||||
|
}
|
||||||
|
}
|
||||||
pipeline {
|
pipeline {
|
||||||
agent any
|
agent any
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'hedera-web'
|
PROJECT_NAME = 'hedera-web'
|
||||||
STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}"
|
|
||||||
}
|
}
|
||||||
stages {
|
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') {
|
stage('Debuild') {
|
||||||
when {
|
when {
|
||||||
anyOf {
|
anyOf {
|
||||||
|
@ -38,7 +28,7 @@ pipeline {
|
||||||
}
|
}
|
||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'registry.verdnatura.es/debuild:2.21.3-vn2'
|
image 'registry.verdnatura.es/debuild:2.23.4-vn1'
|
||||||
registryUrl 'https://registry.verdnatura.es/'
|
registryUrl 'https://registry.verdnatura.es/'
|
||||||
registryCredentialsId 'docker-registry'
|
registryCredentialsId 'docker-registry'
|
||||||
args '-v /mnt/appdata/reprepro:/reprepro'
|
args '-v /mnt/appdata/reprepro:/reprepro'
|
||||||
|
@ -46,7 +36,7 @@ pipeline {
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
sh 'debuild -us -uc -b'
|
sh 'debuild -us -uc -b'
|
||||||
sh 'vn-includedeb stretch'
|
sh 'vn-includedeb bookworm'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Container') {
|
stage('Container') {
|
||||||
|
@ -60,6 +50,10 @@ pipeline {
|
||||||
CREDS = credentials('docker-registry')
|
CREDS = credentials('docker-registry')
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
script {
|
||||||
|
def packageJson = readJSON file: 'package.json'
|
||||||
|
env.VERSION = packageJson.version
|
||||||
|
}
|
||||||
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
||||||
sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel'
|
sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel'
|
||||||
sh 'docker-compose push'
|
sh 'docker-compose push'
|
||||||
|
@ -72,16 +66,25 @@ pipeline {
|
||||||
branch 'test'
|
branch 'test'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
environment {
|
|
||||||
DOCKER_HOST = "${env.SWARM_HOST}"
|
|
||||||
}
|
|
||||||
steps {
|
steps {
|
||||||
sh "docker stack deploy --with-registry-auth --compose-file docker-compose.yml ${env.STACK_NAME}"
|
script {
|
||||||
|
def packageJson = readJSON file: 'package.json'
|
||||||
|
env.VERSION = packageJson.version
|
||||||
|
}
|
||||||
|
withKubeConfig([
|
||||||
|
serverUrl: "$KUBERNETES_API",
|
||||||
|
credentialsId: 'kubernetes',
|
||||||
|
namespace: 'salix'
|
||||||
|
]) {
|
||||||
|
sh 'kubectl set image deployment/hedera-web-$BRANCH_NAME hedera-web-$BRANCH_NAME=$REGISTRY/hedera-web:$VERSION'
|
||||||
|
sh 'kubectl set image deployment/hedera-web-cron-$BRANCH_NAME hedera-web-cron-$BRANCH_NAME=$REGISTRY/hedera-web:$VERSION'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
unsuccessful {
|
unsuccessful {
|
||||||
|
setEnv()
|
||||||
sendEmail()
|
sendEmail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
README.md
47
README.md
|
@ -1,18 +1,49 @@
|
||||||
# Hedera
|
# Hedera
|
||||||
|
|
||||||
Hedera is the main web page for Verdnatura.
|
Hedera is the main web shop page for Verdnatura.
|
||||||
|
|
||||||
## Getting Started
|
## Prerequisites
|
||||||
|
|
||||||
Required dependencies.
|
Required applications.
|
||||||
* PHP >= 7.0
|
* PHP >= 8.4
|
||||||
* Node.js >= 8.0
|
* Node.js >= 20.0
|
||||||
|
|
||||||
Launch application for development.
|
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.
|
||||||
```
|
```
|
||||||
$ npm run dev
|
$ npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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.
|
Run server side method from command line.
|
||||||
```
|
```
|
||||||
$ php hedera-web.php -m method_path
|
$ php hedera-web.php -m method_path
|
||||||
|
@ -20,6 +51,8 @@ $ php hedera-web.php -m method_path
|
||||||
|
|
||||||
## Built with
|
## Built with
|
||||||
|
|
||||||
|
* [nodejs](https://nodejs.org/)
|
||||||
|
* [php](https://www.php.net/)
|
||||||
* [Webpack](https://webpack.js.org/)
|
* [Webpack](https://webpack.js.org/)
|
||||||
* [MooTools](https://mootools.net/)
|
* [MooTools](https://mootools.net/)
|
||||||
* [TinyMCE](https://www.tinymce.com/)
|
* [TinyMCE](https://www.tinymce.com/)
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
*
|
*
|
||||||
* - http://www.mydomain.org -> config.www.php
|
* - http://www.mydomain.org -> config.www.php
|
||||||
* - http://test.mydomain.org -> config.test.php
|
* - http://test.mydomain.org -> config.test.php
|
||||||
|
*
|
||||||
|
* Put the password in base64.
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +24,7 @@ return [
|
||||||
,'port' => 3306
|
,'port' => 3306
|
||||||
,'schema' => 'hedera'
|
,'schema' => 'hedera'
|
||||||
,'user' => 'hedera-web'
|
,'user' => 'hedera-web'
|
||||||
,'pass' => ''
|
,'pass' => '' // base64 encoded
|
||||||
,'tz' => 'Europe/madrid'
|
,'tz' => 'Europe/madrid'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
hedera-web (22.48.2) stable; urgency=low
|
hedera-web (24.14.8) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ Vcs-Git: https://gitea.verdnatura.es/verdnatura/hedera-web
|
||||||
Package: hedera-web
|
Package: hedera-web
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: apache2 | httpd, nodejs, php-cli, php-vn-lib, php-apcu, php-imap, php-soap, libphp-phpmailer, php-gd, php-pear
|
Depends: apache2 | httpd, nodejs, php-cli, php-vn-lib, php-apcu, php-imap, php-soap, libphp-phpmailer, php-gd, php-pear
|
||||||
Suggests: php-text-captcha, php-zip, cron
|
Suggests: php-image-text, php-text-captcha, php-zip, cron
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Description: Verdnatura's web page
|
Description: Verdnatura's web page
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
MAILTO=webmaster
|
MAILTO=webmaster
|
||||||
*/1 * * * * root hedera-web.php -m misc/mail
|
*/1 * * * * root hedera-web.php -m misc/mail
|
||||||
*/4 * * * * root hedera-web.php -m tpv/confirm-mail
|
|
||||||
*/2 * * * * root hedera-web.php -m edi/load
|
*/2 * * * * root hedera-web.php -m edi/load
|
||||||
0 23 * * * root hedera-web.php -m edi/clean
|
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 edi/update
|
||||||
0 5 * * * root hedera-web.php -m misc/exchange-rate
|
|
||||||
0 0 * * * root hedera-web.php -m image/sync
|
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/image-clean.sh > /dev/null
|
||||||
0 */1 * * * root /usr/share/hedera-web/utils/update-browscap.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
|
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/apache.conf etc/apache2/conf-available/hedera-web.conf
|
||||||
etc/hedera-web/php.ini etc/php/7.0/apache2/conf.d/99-hedera-web.ini
|
etc/hedera-web/php.ini etc/php/8.2/apache2/conf.d/99-hedera-web.ini
|
|
@ -1,41 +1,12 @@
|
||||||
version: '3.7'
|
version: '3.7'
|
||||||
services:
|
services:
|
||||||
main:
|
main:
|
||||||
image: registry.verdnatura.es/hedera-web:${BRANCH_NAME:?}
|
image: registry.verdnatura.es/hedera-web:${VERSION:?}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
- VERSION=${VERSION:?}
|
- 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:
|
cron:
|
||||||
image: registry.verdnatura.es/hedera-web:${BRANCH_NAME:?}
|
image: registry.verdnatura.es/hedera-web:${VERSION:?}
|
||||||
command: 'cron -f'
|
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-way="true"
|
||||||
one-time="true">
|
one-time="true">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT id, country FROM vn.country
|
SELECT id, name FROM vn.country
|
||||||
ORDER BY country
|
ORDER BY name
|
||||||
</db-model>
|
</db-model>
|
||||||
</htk-combo>
|
</htk-combo>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,70 +7,7 @@ export default new Class({
|
||||||
activate() {
|
activate() {
|
||||||
this.$.userModel.setInfo('c', 'myClient', 'hedera');
|
this.$.userModel.setInfo('c', 'myClient', 'hedera');
|
||||||
this.$.userModel.setInfo('u', 'myUser', 'account');
|
this.$.userModel.setInfo('u', 'myUser', 'account');
|
||||||
|
this.$.changePassword.conn = this.conn
|
||||||
if (this.hash.$.verificationToken)
|
this.$.changePassword.user = this.gui.user
|
||||||
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() {
|
|
||||||
var oldPassword = this.$.oldPassword.value;
|
|
||||||
var newPassword = this.$.newPassword.value;
|
|
||||||
var repeatedPassword = this.$.repeatPassword.value;
|
|
||||||
|
|
||||||
if (newPassword == '' && repeatedPassword == '')
|
|
||||||
throw new Error(_('Passwords empty'));
|
|
||||||
if (newPassword !== repeatedPassword)
|
|
||||||
throw new Error(_('Passwords doesn\'t match'));
|
|
||||||
|
|
||||||
var verificationToken = this.hash.$.verificationToken;
|
|
||||||
var params = {newPassword};
|
|
||||||
|
|
||||||
let err;
|
|
||||||
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(e) {
|
|
||||||
err = e;
|
|
||||||
Htk.Toast.showError(err.message);
|
|
||||||
|
|
||||||
if (this.hash.$.verificationToken)
|
|
||||||
this.$.newPassword.select();
|
|
||||||
else
|
|
||||||
this.$.oldPassword.select();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$.changePassword.hide();
|
|
||||||
this.hash.unset('verificationToken');
|
|
||||||
Htk.Toast.showMessage(_('Password changed!'));
|
|
||||||
this.$.userForm.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassInfoClick() {
|
|
||||||
this.$.passwordInfo.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<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-form id="user-form">
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
<db-model property="model" id="user-model" updatable="true">
|
||||||
SELECT u.id, u.name, u.email, u.nickname,
|
SELECT u.id, u.name, u.email, u.nickname,
|
||||||
|
@ -27,7 +21,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="lock_reset"
|
icon="lock_reset"
|
||||||
tip="_Change password"
|
tip="_Change password"
|
||||||
on-click="this.onPassChangeClick()"/>
|
on-click="this.$.changePassword.open()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="conf">
|
<div id="form" class="conf">
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
|
@ -74,62 +68,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<htk-popup
|
<htk-change-password id="change-password"/>
|
||||||
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"/>
|
|
||||||
<input
|
|
||||||
id="repeat-password"
|
|
||||||
type="password"
|
|
||||||
placeholder="_Repeat 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>
|
</vn>
|
||||||
|
|
|
@ -7,8 +7,8 @@ export default new Class({
|
||||||
,activate() {
|
,activate() {
|
||||||
if (!this.hash.$.to)
|
if (!this.hash.$.to)
|
||||||
this.hash.assign({
|
this.hash.assign({
|
||||||
from: new Date(),
|
from: Date.vnNew(),
|
||||||
to: new Date()
|
to: Date.vnNew()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,12 +3,5 @@ import './style.scss';
|
||||||
export default new Class({
|
export default new Class({
|
||||||
Extends: Hedera.Form,
|
Extends: Hedera.Form,
|
||||||
Template: require('./ui.xml'),
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
onShowClick(column, agencyId) {
|
|
||||||
this.hash.setAll({
|
|
||||||
form: 'agencies/provinces',
|
|
||||||
agency: agencyId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Paquets per agència
|
ListByAgency: Paquets per agència
|
||||||
ShowByProvince: Mostrar desglose per província
|
|
||||||
Agency: Agència
|
Agency: Agència
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Paquets
|
Bundles: Paquets
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bundles by agency
|
ListByAgency: Bundles by agency
|
||||||
ShowByProvince: Show breakdown by province
|
|
||||||
Agency: Agency
|
Agency: Agency
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bundles
|
Bundles: Bundles
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bultos por agencia
|
ListByAgency: Bultos por agencia
|
||||||
ShowByProvince: Mostrar desglose por provincia
|
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bultos
|
Bundles: Bultos
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Liste par agence
|
ListByAgency: Liste par agence
|
||||||
ShowByProvince: Montrer par province
|
|
||||||
Agency: Agence
|
Agency: Agence
|
||||||
Exps: Expéditeur
|
Exps: Expéditeur
|
||||||
Bundles: Cartons
|
Bundles: Cartons
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bultos por agencia
|
ListByAgency: Bultos por agencia
|
||||||
ShowByProvince: Mostrar desglosse por Distrito
|
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bultos
|
Bundles: Bultos
|
||||||
|
|
|
@ -7,14 +7,9 @@
|
||||||
<htk-grid>
|
<htk-grid>
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
<custom>
|
<custom>
|
||||||
CALL vn2008.agencia_volume ()
|
CALL vn.agencyVolume()
|
||||||
</custom>
|
</custom>
|
||||||
</db-model>
|
</db-model>
|
||||||
<htk-column-button
|
|
||||||
column="agency_id"
|
|
||||||
icon="search"
|
|
||||||
tip="_ShowByProvince"
|
|
||||||
on-clicked="onShowClick"/>
|
|
||||||
<htk-column-text title="_Agency" column="Agencia"/>
|
<htk-column-text title="_Agency" column="Agencia"/>
|
||||||
<htk-column-spin title="_Exps" column="expediciones"/>
|
<htk-column-spin title="_Exps" column="expediciones"/>
|
||||||
<htk-column-spin title="_Bundles" column="Bultos"/>
|
<htk-column-spin title="_Bundles" column="Bultos"/>
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
ByProvince: Desglose per província
|
|
||||||
Return: Tornar
|
|
||||||
SelectAgency: Selecciona una agència al llistat de l'esquerra
|
|
||||||
Province: Província
|
|
||||||
Expeditions: Exps.
|
|
||||||
Left: Falten
|
|
|
@ -1,6 +0,0 @@
|
||||||
ByProvince: Breakdown by province
|
|
||||||
Return: Return
|
|
||||||
SelectAgency: Select an agency
|
|
||||||
Province: Province
|
|
||||||
Expeditions: Exps.
|
|
||||||
Left: Left
|
|
|
@ -1,6 +0,0 @@
|
||||||
ByProvince: Desglose por provincia
|
|
||||||
Return: Volver
|
|
||||||
SelectAgency: Selecciona una agencia
|
|
||||||
Province: Provincia
|
|
||||||
Expeditions: Exps.
|
|
||||||
Left: Faltan
|
|
|
@ -1,6 +0,0 @@
|
||||||
ByProvince: Par province
|
|
||||||
Return: Retour
|
|
||||||
SelectAgency: Sélectionnez une agence
|
|
||||||
Province: Province
|
|
||||||
Expeditions: Expéditions
|
|
||||||
Left: Restant
|
|
|
@ -1,6 +0,0 @@
|
||||||
ByProvince: Desglosse por Distritos
|
|
||||||
Return: Voltar
|
|
||||||
SelectAgency: Seleccione uma agência
|
|
||||||
Province: Distrito
|
|
||||||
Expeditions: Exps.
|
|
||||||
Left: Faltam
|
|
|
@ -1,18 +0,0 @@
|
||||||
<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() {
|
,refreshCaptcha() {
|
||||||
params = {
|
params = {
|
||||||
srv: 'rest:misc/captcha',
|
srv: 'rest:misc/captcha',
|
||||||
stamp: new Date().getTime()
|
stamp: Date.vnNew().getTime()
|
||||||
};
|
};
|
||||||
this.$.captchaImg.src = '?'+ Vn.Url.makeUri(params);
|
this.$.captchaImg.src = '?'+ Vn.Url.makeUri(params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ BecauseOurSalesDep: >-
|
||||||
Pour nos professionnels de service commercial qui sera toujours de trouver une
|
Pour nos professionnels de service commercial qui sera toujours de trouver une
|
||||||
solution à vos besoins.
|
solution à vos besoins.
|
||||||
BecauseOurWorkShop: Parce que nous avons un atelier de couture pour aider.
|
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: >-
|
AboutDesc: >-
|
||||||
Nous sommes une société spécialisée dans le commerce de gros et de la
|
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
|
distribution d'une large gamme d'accessoires, des verts et des fleurs à des
|
||||||
|
@ -31,6 +32,6 @@ AboutDisp: >-
|
||||||
Mercaflor - Mercavalencia (Valencia) qui effectuent des ventes directes
|
Mercaflor - Mercavalencia (Valencia) qui effectuent des ventes directes
|
||||||
seulement.
|
seulement.
|
||||||
AboutOrder: >-
|
AboutOrder: >-
|
||||||
Vous pouvez faire vos commandes et réservations par téléphone au +33 781 533
|
Vous pouvez faire vos commandes et réservations par téléphone au +33 783 285
|
||||||
900, en ligne grâce à notre site Internet ou directement dans nos
|
437, en ligne grâce à notre site Internet ou directement dans nos
|
||||||
installations.
|
installations.
|
||||||
|
|
|
@ -5,17 +5,64 @@ export default new Class({
|
||||||
Template: require('./ui.xml'),
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
async open() {
|
async open() {
|
||||||
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
await this.loadOrder();
|
||||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
if (this.orderId) {
|
||||||
|
await Hedera.Form.prototype.open.call(this);
|
||||||
|
this.$.lot.assign({id: this.orderId});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.$.items.setInfo('bi', 'myBasketItem', 'hedera');
|
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() {
|
onConfigureClick() {
|
||||||
Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
|
Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
|
||||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
this.hash.setAll({
|
||||||
|
form: 'ecomerce/checkout',
|
||||||
|
id: this.orderId
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async onCatalogClick() {
|
||||||
|
const basket = new Hedera.Basket(this.app);
|
||||||
|
await basket.load(this.orderId);
|
||||||
|
},
|
||||||
|
|
||||||
|
onConfirmClick() {
|
||||||
|
this.hash.setAll({
|
||||||
|
form: 'ecomerce/confirm',
|
||||||
|
id: this.orderId
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onDeleteClick(form) {
|
onDeleteClick(form) {
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
ShoppingBasket: Cistella de la compra
|
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
|
Delete: Borrar encàrrec
|
||||||
GoToCatalog: Anar al catàleg
|
GoToCatalog: Anar al catàleg
|
||||||
ConfigureOrder: Configurar encàrrec
|
ConfigureOrder: Configurar encàrrec
|
||||||
Checkout: Tramitar encàrrec
|
Checkout: Tramitar encàrrec
|
||||||
OrderNumber: N encàrec
|
OrderNumber: N encàrec
|
||||||
DateExit: Data d'eixida
|
DateExit: Data d'eixida
|
||||||
Warehouse: Magatzem
|
|
||||||
OrderTotal: Total encàrrec
|
OrderTotal: Total encàrrec
|
||||||
Amount: Quant
|
Amount: Quant
|
||||||
Pack: Pack
|
Pack: Pack
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
ShoppingBasket: Shopping basket
|
ShoppingBasket: Shopping basket
|
||||||
|
Order: Order
|
||||||
|
ShippingInformation: Shipping information
|
||||||
|
DeliveryAddress: Delivery address
|
||||||
|
Delivery at: Delivery at
|
||||||
|
Agency: Agency
|
||||||
|
Warehouse: Store
|
||||||
Delete: Delete order
|
Delete: Delete order
|
||||||
GoToCatalog: Go to catalog
|
GoToCatalog: Go to catalog
|
||||||
ConfigureOrder: Configure order
|
ConfigureOrder: Configure order
|
||||||
Checkout: Checkout
|
Checkout: Checkout
|
||||||
OrderNumber: Order number
|
OrderNumber: Order number
|
||||||
DateExit: Shipping date
|
DateExit: Shipping date
|
||||||
Warehouse: Store
|
|
||||||
OrderTotal: Total
|
OrderTotal: Total
|
||||||
Amount: Amount
|
Amount: Amount
|
||||||
Pack: Pack
|
Pack: Pack
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
ShoppingBasket: Cesta de la compra
|
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
|
Delete: Borrar pedido
|
||||||
GoToCatalog: Ir al catálogo
|
GoToCatalog: Ir al catálogo
|
||||||
ConfigureOrder: Configurar pedido
|
ConfigureOrder: Configurar pedido
|
||||||
Checkout: Finalizar pedido
|
Checkout: Finalizar pedido
|
||||||
OrderNumber: Nº pedido
|
OrderNumber: Nº pedido
|
||||||
DateExit: Fecha de salida
|
DateExit: Fecha de salida
|
||||||
Warehouse: Almacén
|
|
||||||
OrderTotal: Total
|
OrderTotal: Total
|
||||||
Amount: Cantidad
|
Amount: Cantidad
|
||||||
Pack: Pack
|
Pack: Pack
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
ShoppingBasket: Panier
|
ShoppingBasket: Panier
|
||||||
|
Order: Commande
|
||||||
|
ShippingInformation: Informations sur la livraison
|
||||||
|
DeliveryAddress: Addresse de livraison
|
||||||
|
Delivery at: Livraison à
|
||||||
|
Agency: Agence
|
||||||
|
Warehouse: Entrepôt
|
||||||
Delete: Effacer
|
Delete: Effacer
|
||||||
GoToCatalog: Aller au catalogue
|
GoToCatalog: Aller au catalogue
|
||||||
ConfigureOrder: Définissez l'ordre
|
ConfigureOrder: Définissez l'ordre
|
||||||
Checkout: Caisse
|
Checkout: Caisse
|
||||||
OrderNumber: Numéro de commande
|
OrderNumber: Numéro de commande
|
||||||
DateExit: Date de sortie
|
DateExit: Date de sortie
|
||||||
Warehouse: Magasin
|
|
||||||
OrderTotal: Total commande
|
OrderTotal: Total commande
|
||||||
Amount: Quant
|
Amount: Quant
|
||||||
Pack: Pack
|
Pack: Pack
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
ShoppingBasket: Cesta da compra
|
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
|
Delete: Eliminar encomenda
|
||||||
GoToCatalog: Ir ao catálogo
|
GoToCatalog: Ir ao catálogo
|
||||||
ConfigureOrder: Configurar encomenda
|
ConfigureOrder: Configurar encomenda
|
||||||
Checkout: Finalizar encomenda
|
Checkout: Finalizar encomenda
|
||||||
OrderNumber: Nº encomenda
|
OrderNumber: Nº encomenda
|
||||||
DateExit: Data de saída
|
DateExit: Data de saída
|
||||||
Warehouse: Armazém
|
|
||||||
OrderTotal: Total
|
OrderTotal: Total
|
||||||
Amount: Quantidade
|
Amount: Quantidade
|
||||||
Pack: Pack
|
Pack: Pack
|
||||||
|
|
|
@ -1,76 +1,93 @@
|
||||||
|
|
||||||
.basket .head {
|
.hedera-basket {
|
||||||
border-bottom: 1px solid #DDD;
|
.head {
|
||||||
}
|
border-bottom: 1px solid #DDD;
|
||||||
.basket .head p {
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.basket .form > p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
color: white;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lines */
|
& > div > div {
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
& > div > div:first-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 3px 0;
|
||||||
|
|
||||||
.basket .line {
|
&.important {
|
||||||
display: flex;
|
font-size: 1.2rem;
|
||||||
align-items: center;
|
font-weight: bold;
|
||||||
gap: 12px;
|
}
|
||||||
margin: 10px 0;
|
}
|
||||||
height: 80px;
|
.total {
|
||||||
}
|
|
||||||
.basket .line:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
.basket .line:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.basket .line > .delete {
|
|
||||||
margin: 0 -8px;
|
|
||||||
}
|
|
||||||
.basket .line > .photo {
|
|
||||||
flex: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 68px;
|
|
||||||
height: 68px;
|
|
||||||
gap: 0;
|
|
||||||
}
|
|
||||||
.basket .line > .info {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.basket .line > .info > * {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.basket .line > .info > h2 {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.basket .line > .info > p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.basket .line > .info > .tags {
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
.basket .line .subtotal {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fields */
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form > p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: white;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.basket td.available-exceeded input {
|
/* Lines */
|
||||||
background-color: #FCC;
|
|
||||||
}
|
|
||||||
.basket .icon > img {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.line {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 10px 0;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
.line:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.line:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.line > .delete {
|
||||||
|
margin: 0 -8px;
|
||||||
|
}
|
||||||
|
.line > .photo {
|
||||||
|
flex: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 68px;
|
||||||
|
height: 68px;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
.line > .info {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.line > .info > * {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.line > .info > h2 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.line > .info > p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.line > .info > .tags {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
.line .subtotal {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fields */
|
||||||
|
|
||||||
|
td.available-exceeded input {
|
||||||
|
background-color: #FCC;
|
||||||
|
}
|
||||||
|
.icon > img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vn>
|
<vn>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>ShoppingBasket</t></h1>
|
<h1>{{_(params.$.id ? 'Order' : 'ShoppingBasket')}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions">
|
<div id="actions">
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
|
@ -8,18 +8,52 @@
|
||||||
tip="_ConfigureOrder"
|
tip="_ConfigureOrder"
|
||||||
on-click="this.onConfigureClick()"/>
|
on-click="this.onConfigureClick()"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="local_florist"
|
icon="shopping_bag"
|
||||||
tip="_Catalog"
|
tip="_Catalog"
|
||||||
on-click="this.hash.setAll({form: 'ecomerce/catalog'})"/>
|
on-click="this.onCatalogClick()"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="shopping_cart_checkout"
|
icon="shopping_cart_checkout"
|
||||||
tip="_Checkout"
|
tip="_Checkout"
|
||||||
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/>
|
on-click="this.onConfirmClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="basket">
|
<vn-group>
|
||||||
|
<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-model property="model" lot="lot">
|
||||||
|
SELECT o.id, o.sent,
|
||||||
|
ag.description agency, v.code method,
|
||||||
|
ad.nickname, ad.postalCode, ad.city, ad.street
|
||||||
|
FROM myOrder o
|
||||||
|
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
||||||
|
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||||
|
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
|
||||||
|
WHERE o.id = #id;
|
||||||
|
</db-model>
|
||||||
|
</db-form>
|
||||||
|
</vn-group>
|
||||||
|
<div id="form" class="hedera-basket">
|
||||||
<div class="box vn-w-sm vn-pa-lg">
|
<div class="box vn-w-sm vn-pa-lg">
|
||||||
<div class="head vn-pb-lg">
|
<div class="head vn-pb-lg">
|
||||||
<p>
|
<h5>#{{order.id}}</h5>
|
||||||
|
<div class="delivery">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
<p class="total">
|
||||||
<t>Total</t>
|
<t>Total</t>
|
||||||
<htk-text format="%.2d€">
|
<htk-text format="%.2d€">
|
||||||
<db-calc-sum property="param" func="subtotal" model="items"/>
|
<db-calc-sum property="param" func="subtotal" model="items"/>
|
||||||
|
@ -28,15 +62,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="lines vn-pt-lg">
|
<div class="lines vn-pt-lg">
|
||||||
<htk-repeater form-id="iter">
|
<htk-repeater form-id="iter">
|
||||||
<db-model id="items" property="model" updatable="true">
|
<db-model id="items" property="model" lot="lot" updatable="true">
|
||||||
SELECT bi.id, bi.amount, bi.price, i.longName item,
|
SELECT bi.id, bi.amount, bi.price, i.longName item,
|
||||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
||||||
i.image, im.updated
|
i.image, im.updated
|
||||||
FROM myBasketItem bi
|
FROM myOrderRow bi
|
||||||
JOIN vn.item i ON i.id = bi.itemFk
|
JOIN vn.item i ON i.id = bi.itemFk
|
||||||
LEFT JOIN image im
|
LEFT JOIN image im
|
||||||
ON im.collectionFk = 'catalog'
|
ON im.collectionFk = 'catalog'
|
||||||
AND im.name = i.image
|
AND im.name = i.image
|
||||||
|
WHERE orderFk = #id
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<div class="line">
|
<div class="line">
|
||||||
|
|
|
@ -7,19 +7,27 @@ const Catalog = new Class({
|
||||||
,_menuShown: false
|
,_menuShown: false
|
||||||
|
|
||||||
,async open() {
|
,async open() {
|
||||||
let isOk = true;
|
const basket = new Hedera.Basket(this.app);
|
||||||
|
|
||||||
if (!localStorage.getItem('hederaGuest'))
|
if (!localStorage.getItem('hederaGuest')) {
|
||||||
isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
if (await basket.check('catalog'))
|
||||||
else
|
this.orderId = basket.orderId;
|
||||||
await this.conn.execQuery('CALL mybasket_configureForGuest');
|
} else {
|
||||||
|
const resultSet = await this.conn.execQuery(
|
||||||
|
'CALL myOrder_configureForGuest(@orderId); SELECT @orderId;');
|
||||||
|
|
||||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
resultSet.fetchResult();
|
||||||
|
this.orderId = resultSet.fetchValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.orderId)
|
||||||
|
await Hedera.Form.prototype.open.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
,activate() {
|
,activate() {
|
||||||
document.body.appendChild(this.$.rightPanel);
|
document.body.appendChild(this.$.rightPanel);
|
||||||
this.$.items.setInfo('i', 'item', 'vn', ['id']);
|
this.$.items.setInfo('i', 'item', 'vn', ['id']);
|
||||||
|
this.$.orderLot.assign({orderId: this.orderId});
|
||||||
|
|
||||||
if (localStorage.getItem('hederaView'))
|
if (localStorage.getItem('hederaView'))
|
||||||
this.setView(parseInt(localStorage.getItem('hederaView')));
|
this.setView(parseInt(localStorage.getItem('hederaView')));
|
||||||
|
@ -98,6 +106,7 @@ const Catalog = new Class({
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.orderId = this.orderId;
|
||||||
const refreshItems = hasTagFilter
|
const refreshItems = hasTagFilter
|
||||||
|| params.search != null
|
|| params.search != null
|
||||||
|| params.type != null;
|
|| params.type != null;
|
||||||
|
@ -193,6 +202,12 @@ const Catalog = new Class({
|
||||||
|
|
||||||
this.hideMenu();
|
this.hideMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
,itemRenderer(builder, form) {
|
||||||
|
var minQuantity = builder.$.minQuantity;
|
||||||
|
minQuantity.style.display = form.$.minQuantity
|
||||||
|
? 'block' : 'hidden';
|
||||||
|
}
|
||||||
|
|
||||||
,realmRenderer(builder, form) {
|
,realmRenderer(builder, form) {
|
||||||
var link = builder.$.link;
|
var link = builder.$.link;
|
||||||
|
@ -245,7 +260,11 @@ const Catalog = new Class({
|
||||||
if (this.isGuest())
|
if (this.isGuest())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
this.hash.setAll({
|
||||||
|
form: 'ecomerce/checkout',
|
||||||
|
id: this.orderId,
|
||||||
|
continue: 'catalog'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
,onAddItemClick(event, form) {
|
,onAddItemClick(event, form) {
|
||||||
|
@ -255,8 +274,13 @@ const Catalog = new Class({
|
||||||
|
|
||||||
this.onEraseClick();
|
this.onEraseClick();
|
||||||
this.$.$card.row = form.row;
|
this.$.$card.row = form.row;
|
||||||
this.$.cardLot.assign({item: form.$.id});
|
this.$.cardLot.assign({
|
||||||
|
item: form.$.id,
|
||||||
|
orderId: this.orderId
|
||||||
|
});
|
||||||
this.$.cardPopup.show(event.currentTarget);
|
this.$.cardPopup.show(event.currentTarget);
|
||||||
|
this.$.cardMinQuantity.style.display = form.$.minQuantity
|
||||||
|
? 'block' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
,onAddLotClick(column, value, row) {
|
,onAddLotClick(column, value, row) {
|
||||||
|
@ -284,7 +308,7 @@ const Catalog = new Class({
|
||||||
|
|
||||||
,async onConfirmClick() {
|
,async onConfirmClick() {
|
||||||
var sql = '';
|
var sql = '';
|
||||||
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
|
var query = new Sql.String({query: 'CALL myOrder_addItem(#orderId, #warehouse, #item, #amount);'});
|
||||||
var amountSum = 0;
|
var amountSum = 0;
|
||||||
|
|
||||||
for (var warehouse in this.items) {
|
for (var warehouse in this.items) {
|
||||||
|
@ -292,6 +316,7 @@ const Catalog = new Class({
|
||||||
amountSum += amount;
|
amountSum += amount;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
|
orderId: this.orderId,
|
||||||
warehouse: warehouse,
|
warehouse: warehouse,
|
||||||
item: this.$.cardLot.$.item,
|
item: this.$.cardLot.$.item,
|
||||||
amount: amount
|
amount: amount
|
||||||
|
@ -300,7 +325,7 @@ const Catalog = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amountSum > 0) {
|
if (amountSum > 0) {
|
||||||
this.conn.execQuery(sql);
|
await this.conn.execQuery(sql);
|
||||||
|
|
||||||
var itemName = this.$.$card.get('item');
|
var itemName = this.$.$card.get('item');
|
||||||
Htk.Toast.showMessage(
|
Htk.Toast.showMessage(
|
||||||
|
|
|
@ -46,3 +46,4 @@ NoMoreAmountAvailable: No hi ha més quantitat disponible
|
||||||
MinimalGrouping: Empaquetat mínim
|
MinimalGrouping: Empaquetat mínim
|
||||||
Available: Disponible
|
Available: Disponible
|
||||||
GroupingPrice: Preu per grup
|
GroupingPrice: Preu per grup
|
||||||
|
MinimalQuantity: Quantitat mínima
|
||||||
|
|
|
@ -46,3 +46,4 @@ NoMoreAmountAvailable: No more amount available
|
||||||
MinimalGrouping: Minimal packing
|
MinimalGrouping: Minimal packing
|
||||||
Available: Available
|
Available: Available
|
||||||
GroupingPrice: Price per group
|
GroupingPrice: Price per group
|
||||||
|
MinimalQuantity: Minimal quantity
|
||||||
|
|
|
@ -46,3 +46,4 @@ NoMoreAmountAvailable: No hay más cantidad disponible
|
||||||
MinimalGrouping: Empaquetado mínimo
|
MinimalGrouping: Empaquetado mínimo
|
||||||
Available: Disponible
|
Available: Disponible
|
||||||
GroupingPrice: Precio per grupo
|
GroupingPrice: Precio per grupo
|
||||||
|
MinimalQuantity: Cantidad mínima
|
||||||
|
|
|
@ -46,3 +46,4 @@ NoMoreAmountAvailable: Pas plus disponible
|
||||||
MinimalGrouping: Emballage minimal
|
MinimalGrouping: Emballage minimal
|
||||||
Available: Disponible
|
Available: Disponible
|
||||||
GroupingPrice: Prix par groupe
|
GroupingPrice: Prix par groupe
|
||||||
|
MinimalQuantity: Quantité minimum
|
||||||
|
|
|
@ -46,3 +46,4 @@ NoMoreAmountAvailable: Não há mais quantidade disponível
|
||||||
MinimalGrouping: Embalagem mínima
|
MinimalGrouping: Embalagem mínima
|
||||||
Available: Disponível
|
Available: Disponível
|
||||||
GroupingPrice: Preço por grupo
|
GroupingPrice: Preço por grupo
|
||||||
|
MinimalQuantity: Quantidade mínima
|
||||||
|
|
|
@ -192,6 +192,25 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 1px;
|
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 */
|
/* Tags */
|
||||||
|
@ -256,7 +275,7 @@
|
||||||
}
|
}
|
||||||
& > .htk-image {
|
& > .htk-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 180px;
|
height: 210px;
|
||||||
|
|
||||||
& > img {
|
& > img {
|
||||||
height: initial;
|
height: initial;
|
||||||
|
@ -266,7 +285,7 @@
|
||||||
flex: auto;
|
flex: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
height: 170px;
|
height: 185px;
|
||||||
|
|
||||||
& > h2 {
|
& > h2 {
|
||||||
max-height: 3rem;
|
max-height: 3rem;
|
||||||
|
@ -351,6 +370,7 @@
|
||||||
|
|
||||||
& > .top {
|
& > .top {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
& > .item-info {
|
& > .item-info {
|
||||||
margin-left: 126px;
|
margin-left: 126px;
|
||||||
|
@ -371,6 +391,11 @@
|
||||||
margin-top: 15px 0;
|
margin-top: 15px 0;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
|
& > .min-quantity {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
& > .lots-grid {
|
& > .lots-grid {
|
||||||
border-top: 1px solid #DDD;
|
border-top: 1px solid #DDD;
|
||||||
|
|
|
@ -91,12 +91,13 @@
|
||||||
param="producer"/>
|
param="producer"/>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
|
<vn-lot id="order-lot"/>
|
||||||
<db-form v-model="basket">
|
<db-form v-model="basket">
|
||||||
<db-model property="model">
|
<db-model property="model" lot="order-lot">
|
||||||
SELECT b.id, b.sent, a.description agency, m.code method
|
SELECT o.id, o.sent, ad.nickname
|
||||||
FROM myBasket b
|
FROM myOrder o
|
||||||
JOIN vn.agencyMode a ON a.id = b.agencyModeFk
|
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||||
JOIN vn.deliveryMethod m ON m.id = b.deliveryMethodFk
|
WHERE o.id = #orderId
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-model
|
<db-model
|
||||||
|
@ -104,18 +105,18 @@
|
||||||
auto-load="false"
|
auto-load="false"
|
||||||
result-index="3"
|
result-index="3"
|
||||||
on-status-changed="onItemsChange">
|
on-status-changed="onItemsChange">
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.item;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.item
|
||||||
CREATE TEMPORARY TABLE tmp.item
|
|
||||||
(INDEX (itemFk))
|
(INDEX (itemFk))
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT i.id itemFk
|
SELECT i.id itemFk
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
WHERE #filter;
|
WHERE #filter;
|
||||||
CALL myBasket_calcCatalogFull;
|
CALL myOrder_calcCatalogFull(#orderId);
|
||||||
SELECT i.id, i.longName item, i.subName,
|
SELECT i.id, i.longName item, i.subName,
|
||||||
i.tag5, i.value5, i.tag6, i.value6, i.tag7, i.value7,
|
i.tag5, i.value5, i.tag6, i.value6,
|
||||||
i.relevancy, i.size, i.category,
|
i.tag7, i.value7, i.tag8, i.value8,
|
||||||
|
i.relevancy, i.size, i.category, b.minQuantity,
|
||||||
k.name ink, p.name producer, o.name origin,
|
k.name ink, p.name producer, o.name origin,
|
||||||
b.available, b.price, b.`grouping`,
|
b.available, b.price, b.`grouping`,
|
||||||
i.image, im.updated
|
i.image, im.updated
|
||||||
|
@ -124,19 +125,13 @@
|
||||||
LEFT JOIN vn.ink k ON k.id = i.inkFk
|
LEFT JOIN vn.ink k ON k.id = i.inkFk
|
||||||
LEFT JOIN vn.producer p ON p.id = i.producerFk
|
LEFT JOIN vn.producer p ON p.id = i.producerFk
|
||||||
LEFT JOIN vn.origin o ON o.id = i.originFk
|
LEFT JOIN vn.origin o ON o.id = i.originFk
|
||||||
LEFT JOIN image im
|
LEFT JOIN image im ON im.collectionFk = 'catalog'
|
||||||
ON im.collectionFk = 'catalog'
|
|
||||||
AND im.name = i.image
|
AND im.name = i.image
|
||||||
WHERE b.available > 0
|
WHERE b.available > 0
|
||||||
ORDER BY i.relevancy DESC, i.name, i.size
|
ORDER BY i.relevancy DESC, i.name, i.size
|
||||||
LIMIT 5000;
|
LIMIT 5000;
|
||||||
DROP TEMPORARY TABLE
|
DROP TEMPORARY TABLE tmp.item;
|
||||||
tmp.item,
|
CALL vn.ticketCalculatePurge();
|
||||||
tmp.ticketCalculateItem,
|
|
||||||
tmp.ticketComponentPrice,
|
|
||||||
tmp.ticketComponent,
|
|
||||||
tmp.ticketLot,
|
|
||||||
tmp.zoneGetShipped;
|
|
||||||
</db-model>
|
</db-model>
|
||||||
<db-form id="$card" v-model="card" model="items"/>
|
<db-form id="$card" v-model="card" model="items"/>
|
||||||
<vn-lot id="card-lot"/>
|
<vn-lot id="card-lot"/>
|
||||||
|
@ -147,7 +142,8 @@
|
||||||
id="grid-view"
|
id="grid-view"
|
||||||
empty-message="_Choose filter from right menu"
|
empty-message="_Choose filter from right menu"
|
||||||
form-id="item"
|
form-id="item"
|
||||||
model="items">
|
model="items"
|
||||||
|
renderer="itemRenderer">
|
||||||
<custom>
|
<custom>
|
||||||
<div
|
<div
|
||||||
id="item-box"
|
id="item-box"
|
||||||
|
@ -185,6 +181,10 @@
|
||||||
<td>{{item.tag7}}</td>
|
<td>{{item.tag7}}</td>
|
||||||
<td>{{item.value7}}</td>
|
<td>{{item.value7}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{item.tag8}}</td>
|
||||||
|
<td>{{item.value8}}</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div class="available-price">
|
<div class="available-price">
|
||||||
<span class="grouping" title="_MinimalGrouping">
|
<span class="grouping" title="_MinimalGrouping">
|
||||||
|
@ -197,6 +197,12 @@
|
||||||
{{Vn.Value.format(item.price, '%.02d€')}}
|
{{Vn.Value.format(item.price, '%.02d€')}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
</custom>
|
||||||
|
@ -205,11 +211,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="right-panel" class="catalog-panel right-panel side-panel" on-click="onRightPanelClick">
|
<div id="right-panel" class="catalog-panel right-panel side-panel" on-click="onRightPanelClick">
|
||||||
<div class="basket-info">
|
<div class="basket-info">
|
||||||
|
<p>{{basket.nickname}}</p>
|
||||||
<p>{{Vn.Value.format(basket.sent, '%D')}}</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()">
|
<button class="thin" on-click="this.onConfigureClick()">
|
||||||
<t>Modify</t>
|
<t>Modify</t>
|
||||||
</button>
|
</button>
|
||||||
|
@ -261,7 +264,7 @@
|
||||||
lot="params"
|
lot="params"
|
||||||
result-index="1"
|
result-index="1"
|
||||||
on-status-changed="refreshTitle">
|
on-status-changed="refreshTitle">
|
||||||
CALL myBasket_getAvailable;
|
CALL myOrder_getAvailable(#orderId);
|
||||||
SELECT DISTINCT t.id, l.name
|
SELECT DISTINCT t.id, l.name
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
|
@ -283,7 +286,7 @@
|
||||||
property="model"
|
property="model"
|
||||||
auto-load="false"
|
auto-load="false"
|
||||||
result-index="1">
|
result-index="1">
|
||||||
CALL myBasket_getAvailable;
|
CALL myOrder_getAvailable(#orderId);
|
||||||
SELECT DISTINCT l.id, l.name
|
SELECT DISTINCT l.id, l.name
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
|
@ -304,7 +307,7 @@
|
||||||
property="model"
|
property="model"
|
||||||
auto-load="false"
|
auto-load="false"
|
||||||
result-index="1">
|
result-index="1">
|
||||||
CALL myBasket_getAvailable;
|
CALL myOrder_getAvailable(#orderId);
|
||||||
SELECT DISTINCT p.id, p.name
|
SELECT DISTINCT p.id, p.name
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
|
@ -325,7 +328,7 @@
|
||||||
property="model"
|
property="model"
|
||||||
auto-load="false"
|
auto-load="false"
|
||||||
result-index="1">
|
result-index="1">
|
||||||
CALL myBasket_getAvailable;
|
CALL myOrder_getAvailable(#orderId);
|
||||||
SELECT DISTINCT o.id, l.name, o.code
|
SELECT DISTINCT o.id, l.name, o.code
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
|
@ -347,7 +350,7 @@
|
||||||
property="model"
|
property="model"
|
||||||
auto-load="false"
|
auto-load="false"
|
||||||
result-index="1">
|
result-index="1">
|
||||||
CALL myBasket_getAvailable;
|
CALL myOrder_getAvailable(#orderId);
|
||||||
SELECT DISTINCT i.category, i.category
|
SELECT DISTINCT i.category, i.category
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType t ON t.id = i.typeFk
|
JOIN vn.itemType t ON t.id = i.typeFk
|
||||||
|
@ -458,6 +461,12 @@
|
||||||
</tr>
|
</tr>
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</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>
|
</div>
|
||||||
<htk-grid class="lots-grid" show-header="false">
|
<htk-grid class="lots-grid" show-header="false">
|
||||||
<db-model
|
<db-model
|
||||||
|
@ -466,7 +475,7 @@
|
||||||
result-index="1"
|
result-index="1"
|
||||||
on-status-changed-after="onCardLoad"
|
on-status-changed-after="onCardLoad"
|
||||||
lot="card-lot">
|
lot="card-lot">
|
||||||
CALL myBasket_calcCatalogFromItem(#item);
|
CALL myOrder_calcCatalogFromItem(#orderId, #item);
|
||||||
SELECT l.warehouseFk, w.name warehouse, p.`grouping`,
|
SELECT l.warehouseFk, w.name warehouse, p.`grouping`,
|
||||||
p.price, p.priceKg, p.rate, l.available
|
p.price, p.priceKg, p.rate, l.available
|
||||||
FROM tmp.ticketLot l
|
FROM tmp.ticketLot l
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default new Class({
|
||||||
this.autoStepLocked = true;
|
this.autoStepLocked = true;
|
||||||
this.$.assistant.stepsIndex = this.agencySteps;
|
this.$.assistant.stepsIndex = this.agencySteps;
|
||||||
|
|
||||||
this.today = new Date();
|
this.today = Date.vnNew();
|
||||||
this.today.setHours(0, 0, 0, 0);
|
this.today.setHours(0, 0, 0, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ export default new Class({
|
||||||
let date;
|
let date;
|
||||||
const row = orderForm.$ || defaultsForm.$ || {};
|
const row = orderForm.$ || defaultsForm.$ || {};
|
||||||
|
|
||||||
if (!date || date.getTime() < (new Date()).getTime()) {
|
if (!date || date.getTime() < (Date.vnNew()).getTime()) {
|
||||||
date = new Date();
|
date = Date.vnNew();
|
||||||
date.setHours(0, 0, 0, 0);
|
date.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
let addDays = 0;
|
let addDays = 0;
|
||||||
|
@ -44,7 +44,7 @@ export default new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$.lot.assign({
|
this.$.lot.assign({
|
||||||
date: date,
|
date,
|
||||||
method: row.deliveryMethod,
|
method: row.deliveryMethod,
|
||||||
agency: row.agencyModeFk,
|
agency: row.agencyModeFk,
|
||||||
address: row.addressFk
|
address: row.addressFk
|
||||||
|
@ -59,11 +59,21 @@ export default new Class({
|
||||||
async onConfirmClick() {
|
async onConfirmClick() {
|
||||||
this.disableButtons(true);
|
this.disableButtons(true);
|
||||||
|
|
||||||
const query = 'CALL myBasket_configure(#date, #method, #agency, #address)';
|
let id = this.$.params.$.id;
|
||||||
|
const params = Object.assign({}, this.$.lot.$);
|
||||||
|
|
||||||
|
let query;
|
||||||
|
if (id) {
|
||||||
|
params.id = id;
|
||||||
|
query = 'CALL myOrder_configure(#id, #date, #method, #agency, #address)';
|
||||||
|
} else {
|
||||||
|
query = 'CALL myOrder_create(@orderId, #date, #method, #agency, #address); SELECT @orderId;';
|
||||||
|
}
|
||||||
|
|
||||||
let resultSet;
|
let resultSet;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
resultSet = await this.conn.execQuery(query, this.$.lot.$);
|
resultSet = await this.conn.execQuery(query, params);
|
||||||
} finally {
|
} finally {
|
||||||
this.disableButtons(false);
|
this.disableButtons(false);
|
||||||
}
|
}
|
||||||
|
@ -71,16 +81,31 @@ export default new Class({
|
||||||
if (!resultSet.fetchResult())
|
if (!resultSet.fetchResult())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.$.orderForm.numRows > 0)
|
let redirect;
|
||||||
Htk.Toast.showMessage(_('OrderUpdated'));
|
const basket = new Hedera.Basket(this.app);
|
||||||
else
|
|
||||||
Htk.Toast.showMessage(_('OrderStarted'));
|
|
||||||
|
|
||||||
this.hash.setAll({form: 'ecomerce/catalog'});
|
if (id) {
|
||||||
|
Htk.Toast.showMessage(_('OrderUpdated'));
|
||||||
|
|
||||||
|
switch(this.hash.$.continue) {
|
||||||
|
case 'catalog':
|
||||||
|
redirect = {form: 'ecomerce/catalog'};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
redirect = {form: 'ecomerce/basket'};
|
||||||
|
if (id !== basket.orderId)
|
||||||
|
redirect.id = id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
basket.loadIntoBasket(resultSet.fetchValue());
|
||||||
|
redirect = {form: 'ecomerce/catalog'};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hash.setAll(redirect);
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancelClick() {
|
onCancelClick() {
|
||||||
if (this.$.orderForm.numRows > 0)
|
if (this.$.params.$.id)
|
||||||
window.history.back();
|
window.history.back();
|
||||||
else
|
else
|
||||||
this.hash.setAll({form: 'ecomerce/orders'});
|
this.hash.setAll({form: 'ecomerce/orders'});
|
||||||
|
@ -150,13 +175,9 @@ export default new Class({
|
||||||
this.$.assistant.moveNext();
|
this.$.assistant.moveNext();
|
||||||
},
|
},
|
||||||
|
|
||||||
goNextStep() {
|
|
||||||
this.$.assistant.moveNext();
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddressClick(addressId) {
|
onAddressClick(addressId) {
|
||||||
this.$.lot.set('address', addressId);
|
this.$.lot.set('address', addressId);
|
||||||
this.goNextStep();
|
this.$.assistant.moveNext();
|
||||||
},
|
},
|
||||||
|
|
||||||
onAddressChange() {
|
onAddressChange() {
|
||||||
|
@ -192,9 +213,9 @@ export default new Class({
|
||||||
|
|
||||||
const defaults = this.$.defaults.$ || {};
|
const defaults = this.$.defaults.$ || {};
|
||||||
if (defaults.agencyModeFk)
|
if (defaults.agencyModeFk)
|
||||||
defaults.push(defaults.agencyModeFk);
|
agencies.push(defaults.agencyModeFk);
|
||||||
if (defaults.defaultAgencyFk)
|
if (defaults.defaultAgencyFk)
|
||||||
defaults.push(defaults.defaultAgencyFk);
|
agencies.push(defaults.defaultAgencyFk);
|
||||||
|
|
||||||
for (const agency of agencies)
|
for (const agency of agencies)
|
||||||
if (model.search('id', agency) !== -1) {
|
if (model.search('id', agency) !== -1) {
|
||||||
|
|
|
@ -1,54 +1,55 @@
|
||||||
|
|
||||||
.checkout .bar {
|
.hedera-checkout {
|
||||||
margin-bottom: 16px;
|
.bar {
|
||||||
}
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Step */
|
/* Step */
|
||||||
|
|
||||||
.answers button,
|
.answers button,
|
||||||
.answers p,
|
.answers p,
|
||||||
.radio > div {
|
.radio > div {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.answers .htk-select {
|
||||||
|
max-width: 15em;
|
||||||
|
margin: 0 auto;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
.answers p {
|
||||||
|
margin: 0.3em 0;
|
||||||
|
}
|
||||||
|
.target {
|
||||||
|
max-width: 28em;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.address {
|
||||||
|
border-radius: 0.1em;
|
||||||
|
padding: 0.6em 1.4em;
|
||||||
|
}
|
||||||
|
.address.selected {
|
||||||
|
background-color: rgba(1, 1, 1, .1);
|
||||||
|
}
|
||||||
|
.address:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: rgba(1, 1, 1, .05);
|
||||||
|
}
|
||||||
|
.address p.consignee {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.radio {
|
||||||
|
max-width: 20em;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.radio > div {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
.thin-calendar {
|
||||||
|
max-width: 24em;
|
||||||
|
margin: 0 auto;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.htk-assistant .thin {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.answers .htk-select {
|
|
||||||
max-width: 15em;
|
|
||||||
margin: 0 auto;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
}
|
|
||||||
.answers p {
|
|
||||||
margin: 0.3em 0;
|
|
||||||
}
|
|
||||||
.target {
|
|
||||||
max-width: 28em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.address {
|
|
||||||
border-radius: 0.1em;
|
|
||||||
padding: 0.6em 1.4em;
|
|
||||||
}
|
|
||||||
.address.selected {
|
|
||||||
background-color: rgba(1, 1, 1, .1);
|
|
||||||
}
|
|
||||||
.address:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgba(1, 1, 1, .05);
|
|
||||||
}
|
|
||||||
.address p.consignee {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.radio {
|
|
||||||
max-width: 20em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.radio > div {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
.thin-calendar {
|
|
||||||
max-width: 24em;
|
|
||||||
margin: 0 auto;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
.htk-assistant .thin {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<vn>
|
<vn>
|
||||||
|
<vn-lot-query id="params">
|
||||||
|
<vn-spec name="id" type="Number"/>
|
||||||
|
</vn-lot-query>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<vn-lot id="lot" on-change="this.onAddressChange()"/>
|
<vn-lot id="lot" on-change="this.onAddressChange()"/>
|
||||||
<db-form id="defaults" on-ready="onValuesReady">
|
<db-form id="defaults" on-ready="onValuesReady">
|
||||||
|
@ -8,10 +11,11 @@
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-form id="order-form" on-ready="onValuesReady">
|
<db-form id="order-form" on-ready="onValuesReady">
|
||||||
<db-model property="model">
|
<db-model property="model" lot="params">
|
||||||
SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk
|
SELECT m.code deliveryMethod, o.sent, o.agencyModeFk, o.addressFk
|
||||||
FROM myBasket o
|
FROM myOrder o
|
||||||
JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
|
JOIN vn.deliveryMethod m ON m.id = o.deliveryMethodFk
|
||||||
|
WHERE o.id = #id
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-model id="agencies"
|
<db-model id="agencies"
|
||||||
|
@ -54,7 +58,7 @@
|
||||||
tip="_Cancel"
|
tip="_Cancel"
|
||||||
on-click="onCancelClick"/>
|
on-click="onCancelClick"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="checkout">
|
<div id="form" class="hedera-checkout">
|
||||||
<div class="vn-w-sm">
|
<div class="vn-w-sm">
|
||||||
<div class="box bar">
|
<div class="box bar">
|
||||||
<htk-assistant-bar
|
<htk-assistant-bar
|
||||||
|
@ -116,7 +120,7 @@
|
||||||
form-id="iter"
|
form-id="iter"
|
||||||
on-change="onAddressChange">
|
on-change="onAddressChange">
|
||||||
<db-model property="model" id="addresses">
|
<db-model property="model" id="addresses">
|
||||||
SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.country
|
SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.name
|
||||||
FROM myAddress a
|
FROM myAddress a
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||||
JOIN vn.country c ON c.id = p.countryFk
|
JOIN vn.country c ON c.id = p.countryFk
|
||||||
|
|
|
@ -5,8 +5,13 @@ export default new Class({
|
||||||
Template: require('./ui.xml'),
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
async open() {
|
async open() {
|
||||||
const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
|
const basket = new Hedera.Basket(this.app);
|
||||||
if (isOk) await Hedera.Form.prototype.open.call(this);
|
try {
|
||||||
|
await basket.checkOrder(this.hash.$.id);
|
||||||
|
} catch (err) {
|
||||||
|
Htk.Toast.showError(err.message);
|
||||||
|
}
|
||||||
|
await Hedera.Form.prototype.open.call(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
onOrderReady(form) {
|
onOrderReady(form) {
|
||||||
|
@ -106,25 +111,22 @@ export default new Class({
|
||||||
Vn.Node.addClass(this.$[id], 'selected');
|
Vn.Node.addClass(this.$[id], 'selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
disableButtons(disable) {
|
|
||||||
this.$.modify.disabled = disable;
|
|
||||||
this.$.confirm.disabled = disable;
|
|
||||||
},
|
|
||||||
|
|
||||||
onModifyClick() {
|
onModifyClick() {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
},
|
},
|
||||||
|
|
||||||
async onConfirmClick() {
|
async onConfirmClick() {
|
||||||
this.disableButtons(true);
|
Vn.Node.disableInputs(this.node);
|
||||||
await this.$.confirmQuery.execute();
|
try {
|
||||||
},
|
await this.conn.execQuery(
|
||||||
|
'CALL myOrder_confirm(#id)',
|
||||||
onConfirm(query, resultSet) {
|
this.$.params.$
|
||||||
this.disableButtons(false);
|
);
|
||||||
|
Hedera.Basket.unload();
|
||||||
if (resultSet.fetchResult())
|
|
||||||
this.$.successDialog.show();
|
this.$.successDialog.show();
|
||||||
|
} finally {
|
||||||
|
Vn.Node.disableInputs(this.node, false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async onDialogResponse() {
|
async onDialogResponse() {
|
||||||
|
|
|
@ -1,93 +1,95 @@
|
||||||
|
|
||||||
.confirm .summary {
|
.hedera-confirm {
|
||||||
margin-bottom: 16px;
|
.summary {
|
||||||
}
|
margin-bottom: 16px;
|
||||||
.confirm p {
|
}
|
||||||
margin: .2em 0;
|
p {
|
||||||
}
|
margin: .2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Table */
|
/* Table */
|
||||||
|
|
||||||
.confirm .debt-info {
|
.debt-info {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.confirm .debt-info > table {
|
.debt-info > table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
.confirm td {
|
td {
|
||||||
padding: .15em 0;
|
padding: .15em 0;
|
||||||
}
|
}
|
||||||
.confirm .sum-total > td {
|
.sum-total > td {
|
||||||
border-top: solid 1px #DDD;
|
border-top: solid 1px #DDD;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.confirm .currency {
|
.currency {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.confirm .credit-info {
|
.credit-info {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.confirm .exceeded-info {
|
.exceeded-info {
|
||||||
display: none;
|
display: none;
|
||||||
color: #E53935;
|
color: #E53935;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pay */
|
/* Pay */
|
||||||
|
|
||||||
.confirm .amount-selector,
|
.amount-selector,
|
||||||
.confirm .pay-methods > div {
|
.pay-methods > div {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.confirm .pay-methods > div {
|
.pay-methods > div {
|
||||||
margin: .3em 0;
|
margin: .3em 0;
|
||||||
}
|
}
|
||||||
.confirm .pay-methods > div > label > input[type=radio] {
|
.pay-methods > div > label > input[type=radio] {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-right: .5em;
|
margin-right: .5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
.confirm .pay-methods > div > div {
|
.pay-methods > div > div {
|
||||||
padding: .5em 1.5em;
|
padding: .5em 1.5em;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.confirm .pay-methods > div.selected > div {
|
.pay-methods > div.selected > div {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.confirm .transfer-account {
|
.transfer-account {
|
||||||
margin-top: .5em;
|
margin-top: .5em;
|
||||||
}
|
}
|
||||||
.confirm .transfer-account > p {
|
.transfer-account > p {
|
||||||
margin: .1em 0;
|
margin: .1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.confirm .payment > div {
|
.payment > div {
|
||||||
margin-bottom: 1.4em;
|
margin-bottom: 1.4em;
|
||||||
|
}
|
||||||
|
.payment > .button-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 32px;
|
||||||
|
}
|
||||||
|
.payment > .button-bar button{
|
||||||
|
font-size: 1.2rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.modify-order {
|
||||||
|
border: 1px solid #1a1a1a;
|
||||||
|
}
|
||||||
|
.modify-order:hover {
|
||||||
|
color: white;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
}
|
||||||
|
.confirm-order {
|
||||||
|
border: 1px solid #8cc63f;
|
||||||
|
background-color: #8cc63f;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.confirm-order:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #6b5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.confirm .payment > .button-bar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 32px;
|
|
||||||
}
|
|
||||||
.confirm .payment > .button-bar button{
|
|
||||||
font-size: 1.2rem;
|
|
||||||
border-radius: 2rem;
|
|
||||||
padding: .5rem 1rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.confirm .modify-order {
|
|
||||||
border: 1px solid #1a1a1a;
|
|
||||||
}
|
|
||||||
.confirm .modify-order:hover {
|
|
||||||
color: white;
|
|
||||||
background-color: #1a1a1a;
|
|
||||||
}
|
|
||||||
.confirm .confirm-order {
|
|
||||||
border: 1px solid #8cc63f;
|
|
||||||
background-color: #8cc63f;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.confirm .confirm-order:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
color: #6b5;
|
|
||||||
}
|
|
|
@ -1,13 +1,16 @@
|
||||||
<vn>
|
<vn>
|
||||||
|
<vn-lot-query id="params">
|
||||||
|
<vn-spec name="id" type="Number"/>
|
||||||
|
</vn-lot-query>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form v-model="order" on-ready="onOrderReady">
|
<db-form v-model="order" on-ready="onOrderReady">
|
||||||
<db-model property="model" result-index="1">
|
<db-model property="model" result-index="1" lot="params">
|
||||||
CALL myBasket_getTax;
|
CALL myOrder_getTax(#id);
|
||||||
SELECT o.id, o.sent, o.notes, o.companyFk,
|
SELECT o.id, o.sent, o.notes, o.companyFk,
|
||||||
ag.description agency, v.code method,
|
ag.description agency, v.code method,
|
||||||
ad.nickname, ad.postalCode, ad.city, ad.street,
|
ad.nickname, ad.postalCode, ad.city, ad.street,
|
||||||
t.*, c.credit, myClient_getDebt(NULL) debt
|
t.*, c.credit, myClient_getDebt(NULL) debt
|
||||||
FROM myBasket o
|
FROM myOrder o
|
||||||
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
JOIN vn.agencyMode ag ON ag.id = o.agencyModeFk
|
||||||
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
LEFT JOIN myAddress ad ON ad.id = o.addressFk
|
||||||
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
|
JOIN vn.deliveryMethod v ON v.id = o.deliveryMethodFk
|
||||||
|
@ -17,27 +20,27 @@
|
||||||
IFNULL(SUM(taxableBase), 0) taxableBase,
|
IFNULL(SUM(taxableBase), 0) taxableBase,
|
||||||
IFNULL(SUM(tax), 0) tax
|
IFNULL(SUM(tax), 0) tax
|
||||||
FROM tmp.orderAmount
|
FROM tmp.orderAmount
|
||||||
) t;
|
) t
|
||||||
|
WHERE o.id = #id;
|
||||||
DROP TEMPORARY TABLE
|
DROP TEMPORARY TABLE
|
||||||
tmp.orderAmount,
|
tmp.orderAmount,
|
||||||
tmp.orderTax;
|
tmp.orderTax;
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-query id="confirm-query" on-ready="onConfirm">
|
|
||||||
CALL myBasket_confirm
|
|
||||||
</db-query>
|
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Order summary</t></h1>
|
<h1><t>Order summary</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="confirm">
|
<div id="form" class="hedera-confirm">
|
||||||
<div class="vn-w-sm">
|
<div class="vn-w-sm">
|
||||||
<div class="box vn-pa-lg summary">
|
<div class="box vn-pa-lg summary">
|
||||||
<div>
|
<div>
|
||||||
|
<h5>#{{order.id}}</h5>
|
||||||
<div class="delivery">
|
<div class="delivery">
|
||||||
<h6><t>ShippingInformation</t></h6>
|
<h6><t>ShippingInformation</t></h6>
|
||||||
|
<p>{{order.nickname}}</p>
|
||||||
<p>
|
<p>
|
||||||
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
<t>Delivery at</t> {{Vn.Value.format(order.sent, _('%D'))}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span id="method"><t>Agency</t></span> {{order.agency}}
|
<span id="method"><t>Agency</t></span> {{order.agency}}
|
||||||
|
@ -45,7 +48,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="address" class="address vn-mt-md">
|
<div id="address" class="address vn-mt-md">
|
||||||
<h6><t>DeliveryAddress</t></h6>
|
<h6><t>DeliveryAddress</t></h6>
|
||||||
<p>{{order.nickname}}</p>
|
|
||||||
<p>{{order.street}}</p>
|
<p>{{order.street}}</p>
|
||||||
<p>{{order.postalCode}}, {{order.city}}</p>
|
<p>{{order.postalCode}}, {{order.city}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,30 +3,17 @@ import './style.scss';
|
||||||
export default new Class({
|
export default new Class({
|
||||||
Extends: Hedera.Form,
|
Extends: Hedera.Form,
|
||||||
Template: require('./ui.xml'),
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
donwloadRenderer(column, invoice) {
|
|
||||||
var invoiceId = invoice.$.id;
|
|
||||||
|
|
||||||
if (invoice.$.hasPdf && invoiceId) {
|
onDownloadClick(column, value, row) {
|
||||||
var params = {
|
var model = this.$.invoices;
|
||||||
srv: 'rest:dms/invoice',
|
var hasPdf = model.get(row, 'hasPdf');
|
||||||
invoice: invoiceId,
|
var id = model.get(row, 'id');
|
||||||
access_token: this.conn.token
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.assign(column, {
|
if (hasPdf && id) {
|
||||||
tip: _('Download PDF'),
|
let params = Vn.Url.makeUri({ access_token: this.conn.token });
|
||||||
disabled: false,
|
window.open(`/api/InvoiceOuts/${id}/download?${params}`);
|
||||||
icon: 'download',
|
|
||||||
href: '?'+ Vn.Url.makeUri(params)
|
|
||||||
});
|
|
||||||
} else
|
} else
|
||||||
Object.assign(column, {
|
Htk.Toast.showWarning(_('Request the invoice to your salesperson'));
|
||||||
tip: _('Request the invoice to your salesperson'),
|
|
||||||
disabled: true,
|
|
||||||
icon: 'warning',
|
|
||||||
href: null
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Invoices</t></h1>
|
<h1><t>Invoices</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="invoices">
|
<div id="form" class="hedera-invoices">
|
||||||
<htk-grid
|
<htk-grid
|
||||||
class="box vn-w-sm"
|
class="box vn-w-sm"
|
||||||
show-header="false">
|
show-header="false">
|
||||||
<db-model property="model" id="tickets">
|
<db-model property="model" id="invoices">
|
||||||
SELECT id, ref, issued, amount, hasPdf
|
SELECT id, ref, issued, amount, hasPdf
|
||||||
FROM myInvoice
|
FROM myInvoice
|
||||||
ORDER BY issued DESC
|
ORDER BY issued DESC
|
||||||
|
@ -16,8 +16,9 @@
|
||||||
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
|
<htk-column-date title="_Date" column="issued" format="_%e %b %Y"/>
|
||||||
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
|
<htk-column-spin title="_Import" column="amount" unit="€" digits="2"/>
|
||||||
<htk-column-button
|
<htk-column-button
|
||||||
renderer="donwloadRenderer"
|
icon="download"
|
||||||
target="_blank"/>
|
tip="_Download PDF"
|
||||||
|
on-clicked="onDownloadClick"/>
|
||||||
</htk-grid>
|
</htk-grid>
|
||||||
</div>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: N encàrrec
|
||||||
DateMake: Data de creació
|
DateMake: Data de creació
|
||||||
DateExit: Data d'eixida
|
DateExit: Data d'eixida
|
||||||
SendMethod: Forma d'enviament
|
SendMethod: Forma d'enviament
|
||||||
LastOrders: Últimes comandes
|
LastOrders: Comandes confirmades
|
||||||
'Balance:': 'Saldo:'
|
'Balance:': 'Saldo:'
|
||||||
PaymentInfo: >-
|
PaymentInfo: >-
|
||||||
La quantitat mostrada és el teu saldo pendent (negatiu) o favorable a dia
|
La quantitat mostrada és el teu saldo pendent (negatiu) o favorable a dia
|
||||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Order number
|
||||||
DateMake: Creation date
|
DateMake: Creation date
|
||||||
DateExit: Shipping date
|
DateExit: Shipping date
|
||||||
SendMethod: Delivery method
|
SendMethod: Delivery method
|
||||||
LastOrders: Last orders
|
LastOrders: Confirmed orders
|
||||||
'Balance:': 'Balance:'
|
'Balance:': 'Balance:'
|
||||||
PaymentInfo: >-
|
PaymentInfo: >-
|
||||||
The amount shown is your slope (negative) or favorable balance today, it
|
The amount shown is your slope (negative) or favorable balance today, it
|
||||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Nº pedido
|
||||||
DateMake: Fecha de creación
|
DateMake: Fecha de creación
|
||||||
DateExit: Fecha de salida
|
DateExit: Fecha de salida
|
||||||
SendMethod: Forma de envío
|
SendMethod: Forma de envío
|
||||||
LastOrders: Últimos pedidos
|
LastOrders: Pedidos confirmados
|
||||||
'Balance:': 'Saldo:'
|
'Balance:': 'Saldo:'
|
||||||
PaymentInfo: >-
|
PaymentInfo: >-
|
||||||
La cantidad mostrada es tu saldo pendiente (negativa) o favorable a día de
|
La cantidad mostrada es tu saldo pendiente (negativa) o favorable a día de
|
||||||
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Numéro de commande
|
||||||
DateMake: Date de creation
|
DateMake: Date de creation
|
||||||
DateExit: Date de sortie
|
DateExit: Date de sortie
|
||||||
SendMethod: Typo
|
SendMethod: Typo
|
||||||
LastOrders: Les dernières commandes
|
LastOrders: Commandes confirmées
|
||||||
'Balance:': 'Balance:'
|
'Balance:': 'Balance:'
|
||||||
PaymentInfo: >-
|
PaymentInfo: >-
|
||||||
Le montant indiqué est votre pente (négative) ou balance favorable
|
Le montant indiqué est votre pente (négative) ou balance favorable
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
OpenOrders: Open orders
|
|
||||||
StartOrder: Start order
|
|
||||||
ContinueOrder: Continue order
|
|
||||||
OrderNumber: Order number
|
|
||||||
DateMake: Creation date
|
|
||||||
DateExit: Shipping date
|
|
||||||
SendMethod: Delivery method
|
|
||||||
LastOrders: Last orders
|
|
||||||
'Balance:': 'Balance:'
|
|
||||||
PaymentInfo: >-
|
|
||||||
Үзүүлсэн хэмжээ цаашид захиалга эзэлж биш, таны налуу (сөрөг), эсвэл
|
|
||||||
тааламжтай тэнцвэр нь өнөөдөр юм. Хэрэв та дүн арилгаж гэж хэлж байсан нь доош
|
|
||||||
нь төлбөр хийж, өөрийн хүссэн хэмжээгээр орж хүсэж байгаа бол таны захиалга
|
|
||||||
ирдэг бол авах, энэ хэмжээ тэнцүү буюу 0-ээс их байх ёстой.
|
|
||||||
MakePayment: Make payment
|
|
||||||
Company: Company
|
|
||||||
Pending: Pending
|
|
||||||
Pay: Pay
|
|
||||||
Basket: Basket
|
|
||||||
ShoppingBasket: Shopping basket
|
|
||||||
SeeOrder: Show details of the order
|
|
||||||
Delivery: Delivery
|
|
||||||
TicketNumber: Ticket number
|
|
||||||
SentAddress: Delivery address
|
|
||||||
Consignee: Consignee
|
|
||||||
Boxes: Bundles
|
|
||||||
TotalWithVAT: Total with VAT
|
|
||||||
PayOrder: Pay order
|
|
||||||
'AmountToPay:': 'Amount to pay (€):'
|
|
||||||
AmountError: >-
|
|
||||||
The amount must be a positive number less than or equal to the outstanding
|
|
||||||
amount
|
|
||||||
PayError: Failed to make the payment
|
|
||||||
An error has been in the payment: >-
|
|
||||||
It seems that there has been an error in the payment
|
|
||||||
Retry: Retry
|
|
||||||
Accept: Accept
|
|
|
@ -5,7 +5,7 @@ OrderNumber: Nº pedido
|
||||||
DateMake: Data de criação
|
DateMake: Data de criação
|
||||||
DateExit: Data de saída
|
DateExit: Data de saída
|
||||||
SendMethod: Forma de envío
|
SendMethod: Forma de envío
|
||||||
LastOrders: Últimas encomendas
|
LastOrders: Encomendas confirmadas
|
||||||
'Balance:': 'Saldo:'
|
'Balance:': 'Saldo:'
|
||||||
PaymentInfo: >-
|
PaymentInfo: >-
|
||||||
A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de
|
A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
/* List */
|
/* List */
|
||||||
|
|
||||||
.orders .htk-list .total {
|
.hedera-orders .htk-list .total {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
tip="_ShoppingBasket"
|
tip="_ShoppingBasket"
|
||||||
on-click="onBasketClick"/>
|
on-click="onBasketClick"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="orders">
|
<div id="form" class="hedera-orders">
|
||||||
<htk-repeater
|
<htk-repeater
|
||||||
class="htk-list box confirmed vn-w-sm"
|
class="htk-list box confirmed vn-w-sm"
|
||||||
form-id="iter"
|
form-id="iter"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
this.basket = new Hedera.Basket(this.app);
|
||||||
|
this.$.orders.setInfo('o', 'myOrder', 'hedera', ['id'], 'id');
|
||||||
|
},
|
||||||
|
|
||||||
|
async onRemoveOrderClick(form) {
|
||||||
|
if (confirm(_('AreYouSureDeleteOrder')))
|
||||||
|
await form.deleteRow();
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadOrder(id) {
|
||||||
|
const basket = new Hedera.Basket(this.app);
|
||||||
|
await basket.load(id);
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
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!
|
|
@ -0,0 +1,8 @@
|
||||||
|
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!
|
|
@ -0,0 +1,8 @@
|
||||||
|
Pending: Pendientes
|
||||||
|
PendingOrders: Pedidos pendientes
|
||||||
|
NewOrder: Nuevo pedido
|
||||||
|
ViewOrder: Ver pedido
|
||||||
|
RemoveOrder: Eliminar pedido
|
||||||
|
LoadOrderIntoCart: Cargar pedido en la cesta
|
||||||
|
AreYouSureDeleteOrder: ¿Seguro que quieres borrar el pedido?
|
||||||
|
OrderLoadedIntoBasket: ¡Pedido cargado en la cesta!
|
|
@ -0,0 +1,8 @@
|
||||||
|
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!
|
|
@ -0,0 +1,8 @@
|
||||||
|
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!
|
|
@ -0,0 +1,54 @@
|
||||||
|
<vn>
|
||||||
|
<div id="title">
|
||||||
|
<h1><t>PendingOrders</t></h1>
|
||||||
|
</div>
|
||||||
|
<div id="actions">
|
||||||
|
<htk-bar-button
|
||||||
|
class="start-order"
|
||||||
|
icon="add_shopping_cart"
|
||||||
|
tip="_NewOrder"
|
||||||
|
on-click="hash.setAll({form: 'ecomerce/checkout'})"/>
|
||||||
|
</div>
|
||||||
|
<div id="form" class="hedera-pending">
|
||||||
|
<htk-repeater
|
||||||
|
class="htk-list box confirmed vn-w-sm"
|
||||||
|
form-id="iter">
|
||||||
|
<db-model property="model" id="orders">
|
||||||
|
SELECT o.id, o.sent, o.deliveryMethodFk, o.taxableBase,
|
||||||
|
a.nickname, am.description agency
|
||||||
|
FROM myOrder o
|
||||||
|
JOIN myAddress a ON a.id = o.addressFk
|
||||||
|
JOIN vn.agencyMode am ON am.id = o.agencyModeFk
|
||||||
|
WHERE NOT o.isConfirmed
|
||||||
|
ORDER BY o.sent DESC
|
||||||
|
</db-model>
|
||||||
|
<custom>
|
||||||
|
<a class="item"
|
||||||
|
title="{{_('ViewOrder')}}"
|
||||||
|
href="{{'#!form=ecomerce/basket&id='+iter.id}}">
|
||||||
|
<div class="content">
|
||||||
|
<p class="important">
|
||||||
|
{{Vn.Value.format(iter.sent, '%D')}}
|
||||||
|
</p>
|
||||||
|
<p>#{{iter.id}}</p>
|
||||||
|
<p>{{iter.nickname}}</p>
|
||||||
|
<p>{{iter.agency}}</p>
|
||||||
|
<p>{{Vn.Value.format(iter.taxableBase, '%.2d€')}}</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="actions"
|
||||||
|
on-click="$event.preventDefault()">
|
||||||
|
<htk-button
|
||||||
|
icon="delete"
|
||||||
|
tip="_RemoveOrder"
|
||||||
|
on-click="this.onRemoveOrderClick($iter)"/>
|
||||||
|
<htk-button
|
||||||
|
icon="shopping_bag"
|
||||||
|
tip="_LoadOrderIntoCart"
|
||||||
|
on-click="this.loadOrder(iter.id)"/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</custom>
|
||||||
|
</htk-repeater>
|
||||||
|
</div>
|
||||||
|
</vn>
|
|
@ -1,78 +1,79 @@
|
||||||
|
|
||||||
/* Header */
|
.hedera-ticket {
|
||||||
|
/* Header */
|
||||||
|
|
||||||
.ticket .head {
|
.head {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-bottom: 3px;
|
padding-bottom: 3px;
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
}
|
}
|
||||||
.ticket .head > div > div {
|
.head > div > div {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
.ticket .head > div > div:first-child {
|
.head > div > div:first-child {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.ticket .head p {
|
.head p {
|
||||||
margin: 3px 0;
|
margin: 3px 0;
|
||||||
}
|
}
|
||||||
.ticket .head p.important {
|
.head p.important {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.ticket .total {
|
.total {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.ticket .packages {
|
.packages {
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
padding-top: 14px;
|
padding-top: 14px;
|
||||||
border-top: 1px solid #DDD;
|
border-top: 1px solid #DDD;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lines */
|
/* Lines */
|
||||||
|
|
||||||
.ticket .line {
|
.line {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
}
|
||||||
|
.line:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.line > .photo {
|
||||||
|
flex: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 68px;
|
||||||
|
height: 68px;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
.line > .info {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.line > .info > * {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.line > .info > h2 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.line > .info > p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.line > .info > .tags {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
.line > .info .discount {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.line > .info > .subtotal {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ticket .line:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.ticket .line > .photo {
|
|
||||||
flex: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 68px;
|
|
||||||
height: 68px;
|
|
||||||
gap: 0;
|
|
||||||
}
|
|
||||||
.ticket .line > .info {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.ticket .line > .info > * {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.ticket .line > .info > h2 {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
.ticket .line > .info > p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.ticket .line > .info > .tags {
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
.ticket .line > .info .discount {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
.ticket .line > .info > .subtotal {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
tip="_Print delivery note"
|
tip="_Print delivery note"
|
||||||
on-click="this.onPrintClick()"/>
|
on-click="this.onPrintClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="ticket">
|
<div id="form" class="hedera-ticket">
|
||||||
<div class="box vn-w-sm vn-pa-lg">
|
<div class="box vn-w-sm vn-pa-lg">
|
||||||
<htk-loader class="head" form="ticket-form">
|
<htk-loader class="head" form="ticket-form">
|
||||||
<h5>#{{ticket.id}}</h5>
|
<h5>#{{ticket.id}}</h5>
|
||||||
|
|
|
@ -1,42 +1,44 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-lot id="lot"/>
|
<vn-lot id="lot"/>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Item list</t></h1>
|
<h1><t>Item list</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions" class="action-bar">
|
<div id="actions" class="action-bar">
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="print"
|
icon="print"
|
||||||
tip="_Preview"
|
tip="_Preview"
|
||||||
on-click="this.onPreviewClick()"/>
|
on-click="this.onPreviewClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="items">
|
<div id="form" class="items">
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Store</t></label>
|
<label><t>Store</t></label>
|
||||||
<htk-combo form="lot" column="warehouse">
|
<htk-combo form="lot" column="warehouse">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT id, name FROM vn2008.warehouse
|
SELECT id, name
|
||||||
WHERE reserve ORDER BY name
|
FROM vn.warehouse
|
||||||
</db-model>
|
WHERE hasAvailable
|
||||||
</htk-combo>
|
ORDER BY name
|
||||||
</div>
|
</db-model>
|
||||||
<div class="form-group">
|
</htk-combo>
|
||||||
<label><t>Realm</t></label>
|
</div>
|
||||||
<htk-combo form="lot" column="realm" not-null="false">
|
<div class="form-group">
|
||||||
<db-model property="model">
|
<label><t>Realm</t></label>
|
||||||
SELECT id, reino FROM vn2008.reinos
|
<htk-combo form="lot" column="realm" not-null="false">
|
||||||
WHERE display != FALSE ORDER BY reino
|
<db-model property="model">
|
||||||
</db-model>
|
SELECT id, name FROM vn.itemCategory
|
||||||
</htk-combo>
|
WHERE display ORDER BY name
|
||||||
</div>
|
</db-model>
|
||||||
<div class="form-group">
|
</htk-combo>
|
||||||
<label><t>Rate</t></label>
|
</div>
|
||||||
<select id="rate">
|
<div class="form-group">
|
||||||
<option>3</option>
|
<label><t>Rate</t></label>
|
||||||
<option>2</option>
|
<select id="rate">
|
||||||
<option>1</option>
|
<option>3</option>
|
||||||
</select>
|
<option>2</option>
|
||||||
</div>
|
<option>1</option>
|
||||||
</div>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</vn>
|
</div>
|
||||||
|
</div>
|
||||||
|
</vn>
|
||||||
|
|
|
@ -6,7 +6,7 @@ export default new Class({
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.$.lot.assign({
|
this.$.lot.assign({
|
||||||
date: new Date(),
|
date: Date.vnNew(),
|
||||||
useIds: false
|
useIds: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,105 +1,107 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-lot-query id="params">
|
<vn-lot-query id="params">
|
||||||
<vn-spec name="config" type="Number"/>
|
<vn-spec name="config" type="Number"/>
|
||||||
</vn-lot-query>
|
</vn-lot-query>
|
||||||
<vn-lot id="lot"/>
|
<vn-lot id="lot"/>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Shelves</t></h1>
|
<h1><t>Shelves</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions" class="action-bar">
|
<div id="actions" class="action-bar">
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="print"
|
icon="print"
|
||||||
tip="_Preview"
|
tip="_Preview"
|
||||||
on-click="this.onPreviewClick()"/>
|
on-click="this.onPreviewClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="shelves">
|
<div id="form" class="shelves">
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Configuration</t></label>
|
<label><t>Configuration</t></label>
|
||||||
<htk-combo
|
<htk-combo
|
||||||
id="config"
|
id="config"
|
||||||
placeholder="_Select config"
|
placeholder="_Select config"
|
||||||
form="params"
|
form="params"
|
||||||
column="config"
|
column="config"
|
||||||
on-changed="this.onConfigChange()"
|
on-changed="this.onConfigChange()"
|
||||||
on-ready="this.onConfigChange()">
|
on-ready="this.onConfigChange()">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
|
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
|
||||||
c.shelf, c.maxAmount, c.showPacking, c.stack, t.reino_id realm
|
c.shelf, c.maxAmount, c.showPacking, c.stack, it.categoryFk realm
|
||||||
FROM shelfConfig c
|
FROM shelfConfig c
|
||||||
JOIN vn2008.Tipos t ON t.tipo_id = c.family
|
JOIN vn.itemType it ON it.id = c.family
|
||||||
</db-model>
|
</db-model>
|
||||||
</htk-combo>
|
</htk-combo>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Date</t></label>
|
<label><t>Date</t></label>
|
||||||
<htk-date-chooser form="lot" name="date"/>
|
<htk-date-chooser form="lot" name="date"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Reign</t></label>
|
<label><t>Reign</t></label>
|
||||||
<htk-combo form="lot" name="realm">
|
<htk-combo form="lot" name="realm">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT id, reino FROM vn2008.reinos
|
SELECT id, name FROM vn.itemCategory
|
||||||
WHERE display != FALSE ORDER BY reino
|
WHERE display ORDER BY name
|
||||||
</db-model>
|
</db-model>
|
||||||
</htk-combo>
|
</htk-combo>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Family</t></label>
|
<label><t>Family</t></label>
|
||||||
<htk-combo form="lot" name="family">
|
<htk-combo form="lot" name="family">
|
||||||
<db-model property="model" lot="lot">
|
<db-model property="model" lot="lot">
|
||||||
SELECT tipo_id, Tipo FROM vn2008.Tipos
|
SELECT id, name FROM vn.itemType
|
||||||
WHERE reino_id = #realm ORDER BY Tipo
|
WHERE categoryFk = #realm ORDER BY name
|
||||||
</db-model>
|
</db-model>
|
||||||
</htk-combo>
|
</htk-combo>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Store</t></label>
|
<label><t>Store</t></label>
|
||||||
<htk-combo form="lot">
|
<htk-combo form="lot">
|
||||||
<db-model property="model">
|
<db-model property="model">
|
||||||
SELECT id, name FROM vn2008.warehouse
|
SELECT id, name
|
||||||
WHERE reserve ORDER BY name
|
FROM vn.warehouse
|
||||||
</db-model>
|
WHERE hasAvailable
|
||||||
</htk-combo>
|
ORDER BY name
|
||||||
</div>
|
</db-model>
|
||||||
<div class="form-group">
|
</htk-combo>
|
||||||
<label><t>Shelf</t></label>
|
</div>
|
||||||
<htk-combo form="lot" name="shelf">
|
<div class="form-group">
|
||||||
<db-model property="model">
|
<label><t>Shelf</t></label>
|
||||||
SELECT id, name FROM shelf
|
<htk-combo form="lot" name="shelf">
|
||||||
</db-model>
|
<db-model property="model">
|
||||||
</htk-combo>
|
SELECT id, name FROM shelf
|
||||||
</div>
|
</db-model>
|
||||||
<div class="form-group">
|
</htk-combo>
|
||||||
<label><t>Name prefix</t></label>
|
</div>
|
||||||
<htk-entry form="lot" name="namePrefix"/>
|
<div class="form-group">
|
||||||
</div>
|
<label><t>Name prefix</t></label>
|
||||||
<div class="form-group">
|
<htk-entry form="lot" name="namePrefix"/>
|
||||||
<label><t>Limit amount per item</t></label>
|
</div>
|
||||||
<htk-entry form="lot" name="maxAmount"/>
|
<div class="form-group">
|
||||||
</div>
|
<label><t>Limit amount per item</t></label>
|
||||||
<div class="form-group">
|
<htk-entry form="lot" name="maxAmount"/>
|
||||||
<label><t>Title</t></label>
|
</div>
|
||||||
<htk-entry form="lot" name="reportTitle"/>
|
<div class="form-group">
|
||||||
</div>
|
<label><t>Title</t></label>
|
||||||
<div class="form-group">
|
<htk-entry form="lot" name="reportTitle"/>
|
||||||
<label>
|
</div>
|
||||||
<htk-check form="lot" name="showPacking"/>
|
<div class="form-group">
|
||||||
<t>Show packing</t>
|
<label>
|
||||||
</label>
|
<htk-check form="lot" name="showPacking"/>
|
||||||
</div>
|
<t>Show packing</t>
|
||||||
<div class="form-group">
|
</label>
|
||||||
<label>
|
</div>
|
||||||
<htk-check form="lot" name="stack"/>
|
<div class="form-group">
|
||||||
<t>Stack different items</t>
|
<label>
|
||||||
</label>
|
<htk-check form="lot" name="stack"/>
|
||||||
</div>
|
<t>Stack different items</t>
|
||||||
<div class="form-group">
|
</label>
|
||||||
<label>
|
</div>
|
||||||
<htk-check form="lot" name="useIds"/>
|
<div class="form-group">
|
||||||
<t>Use ids instead of names</t>
|
<label>
|
||||||
</label>
|
<htk-check form="lot" name="useIds"/>
|
||||||
</div>
|
<t>Use ids instead of names</t>
|
||||||
</div>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</vn>
|
</div>
|
||||||
|
</div>
|
||||||
|
</vn>
|
||||||
|
|
|
@ -40,9 +40,7 @@ export const routes = {
|
||||||
},
|
},
|
||||||
agencies: {
|
agencies: {
|
||||||
packages:
|
packages:
|
||||||
() => import('agencies/packages'),
|
() => import('agencies/packages')
|
||||||
provinces:
|
|
||||||
() => import('agencies/provinces')
|
|
||||||
},
|
},
|
||||||
cms: {
|
cms: {
|
||||||
about:
|
about:
|
||||||
|
@ -70,7 +68,9 @@ export const routes = {
|
||||||
orders:
|
orders:
|
||||||
() => import('ecomerce/orders'),
|
() => import('ecomerce/orders'),
|
||||||
ticket:
|
ticket:
|
||||||
() => import('ecomerce/ticket')
|
() => import('ecomerce/ticket'),
|
||||||
|
pending:
|
||||||
|
() => import('ecomerce/pending')
|
||||||
},
|
},
|
||||||
news: {
|
news: {
|
||||||
new:
|
new:
|
||||||
|
|
|
@ -9,6 +9,24 @@ module.exports = new Class({
|
||||||
,get() {
|
,get() {
|
||||||
return this._conn;
|
return this._conn;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
hash: {
|
||||||
|
type: Vn.Hash
|
||||||
|
,get() {
|
||||||
|
return this._hash;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gui: {
|
||||||
|
type: Gui
|
||||||
|
,get() {
|
||||||
|
return this._gui;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
type: Login
|
||||||
|
,get() {
|
||||||
|
return this._login;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +53,7 @@ module.exports = new Class({
|
||||||
|
|
||||||
,showLogin() {
|
,showLogin() {
|
||||||
const login = this._login = new Login({
|
const login = this._login = new Login({
|
||||||
|
app: this,
|
||||||
conn: this._conn,
|
conn: this._conn,
|
||||||
hash: this._hash
|
hash: this._hash
|
||||||
});
|
});
|
||||||
|
@ -47,6 +66,7 @@ module.exports = new Class({
|
||||||
if (this._gui) return;
|
if (this._gui) return;
|
||||||
|
|
||||||
const gui = this._gui = new Gui({
|
const gui = this._gui = new Gui({
|
||||||
|
app: this,
|
||||||
conn: this._conn,
|
conn: this._conn,
|
||||||
hash: this._hash
|
hash: this._hash
|
||||||
});
|
});
|
||||||
|
@ -198,11 +218,11 @@ module.exports = new Class({
|
||||||
,async _onConnError(conn, err) {
|
,async _onConnError(conn, err) {
|
||||||
if (!(err instanceof Vn.JsonException)) return;
|
if (!(err instanceof Vn.JsonException)) return;
|
||||||
switch (err.exception) {
|
switch (err.exception) {
|
||||||
case 'UserDisabled':
|
case 'UserDisabledError':
|
||||||
Htk.Toast.showError(_('User disabled'));
|
Htk.Toast.showError(_('User disabled'));
|
||||||
await this._logout();
|
await this._logout();
|
||||||
return;
|
return;
|
||||||
case 'OutdatedVersion':
|
case 'OutdatedVersionError':
|
||||||
this._newVersion();
|
this._newVersion();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -218,12 +238,13 @@ module.exports = new Class({
|
||||||
if (err instanceof Vn.JsonException) {
|
if (err instanceof Vn.JsonException) {
|
||||||
const statusCode = err.statusCode;
|
const statusCode = err.statusCode;
|
||||||
if (statusCode >= 400 && statusCode < 500) {
|
if (statusCode >= 400 && statusCode < 500) {
|
||||||
if (err.statusCode == 403)
|
if (err.statusCode == 403) {
|
||||||
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
Htk.Toast.showError(err.message ||
|
||||||
else {
|
_('You don\'t have enough privileges'));
|
||||||
|
} else {
|
||||||
switch (err.exception) {
|
switch (err.exception) {
|
||||||
case 'UserDisabled':
|
case 'UserDisabledError':
|
||||||
case 'OutdatedVersion':
|
case 'OutdatedVersionError':
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (err.statusCode == 401)
|
if (err.statusCode == 401)
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
async check(conn, hash) {
|
|
||||||
this.hash = hash;
|
|
||||||
const resultSet = await conn.execQuery('CALL myBasket_check');
|
|
||||||
|
|
||||||
const status = resultSet.fetchValue();
|
|
||||||
if (!status) return;
|
|
||||||
|
|
||||||
const isOk = status == 'UPDATED' || status == 'OK';
|
|
||||||
|
|
||||||
if (status == 'UPDATED')
|
|
||||||
Htk.Toast.showWarning(_('Order items updated'));
|
|
||||||
|
|
||||||
if (!isOk)
|
|
||||||
this.hash.setAll({form: 'ecomerce/checkout'});
|
|
||||||
|
|
||||||
return isOk;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
module.exports = class {
|
||||||
|
constructor(app) {
|
||||||
|
this.app = app;
|
||||||
|
let orderId = localStorage.getItem('hederaBasket');
|
||||||
|
if (orderId) orderId = parseInt(orderId);
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
async checkOrder(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) {
|
||||||
|
try {
|
||||||
|
await this.checkOrder(this.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'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async load(orderId) {
|
||||||
|
this.loadIntoBasket(orderId);
|
||||||
|
if (await this.checkRedirect('catalog'))
|
||||||
|
this.app.hash.setAll({
|
||||||
|
form: 'ecomerce/catalog'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
loadIntoBasket(orderId) {
|
||||||
|
if (this.orderId != orderId) {
|
||||||
|
localStorage.setItem('hederaBasket', orderId);
|
||||||
|
this.orderId = orderId;
|
||||||
|
Htk.Toast.showMessage(_('OrderLoadedIntoBasket'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static unload() {
|
||||||
|
localStorage.removeItem('hederaBasket');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ module.exports = new Class({
|
||||||
|
|
||||||
,initialize(gui) {
|
,initialize(gui) {
|
||||||
this.gui = gui;
|
this.gui = gui;
|
||||||
|
this.app = gui.app;
|
||||||
this.conn = gui.conn;
|
this.conn = gui.conn;
|
||||||
this.hash = gui.hash;
|
this.hash = gui.hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,19 +50,16 @@ module.exports = new Class({
|
||||||
this.doc.body.appendChild(this.node);
|
this.doc.body.appendChild(this.node);
|
||||||
Htk.Toast.pushTop(this.$.formHolder);
|
Htk.Toast.pushTop(this.$.formHolder);
|
||||||
|
|
||||||
|
await this.refreshUserData();
|
||||||
|
Vn.Node.setText(this.$.userName, this.user.nickname);
|
||||||
|
|
||||||
const resultSet = await this._conn.execQuery(
|
const resultSet = await this._conn.execQuery(
|
||||||
'SELECT id, name, nickname FROM account.myUser;'
|
'SELECT defaultForm FROM config;'
|
||||||
+'SELECT defaultForm FROM config;'
|
|
||||||
+'SELECT url FROM imageConfig;'
|
+'SELECT url FROM imageConfig;'
|
||||||
+'SELECT dbproduccion FROM vn.config;'
|
+'SELECT dbproduccion FROM vn.config;'
|
||||||
+'SELECT productionDomain, testDomain FROM config;'
|
+'SELECT productionDomain, testDomain FROM config;'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Retrieving the user name
|
|
||||||
|
|
||||||
this.user = resultSet.fetchObject();
|
|
||||||
Vn.Node.setText(this.$.userName, this.user.nickname);
|
|
||||||
|
|
||||||
// Retrieving configuration parameters
|
// Retrieving configuration parameters
|
||||||
|
|
||||||
Vn.Config.defaultForm = resultSet.fetchValue();
|
Vn.Config.defaultForm = resultSet.fetchValue();
|
||||||
|
@ -119,6 +116,12 @@ module.exports = new Class({
|
||||||
Htk.Toast.showWarning(_('By using this site you accept cookies'));
|
Htk.Toast.showWarning(_('By using this site you accept cookies'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
,async refreshUserData() {
|
||||||
|
const resultSet = await this._conn.execQuery(
|
||||||
|
'SELECT id, name, nickname FROM account.myUser');
|
||||||
|
this.user = resultSet.fetchObject();
|
||||||
|
}
|
||||||
|
|
||||||
,async hide() {
|
,async hide() {
|
||||||
if (!this._shown)
|
if (!this._shown)
|
||||||
|
@ -463,29 +466,41 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supplants another user.
|
||||||
|
*
|
||||||
|
* @param {String} supplantUser The user name
|
||||||
|
*/
|
||||||
|
,async supplantUser(supplantUser) {
|
||||||
|
const json = await this._conn.send('client/supplant', {supplantUser});
|
||||||
|
this._conn.token = json;
|
||||||
|
sessionStorage.setItem('supplantUser', supplantUser);
|
||||||
|
|
||||||
|
await this.refreshUserData();
|
||||||
|
Vn.Node.setText(this.$.supplanted, this.user.nickname);
|
||||||
|
this.$.supplant.classList.toggle('show', true);
|
||||||
|
await this.loadMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ends the user supplanting and restores the original login.
|
||||||
|
*/
|
||||||
|
,async onSupplantExitClick() {
|
||||||
|
this._conn.post('Accounts/logout');
|
||||||
|
this._conn.fetchToken();
|
||||||
|
sessionStorage.removeItem('supplantUser');
|
||||||
|
|
||||||
|
this.$.supplant.classList.toggle('show', false);
|
||||||
|
await this.refreshUserData();
|
||||||
|
await this.loadMenu();
|
||||||
|
this._onFormChange();
|
||||||
|
}
|
||||||
|
|
||||||
,async supplantInit() {
|
,async supplantInit() {
|
||||||
var user = sessionStorage.getItem('supplantUser');
|
var user = sessionStorage.getItem('supplantUser');
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
|
await this.supplantUser(user);
|
||||||
await this._conn.supplantUser(user);
|
|
||||||
sessionStorage.setItem('supplantUser', user);
|
|
||||||
await this.loadMenu();
|
|
||||||
|
|
||||||
const res = await this._conn.execQuery(
|
|
||||||
'SELECT nickname FROM account.myUser');
|
|
||||||
|
|
||||||
const userName = res.fetchValue();
|
|
||||||
Vn.Node.setText(this.$.supplanted, userName);
|
|
||||||
this.$.supplant.classList.toggle('show', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onSupplantExitClick() {
|
|
||||||
this.$.supplant.classList.toggle('show', false);
|
|
||||||
await this._conn.supplantEnd();
|
|
||||||
sessionStorage.removeItem('supplantUser');
|
|
||||||
await this.loadMenu();
|
|
||||||
this._onFormChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Destroy
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Destroy
|
||||||
|
|
|
@ -10,6 +10,6 @@ Hedera = module.exports = {
|
||||||
,Report : require('./report')
|
,Report : require('./report')
|
||||||
,App : require('./app')
|
,App : require('./app')
|
||||||
,Tpv : require('./tpv')
|
,Tpv : require('./tpv')
|
||||||
,BasketChecker : require('./basket-checker')
|
,Basket : require('./basket')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
||||||
Home: Inici
|
Home: Inici
|
||||||
Orders: Encàrrecs
|
Orders: Encàrrecs
|
||||||
Basket: Cistella
|
Basket: Cistella
|
||||||
Last orders: Últims comandes
|
Pending orders: Pendents
|
||||||
|
Last orders: Confirmades
|
||||||
Invoices: Factures
|
Invoices: Factures
|
||||||
Catalog: Catàleg
|
Catalog: Catàleg
|
||||||
About: Coneix-nos
|
About: Coneix-nos
|
||||||
|
@ -62,3 +63,22 @@ Agencies: Agències
|
||||||
Configuration: Configuració
|
Configuration: Configuració
|
||||||
Account: Compte
|
Account: Compte
|
||||||
Addresses: Adreces
|
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
|
|
@ -34,7 +34,8 @@ AppName: Verdnatura
|
||||||
Home: Home
|
Home: Home
|
||||||
Orders: Orders
|
Orders: Orders
|
||||||
Basket: Basket
|
Basket: Basket
|
||||||
Last orders: Last orders
|
Pending orders: Pending
|
||||||
|
Last orders: Confirmed
|
||||||
Invoices: Invoices
|
Invoices: Invoices
|
||||||
Catalog: Catalog
|
Catalog: Catalog
|
||||||
About: About
|
About: About
|
||||||
|
@ -58,3 +59,5 @@ Agencies: Agencies
|
||||||
Configuration: Configuration
|
Configuration: Configuration
|
||||||
Account: Account
|
Account: Account
|
||||||
Addresses: Addresses
|
Addresses: Addresses
|
||||||
|
|
||||||
|
Load an order: Please load a pending order to the cart or start a new one
|
||||||
|
|
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
||||||
Home: Inicio
|
Home: Inicio
|
||||||
Orders: Pedidos
|
Orders: Pedidos
|
||||||
Basket: Cesta
|
Basket: Cesta
|
||||||
Last orders: Últimos pedidos
|
Pending orders: Pendientes
|
||||||
|
Last orders: Confirmados
|
||||||
Invoices: Facturas
|
Invoices: Facturas
|
||||||
Catalog: Catálogo
|
Catalog: Catálogo
|
||||||
About: Conócenos
|
About: Conócenos
|
||||||
|
@ -62,3 +63,24 @@ Agencies: Agencias
|
||||||
Configuration: Configuración
|
Configuration: Configuración
|
||||||
Account: Cuenta
|
Account: Cuenta
|
||||||
Addresses: Direcciones
|
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é
|
Log in as guest: Entrez en tant qu'invité
|
||||||
Login: Se connecter
|
Login: Se connecter
|
||||||
Login mail: info@verdnatura.es
|
Login mail: info@verdnatura.es
|
||||||
Login phone: +33 781 533 900
|
Login phone: +33 783 285 437
|
||||||
Password forgotten? Push here: Vous avez oublié votre mot de passe?
|
Password forgotten? Push here: Vous avez oublié votre mot de passe?
|
||||||
Yet you are not a customer?: Vous n'êtes pas encore client?
|
Yet you are not a customer?: Vous n'êtes pas encore client?
|
||||||
Sign up: S'inscrire
|
Sign up: S'inscrire
|
||||||
|
@ -38,7 +38,8 @@ AppName: Verdnatura
|
||||||
Home: Accueil
|
Home: Accueil
|
||||||
Orders: Commandes
|
Orders: Commandes
|
||||||
Basket: Panier
|
Basket: Panier
|
||||||
Last orders: Dernières commandes
|
Pending orders: En attente
|
||||||
|
Last orders: Confirmées
|
||||||
Invoices: Facturas
|
Invoices: Facturas
|
||||||
Catalog: Catalogue
|
Catalog: Catalogue
|
||||||
About: Nous
|
About: Nous
|
||||||
|
@ -62,3 +63,22 @@ Agencies: Agences
|
||||||
Configuration: Configuration
|
Configuration: Configuration
|
||||||
Account: Compte
|
Account: Compte
|
||||||
Addresses: Adresses
|
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
|
|
@ -36,7 +36,8 @@ AppName: VerdNatura
|
||||||
Home: Principio
|
Home: Principio
|
||||||
Orders: Encomendas
|
Orders: Encomendas
|
||||||
Basket: Cesta
|
Basket: Cesta
|
||||||
Last orders: Últimas encomendas
|
Pending orders: Pendentes
|
||||||
|
Last orders: Confirmados
|
||||||
Invoices: Facturas
|
Invoices: Facturas
|
||||||
Catalog: Catálogo
|
Catalog: Catálogo
|
||||||
About: Conheça-nos
|
About: Conheça-nos
|
||||||
|
@ -60,3 +61,22 @@ Agencies: Agências
|
||||||
Configuration: Configuração
|
Configuration: Configuração
|
||||||
Account: Conta
|
Account: Conta
|
||||||
Addresses: Moradas
|
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,6 +26,12 @@ module.exports = new Class({
|
||||||
self._onSubmit();
|
self._onSubmit();
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(this.hash.$.verificationToken){
|
||||||
|
this.$.changePassword.conn = this.conn;
|
||||||
|
this.$.changePassword.token = this.hash.$.verificationToken;
|
||||||
|
this.$.changePassword.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onConnLoadChange(conn, isLoading) {
|
,_onConnLoadChange(conn, isLoading) {
|
||||||
|
@ -94,7 +100,11 @@ module.exports = new Class({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._conn.send('user/recover-password', {recoverUser});
|
await this.conn.post('VnUsers/recoverPassword', {
|
||||||
|
user: recoverUser,
|
||||||
|
app: 'hedera'
|
||||||
|
});
|
||||||
|
|
||||||
Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password'));
|
Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,4 +54,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<htk-change-password id="change-password"/>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -9,11 +9,10 @@ module.exports = new Class({
|
||||||
this.tpvStatus = this.hash.$.tpvStatus;
|
this.tpvStatus = this.hash.$.tpvStatus;
|
||||||
|
|
||||||
if (this.tpvStatus) {
|
if (this.tpvStatus) {
|
||||||
const query = 'CALL myTpvTransaction_end(#transaction, #status)';
|
this.conn.post('TpvTransactions/end', {
|
||||||
this.conn.execQuery(query, {
|
orderId: this.tpvOrder,
|
||||||
transaction: this.tpvOrder,
|
|
||||||
status: this.tpvStatus
|
status: this.tpvStatus
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.tpvStatus;
|
return this.tpvStatus;
|
||||||
|
@ -24,22 +23,18 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,async _realPay(amount, company) {
|
,async _realPay(amount, company) {
|
||||||
if (!isNumeric(amount) || amount <= 0)
|
if (!isNumeric(amount) || amount <= 0) {
|
||||||
throw new UserError(_('AmountError'));
|
Htk.Toast.showError(_('AmountError'));
|
||||||
|
return;
|
||||||
let json;
|
|
||||||
|
|
||||||
try {
|
|
||||||
json = await this.conn.send('tpv/transaction', {
|
|
||||||
amount: parseInt(amount)
|
|
||||||
,urlOk: this._makeUrl('ok')
|
|
||||||
,urlKo: this._makeUrl('ko')
|
|
||||||
,company: company
|
|
||||||
});
|
|
||||||
} catch(err) {
|
|
||||||
throw new UserError(_('PayError'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const json = await this.conn.post('TpvTransactions/start', {
|
||||||
|
amount: parseInt(amount),
|
||||||
|
urlOk: this._makeUrl('ok'),
|
||||||
|
urlKo: this._makeUrl('ko'),
|
||||||
|
company
|
||||||
|
});
|
||||||
|
|
||||||
const postValues = json.postValues;
|
const postValues = json.postValues;
|
||||||
|
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
|
|
|
@ -141,7 +141,7 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,goToCurrentMonth() {
|
,goToCurrentMonth() {
|
||||||
var date = new Date();
|
var date = Date.vnNew();
|
||||||
this.goToMonth(date.getFullYear(), date.getMonth());
|
this.goToMonth(date.getFullYear(), date.getMonth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ module.exports = new Class({
|
||||||
|
|
||||||
// Marks the current day
|
// Marks the current day
|
||||||
|
|
||||||
var today = new Date();
|
var today = Date.vnNew();
|
||||||
|
|
||||||
if (this.year == today.getFullYear()
|
if (this.year == today.getFullYear()
|
||||||
&& this.month == today.getMonth()) {
|
&& this.month == today.getMonth()) {
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
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!'));
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,62 @@
|
||||||
|
<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>
|
|
@ -10,15 +10,7 @@ module.exports = new Class({
|
||||||
value: {
|
value: {
|
||||||
type: String
|
type: String
|
||||||
,set(x) {
|
,set(x) {
|
||||||
if (Vn.Value.compare(x, this._value))
|
this._setValue(x);
|
||||||
return;
|
|
||||||
|
|
||||||
if (x instanceof Date)
|
|
||||||
x = x.clone();
|
|
||||||
|
|
||||||
this.valueChanged(x);
|
|
||||||
this.putValue(x);
|
|
||||||
this._notifyChanges();
|
|
||||||
}
|
}
|
||||||
,get() {
|
,get() {
|
||||||
return this._value;
|
return this._value;
|
||||||
|
@ -109,11 +101,11 @@ module.exports = new Class({
|
||||||
,_lockField: false
|
,_lockField: false
|
||||||
|
|
||||||
,_setValue(newValue) {
|
,_setValue(newValue) {
|
||||||
if (!this._putValue(newValue))
|
if (!this._putValue(newValue)) return;
|
||||||
return;
|
newValue = this._value;
|
||||||
|
|
||||||
if (!this._lockField)
|
if (!this._lockField)
|
||||||
this.putValue(newValue);
|
this.putValue(this._value);
|
||||||
|
|
||||||
if (this.conditionalFunc)
|
if (this.conditionalFunc)
|
||||||
this.conditionalFunc(this, newValue);
|
this.conditionalFunc(this, newValue);
|
||||||
|
|
|
@ -3,22 +3,23 @@ require('db/db');
|
||||||
require('./style/index.scss');
|
require('./style/index.scss');
|
||||||
|
|
||||||
Htk = module.exports = {
|
Htk = module.exports = {
|
||||||
Popup : require('./popup')
|
Popup : require('./popup')
|
||||||
,Dialog : require('./dialog')
|
,Dialog : require('./dialog')
|
||||||
,Toast : require('./toast')
|
,Toast : require('./toast')
|
||||||
,Repeater : require('./repeater')
|
,Repeater : require('./repeater')
|
||||||
,Grid : require('./grid')
|
,Grid : require('./grid')
|
||||||
,Spinner : require('./spinner')
|
,Spinner : require('./spinner')
|
||||||
,Icon : require('./icon')
|
,Icon : require('./icon')
|
||||||
,FullImage : require('./full-image')
|
,FullImage : require('./full-image')
|
||||||
,ImageEditor : require('./image-editor')
|
,ImageEditor : require('./image-editor')
|
||||||
,Assistant : require('./assistant')
|
,Assistant : require('./assistant')
|
||||||
,AssistantBar : require('./assistant-bar')
|
,AssistantBar : require('./assistant-bar')
|
||||||
,Step : require('./step')
|
,Step : require('./step')
|
||||||
,Loader : require('./loader')
|
,Loader : require('./loader')
|
||||||
,List : require('./list')
|
,List : require('./list')
|
||||||
,Field : require('./field')
|
,Field : require('./field')
|
||||||
,Column : require('./column')
|
,Column : require('./column')
|
||||||
|
,ChangePassword : require('./change-password')
|
||||||
};
|
};
|
||||||
|
|
||||||
var Fields = {
|
var Fields = {
|
||||||
|
|
|
@ -192,7 +192,7 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onFileUpload(cell) {
|
,_onFileUpload(cell) {
|
||||||
this._stamp = new Date().getTime();
|
this._stamp = Date.vnNew().getTime();
|
||||||
this._refreshSrc(cell);
|
this._refreshSrc(cell);
|
||||||
this.popup.hide();
|
this.popup.hide();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ module.exports = new Class({
|
||||||
,render() {
|
,render() {
|
||||||
var radio = Vn.Browser.createRadio('', this.doc);
|
var radio = Vn.Browser.createRadio('', this.doc);
|
||||||
radio.checked = false;
|
radio.checked = false;
|
||||||
radio.addEventListener('change', this._onChange.bind(this));
|
radio.addEventListener('change', () => this._onChange());
|
||||||
this._node = radio;
|
this._node = radio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ var htkRadioGroupUid = 0;
|
||||||
module.exports = new Class({
|
module.exports = new Class({
|
||||||
Extends: Htk.Field
|
Extends: Htk.Field
|
||||||
,Tag: 'htk-radio-group'
|
,Tag: 'htk-radio-group'
|
||||||
|
|
||||||
,radioLock: false
|
|
||||||
|
|
||||||
,initialize(props) {
|
,initialize(props) {
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
|
@ -3,69 +3,61 @@
|
||||||
*/
|
*/
|
||||||
module.exports =
|
module.exports =
|
||||||
{
|
{
|
||||||
set: function (key, value, days)
|
set: function(key, value, days) {
|
||||||
{
|
|
||||||
var strCookie = key + '=' + value + ';';
|
var strCookie = key + '=' + value + ';';
|
||||||
|
|
||||||
if (days != undefined)
|
if (days != undefined) {
|
||||||
{
|
var date = Date.vnNew();
|
||||||
var date = new Date ();
|
date.setTime(date.getTime() + days * 86400000);
|
||||||
date.setTime (date.getTime () + days * 86400000);
|
strCookie += 'expires=' + date.toGMTString();
|
||||||
strCookie += 'expires=' + date.toGMTString ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.cookie = strCookie;
|
document.cookie = strCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
,unset: function (key)
|
,unset: function(key) {
|
||||||
{
|
this.set(key, '', -1);
|
||||||
this.set (key, '', -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,get: function (key)
|
,get: function(key) {
|
||||||
{
|
var cookie = new String(document.cookie);
|
||||||
var cookie = new String (document.cookie);
|
var start = cookie.indexOf(key + '=');
|
||||||
var start = cookie.indexOf (key + '=');
|
|
||||||
|
|
||||||
if (start != -1)
|
if (start != -1) {
|
||||||
{
|
|
||||||
var end;
|
var end;
|
||||||
|
|
||||||
start += key.length + 1;
|
start += key.length + 1;
|
||||||
end = cookie.indexOf (';', start);
|
end = cookie.indexOf(';', start);
|
||||||
|
|
||||||
if (end > 0)
|
if (end > 0)
|
||||||
return cookie.substring (start, end);
|
return cookie.substring(start, end);
|
||||||
else
|
else
|
||||||
return cookie.substring (start);
|
return cookie.substring(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
,getInt: function (key)
|
,getInt: function(key) {
|
||||||
{
|
var value = this.get(key);
|
||||||
var value = this.get (key);
|
|
||||||
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
return parseInt (value);
|
return parseInt(value);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
,getFloat: function (key)
|
,getFloat: function(key) {
|
||||||
{
|
var value = this.get(key);
|
||||||
var value = this.get (key);
|
|
||||||
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
return parseFloat (value);
|
return parseFloat(value);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
,check: function (key)
|
,check: function(key) {
|
||||||
{
|
return this.get(key) != null;
|
||||||
return this.get (key) != null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,22 @@ Date.prototype.clone = function() {
|
||||||
return new Date(this.getTime());
|
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 =
|
module.exports =
|
||||||
{
|
{
|
||||||
WDays: [
|
WDays: [
|
||||||
|
@ -55,7 +71,7 @@ module.exports =
|
||||||
,'Dec'
|
,'Dec'
|
||||||
]
|
]
|
||||||
|
|
||||||
,tokenD: '%A, %B %e'
|
,tokenD: '%A, %B %e %Y'
|
||||||
|
|
||||||
,regexp: new RegExp('%[a-zA-Z]', 'g')
|
,regexp: new RegExp('%[a-zA-Z]', 'g')
|
||||||
|
|
||||||
|
@ -101,7 +117,7 @@ module.exports =
|
||||||
// Year with 4 digits
|
// Year with 4 digits
|
||||||
case 'Y': return d.getFullYear();
|
case 'Y': return d.getFullYear();
|
||||||
|
|
||||||
// Complete date without year
|
// Complete date
|
||||||
case 'D': return _(this.tokenD).replace(this.regexp, this.regexpFunc.bind(this, d));
|
case 'D': return _(this.tokenD).replace(this.regexp, this.regexpFunc.bind(this, d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue