diff --git a/db/10001-ticketService/00-myTicketService.sql b/db/10001-ticketService/00-myTicketService.sql
new file mode 100644
index 00000000..435c2487
--- /dev/null
+++ b/db/10001-ticketService/00-myTicketService.sql
@@ -0,0 +1,17 @@
+CREATE OR REPLACE
+ DEFINER=`root`@`%`
+ ALGORITHM = UNDEFINED VIEW `hedera`.`myTicketService` AS
+ select
+ `s`.`id` AS `id`,
+ `s`.`description` AS `description`,
+ `s`.`quantity` AS `quantity`,
+ `s`.`price` AS `price`,
+ `s`.`taxClassFk` AS `taxClassFk`,
+ `s`.`ticketFk` AS `ticketFk`,
+ `s`.`ticketServiceTypeFk` AS `ticketServiceTypeFk`
+ from
+ (`vn`.`ticketService` `s`
+ join `hedera`.`myTicket` `t` on
+ (`s`.`ticketFk` = `t`.`id`)) WITH CASCADED CHECK OPTION;
+
+GRANT SELECT ON TABLE hedera.myTicketService TO account@'localhost';
diff --git a/db/10001-ticketService/00-myTicket_getServices.sql b/db/10001-ticketService/00-myTicket_getServices.sql
new file mode 100644
index 00000000..df52878d
--- /dev/null
+++ b/db/10001-ticketService/00-myTicket_getServices.sql
@@ -0,0 +1,18 @@
+
+DROP PROCEDURE IF EXISTS hedera.myTicket_getServices;
+DELIMITER $$
+CREATE DEFINER=`root`@`%` PROCEDURE `hedera`.`myTicket_getServices`(vSelf INT)
+BEGIN
+/**
+ * Returns a current user ticket services.
+ *
+ * @param vSelf The ticket identifier
+ * @select The ticket services
+ */
+ SELECT id, description, quantity, price
+ FROM myTicketService
+ WHERE ticketFk = vSelf;
+END$$
+DELIMITER ;
+
+GRANT EXECUTE ON PROCEDURE hedera.myTicket_getServices TO account@'localhost';
diff --git a/db/10001-ticketService/99-role_sync.sql b/db/10001-ticketService/99-role_sync.sql
new file mode 100644
index 00000000..86dd0b46
--- /dev/null
+++ b/db/10001-ticketService/99-role_sync.sql
@@ -0,0 +1 @@
+CALL account.role_sync;
diff --git a/debian/changelog b/debian/changelog
index 4f3d0d9c..343ef91c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-hedera-web (1.407.32) stable; urgency=low
+hedera-web (1.407.33) stable; urgency=low
* Initial Release.
diff --git a/forms/account/address/address.js b/forms/account/address/address.js
index 0404979a..db430998 100644
--- a/forms/account/address/address.js
+++ b/forms/account/address/address.js
@@ -5,7 +5,7 @@ Hedera.Address = new Class({
activate: function() {
this.$('model').setInfo('a', 'myAddress', 'hedera', ['id'], 'id');
this.$('model').setDefault('clientFk', 'a',
- new Sql.Function({schema: 'account', name: 'myUserGetId'}));
+ new Sql.Function({schema: 'account', name: 'myUser_getId'}));
},
onStatusChange: function(form) {
diff --git a/forms/ecomerce/ticket/locale/ca.yml b/forms/ecomerce/ticket/locale/ca.yml
index 04a36470..c0141846 100644
--- a/forms/ecomerce/ticket/locale/ca.yml
+++ b/forms/ecomerce/ticket/locale/ca.yml
@@ -19,3 +19,5 @@ Disc: Desc
Subtotal: Subtotal
Preparation: Preparació
Delivery: Entrega
+Service: Servei
+Packaging: Embalatge
diff --git a/forms/ecomerce/ticket/locale/en.yml b/forms/ecomerce/ticket/locale/en.yml
index 1d09f9b4..01412c9e 100644
--- a/forms/ecomerce/ticket/locale/en.yml
+++ b/forms/ecomerce/ticket/locale/en.yml
@@ -19,3 +19,5 @@ Disc: Disc
Subtotal: Subtotal
Preparation: Preparation
Delivery: Delivery
+Service: Service
+Packaging: Packaging
diff --git a/forms/ecomerce/ticket/locale/es.yml b/forms/ecomerce/ticket/locale/es.yml
index 271d5dde..627786d3 100644
--- a/forms/ecomerce/ticket/locale/es.yml
+++ b/forms/ecomerce/ticket/locale/es.yml
@@ -19,3 +19,5 @@ Disc: Desc
Subtotal: Subtotal
Preparation: Preparación
Delivery: Entrega
+Service: Servicio
+Packaging: Embalaje
diff --git a/forms/ecomerce/ticket/locale/fr.yml b/forms/ecomerce/ticket/locale/fr.yml
index b40629e8..6345329e 100644
--- a/forms/ecomerce/ticket/locale/fr.yml
+++ b/forms/ecomerce/ticket/locale/fr.yml
@@ -19,3 +19,5 @@ Disc: Remise
Subtotal: Sous-total
Preparation: Préparation
Delivery: Livraison
+Service: Service
+Packaging: Emballage
diff --git a/forms/ecomerce/ticket/locale/pt.yml b/forms/ecomerce/ticket/locale/pt.yml
index 8cc2e758..2399b4fb 100644
--- a/forms/ecomerce/ticket/locale/pt.yml
+++ b/forms/ecomerce/ticket/locale/pt.yml
@@ -19,3 +19,5 @@ Disc: Desc
Subtotal: Sub-total
Preparation: Preparação
Delivery: Entrega
+Service: Serviço
+Packaging: Embalagem
diff --git a/forms/ecomerce/ticket/ticket.js b/forms/ecomerce/ticket/ticket.js
index ec442ee5..59a6f408 100644
--- a/forms/ecomerce/ticket/ticket.js
+++ b/forms/ecomerce/ticket/ticket.js
@@ -39,10 +39,19 @@ Hedera.Ticket = new Class({
var discount = form.get('discount');
return this.discountSubtotal(form) * ((100 - discount) / 100);
},
+
+ servicesFunc: function(res, form) {
+ res.$('subtotal').value = form.get('quantity') * form.get('price');
+ },
+
+ onServicesChanged: function(model) {
+ this.$('services').node.style.display =
+ model.numRows > 0 ? 'block' : 'none';
+ },
onPackagesChanged: function(model) {
this.$('packages').node.style.display =
model.numRows > 0 ? 'block' : 'none';
- }
+ },
});
diff --git a/forms/ecomerce/ticket/ui.xml b/forms/ecomerce/ticket/ui.xml
index e4fce691..0901920f 100644
--- a/forms/ecomerce/ticket/ui.xml
+++ b/forms/ecomerce/ticket/ui.xml
@@ -105,6 +105,31 @@
+
+
+ CALL myTicket_getServices(#ticket)
+
+
+
+
+
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/10.svg b/image/family/light/10.svg
index 3e86e100..795a9d3d 100644
--- a/image/family/light/10.svg
+++ b/image/family/light/10.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/12.svg b/image/family/light/12.svg
index d1b4c245..f53331e4 100644
--- a/image/family/light/12.svg
+++ b/image/family/light/12.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ version="1.1"
+ id="svg1600"
+ inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+ sodipodi:docname="12.svg">
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/2.svg b/image/family/light/2.svg
index e9d87544..3150fe12 100644
--- a/image/family/light/2.svg
+++ b/image/family/light/2.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/3.svg b/image/family/light/3.svg
index 6b748136..dde26852 100644
--- a/image/family/light/3.svg
+++ b/image/family/light/3.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/4.svg b/image/family/light/4.svg
index 92dc2c70..be3b1f5c 100644
--- a/image/family/light/4.svg
+++ b/image/family/light/4.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/5.svg b/image/family/light/5.svg
index e8f73199..91d6946a 100644
--- a/image/family/light/5.svg
+++ b/image/family/light/5.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/7.svg b/image/family/light/7.svg
index 65e63c9b..233f5e13 100644
--- a/image/family/light/7.svg
+++ b/image/family/light/7.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/image/family/light/9.svg b/image/family/light/9.svg
index 38edee97..1d9c32f2 100644
--- a/image/family/light/9.svg
+++ b/image/family/light/9.svg
@@ -1,6 +1,4 @@
-
-
\ No newline at end of file
+ version="1.1"
+ id="svg1600"
+ inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
+ sodipodi:docname="9.svg">
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 29e5c378..f22e4bb1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hedera-web",
- "version": "1.407.32",
+ "version": "1.407.33",
"description": "Verdnatura web page",
"license": "GPL-3.0",
"repository": {
diff --git a/reports/delivery-note/delivery-note.js b/reports/delivery-note/delivery-note.js
index db24e0c7..bfe0332b 100644
--- a/reports/delivery-note/delivery-note.js
+++ b/reports/delivery-note/delivery-note.js
@@ -22,6 +22,15 @@ Hedera.DeliveryNote = new Class({
var discount = form.get('discount');
return form.get('quantity') * price *((100 - discount) / 100);
},
+
+ serviceSubtotal: function(column, form) {
+ column.value = form.get('quantity') * form.get('price');
+ },
+
+ onServicesChanged: function(model) {
+ this.$('services').node.style.display =
+ model.numRows > 0 ? 'block' : 'none';
+ },
onPackagesChanged: function(model) {
this.$('packages').node.style.display =
diff --git a/reports/delivery-note/style.css b/reports/delivery-note/style.css
index 96d47eca..fe39e671 100644
--- a/reports/delivery-note/style.css
+++ b/reports/delivery-note/style.css
@@ -9,7 +9,6 @@
h2
{
font-size: 1.2em;
- margin-bottom: 8mm;
font-weight: bold;
}
.header
@@ -18,29 +17,29 @@ h2
}
.header > div > p
{
- text-align: right;
margin: .1em 0;
}
-.address
-{
- margin-top: .8em;
-}
.important
{
font-size: 1.2em;
font-weight: bold;
+}
+.address,
+.total
+{
+ margin-top: .8em;
+}
+.total
+{
text-align: right;
}
-.footer
+.htk-grid
{
- margin-top: .2em;
- border-top: 1px solid #333;
- padding-top: .3em;
+ margin-top: 1em;
}
.packages
{
width: 50%;
- padding-top: 1em;
margin-left: 0;
display: none;
}
diff --git a/reports/delivery-note/ui.xml b/reports/delivery-note/ui.xml
index 56b09d54..452bb5e4 100644
--- a/reports/delivery-note/ui.xml
+++ b/reports/delivery-note/ui.xml
@@ -2,13 +2,13 @@
- CALL myTicket_get (#ticket)
+ CALL myTicket_get(#ticket)
-
+ @
- CALL myTicket_getRows (#ticket)
+ CALL myTicket_getRows(#ticket)
@@ -49,26 +59,31 @@
-
-
- Total + tax
-
-
+
+
+ CALL myTicket_getServices(#ticket)
+
+
+
+
+
+
- CALL myTicket_getPackages (#ticket)
+ CALL myTicket_getPackages(#ticket)
-
+
diff --git a/rest/core/account.php b/rest/core/account.php
index f4c161ae..0e6a0cc6 100644
--- a/rest/core/account.php
+++ b/rest/core/account.php
@@ -3,7 +3,7 @@
class Account {
static function trySync($db, $userName, $password = NULL) {
$isSync = $db->getValue(
- 'SELECT sync FROM account.user WHERE name = #',
+ 'SELECT COUNT(*) > 0 FROM account.userSync WHERE name = #',
[$userName]
);
@@ -13,7 +13,20 @@ class Account {
self::sync($db, $userName, $password);
}
- static function sync($db, $userName, $password = NULL, $force = TRUE) {
+ static function sync($db, $userName, $password = NULL) {
+ $bcryptPassword = password_hash($password, PASSWORD_BCRYPT);
+
+ $userId = $db->getValue(
+ 'SELECT id FROM account.user WHERE `name` = #',
+ [$userName]
+ );
+ $db->query(
+ 'UPDATE account.user SET
+ bcryptPassword = #
+ WHERE id = #',
+ [$bcryptPassword, $userId]
+ );
+
$hasAccount = $db->getValue(
'SELECT COUNT(*) > 0
FROM account.user u
@@ -21,235 +34,9 @@ class Account {
WHERE u.name = #',
[$userName]
);
-
- if ($hasAccount) {
- self::ldapSync($db, $userName, $password);
- self::sambaSync($db, $userName, $password);
- }
-
- $bcryptPassword = password_hash($password, PASSWORD_BCRYPT);
-
- $userId = $db->getValue(
- 'SELECT id FROM account.user WHERE `name` = #',
- [$userName]
- );
- $db->query(
- 'CALL account.user_syncPassword(#, #)',
- [$userId, $password]
- );
- $db->query(
- 'UPDATE account.user SET
- sync = TRUE,
- bcryptPassword = #
- WHERE id = #',
- [$bcryptPassword, $userId]
- );
- }
-
- /**
- * Synchronizes the user credentials in the LDAP server.
- */
- static function ldapSync($db, $userName, $password) {
- // Gets LDAP configuration parameters
-
- $conf = $db->getObject(
- 'SELECT host, rdn, password, baseDn, filter
- FROM account.ldapConfig'
- );
-
- // Connects an authenticates against server
-
- $ds = ldap_connect($conf->host);
-
- if (!$ds)
- throw new Exception("Can't connect to LDAP server: ". ldapError($ds));
-
- try {
- ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
- $bind = ldap_bind($ds, $conf->rdn, base64_decode($conf->password));
-
- if (!$bind)
- throw new Exception("Authentication failed on LDAP server: ". ldapError($ds));
-
- // Prepares the data
-
- $domain = $db->getValue('SELECT domain FROM account.mailConfig');
-
- $user = $db->getObject(
- 'SELECT `id`, `nickname`, `lang`, `role`
- FROM account.user
- WHERE `name` = #',
+ if (!$hasAccount)
+ $db->getValue('DELETE FROM account.userSync WHERE name = #',
[$userName]
);
-
- $accountCfg = $db->getObject(
- 'SELECT homedir, shell, idBase
- FROM account.accountConfig'
- );
-
- $cn = empty($user->nickname) ? $userName : $user->nickname;
-
- $nameArgs = explode(' ', $user->nickname);
- $givenName = $nameArgs[0];
-
- if (count($nameArgs) > 1)
- $sn = $nameArgs[1];
- if (empty($sn))
- $sn = 'Empty';
-
- $attrs = [
- 'cn' => $cn,
- 'displayName' => $user->nickname,
- 'givenName' => $givenName,
- 'sn' => $sn,
- 'mail' => "$userName@{$domain}",
- 'userPassword' => sshaEncode($password),
- 'preferredLanguage' => $user->lang,
- 'homeDirectory' => "$accountCfg->homedir/$userName",
- 'loginShell' => $accountCfg->shell,
- 'uidNumber' => $accountCfg->idBase + $user->id,
- 'gidNumber' => $accountCfg->idBase + $user->role
- ];
-
- // Search the user entry
-
- $filter = "uid=$userName";
-
- if (!empty($conf->filter))
- $filter = "(&($filter)($conf->filter))";
-
- $res = ldap_search($ds, $conf->baseDn, $filter);
-
- if (!$res)
- throw new Exception("Can't get the LDAP entry: ". ldapError($ds));
-
- $dn = "uid=$userName,{$conf->baseDn}";
- $entry = ldap_first_entry($ds, $res);
- if ($entry) ldap_delete($ds, $dn);
-
- $addAttrs = [];
-
- foreach ($attrs as $attribute => $value)
- if (!empty($value))
- $addAttrs[$attribute] = $value;
-
- $addAttrs = array_merge($addAttrs, [
- 'objectClass' => ['inetOrgPerson', 'posixAccount'],
- 'uid' => $userName
- ]);
- $updated = ldap_add($ds, $dn, $addAttrs);
-
- if (!$updated)
- throw new Exception("Can't update the LDAP entry: ". ldapError($ds));
- } catch (Exception $e) {
- ldap_unbind($ds);
- throw $e;
- }
- }
-
- /**
- * Synchronizes the user credentials in the Samba server.
- */
- static function sambaSync($db, $userName, $password) {
- $conf = $db->getObject(
- 'SELECT host, sshUser, sshPass
- FROM account.sambaConfig'
- );
-
- $accountCfg = $db->getObject(
- 'SELECT idBase
- FROM account.accountConfig'
- );
-
- $domain = $db->getValue('SELECT domain FROM account.mailConfig');
-
- $samba = new SshConnection($conf->host
- ,$conf->sshUser
- ,base64_decode($conf->sshPass)
- );
-
- $scriptDir = '/mnt/storage/scripts';
-
- // Creates the Samba user and initializes it's home directory
-
- $userId = $db->getValue(
- 'SELECT id FROM account.user WHERE name = #', [$userName]);
-
- $samba->exec("$scriptDir/create-user.sh %s %s %s"
- ,$userName
- ,$accountCfg->idBase + $userId
- ,"$userName@{$domain}"
- );
-
- // Syncronizes the Samba password
-
- if (empty($password))
- return;
-
- $samba->exec("$scriptDir/set-password.sh %s %s"
- ,$userName
- ,$password
- );
- }
-}
-
-function ldapError($ds) {
- return ldap_errno($ds) .': '. ldap_error($ds);
-}
-
-function sshaEncode($value) {
- mt_srand((double) microtime() * 1000000);
- $salt = pack('CCCC', mt_rand(), mt_rand(), mt_rand(), mt_rand());
- $hash = '{SSHA}' . base64_encode(pack('H*', sha1($value . $salt)) . $salt);
- return $hash;
-}
-
-function sshaVerify($hash, $value) {
- $ohash = base64_decode(substr($hash, 6));
- $osalt = substr($ohash, 20);
- $ohash = substr($ohash, 0, 20);
- $nhash = pack('H*', sha1($value . $osalt));
- return $ohash == $nhash;
-}
-
-class SshConnection {
- var $connection;
-
- /**
- * Abrebiated method to make SSH connections.
- */
- function __construct($host, $user, $password) {
- $this->connection = $connection = ssh2_connect($host);
-
- if (!$connection)
- throw new Exception("Can't connect to SSH server $host");
-
- $authOk = ssh2_auth_password($connection, $user, $password);
-
- if (!$authOk)
- throw new Exception("SSH authentication failed on server $host");
-
- return $connection;
- }
-
- /**
- * Executes a command on the host.
- */
- function exec() {
- $nargs = func_num_args();
- $args = func_get_args();
-
- for ($i = 1; $i < $nargs; $i++)
- $args[$i] = self::escape($args[$i]);
-
- $command = call_user_func_array('sprintf', $args);
- return ssh2_exec($this->connection, $command);
- }
-
- /**
- * Escapes the double quotes from an string.
- */
- static function escape($str) {
- return '"'. str_replace('"', '\\"', $str) .'"';
}
}
diff --git a/rest/core/change-password.php b/rest/core/change-password.php
index cb421b0a..a999e836 100644
--- a/rest/core/change-password.php
+++ b/rest/core/change-password.php
@@ -12,7 +12,7 @@ class ChangePassword extends Vn\Web\JsonRequest {
$newPassword = $_REQUEST['newPassword'];
$oldPassword = $_REQUEST['oldPassword'];
- $db->query('CALL account.myUserChangePassword(#, #)',
+ $db->query('CALL account.myUser_changePassword(#, #)',
[$oldPassword, $newPassword]);
Account::sync($db, $_SESSION['user'], $newPassword);
return TRUE;
diff --git a/rest/core/set-password.php b/rest/core/set-password.php
index 78d05686..99de91bd 100644
--- a/rest/core/set-password.php
+++ b/rest/core/set-password.php
@@ -14,9 +14,13 @@ class SetPassword extends Vn\Web\JsonRequest {
function run($db) {
$setUser = $_REQUEST['setUser'];
$setPassword = $_REQUEST['setPassword'];
-
- $db->query('CALL account.userSetPassword(#, #)',
- [$setUser, $setPassword]);
+
+ $userId = $db->getValue(
+ 'SELECT id FROM account.user WHERE `name` = #',
+ [$setUser]
+ );
+ $db->query('CALL account.user_setPassword(#, #)',
+ [$userId, $setPassword]);
Account::sync($db, $setUser, $setPassword);
return TRUE;
}
diff --git a/rest/misc/sms.php b/rest/misc/sms.php
index b3e20308..7be046a7 100644
--- a/rest/misc/sms.php
+++ b/rest/misc/sms.php
@@ -29,7 +29,7 @@ class Sms extends Vn\Web\JsonRequest {
$db->query(
'INSERT INTO vn.sms SET
- `senderFk` = account.myUserGetId(),
+ `senderFk` = account.myUser_getId(),
`destinationFk` = #,
`destination` = #,
`message` = #,
diff --git a/web/rest-service.php b/web/rest-service.php
index 84210a8b..3677cf52 100644
--- a/web/rest-service.php
+++ b/web/rest-service.php
@@ -57,9 +57,9 @@ class RestService extends Service {
}
if ($method::SECURITY == Security::DEFINER)
- $methodDb->query('CALL account.myUserLogout()');
+ $methodDb->query('CALL account.myUser_logout');
- $db->query('CALL account.myUserLogout()');
+ $db->query('CALL account.myUser_logout');
return $res;
}
diff --git a/web/service.php b/web/service.php
index b4ba97ca..aa65df31 100644
--- a/web/service.php
+++ b/web/service.php
@@ -204,7 +204,7 @@ abstract class Service {
throw new UserDisabledException();
}
- $db->query('CALL account.userLoginWithName(#)', [$user]);
+ $db->query('CALL account.myUser_loginWithName(#)', [$user]);
$userChanged = !$anonymousUser
&&(empty($_SESSION['user']) || $_SESSION['user'] != $user);
@@ -251,7 +251,7 @@ abstract class Service {
$password = base64_decode($row->mysqlPassword);
$userDb = $this->app->createConnection($userName, $password, TRUE);
- $userDb->query('CALL account.userLoginWithKey(#, #)', [$user, $row->loginKey]);
+ $userDb->query('CALL account.myUser_loginWithKey(#, #)', [$user, $row->loginKey]);
return $userDb;
}