Add support for custom fields on customers (#1133)
This commit is contained in:
parent
aa10b57b3a
commit
e6b3ffd66b
47 changed files with 769 additions and 434 deletions
|
@ -43,6 +43,7 @@ developers to maintain and readjust their custom modifications on the main proje
|
||||||
- Create new layout structure for the markup, so that common HTML markup is being reused (#1152)
|
- Create new layout structure for the markup, so that common HTML markup is being reused (#1152)
|
||||||
- Have an option to hide customer data fields during booking (#1081)
|
- Have an option to hide customer data fields during booking (#1081)
|
||||||
- Add a SECURITY.md file to the repository (#1122)
|
- Add a SECURITY.md file to the repository (#1122)
|
||||||
|
- Add support for custom fields on customers (#1133)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
*
|
*
|
||||||
* @package Controllers
|
* @package Controllers
|
||||||
*/
|
*/
|
||||||
class Customers extends EA_Controller {
|
class Customers extends EA_Controller
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Customers constructor.
|
* Customers constructor.
|
||||||
*/
|
*/
|
||||||
|
@ -49,10 +50,8 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$user_id = session('user_id');
|
$user_id = session('user_id');
|
||||||
|
|
||||||
if (cannot('view', PRIV_CUSTOMERS))
|
if (cannot('view', PRIV_CUSTOMERS)) {
|
||||||
{
|
if ($user_id) {
|
||||||
if ($user_id)
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +74,7 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$secretary_providers = [];
|
$secretary_providers = [];
|
||||||
|
|
||||||
if ($role_slug === DB_SLUG_SECRETARY)
|
if ($role_slug === DB_SLUG_SECRETARY) {
|
||||||
{
|
|
||||||
$secretary = $this->secretaries_model->find($user_id);
|
$secretary = $this->secretaries_model->find($user_id);
|
||||||
|
|
||||||
$secretary_providers = $secretary['providers'];
|
$secretary_providers = $secretary['providers'];
|
||||||
|
@ -88,7 +86,7 @@ class Customers extends EA_Controller {
|
||||||
'date_format' => $date_format,
|
'date_format' => $date_format,
|
||||||
'time_format' => $time_format,
|
'time_format' => $time_format,
|
||||||
'timezones' => $this->timezones->to_array(),
|
'timezones' => $this->timezones->to_array(),
|
||||||
'secretary_providers' => $secretary_providers,
|
'secretary_providers' => $secretary_providers
|
||||||
]);
|
]);
|
||||||
|
|
||||||
html_vars([
|
html_vars([
|
||||||
|
@ -105,21 +103,45 @@ class Customers extends EA_Controller {
|
||||||
'require_address' => $require_address,
|
'require_address' => $require_address,
|
||||||
'require_city' => $require_city,
|
'require_city' => $require_city,
|
||||||
'require_zip_code' => $require_zip_code,
|
'require_zip_code' => $require_zip_code,
|
||||||
'available_languages' => config('available_languages'),
|
'available_languages' => config('available_languages')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->load->view('pages/customers');
|
$this->load->view('pages/customers');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a customer.
|
||||||
|
*/
|
||||||
|
public function find()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (cannot('view', PRIV_CUSTOMERS)) {
|
||||||
|
abort(403, 'Forbidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = session('user_id');
|
||||||
|
|
||||||
|
$customer_id = request('customer_id');
|
||||||
|
|
||||||
|
if (!$this->permissions->has_customer_access($user_id, $customer_id)) {
|
||||||
|
abort(403, 'Forbidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer = $this->customers_model->find($customer_id);
|
||||||
|
|
||||||
|
json_response($customer);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
json_exception($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter customers by the provided keyword.
|
* Filter customers by the provided keyword.
|
||||||
*/
|
*/
|
||||||
public function search()
|
public function search()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
if (cannot('view', PRIV_CUSTOMERS)) {
|
||||||
if (cannot('view', PRIV_CUSTOMERS))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,10 +157,8 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$user_id = session('user_id');
|
$user_id = session('user_id');
|
||||||
|
|
||||||
foreach ($customers as $index => &$customer)
|
foreach ($customers as $index => &$customer) {
|
||||||
{
|
if (!$this->permissions->has_customer_access($user_id, $customer['id'])) {
|
||||||
if ( ! $this->permissions->has_customer_access($user_id, $customer['id']))
|
|
||||||
{
|
|
||||||
unset($customers[$index]);
|
unset($customers[$index]);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -146,21 +166,15 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$appointments = $this->appointments_model->get(['id_users_customer' => $customer['id']]);
|
$appointments = $this->appointments_model->get(['id_users_customer' => $customer['id']]);
|
||||||
|
|
||||||
foreach ($appointments as &$appointment)
|
foreach ($appointments as &$appointment) {
|
||||||
{
|
$this->appointments_model->load($appointment, ['service', 'provider']);
|
||||||
$this->appointments_model->load($appointment, [
|
|
||||||
'service',
|
|
||||||
'provider',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$customer['appointments'] = $appointments;
|
$customer['appointments'] = $appointments;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_response(array_values($customers));
|
json_response(array_values($customers));
|
||||||
}
|
} catch (Throwable $e) {
|
||||||
catch (Throwable $e)
|
|
||||||
{
|
|
||||||
json_exception($e);
|
json_exception($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,15 +184,12 @@ class Customers extends EA_Controller {
|
||||||
*/
|
*/
|
||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
if (cannot('add', PRIV_CUSTOMERS)) {
|
||||||
if (cannot('add', PRIV_CUSTOMERS))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session('role_slug') !== DB_SLUG_ADMIN && setting('limit_customer_visibility'))
|
if (session('role_slug') !== DB_SLUG_ADMIN && setting('limit_customer_visibility')) {
|
||||||
{
|
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +207,11 @@ class Customers extends EA_Controller {
|
||||||
'notes',
|
'notes',
|
||||||
'timezone',
|
'timezone',
|
||||||
'language',
|
'language',
|
||||||
|
'custom_field_1',
|
||||||
|
'custom_field_2',
|
||||||
|
'custom_field_3',
|
||||||
|
'custom_field_4',
|
||||||
|
'custom_field_5'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$customer_id = $this->customers_model->save($customer);
|
$customer_id = $this->customers_model->save($customer);
|
||||||
|
@ -205,12 +221,10 @@ class Customers extends EA_Controller {
|
||||||
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_SAVE, $customer);
|
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_SAVE, $customer);
|
||||||
|
|
||||||
json_response([
|
json_response([
|
||||||
'success' => TRUE,
|
'success' => true,
|
||||||
'id' => $customer_id
|
'id' => $customer_id
|
||||||
]);
|
]);
|
||||||
}
|
} catch (Throwable $e) {
|
||||||
catch (Throwable $e)
|
|
||||||
{
|
|
||||||
json_exception($e);
|
json_exception($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,10 +234,8 @@ class Customers extends EA_Controller {
|
||||||
*/
|
*/
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
if (cannot('edit', PRIV_CUSTOMERS)) {
|
||||||
if (cannot('edit', PRIV_CUSTOMERS))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +243,7 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$customer = request('customer');
|
$customer = request('customer');
|
||||||
|
|
||||||
if ( ! $this->permissions->has_customer_access($user_id, $customer['id']))
|
if (!$this->permissions->has_customer_access($user_id, $customer['id'])) {
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +260,11 @@ class Customers extends EA_Controller {
|
||||||
'notes',
|
'notes',
|
||||||
'timezone',
|
'timezone',
|
||||||
'language',
|
'language',
|
||||||
|
'custom_field_1',
|
||||||
|
'custom_field_2',
|
||||||
|
'custom_field_3',
|
||||||
|
'custom_field_4',
|
||||||
|
'custom_field_5'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$customer_id = $this->customers_model->save($customer);
|
$customer_id = $this->customers_model->save($customer);
|
||||||
|
@ -258,12 +274,10 @@ class Customers extends EA_Controller {
|
||||||
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_SAVE, $customer);
|
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_SAVE, $customer);
|
||||||
|
|
||||||
json_response([
|
json_response([
|
||||||
'success' => TRUE,
|
'success' => true,
|
||||||
'id' => $customer_id
|
'id' => $customer_id
|
||||||
]);
|
]);
|
||||||
}
|
} catch (Throwable $e) {
|
||||||
catch (Throwable $e)
|
|
||||||
{
|
|
||||||
json_exception($e);
|
json_exception($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,10 +287,8 @@ class Customers extends EA_Controller {
|
||||||
*/
|
*/
|
||||||
public function destroy()
|
public function destroy()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
if (cannot('delete', PRIV_CUSTOMERS)) {
|
||||||
if (cannot('delete', PRIV_CUSTOMERS))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,8 +296,7 @@ class Customers extends EA_Controller {
|
||||||
|
|
||||||
$customer_id = request('customer_id');
|
$customer_id = request('customer_id');
|
||||||
|
|
||||||
if ( ! $this->permissions->has_customer_access($user_id, $customer_id))
|
if (!$this->permissions->has_customer_access($user_id, $customer_id)) {
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
abort(403, 'Forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,42 +307,9 @@ class Customers extends EA_Controller {
|
||||||
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_DELETE, $customer);
|
$this->webhooks_client->trigger(WEBHOOK_CUSTOMER_DELETE, $customer);
|
||||||
|
|
||||||
json_response([
|
json_response([
|
||||||
'success' => TRUE,
|
'success' => true
|
||||||
]);
|
]);
|
||||||
}
|
} catch (Throwable $e) {
|
||||||
catch (Throwable $e)
|
|
||||||
{
|
|
||||||
json_exception($e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a customer.
|
|
||||||
*/
|
|
||||||
public function find()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cannot('view', PRIV_CUSTOMERS))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_id = session('user_id');
|
|
||||||
|
|
||||||
$customer_id = request('customer_id');
|
|
||||||
|
|
||||||
if ( ! $this->permissions->has_customer_access($user_id, $customer_id))
|
|
||||||
{
|
|
||||||
abort(403, 'Forbidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
$customer = $this->customers_model->find($customer_id);
|
|
||||||
|
|
||||||
json_response($customer);
|
|
||||||
}
|
|
||||||
catch (Throwable $e)
|
|
||||||
{
|
|
||||||
json_exception($e);
|
json_exception($e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -446,5 +446,7 @@ $lang['blocked_periods'] = 'Blocked Periods';
|
||||||
$lang['blocked_period_save'] = 'Blocked Period Save';
|
$lang['blocked_period_save'] = 'Blocked Period Save';
|
||||||
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
$lang['blocked_period_delete'] = 'Blocked Period Delete';
|
||||||
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
$lang['blocked_periods_hint'] = 'Define periods of time where public bookings will be disabled for all providers (e.g. closed dates, holidays etc.).';
|
||||||
$lang['auxiliary_field'] = 'Auxiliary Field';
|
$lang['custom_field'] = 'Custom Field';
|
||||||
|
$lang['custom_fields'] = 'Custom Fields';
|
||||||
|
$lang['label'] = 'Label';
|
||||||
// End
|
// End
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Easy!Appointments - Online Appointment Scheduler
|
||||||
|
*
|
||||||
|
* @package EasyAppointments
|
||||||
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
||||||
|
* @copyright Copyright (c) Alex Tselegidis
|
||||||
|
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
|
||||||
|
* @link https://easyappointments.org
|
||||||
|
* @since v1.4.0
|
||||||
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class Migration_Add_custom_fields_columns_to_users_table extends EA_Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private const FIELD_NUMBER = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrade method.
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
for ($i = self::FIELD_NUMBER; $i > 0; $i--) {
|
||||||
|
$field_name = 'custom_field_' . $i;
|
||||||
|
|
||||||
|
if (!$this->db->field_exists($field_name, 'users')) {
|
||||||
|
$fields = [
|
||||||
|
$field_name => [
|
||||||
|
'type' => 'TEXT',
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'language'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->dbforge->add_column('users', $fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downgrade method.
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
for ($i = self::FIELD_NUMBER; $i > 0; $i--) {
|
||||||
|
$field_name = 'custom_fields_' . $i;
|
||||||
|
|
||||||
|
if ($this->db->field_exists($field_name, 'users')) {
|
||||||
|
$this->dbforge->drop_column('users', $field_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php defined('BASEPATH') or exit('No direct script access allowed');
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Easy!Appointments - Online Appointment Scheduler
|
||||||
|
*
|
||||||
|
* @package EasyAppointments
|
||||||
|
* @author A.Tselegidis <alextselegidis@gmail.com>
|
||||||
|
* @copyright Copyright (c) Alex Tselegidis
|
||||||
|
* @license https://opensource.org/licenses/GPL-3.0 - GPLv3
|
||||||
|
* @link https://easyappointments.org
|
||||||
|
* @since v1.4.0
|
||||||
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class Migration_Insert_custom_field_rows_to_settings_table extends EA_Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private const FIELD_NUMBER = 5;
|
||||||
|
|
||||||
|
private const SETTINGS = [
|
||||||
|
'display' => '0',
|
||||||
|
'require' => '0',
|
||||||
|
'label' => ''
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrade method.
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
for ($i = 1; $i <= self::FIELD_NUMBER; $i++) {
|
||||||
|
$field_name = 'custom_field_' . $i;
|
||||||
|
|
||||||
|
foreach (self::SETTINGS as $name => $default_value) {
|
||||||
|
$setting_name = $name . '_' . $field_name;
|
||||||
|
|
||||||
|
if (!$this->db->get_where('settings', ['name' => $setting_name])->num_rows()) {
|
||||||
|
$this->db->insert('settings', [
|
||||||
|
'name' => $setting_name,
|
||||||
|
'value' => $default_value
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downgrade method.
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
for ($i = 1; $i >= self::FIELD_NUMBER; $i++) {
|
||||||
|
$field_name = 'custom_field_' . $i;
|
||||||
|
|
||||||
|
foreach (self::SETTINGS as $name => $default_value) {
|
||||||
|
$setting_name = $name . '_' . $field_name;
|
||||||
|
|
||||||
|
if ($this->db->get_where('settings', ['name' => $setting_name])->num_rows()) {
|
||||||
|
$this->db->delete('settings', ['name' => $setting_name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,13 +18,14 @@
|
||||||
*
|
*
|
||||||
* @package Models
|
* @package Models
|
||||||
*/
|
*/
|
||||||
class Customers_model extends EA_Model {
|
class Customers_model extends EA_Model
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected array $casts = [
|
protected array $casts = [
|
||||||
'id' => 'integer',
|
'id' => 'integer',
|
||||||
'id_roles' => 'integer',
|
'id_roles' => 'integer'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +43,12 @@ class Customers_model extends EA_Model {
|
||||||
'zip' => 'zip_code',
|
'zip' => 'zip_code',
|
||||||
'timezone' => 'timezone',
|
'timezone' => 'timezone',
|
||||||
'language' => 'language',
|
'language' => 'language',
|
||||||
'notes' => 'notes',
|
'customField1' => 'custom_field_1',
|
||||||
|
'customField2' => 'custom_field_2',
|
||||||
|
'customField3' => 'custom_field_3',
|
||||||
|
'customField4' => 'custom_field_4',
|
||||||
|
'customField5' => 'custom_field_5',
|
||||||
|
'notes' => 'notes'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,17 +64,13 @@ class Customers_model extends EA_Model {
|
||||||
{
|
{
|
||||||
$this->validate($customer);
|
$this->validate($customer);
|
||||||
|
|
||||||
if ($this->exists($customer) && empty($customer['id']))
|
if ($this->exists($customer) && empty($customer['id'])) {
|
||||||
{
|
|
||||||
$customer['id'] = $this->find_record_id($customer);
|
$customer['id'] = $this->find_record_id($customer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($customer['id']))
|
if (empty($customer['id'])) {
|
||||||
{
|
|
||||||
return $this->insert($customer);
|
return $this->insert($customer);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->update($customer);
|
return $this->update($customer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,13 +85,13 @@ class Customers_model extends EA_Model {
|
||||||
public function validate(array $customer)
|
public function validate(array $customer)
|
||||||
{
|
{
|
||||||
// If a customer ID is provided then check whether the record really exists in the database.
|
// If a customer ID is provided then check whether the record really exists in the database.
|
||||||
if ( ! empty($customer['id']))
|
if (!empty($customer['id'])) {
|
||||||
{
|
|
||||||
$count = $this->db->get_where('users', ['id' => $customer['id']])->num_rows();
|
$count = $this->db->get_where('users', ['id' => $customer['id']])->num_rows();
|
||||||
|
|
||||||
if ( ! $count)
|
if (!$count) {
|
||||||
{
|
throw new InvalidArgumentException(
|
||||||
throw new InvalidArgumentException('The provided customer ID does not exist in the database: ' . $customer['id']);
|
'The provided customer ID does not exist in the database: ' . $customer['id']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,31 +105,27 @@ class Customers_model extends EA_Model {
|
||||||
$require_zip_code = filter_var(setting('require_zip_code'), FILTER_VALIDATE_BOOLEAN);
|
$require_zip_code = filter_var(setting('require_zip_code'), FILTER_VALIDATE_BOOLEAN);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(empty($customer['first_name']) && $require_first_name)
|
(empty($customer['first_name']) && $require_first_name) ||
|
||||||
|| (empty($customer['last_name']) && $require_last_name)
|
(empty($customer['last_name']) && $require_last_name) ||
|
||||||
|| (empty($customer['email']) && $require_email)
|
(empty($customer['email']) && $require_email) ||
|
||||||
|| (empty($customer['phone_number']) && $require_phone_number)
|
(empty($customer['phone_number']) && $require_phone_number) ||
|
||||||
|| (empty($customer['address']) && $require_address)
|
(empty($customer['address']) && $require_address) ||
|
||||||
|| (empty($customer['city']) && $require_city)
|
(empty($customer['city']) && $require_city) ||
|
||||||
|| (empty($customer['zip_code']) && $require_zip_code)
|
(empty($customer['zip_code']) && $require_zip_code)
|
||||||
)
|
) {
|
||||||
{
|
throw new InvalidArgumentException('Not all required fields are provided: ' . print_r($customer, true));
|
||||||
throw new InvalidArgumentException('Not all required fields are provided: ' . print_r($customer, TRUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty($customer['email']))
|
if (!empty($customer['email'])) {
|
||||||
{
|
|
||||||
// Validate the email address.
|
// Validate the email address.
|
||||||
if ( ! filter_var($customer['email'], FILTER_VALIDATE_EMAIL))
|
if (!filter_var($customer['email'], FILTER_VALIDATE_EMAIL)) {
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('Invalid email address provided: ' . $customer['email']);
|
throw new InvalidArgumentException('Invalid email address provided: ' . $customer['email']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the email address is unique.
|
// Make sure the email address is unique.
|
||||||
$customer_id = $customer['id'] ?? NULL;
|
$customer_id = $customer['id'] ?? null;
|
||||||
|
|
||||||
$count = $this
|
$count = $this->db
|
||||||
->db
|
|
||||||
->select()
|
->select()
|
||||||
->from('users')
|
->from('users')
|
||||||
->join('roles', 'roles.id = users.id_roles', 'inner')
|
->join('roles', 'roles.id = users.id_roles', 'inner')
|
||||||
|
@ -137,13 +135,123 @@ class Customers_model extends EA_Model {
|
||||||
->get()
|
->get()
|
||||||
->num_rows();
|
->num_rows();
|
||||||
|
|
||||||
if ($count > 0)
|
if ($count > 0) {
|
||||||
{
|
throw new InvalidArgumentException(
|
||||||
throw new InvalidArgumentException('The provided email address is already in use, please use a different one.');
|
'The provided email address is already in use, please use a different one.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all customers that match the provided criteria.
|
||||||
|
*
|
||||||
|
* @param array|string|null $where Where conditions.
|
||||||
|
* @param int|null $limit Record limit.
|
||||||
|
* @param int|null $offset Record offset.
|
||||||
|
* @param string|null $order_by Order by.
|
||||||
|
*
|
||||||
|
* @return array Returns an array of customers.
|
||||||
|
*/
|
||||||
|
public function get(
|
||||||
|
array|string $where = null,
|
||||||
|
int $limit = null,
|
||||||
|
int $offset = null,
|
||||||
|
string $order_by = null
|
||||||
|
): array {
|
||||||
|
$role_id = $this->get_customer_role_id();
|
||||||
|
|
||||||
|
if ($where !== null) {
|
||||||
|
$this->db->where($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($order_by !== null) {
|
||||||
|
$this->db->order_by($order_by);
|
||||||
|
}
|
||||||
|
|
||||||
|
$customers = $this->db->get_where('users', ['id_roles' => $role_id], $limit, $offset)->result_array();
|
||||||
|
|
||||||
|
foreach ($customers as &$customer) {
|
||||||
|
$this->cast($customer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the customer role ID.
|
||||||
|
*
|
||||||
|
* @return int Returns the role ID.
|
||||||
|
*/
|
||||||
|
public function get_customer_role_id(): int
|
||||||
|
{
|
||||||
|
$role = $this->db->get_where('roles', ['slug' => DB_SLUG_CUSTOMER])->row_array();
|
||||||
|
|
||||||
|
if (empty($role)) {
|
||||||
|
throw new RuntimeException('The customer role was not found in the database.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $role['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a particular customer record already exists in the database.
|
||||||
|
*
|
||||||
|
* @param array $customer Associative array with the customer data.
|
||||||
|
*
|
||||||
|
* @return bool Returns whether there is a record matching the provided one or not.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function exists(array $customer): bool
|
||||||
|
{
|
||||||
|
if (empty($customer['email'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = $this->db
|
||||||
|
->select()
|
||||||
|
->from('users')
|
||||||
|
->join('roles', 'roles.id = users.id_roles', 'inner')
|
||||||
|
->where('users.email', $customer['email'])
|
||||||
|
->where('roles.slug', DB_SLUG_CUSTOMER)
|
||||||
|
->get()
|
||||||
|
->num_rows();
|
||||||
|
|
||||||
|
return $count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the record ID of a customer.
|
||||||
|
*
|
||||||
|
* @param array $customer Associative array with the customer data.
|
||||||
|
*
|
||||||
|
* @return int Returns the ID of the record that matches the provided argument.
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function find_record_id(array $customer): int
|
||||||
|
{
|
||||||
|
if (empty($customer['email'])) {
|
||||||
|
throw new InvalidArgumentException('The customer email was not provided: ' . print_r($customer, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
$customer = $this->db
|
||||||
|
->select('users.id')
|
||||||
|
->from('users')
|
||||||
|
->join('roles', 'roles.id = users.id_roles', 'inner')
|
||||||
|
->where('users.email', $customer['email'])
|
||||||
|
->where('roles.slug', DB_SLUG_CUSTOMER)
|
||||||
|
->get()
|
||||||
|
->row_array();
|
||||||
|
|
||||||
|
if (empty($customer)) {
|
||||||
|
throw new InvalidArgumentException('Could not find customer record id.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) $customer['id'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a new customer into the database.
|
* Insert a new customer into the database.
|
||||||
*
|
*
|
||||||
|
@ -159,8 +267,7 @@ class Customers_model extends EA_Model {
|
||||||
$customer['update_datetime'] = date('Y-m-d H:i:s');
|
$customer['update_datetime'] = date('Y-m-d H:i:s');
|
||||||
$customer['id_roles'] = $this->get_customer_role_id();
|
$customer['id_roles'] = $this->get_customer_role_id();
|
||||||
|
|
||||||
if ( ! $this->db->insert('users', $customer))
|
if (!$this->db->insert('users', $customer)) {
|
||||||
{
|
|
||||||
throw new RuntimeException('Could not insert customer.');
|
throw new RuntimeException('Could not insert customer.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +287,7 @@ class Customers_model extends EA_Model {
|
||||||
{
|
{
|
||||||
$customer['update_datetime'] = date('Y-m-d H:i:s');
|
$customer['update_datetime'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
if ( ! $this->db->update('users', $customer, ['id' => $customer['id']]))
|
if (!$this->db->update('users', $customer, ['id' => $customer['id']])) {
|
||||||
{
|
|
||||||
throw new RuntimeException('Could not update customer.');
|
throw new RuntimeException('Could not update customer.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,9 +317,10 @@ class Customers_model extends EA_Model {
|
||||||
{
|
{
|
||||||
$customer = $this->db->get_where('users', ['id' => $customer_id])->row_array();
|
$customer = $this->db->get_where('users', ['id' => $customer_id])->row_array();
|
||||||
|
|
||||||
if ( ! $customer)
|
if (!$customer) {
|
||||||
{
|
throw new InvalidArgumentException(
|
||||||
throw new InvalidArgumentException('The provided customer ID was not found in the database: ' . $customer_id);
|
'The provided customer ID was not found in the database: ' . $customer_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->cast($customer);
|
$this->cast($customer);
|
||||||
|
@ -233,22 +340,21 @@ class Customers_model extends EA_Model {
|
||||||
*/
|
*/
|
||||||
public function value(int $customer_id, string $field): mixed
|
public function value(int $customer_id, string $field): mixed
|
||||||
{
|
{
|
||||||
if (empty($field))
|
if (empty($field)) {
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('The field argument is cannot be empty.');
|
throw new InvalidArgumentException('The field argument is cannot be empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($customer_id))
|
if (empty($customer_id)) {
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('The customer ID argument cannot be empty.');
|
throw new InvalidArgumentException('The customer ID argument cannot be empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the customer exists.
|
// Check whether the customer exists.
|
||||||
$query = $this->db->get_where('users', ['id' => $customer_id]);
|
$query = $this->db->get_where('users', ['id' => $customer_id]);
|
||||||
|
|
||||||
if ( ! $query->num_rows())
|
if (!$query->num_rows()) {
|
||||||
{
|
throw new InvalidArgumentException(
|
||||||
throw new InvalidArgumentException('The provided customer ID was not found in the database: ' . $customer_id);
|
'The provided customer ID was not found in the database: ' . $customer_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the required field is part of the customer data.
|
// Check if the required field is part of the customer data.
|
||||||
|
@ -256,128 +362,13 @@ class Customers_model extends EA_Model {
|
||||||
|
|
||||||
$this->cast($customer);
|
$this->cast($customer);
|
||||||
|
|
||||||
if ( ! array_key_exists($field, $customer))
|
if (!array_key_exists($field, $customer)) {
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('The requested field was not found in the customer data: ' . $field);
|
throw new InvalidArgumentException('The requested field was not found in the customer data: ' . $field);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $customer[$field];
|
return $customer[$field];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all customers that match the provided criteria.
|
|
||||||
*
|
|
||||||
* @param array|string|null $where Where conditions.
|
|
||||||
* @param int|null $limit Record limit.
|
|
||||||
* @param int|null $offset Record offset.
|
|
||||||
* @param string|null $order_by Order by.
|
|
||||||
*
|
|
||||||
* @return array Returns an array of customers.
|
|
||||||
*/
|
|
||||||
public function get(array|string $where = NULL, int $limit = NULL, int $offset = NULL, string $order_by = NULL): array
|
|
||||||
{
|
|
||||||
$role_id = $this->get_customer_role_id();
|
|
||||||
|
|
||||||
if ($where !== NULL)
|
|
||||||
{
|
|
||||||
$this->db->where($where);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($order_by !== NULL)
|
|
||||||
{
|
|
||||||
$this->db->order_by($order_by);
|
|
||||||
}
|
|
||||||
|
|
||||||
$customers = $this->db->get_where('users', ['id_roles' => $role_id], $limit, $offset)->result_array();
|
|
||||||
|
|
||||||
foreach ($customers as &$customer)
|
|
||||||
{
|
|
||||||
$this->cast($customer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $customers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the customer role ID.
|
|
||||||
*
|
|
||||||
* @return int Returns the role ID.
|
|
||||||
*/
|
|
||||||
public function get_customer_role_id(): int
|
|
||||||
{
|
|
||||||
$role = $this->db->get_where('roles', ['slug' => DB_SLUG_CUSTOMER])->row_array();
|
|
||||||
|
|
||||||
if (empty($role))
|
|
||||||
{
|
|
||||||
throw new RuntimeException('The customer role was not found in the database.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $role['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a particular customer record already exists in the database.
|
|
||||||
*
|
|
||||||
* @param array $customer Associative array with the customer data.
|
|
||||||
*
|
|
||||||
* @return bool Returns whether there is a record matching the provided one or not.
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function exists(array $customer): bool
|
|
||||||
{
|
|
||||||
if (empty($customer['email']))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = $this
|
|
||||||
->db
|
|
||||||
->select()
|
|
||||||
->from('users')
|
|
||||||
->join('roles', 'roles.id = users.id_roles', 'inner')
|
|
||||||
->where('users.email', $customer['email'])
|
|
||||||
->where('roles.slug', DB_SLUG_CUSTOMER)
|
|
||||||
->get()
|
|
||||||
->num_rows();
|
|
||||||
|
|
||||||
return $count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the record ID of a customer.
|
|
||||||
*
|
|
||||||
* @param array $customer Associative array with the customer data.
|
|
||||||
*
|
|
||||||
* @return int Returns the ID of the record that matches the provided argument.
|
|
||||||
*
|
|
||||||
* @throws InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function find_record_id(array $customer): int
|
|
||||||
{
|
|
||||||
if (empty($customer['email']))
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('The customer email was not provided: ' . print_r($customer, TRUE));
|
|
||||||
}
|
|
||||||
|
|
||||||
$customer = $this
|
|
||||||
->db
|
|
||||||
->select('users.id')
|
|
||||||
->from('users')
|
|
||||||
->join('roles', 'roles.id = users.id_roles', 'inner')
|
|
||||||
->where('users.email', $customer['email'])
|
|
||||||
->where('roles.slug', DB_SLUG_CUSTOMER)
|
|
||||||
->get()
|
|
||||||
->row_array();
|
|
||||||
|
|
||||||
if (empty($customer))
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException('Could not find customer record id.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)$customer['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the query builder interface, configured for use with the users (customer-filtered) table.
|
* Get the query builder interface, configured for use with the users (customer-filtered) table.
|
||||||
*
|
*
|
||||||
|
@ -400,12 +391,11 @@ class Customers_model extends EA_Model {
|
||||||
*
|
*
|
||||||
* @return array Returns an array of customers.
|
* @return array Returns an array of customers.
|
||||||
*/
|
*/
|
||||||
public function search(string $keyword, int $limit = NULL, int $offset = NULL, string $order_by = NULL): array
|
public function search(string $keyword, int $limit = null, int $offset = null, string $order_by = null): array
|
||||||
{
|
{
|
||||||
$role_id = $this->get_customer_role_id();
|
$role_id = $this->get_customer_role_id();
|
||||||
|
|
||||||
$customers = $this
|
$customers = $this->db
|
||||||
->db
|
|
||||||
->select()
|
->select()
|
||||||
->from('users')
|
->from('users')
|
||||||
->where('id_roles', $role_id)
|
->where('id_roles', $role_id)
|
||||||
|
@ -428,8 +418,7 @@ class Customers_model extends EA_Model {
|
||||||
->get()
|
->get()
|
||||||
->result_array();
|
->result_array();
|
||||||
|
|
||||||
foreach ($customers as &$customer)
|
foreach ($customers as &$customer) {
|
||||||
{
|
|
||||||
$this->cast($customer);
|
$this->cast($customer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +446,7 @@ class Customers_model extends EA_Model {
|
||||||
public function api_encode(array &$customer)
|
public function api_encode(array &$customer)
|
||||||
{
|
{
|
||||||
$encoded_resource = [
|
$encoded_resource = [
|
||||||
'id' => array_key_exists('id', $customer) ? (int)$customer['id'] : NULL,
|
'id' => array_key_exists('id', $customer) ? (int) $customer['id'] : null,
|
||||||
'firstName' => $customer['first_name'],
|
'firstName' => $customer['first_name'],
|
||||||
'lastName' => $customer['last_name'],
|
'lastName' => $customer['last_name'],
|
||||||
'email' => $customer['email'],
|
'email' => $customer['email'],
|
||||||
|
@ -467,6 +456,11 @@ class Customers_model extends EA_Model {
|
||||||
'zip' => $customer['zip_code'],
|
'zip' => $customer['zip_code'],
|
||||||
'notes' => $customer['notes'],
|
'notes' => $customer['notes'],
|
||||||
'timezone' => $customer['timezone'],
|
'timezone' => $customer['timezone'],
|
||||||
|
'customField1' => $customer['custom_field_1'],
|
||||||
|
'customField2' => $customer['custom_field_2'],
|
||||||
|
'customField3' => $customer['custom_field_3'],
|
||||||
|
'customField4' => $customer['custom_field_4'],
|
||||||
|
'customField5' => $customer['custom_field_5']
|
||||||
];
|
];
|
||||||
|
|
||||||
$customer = $encoded_resource;
|
$customer = $encoded_resource;
|
||||||
|
@ -478,52 +472,67 @@ class Customers_model extends EA_Model {
|
||||||
* @param array $customer API resource.
|
* @param array $customer API resource.
|
||||||
* @param array|null $base Base customer data to be overwritten with the provided values (useful for updates).
|
* @param array|null $base Base customer data to be overwritten with the provided values (useful for updates).
|
||||||
*/
|
*/
|
||||||
public function api_decode(array &$customer, array $base = NULL)
|
public function api_decode(array &$customer, array $base = null)
|
||||||
{
|
{
|
||||||
$decoded_resource = $base ?: [];
|
$decoded_resource = $base ?: [];
|
||||||
|
|
||||||
if (array_key_exists('id', $customer))
|
if (array_key_exists('id', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['id'] = $customer['id'];
|
$decoded_resource['id'] = $customer['id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('firstName', $customer))
|
if (array_key_exists('firstName', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['first_name'] = $customer['firstName'];
|
$decoded_resource['first_name'] = $customer['firstName'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('lastName', $customer))
|
if (array_key_exists('lastName', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['last_name'] = $customer['lastName'];
|
$decoded_resource['last_name'] = $customer['lastName'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('email', $customer))
|
if (array_key_exists('email', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['email'] = $customer['email'];
|
$decoded_resource['email'] = $customer['email'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('phone', $customer))
|
if (array_key_exists('phone', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['phone_number'] = $customer['phone'];
|
$decoded_resource['phone_number'] = $customer['phone'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('address', $customer))
|
if (array_key_exists('address', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['address'] = $customer['address'];
|
$decoded_resource['address'] = $customer['address'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('city', $customer))
|
if (array_key_exists('city', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['city'] = $customer['city'];
|
$decoded_resource['city'] = $customer['city'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('zip', $customer))
|
if (array_key_exists('zip', $customer)) {
|
||||||
{
|
|
||||||
$decoded_resource['zip_code'] = $customer['zip'];
|
$decoded_resource['zip_code'] = $customer['zip'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('notes', $customer))
|
if (array_key_exists('language', $customer)) {
|
||||||
{
|
$decoded_resource['language'] = $customer['language'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('customField1', $customer)) {
|
||||||
|
$decoded_resource['custom_field_1'] = $customer['customField1'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('customField2', $customer)) {
|
||||||
|
$decoded_resource['custom_field_2'] = $customer['customField2'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('customField3', $customer)) {
|
||||||
|
$decoded_resource['custom_field_3'] = $customer['customField3'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('customField4', $customer)) {
|
||||||
|
$decoded_resource['custom_field_4'] = $customer['customField4'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('customField5', $customer)) {
|
||||||
|
$decoded_resource['custom_field_5'] = $customer['customField5'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('notes', $customer)) {
|
||||||
$decoded_resource['notes'] = $customer['notes'];
|
$decoded_resource['notes'] = $customer['notes'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,27 +43,21 @@
|
||||||
<?php
|
<?php
|
||||||
// Group services by category, only if there is at least one service
|
// Group services by category, only if there is at least one service
|
||||||
// with a parent category.
|
// with a parent category.
|
||||||
$has_category = FALSE;
|
$has_category = false;
|
||||||
|
|
||||||
foreach ($available_services as $service)
|
foreach ($available_services as $service) {
|
||||||
{
|
if (!empty($service['category_id'])) {
|
||||||
if ( ! empty($service['category_id']))
|
$has_category = true;
|
||||||
{
|
|
||||||
$has_category = TRUE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($has_category)
|
if ($has_category) {
|
||||||
{
|
|
||||||
$grouped_services = [];
|
$grouped_services = [];
|
||||||
|
|
||||||
foreach ($available_services as $service)
|
foreach ($available_services as $service) {
|
||||||
{
|
if (!empty($service['category_id'])) {
|
||||||
if ( ! empty($service['category_id']))
|
if (!isset($grouped_services[$service['category_name']])) {
|
||||||
{
|
|
||||||
if ( ! isset($grouped_services[$service['category_name']]))
|
|
||||||
{
|
|
||||||
$grouped_services[$service['category_name']] = [];
|
$grouped_services[$service['category_name']] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,40 +69,39 @@
|
||||||
// another iteration only for the uncategorized services.
|
// another iteration only for the uncategorized services.
|
||||||
$grouped_services['uncategorized'] = [];
|
$grouped_services['uncategorized'] = [];
|
||||||
|
|
||||||
foreach ($available_services as $service)
|
foreach ($available_services as $service) {
|
||||||
{
|
if ($service['category_id'] == null) {
|
||||||
if ($service['category_id'] == NULL)
|
|
||||||
{
|
|
||||||
$grouped_services['uncategorized'][] = $service;
|
$grouped_services['uncategorized'][] = $service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($grouped_services as $key => $group)
|
foreach ($grouped_services as $key => $group) {
|
||||||
{
|
$group_label =
|
||||||
$group_label = $key !== 'uncategorized'
|
$key !== 'uncategorized'
|
||||||
? e($group[0]['category_name'])
|
? e($group[0]['category_name'])
|
||||||
: 'Uncategorized';
|
: 'Uncategorized';
|
||||||
|
|
||||||
if (count($group) > 0)
|
if (count($group) > 0) {
|
||||||
{
|
|
||||||
echo '<optgroup label="' . $group_label . '">';
|
echo '<optgroup label="' . $group_label . '">';
|
||||||
|
|
||||||
foreach ($group as $service)
|
foreach ($group as $service) {
|
||||||
{
|
echo '<option value="' .
|
||||||
echo '<option value="' . $service['id'] . '">'
|
$service['id'] .
|
||||||
. e($service['name']) . '</option>';
|
'">' .
|
||||||
|
e($service['name']) .
|
||||||
|
'</option>';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</optgroup>';
|
echo '</optgroup>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
foreach ($available_services as $service) {
|
||||||
{
|
echo '<option value="' .
|
||||||
foreach ($available_services as $service)
|
$service['id'] .
|
||||||
{
|
'">' .
|
||||||
echo '<option value="' . $service['id'] . '">'
|
e($service['name']) .
|
||||||
. e($service['name']) . '</option>';
|
'</option>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -124,7 +117,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<?php component('color_selection', ['attributes' => 'id="appointment-color"']) ?>
|
<?php component('color_selection', ['attributes' => 'id="appointment-color"']); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -143,7 +136,7 @@
|
||||||
<option value="<?= e($appointment_status_option) ?>">
|
<option value="<?= e($appointment_status_option) ?>">
|
||||||
<?= e($appointment_status_option) ?>
|
<?= e($appointment_status_option) ?>
|
||||||
</option>
|
</option>
|
||||||
<?php endforeach ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -228,7 +221,7 @@
|
||||||
<?= lang('first_name') ?>
|
<?= lang('first_name') ?>
|
||||||
<?php if ($require_first_name): ?>
|
<?php if ($require_first_name): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="first-name"
|
<input type="text" id="first-name"
|
||||||
class="<?= $require_first_name ? 'required' : '' ?> form-control"
|
class="<?= $require_first_name ? 'required' : '' ?> form-control"
|
||||||
|
@ -240,7 +233,7 @@
|
||||||
<?= lang('last_name') ?>
|
<?= lang('last_name') ?>
|
||||||
<?php if ($require_last_name): ?>
|
<?php if ($require_last_name): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="last-name"
|
<input type="text" id="last-name"
|
||||||
class="<?= $require_last_name ? 'required' : '' ?> form-control"
|
class="<?= $require_last_name ? 'required' : '' ?> form-control"
|
||||||
|
@ -252,7 +245,7 @@
|
||||||
<?= lang('email') ?>
|
<?= lang('email') ?>
|
||||||
<?php if ($require_email): ?>
|
<?php if ($require_email): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="email"
|
<input type="text" id="email"
|
||||||
class="<?= $require_email ? 'required' : '' ?> form-control"
|
class="<?= $require_email ? 'required' : '' ?> form-control"
|
||||||
|
@ -264,7 +257,7 @@
|
||||||
<?= lang('phone_number') ?>
|
<?= lang('phone_number') ?>
|
||||||
<?php if ($require_phone_number): ?>
|
<?php if ($require_phone_number): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="phone-number" maxlength="60"
|
<input type="text" id="phone-number" maxlength="60"
|
||||||
class="<?= $require_phone_number ? 'required' : '' ?> form-control"/>
|
class="<?= $require_phone_number ? 'required' : '' ?> form-control"/>
|
||||||
|
@ -280,7 +273,7 @@
|
||||||
<option value="<?= $available_language ?>">
|
<option value="<?= $available_language ?>">
|
||||||
<?= ucfirst($available_language) ?>
|
<?= ucfirst($available_language) ?>
|
||||||
</option>
|
</option>
|
||||||
<?php endforeach ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -290,7 +283,7 @@
|
||||||
<?= lang('address') ?>
|
<?= lang('address') ?>
|
||||||
<?php if ($require_address): ?>
|
<?php if ($require_address): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="address"
|
<input type="text" id="address"
|
||||||
class="<?= $require_address ? 'required' : '' ?> form-control"
|
class="<?= $require_address ? 'required' : '' ?> form-control"
|
||||||
|
@ -302,7 +295,7 @@
|
||||||
<?= lang('city') ?>
|
<?= lang('city') ?>
|
||||||
<?php if ($require_city): ?>
|
<?php if ($require_city): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="city"
|
<input type="text" id="city"
|
||||||
class="<?= $require_city ? 'required' : '' ?> form-control"
|
class="<?= $require_city ? 'required' : '' ?> form-control"
|
||||||
|
@ -314,7 +307,7 @@
|
||||||
<?= lang('zip_code') ?>
|
<?= lang('zip_code') ?>
|
||||||
<?php if ($require_zip_code): ?>
|
<?php if ($require_zip_code): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="zip-code"
|
<input type="text" id="zip-code"
|
||||||
class="<?= $require_zip_code ? 'required' : '' ?> form-control"
|
class="<?= $require_zip_code ? 'required' : '' ?> form-control"
|
||||||
|
@ -329,7 +322,7 @@
|
||||||
<?php component('timezone_dropdown', [
|
<?php component('timezone_dropdown', [
|
||||||
'attributes' => 'id="timezone" class="form-control required"',
|
'attributes' => 'id="timezone" class="form-control required"',
|
||||||
'grouped_timezones' => vars('grouped_timezones')
|
'grouped_timezones' => vars('grouped_timezones')
|
||||||
]) ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
@ -337,12 +330,16 @@
|
||||||
<?= lang('notes') ?>
|
<?= lang('notes') ?>
|
||||||
<?php if ($require_notes): ?>
|
<?php if ($require_notes): ?>
|
||||||
<span class="text-danger">*</span>
|
<span class="text-danger">*</span>
|
||||||
<?php endif ?>
|
<?php endif; ?>
|
||||||
</label>
|
</label>
|
||||||
<textarea id="customer-notes" rows="2"
|
<textarea id="customer-notes" rows="2"
|
||||||
class="<?= $require_notes ? 'required' : '' ?> form-control"></textarea>
|
class="<?= $require_notes ? 'required' : '' ?> form-control"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<?php component('custom_fields'); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
@ -361,8 +358,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php section('scripts') ?>
|
<?php section('scripts'); ?>
|
||||||
|
|
||||||
<script src="<?= asset_url('assets/js/components/appointments_modal.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/components/appointments_modal.js') ?>"></script>
|
||||||
|
|
||||||
<?php end_section('scripts') ?>
|
<?php end_section('scripts'); ?>
|
||||||
|
|
|
@ -131,6 +131,10 @@
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<?php component('custom_fields'); ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
24
application/views/components/custom_fields.php
Normal file
24
application/views/components/custom_fields.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Local variables.
|
||||||
|
*
|
||||||
|
* @var bool $disabled (false)
|
||||||
|
*/
|
||||||
|
|
||||||
|
$disabled = $disabled ?? false; ?>
|
||||||
|
|
||||||
|
<?php for ($i = 1; $i <= 5; $i++): ?>
|
||||||
|
<?php if (setting('display_custom_field_' . $i)): ?>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="custom-field-<?= $i ?>" class="form-label">
|
||||||
|
<?= setting('label_custom_field_' . $i) ?: lang('custom_field') . ' #' . $i ?>
|
||||||
|
<?php if (vars('require_custom_field_' . $i)): ?>
|
||||||
|
<span class="text-danger" hidden>*</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</label>
|
||||||
|
<input type="text" id="custom-field-<?= $i ?>"
|
||||||
|
class="<?= vars('require_custom_field_' . $i) ? 'required' : '' ?> form-control"
|
||||||
|
maxlength="120" <?= $disabled ? 'disabled' : '' ?>/>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endfor; ?>
|
|
@ -246,6 +246,50 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h5 class="text-black-50 mb-3 fw-light">
|
||||||
|
<?= lang('custom_fields') ?>
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<div class="row mb-5 fields-row">
|
||||||
|
<?php for ($i = 1; $i <= 5; $i++): ?>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-group mb-5">
|
||||||
|
<label for="first-name" class="form-label">
|
||||||
|
<?= lang('custom_field') ?> #<?= $i ?>
|
||||||
|
<span class="text-danger">*</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="text" id="custom-field-<?= $i ?>" class="form-control mb-2"
|
||||||
|
placeholder="<?= lang('label') ?>"
|
||||||
|
data-field="label_custom_field_<?= $i ?>"
|
||||||
|
aria-label="label"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="d-flex">
|
||||||
|
<div class="form-check form-switch me-4">
|
||||||
|
<input class="form-check-input display-switch" type="checkbox"
|
||||||
|
id="display-custom-field-<?= $i ?>"
|
||||||
|
data-field="display_custom_field_<?= $i ?>">
|
||||||
|
<label class="form-check-label" for="display-custom-field-<?= $i ?>">
|
||||||
|
<?= lang('display') ?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input require-switch" type="checkbox"
|
||||||
|
id="require-custom-field-<?= $i ?>"
|
||||||
|
data-field="require_custom_field_<?= $i ?>">
|
||||||
|
<label class="form-check-label" for="require-custom-field-<?= $i ?>">
|
||||||
|
<?= lang('require') ?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<h5 class="text-black-50 mb-3 fw-light">
|
<h5 class="text-black-50 mb-3 fw-light">
|
||||||
<?= lang('options') ?>
|
<?= lang('options') ?>
|
||||||
</h5>
|
</h5>
|
||||||
|
|
|
@ -181,7 +181,9 @@
|
||||||
]); ?>
|
]); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php component('auxiliary_fields'); ?>
|
<?php component('custom_fields', [
|
||||||
|
'disabled' => true
|
||||||
|
]); ?>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" for="notes">
|
<label class="form-label" for="notes">
|
||||||
|
|
|
@ -46,6 +46,11 @@ App.Components.AppointmentsModal = (function () {
|
||||||
const $insertAppointment = $('#insert-appointment');
|
const $insertAppointment = $('#insert-appointment');
|
||||||
const $existingCustomersList = $('#existing-customers-list');
|
const $existingCustomersList = $('#existing-customers-list');
|
||||||
const $newCustomer = $('#new-customer');
|
const $newCustomer = $('#new-customer');
|
||||||
|
const $customField1 = $('#custom-field-1');
|
||||||
|
const $customField2 = $('#custom-field-2');
|
||||||
|
const $customField3 = $('#custom-field-3');
|
||||||
|
const $customField4 = $('#custom-field-4');
|
||||||
|
const $customField5 = $('#custom-field-5');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the displayed timezone.
|
* Update the displayed timezone.
|
||||||
|
@ -110,7 +115,12 @@ App.Components.AppointmentsModal = (function () {
|
||||||
zip_code: $zipCode.val(),
|
zip_code: $zipCode.val(),
|
||||||
language: $language.val(),
|
language: $language.val(),
|
||||||
timezone: $timezone.val(),
|
timezone: $timezone.val(),
|
||||||
notes: $customerNotes.val()
|
notes: $customerNotes.val(),
|
||||||
|
custom_field_1: $customField1.val(),
|
||||||
|
custom_field_2: $customField2.val(),
|
||||||
|
custom_field_3: $customField3.val(),
|
||||||
|
custom_field_4: $customField4.val(),
|
||||||
|
custom_field_5: $customField5.val()
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($customerId.val() !== '') {
|
if ($customerId.val() !== '') {
|
||||||
|
@ -196,7 +206,7 @@ App.Components.AppointmentsModal = (function () {
|
||||||
|
|
||||||
$startDatetime[0]._flatpickr.setDate(startMoment.toDate());
|
$startDatetime[0]._flatpickr.setDate(startMoment.toDate());
|
||||||
$endDatetime[0]._flatpickr.setDate(startMoment.add(duration, 'minutes').toDate());
|
$endDatetime[0]._flatpickr.setDate(startMoment.add(duration, 'minutes').toDate());
|
||||||
|
|
||||||
// Display modal form.
|
// Display modal form.
|
||||||
$appointmentsModal.find('.modal-header h3').text(lang('new_appointment_title'));
|
$appointmentsModal.find('.modal-header h3').text(lang('new_appointment_title'));
|
||||||
|
|
||||||
|
@ -217,7 +227,8 @@ App.Components.AppointmentsModal = (function () {
|
||||||
vars('customers').forEach((customer) => {
|
vars('customers').forEach((customer) => {
|
||||||
$('<div/>', {
|
$('<div/>', {
|
||||||
'data-id': customer.id,
|
'data-id': customer.id,
|
||||||
'text': (customer.first_name || '[No First Name]') + ' ' + (customer.last_name || '[No Last Name]')
|
'text':
|
||||||
|
(customer.first_name || '[No First Name]') + ' ' + (customer.last_name || '[No Last Name]')
|
||||||
}).appendTo($existingCustomersList);
|
}).appendTo($existingCustomersList);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,6 +260,11 @@ App.Components.AppointmentsModal = (function () {
|
||||||
$language.val(customer.language);
|
$language.val(customer.language);
|
||||||
$timezone.val(customer.timezone);
|
$timezone.val(customer.timezone);
|
||||||
$customerNotes.val(customer.notes);
|
$customerNotes.val(customer.notes);
|
||||||
|
$customField1.val(customer.custom_field_1);
|
||||||
|
$customField2.val(customer.custom_field_2);
|
||||||
|
$customField3.val(customer.custom_field_3);
|
||||||
|
$customField4.val(customer.custom_field_4);
|
||||||
|
$customField5.val(customer.custom_field_5);
|
||||||
}
|
}
|
||||||
|
|
||||||
$selectCustomer.trigger('click'); // Hide the list.
|
$selectCustomer.trigger('click'); // Hide the list.
|
||||||
|
@ -278,7 +294,10 @@ App.Components.AppointmentsModal = (function () {
|
||||||
response.forEach((customer) => {
|
response.forEach((customer) => {
|
||||||
$('<div/>', {
|
$('<div/>', {
|
||||||
'data-id': customer.id,
|
'data-id': customer.id,
|
||||||
'text': (customer.first_name || '[No First Name]') + ' ' + (customer.last_name || '[No Last Name]')
|
'text':
|
||||||
|
(customer.first_name || '[No First Name]') +
|
||||||
|
' ' +
|
||||||
|
(customer.last_name || '[No Last Name]')
|
||||||
}).appendTo($existingCustomersList);
|
}).appendTo($existingCustomersList);
|
||||||
|
|
||||||
// Verify if this customer is on the old customer list.
|
// Verify if this customer is on the old customer list.
|
||||||
|
@ -309,7 +328,10 @@ App.Components.AppointmentsModal = (function () {
|
||||||
) {
|
) {
|
||||||
$('<div/>', {
|
$('<div/>', {
|
||||||
'data-id': customer.id,
|
'data-id': customer.id,
|
||||||
'text': (customer.first_name || '[No First Name]') + ' ' + (customer.last_name || '[No Last Name]')
|
'text':
|
||||||
|
(customer.first_name || '[No First Name]') +
|
||||||
|
' ' +
|
||||||
|
(customer.last_name || '[No Last Name]')
|
||||||
}).appendTo($existingCustomersList);
|
}).appendTo($existingCustomersList);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -328,8 +350,8 @@ App.Components.AppointmentsModal = (function () {
|
||||||
*/
|
*/
|
||||||
$selectService.on('change', () => {
|
$selectService.on('change', () => {
|
||||||
const serviceId = $selectService.val();
|
const serviceId = $selectService.val();
|
||||||
|
|
||||||
const providerId = $selectProvider.val();
|
const providerId = $selectProvider.val();
|
||||||
|
|
||||||
$selectProvider.empty();
|
$selectProvider.empty();
|
||||||
|
|
||||||
|
@ -341,7 +363,7 @@ App.Components.AppointmentsModal = (function () {
|
||||||
const duration = service ? service.duration : 60;
|
const duration = service ? service.duration : 60;
|
||||||
|
|
||||||
const start = $startDatetime[0]._flatpickr.selectedDates[0];
|
const start = $startDatetime[0]._flatpickr.selectedDates[0];
|
||||||
$endDatetime[0]._flatpickr.setDate( new Date(start.getTime() + duration * 60000));
|
$endDatetime[0]._flatpickr.setDate(new Date(start.getTime() + duration * 60000));
|
||||||
|
|
||||||
// Update the providers select box.
|
// Update the providers select box.
|
||||||
|
|
||||||
|
@ -366,7 +388,7 @@ App.Components.AppointmentsModal = (function () {
|
||||||
$selectProvider.append(new Option(provider.first_name + ' ' + provider.last_name, provider.id));
|
$selectProvider.append(new Option(provider.first_name + ' ' + provider.last_name, provider.id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($selectProvider.find(`option[value="${providerId}"]`).length) {
|
if ($selectProvider.find(`option[value="${providerId}"]`).length) {
|
||||||
$selectProvider.val(providerId);
|
$selectProvider.val(providerId);
|
||||||
}
|
}
|
||||||
|
@ -395,6 +417,11 @@ App.Components.AppointmentsModal = (function () {
|
||||||
$language.val('english');
|
$language.val('english');
|
||||||
$timezone.val('UTC');
|
$timezone.val('UTC');
|
||||||
$customerNotes.val('');
|
$customerNotes.val('');
|
||||||
|
$customField1.val('');
|
||||||
|
$customField2.val('');
|
||||||
|
$customField3.val('');
|
||||||
|
$customField4.val('');
|
||||||
|
$customField5.val('');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,14 +491,14 @@ App.Components.AppointmentsModal = (function () {
|
||||||
);
|
);
|
||||||
|
|
||||||
const start = $startDatetime[0]._flatpickr.selectedDates[0];
|
const start = $startDatetime[0]._flatpickr.selectedDates[0];
|
||||||
$endDatetime[0]._flatpickr.setDate( new Date(start.getTime() + service.duration * 60000));
|
$endDatetime[0]._flatpickr.setDate(new Date(start.getTime() + service.duration * 60000));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$startDatetime[0]._flatpickr.setDate( startDatetime);
|
$startDatetime[0]._flatpickr.setDate(startDatetime);
|
||||||
|
|
||||||
App.Utils.UI.initializeDatetimepicker($endDatetime);
|
App.Utils.UI.initializeDatetimepicker($endDatetime);
|
||||||
$endDatetime[0]._flatpickr.setDate( endDatetime);
|
$endDatetime[0]._flatpickr.setDate(endDatetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -502,7 +529,10 @@ App.Components.AppointmentsModal = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check email address.
|
// Check email address.
|
||||||
if ($appointmentsModal.find('#email').val() && !App.Utils.Validation.email($appointmentsModal.find('#email').val())) {
|
if (
|
||||||
|
$appointmentsModal.find('#email').val() &&
|
||||||
|
!App.Utils.Validation.email($appointmentsModal.find('#email').val())
|
||||||
|
) {
|
||||||
$appointmentsModal.find('#email').addClass('is-invalid');
|
$appointmentsModal.find('#email').addClass('is-invalid');
|
||||||
throw new Error(lang('invalid_email'));
|
throw new Error(lang('invalid_email'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,15 @@ App.Pages.Customers = (function () {
|
||||||
const $zipCode = $('#zip-code');
|
const $zipCode = $('#zip-code');
|
||||||
const $timezone = $('#timezone');
|
const $timezone = $('#timezone');
|
||||||
const $language = $('#language');
|
const $language = $('#language');
|
||||||
|
const $customField1 = $('#custom-field-1');
|
||||||
|
const $customField2 = $('#custom-field-2');
|
||||||
|
const $customField3 = $('#custom-field-3');
|
||||||
|
const $customField4 = $('#custom-field-4');
|
||||||
|
const $customField5 = $('#custom-field-5');
|
||||||
const $notes = $('#notes');
|
const $notes = $('#notes');
|
||||||
const $formMessage = $('#form-message');
|
const $formMessage = $('#form-message');
|
||||||
const $customerAppointments = $('#customer-appointments');
|
const $customerAppointments = $('#customer-appointments');
|
||||||
|
|
||||||
let filterResults = {};
|
let filterResults = {};
|
||||||
let filterLimit = 20;
|
let filterLimit = 20;
|
||||||
|
|
||||||
|
@ -124,7 +130,12 @@ App.Pages.Customers = (function () {
|
||||||
zip_code: $zipCode.val(),
|
zip_code: $zipCode.val(),
|
||||||
notes: $notes.val(),
|
notes: $notes.val(),
|
||||||
timezone: $timezone.val(),
|
timezone: $timezone.val(),
|
||||||
language: $language.val() || 'english'
|
language: $language.val() || 'english',
|
||||||
|
custom_field_1: $customField1.val(),
|
||||||
|
custom_field_2: $customField2.val(),
|
||||||
|
custom_field_3: $customField3.val(),
|
||||||
|
custom_field_4: $customField4.val(),
|
||||||
|
custom_field_5: $customField5.val()
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($id.val()) {
|
if ($id.val()) {
|
||||||
|
@ -276,6 +287,11 @@ App.Pages.Customers = (function () {
|
||||||
$notes.val(customer.notes);
|
$notes.val(customer.notes);
|
||||||
$timezone.val(customer.timezone);
|
$timezone.val(customer.timezone);
|
||||||
$language.val(customer.language || 'english');
|
$language.val(customer.language || 'english');
|
||||||
|
$customField1.val(customer.custom_field_1);
|
||||||
|
$customField2.val(customer.custom_field_2);
|
||||||
|
$customField3.val(customer.custom_field_3);
|
||||||
|
$customField4.val(customer.custom_field_4);
|
||||||
|
$customField5.val(customer.custom_field_5);
|
||||||
|
|
||||||
$customerAppointments.empty();
|
$customerAppointments.empty();
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,11 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
||||||
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
||||||
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
||||||
|
$appointmentsModal.find('#custom-field-1').val(customer.custom_field_1);
|
||||||
|
$appointmentsModal.find('#custom-field-2').val(customer.custom_field_2);
|
||||||
|
$appointmentsModal.find('#custom-field-3').val(customer.custom_field_3);
|
||||||
|
$appointmentsModal.find('#custom-field-4').val(customer.custom_field_4);
|
||||||
|
$appointmentsModal.find('#custom-field-5').val(customer.custom_field_5);
|
||||||
|
|
||||||
App.Components.ColorSelection.setColor(
|
App.Components.ColorSelection.setColor(
|
||||||
$appointmentsModal.find('#appointment-color'),
|
$appointmentsModal.find('#appointment-color'),
|
||||||
|
@ -287,7 +292,10 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
*/
|
*/
|
||||||
$selectFilterItem.on('change', () => {
|
$selectFilterItem.on('change', () => {
|
||||||
// If current value is service, then the sync buttons must be disabled.
|
// If current value is service, then the sync buttons must be disabled.
|
||||||
if ($selectFilterItem.find('option:selected').attr('type') === FILTER_TYPE_SERVICE || $selectFilterItem.val() === 'all') {
|
if (
|
||||||
|
$selectFilterItem.find('option:selected').attr('type') === FILTER_TYPE_SERVICE ||
|
||||||
|
$selectFilterItem.val() === 'all'
|
||||||
|
) {
|
||||||
$('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', true);
|
$('#google-sync, #enable-sync, #insert-appointment, #insert-dropdown').prop('disabled', true);
|
||||||
fullCalendar.setOption('selectable', false);
|
fullCalendar.setOption('selectable', false);
|
||||||
fullCalendar.setOption('editable', false);
|
fullCalendar.setOption('editable', false);
|
||||||
|
@ -317,7 +325,9 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
$('#google-sync').prop('disabled', true);
|
$('#google-sync').prop('disabled', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#insert-working-plan-exception').toggle(providerId !== App.Utils.CalendarDefaultView.FILTER_TYPE_ALL);
|
$('#insert-working-plan-exception').toggle(
|
||||||
|
providerId !== App.Utils.CalendarDefaultView.FILTER_TYPE_ALL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$reloadAppointments.trigger('click');
|
$reloadAppointments.trigger('click');
|
||||||
|
@ -382,10 +392,10 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
$target.hasClass('fc-custom') && vars('privileges').appointments.edit === true ? '' : 'd-none';
|
$target.hasClass('fc-custom') && vars('privileges').appointments.edit === true ? '' : 'd-none';
|
||||||
displayDelete =
|
displayDelete =
|
||||||
$target.hasClass('fc-custom') && vars('privileges').appointments.delete === true ? 'me-2' : 'd-none'; // Same value at the time.
|
$target.hasClass('fc-custom') && vars('privileges').appointments.delete === true ? 'me-2' : 'd-none'; // Same value at the time.
|
||||||
|
|
||||||
let startDateTimeObject = info.event.start;
|
let startDateTimeObject = info.event.start;
|
||||||
let endDateTimeObject = info.event.end || info.event.start;
|
let endDateTimeObject = info.event.end || info.event.start;
|
||||||
|
|
||||||
if (info.event.extendedProps.data) {
|
if (info.event.extendedProps.data) {
|
||||||
startDateTimeObject = new Date(info.event.extendedProps.data.start_datetime);
|
startDateTimeObject = new Date(info.event.extendedProps.data.start_datetime);
|
||||||
endDateTimeObject = new Date(info.event.extendedProps.data.end_datetime);
|
endDateTimeObject = new Date(info.event.extendedProps.data.end_datetime);
|
||||||
|
@ -496,11 +506,14 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
'text': lang('start')
|
'text': lang('start')
|
||||||
}),
|
}),
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': startTime ? App.Utils.Date.format(`${date} ${startTime}`,
|
'text': startTime
|
||||||
vars('date_format'),
|
? App.Utils.Date.format(
|
||||||
vars('time_format'),
|
`${date} ${startTime}`,
|
||||||
true
|
vars('date_format'),
|
||||||
) : '-'
|
vars('time_format'),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
: '-'
|
||||||
}),
|
}),
|
||||||
$('<br/>'),
|
$('<br/>'),
|
||||||
|
|
||||||
|
@ -509,11 +522,14 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
'text': lang('end')
|
'text': lang('end')
|
||||||
}),
|
}),
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': endTime ? App.Utils.Date.format(`${date} ${endTime}`,
|
'text': endTime
|
||||||
vars('date_format'),
|
? App.Utils.Date.format(
|
||||||
vars('time_format'),
|
`${date} ${endTime}`,
|
||||||
true
|
vars('date_format'),
|
||||||
) : '-'
|
vars('time_format'),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
: '-'
|
||||||
}),
|
}),
|
||||||
$('<br/>'),
|
$('<br/>'),
|
||||||
|
|
||||||
|
@ -626,7 +642,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
'text': lang('status')
|
'text': lang('status')
|
||||||
}),
|
}),
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': info.event.extendedProps.data.status || '-',
|
'text': info.event.extendedProps.data.status || '-'
|
||||||
}),
|
}),
|
||||||
$('<br/>'),
|
$('<br/>'),
|
||||||
|
|
||||||
|
@ -1025,8 +1041,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isProviderDisplayed =
|
const isProviderDisplayed = $selectFilterItem.find('option:selected').attr('type') === FILTER_TYPE_PROVIDER;
|
||||||
$selectFilterItem.find('option:selected').attr('type') === FILTER_TYPE_PROVIDER;
|
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
|
@ -1059,8 +1074,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
|
|
||||||
if (isProviderDisplayed) {
|
if (isProviderDisplayed) {
|
||||||
const provider = vars('available_providers').find(
|
const provider = vars('available_providers').find(
|
||||||
(availableProvider) =>
|
(availableProvider) => Number(availableProvider.id) === Number($selectFilterItem.val())
|
||||||
Number(availableProvider.id) === Number($selectFilterItem.val())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (provider) {
|
if (provider) {
|
||||||
|
@ -1090,8 +1104,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
$appointmentsModal.find('#select-provider').trigger('change');
|
$appointmentsModal.find('#select-provider').trigger('change');
|
||||||
} else {
|
} else {
|
||||||
service = vars('available_services').find(
|
service = vars('available_services').find(
|
||||||
(availableService) =>
|
(availableService) => Number(availableService.id) === Number($selectFilterItem.val())
|
||||||
Number(availableService.id) === Number($selectFilterItem.val())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
|
@ -1182,9 +1195,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
|
|
||||||
// Add appointments to calendar.
|
// Add appointments to calendar.
|
||||||
response.appointments.forEach((appointment) => {
|
response.appointments.forEach((appointment) => {
|
||||||
const title = [
|
const title = [appointment.service.name];
|
||||||
appointment.service.name
|
|
||||||
];
|
|
||||||
|
|
||||||
const customerInfo = [];
|
const customerInfo = [];
|
||||||
|
|
||||||
|
@ -1236,7 +1247,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
calendarEventSource.push(unavailabilityEvent);
|
calendarEventSource.push(unavailabilityEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
response.blocked_periods.forEach(blockedPeriod => {
|
response.blocked_periods.forEach((blockedPeriod) => {
|
||||||
const blockedPeriodEvent = {
|
const blockedPeriodEvent = {
|
||||||
title: blockedPeriod.name,
|
title: blockedPeriod.name,
|
||||||
start: moment(blockedPeriod.start_datetime).toDate(),
|
start: moment(blockedPeriod.start_datetime).toDate(),
|
||||||
|
@ -1263,7 +1274,9 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
(availableProvider) => Number(availableProvider.id) === Number(recordId)
|
(availableProvider) => Number(availableProvider.id) === Number(recordId)
|
||||||
);
|
);
|
||||||
|
|
||||||
const workingPlan = JSON.parse(provider ? provider.settings.working_plan : vars('company_working_plan'));
|
const workingPlan = JSON.parse(
|
||||||
|
provider ? provider.settings.working_plan : vars('company_working_plan')
|
||||||
|
);
|
||||||
const workingPlanExceptions = JSON.parse(provider ? provider.settings.working_plan_exceptions : '{}');
|
const workingPlanExceptions = JSON.parse(provider ? provider.settings.working_plan_exceptions : '{}');
|
||||||
let unavailabilityEvent;
|
let unavailabilityEvent;
|
||||||
let breakStart;
|
let breakStart;
|
||||||
|
@ -1304,9 +1317,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
workingPlanExceptionEvent = {
|
workingPlanExceptionEvent = {
|
||||||
title: lang('working_plan_exception'),
|
title: lang('working_plan_exception'),
|
||||||
start: moment(workingPlanExceptionStart, 'YYYY-MM-DD HH:mm', true).toDate(),
|
start: moment(workingPlanExceptionStart, 'YYYY-MM-DD HH:mm', true).toDate(),
|
||||||
end: moment(workingPlanExceptionEnd, 'YYYY-MM-DD HH:mm', true)
|
end: moment(workingPlanExceptionEnd, 'YYYY-MM-DD HH:mm', true).add(1, 'day').toDate(),
|
||||||
.add(1, 'day')
|
|
||||||
.toDate(),
|
|
||||||
allDay: true,
|
allDay: true,
|
||||||
color: '#879DB4',
|
color: '#879DB4',
|
||||||
editable: false,
|
editable: false,
|
||||||
|
@ -1352,10 +1363,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
title: lang('not_working'),
|
title: lang('not_working'),
|
||||||
start: calendarDate.clone().toDate(),
|
start: calendarDate.clone().toDate(),
|
||||||
end: moment(
|
end: moment(
|
||||||
calendarDate.format('YYYY-MM-DD') +
|
calendarDate.format('YYYY-MM-DD') + ' ' + sortedWorkingPlan[weekdayName].start + ':00'
|
||||||
' ' +
|
|
||||||
sortedWorkingPlan[weekdayName].start +
|
|
||||||
':00'
|
|
||||||
).toDate(),
|
).toDate(),
|
||||||
allDay: false,
|
allDay: false,
|
||||||
color: '#BEBEBE',
|
color: '#BEBEBE',
|
||||||
|
@ -1376,10 +1384,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
unavailabilityEvent = {
|
unavailabilityEvent = {
|
||||||
title: lang('not_working'),
|
title: lang('not_working'),
|
||||||
start: moment(
|
start: moment(
|
||||||
calendarDate.format('YYYY-MM-DD') +
|
calendarDate.format('YYYY-MM-DD') + ' ' + sortedWorkingPlan[weekdayName].end + ':00'
|
||||||
' ' +
|
|
||||||
sortedWorkingPlan[weekdayName].end +
|
|
||||||
':00'
|
|
||||||
).toDate(),
|
).toDate(),
|
||||||
end: calendarDate.clone().add(1, 'day').toDate(),
|
end: calendarDate.clone().add(1, 'day').toDate(),
|
||||||
allDay: false,
|
allDay: false,
|
||||||
|
@ -1405,9 +1410,7 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
|
|
||||||
const unavailabilityEvent = {
|
const unavailabilityEvent = {
|
||||||
title: lang('break'),
|
title: lang('break'),
|
||||||
start: moment(
|
start: moment(calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.start).toDate(),
|
||||||
calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.start
|
|
||||||
).toDate(),
|
|
||||||
end: moment(calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.end).toDate(),
|
end: moment(calendarDate.format('YYYY-MM-DD') + ' ' + breakPeriod.end).toDate(),
|
||||||
allDay: false,
|
allDay: false,
|
||||||
color: '#BEBEBE',
|
color: '#BEBEBE',
|
||||||
|
@ -1420,7 +1423,6 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
|
|
||||||
calendarDate.add(1, 'day');
|
calendarDate.add(1, 'day');
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.always(() => {
|
.always(() => {
|
||||||
$('#loading').css('visibility', '');
|
$('#loading').css('visibility', '');
|
||||||
|
@ -1562,7 +1564,10 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
|
|
||||||
const localSelectFilterItemValue = window.localStorage.getItem('EasyAppointments.SelectFilterItem');
|
const localSelectFilterItemValue = window.localStorage.getItem('EasyAppointments.SelectFilterItem');
|
||||||
|
|
||||||
if (localSelectFilterItemValue && $selectFilterItem.find(`option[value="${localSelectFilterItemValue}"]`).length) {
|
if (
|
||||||
|
localSelectFilterItemValue &&
|
||||||
|
$selectFilterItem.find(`option[value="${localSelectFilterItemValue}"]`).length
|
||||||
|
) {
|
||||||
$selectFilterItem.val(localSelectFilterItemValue).trigger('change');
|
$selectFilterItem.val(localSelectFilterItemValue).trigger('change');
|
||||||
} else {
|
} else {
|
||||||
$reloadAppointments.trigger('click');
|
$reloadAppointments.trigger('click');
|
||||||
|
@ -1601,6 +1606,11 @@ App.Utils.CalendarDefaultView = (function () {
|
||||||
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
||||||
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
||||||
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
||||||
|
$appointmentsModal.find('#custom-field-1').val(customer.custom_field_1);
|
||||||
|
$appointmentsModal.find('#custom-field-2').val(customer.custom_field_2);
|
||||||
|
$appointmentsModal.find('#custom-field-3').val(customer.custom_field_3);
|
||||||
|
$appointmentsModal.find('#custom-field-4').val(customer.custom_field_4);
|
||||||
|
$appointmentsModal.find('#custom-field-5').val(customer.custom_field_5);
|
||||||
|
|
||||||
App.Components.ColorSelection.setColor($appointmentsModal.find('#appointment-color'), appointment.color);
|
App.Components.ColorSelection.setColor($appointmentsModal.find('#appointment-color'), appointment.color);
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ App.Utils.CalendarTableView = (function () {
|
||||||
createUnavailabilities($providerColumn, response.unavailabilities);
|
createUnavailabilities($providerColumn, response.unavailabilities);
|
||||||
|
|
||||||
// Add the blocked periods to the column.
|
// Add the blocked periods to the column.
|
||||||
createBlockedPeriods($providerColumn, response.blocked_periods);
|
createBlockedPeriods($providerColumn, response.blocked_periods);
|
||||||
|
|
||||||
// Add the provider breaks to the column.
|
// Add the provider breaks to the column.
|
||||||
const workingPlan = JSON.parse(provider.settings.working_plan);
|
const workingPlan = JSON.parse(provider.settings.working_plan);
|
||||||
|
@ -232,6 +232,11 @@ App.Utils.CalendarTableView = (function () {
|
||||||
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
$appointmentsModal.find('#appointment-status').val(appointment.status);
|
||||||
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
$appointmentsModal.find('#appointment-notes').val(appointment.notes);
|
||||||
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
$appointmentsModal.find('#customer-notes').val(customer.notes);
|
||||||
|
$appointmentsModal.find('#custom-field-1').val(customer.custom_field_1);
|
||||||
|
$appointmentsModal.find('#custom-field-2').val(customer.custom_field_2);
|
||||||
|
$appointmentsModal.find('#custom-field-3').val(customer.custom_field_3);
|
||||||
|
$appointmentsModal.find('#custom-field-4').val(customer.custom_field_4);
|
||||||
|
$appointmentsModal.find('#custom-field-5').val(customer.custom_field_5);
|
||||||
|
|
||||||
App.Components.ColorSelection.setColor(
|
App.Components.ColorSelection.setColor(
|
||||||
$appointmentsModal.find('#appointment-color'),
|
$appointmentsModal.find('#appointment-color'),
|
||||||
|
@ -387,7 +392,9 @@ App.Utils.CalendarTableView = (function () {
|
||||||
App.Utils.UI.initializeDatepicker($calendarHeader.find('.select-date'), {
|
App.Utils.UI.initializeDatepicker($calendarHeader.find('.select-date'), {
|
||||||
onChange(selectedDates) {
|
onChange(selectedDates) {
|
||||||
const startDate = selectedDates[0];
|
const startDate = selectedDates[0];
|
||||||
const endDate = moment(startDate).add(parseInt($selectFilterItem.val()) - 1, 'days').toDate();
|
const endDate = moment(startDate)
|
||||||
|
.add(parseInt($selectFilterItem.val()) - 1, 'days')
|
||||||
|
.toDate();
|
||||||
createView(startDate, endDate);
|
createView(startDate, endDate);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -853,7 +860,7 @@ App.Utils.CalendarTableView = (function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterServiceIds = $filterService.val().map(serviceId => Number(serviceId));
|
const filterServiceIds = $filterService.val().map((serviceId) => Number(serviceId));
|
||||||
|
|
||||||
appointments = appointments.filter(
|
appointments = appointments.filter(
|
||||||
(appointment) => !filterServiceIds.length || filterServiceIds.includes(appointment.id_services)
|
(appointment) => !filterServiceIds.length || filterServiceIds.includes(appointment.id_services)
|
||||||
|
@ -868,9 +875,7 @@ App.Utils.CalendarTableView = (function () {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = [
|
const title = [appointment.service.name];
|
||||||
appointment.service.name
|
|
||||||
];
|
|
||||||
|
|
||||||
const customerInfo = [];
|
const customerInfo = [];
|
||||||
|
|
||||||
|
@ -938,7 +943,7 @@ App.Utils.CalendarTableView = (function () {
|
||||||
|
|
||||||
$providerColumn.find('.calendar-wrapper').data('fullCalendar').addEventSource(calendarEventSource);
|
$providerColumn.find('.calendar-wrapper').data('fullCalendar').addEventSource(calendarEventSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Blocked Period Events
|
* Create Blocked Period Events
|
||||||
*
|
*
|
||||||
|
@ -1015,11 +1020,11 @@ App.Utils.CalendarTableView = (function () {
|
||||||
|
|
||||||
$event.html(
|
$event.html(
|
||||||
lang('break') +
|
lang('break') +
|
||||||
' <span class="hour">' +
|
' <span class="hour">' +
|
||||||
moment(eventDate).format('HH:mm') +
|
moment(eventDate).format('HH:mm') +
|
||||||
'</span> (' +
|
'</span> (' +
|
||||||
eventDuration +
|
eventDuration +
|
||||||
"')"
|
"')"
|
||||||
);
|
);
|
||||||
|
|
||||||
$event.data(entry);
|
$event.data(entry);
|
||||||
|
@ -1199,8 +1204,8 @@ App.Utils.CalendarTableView = (function () {
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': info.event.extendedProps.data
|
'text': info.event.extendedProps.data
|
||||||
? info.event.extendedProps.data.provider.first_name +
|
? info.event.extendedProps.data.provider.first_name +
|
||||||
' ' +
|
' ' +
|
||||||
info.event.extendedProps.data.provider.last_name
|
info.event.extendedProps.data.provider.last_name
|
||||||
: '-'
|
: '-'
|
||||||
}),
|
}),
|
||||||
$('<br/>'),
|
$('<br/>'),
|
||||||
|
@ -1212,8 +1217,8 @@ App.Utils.CalendarTableView = (function () {
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': App.Utils.Date.format(
|
'text': App.Utils.Date.format(
|
||||||
info.event.extendedProps.data.date +
|
info.event.extendedProps.data.date +
|
||||||
' ' +
|
' ' +
|
||||||
info.event.extendedProps.data.workingPlanException.start,
|
info.event.extendedProps.data.workingPlanException.start,
|
||||||
vars('date_format'),
|
vars('date_format'),
|
||||||
vars('time_format'),
|
vars('time_format'),
|
||||||
true
|
true
|
||||||
|
@ -1228,8 +1233,8 @@ App.Utils.CalendarTableView = (function () {
|
||||||
$('<span/>', {
|
$('<span/>', {
|
||||||
'text': App.Utils.Date.format(
|
'text': App.Utils.Date.format(
|
||||||
info.event.extendedProps.data.date +
|
info.event.extendedProps.data.date +
|
||||||
' ' +
|
' ' +
|
||||||
info.event.extendedProps.data.workingPlanException.end,
|
info.event.extendedProps.data.workingPlanException.end,
|
||||||
vars('date_format'),
|
vars('date_format'),
|
||||||
vars('time_format'),
|
vars('time_format'),
|
||||||
true
|
true
|
||||||
|
|
30
openapi.yml
30
openapi.yml
|
@ -1902,6 +1902,16 @@ components:
|
||||||
type: string
|
type: string
|
||||||
language:
|
language:
|
||||||
type: string
|
type: string
|
||||||
|
customField1:
|
||||||
|
type: string
|
||||||
|
customField2:
|
||||||
|
type: string
|
||||||
|
customField3:
|
||||||
|
type: string
|
||||||
|
customField4:
|
||||||
|
type: string
|
||||||
|
customField5:
|
||||||
|
type: string
|
||||||
notes:
|
notes:
|
||||||
type: string
|
type: string
|
||||||
example:
|
example:
|
||||||
|
@ -1914,6 +1924,11 @@ components:
|
||||||
zip: '12345'
|
zip: '12345'
|
||||||
timezone: UTC
|
timezone: UTC
|
||||||
language: english
|
language: english
|
||||||
|
customField1: Value1
|
||||||
|
customField2: Value2
|
||||||
|
customField3: Value3
|
||||||
|
customField4: Value4
|
||||||
|
customField5: Value5
|
||||||
notes: This is a test customer.
|
notes: This is a test customer.
|
||||||
CustomerPayload:
|
CustomerPayload:
|
||||||
type: object
|
type: object
|
||||||
|
@ -1936,6 +1951,16 @@ components:
|
||||||
type: string
|
type: string
|
||||||
language:
|
language:
|
||||||
type: string
|
type: string
|
||||||
|
customField1:
|
||||||
|
type: string
|
||||||
|
customField2:
|
||||||
|
type: string
|
||||||
|
customField3:
|
||||||
|
type: string
|
||||||
|
customField4:
|
||||||
|
type: string
|
||||||
|
customField5:
|
||||||
|
type: string
|
||||||
notes:
|
notes:
|
||||||
type: string
|
type: string
|
||||||
example:
|
example:
|
||||||
|
@ -1947,6 +1972,11 @@ components:
|
||||||
zip: '12345'
|
zip: '12345'
|
||||||
timezone: UTC
|
timezone: UTC
|
||||||
language: english
|
language: english
|
||||||
|
customField1: Value1
|
||||||
|
customField2: Value2
|
||||||
|
customField3: Value3
|
||||||
|
customField4: Value4
|
||||||
|
customField5: Value5
|
||||||
notes: This is a test customer.
|
notes: This is a test customer.
|
||||||
CustomerCollection:
|
CustomerCollection:
|
||||||
type: array
|
type: array
|
||||||
|
|
Loading…
Reference in a new issue