* Added username validation (username must be unique for every record).

* Admins can manage the working plan of a single provider on the backend/users page.
* Before sending a new notification email the system checks whether the provider user has notifications enabled.
* Added salt field in the "ea_user_settings" table.
This commit is contained in:
alextselegidis@gmail.com 2013-09-24 13:09:04 +00:00
parent e596cb768a
commit 08a50c14be
11 changed files with 789 additions and 187 deletions

View file

@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net -- http://www.phpmyadmin.net
-- --
-- Φιλοξενητής: localhost -- Φιλοξενητής: localhost
-- Χρόνος δημιουργίας: 13 Σεπ 2013 στις 16:10:44 -- Χρόνος δημιουργίας: 24 Σεπ 2013 στις 11:03:51
-- Έκδοση διακομιστή: 5.5.24-log -- Έκδοση διακομιστή: 5.5.24-log
-- Έκδοση PHP: 5.4.3 -- Έκδοση PHP: 5.4.3
@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS `ea_appointments` (
KEY `id_users_customer` (`id_users_customer`), KEY `id_users_customer` (`id_users_customer`),
KEY `id_services` (`id_services`), KEY `id_services` (`id_services`),
KEY `id_users_provider` (`id_users_provider`) KEY `id_users_provider` (`id_users_provider`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=42 ;
-- --
-- Άδειασμα δεδομένων του πίνακα `ea_appointments` -- Άδειασμα δεδομένων του πίνακα `ea_appointments`
@ -53,7 +53,8 @@ INSERT INTO `ea_appointments` (`id`, `book_datetime`, `start_datetime`, `end_dat
(37, '2013-09-13 13:47:54', '2013-09-14 11:30:00', '2013-09-14 13:30:00', 'Γυμναστήριο ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'cqm0t14p50d0917ghkirtruuno'), (37, '2013-09-13 13:47:54', '2013-09-14 11:30:00', '2013-09-14 13:30:00', 'Γυμναστήριο ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'cqm0t14p50d0917ghkirtruuno'),
(38, '2013-09-13 13:47:54', '2013-09-14 15:00:00', '2013-09-14 18:00:00', 'Ε!Α ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'vs0btdvi34t73rvkeubh77ln40'), (38, '2013-09-13 13:47:54', '2013-09-14 15:00:00', '2013-09-14 18:00:00', 'Ε!Α ', '3ace1513fdf92a4983b7ae719a8475b5', 1, 2, NULL, NULL, 'vs0btdvi34t73rvkeubh77ln40'),
(39, '2013-09-13 15:39:44', '2013-09-13 17:00:00', '2013-09-13 17:20:00', 'This is a test appt.', '6fd60f567310511d8f2fb4ff4c787d5e', 0, 2, 22, 3, NULL), (39, '2013-09-13 15:39:44', '2013-09-13 17:00:00', '2013-09-13 17:20:00', 'This is a test appt.', '6fd60f567310511d8f2fb4ff4c787d5e', 0, 2, 22, 3, NULL),
(40, '2013-09-13 15:50:14', '2013-09-14 10:00:00', '2013-09-14 11:00:00', 'heart decease', '39b81301e5bb1a82f77bd23d07ec63ce', 0, 4, 23, 2, NULL); (40, '2013-09-13 15:50:14', '2013-09-14 10:00:00', '2013-09-14 11:00:00', 'heart decease', '39b81301e5bb1a82f77bd23d07ec63ce', 0, 4, 23, 2, NULL),
(41, '2013-09-23 17:04:53', '2013-09-24 09:45:00', '2013-09-24 10:15:00', '', '4c782e7af14a98e03657cc64c9a4fe61', 0, 25, 26, 4, NULL);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -66,11 +67,12 @@ CREATE TABLE IF NOT EXISTS `ea_roles` (
`name` varchar(256) DEFAULT NULL, `name` varchar(256) DEFAULT NULL,
`slug` varchar(256) DEFAULT NULL, `slug` varchar(256) DEFAULT NULL,
`is_admin` tinyint(4) DEFAULT NULL COMMENT '0', `is_admin` tinyint(4) DEFAULT NULL COMMENT '0',
`services` int(4) DEFAULT NULL COMMENT '0',
`providers` int(4) DEFAULT NULL COMMENT '0',
`customers` int(4) DEFAULT NULL COMMENT '0',
`notifications` int(4) DEFAULT NULL COMMENT '0',
`appointments` int(4) DEFAULT NULL COMMENT '0', `appointments` int(4) DEFAULT NULL COMMENT '0',
`customers` int(4) DEFAULT NULL COMMENT '0',
`services` int(4) DEFAULT NULL COMMENT '0',
`users` int(4) DEFAULT NULL COMMENT '0',
`system_settings` int(4) DEFAULT NULL COMMENT '0',
`user_settings` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
@ -78,11 +80,11 @@ CREATE TABLE IF NOT EXISTS `ea_roles` (
-- Άδειασμα δεδομένων του πίνακα `ea_roles` -- Άδειασμα δεδομένων του πίνακα `ea_roles`
-- --
INSERT INTO `ea_roles` (`id`, `name`, `slug`, `is_admin`, `services`, `providers`, `customers`, `notifications`, `appointments`) VALUES INSERT INTO `ea_roles` (`id`, `name`, `slug`, `is_admin`, `appointments`, `customers`, `services`, `users`, `system_settings`, `user_settings`) VALUES
(1, 'Administrator', 'admin', 1, 15, 15, 15, 15, 15), (1, 'Administrator', 'admin', 1, 15, 15, 15, 15, 15, NULL),
(2, 'Provider', 'provider', 0, 0, 0, 15, 0, 15), (2, 'Provider', 'provider', 0, 15, 15, 0, 0, 0, NULL),
(3, 'Customer', 'customer', 0, 0, 0, 0, 0, 0), (3, 'Customer', 'customer', 0, 0, 0, 0, 0, 0, NULL),
(4, 'Secretary', 'secretary', 0, 0, 0, 15, 15, 15); (4, 'Secretary', 'secretary', 0, 15, 15, 0, 0, 15, NULL);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -155,7 +157,8 @@ INSERT INTO `ea_services_providers` (`id_users`, `id_services`) VALUES
(4, 2), (4, 2),
(2, 3), (2, 3),
(3, 3), (3, 3),
(2, 4); (2, 4),
(25, 4);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -190,18 +193,19 @@ CREATE TABLE IF NOT EXISTS `ea_settings` (
`name` varchar(512) DEFAULT NULL, `name` varchar(512) DEFAULT NULL,
`value` longtext, `value` longtext,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
-- --
-- Άδειασμα δεδομένων του πίνακα `ea_settings` -- Άδειασμα δεδομένων του πίνακα `ea_settings`
-- --
INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES INSERT INTO `ea_settings` (`id`, `name`, `value`) VALUES
(1, 'company_name', 'Easy!Appointments & Co'), (1, 'company_name', 'Easy!Appointmnets & Co'),
(2, 'company_working_plan', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}'), (2, 'company_working_plan', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}'),
(3, 'company_email', 'info@alextselegidis.com'), (3, 'company_email', 'info@alextselegidis.com'),
(8, 'company_link', 'http://easyappointments.org'), (8, 'company_link', 'http://easyappointments.org'),
(9, 'book_advance_timeout', '30'); (9, 'book_advance_timeout', '30'),
(15, NULL, NULL);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -224,7 +228,7 @@ CREATE TABLE IF NOT EXISTS `ea_users` (
`id_roles` bigint(20) unsigned NOT NULL, `id_roles` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `id_roles` (`id_roles`) KEY `id_roles` (`id_roles`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=24 ; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
-- --
-- Άδειασμα δεδομένων του πίνακα `ea_users` -- Άδειασμα δεδομένων του πίνακα `ea_users`
@ -234,11 +238,14 @@ INSERT INTO `ea_users` (`id`, `first_name`, `last_name`, `email`, `mobile_number
(2, 'Ned', 'Janger', 'alextselegidis@gmail.com', '659875666', '785448465', 'Kloesel', 'Berlin', '', '23980', '', 2), (2, 'Ned', 'Janger', 'alextselegidis@gmail.com', '659875666', '785448465', 'Kloesel', 'Berlin', '', '23980', '', 2),
(3, 'Urlich', 'Setzel', 'u.setzel@piorin.com', '23908252398', '20923798723', 'Groundliche Str. 23', 'Munich', 'Bayern', '86895', '', 2), (3, 'Urlich', 'Setzel', 'u.setzel@piorin.com', '23908252398', '20923798723', 'Groundliche Str. 23', 'Munich', 'Bayern', '86895', '', 2),
(4, 'Brandon', 'Clod', 'b.clod@besters.org', '239072439', '858754487', 'Wellin Str 8', 'Plymouth', '', '20940', '', 2), (4, 'Brandon', 'Clod', 'b.clod@besters.org', '239072439', '858754487', 'Wellin Str 8', 'Plymouth', '', '20940', '', 2),
(18, 'Tod', 'Cliffer', 'info@alextselegidis.com', '987568857', '875986878', 'Yourd Str 98', 'Blackpool', '', '09234', '', 1), (18, 'Tod', 'Cliffer', 'info@alextselegidis.com', '987568857', '875986878', 'Yourd Str 98', 'Blackpool', 'MyState', '85874', 'This is a test admin record used for testing the project. All the data are not real.', 1),
(20, 'Sonia', 'Sterling', 's.sterling@reo.com', '584256658', '4265462587', '', '', '', '', '', 4), (20, 'Sonia', 'Sterling', 's.sterling@reo.com', '584256658', '4265462587', '', '', '', '', '', 4),
(21, 'Alex', 'Tselegidis', 'info@alextselegidis.com', NULL, '98765465712', '', '', NULL, '', '', 3), (21, 'Alex', 'Tselegidis', 'info@alextselegidis.com', NULL, '98765465712', '', '', NULL, '', '', 3),
(22, 'John', 'Doe', 'john.doe@oizent.com', NULL, '8757595445', 'Orizend 51', 'London', NULL, '56648', 'Test customer record.', 3), (22, 'John', 'Doe', 'john.doe@oizent.com', NULL, '8757595445', 'Orizend 51', 'London', NULL, '56648', 'Test customer record.', 3),
(23, 'James', 'Goern', 'james.goern@softiner.com', NULL, '98654869544', 'Ureklin 09', 'New York', NULL, '56987', NULL, 3); (23, 'James', 'Goern', 'james.goern@softiner.com', NULL, '98654869544', 'Ureklin 09', 'New York', NULL, '56987', NULL, 3),
(24, 'test', 'test', 'test@test.com', '233252325', '234523342', 'test', 'test', '', '', '', 1),
(25, 'Jason', 'Brandon', 'j.brandon@solyell.uk', '7899875789', '7854789897', 'Hilton Str. 52', 'Michigan', '', '87786', 'This is a test provider. All data are fictional.', 2),
(26, 'John', 'Doe', 'j.doe@doens.com', NULL, '897987657', '', '', NULL, '', NULL, 3);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -250,8 +257,9 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` (
`id_users` bigint(20) unsigned NOT NULL, `id_users` bigint(20) unsigned NOT NULL,
`username` varchar(256) DEFAULT NULL, `username` varchar(256) DEFAULT NULL,
`password` varchar(512) DEFAULT NULL, `password` varchar(512) DEFAULT NULL,
`salt` varchar(512) DEFAULT NULL,
`working_plan` text, `working_plan` text,
`notifications` text, `notifications` tinyint(4) DEFAULT '0',
`google_sync` tinyint(4) DEFAULT '0', `google_sync` tinyint(4) DEFAULT '0',
`google_token` text, `google_token` text,
`sync_past_days` int(11) DEFAULT '5', `sync_past_days` int(11) DEFAULT '5',
@ -263,12 +271,14 @@ CREATE TABLE IF NOT EXISTS `ea_user_settings` (
-- Άδειασμα δεδομένων του πίνακα `ea_user_settings` -- Άδειασμα δεδομένων του πίνακα `ea_user_settings`
-- --
INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `working_plan`, `notifications`, `google_sync`, `google_token`, `sync_past_days`, `sync_future_days`) VALUES INSERT INTO `ea_user_settings` (`id_users`, `username`, `password`, `salt`, `working_plan`, `notifications`, `google_sync`, `google_token`, `sync_past_days`, `sync_future_days`) VALUES
(2, 'ned.janger', 'test', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', '1', 0, NULL, 5, 5), (2, 'ned.janger', '6ad76c5daab92f2aaf9f9d725cb72bc2774fdb4ac2172828a8f1c6aa69e9b0d1', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5),
(3, 'u.setzel', 'test', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', '1', 0, NULL, 5, 5), (3, 'u.setzel', 'f00e1e6f3780859b40645be7ff8e91878ea2679eb62fbc45a8bff1243338b741', '7f8231dd21df341c651522e4091637e6a93d160decb6a7a99bd08a5dc5d947c8', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5),
(4, 'b.clod', 'test', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', '0', 0, NULL, 5, 5), (4, 'b.clod', '811acf5c450e0eb2866a17cdc3701a0b1fddb98ea2065e91259e8e6ce9b678b6', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 0, 0, NULL, 5, 5),
(18, 't.cliffer', 'test', NULL, '0', 0, NULL, 5, 5), (18, 'admin', '9e81360f0a631fe7e49e9d051b05c581a0f17575ca043a340be4441e166de821', 'd6ac3bfb4e6d9f82ec54e606852a9afbe8697696cddd28f30423eddf98762f41', NULL, 0, 0, NULL, 5, 5),
(20, 's.sterling', 'test', NULL, '0', 0, NULL, 5, 5); (20, 's.sterling', '8746aff0a416b63e71046d6a6adc6e2fd9de4a1cf4de0281e5b5f60ba8ae4451', 'edd27f8204a0cc47c60a3cd031fe03211be2561c76b334678e0f982ef582bf6e', NULL, 0, 0, NULL, 5, 5),
(24, 'test', 'd1dce587f7eefdb93adceb4e8903d72036bf97d37482b9c7b1d5f08353d061f3', 'd6ac3bfb4e6d9f82ec54e606852a9afbe8697696cddd28f30423eddf98762f41', NULL, 0, 0, NULL, 5, 5),
(25, 'j.brandon', 'dc93d098ccbcaa871e4adcc2dd770d71f6fca7a24dbd635e00006b5075dc2db1', '7f8231dd21df341c651522e4091637e6a93d160decb6a7a99bd08a5dc5d947c8', '{"monday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"tuesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"wednesday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"thursday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"friday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"saturday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]},"sunday":{"start":"09:00","end":"18:00","breaks":[{"start":"11:20","end":"11:30"},{"start":"14:30","end":"15:00"}]}}', 1, 0, NULL, 5, 5);
-- --
-- Περιορισμοί για άχρηστους πίνακες -- Περιορισμοί για άχρηστους πίνακες

View file

@ -137,7 +137,10 @@ class Appointments extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER // :: SEND NOTIFICATION EMAILS TO BOTH CUSTOMER AND PROVIDER
try { try {
$this->load->library('Notifications'); $this->load->library('Notifications');
$send_provider = $this->providers_model
->get_setting('notifications', $provider['id']);
if (!$post_data['manage_mode']) { if (!$post_data['manage_mode']) {
$customer_title = 'Your appointment has been successfully booked!'; $customer_title = 'Your appointment has been successfully booked!';
$customer_message = 'Thank you for arranging an appointment with us. ' $customer_message = 'Thank you for arranging an appointment with us. '
@ -166,10 +169,12 @@ class Appointments extends CI_Controller {
$this->notifications->send_appointment_details($appointment, $provider, $this->notifications->send_appointment_details($appointment, $provider,
$service, $customer,$company_settings, $customer_title, $service, $customer,$company_settings, $customer_title,
$customer_message, $customer_link, $customer['email']); $customer_message, $customer_link, $customer['email']);
$this->notifications->send_appointment_details($appointment, $provider, if ($send_provider == TRUE) {
$service, $customer, $company_settings, $provider_title, $this->notifications->send_appointment_details($appointment, $provider,
$provider_message, $provider_link, $provider['email']); $service, $customer, $company_settings, $provider_title,
$provider_message, $provider_link, $provider['email']);
}
} catch(Exception $exc) { } catch(Exception $exc) {
$view['exceptions'][] = $exc; $view['exceptions'][] = $exc;
} }
@ -254,9 +259,16 @@ class Appointments extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO CUSTOMER AND PROVIDER // :: SEND NOTIFICATION EMAILS TO CUSTOMER AND PROVIDER
try { try {
$this->load->library('Notifications'); $this->load->library('Notifications');
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $provider['email'], $send_provider = $this->providers_model
$_POST['cancel_reason']); ->get_setting('notifications', $provider['id']);
if ($send_provider == TRUE) {
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $provider['email'],
$_POST['cancel_reason']);
}
$this->notifications->send_delete_appointment($appointment, $provider, $this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $customer['email'], $service, $customer, $company_settings, $customer['email'],
$_POST['cancel_reason']); $_POST['cancel_reason']);
@ -268,6 +280,8 @@ class Appointments extends CI_Controller {
$exceptions[] = $exc; $exceptions[] = $exc;
} }
$view = array();
if (isset($exceptions)) { if (isset($exceptions)) {
$view['exceptions'] = $exceptions; $view['exceptions'] = $exceptions;
} }

View file

@ -122,6 +122,7 @@ class Backend extends CI_Controller {
$view['providers'] = $this->providers_model->get_batch(); $view['providers'] = $this->providers_model->get_batch();
$view['secretaries'] = $this->secretaries_model->get_batch(); $view['secretaries'] = $this->secretaries_model->get_batch();
$view['services'] = $this->services_model->get_batch(); $view['services'] = $this->services_model->get_batch();
$view['working_plan'] = $this->settings_model->get_setting('company_working_plan');
$this->load->view('backend/header', $view); $this->load->view('backend/header', $view);
$this->load->view('backend/users', $view); $this->load->view('backend/users', $view);

View file

@ -141,7 +141,10 @@ class Backend_api extends CI_Controller {
// :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER // :: SEND EMAIL NOTIFICATIONS TO PROVIDER AND CUSTOMER
try { try {
$this->load->library('Notifications'); $this->load->library('Notifications');
$send_provider = $this->providers_model
->get_setting('notifications', $provider['id']);
if (!$manage_mode) { if (!$manage_mode) {
$customer_title = 'Your appointment has been successfully booked!'; $customer_title = 'Your appointment has been successfully booked!';
$customer_message = 'Thank you for arranging an appointment with us. ' $customer_message = 'Thank you for arranging an appointment with us. '
@ -171,9 +174,11 @@ class Backend_api extends CI_Controller {
$service, $customer, $company_settings, $customer_title, $service, $customer, $company_settings, $customer_title,
$customer_message, $customer_link, $customer['email']); $customer_message, $customer_link, $customer['email']);
$this->notifications->send_appointment_details($appointment, $provider, if ($send_provider == TRUE) {
$service, $customer, $company_settings, $provider_title, $this->notifications->send_appointment_details($appointment, $provider,
$provider_message, $provider_link, $provider['email']); $service, $customer, $company_settings, $provider_title,
$provider_message, $provider_link, $provider['email']);
}
} catch(Exception $exc) { } catch(Exception $exc) {
$warnings[] = exceptionToJavaScript($exc); $warnings[] = exceptionToJavaScript($exc);
@ -250,9 +255,16 @@ class Backend_api extends CI_Controller {
// :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER // :: SEND NOTIFICATION EMAILS TO PROVIDER AND CUSTOMER
try { try {
$this->load->library('Notifications'); $this->load->library('Notifications');
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $provider['email'], $send_provider = $this->providers_model
$_POST['delete_reason']); ->get_setting('notifications', $provider['id']);
if ($send_provider == TRUE) {
$this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $provider['email'],
$_POST['delete_reason']);
}
$this->notifications->send_delete_appointment($appointment, $provider, $this->notifications->send_delete_appointment($appointment, $provider,
$service, $customer, $company_settings, $customer['email'], $service, $customer, $company_settings, $customer['email'],
$_POST['delete_reason']); $_POST['delete_reason']);
@ -704,7 +716,7 @@ class Backend_api extends CI_Controller {
$this->load->model('providers_model'); $this->load->model('providers_model');
$provider = json_decode($_POST['provider'], true); $provider = json_decode($_POST['provider'], true);
if (!isset($provider['working_plan'])) { if (!isset($provider['settings']['working_plan'])) {
$this->load->model('settings_model'); $this->load->model('settings_model');
$provider['settings']['working_plan'] = $this->settings_model $provider['settings']['working_plan'] = $this->settings_model
->get_setting('company_working_plan'); ->get_setting('company_working_plan');

View file

@ -37,8 +37,6 @@ function date3339($timestamp=0) {
* @return string Returns the hash string of the given password. * @return string Returns the hash string of the given password.
*/ */
function hash_password($salt, $password) { function hash_password($salt, $password) {
$salt = strtoupper($salt);
$password = strtoupper($password);
$half = (int)(strlen($salt) / 2); $half = (int)(strlen($salt) / 2);
$hash = hash('sha256', substr($salt, 0, $half ) . $password . substr($salt, $half)); $hash = hash('sha256', substr($salt, 0, $half ) . $password . substr($salt, $half));

View file

@ -204,16 +204,6 @@ class Admins_Model extends CI_Model {
throw new Exception('Invalid email address provided : ' . $admin['email']); throw new Exception('Invalid email address provided : ' . $admin['email']);
} }
// Validate admin username
if (isset($admin['settings']['username'])) {
$num_rows = $this->db->get_where('ea_user_settings',
array('username' => $admin['settings']['username']))->num_rows();
if ($num_rows > 0) {
throw new Exception('Username already exists, please select another '
. 'and try again (username: ' . $admin['settings']['username'] . ')');
}
}
// Validate admin password // Validate admin password
if (isset($admin['settings']['password'])) { if (isset($admin['settings']['password'])) {
if (strlen($admin['settings']['password']) < MIN_PASSWORD_LENGTH) { if (strlen($admin['settings']['password']) < MIN_PASSWORD_LENGTH) {
@ -367,10 +357,10 @@ class Admins_Model extends CI_Model {
*/ */
public function validate_username($username, $record_exists) { public function validate_username($username, $record_exists) {
$num_rows = $this->db->get_where('ea_user_settings', array('username' => $username))->num_rows(); $num_rows = $this->db->get_where('ea_user_settings', array('username' => $username))->num_rows();
if ($num_rows == 0 && $record_exists == FALSE || $num_rows == 1 && $record_exists == TRUE) { if (($num_rows == 0 && $record_exists == FALSE) || ($num_rows == 1 && $record_exists == TRUE)) {
return true; return TRUE;
} else { } else {
return false; return FALSE;
} }
} }
} }

View file

@ -236,16 +236,6 @@ class Providers_Model extends CI_Model {
throw new Exception('Invalid provider settings given: ' . print_r($provider, TRUE)); throw new Exception('Invalid provider settings given: ' . print_r($provider, TRUE));
} }
// Validate admin username
if (isset($provider['settings']['username'])) {
$num_rows = $this->db->get_where('ea_user_settings',
array('username' => $provider['settings']['username']))->num_rows();
if ($num_rows > 0) {
throw new Exception('Username already exists, please select another '
. 'and try again (username: ' . $provider['settings']['username'] . ')');
}
}
// Validate admin password // Validate admin password
if (isset($provider['settings']['password'])) { if (isset($provider['settings']['password'])) {
if (strlen($provider['settings']['password']) < MIN_PASSWORD_LENGTH) { if (strlen($provider['settings']['password']) < MIN_PASSWORD_LENGTH) {

View file

@ -60,6 +60,13 @@
<input type="text" id="company-link" data-field="company_link"> <input type="text" id="company-link" data-field="company_link">
<span class="help-block">Company link should point to the official website of <span class="help-block">Company link should point to the official website of
the company (optional).</span> the company (optional).</span>
<br><br>
<a href="<?php echo $this->config->base_url(); ?>" class="btn btn-primary btn-large">
<i class="icon-calendar icon-white"></i>
Visit Book Appointment Page
</a>
</fieldset> </fieldset>
</form> </form>
</div> </div>
@ -230,7 +237,7 @@
<input type="text" id="zip-code" class="span9" /> <input type="text" id="zip-code" class="span9" />
<label for="notes">Notes</label> <label for="notes">Notes</label>
<textarea id="notes" class="span9"></textarea> <textarea id="notes" class="span9" rows="3"></textarea>
</fieldset> </fieldset>
<fieldset class="span5"> <fieldset class="span5">

View file

@ -1,5 +1,9 @@
<script type="text/javascript" <script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/backend_users.js"></script> src="<?php echo $base_url; ?>assets/js/backend_users.js"></script>
<script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery-ui-timepicker-addon.js"></script>
<script type="text/javascript"
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery.jeditable.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var GlobalVariables = { var GlobalVariables = {
@ -7,7 +11,8 @@
'admins': <?php echo json_encode($admins); ?>, 'admins': <?php echo json_encode($admins); ?>,
'providers': <?php echo json_encode($providers); ?>, 'providers': <?php echo json_encode($providers); ?>,
'secretaries': <?php echo json_encode($secretaries); ?>, 'secretaries': <?php echo json_encode($secretaries); ?>,
'services': <?php echo json_encode($services); ?> 'services': <?php echo json_encode($services); ?>,
'workingPlan': $.parseJSON(<?php echo json_encode($working_plan); ?>)
}; };
$(document).ready(function() { $(document).ready(function() {
@ -63,7 +68,7 @@
<div class="form-message alert" style="display:none;"></div> <div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="admin-id" /> <input type="hidden" id="admin-id" class="record-id" />
<div class="row-fluid"> <div class="row-fluid">
<div class="admin-details span6"> <div class="admin-details span6">
@ -95,17 +100,17 @@
<input type="text" id="admin-zip-code" class="span11" /> <input type="text" id="admin-zip-code" class="span11" />
<label for="admin-notes">Notes</label> <label for="admin-notes">Notes</label>
<textarea id="admin-notes" class="span11"></textarea> <textarea id="admin-notes" class="span11" rows="3"></textarea>
</div> </div>
<div class="admin-settings span6"> <div class="admin-settings span6">
<label for="admin-username">Username *</label> <label for="admin-username">Username *</label>
<input type="text" id="admin-username" class="span7 required" /> <input type="text" id="admin-username" class="span9 required" />
<label for="admin-password">Password *</label> <label for="admin-password">Password *</label>
<input type="password" id="admin-password" class="span7 required"/> <input type="password" id="admin-password" class="span9 required"/>
<label for="admin-password-confirm">Retype Password *</label> <label for="admin-password-confirm">Retype Password *</label>
<input type="password" id="admin-password-confirm" class="span7 required" /> <input type="password" id="admin-password-confirm" class="span9 required" />
<br> <br>
@ -130,7 +135,7 @@
</div> </div>
<div class="details span7"> <div class="details span7">
<div class="btn-toolbar"> <div class="btn-toolbar span5">
<div class="add-edit-delete-group btn-group"> <div class="add-edit-delete-group btn-group">
<button id="add-provider" class="btn"> <button id="add-provider" class="btn">
<i class="icon-plus"></i> <i class="icon-plus"></i>
@ -153,66 +158,154 @@
</div> </div>
</div> </div>
<h2>Details</h2> <div class="switch-view pull-right">
<div class="display-details current">Details</div>
<div class="display-working-plan">Working Plan</div>
</div>
<div class="form-message alert" style="display:none;"></div> <div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="provider-id" /> <div class="details-view">
<h2>Details</h2>
<div class="row-fluid">
<div class="provider-details span6">
<label for="provider-first-name">First Name</label>
<input type="text" id="provider-first-name" class="span11" />
<label for="provider-last-name">Last Name *</label> <input type="hidden" id="provider-id" class="record-id" />
<input type="text" id="provider-last-name" class="span11 required" />
<label for="provider-email">Email *</label> <div class="row-fluid">
<input type="text" id="provider-email" class="span11 required" /> <div class="provider-details span6">
<label for="provider-first-name">First Name</label>
<input type="text" id="provider-first-name" class="span11" />
<label for="provider-mobile-number">Mobile Number</label> <label for="provider-last-name">Last Name *</label>
<input type="text" id="provider-mobile-number" class="span11" /> <input type="text" id="provider-last-name" class="span11 required" />
<label for="provider-phone-number">Phone Number *</label> <label for="provider-email">Email *</label>
<input type="text" id="provider-phone-number" class="span11 required" /> <input type="text" id="provider-email" class="span11 required" />
<label for="provider-address">Address</label> <label for="provider-mobile-number">Mobile Number</label>
<input type="text" id="provider-address" class="span11" /> <input type="text" id="provider-mobile-number" class="span11" />
<label for="provider-city">City</label> <label for="provider-phone-number">Phone Number *</label>
<input type="text" id="provider-city" class="span11" /> <input type="text" id="provider-phone-number" class="span11 required" />
<label for="provider-state">State</label> <label for="provider-address">Address</label>
<input type="text" id="provider-state" class="span11" /> <input type="text" id="provider-address" class="span11" />
<label for="provider-zip-code">Zip Code</label> <label for="provider-city">City</label>
<input type="text" id="provider-zip-code" class="span11" /> <input type="text" id="provider-city" class="span11" />
<label for="provider-notes">Notes</label> <label for="provider-state">State</label>
<textarea id="provider-notes" class="span11"></textarea> <input type="text" id="provider-state" class="span11" />
<label for="provider-zip-code">Zip Code</label>
<input type="text" id="provider-zip-code" class="span11" />
<label for="provider-notes">Notes</label>
<textarea id="provider-notes" class="span11" rows="3"></textarea>
</div>
<div class="provider-settings span6">
<label for="provider-username">Username *</label>
<input type="text" id="provider-username" class="span9 required" />
<label for="provider-password">Password *</label>
<input type="password" id="provider-password" class="span9 required"/>
<label for="provider-password-confirm">Retype Password *</label>
<input type="password" id="provider-password-confirm" class="span9 required" />
<br>
<button type="button" id="provider-notifications" class="btn" data-toggle="button">
<i class="icon-asterisk"></i>
<span>Receive Email Notifications</span>
</button>
<br><br>
<h4>Services</h4>
<div id="provider-services"></div>
</div>
</div> </div>
<div class="provider-settings span6"> </div>
<label for="provider-username">Username *</label>
<input type="text" id="provider-username" class="span7 required" /> <div class="working-plan-view" style="display: none;">
<h2>Working Plan</h2>
<label for="provider-password">Password *</label> <table class="working-plan table table-striped">
<input type="password" id="provider-password" class="span7 required"/> <thead>
<tr>
<label for="provider-password-confirm">Retype Password *</label> <th>Day</th>
<input type="password" id="provider-password-confirm" class="span7 required" /> <th>Start</th>
<th>End</th>
<br> </tr>
</thead>
<button type="button" id="provider-notifications" class="btn" data-toggle="button"> <tbody>
<i class="icon-asterisk"></i> <tr>
<span>Receive Email Notifications</span> <td><label class="checkbox"><input type="checkbox" id="monday" />Monday</label></td>
<td><input type="text" id="monday-start" class="work-start" /></td>
<td><input type="text" id="monday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="tuesday" />Tuesday</label></td>
<td><input type="text" id="tuesday-start" class="work-start" /></td>
<td><input type="text" id="tuesday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="wednesday" />Wednesday</label></td>
<td><input type="text" id="wednesday-start" class="work-start" /></td>
<td><input type="text" id="wednesday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="thursday" />Thursday</label></td>
<td><input type="text" id="thursday-start" class="work-start" /></td>
<td><input type="text" id="thursday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="friday" />Friday</label></td>
<td><input type="text" id="friday-start" class="work-start" /></td>
<td><input type="text" id="friday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="saturday" />Saturday</label></td>
<td><input type="text" id="saturday-start" class="work-start" /></td>
<td><input type="text" id="saturday-end" class="work-end" /></td>
</tr>
<tr>
<td><label class="checkbox"><input type="checkbox" id="sunday" />Sunday</label></td>
<td><input type="text" id="sunday-start" class="work-start" /></td>
<td><input type="text" id="sunday-end" class="work-end" /></td>
</tr>
</tbody>
</table>
<br>
<h2>Breaks</h2>
<span class="help-block">
Add the working breaks during each day. These breaks will be applied for
all new providers.
</span>
<div>
<button type="button" class="add-break btn btn-primary">
<i class="icon-white icon-plus"></i>
Add Break
</button> </button>
<br><br>
<h4>Services</h4>
<div id="provider-services"></div>
</div> </div>
<br>
<table id="breaks" class="table table-striped">
<thead>
<tr>
<th>Day</th>
<th>Start</th>
<th>End</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
@ -256,7 +349,7 @@
<div class="form-message alert" style="display:none;"></div> <div class="form-message alert" style="display:none;"></div>
<input type="hidden" id="secretary-id" /> <input type="hidden" id="secretary-id" class="record-id" />
<div class="row-fluid"> <div class="row-fluid">
<div class="secretary-details span6"> <div class="secretary-details span6">
@ -288,17 +381,17 @@
<input type="text" id="secretary-zip-code" class="span11" /> <input type="text" id="secretary-zip-code" class="span11" />
<label for="secretary-notes">Notes</label> <label for="secretary-notes">Notes</label>
<textarea id="secretary-notes" class="span11"></textarea> <textarea id="secretary-notes" class="span11" rows="3"></textarea>
</div> </div>
<div class="secretary-settings span6"> <div class="secretary-settings span6">
<label for="secretary-username">Username *</label> <label for="secretary-username">Username *</label>
<input type="text" id="secretary-username" class="span7 required" /> <input type="text" id="secretary-username" class="span9 required" />
<label for="secretary-password">Password *</label> <label for="secretary-password">Password *</label>
<input type="password" id="secretary-password" class="span7 required"/> <input type="password" id="secretary-password" class="span9 required"/>
<label for="secretary-password-confirm">Retype Password *</label> <label for="secretary-password-confirm">Retype Password *</label>
<input type="password" id="secretary-password-confirm" class="span7 required" /> <input type="password" id="secretary-password-confirm" class="span9 required" />
<br> <br>

View file

@ -184,6 +184,7 @@ body .modal-header h3 {
#calendar table thead .fc-first th { #calendar table thead .fc-first th {
vertical-align: middle; vertical-align: middle;
padding: 2px 0; padding: 2px 0;
color: #555;
} }
#manage-appointment { #manage-appointment {
@ -369,6 +370,48 @@ body .modal-header h3 {
padding: 7px; padding: 7px;
} }
#users-page #providers .switch-view {
overflow: auto;
margin-bottom: 5px;
}
#users-page #providers .switch-view div {
display: inline-block;
padding: 10px 15px;
border-radius: 4px;
color: #333;
float: left;
margin-right: 5px;
cursor: pointer;
}
#users-page #providers .switch-view div:hover:not(.current) {
background: #F5F5F5;
}
#users-page #providers .switch-view .current {
color: #FFF;
background: #95E4A8;
}
#users-page #providers .details-view,
#users-page #providers .working-plan-view {
clear: both;
}
#users-page .btn-toolbar {
margin-top: 0;
margin-bottom: 15px;
}
#users-page #providers .form-message {
clear: both;
}
#users-page #providers #breaks .btn {
margin-right: 5px;
padding: 4px 7px;
}
/* BACKEND SETTINGS PAGE /* BACKEND SETTINGS PAGE
-------------------------------------------------------------------- */ -------------------------------------------------------------------- */

View file

@ -7,6 +7,21 @@
var BackendUsers = { var BackendUsers = {
MIN_PASSWORD_LENGTH: 7, MIN_PASSWORD_LENGTH: 7,
/**
* This flag is used when trying to cancel row editing. It is
* true only whenever the user presses the cancel button.
*
* @type {bool}
*/
enableCancel: false,
/**
* This flag determines whether the jeditables are allowed to submit. It is
* true only whenever the user presses the save button.
*
* @type {bool}
*/
enableSubmit: false,
/** /**
* Contains the current tab record methods for the page. * Contains the current tab record methods for the page.
@ -98,26 +113,45 @@ var BackendUsers = {
$('.filter-key').val(''); $('.filter-key').val('');
}); });
$('#admin-username').focusout(function() { /**
// Validate username. * Event: Admin, Provider, Secretary Username "Focusout"
*
* When the user leaves the username input field we will need to check if the username
* is not taken by another record in the system. Usernames must be unique.
*/
$('#admin-username, #provider-username, #secretary-username').focusout(function() {
var $input = $(this);
if ($input.prop('readonly') == true || $input.val() == '') {
return;
}
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_validate_username'; var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_validate_username';
var postData = { var postData = {
'username': $('#admin-username').val(), 'username': $input.val(),
'record_exists': ($('#admin-id').val() != '') ? true : false 'record_exists': ($input.parents().eq(2).find('.record-id').val() != '') ? true : false
}; };
$.post(postUrl, postData, function(response) { $.post(postUrl, postData, function(response) {
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
console.log('Validate Username Response:', response); console.log('Validate Username Response:', response);
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return; if (!GeneralFunctions.handleAjaxExceptions(response)) return;
if (!response) { if (response == false) {
$('#admin-username').css('border', '2px solid red'); $input.css('border', '2px solid red');
$('#admins .form-message').text('Username already exists.'); $input.parents().eq(3).find('.form-message').text('Username already exists.');
$('#admins .form-message').show(); $input.parents().eq(3).find('.form-message').show();
} else {
$input.css('border', '');
if ($input.parents().eq(3).find('.form-message').text() == 'Username already exists.') {
$input.parents().eq(3).find('.form-message').hide();
}
} }
}, 'json'); }, 'json');
}); });
// -----------------------------------------------------------------
/** /**
* Event: Filter Admins Button "Click" * Event: Filter Admins Button "Click"
* *
@ -244,6 +278,19 @@ var BackendUsers = {
*/ */
$('#cancel-admin').click(function() { $('#cancel-admin').click(function() {
BackendUsers.helper.resetForm(); BackendUsers.helper.resetForm();
var admin = { 'id': $('#admins .selected-row').attr('data-id') };
$.each(BackendUsers.helper.filterResults, function(index, item) {
if (item.id === admin.id) {
admin = item;
return;
}
});
BackendUsers.helper.display(admin);
$('#edit-admin, #delete-admin').prop('disabled', false);
}); });
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -297,6 +344,186 @@ var BackendUsers = {
$('#provider-password, #provider-password-confirm').addClass('required'); $('#provider-password, #provider-password-confirm').addClass('required');
$('#provider-notifications').prop('disabled', false); $('#provider-notifications').prop('disabled', false);
$('#provider-services input[type="checkbox"]').prop('disabled', false); $('#provider-services input[type="checkbox"]').prop('disabled', false);
$('#providers .add-break').prop('disabled', false);
$('.edit-break, .delete-break').prop('disabled', false);
$('#providers input[type="checkbox"]').prop('disabled', false);
// Apply default working plan
$.each(GlobalVariables.workingPlan, function(index, workingDay) {
if (workingDay != null) {
$('#' + index).prop('checked', true);
$('#' + index + '-start').val(workingDay.start);
$('#' + index + '-end').val(workingDay.end);
// Add the day's breaks on the breaks table.
$.each(workingDay.breaks, function(i, brk) {
var tr =
'<tr>' +
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
'<td class="break-start editable">' + brk.start + '</td>' +
'<td class="break-end editable">' + brk.end + '</td>' +
'<td>' +
'<button type="button" class="btn edit-break" title="Edit Break">' +
'<i class="icon-pencil"></i>' +
'</button>' +
'<button type="button" class="btn delete-break" title="Delete Break">' +
'<i class="icon-remove"></i>' +
'</button>' +
'<button type="button" class="btn save-break hidden" title="Save Break">' +
'<i class="icon-ok"></i>' +
'</button>' +
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
'<i class="icon-ban-circle"></i>' +
'</button>' +
'</td>' +
'</tr>';
$('#breaks').append(tr);
});
} else {
$('#' + index).prop('checked', false);
$('#' + index + '-start').prop('disabled', true);
$('#' + index + '-end').prop('disabled', true);
}
});
// Make break cells editable.
BackendUsers.editableBreakDay($('#breaks .break-day'));
BackendUsers.editableBreakTime($('#breaks').find('.break-start, .break-end'));
// Set timepickers where needed.
$('.working-plan input').timepicker({
'timeFormat': 'HH:mm',
'onSelect': function(datetime, inst) {
// Start time must be earlier than end time.
var start = Date.parse($(this).parent().parent().find('.work-start').val());
var end = Date.parse($(this).parent().parent().find('.work-end').val());
if (start > end) {
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
}
}
});
});
/**
* Event: Day Checkbox "Click"
*
* Enable or disable the time selection for each day.
*/
$('.working-plan input[type="checkbox"]').click(function() {
var id = $(this).attr('id');
if ($(this).prop('checked') == true) {
$('#' + id + '-start').prop('disabled', false).val('09:00');
$('#' + id + '-end').prop('disabled', false).val('18:00');
} else {
$('#' + id + '-start').prop('disabled', true).val('');
$('#' + id + '-end').prop('disabled', true).val('');
}
});
/**
* Event: Add Break Button "Click"
*
* A new row is added on the table and the user can enter the new break
* data. After that he can either press the save or cancel button.
*/
$('.add-break').click(function() {
var tr =
'<tr>' +
'<td class="break-day editable">Monday</td>' +
'<td class="break-start editable">09:00</td>' +
'<td class="break-end editable">10:00</td>' +
'<td>' +
'<button type="button" class="btn edit-break" title="Edit Break">' +
'<i class="icon-pencil"></i>' +
'</button>' +
'<button type="button" class="btn delete-break" title="Delete Break">' +
'<i class="icon-remove"></i>' +
'</button>' +
'<button type="button" class="btn save-break hidden" title="Save Break">' +
'<i class="icon-ok"></i>' +
'</button>' +
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
'<i class="icon-ban-circle"></i>' +
'</button>' +
'</td>' +
'</tr>';
$('#breaks').prepend(tr);
// Bind editable and event handlers.
tr = $('#breaks tr').get()[1];
BackendUsers.editableBreakDay($(tr).find('.break-day'));
BackendUsers.editableBreakTime($(tr).find('.break-start, .break-end'));
$(tr).find('.edit-break').trigger('click');
});
/**
* Event: Edit Break Button "Click"
*
* Enables the row editing for the "Breaks" table rows.
*/
$(document).on('click', '.edit-break', function() {
// Reset previous editable tds
var $previousEdt = $(this).closest('table').find('.editable').get();
$.each($previousEdt, function(index, edt) {
edt.reset();
});
// Make all cells in current row editable.
$(this).parent().parent().children().trigger('edit');
$(this).parent().parent().find('.break-start input, .break-end input').timepicker();
$(this).parent().parent().find('.break-day select').focus();
// Show save - cancel buttons.
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
});
/**
* Event: Delete Break Button "Click"
*
* Removes the current line from the "Breaks" table.
*/
$(document).on('click', '.delete-break', function() {
$(this).parent().parent().remove();
});
/**
* Event: Cancel Break Button "Click"
*
* Bring the "#breaks" table back to its initial state.
*/
$(document).on('click', '.cancel-break', function() {
BackendUsers.enableCancel = true;
$(this).parent().parent().find('.cancel-editable').trigger('click');
BackendUsers.enableCancel = false;
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
});
/**
* Event: Save Break Button "Click"
*
* Save the editable values and restore the table to its initial state.
*/
$(document).on('click', '.save-break', function() {
// Break's start time must always be prior to break's end.
var start = Date.parse($(this).parent().parent().find('.break-start input').val());
var end = Date.parse($(this).parent().parent().find('.break-end input').val());
if (start > end) {
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
}
BackendUsers.enableSubmit = true;
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
BackendUsers.enableSubmit = false;
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
}); });
/** /**
@ -311,6 +538,10 @@ var BackendUsers = {
$('#provider-password, #provider-password-confirm').removeClass('required'); $('#provider-password, #provider-password-confirm').removeClass('required');
$('#provider-notifications').prop('disabled', false); $('#provider-notifications').prop('disabled', false);
$('#provider-services input[type="checkbox"]').prop('disabled', false); $('#provider-services input[type="checkbox"]').prop('disabled', false);
$('#providers .add-break').prop('disabled', false);
$('.edit-break, .delete-break').prop('disabled', false);
$('#providers input[type="checkbox"]').prop('disabled', false);
}); });
/** /**
@ -349,7 +580,8 @@ var BackendUsers = {
'zip_code': $('#provider-zip-code').val(), 'zip_code': $('#provider-zip-code').val(),
'notes': $('#provider-notes').val(), 'notes': $('#provider-notes').val(),
'settings': { 'settings': {
'username': $('#provider-username').val(), 'username': $('#provider-username').val(),
'working_plan': BackendUsers.helper.getWorkingPlan(),
'notifications': $('#provider-notifications').hasClass('active') 'notifications': $('#provider-notifications').hasClass('active')
} }
}; };
@ -384,6 +616,42 @@ var BackendUsers = {
*/ */
$('#cancel-provider').click(function() { $('#cancel-provider').click(function() {
BackendUsers.helper.resetForm(); BackendUsers.helper.resetForm();
var provider = { 'id': $('#providers .selected-row').attr('data-id') };
$.each(BackendUsers.helper.filterResults, function(index, item) {
if (item.id === provider.id) {
provider = item;
return;
}
});
BackendUsers.helper.display(provider);
$('#edit-provider, #delete-provider').prop('disabled', false);
});
/**
* Event: Display Provider Details "Click"
*/
$('#providers .display-details').click(function() {
$('#providers .switch-view .current').removeClass('current');
$(this).addClass('current');
$('.working-plan-view').hide('fade', function() {
$('.details-view').show('fade');
});
});
/**
* Event: Display Provider Working Plan "Click"
*/
$('#providers .display-working-plan').click(function() {
$('#providers .switch-view .current').removeClass('current');
$(this).addClass('current');
$('.details-view').hide('fade', function() {
$('.working-plan-view').show('fade');
});
}); });
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -525,8 +793,58 @@ var BackendUsers = {
$('#cancel-secretary').click(function() { $('#cancel-secretary').click(function() {
BackendUsers.helper.resetForm(); BackendUsers.helper.resetForm();
}); });
},
}
/**
* Initialize the editable functionality to the break day table cells.
*
* @param {object} $selector The cells to be initialized.
*/
editableBreakDay: function($selector) {
$selector.editable(function(value, settings) {
return value;
}, {
'type': 'select',
'data': '{ "Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", '
+ '"Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", '
+ '"Sunday": "Sunday", "selected": "Monday"}',
'event': 'edit',
'height': '30px',
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
'onblur': 'ignore',
'onreset': function(settings, td) {
if (!BackendUsers.enableCancel) return false; // disable ESC button
},
'onsubmit': function(settings, td) {
if (!BackendUsers.enableSubmit) return false; // disable Enter button
}
});
},
/**
* Initialize the editable functionality to the break time table cells.
*
* @param {object} $selector The cells to be initialized.
*/
editableBreakTime: function($selector) {
$selector.editable(function(value, settings) {
// Do not return the value because the user needs to press the "Save" button.
return value;
}, {
'event': 'edit',
'height': '25px',
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
'onblur': 'ignore',
'onreset': function(settings, td) {
if (!BackendUsers.enableCancel) return false; // disable ESC button
},
'onsubmit': function(settings, td) {
if (!BackendUsers.enableSubmit) return false; // disable Enter button
}
});
}
}; };
/** /**
@ -558,8 +876,11 @@ AdminsHelper.prototype.save = function(admin) {
//////////////////////////////////////////////// ////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return; if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification('Admin saved successfully!'); Backend.displayNotification('Admin saved successfully!');
BackendUsers.helper.resetForm(); BackendUsers.helper.resetForm(true);
BackendUsers.helper.filter($('#admins .filter-key').val()); // When adding a new record the "admin.id" will be undefined. In this situation
// no record will be selected because we do not yet know the id of the new record,
// but no error will occur either.
BackendUsers.helper.filter($('#admins .filter-key').val(), admin.id);
}, 'json'); }, 'json');
}; };
@ -612,7 +933,8 @@ AdminsHelper.prototype.validate = function(admin) {
throw 'Passwords mismatch!'; throw 'Passwords mismatch!';
} }
if ($('#admin-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH) { if ($('#admin-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH
&& $('#admin-password').val() != '') {
$('#admin-password, #admin-password-confirm').css('border', '2px solid red'); $('#admin-password, #admin-password-confirm').css('border', '2px solid red');
throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH
+ ' characters long.'; + ' characters long.';
@ -634,20 +956,28 @@ AdminsHelper.prototype.validate = function(admin) {
/** /**
* Resets the admin tab form back to its initial state. * Resets the admin tab form back to its initial state.
*
* @param {bool} keepRecordData (OPTIONAL = false) If false then the current record data
* will remain on the form.
*/ */
AdminsHelper.prototype.resetForm = function() { AdminsHelper.prototype.resetForm = function(keepRecordData) {
$('#admins .details').find('input, textarea').val(''); if (keepRecordData == undefined) keepRecordData = false;
$('#admins .add-edit-delete-group').show(); $('#admins .add-edit-delete-group').show();
$('#admins .save-cancel-group').hide(); $('#admins .save-cancel-group').hide();
$('#edit-admin, #delete-admin').prop('disabled', true);
$('#admins .details').find('input, textarea').prop('readonly', true); $('#admins .details').find('input, textarea').prop('readonly', true);
$('.filter-admins').prop('disabled', false); $('.filter-admins').prop('disabled', false);
$('#admins .filter-results').css('color', ''); $('#admins .filter-results').css('color', '');
$('#admins .form-message').hide(); $('#admins .form-message').hide();
$('#admin-notifications').removeClass('active');
$('#admin-notifications').prop('disabled', true); $('#admin-notifications').prop('disabled', true);
$('#admins .required').css('border', ''); $('#admins .required').css('border', '');
$('#admin-password, #admin-password-confirm').css('border', ''); $('#admin-password, #admin-password-confirm').css('border', '');
if (!keepRecordData) {
$('#admins .details').find('input, textarea').val('');
$('#admin-notifications').removeClass('active');
$('#edit-admin, #delete-admin').prop('disabled', true);
}
}; };
/** /**
@ -681,7 +1011,7 @@ AdminsHelper.prototype.display = function(admin) {
* *
* @param {string} key This is used to filter the admin records of the database. * @param {string} key This is used to filter the admin records of the database.
*/ */
AdminsHelper.prototype.filter = function(key) { AdminsHelper.prototype.filter = function(key, selectRecordId) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_admins'; var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_admins';
var postData = { 'key': key }; var postData = { 'key': key };
@ -699,6 +1029,15 @@ AdminsHelper.prototype.filter = function(key) {
var html = AdminsHelper.prototype.getFilterHtml(admin); var html = AdminsHelper.prototype.getFilterHtml(admin);
$('#admins .filter-results').append(html); $('#admins .filter-results').append(html);
}); });
if (selectRecordId != undefined) {
$('.admin-row').each(function() {
if ($(this).attr('data-id') == selectRecordId) {
$(this).addClass('selected-row');
return false;
}
});
}
}, 'json'); }, 'json');
}; };
@ -747,8 +1086,10 @@ ProvidersHelper.prototype.save = function(provider) {
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return; if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification('Provider saved successfully!'); Backend.displayNotification('Provider saved successfully!');
BackendUsers.helper.resetForm(); BackendUsers.helper.resetForm(true);
BackendUsers.helper.filter($('#providers .filter-key').val()); // If "id" is not defined then no record will be selected (applies when adding
// a new provider record).
BackendUsers.helper.filter($('#providers .filter-key').val(), provider.id);
}, 'json'); }, 'json');
}; };
@ -801,7 +1142,8 @@ ProvidersHelper.prototype.validate = function(provider) {
throw 'Passwords mismatch!'; throw 'Passwords mismatch!';
} }
if ($('#provider-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH) { if ($('#provider-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH
&& $('#provider-password').val() != '') {
$('#provider-password, #provider-password-confirm').css('border', '2px solid red'); $('#provider-password, #provider-password-confirm').css('border', '2px solid red');
throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH
+ ' characters long.'; + ' characters long.';
@ -813,22 +1155,6 @@ ProvidersHelper.prototype.validate = function(provider) {
throw 'Invalid email address!'; throw 'Invalid email address!';
} }
// Validate username.
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_validate_username';
var postData = {
'username': $('#provider-username').val(),
'record_exists': ($('#provider-id').val() != '') ? true : false
};
$.post(postUrl, postData, function(response) {
///////////////////////////////////////////////////////
console.log('Validate Username Response:', response);
///////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
if (!response) {
throw('Username already exists, please enter another one and try again.');
}
});
return true; return true;
} catch(exc) { } catch(exc) {
$('#providers .form-message').text(exc); $('#providers .form-message').text(exc);
@ -839,22 +1165,36 @@ ProvidersHelper.prototype.validate = function(provider) {
/** /**
* Resets the admin tab form back to its initial state. * Resets the admin tab form back to its initial state.
*
* @param {bool} keepRecordData (OPTIONAL = false) If true then the current record data will
* remain on the form.
*/ */
ProvidersHelper.prototype.resetForm = function() { ProvidersHelper.prototype.resetForm = function(keepRecordData) {
$('#providers .details').find('input, textarea').val(''); if (keepRecordData == undefined) keepRecordData = false;
$('#providers .add-edit-delete-group').show(); $('#providers .add-edit-delete-group').show();
$('#providers .save-cancel-group').hide(); $('#providers .save-cancel-group').hide();
$('#edit-provider, #delete-provider').prop('disabled', true);
$('#providers .details').find('input, textarea').prop('readonly', true); $('#providers .details').find('input, textarea').prop('readonly', true);
$('.filter-providers').prop('disabled', false); $('.filter-providers').prop('disabled', false);
$('#providers .filter-results').css('color', ''); $('#providers .filter-results').css('color', '');
$('#providers .form-message').hide(); $('#providers .form-message').hide();
$('#provider-notifications').removeClass('active'); $('#provider-notifications').removeClass('active');
$('#provider-notifications').prop('disabled', true); $('#provider-notifications').prop('disabled', true);
$('#provider-services input[type="checkbox"]').prop('checked', false);
$('#provider-services input[type="checkbox"]').prop('disabled', true); $('#provider-services input[type="checkbox"]').prop('disabled', true);
$('#providers .required').css('border', ''); $('#providers .required').css('border', '');
$('#provider-password, #provider-password-confirm').css('border', ''); $('#provider-password, #provider-password-confirm').css('border', '');
$('#providers .add-break').prop('disabled', true);
$('#providers input[type="checkbox"]').prop('disabled', true);
$('#providers .working-plan input[type="text"]').timepicker('destroy');
$('#breaks').find('.edit-break, .delete-break').prop('disabled', true);
if (!keepRecordData) {
$('#edit-provider, #delete-provider').prop('disabled', true);
$('#providers .details').find('input, textarea').val('');
$('#providers input[type="checkbox"]').prop('checked', false);
$('#provider-services input[type="checkbox"]').prop('checked', false);
$('#providers #breaks tbody').empty();
}
}; };
/** /**
@ -890,14 +1230,76 @@ ProvidersHelper.prototype.display = function(provider) {
} }
}); });
}); });
// Display working plan
$('#providers #breaks tbody').empty();
var workingPlan = $.parseJSON(provider.settings.working_plan);
$.each(workingPlan, function(index, workingDay) {
if (workingDay != null) {
$('#' + index).prop('checked', true);
$('#' + index + '-start').val(workingDay.start);
$('#' + index + '-end').val(workingDay.end);
// Add the day's breaks on the breaks table.
$.each(workingDay.breaks, function(i, brk) {
var tr =
'<tr>' +
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
'<td class="break-start editable">' + brk.start + '</td>' +
'<td class="break-end editable">' + brk.end + '</td>' +
'<td>' +
'<button type="button" class="btn edit-break" title="Edit Break">' +
'<i class="icon-pencil"></i>' +
'</button>' +
'<button type="button" class="btn delete-break" title="Delete Break">' +
'<i class="icon-remove"></i>' +
'</button>' +
'<button type="button" class="btn save-break hidden" title="Save Break">' +
'<i class="icon-ok"></i>' +
'</button>' +
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
'<i class="icon-ban-circle"></i>' +
'</button>' +
'</td>' +
'</tr>';
$('#breaks').append(tr);
});
} else {
$('#' + index).prop('checked', false);
$('#' + index + '-start').prop('disabled', true);
$('#' + index + '-end').prop('disabled', true);
}
});
$('.edit-break, .delete-break').prop('disabled', true);
// Make break cells editable.
BackendUsers.editableBreakDay($('#breaks .break-day'));
BackendUsers.editableBreakTime($('#breaks').find('.break-start, .break-end'));
// Set timepickers where needed.
$('.working-plan input').timepicker({
'timeFormat': 'HH:mm',
'onSelect': function(datetime, inst) {
// Start time must be earlier than end time.
var start = Date.parse($(this).parent().parent().find('.work-start').val());
var end = Date.parse($(this).parent().parent().find('.work-end').val());
if (start > end) {
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
}
}
});
}; };
/** /**
* Filters provider records depending a string key. * Filters provider records depending a string key.
* *
* @param {string} key This is used to filter the provider records of the database. * @param {string} key This is used to filter the provider records of the database.
* @param {numeric} selectRecordId (OPTIONAL) If set, when the function is complete
* a result row can be set as selected.
*/ */
ProvidersHelper.prototype.filter = function(key) { ProvidersHelper.prototype.filter = function(key, selectRecordId) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_providers'; var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_providers';
var postData = { 'key': key }; var postData = { 'key': key };
@ -915,6 +1317,15 @@ ProvidersHelper.prototype.filter = function(key) {
var html = ProvidersHelper.prototype.getFilterHtml(provider); var html = ProvidersHelper.prototype.getFilterHtml(provider);
$('#providers .filter-results').append(html); $('#providers .filter-results').append(html);
}); });
if (selectRecordId != undefined) {
$('.provider-row').each(function() {
if ($(this).attr('data-id') == selectRecordId) {
$(this).addClass('selected-row');
return false;
}
});
}
}, 'json'); }, 'json');
}; };
@ -934,6 +1345,43 @@ ProvidersHelper.prototype.getFilterHtml = function(provider) {
return html; return html;
}; };
/**
* Get the current working plan.
*
* @return {string} Returns the working plan (already stringified).
*/
ProvidersHelper.prototype.getWorkingPlan = function() {
var workingPlan = {};
$('.working-plan input[type="checkbox"').each(function() {
var id = $(this).attr('id');
if ($(this).prop('checked') == true) {
workingPlan[id] = {}
workingPlan[id].start = $('#' + id + '-start').val();
workingPlan[id].end = $('#' + id + '-end').val();
workingPlan[id].breaks = [];
$('#breaks tr').each(function(index, tr) {
var day = $(tr).find('.break-day').text().toLowerCase();
if (day == id) {
var start = $(tr).find('.break-start').text();
var end = $(tr).find('.break-end').text();
workingPlan[id].breaks.push({
'start': start,
'end': end
});
}
});
} else {
workingPlan[id] = null;
}
});
return JSON.stringify(workingPlan);
};
/** /**
* This class contains the methods that will be used by the "Secretaries" tab of the page. * This class contains the methods that will be used by the "Secretaries" tab of the page.
* *
@ -1017,7 +1465,8 @@ SecretariesHelper.prototype.validate = function(secretary) {
throw 'Passwords mismatch!'; throw 'Passwords mismatch!';
} }
if ($('#secretary-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH) { if ($('#secretary-password').val().length < BackendUsers.MIN_PASSWORD_LENGTH
&& $('#secretary-password').val() != '') {
$('#secretary-password, #secretary-password-confirm').css('border', '2px solid red'); $('#secretary-password, #secretary-password-confirm').css('border', '2px solid red');
throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH throw 'Password must be at least ' + BackendUsers.MIN_PASSWORD_LENGTH
+ ' characters long.'; + ' characters long.';
@ -1029,22 +1478,6 @@ SecretariesHelper.prototype.validate = function(secretary) {
throw 'Invalid email address!'; throw 'Invalid email address!';
} }
// Validate username.
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_validate_username';
var postData = {
'username': $('#secretary-username').val(),
'record_exists': ($('#secretary-id').val() != '') ? true : false
};
$.post(postUrl, postData, function(response) {
///////////////////////////////////////////////////////
console.log('Validate Username Response:', response);
///////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
if (!response) {
throw('Username already exists, please enter another one and try again.');
}
});
return true; return true;
} catch(exc) { } catch(exc) {
$('#secretaries .form-message').text(exc); $('#secretaries .form-message').text(exc);
@ -1112,8 +1545,10 @@ SecretariesHelper.prototype.display = function(secretary) {
* Filters secretary records depending a string key. * Filters secretary records depending a string key.
* *
* @param {string} key This is used to filter the secretary records of the database. * @param {string} key This is used to filter the secretary records of the database.
* @param {numeric} selectRecordId (OPTIONAL) If provided then the given id will be
* selected in the filter results (only selected, not displayed).
*/ */
SecretariesHelper.prototype.filter = function(key) { SecretariesHelper.prototype.filter = function(key, selectRecordId) {
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_secretaries'; var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_secretaries';
var postData = { 'key': key }; var postData = { 'key': key };
@ -1131,6 +1566,15 @@ SecretariesHelper.prototype.filter = function(key) {
var html = SecretariesHelper.prototype.getFilterHtml(secretary); var html = SecretariesHelper.prototype.getFilterHtml(secretary);
$('#secretaries .filter-results').append(html); $('#secretaries .filter-results').append(html);
}); });
if (selectRecordId != undefined) {
$('.secretary-row').each(function() {
if ($(this).attr('data-id') == selectRecordId) {
$(this).addClass('selected-row');
return false;
}
});
}
}, 'json'); }, 'json');
}; };