forked from verdnatura/hedera-web
Merge pull request 'test' (!18) from test into dev
Reviewed-on: verdnatura/hedera-web#18
This commit is contained in:
commit
326aeee127
|
@ -33,9 +33,9 @@ RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | apt-key add - \
|
||||||
> /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,4 +1,4 @@
|
||||||
hedera-web (22.48.5) stable; urgency=low
|
hedera-web (22.48.10) 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,6 +1,5 @@
|
||||||
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
|
||||||
|
|
|
@ -28,19 +28,25 @@ export default new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
,async onPassModifyClick() {
|
,async onPassModifyClick() {
|
||||||
var oldPassword = this.$.oldPassword.value;
|
const form = this.$.changePassword.node;
|
||||||
var newPassword = this.$.newPassword.value;
|
Vn.Node.disableInputs(form);
|
||||||
var repeatedPassword = this.$.repeatPassword.value;
|
try {
|
||||||
|
const oldPassword = this.$.oldPassword.value;
|
||||||
|
const newPassword = this.$.newPassword.value;
|
||||||
|
const repeatedPassword = this.$.repeatPassword.value;
|
||||||
|
|
||||||
|
try {
|
||||||
if (newPassword == '' && repeatedPassword == '')
|
if (newPassword == '' && repeatedPassword == '')
|
||||||
throw new Error(_('Passwords empty'));
|
throw new Error(_('Passwords empty'));
|
||||||
if (newPassword !== repeatedPassword)
|
if (newPassword !== repeatedPassword)
|
||||||
throw new Error(_('Passwords doesn\'t match'));
|
throw new Error(_('Passwords doesn\'t match'));
|
||||||
|
} catch (err) {
|
||||||
|
return Htk.Toast.showError(err.message);
|
||||||
|
}
|
||||||
|
|
||||||
var verificationToken = this.hash.$.verificationToken;
|
const verificationToken = this.hash.$.verificationToken;
|
||||||
var params = {newPassword};
|
const params = {newPassword};
|
||||||
|
|
||||||
let err;
|
|
||||||
try {
|
try {
|
||||||
if (verificationToken) {
|
if (verificationToken) {
|
||||||
params.verificationToken = verificationToken;
|
params.verificationToken = verificationToken;
|
||||||
|
@ -51,11 +57,10 @@ export default new Class({
|
||||||
await this.conn.patch(
|
await this.conn.patch(
|
||||||
`Accounts/${userId}/changePassword`, params);
|
`Accounts/${userId}/changePassword`, params);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(err) {
|
||||||
err = e;
|
|
||||||
Htk.Toast.showError(err.message);
|
Htk.Toast.showError(err.message);
|
||||||
|
|
||||||
if (this.hash.$.verificationToken)
|
if (verificationToken)
|
||||||
this.$.newPassword.select();
|
this.$.newPassword.select();
|
||||||
else
|
else
|
||||||
this.$.oldPassword.select();
|
this.$.oldPassword.select();
|
||||||
|
@ -63,10 +68,14 @@ export default new Class({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$.changePassword.hide();
|
|
||||||
this.hash.unset('verificationToken');
|
this.hash.unset('verificationToken');
|
||||||
|
await this.conn.open(this.gui.user.name, newPassword);
|
||||||
|
this.$.changePassword.hide();
|
||||||
|
} finally {
|
||||||
|
Vn.Node.disableInputs(form, false);
|
||||||
|
}
|
||||||
|
|
||||||
Htk.Toast.showMessage(_('Password changed!'));
|
Htk.Toast.showMessage(_('Password changed!'));
|
||||||
this.$.userForm.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,onPassInfoClick() {
|
,onPassInfoClick() {
|
||||||
|
|
|
@ -89,11 +89,13 @@
|
||||||
<input
|
<input
|
||||||
id="new-password"
|
id="new-password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="_New password"/>
|
placeholder="_New password"
|
||||||
|
autocomplete="new-password"/>
|
||||||
<input
|
<input
|
||||||
id="repeat-password"
|
id="repeat-password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="_Repeat password"/>
|
placeholder="_Repeat password"
|
||||||
|
autocomplete="new-password"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar">
|
<div class="button-bar">
|
||||||
<button class="thin" on-click="this.onPassModifyClick()">
|
<button class="thin" on-click="this.onPassModifyClick()">
|
||||||
|
|
|
@ -1,76 +1,77 @@
|
||||||
|
|
||||||
.basket .head {
|
.hedera-basket {
|
||||||
|
.head {
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
}
|
}
|
||||||
.basket .head p {
|
.head p {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.basket .form > p {
|
.form > p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lines */
|
/* Lines */
|
||||||
|
|
||||||
.basket .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;
|
||||||
}
|
}
|
||||||
.basket .line:first-child {
|
.line:first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
.basket .line:last-child {
|
.line:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.basket .line > .delete {
|
.line > .delete {
|
||||||
margin: 0 -8px;
|
margin: 0 -8px;
|
||||||
}
|
}
|
||||||
.basket .line > .photo {
|
.line > .photo {
|
||||||
flex: none;
|
flex: none;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 68px;
|
width: 68px;
|
||||||
height: 68px;
|
height: 68px;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
.basket .line > .info {
|
.line > .info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.basket .line > .info > * {
|
.line > .info > * {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.basket .line > .info > h2 {
|
.line > .info > h2 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.basket .line > .info > p {
|
.line > .info > p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.basket .line > .info > .tags {
|
.line > .info > .tags {
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
.basket .line .subtotal {
|
.line .subtotal {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fields */
|
/* Fields */
|
||||||
|
|
||||||
.basket td.available-exceeded input {
|
td.available-exceeded input {
|
||||||
background-color: #FCC;
|
background-color: #FCC;
|
||||||
}
|
}
|
||||||
.basket .icon > img {
|
.icon > img {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
tip="_Checkout"
|
tip="_Checkout"
|
||||||
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/>
|
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="basket">
|
<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>
|
<p>
|
||||||
|
|
|
@ -1,54 +1,55 @@
|
||||||
|
|
||||||
.checkout .bar {
|
.hedera-checkout {
|
||||||
|
.bar {
|
||||||
margin-bottom: 16px;
|
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 {
|
.answers .htk-select {
|
||||||
max-width: 15em;
|
max-width: 15em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
}
|
}
|
||||||
.answers p {
|
.answers p {
|
||||||
margin: 0.3em 0;
|
margin: 0.3em 0;
|
||||||
}
|
}
|
||||||
.target {
|
.target {
|
||||||
max-width: 28em;
|
max-width: 28em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.address {
|
.address {
|
||||||
border-radius: 0.1em;
|
border-radius: 0.1em;
|
||||||
padding: 0.6em 1.4em;
|
padding: 0.6em 1.4em;
|
||||||
}
|
}
|
||||||
.address.selected {
|
.address.selected {
|
||||||
background-color: rgba(1, 1, 1, .1);
|
background-color: rgba(1, 1, 1, .1);
|
||||||
}
|
}
|
||||||
.address:hover {
|
.address:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: rgba(1, 1, 1, .05);
|
background-color: rgba(1, 1, 1, .05);
|
||||||
}
|
}
|
||||||
.address p.consignee {
|
.address p.consignee {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.radio {
|
.radio {
|
||||||
max-width: 20em;
|
max-width: 20em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.radio > div {
|
.radio > div {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
.thin-calendar {
|
.thin-calendar {
|
||||||
max-width: 24em;
|
max-width: 24em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
.htk-assistant .thin {
|
.htk-assistant .thin {
|
||||||
float: right;
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,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
|
||||||
|
|
|
@ -106,25 +106,18 @@ 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 myBasket_confirm');
|
||||||
|
|
||||||
onConfirm(query, resultSet) {
|
|
||||||
this.disableButtons(false);
|
|
||||||
|
|
||||||
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 {
|
||||||
|
.summary {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
.confirm p {
|
p {
|
||||||
margin: .2em 0;
|
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;
|
||||||
}
|
}
|
||||||
.confirm .payment > .button-bar {
|
.payment > .button-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
}
|
}
|
||||||
.confirm .payment > .button-bar button{
|
.payment > .button-bar button{
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
border-radius: 2rem;
|
border-radius: 2rem;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.confirm .modify-order {
|
.modify-order {
|
||||||
border: 1px solid #1a1a1a;
|
border: 1px solid #1a1a1a;
|
||||||
}
|
}
|
||||||
.confirm .modify-order:hover {
|
.modify-order:hover {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #1a1a1a;
|
background-color: #1a1a1a;
|
||||||
}
|
}
|
||||||
.confirm .confirm-order {
|
.confirm-order {
|
||||||
border: 1px solid #8cc63f;
|
border: 1px solid #8cc63f;
|
||||||
background-color: #8cc63f;
|
background-color: #8cc63f;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.confirm .confirm-order:hover {
|
.confirm-order:hover {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #6b5;
|
color: #6b5;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,14 +23,11 @@
|
||||||
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>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<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">
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
.ticket .line:last-child {
|
.line:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.ticket .line > .photo {
|
.line > .photo {
|
||||||
flex: none;
|
flex: none;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 68px;
|
width: 68px;
|
||||||
height: 68px;
|
height: 68px;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
.ticket .line > .info {
|
.line > .info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.ticket .line > .info > * {
|
.line > .info > * {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.ticket .line > .info > h2 {
|
.line > .info > h2 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
.ticket .line > .info > p {
|
.line > .info > p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.ticket .line > .info > .tags {
|
.line > .info > .tags {
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
.ticket .line > .info .discount {
|
.line > .info .discount {
|
||||||
color: green;
|
color: green;
|
||||||
}
|
}
|
||||||
.ticket .line > .info > .subtotal {
|
.line > .info > .subtotal {
|
||||||
float: right;
|
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>
|
||||||
|
|
|
@ -198,11 +198,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;
|
||||||
}
|
}
|
||||||
|
@ -222,8 +222,8 @@ module.exports = new Class({
|
||||||
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
Htk.Toast.showError(_('You don\'t have enough privileges'));
|
||||||
else {
|
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)
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -120,6 +117,12 @@ module.exports = new Class({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
,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)
|
||||||
return;
|
return;
|
||||||
|
@ -474,11 +477,8 @@ module.exports = new Class({
|
||||||
this._conn.token = json;
|
this._conn.token = json;
|
||||||
sessionStorage.setItem('supplantUser', supplantUser);
|
sessionStorage.setItem('supplantUser', supplantUser);
|
||||||
|
|
||||||
const resultSet = await this._conn.execQuery(
|
await this.refreshUserData();
|
||||||
'SELECT nickname FROM account.myUser');
|
Vn.Node.setText(this.$.supplanted, this.user.nickname);
|
||||||
|
|
||||||
const userName = resultSet.fetchValue();
|
|
||||||
Vn.Node.setText(this.$.supplanted, userName);
|
|
||||||
this.$.supplant.classList.toggle('show', true);
|
this.$.supplant.classList.toggle('show', true);
|
||||||
await this.loadMenu();
|
await this.loadMenu();
|
||||||
}
|
}
|
||||||
|
@ -492,6 +492,7 @@ module.exports = new Class({
|
||||||
sessionStorage.removeItem('supplantUser');
|
sessionStorage.removeItem('supplantUser');
|
||||||
|
|
||||||
this.$.supplant.classList.toggle('show', false);
|
this.$.supplant.classList.toggle('show', false);
|
||||||
|
await this.refreshUserData();
|
||||||
await this.loadMenu();
|
await this.loadMenu();
|
||||||
this._onFormChange();
|
this._onFormChange();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -29,11 +28,11 @@ module.exports = new Class({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const json = await this.conn.send('tpv/transaction', {
|
const json = await this.conn.post('TpvTransactions/start', {
|
||||||
amount: parseInt(amount)
|
amount: parseInt(amount),
|
||||||
,urlOk: this._makeUrl('ok')
|
urlOk: this._makeUrl('ok'),
|
||||||
,urlKo: this._makeUrl('ko')
|
urlKo: this._makeUrl('ko'),
|
||||||
,company
|
company
|
||||||
});
|
});
|
||||||
|
|
||||||
const postValues = json.postValues;
|
const postValues = json.postValues;
|
||||||
|
|
|
@ -50,9 +50,8 @@ module.exports = new Class({
|
||||||
|
|
||||||
if (user !== null && user !== undefined) {
|
if (user !== null && user !== undefined) {
|
||||||
params = {
|
params = {
|
||||||
user: user,
|
user,
|
||||||
password: pass,
|
password: pass
|
||||||
remember: remember
|
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
params = null;
|
params = null;
|
||||||
|
@ -261,7 +260,7 @@ module.exports = new Class({
|
||||||
if (exception) {
|
if (exception) {
|
||||||
exception = exception
|
exception = exception
|
||||||
.replace(/\\/g, '.')
|
.replace(/\\/g, '.')
|
||||||
.replace(/Exception$/, '')
|
.replace(/Exception$/, 'Error')
|
||||||
.replace(/^Vn\.Web\./, '');
|
.replace(/^Vn\.Web\./, '');
|
||||||
|
|
||||||
err.exception = exception;
|
err.exception = exception;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds a plain key-value javascript object and monitorizes changes over it.
|
* Holds a plain key-value javascript object and monitorizes changes over it.
|
||||||
*/
|
*/
|
||||||
|
@ -10,14 +9,14 @@ module.exports = new Class({
|
||||||
*/
|
*/
|
||||||
params: {
|
params: {
|
||||||
type: Object
|
type: Object
|
||||||
}
|
},
|
||||||
/**
|
/**
|
||||||
* Shortcut for params property.
|
* Shortcut for params property.
|
||||||
*/
|
*/
|
||||||
,$: {
|
$: {
|
||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a value from the lot.
|
* Gets a value from the lot.
|
||||||
|
@ -25,9 +24,9 @@ module.exports = new Class({
|
||||||
* @param {string} field The field name
|
* @param {string} field The field name
|
||||||
* @return {*} The field value
|
* @return {*} The field value
|
||||||
*/
|
*/
|
||||||
,get(field) {
|
get(field) {
|
||||||
return this.params[field];
|
return this.params[field];
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a value on the lot.
|
* Sets a value on the lot.
|
||||||
|
@ -35,48 +34,50 @@ module.exports = new Class({
|
||||||
* @param {string} field The field name
|
* @param {string} field The field name
|
||||||
* @param {*} value The new field value
|
* @param {*} value The new field value
|
||||||
*/
|
*/
|
||||||
,set(field, value) {
|
set(field, value) {
|
||||||
var params = {};
|
this.assign({[field]: value});
|
||||||
params[field] = value;
|
},
|
||||||
this.assign(params);
|
|
||||||
}
|
unset(field) {
|
||||||
|
this.assign({[field]: undefined});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array with the lot keys.
|
* Returns an array with the lot keys.
|
||||||
*
|
*
|
||||||
* @return {Array} The lot keys
|
* @return {Array} The lot keys
|
||||||
*/
|
*/
|
||||||
,keys() {}
|
keys() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits the 'change' signal on the lot.
|
* Emits the 'change' signal on the lot.
|
||||||
*
|
*
|
||||||
* @param {Object} changes The changed params and its values
|
* @param {Object} changes The changed params and its values
|
||||||
*/
|
*/
|
||||||
,changed(changes) {
|
changed(changes) {
|
||||||
this.emit('change', changes);
|
this.emit('change', changes);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies all values from another lot.
|
* Copies all values from another lot.
|
||||||
*
|
*
|
||||||
* @param {Object} object The source object
|
* @param {Object} object The source object
|
||||||
*/
|
*/
|
||||||
,assign() {}
|
assign() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies all values from another lot.
|
* Copies all values from another lot.
|
||||||
*
|
*
|
||||||
* @param {LotIface} lot The source lot
|
* @param {LotIface} lot The source lot
|
||||||
*/
|
*/
|
||||||
,assignLot(lot) {
|
assignLot(lot) {
|
||||||
this.assign(lot.$);
|
this.assign(lot.$);
|
||||||
}
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all values.
|
* Resets all values.
|
||||||
*/
|
*/
|
||||||
,reset() {
|
reset() {
|
||||||
this.params = {};
|
this.params = {};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,66 +1,63 @@
|
||||||
|
|
||||||
module.exports =
|
module.exports = {
|
||||||
{
|
removeChilds(node) {
|
||||||
removeChilds: function (node)
|
|
||||||
{
|
|
||||||
var childs = node.childNodes;
|
var childs = node.childNodes;
|
||||||
|
|
||||||
if (childs)
|
if (childs)
|
||||||
while (childs.length > 0)
|
while (childs.length > 0)
|
||||||
node.removeChild (childs[0]);
|
node.removeChild(childs[0]);
|
||||||
}
|
},
|
||||||
|
|
||||||
,remove: function (node)
|
remove(node) {
|
||||||
{
|
|
||||||
if (node.parentNode)
|
if (node.parentNode)
|
||||||
node.parentNode.removeChild (node);
|
node.parentNode.removeChild(node);
|
||||||
}
|
},
|
||||||
|
|
||||||
,setText: function (node, text)
|
setText(node, text) {
|
||||||
{
|
Vn.Node.removeChilds(node);
|
||||||
Vn.Node.removeChilds (node);
|
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
node.appendChild (
|
node.appendChild(
|
||||||
node.ownerDocument.createTextNode (text));
|
node.ownerDocument.createTextNode(text));
|
||||||
}
|
},
|
||||||
|
|
||||||
,addClass: function (node, className)
|
addClass(node, className) {
|
||||||
{
|
/* var classes = node.className.split(' ');
|
||||||
/* var classes = node.className.split (' ');
|
|
||||||
|
|
||||||
if (classes.split (' ').indexOf (className) == -1)
|
if (classes.split(' ').indexOf(className) == -1)
|
||||||
*/ node.className = className +' '+ node.className;
|
*/ node.className = className +' '+ node.className;
|
||||||
}
|
},
|
||||||
|
|
||||||
,removeClass: function (node, className)
|
removeClass(node, className) {
|
||||||
{
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var found = false;
|
var found = false;
|
||||||
var classes = node.className.split (' ');
|
var classes = node.className.split(' ');
|
||||||
|
|
||||||
while ((index = classes.indexOf (className, index)) != -1)
|
while ((index = classes.indexOf(className, index)) != -1) {
|
||||||
{
|
classes.splice(index, 1);
|
||||||
classes.splice (index, 1);
|
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
node.className = classes.join (' ');
|
node.className = classes.join(' ');
|
||||||
}
|
},
|
||||||
|
|
||||||
,hide: function (node)
|
hide: function(node) {
|
||||||
{
|
|
||||||
node.style.display = 'none';
|
node.style.display = 'none';
|
||||||
}
|
},
|
||||||
|
|
||||||
,show: function (node)
|
show: function(node) {
|
||||||
{
|
|
||||||
node.style.display = 'block';
|
node.style.display = 'block';
|
||||||
|
},
|
||||||
|
|
||||||
|
disableInputs(formNode, disable = true) {
|
||||||
|
const inputs = formNode
|
||||||
|
.querySelectorAll('input, textarea, button, select');
|
||||||
|
for (const input of inputs)
|
||||||
|
input.disabled = disable;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$ = function (id)
|
$ = function(id) {
|
||||||
{
|
return document.getElementById(id);
|
||||||
return document.getElementById (id);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hedera-web",
|
"name": "hedera-web",
|
||||||
"version": "22.48.5",
|
"version": "22.48.10",
|
||||||
"description": "Verdnatura web page",
|
"description": "Verdnatura web page",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
|
@ -1,2 +1,4 @@
|
||||||
UpdateYourBrowser: Actualitza el teu navegador
|
UpdateYourBrowser: Actualitza el teu navegador
|
||||||
ContinueAnyway: Continuar igualment
|
ContinueAnyway: Continuar igualment
|
||||||
|
BrowserVersionNotCompatible: El vostre navegador no és compatible amb aquesta versió de la pàgina web
|
||||||
|
PushHereToInstallFirefox: Clica aquí per instal·lar Firefox
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
UpdateYourBrowser: Upgrade your browser
|
UpdateYourBrowser: Upgrade your browser
|
||||||
ContinueAnyway: Continue anyway
|
ContinueAnyway: Continue anyway
|
||||||
|
BrowserVersionNotCompatible: Your browser is not compatible with this version of the website
|
||||||
|
PushHereToInstallFirefox: Click here to install Firefox
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
UpdateYourBrowser: Actualiza tu navegador
|
UpdateYourBrowser: Actualiza tu navegador
|
||||||
ContinueAnyway: Continuar de todos modos
|
ContinueAnyway: Continuar de todos modos
|
||||||
|
BrowserVersionNotCompatible: Tu navegador no es compatible con esta versión de la página web
|
||||||
|
PushHereToInstallFirefox: Pulsa aquí para instalar Firefox
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
UpdateYourBrowser: Mettez à jour votre navigateur
|
UpdateYourBrowser: Mettez à jour votre navigateur
|
||||||
ContinueAnyway: Continuer
|
ContinueAnyway: Continuer
|
||||||
|
BrowserVersionNotCompatible: Votre navigateur n'est pas compatible avec cette version du site
|
||||||
|
PushHereToInstallFirefox: Cliquez ici pour installer Firefox
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
UpdateYourBrowser: Upgrade your browser
|
|
||||||
ContinueAnyway: Continue anyway
|
|
|
@ -1,2 +1,4 @@
|
||||||
UpdateYourBrowser: Atualize seu navegador
|
UpdateYourBrowser: Atualize seu navegador
|
||||||
ContinueAnyway: Continuar de todas maneiras
|
ContinueAnyway: Continuar de todas maneiras
|
||||||
|
BrowserVersionNotCompatible: Seu navegador não é compatível com esta versão do site
|
||||||
|
PushHereToInstallFirefox: Clique aqui para instalar o Firefox
|
||||||
|
|
|
@ -1,26 +1,53 @@
|
||||||
*
|
* {
|
||||||
{
|
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
}
|
}
|
||||||
img
|
.box {
|
||||||
{
|
text-align: center;
|
||||||
position: absolute;
|
margin: 0 auto;
|
||||||
margin-top: -200px;
|
max-width: 380px;
|
||||||
margin-left: -200px;
|
padding: 40px;
|
||||||
top: 50%;
|
padding-bottom: 60px;
|
||||||
left: 50%;
|
|
||||||
}
|
}
|
||||||
#continue
|
.logo {
|
||||||
{
|
padding: 5px;
|
||||||
position: absolute;
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
.browser-logo {
|
||||||
|
display: block;
|
||||||
|
margin: 30px auto;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
.download {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
a
|
.continue {
|
||||||
{
|
color: white;
|
||||||
color: #444;
|
background-color: #8cc63f;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.continue:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #7eb239;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #6a1;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,20 +2,35 @@
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
<meta name="viewport" content="user-scalable=no"/>
|
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=no"/>
|
||||||
<meta name="content-language" content="<?=$lang?>"/>
|
<meta name="content-language" content="<?=$lang?>"/>
|
||||||
<link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css"/>
|
<link href="//fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css"/>
|
||||||
<?=css("$dir/style")?>
|
<?=css("$dir/style")?>
|
||||||
<title>Verdnatura</title>
|
<title>Verdnatura</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div class="box">
|
||||||
<a href="http://www.mozilla.org/es-ES/firefox/new/" target="_blank">
|
<img
|
||||||
<img src="<?=$dir?>/update-browser.png" alt="<?=s('UpdateYourBrowser')?>"></img>
|
class="logo"
|
||||||
|
src="image/logo.png"
|
||||||
|
alt="VerdNatura">
|
||||||
|
</img>
|
||||||
|
<h2><?=s('BrowserVersionNotCompatible')?></h2>
|
||||||
|
<a
|
||||||
|
class="download"
|
||||||
|
href="http://www.mozilla.org/firefox/new/"
|
||||||
|
target="_blank">
|
||||||
|
<img
|
||||||
|
class="browser-logo"
|
||||||
|
src="<?=$dir?>/firefox.png"
|
||||||
|
alt="Firefox">
|
||||||
|
</img>
|
||||||
|
<?=s('PushHereToInstallFirefox')?>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="continue">
|
<div class="bottom">
|
||||||
<a href="?skipBrowser=true">
|
<a class="continue"
|
||||||
|
href="?skipBrowser=true">
|
||||||
<?=s('ContinueAnyway')?>
|
<?=s('ContinueAnyway')?>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB |
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"Recover password": "Recover password",
|
|
||||||
"Press on the following link to change your password.": "Press on the following link to change your password."
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
recoverPassword: Recover password
|
||||||
|
pressLinkToRecoverPassword: Press on the following link to change your password.
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"Recover password": "Restaurar contraseña",
|
|
||||||
"Press on the following link to change your password.": "Pulsa en el siguiente link para cambiar tu contraseña."
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
recoverPassword: Restaurar contraseña
|
||||||
|
pressLinkToRecoverPassword: Pulsa en el siguiente link para cambiar tu contraseña.
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"Recover password": "Réinitialisation du mot de passe",
|
|
||||||
"Press on the following link to change your password.": "Appuyez sur le lien suivant pour changer votre mot de passe."
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
recoverPassword: Réinitialisation du mot de passe
|
||||||
|
pressLinkToRecoverPassword: Appuyez sur le lien suivant pour changer votre mot de passe.
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"Recover password": "Recuperar palavra-passe",
|
|
||||||
"Press on the following link to change your password.": "Pressione o botão para modificar sua palavra-passe."
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
recoverPassword: Recuperar palavra-passe
|
||||||
|
pressLinkToRecoverPassword: Pressione o botão para modificar sua palavra-passe.
|
|
@ -1,7 +1,7 @@
|
||||||
<?php $title = s('Recover password') ?>
|
<?php $title = s('recoverPassword') ?>
|
||||||
<p>
|
<p>
|
||||||
<?=s('Press on the following link to change your password.')?>
|
<?=s('pressLinkToRecoverPassword')?>
|
||||||
</p>
|
</p>
|
||||||
<a href="<?=$url?>">
|
<a href="<?=$url?>">
|
||||||
<?=s('Recover password')?>
|
<?=s('recoverPassword')?>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Supplant extends Vn\Web\JsonRequest {
|
||||||
'SELECT id FROM account.user WHERE `name` = #',
|
'SELECT id FROM account.user WHERE `name` = #',
|
||||||
[$_REQUEST['supplantUser']]
|
[$_REQUEST['supplantUser']]
|
||||||
);
|
);
|
||||||
|
/*
|
||||||
$isClient = $db->getValue(
|
$isClient = $db->getValue(
|
||||||
'SELECT COUNT(*) > 0 FROM vn.client WHERE id = #',
|
'SELECT COUNT(*) > 0 FROM vn.client WHERE id = #',
|
||||||
[$userId]
|
[$userId]
|
||||||
|
@ -24,7 +24,7 @@ class Supplant extends Vn\Web\JsonRequest {
|
||||||
);
|
);
|
||||||
if ($hasAccount)
|
if ($hasAccount)
|
||||||
throw new Web\ForbiddenException(s('The user is not impersonable'));
|
throw new Web\ForbiddenException(s('The user is not impersonable'));
|
||||||
|
*/
|
||||||
return $this->service->createToken($_REQUEST['supplantUser']);
|
return $this->service->createToken($_REQUEST['supplantUser']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"InvalidAction": "Acció invàlida"
|
|
||||||
|
|
||||||
,"EmptyQuery": "Consulta buida"
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
InvalidAction: Acció invàlida
|
||||||
|
EmptyQuery: Consulta buida
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"InvalidAction": "Invalid action"
|
|
||||||
|
|
||||||
,"EmptyQuery": "Empty query"
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
InvalidAction: Invalid action
|
||||||
|
EmptyQuery: Empty query
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"InvalidAction": "Acción inválida"
|
|
||||||
,"EmptyQuery": "Consulta vacía"
|
|
||||||
,"Invalid password": "Contraseña inválida"
|
|
||||||
,"Password does not meet requirements":
|
|
||||||
"La nueva contraseña no reune los requisitos de seguridad necesarios"
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
InvalidAction: Acción inválida
|
||||||
|
EmptyQuery: Consulta vacía
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"InvalidAction": "Action non valide"
|
|
||||||
|
|
||||||
,"EmptyQuery": "Requête vide"
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
InvalidAction: Action non valide
|
||||||
|
EmptyQuery: Requête vide
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"InvalidAction": "Ação Inválida"
|
|
||||||
|
|
||||||
,"EmptyQuery": "Consulta vazía"
|
|
||||||
}
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
InvalidAction: Ação Inválida
|
||||||
|
EmptyQuery: Consulta vazía
|
|
@ -22,8 +22,6 @@ class Query extends Vn\Web\JsonRequest {
|
||||||
|
|
||||||
function run($db) {
|
function run($db) {
|
||||||
$results = [];
|
$results = [];
|
||||||
|
|
||||||
try {
|
|
||||||
$db->multiQuery($_REQUEST['sql']);
|
$db->multiQuery($_REQUEST['sql']);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -37,8 +35,6 @@ class Query extends Vn\Web\JsonRequest {
|
||||||
}
|
}
|
||||||
while ($db->moreResults() && $db->nextResult());
|
while ($db->moreResults() && $db->nextResult());
|
||||||
|
|
||||||
// Checks for warnings
|
|
||||||
|
|
||||||
if ($db->checkWarnings()
|
if ($db->checkWarnings()
|
||||||
&&($result = $db->query('SHOW WARNINGS'))) {
|
&&($result = $db->query('SHOW WARNINGS'))) {
|
||||||
$sql = 'SELECT `description`, @warn `code`
|
$sql = 'SELECT `description`, @warn `code`
|
||||||
|
@ -53,22 +49,7 @@ class Query extends Vn\Web\JsonRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for errors
|
|
||||||
|
|
||||||
$db->checkError();
|
$db->checkError();
|
||||||
} catch (Vn\Db\Exception $e) {
|
|
||||||
if ($e->getCode() == 1644) {
|
|
||||||
$dbMessage = $e->getMessage();
|
|
||||||
$sql = 'SELECT `description` FROM `message` WHERE `code` = #';
|
|
||||||
$message = $db->getValue($sql, [$dbMessage]);
|
|
||||||
|
|
||||||
if ($message)
|
|
||||||
throw new Lib\UserException($message, $dbMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"Cant lock cache": "The cache could not be blocked"
|
|
||||||
,"Bad file format": "Unrecognized file format"
|
|
||||||
,"File not choosed": "You have not selected any file"
|
|
||||||
,"Permission denied": "You are not allowed to upload the file"
|
|
||||||
,"File upload error": "Failed to upload the file, check that size is not too large"
|
|
||||||
,"File save error": "Failed to save the file: %s"
|
|
||||||
,"File size error": "The file must be no longer than %.2f MB"
|
|
||||||
,"Bad file name": "The file name must contain only lowercase letters, digits or the '_' character"
|
|
||||||
,"Bad collection name": "Invalid collection name"
|
|
||||||
,"Collection not exists": "Collection does not exist"
|
|
||||||
,"Unreferenced file": "The file is not referenced by the database"
|
|
||||||
,"Cannot update matching id": "Cannot update matching id"
|
|
||||||
,"Com error": "Error communicating with the server"
|
|
||||||
,"Image open error": "Error opening the image file"
|
|
||||||
,"Operation disabled": "Operation disabled for security"
|
|
||||||
,"Image added": "Image added correctly"
|
|
||||||
|
|
||||||
,"ErrIniSize": "File exceeds the upload_max_filesize directive in php.ini"
|
|
||||||
,"ErrFormSize": "File exceeds the MAX_FILE_SIZE specified in the HTML form"
|
|
||||||
,"ErrPartial": "File was partially uploaded"
|
|
||||||
,"ErrNoFile": "No file was uploaded"
|
|
||||||
,"ErrNoTmpDir": "Missing a temporary folder"
|
|
||||||
,"ErrCantWrite": "Failed to write file to disk"
|
|
||||||
,"ErrExtension": "File upload stopped by extension"
|
|
||||||
,"ErrDefault": "Unknown upload error"
|
|
||||||
|
|
||||||
,"Sync complete": "Synchronization complete"
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
Cant lock cache: The cache could not be blocked
|
||||||
|
Bad file format: Unrecognized file format
|
||||||
|
File not choosed: You have not selected any file
|
||||||
|
Permission denied: You are not allowed to upload the file
|
||||||
|
File upload error: Failed to upload the file, check that size is not too large
|
||||||
|
File save error: 'Failed to save the file: %s'
|
||||||
|
File size error: The file must be no longer than %.2f MB
|
||||||
|
Bad file name: 'The file name must contain only lowercase letters, digits or the ''_'' character'
|
||||||
|
Bad collection name: Invalid collection name
|
||||||
|
Collection not exists: Collection does not exist
|
||||||
|
Unreferenced file: The file is not referenced by the database
|
||||||
|
Cannot update matching id: Cannot update matching id
|
||||||
|
Com error: Error communicating with the server
|
||||||
|
Image open error: Error opening the image file
|
||||||
|
Operation disabled: Operation disabled for security
|
||||||
|
Image added: Image added correctly
|
||||||
|
|
||||||
|
ErrIniSize: File exceeds the upload_max_filesize directive in php.ini
|
||||||
|
ErrFormSize: File exceeds the MAX_FILE_SIZE specified in the HTML form
|
||||||
|
ErrPartial: File was partially uploaded
|
||||||
|
ErrNoFile: No file was uploaded
|
||||||
|
ErrNoTmpDir: Missing a temporary folder
|
||||||
|
ErrCantWrite: Failed to write file to disk
|
||||||
|
ErrExtension: File upload stopped by extension
|
||||||
|
ErrDefault: Unknown upload error
|
||||||
|
|
||||||
|
Sync complete: Synchronization complete
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"Cant lock cache": "La caché no pudo ser bloqueada"
|
|
||||||
,"Bad file format": "Formato de archivo no reconocido"
|
|
||||||
,"File not choosed": "No has seleccionado ningún archivo"
|
|
||||||
,"Permission denied": "No tienes permiso para subir el fichero"
|
|
||||||
,"File upload error": "Error al subir el fichero, comprueba que su tamaño no sea demasiado grande"
|
|
||||||
,"File save error": "Error al guardar el fichero: %s"
|
|
||||||
,"File size error": "El fichero no debe ocupar más de %.2f MB"
|
|
||||||
,"Bad file name": "El nombre del archivo solo debe contener letras minúsculas, dígitos o el carácter '_'"
|
|
||||||
,"Bad collection name": "Nombre de colección no válido"
|
|
||||||
,"Collection not exists": "La colección no existe"
|
|
||||||
,"Unreferenced file": "El archivo no está referenciado por la base de datos"
|
|
||||||
,"Cannot update matching id": "No es posible actualizar los ítems con id coincidente"
|
|
||||||
,"Com error": "Error en la comunicación con el servidor"
|
|
||||||
,"Image open error": "Error al abrir el archivo de imagen"
|
|
||||||
,"Operation disabled": "Operación deshabilitada por seguridad"
|
|
||||||
,"Image added": "Imagen añadida correctamente"
|
|
||||||
|
|
||||||
,"ErrIniSize": "File exceeds the upload_max_filesize directive in php.ini"
|
|
||||||
,"ErrFormSize": "File exceeds the MAX_FILE_SIZE specified in the HTML form"
|
|
||||||
,"ErrPartial": "File was partially uploaded"
|
|
||||||
,"ErrNoFile": "No file was uploaded"
|
|
||||||
,"ErrNoTmpDir": "Missing a temporary folder"
|
|
||||||
,"ErrCantWrite": "Failed to write file to disk"
|
|
||||||
,"ErrExtension": "File upload stopped by extension"
|
|
||||||
,"ErrDefault": "Unknown upload error"
|
|
||||||
|
|
||||||
,"Sync complete": "Sincronización completada"
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
Cant lock cache: La caché no pudo ser bloqueada
|
||||||
|
Bad file format: Formato de archivo no reconocido
|
||||||
|
File not choosed: No has seleccionado ningún archivo
|
||||||
|
Permission denied: No tienes permiso para subir el fichero
|
||||||
|
File upload error: Error al subir el fichero, comprueba que su tamaño no sea demasiado grande
|
||||||
|
File save error: 'Error al guardar el fichero: %s'
|
||||||
|
File size error: El fichero no debe ocupar más de %.2f MB
|
||||||
|
Bad file name: 'El nombre del archivo solo debe contener letras minúsculas, dígitos o el carácter ''_'''
|
||||||
|
Bad collection name: Nombre de colección no válido
|
||||||
|
Collection not exists: La colección no existe
|
||||||
|
Unreferenced file: El archivo no está referenciado por la base de datos
|
||||||
|
Cannot update matching id: No es posible actualizar los ítems con id coincidente
|
||||||
|
Com error: Error en la comunicación con el servidor
|
||||||
|
Image open error: Error al abrir el archivo de imagen
|
||||||
|
Operation disabled: Operación deshabilitada por seguridad
|
||||||
|
Image added: Imagen añadida correctamente
|
||||||
|
|
||||||
|
ErrIniSize: File exceeds the upload_max_filesize directive in php.ini
|
||||||
|
ErrFormSize: File exceeds the MAX_FILE_SIZE specified in the HTML form
|
||||||
|
ErrPartial: File was partially uploaded
|
||||||
|
ErrNoFile: No file was uploaded
|
||||||
|
ErrNoTmpDir: Missing a temporary folder
|
||||||
|
ErrCantWrite: Failed to write file to disk
|
||||||
|
ErrExtension: File upload stopped by extension
|
||||||
|
ErrDefault: Unknown upload error
|
||||||
|
|
||||||
|
Sync complete: Sincronización completada
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"Cant lock cache": "O cache não pôde ser bloqueado"
|
|
||||||
,"Bad file format": "Formato de arquivo inválido"
|
|
||||||
,"File not choosed": "Não selecionastes nenhum arquivo"
|
|
||||||
,"Permission denied": "Não estas autorizado a subir o arquivo"
|
|
||||||
,"File upload error": "Erro ao subir o arquivo, verifique o tamanho"
|
|
||||||
,"File save error": "Erro ao salvar o arquivo: %s"
|
|
||||||
,"File size error": "O arquivo não deve ser maior que: %.2f MB"
|
|
||||||
,"Bad file name": "O nome do arquivo deve conter somente letras minusculas, numeros ou '_' "
|
|
||||||
,"Bad collection name": "Nome de coleção inválido"
|
|
||||||
,"Collection not exists": "Coleção não existe"
|
|
||||||
,"Unreferenced file": "O arquivo não é referenciado pelo banco de dados"
|
|
||||||
,"Cannot update matching id": "Não é possível atualizar os itens com id coincidente"
|
|
||||||
,"Com error": "Erro de comunicação com o servidor"
|
|
||||||
,"Image open error": "Erro ao abrir a imagem"
|
|
||||||
,"Operation disabled": "Operação desativada por segurança"
|
|
||||||
,"Image added": "Imagem adicionada corretamente"
|
|
||||||
|
|
||||||
,"ErrIniSize": "Arquivo supera o tamanho maximo de protocolo em php.ini"
|
|
||||||
,"ErrFormSize": "Arquivo supera o tamanho maximo de protocolo em HTML form"
|
|
||||||
,"ErrPartial": "Arquivo subido parcialmente"
|
|
||||||
,"ErrNoFile": "Nenhum arquivo subido"
|
|
||||||
,"ErrNoTmpDir": "Falta a pasta de arquivo temporal"
|
|
||||||
,"ErrCantWrite": "Erro ao gravar arquivo no disco"
|
|
||||||
,"ErrExtension": "Erro de extensão do arquivo"
|
|
||||||
,"ErrDefault": "Erro desconhecido ao subir arquivo"
|
|
||||||
|
|
||||||
,"Sync complete": "Sincronização completa"
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
Cant lock cache: O cache não pôde ser bloqueado
|
||||||
|
Bad file format: Formato de arquivo inválido
|
||||||
|
File not choosed: Não selecionastes nenhum arquivo
|
||||||
|
Permission denied: Não estas autorizado a subir o arquivo
|
||||||
|
File upload error: Erro ao subir o arquivo, verifique o tamanho
|
||||||
|
File save error: 'Erro ao salvar o arquivo: %s'
|
||||||
|
File size error: O arquivo não deve ser maior que %.2f MB
|
||||||
|
Bad file name: 'O nome do arquivo deve conter somente letras minusculas, numeros ou ''_'''
|
||||||
|
Bad collection name: Nome de coleção inválido
|
||||||
|
Collection not exists: Coleção não existe
|
||||||
|
Unreferenced file: O arquivo não é referenciado pelo banco de dados
|
||||||
|
Cannot update matching id: Não é possível atualizar os itens com id coincidente
|
||||||
|
Com error: Erro de comunicação com o servidor
|
||||||
|
Image open error: Erro ao abrir a imagem
|
||||||
|
Operation disabled: Operação desativada por segurança
|
||||||
|
Image added: Imagem adicionada corretamente
|
||||||
|
|
||||||
|
ErrIniSize: Arquivo supera o tamanho maximo de protocolo em php.ini
|
||||||
|
ErrFormSize: Arquivo supera o tamanho maximo de protocolo em HTML form
|
||||||
|
ErrPartial: Arquivo subido parcialmente
|
||||||
|
ErrNoFile: Nenhum arquivo subido
|
||||||
|
ErrNoTmpDir: Falta a pasta de arquivo temporal
|
||||||
|
ErrCantWrite: Erro ao gravar arquivo no disco
|
||||||
|
ErrExtension: Erro de extensão do arquivo
|
||||||
|
ErrDefault: Erro desconhecido ao subir arquivo
|
||||||
|
|
||||||
|
Sync complete: Sincronização completa
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"An automated message could not be delivered": "Un mensaje automatizado no se ha podido entregar"
|
|
||||||
,"Notification from IT department about problem.": "Desde el departamento de informática te enviamos este correo porque ha habido un problema al intentar entregar un correo automatizado."
|
|
||||||
,"If you have questions, resend this email to cau@verdnatura.es.": "Si tienes dudas, reenvia este correo a cau@verdnatura.es."
|
|
||||||
,"The response from the remote server was:": "La respuesta del servidor remoto ha sido:"
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
automatedMessageNotDelivered: Un mensaje automatizado no se ha podido entregar
|
||||||
|
ITProblemNotification: Desde el departamento de informática te enviamos este correo porque ha habido un problema al intentar entregar un correo automatizado.
|
||||||
|
ifQuestionsResendEmailToIT: Si tienes dudas, reenvia este correo a cau@verdnatura.es.
|
||||||
|
'The response from the remote server was:': 'La respuesta del servidor remoto ha sido:'
|
|
@ -48,13 +48,13 @@ class Mail extends Vn\Lib\Method {
|
||||||
if ($row->replyTo) {
|
if ($row->replyTo) {
|
||||||
Vn\Lib\Locale::set('es');
|
Vn\Lib\Locale::set('es');
|
||||||
$errorMsg =
|
$errorMsg =
|
||||||
'<p>'. s('Notification from IT department about problem.') .'</p>'
|
'<p>'. s('ITProblemNotification') .'</p>'
|
||||||
.'<p>'. s('If you have questions, resend this email to cau@verdnatura.es.') .'</p>'
|
.'<p>'. s('ifQuestionsResendEmailToIT') .'</p>'
|
||||||
.'<p style="color: gray">'. $status .'</p>';
|
.'<p style="color: gray">'. $status .'</p>';
|
||||||
|
|
||||||
$errorMail = $mailer->createObject($row->replyTo,
|
$errorMail = $mailer->createObject($row->replyTo,
|
||||||
$errorMsg,
|
$errorMsg,
|
||||||
s('An automated message could not be delivered')
|
s('automatedMessageNotDelivered')
|
||||||
);
|
);
|
||||||
$errorMail->AddStringAttachment(
|
$errorMail->AddStringAttachment(
|
||||||
$mail->getSentMIMEMessage(),
|
$mail->getSentMIMEMessage(),
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once(__DIR__.'/tpv.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets transaction confirmations from the IMAP mailbox.
|
|
||||||
*/
|
|
||||||
class ConfirmMail extends Vn\Lib\Method {
|
|
||||||
function run($db) {
|
|
||||||
$imap = NULL;
|
|
||||||
$imapConf = $db->getObject(
|
|
||||||
'SELECT host, user, pass, cleanPeriod, successFolder, errorFolder
|
|
||||||
FROM tpvImapConfig'
|
|
||||||
);
|
|
||||||
|
|
||||||
$mailbox = sprintf('{%s/imap/ssl/novalidate-cert}',
|
|
||||||
$imapConf->host);
|
|
||||||
|
|
||||||
$imap = imap_open($mailbox
|
|
||||||
,$imapConf->user
|
|
||||||
,base64_decode($imapConf->pass)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$imap)
|
|
||||||
throw new Exception(imap_last_error());
|
|
||||||
|
|
||||||
// Fetchs and confirms new transaction mails
|
|
||||||
|
|
||||||
$count = 0;
|
|
||||||
$inbox = imap_search($imap, 'ALL');
|
|
||||||
|
|
||||||
if ($inbox)
|
|
||||||
foreach ($inbox as $msg) {
|
|
||||||
// Decodes the mail body
|
|
||||||
|
|
||||||
$params = [];
|
|
||||||
$body = imap_fetchbody($imap, $msg, '1');
|
|
||||||
$strings = explode(';', $body);
|
|
||||||
|
|
||||||
foreach ($strings as $string) {
|
|
||||||
$x = explode(':', $string);
|
|
||||||
$params[trim($x[0])] = trim($x[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirms the transaction
|
|
||||||
|
|
||||||
$success = FALSE;
|
|
||||||
|
|
||||||
try {
|
|
||||||
$success = Tpv::confirm($db, $params);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
trigger_error($e->getMessage(), E_USER_WARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Moves the processed mail to another folder
|
|
||||||
|
|
||||||
if ($success)
|
|
||||||
$folder = $imapConf->successFolder;
|
|
||||||
else
|
|
||||||
$folder = $imapConf->errorFolder;
|
|
||||||
|
|
||||||
if (!imap_mail_move($imap, $msg, "$folder"))
|
|
||||||
trigger_error(imap_last_error(), E_USER_WARNING);
|
|
||||||
|
|
||||||
$count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
imap_expunge($imap);
|
|
||||||
|
|
||||||
// Cleans the old mails
|
|
||||||
|
|
||||||
$deleted = 0;
|
|
||||||
|
|
||||||
if (rand(1, 20) == 1) {
|
|
||||||
$folders = array(
|
|
||||||
$imapConf->successFolder
|
|
||||||
,$imapConf->errorFolder
|
|
||||||
);
|
|
||||||
|
|
||||||
$date = new \DateTime(NULL);
|
|
||||||
$date->sub(new \DateInterval($imapConf->cleanPeriod));
|
|
||||||
$filter = sprintf('BEFORE "%s"', $date->format('D, j M Y'));
|
|
||||||
|
|
||||||
foreach ($folders as $folder)
|
|
||||||
if (imap_reopen($imap, $mailbox.$folder))
|
|
||||||
if ($messages = imap_search($imap, $filter)) {
|
|
||||||
foreach ($messages as $message)
|
|
||||||
imap_delete($imap, $message);
|
|
||||||
|
|
||||||
imap_expunge($imap);
|
|
||||||
$deleted += count($messages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "$count mails processed, $deleted mails deleted.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once(__DIR__.'/tpv.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets transaction confirmation from HTTP POST.
|
|
||||||
*/
|
|
||||||
class ConfirmPost extends Vn\Web\RestRequest {
|
|
||||||
function run($db) {
|
|
||||||
Tpv::confirm($db, $_POST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once('vn/web/util.php');
|
|
||||||
require_once(__DIR__.'/tpv.php');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets transaction confirmation from SOAP service.
|
|
||||||
*/
|
|
||||||
class ConfirmSoap extends Vn\Web\RestRequest {
|
|
||||||
function run($db) {
|
|
||||||
global $tpvConfirmSoap;
|
|
||||||
|
|
||||||
$tpvConfirmSoap = $this;
|
|
||||||
ini_set('soap.wsdl_cache_enabled', FALSE);
|
|
||||||
|
|
||||||
$server = new SoapServer(__DIR__ .'/soap.wsdl');
|
|
||||||
$server->addFunction('procesaNotificacionSIS');
|
|
||||||
$server->handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function procesaNotificacionSIS($XML) {
|
|
||||||
global $tpvConfirmSoap;
|
|
||||||
|
|
||||||
$db = $tpvConfirmSoap->app->getSysConn();
|
|
||||||
|
|
||||||
$status = 'OK';
|
|
||||||
$requestString = $XML;
|
|
||||||
|
|
||||||
// Processes the request
|
|
||||||
|
|
||||||
try {
|
|
||||||
$xml = new SimpleXMLElement($requestString);
|
|
||||||
$params =(array) $xml->{'Request'};
|
|
||||||
|
|
||||||
if (!(isset($params['Ds_Amount'])
|
|
||||||
&& isset($params['Ds_Order'])
|
|
||||||
&& isset($params['Ds_MerchantCode'])
|
|
||||||
&& isset($params['Ds_Currency'])
|
|
||||||
&& isset($params['Ds_Response'])))
|
|
||||||
throw new Exception('Missing required parameters');
|
|
||||||
|
|
||||||
// Checks the signature
|
|
||||||
|
|
||||||
$start = strpos($requestString, '<Request');
|
|
||||||
$end = strrpos($requestString, '</Request>');
|
|
||||||
$shaString = substr($requestString, $start, $end - $start + 10);
|
|
||||||
|
|
||||||
$key = $db->getValue(
|
|
||||||
'SELECT secretKey FROM tpvMerchant WHERE id = #'
|
|
||||||
,[$params['Ds_MerchantCode']]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sha1($shaString.$key) != $xml->{'Signature'})
|
|
||||||
throw new Exception('Invalid signature');
|
|
||||||
|
|
||||||
// Confirms the transaction
|
|
||||||
|
|
||||||
Tpv::confirm($db, $params);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$status = 'KO';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates the response
|
|
||||||
|
|
||||||
$responseString = file_get_contents(__DIR__ .'/soap-reply.xml');
|
|
||||||
$xml = new SimpleXMLElement($responseString);
|
|
||||||
|
|
||||||
$response = $xml->{'Response'};
|
|
||||||
$response->{'Ds_Response_Merchant'} = $status;
|
|
||||||
|
|
||||||
$xml->{'Signature'} = sha1($response->asXML().$key);
|
|
||||||
|
|
||||||
return $xml->asXML();
|
|
||||||
/*
|
|
||||||
// Another way to generate the response
|
|
||||||
|
|
||||||
$xmlResponse =
|
|
||||||
'<Response Ds_Version="0.0">
|
|
||||||
<Ds_Response_Merchant>'. $status .'</Ds_Response_Merchant>
|
|
||||||
</Response>';
|
|
||||||
|
|
||||||
$xmlMessage =
|
|
||||||
'<Message>
|
|
||||||
'. $xmlResponse .'
|
|
||||||
<Signature>'. sha1($xmlResponse.$key) .'</Signature>
|
|
||||||
</Message>';
|
|
||||||
|
|
||||||
return $xmlMessage;
|
|
||||||
*/}
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<Message>
|
|
||||||
<Response Ds_Version="0.0">
|
|
||||||
<Ds_Response_Merchant></Ds_Response_Merchant>
|
|
||||||
</Response>
|
|
||||||
<Signature></Signature>
|
|
||||||
</Message>
|
|
|
@ -1,40 +0,0 @@
|
||||||
<!ELEMENT Message (Request, Signature)>
|
|
||||||
|
|
||||||
<!ELEMENT Request (
|
|
||||||
Fecha,
|
|
||||||
Hora,
|
|
||||||
Ds_SecurePayment,
|
|
||||||
Ds_Amount,
|
|
||||||
Ds_Currency,
|
|
||||||
Ds_Order,
|
|
||||||
Ds_MerchantCode,
|
|
||||||
Ds_Terminal,
|
|
||||||
Ds_Response,
|
|
||||||
Ds_MerchantData?,
|
|
||||||
Ds_Card_Type?,
|
|
||||||
Ds_TransactionType,
|
|
||||||
Ds_ConsumerLanguage,
|
|
||||||
Ds_ErrorCode?,
|
|
||||||
Ds_CardCountry?,
|
|
||||||
Ds_AuthorisationCode?
|
|
||||||
)>
|
|
||||||
|
|
||||||
<!ATTLIST Request Ds_Version CDATA #REQUIRED>
|
|
||||||
<!ELEMENT Fecha (#PCDATA)>
|
|
||||||
<!ELEMENT Hora (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_SecurePayment (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Amount (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Currency (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Order (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_MerchantCode (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Terminal (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Response (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_MerchantData (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_Card_Type (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_TransactionType (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_ConsumerLanguage (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_ErrorCode (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_CardCountry (#PCDATA)>
|
|
||||||
<!ELEMENT Ds_AuthorisationCode (#PCDATA)>
|
|
||||||
<!ELEMENT Signature (#PCDATA)>
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
<Message>
|
|
||||||
<Request Ds_Version='0.0'>
|
|
||||||
<Fecha>21/10/2014</Fecha>
|
|
||||||
<Hora>17:56</Hora>
|
|
||||||
<Ds_SecurePayment>1</Ds_SecurePayment>
|
|
||||||
<DS_Card_Type>D</DS_Card_Type>
|
|
||||||
<Ds_Card_Country>724</Ds_Card_Country>
|
|
||||||
<Ds_Amount>1</Ds_Amount>
|
|
||||||
<Ds_Currency>978</Ds_Currency>
|
|
||||||
<Ds_Order>000000007216</Ds_Order>
|
|
||||||
<Ds_MerchantCode>329744999</Ds_MerchantCode>
|
|
||||||
<Ds_Terminal>001</Ds_Terminal>
|
|
||||||
<Ds_Response>0000</Ds_Response>
|
|
||||||
<Ds_MerchantData></Ds_MerchantData>
|
|
||||||
<Ds_TransactionType>0</Ds_TransactionType>
|
|
||||||
<Ds_ConsumerLanguage>1</Ds_ConsumerLanguage>
|
|
||||||
<Ds_AuthorisationCode>563451</Ds_AuthorisationCode>
|
|
||||||
</Request>
|
|
||||||
<Signature>b97d1aba50aac5efc0915f59a70e24fc94cb3ffe</Signature>
|
|
||||||
</Message>
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
if (isset($_POST['key'])) {
|
|
||||||
ini_set('soap.wsdl_cache_enabled', FALSE);
|
|
||||||
|
|
||||||
$requestString = file_get_contents(__DIR__.'/soap-request.xml');
|
|
||||||
|
|
||||||
$client = new SoapClient(__DIR__.'/soap.wsdl');
|
|
||||||
$result = $client->__soapCall('procesaNotificacionSIS', [
|
|
||||||
'XML' => $requestString
|
|
||||||
]);
|
|
||||||
|
|
||||||
$xml = new SimpleXMLElement($result);
|
|
||||||
|
|
||||||
$key = $_POST['key'];
|
|
||||||
|
|
||||||
$start = strpos($result, '<Response');
|
|
||||||
$end = strrpos($result, '</Response>');
|
|
||||||
$shaString = substr($result, $start, $end - $start + 11);
|
|
||||||
$shaHash = sha1($shaString.$key);
|
|
||||||
|
|
||||||
$isValid = $xml->{'Signature'} == $shaHash;
|
|
||||||
} else {
|
|
||||||
$key = '';
|
|
||||||
$result = '';
|
|
||||||
$shaHash = '';
|
|
||||||
$isValid = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
TPV SOAP Client
|
|
||||||
</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<form action="?" method="post">
|
|
||||||
<label>Key:</label>
|
|
||||||
<input type="password" value="<?=$key?>" name="key"/>
|
|
||||||
<input type="submit"/>
|
|
||||||
</form>
|
|
||||||
<h2>Response</h2>
|
|
||||||
<p>
|
|
||||||
<pre><?=htmlentities($result)?></pre>
|
|
||||||
</p>
|
|
||||||
<h2>Signature</h2>
|
|
||||||
<p>
|
|
||||||
Calculated: <?=$shaHash?>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Valid: <input type="checkbox" <?=($isValid ? 'checked' : '')?>/>
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<definitions name="InotificacionSIS"
|
|
||||||
targetNamespace="https://sis.sermepa.es/sis/InotificacionSIS.wsdl"
|
|
||||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
||||||
xmlns:tns="https://sis.sermepa.es/sis/InotificacionSIS.wsdl"
|
|
||||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
|
||||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
|
||||||
xmlns="http://schemas.xmlsoap.org/wsdl/">
|
|
||||||
|
|
||||||
<message name="procesaNotificacionSISRequest">
|
|
||||||
<part name="XML" type="xs:string"/>
|
|
||||||
</message>
|
|
||||||
|
|
||||||
<message name="procesaNotificacionSISResponse">
|
|
||||||
<part name="return" type="xs:string"/>
|
|
||||||
</message>
|
|
||||||
|
|
||||||
<portType name="InotificacionSISPortType">
|
|
||||||
<operation name="procesaNotificacionSIS">
|
|
||||||
<input message="tns:procesaNotificacionSISRequest"/>
|
|
||||||
<output message="tns:procesaNotificacionSISResponse"/>
|
|
||||||
</operation>
|
|
||||||
</portType>
|
|
||||||
|
|
||||||
<binding name="InotificacionSISBinding" type="tns:InotificacionSISPortType">
|
|
||||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
|
|
||||||
<operation name="procesaNotificacionSIS">
|
|
||||||
<soap:operation
|
|
||||||
soapAction="urn:InotificacionSIS#procesaNotificacionSIS" style="rpc"/>
|
|
||||||
<input>
|
|
||||||
<soap:body use="encoded"
|
|
||||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
|
||||||
namespace="InotificacionSIS"/>
|
|
||||||
</input>
|
|
||||||
<output>
|
|
||||||
<soap:body use="encoded"
|
|
||||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
|
||||||
namespace="InotificacionSIS"/>
|
|
||||||
</output>
|
|
||||||
</operation>
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
<service name="InotificacionSISService">
|
|
||||||
<port name="InotificacionSIS" binding="tns:InotificacionSISBinding">
|
|
||||||
<soap:address
|
|
||||||
location="http://localhost/~juan/hedera-web/tpv/soap.php"/>
|
|
||||||
</port>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
</definitions>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
class Tpv {
|
|
||||||
/**
|
|
||||||
* Tryes to confirm a transaction with the given params.
|
|
||||||
*/
|
|
||||||
static function confirm($db, $params) {
|
|
||||||
if (!(isset($params['Ds_Amount'])
|
|
||||||
&& isset($params['Ds_Order'])
|
|
||||||
&& isset($params['Ds_MerchantCode'])
|
|
||||||
&& isset($params['Ds_Currency'])
|
|
||||||
&& isset($params['Ds_Response'])))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (isset($params['Ds_ErrorCode']))
|
|
||||||
$error = $params['Ds_ErrorCode'];
|
|
||||||
else
|
|
||||||
$error = NULL;
|
|
||||||
|
|
||||||
return $db->query(
|
|
||||||
'CALL tpvTransaction_confirm(#, #, #, #, #, #)',
|
|
||||||
[
|
|
||||||
$params['Ds_Amount']
|
|
||||||
,$params['Ds_Order']
|
|
||||||
,$params['Ds_MerchantCode']
|
|
||||||
,$params['Ds_Currency']
|
|
||||||
,$params['Ds_Response']
|
|
||||||
,$error
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a new TPV transaction and returns the params.
|
|
||||||
*/
|
|
||||||
class Transaction extends Vn\Web\JsonRequest {
|
|
||||||
const PARAMS = ['amount'];
|
|
||||||
|
|
||||||
function run($db) {
|
|
||||||
$amount = (int) $_REQUEST['amount'];
|
|
||||||
$companyId = empty($_REQUEST['company']) ? NULL : $_REQUEST['company'];
|
|
||||||
|
|
||||||
$row = $db->getObject('CALL myTpvTransaction_start(#, #)',
|
|
||||||
[$amount, $companyId]);
|
|
||||||
|
|
||||||
if (!isset($row))
|
|
||||||
throw new Exception('Transaction error');
|
|
||||||
|
|
||||||
$transactionId = str_pad($row->transactionId, 12, '0', STR_PAD_LEFT);
|
|
||||||
$merchantUrl = $row->merchantUrl ? $row->merchantUrl : '';
|
|
||||||
$urlOk = empty($_REQUEST['urlOk']) ? '' :
|
|
||||||
str_replace('_transactionId_', $transactionId, $_REQUEST['urlOk']);
|
|
||||||
$urlKo = empty($_REQUEST['urlKo']) ? '' :
|
|
||||||
str_replace('_transactionId_', $transactionId, $_REQUEST['urlKo']);
|
|
||||||
|
|
||||||
$params = [
|
|
||||||
'Ds_Merchant_Amount' => $amount
|
|
||||||
,'Ds_Merchant_Order' => $transactionId
|
|
||||||
,'Ds_Merchant_MerchantCode' => $row->merchant
|
|
||||||
,'Ds_Merchant_Currency' => $row->currency
|
|
||||||
,'Ds_Merchant_TransactionType' => $row->transactionType
|
|
||||||
,'Ds_Merchant_Terminal' => $row->terminal
|
|
||||||
,'Ds_Merchant_MerchantURL' => $merchantUrl
|
|
||||||
,'Ds_Merchant_UrlOK' => $urlOk
|
|
||||||
,'Ds_Merchant_UrlKO' => $urlKo
|
|
||||||
];
|
|
||||||
|
|
||||||
$encodedParams = base64_encode(json_encode($params));
|
|
||||||
|
|
||||||
$key = base64_decode($row->secretKey);
|
|
||||||
|
|
||||||
$bytes = [0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
$iv = implode(array_map('chr', $bytes));
|
|
||||||
|
|
||||||
$paddedData = $transactionId;
|
|
||||||
if (strlen($paddedData) % 8) {
|
|
||||||
$paddedData = str_pad($paddedData,
|
|
||||||
strlen($paddedData) + 8 - strlen($paddedData) % 8, "\0");
|
|
||||||
}
|
|
||||||
|
|
||||||
$encryptedData = openssl_encrypt($paddedData,
|
|
||||||
'des-ede3-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING , $iv);
|
|
||||||
$signature = base64_encode(hash_hmac('sha256', $encodedParams, $encryptedData, TRUE));
|
|
||||||
|
|
||||||
$url = $row->url;
|
|
||||||
$postValues = [
|
|
||||||
'Ds_SignatureVersion' => 'HMAC_SHA256_V1'
|
|
||||||
,'Ds_MerchantParameters' => $encodedParams
|
|
||||||
,'Ds_Signature' => $signature
|
|
||||||
];
|
|
||||||
|
|
||||||
return [
|
|
||||||
'url' => $url
|
|
||||||
,'postValues' => $postValues
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,9 +50,18 @@ class RestService extends Service {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$res = $method->run($methodDb);
|
$res = $method->run($methodDb);
|
||||||
} catch (Db\Exception $e) {
|
} catch (\Vn\Db\Exception $e) {
|
||||||
if ($e->getCode() == 1644)
|
if ($e->getCode() == 1644) {
|
||||||
throw new UserException(s($e->getMessage()));
|
$eMessage = $e->getMessage();
|
||||||
|
$tMessage = $db->getValue(
|
||||||
|
'SELECT `description` FROM `message` WHERE `code` = #',
|
||||||
|
[$eMessage]
|
||||||
|
);
|
||||||
|
if (!$tMessage) $tMessage = $eMessage;
|
||||||
|
throw new Lib\UserException($tMessage, $eMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($method::SECURITY == Security::DEFINER)
|
if ($method::SECURITY == Security::DEFINER)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=no"/>
|
||||||
<title>Not available - Verdnatura</title>
|
<title>Not available - Verdnatura</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
div a {
|
div a {
|
||||||
color: #2962FF;
|
color: #6a1;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue