'contacts.browse', 'create' => 'contacts.create', 'update' => 'contacts.update', 'destroy' => 'contacts.destroy', ]; protected $jsFiles = [ 'BAP_Contacts.js' ]; protected $moduleSettingsLinks = [ ['route' => 'contacts.status.index', 'label' => 'settings.status'], ['route' => 'contacts.source.index', 'label' => 'settings.source'], ['route' => 'contacts.language.index', 'label' => 'settings.language'], ['route' => 'contacts.mailinglist.index', 'label' => 'settings.mailinglist'], ]; protected $settingsPermission = 'contacts.settings'; protected $showFields = [ 'information' => [ 'full_name' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6', 'hide_in_form' => true ], 'first_name' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6', 'hide_in_show' => true ], 'last_name' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6', 'hide_in_show' => true ], 'use_profile_image' => [ 'type' => 'checkbox', 'col-class' => 'col-lg-3 col-md-3 col-sm-6 col-xs-6', 'hide_in_show' => true ], 'force_assigned' => [ 'type' => 'checkbox', 'col-class' => 'col-lg-3 col-md-3 col-sm-6 col-xs-6', 'hide_in_show' => true ], 'profile_image' => [ 'type' => 'gravatar', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6', 'hide_label' => true ], 'phone' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'owned_by' => [ 'type' => 'assigned_to', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'mobile' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'contact_status_id' => [ 'type' => 'manyToOne', 'relation' => 'contactStatus', 'column' => 'name', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'email' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'account_id' => [ 'type' => 'manyToOne', 'relation' => 'account', 'column' => 'name', 'dont_translate' => true, 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], ], 'additional_information' => [ 'fax' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'contact_source_id' => [ 'type' => 'manyToOne', 'relation' => 'contactSource', 'column' => 'name', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'tags' => [ 'type' => 'tags', 'col-class' => 'col-lg-12 col-md-12 col-sm-12 col-xs-12' ], 'job_title' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'assistant_name' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'department' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'assistant_phone' => [ 'type' => 'text', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'referral_id' => [ 'type' => 'manyToOne', 'relation' => 'referral', 'column' => 'full_name', 'dont_translate' => true, 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'birth_date' => [ 'type' => 'date', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], 'language_id' => [ 'type' => 'manyToOne', 'relation' => 'language', 'column' => 'name', 'col-class' => 'col-lg-6 col-md-6 col-sm-6 col-xs-6' ], ], 'address_information' => [ 'street' => [ 'type' => 'text', 'col-class' => 'col-lg-4 col-md-4 col-sm-6 col-xs-6' ], 'city' => [ 'type' => 'text', 'col-class' => 'col-lg-4 col-md-4 col-sm-6 col-xs-6' ], 'zip_code' => [ 'type' => 'text', 'col-class' => 'col-lg-4 col-md-4 col-sm-6 col-xs-6' ], 'state' => [ 'type' => 'text', 'col-class' => 'col-lg-4 col-md-4 col-sm-6 col-xs-6' ], 'country_id' => [ 'type' => 'manyToOne', 'relation' => 'country', 'column' => 'name', 'col-class' => 'col-lg-4 col-md-4 col-sm-6 col-xs-6' ], ], 'notes' => [ 'notes' => [ 'type' => 'text', 'col-class' => 'col-lg-12 col-sm-12 col-md-12' ], ], ]; protected $relationTabs = [ 'multi_email' => [ 'icon' => 'contact_mail', 'permissions' => [ 'browse' => 'contacts.browse', 'update' => 'contacts.update', 'create' => 'contacts.create' ], 'datatable' => [ 'datatable' => ContactEmailDatatable::class ], 'route' => [ 'linked' => 'contacts.contactemails.linked', 'create' => 'contactemails.contactemails.create', 'select' => 'contacts.contactemails.selection', 'bind_selected' => 'contacts.contactemails.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'contactemails::contactemails.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'contactemails::contactemails.module' ], ], 'contact_sent_emails' => [ 'icon' => 'mail', 'permissions' => [ 'browse' => 'contacts.browse', 'update' => 'contacts.update', 'create' => 'contacts.create' ], 'datatable' => [ 'datatable' => ContactSentEmailsDatatable::class ], 'route' => [ 'linked' => 'contacts.sentemails.linked', 'create' => 'sentemails.sentemails.create', 'select' => 'contacts.sentemails.selection', 'bind_selected' => 'contacts.sentemails.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'sentemails::sentemails.create_new', 'label' => 'sentemails::sentemails.compose', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'id', //TODO Fix this ], ], 'select' => [ 'allow' => false, 'modal_title' => 'sentemails::sentemails.module' ], ], 'sms' => [ 'icon' => 'sms', 'permissions' => [ 'browse' => 'sms.browse', 'update' => 'sms.update', 'create' => 'sms.create' ], 'datatable' => [ 'datatable' => ContactSmsDatatable::class ], 'route' => [ 'linked' => 'contacts.sms.linked', 'create' => 'sms.sms.create', 'select' => 'contacts.sms.selection', 'bind_selected' => 'contacts.sms.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'sms::sms.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'sms::sms.module' ], ], 'websites' => [ 'icon' => 'exit_to_app', 'permissions' => [ 'browse' => 'contacts.browse', 'update' => 'contacts.update', 'create' => 'contacts.create' ], 'datatable' => [ 'datatable' => ContactWebsiteDatatable::class ], 'route' => [ 'linked' => 'contacts.contactwebsites.linked', 'create' => 'contactwebsites.contactwebsites.create', 'select' => 'contacts.contactwebsites.selection', 'bind_selected' => 'contacts.contactwebsites.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'contactwebsites::contactwebsites.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'contactwebsites::contactwebsites.module' ], ], 'mailinglists' => [ 'icon' => 'exit_to_app', 'permissions' => [ 'browse' => 'contacts.browse', 'update' => 'contacts.update', 'create' => 'contacts.create' ], 'datatable' => [ 'datatable' => ContactMailinglistsDatatable::class ], 'route' => [ 'linked' => 'contacts.contactmailinglists.linked', 'create' => 'contactmailinglists.contactmailinglists.create', 'select' => 'contacts.contactmailinglists.selection', 'bind_selected' => 'contacts.contactmailinglists.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'contactmailinglists::contactmailinglists.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'contactmailinglists::contactmailinglists.module' ], ], 'contact_sent_emails' => [ 'icon' => 'mail', 'permissions' => [ 'browse' => 'contacts.browse', 'update' => 'contacts.update', 'create' => 'contacts.create' ], 'datatable' => [ 'datatable' => ContactSentEmailsDatatable::class ], 'route' => [ 'linked' => 'contacts.sentemails.linked', 'create' => 'sentemails.sentemails.create', 'select' => 'contacts.sentemails.selection', 'bind_selected' => 'contacts.sentemails.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'sentemails::sentemails.create_new', 'label' => 'sentemails::sentemails.compose', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'id', //TODO Fix this ], ], 'select' => [ 'allow' => false, 'modal_title' => 'sentemails::sentemails.module' ], ], 'events' => [ 'icon' => 'event', 'permissions' => [ 'browse' => 'event.browse', 'update' => 'event.update', 'create' => 'event.create' ], 'datatable' => [ 'datatable' => ContactEventsDatatable::class ], 'route' => [ 'linked' => 'contacts.events.linked', 'create' => 'calendar.events.create', 'select' => 'contacts.events.selection', 'bind_selected' => 'contacts.events.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'calendar::events.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'calendar::events.module' ], ], 'campaigns' => [ 'icon' => 'show_chart', 'permissions' => [ 'browse' => 'campaigns.browse', 'update' => 'campaigns.update', 'create' => 'campaigns.create' ], 'datatable' => [ 'datatable' => ContactCamapginsDatatable::class ], 'route' => [ 'linked' => 'contacts.campaigns.linked', 'create' => 'campaigns.campaigns.create', 'select' => 'contacts.campaigns.selection', 'bind_selected' => 'contacts.campaigns.link' ], 'create' => [ 'allow' => false, 'modal_title' => 'campaigns::campaigns.create_new', 'post_create_bind' => [ 'relationType' => 'manyToMany', 'relatedField' => 'contacts', ] ], 'select' => [ 'allow' => true, 'modal_title' => 'campaigns::campaigns.module' ], ], 'calls' => [ 'icon' => 'phone', 'permissions' => [ 'browse' => 'calls.browse', 'update' => 'calls.update', 'create' => 'calls.create' ], 'datatable' => [ 'datatable' => ContactCallsDatatable::class ], 'route' => [ 'linked' => 'contacts.calls.linked', 'create' => 'calls.calls.create', 'select' => 'contacts.calls.selection', 'bind_selected' => 'contacts.calls.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'calls::calls.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'calls::calls.module' ], ], 'deals' => [ 'icon' => 'monetization_on', 'permissions' => [ 'browse' => 'deals.browse', 'update' => 'deals.update', 'create' => 'deals.create' ], 'datatable' => [ 'datatable' => ContactDealsDatatable::class ], 'route' => [ 'linked' => 'contacts.deals.linked', 'create' => 'deals.deals.create', 'select' => 'contacts.deals.selection', 'bind_selected' => 'contacts.deals.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'deals::deals.create_new', 'post_create_bind' => [ 'relationType' => 'manyToMany', 'relatedField' => 'contacts', ] ], 'select' => [ 'allow' => true, 'modal_title' => 'deals::deals.module' ], ], 'tickets' => [ 'icon' => 'report_problem', 'permissions' => [ 'browse' => 'tickets.browse', 'update' => 'tickets.update', 'create' => 'tickets.create' ], 'datatable' => [ 'datatable' => ContactTicketsDatatable::class ], 'route' => [ 'linked' => 'contacts.tickets.linked', 'create' => 'tickets.tickets.create', 'select' => 'contacts.tickets.selection', 'bind_selected' => 'contacts.tickets.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'tickets::tickets.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'tickets::tickets.module' ], ], 'orders' => [ 'icon' => 'pageview', 'permissions' => [ 'browse' => 'orders.browse', 'update' => 'orders.update', 'create' => 'orders.create' ], 'datatable' => [ 'datatable' => ContactOrdersDatatable::class ], 'route' => [ 'linked' => 'contacts.orders.linked', 'create' => 'orders.orders.create', 'select' => 'contacts.orders.selection', 'bind_selected' => 'contacts.orders.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'orders::orders.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'orders::orders.module' ], ], 'invoices' => [ 'icon' => 'shopping_cart', 'permissions' => [ 'browse' => 'invoices.browse', 'update' => 'invoices.update', 'create' => 'invoices.create' ], 'datatable' => [ 'datatable' => ContactInvoicesDatatable::class ], 'route' => [ 'linked' => 'contacts.invoices.linked', 'create' => 'invoices.invoices.create', 'select' => 'contacts.invoices.selection', 'bind_selected' => 'contacts.invoices.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'invoices::invoices.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'invoices::invoices.module' ], ], 'assets' => [ 'icon' => 'laptop_chromebook', 'permissions' => [ 'browse' => 'assets.browse', 'update' => 'assets.update', 'create' => 'assets.create' ], 'datatable' => [ 'datatable' => ContactAssetsDatatable::class ], 'route' => [ 'linked' => 'contacts.assets.linked', 'create' => 'assets.assets.create', 'select' => 'contacts.assets.selection', 'bind_selected' => 'contacts.assets.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'assets::assets.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'assets::assets.module' ], ], 'quotes' => [ 'icon' => 'chat', 'permissions' => [ 'browse' => 'quotes.browse', 'update' => 'quotes.update', 'create' => 'quotes.create' ], 'datatable' => [ 'datatable' => ContactQuotesDatatable::class ], 'route' => [ 'linked' => 'contacts.quotes.linked', 'create' => 'quotes.quotes.create', 'select' => 'contacts.quotes.selection', 'bind_selected' => 'contacts.quotes.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'quotes::quotes.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'quotes::quotes.module' ], ], 'products' => [ 'icon' => 'pageview', 'permissions' => [ 'browse' => 'products.browse', 'update' => 'products.update', 'create' => 'products.create' ], 'datatable' => [ 'datatable' => ContactProductsDatatable::class ], 'route' => [ 'linked' => 'contacts.products.linked', 'create' => 'products.products.create', 'select' => 'contacts.products.selection', 'bind_selected' => 'contacts.products.link' ], 'create' => [ 'allow' => false, 'modal_title' => 'products::products.create_new', 'post_create_bind' => [ 'relationType' => 'manyToMany', 'relatedField' => 'contacts', ] ], 'select' => [ 'allow' => true, 'modal_title' => 'products::products.module' ], ], 'purchased_products' => [ 'icon' => 'pageview', 'permissions' => [ 'browse' => 'products.browse', 'update' => 'products.update', 'create' => 'products.create' ], 'datatable' => [ 'datatable' => ContactPurchasedProductsDatatable::class ], 'route' => [ 'linked' => 'contacts.purchased_products.linked', 'create' => 'products.purchased_products.create', 'select' => 'contacts.purchased_products.selection', 'bind_selected' => 'contacts.purchased_products.link' ], 'create' => [ 'allow' => false, 'modal_title' => 'products::products.create_new', 'post_create_bind' => [ 'relationType' => 'manyToMany', 'relatedField' => 'contacts', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'products::products.module' ], ], 'testimonials' => [ 'icon' => 'thumb_up', 'permissions' => [ 'browse' => 'testimonials.browse', 'update' => 'testimonials.update', 'create' => 'testimonials.create' ], 'datatable' => [ 'datatable' => ContactTestimonialsDatatable::class ], 'route' => [ 'linked' => 'contacts.testimonials.linked', 'create' => 'testimonials.testimonials.create', 'select' => 'contacts.testimonials.selection', 'bind_selected' => 'contacts.testimonials.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'testimonials::testimonials.create_new', 'post_create_bind' => [ 'relationType' => 'oneToMany', 'relatedField' => 'contact_id', ] ], 'select' => [ 'allow' => false, 'modal_title' => 'testimonials::testimonials.module' ], ], 'documents' => [ 'icon' => 'storage', 'permissions' => [ 'browse' => 'documents.browse', 'update' => 'documents.update', 'create' => 'documents.create' ], 'datatable' => [ 'datatable' => ContactDocumentsDatatable::class ], 'route' => [ 'linked' => 'contacts.documents.linked', 'create' => 'documents.documents.create', 'select' => 'contacts.documents.selection', 'bind_selected' => 'contacts.documents.link' ], 'create' => [ 'allow' => true, 'modal_title' => 'documents::documents.create_new', 'post_create_bind' => [ 'relationType' => 'manyToMany', 'relatedField' => 'contacts', ] ], 'select' => [ 'allow' => true, 'modal_title' => 'documents::documents.module' ], ], ]; protected $languageFile = 'contacts::contacts'; protected $routes = [ 'index' => 'contacts.contacts.index', 'create' => 'contacts.contacts.create', 'show' => 'contacts.contacts.show', 'edit' => 'contacts.contacts.edit', 'store' => 'contacts.contacts.store', 'destroy' => 'contacts.contacts.destroy', 'update' => 'contacts.contacts.update', 'import' => 'contacts.contacts.import', 'import_process' => 'contacts.contacts.import.process' ]; /** * @var ContactFieldSettingsService */ private $contactFieldSettingsService; public function __construct() { parent::__construct(); $this->contactFieldSettingsService = app(ContactFieldSettingsService::class); } /** * Map each Contacts module "Settings" dropdown item to the corresponding * field-settings key so that renamed field labels (e.g. Status -> Test) * are reflected in the dropdown automatically. */ protected function moduleSettingsLinkFieldMap(): array { return [ 'settings.status' => 'contact_status_id', 'settings.source' => 'contact_source_id', 'settings.language' => 'language_id', // 'settings.mailinglist' has no field-settings equivalent -> falls back ]; } /** * Effective field labels from the CRM field-settings service. */ protected function moduleSettingsLinkLabelMap(): array { return $this->contactFieldSettingsService->getFieldLabelMap(auth()->user()); } /** * Override show fields to use the dynamic field settings service. */ public function overrideShowFieldsForCurrentUser() { return $this->contactFieldSettingsService->getShowFields(auth()->user()); } /** * * @param $request * @param $entity * @param $input */ public function beforeUpdate($request, &$entity = NULL, &$input = NULL) { /** * If there is no profile_image in input. Remove this field and don't process. * Why? If there was image before update it will be removed because all variables from input are processed even null values. */ if (!isset($input['profile_image'])) { unset($input['profile_image']); } // Merge incoming custom_fields with existing ones (prevents losing fields not in the current form) // Exclude keys that now have real DB columns — those arrive as top-level fields. if (isset($input['custom_fields']) && is_array($input['custom_fields']) && $entity !== null) { $existingCustomFields = is_array($entity->custom_fields) ? $entity->custom_fields : []; $fieldService = app(ContactFieldSettingsService::class); $provisionedKeys = $fieldService->getProvisionedColumnKeys(auth()->user()); $incomingCustomFields = []; foreach ($input['custom_fields'] as $cfKey => $cfValue) { if (!in_array($cfKey, $provisionedKeys, true)) { $incomingCustomFields[$cfKey] = $cfValue; } } $input['custom_fields'] = array_merge($existingCustomFields, $incomingCustomFields); } } private function handleCustomFileUploads($request, $entity = null): void { if ($entity === null) { return; } $fileFields = $this->contactFieldSettingsService->getFileUploadFields(auth()->user()); if (empty($fileFields)) { return; } $customFields = is_array($entity->custom_fields) ? $entity->custom_fields : []; $customUpdated = false; $dirty = false; foreach ($fileFields as $field) { $storageKey = $field['storage_key'] ?? $field['key']; $usesColumn = !empty($field['uses_column']); $inputKey = $usesColumn ? $storageKey : 'custom_fields.' . $storageKey; $file = $request->file($inputKey); if ($file) { $path = $file->store('contacts/custom_fields', 'public'); if ($usesColumn) { $entity->{$storageKey} = $path; } else { $customFields[$storageKey] = $path; $customUpdated = true; } $dirty = true; } } if ($dirty) { if ($customUpdated) { $entity->custom_fields = $customFields; } $entity->save(); } } /** * After entity store * @param $request * @param $entity * @return bool */ public function afterStore($request, &$entity = NULL) { // Set created_by and company_id $entity->created_by = \Auth::user()->id; $entity->company_id = \Auth::user()->company_id; if( $entity->owned_by_id == null ){ $entity->owned_by_id = \Auth::user()->id; $entity->owned_by_type = 'Modules\Platform\User\Entities\User'; } $entity->save(); // allocate to user $this->allocateToUser($entity); $tags = $request->get('tags',[]); $tags = explode(',',$tags); $entity->syncTags($tags); if (config('bap.demo')) { return false; } /** * Avatar upload */ $profilePicturePath = config('contacts.public_profile_picture_path'); $profilePicture = $request->file('profile_image'); // build SEO filename $filenameSeo=''; if ( config('bap.gravatar_seo') ) { if ( config('bap.gravatar_seo_contact_name') ) { $filenameSeo .= $entity->full_name; } if ( '' != config('bap.gravatar_seo_contact_keywords') ) { $filenameSeo .= "_". config('bap.gravatar_seo_contact_keywords'); } $filenameSeo = Str::slug($filenameSeo, '_'); $filenameSeo .= "_"; } if (config('bap.gravatar_local_cache') && !$entity->use_profile_image) { $fileName = 'contact_gravatar_' . $filenameSeo . md5('__'.$entity->id) . '_.png'; $size = config('bap.gravatar_display_size'); $image = md5(strtolower($entity->email)); $testUrl = "https://www.gravatar.com/avatar/" . $image . "?s=" . $size . "&d=404" . "&r=PG"; $validGravatar = false; if(@file_get_contents($testUrl) ){ $validGravatar = true; } $imageUrl = "https://www.gravatar.com/avatar/" . $image . "?s=" . $size . "&d=" . config('bap.gravatar_default_preview') . "&r=PG"; if ($validGravatar) { $content = file_get_contents($imageUrl); $uploadSuccess = Storage::disk('local')->put('tmp/' . $fileName,$content); if ($uploadSuccess) { Image::make(storage_path('app/tmp/'.$fileName))->save(base_path() . '/public/storage/' . $profilePicturePath . $fileName); $entity = $this->getRepository()->update([ 'profile_image' => $fileName ], $entity->id); } } } if ($profilePicture != null && $entity->use_profile_image) { $image = 'contact_picture_' . $filenameSeo . md5('__'.$entity->id) . '_.' . $profilePicture->getClientOriginalExtension(); $uploadSuccess = $profilePicture->move($profilePicturePath, $image); if ($uploadSuccess) { // Resize uploaded image to 200x200 $img = Image::make(base_path() . '/public/' . $profilePicturePath . $image)->resize( config('bap.gravatar_resize_width'), config('bap.gravatar_resize_height') ); $img->save(base_path() . '/public/storage/' . $profilePicturePath . $image); $entity = $this->getRepository()->update([ 'profile_image' => $image ], $entity->id); } } $this->handleCustomFileUploads($request, $entity); } public function allocateToUser(&$entity) { $nums = []; // handel numbers if($entity->phone != null){ $phone = $entity->phone; $phone = preg_replace('/\D/', '', $phone); if (preg_match('/^(?:\+?2|20|1)/', $phone)) { // Replace the matching part with 01 $phone = preg_replace('/^(?:\+?2|20|1)/', '', $phone); } $nums[] = $phone; } if($entity->mobile != null){ $mobile = $entity->mobile; $mobile = preg_replace('/\D/', '', $mobile); if (preg_match('/^(?:\+?2|20|1)/', $mobile)) { // Replace the matching part with 01 $mobile = preg_replace('/^(?:\+?2|20|1)/', '', $mobile); } $nums[] = $mobile; } if($entity->force_assigned){ if (!empty($nums)) { if ($entity->owned_by_type == 'Modules\Platform\User\Entities\Group' && $entity->owned_by_id != null){ $indoundRoutes = \DB::table('asterisk.incoming') ->whereIn('cidnum', $nums) ->pluck('cidnum') ->toArray(); \Log::debug(['indoundRoutes' => $indoundRoutes]); \Log::debug(['nums' => $nums]); $insertions = []; $insertions2 = []; foreach($nums as $num){ $data = [ 'cidnum' => $num, 'extension' => "0020221261716", 'destination' => 'ext-queues,'.$entity->owned_by_id.',1', 'privacyman' => '0', 'alertinfo' => '', 'ringing' => '', 'fanswer' => '', 'mohclass' => 'default', 'description' => 'Auto Direct To Queue', 'grppre' => '', 'delay_answer' => '0', 'pricid' => '', 'pmmaxretries' => '3', 'pmminlength' => '10', 'reversal' => '', 'rvolume' => '0', 'indication_zone' => 'default', ]; $data2 = [ 'extension' => "0020221261716", 'cidnum' => $num, 'scheme' => 'ALL|ALL', ]; if (in_array($num, $indoundRoutes)) { \DB::table('asterisk.incoming')->updateOrInsert( ['cidnum' => $data['cidnum']], // Match condition $data // Data to update ); \DB::table('asterisk.superfecta_to_incoming')->updateOrInsert( ['cidnum' => $data2['cidnum'], 'extension' => $data2['extension']], // Match condition $data2 // Data to update ); }else{ $insertions[] = $data; $insertions2[] = $data2; } } if(!empty($insertions)) { \DB::table('asterisk.incoming')->insert($insertions); \DB::table('asterisk.superfecta_to_incoming')->insert($insertions2); \Log::debug('allocate run'); } else{ \Log::debug('allocate run'); \Log::debug('no data'); } $process = new Process(['fwconsole','reload']); $process->run(); }else{ \DB::table('asterisk.incoming') ->whereIn('cidnum', $nums) ->delete(); \Log::debug('Rows deleted'); } } }else{ \DB::table('asterisk.incoming') ->whereIn('cidnum', $nums) ->delete(); \Log::debug('Rows deleted'); } } /** * After entity update * @param $request * @param $entity */ public function afterUpdate($request, &$entity = NULL) { /** * Avatar upload */ $this->afterStore($request, $entity); } protected function setupIndexTabButtons() { $this->indexTabButtons[] = array( 'href' => '#all', 'default' => true, 'attr' => [ 'class' => 'waves-effect waves-block', 'role' => 'tab', 'data-toggle'=>"tab", 'onClick' => "BAP_Datatable.headerFilterReset('dataTableBuilder')" ], 'label' => trans('core::core.header_all') ); $this->indexTabButtons[] = array( 'href' => '#assigned', 'attr' => [ 'class' => ' waves-effect waves-block', 'role' => 'tab', 'data-toggle'=>"tab", 'onClick' => "BAP_Datatable.headerFilterSet('assigned_to','dataTableBuilder',window.CURRENT_USER.name)" ], 'label' => trans('core::core.header_assigned') ); } /** * Prepare import - override to use dynamic field labels from CRM Settings. * * @param CsvImportRequest $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View */ protected function import(\Modules\Platform\Core\Http\Requests\CsvImportRequest $request) { try { if (\Auth::user()->hasPermissionTo($this->permissions['create'])) { $path = $request->file('csv_file'); $importConfig = ['delimiter' => $request->get('delimiter')]; $data = \Excel::toArray(new \Modules\Platform\Core\Helper\Excel\RecordImport($importConfig), $path); $data = $data[0]; if (count($data) > 0) { $view = view($this->views['import']); $csv_header_fields = []; foreach ($data[0] as $value) { $csv_header_fields[$value] = $value; } foreach ($data as &$row) { $row = array_combine($csv_header_fields, $row); } $view->with('csv_header', $csv_header_fields); $csvDataFile = \Modules\Platform\Core\Entities\CsvData::create([ 'csv_filename' => $request->file('csv_file')->getClientOriginalName(), 'csv_header' => 1, 'csv_data' => json_encode($data) ]); $csvData = array_slice($data, 0, 2); $moduleFields = \App::make($this->entityClass)->fillable; $moduleFields = \Modules\Platform\Core\Helper\CrudHelper::removeValues($moduleFields, [ 'id', 'company_id', 'full_name' ]); $view->with('csvDataFile', $csvDataFile); $view->with('module_fields', $moduleFields); $view->with('csv_data', $csvData); // Pass dynamic field labels from CRM Settings $labelMap = $this->contactFieldSettingsService->getFieldLabelMap(\Auth::user()); $view->with('fieldLabelMap', $labelMap); return $view; } else { flash(trans('core::core.empty_file'))->error(); return redirect()->back(); } } flash(trans('core::core.you_dont_have_access'))->error(); return redirect()->route($this->routes['index']); } catch (\Exception $exception) { flash(trans('core::core.invalid_file'))->error(); } } /** * Process import - override to use dynamic field definitions from CRM Settings. * * @param Request $request * @return \Illuminate\Http\RedirectResponse */ protected function importProcess(\Illuminate\Http\Request $request) { ini_set('max_execution_time', 0); $data = \Modules\Platform\Core\Entities\CsvData::find($request->get('file_id')); $repository = $this->getRepository(); if (!empty($data)) { $csvData = json_decode($data->csv_data, true); $imported = 0; $notImported = 0; $updated = 0; $errors = []; $requestFields = $request->get('fields'); $deduplicateColumn = $request->get('deduplicate_column'); $entityClass = \App::make($this->entityClass); $csvImporter = new \Modules\Platform\Core\Helper\CsvImporter(); $csvImporter->setEntity($entityClass); // Use dynamic show fields from CRM Settings $csvImporter->setFields($this->resolveShowFieldsForCurrentUser()); $csvImporter->setRelations(\Modules\Platform\Core\Helper\CrudHelper::relationships($entityClass)); $csvImporter->setRepo($repository); unset($csvData[0]); // remove header $csvImporter->preloadRelations($csvData, $requestFields); $batchRows = []; $upsertRows = []; $useTimestamps = method_exists($entityClass, 'usesTimestamps') && $entityClass->usesTimestamps(); $now = now(); foreach ($csvData as $rowKey => $row) { try { $fields = []; foreach ($requestFields as $key => $field) { $fields[$field] = $row[$key]; if ($field == 'owned_by_id') { $fields['owned_by_type'] = \Modules\Platform\User\Entities\User::class; } } $prepared = $csvImporter->prepareAttributes($fields); if ($useTimestamps) { if (!array_key_exists('created_at', $prepared)) { $prepared['created_at'] = $now; } $prepared['updated_at'] = $now; } if ($deduplicateColumn != '' && array_key_exists($deduplicateColumn, $prepared)) { $upsertRows[] = $prepared; } else { $batchRows[] = $prepared; if (count($batchRows) >= $this->importChunkSize) { \DB::table($entityClass->getTable())->insert($batchRows); $imported += count($batchRows); $batchRows = []; } } } catch (\Exception $exception) { $notImported++; \Log::error($exception); } } if (count($batchRows) > 0) { \DB::table($entityClass->getTable())->insert($batchRows); $imported += count($batchRows); } if ($deduplicateColumn != '' && count($upsertRows) > 0) { $dedupeValues = array_values(array_filter(array_column($upsertRows, $deduplicateColumn), function ($value) { return $value !== null && $value !== ''; })); $existingCount = 0; if (count($dedupeValues) > 0) { $existingCount = \App::make($this->entityClass)->whereIn($deduplicateColumn, array_unique($dedupeValues))->count(); } $updated += $existingCount; $imported += count($upsertRows) - $existingCount; $updateColumns = []; if (!empty($upsertRows)) { $updateColumns = array_diff(array_keys($upsertRows[0]), [$deduplicateColumn, 'id']); if ($useTimestamps && in_array('updated_at', array_keys($upsertRows[0]))) { $updateColumns = array_unique(array_merge($updateColumns, ['updated_at'])); } } foreach (array_chunk($upsertRows, $this->importChunkSize) as $chunk) { \DB::table($entityClass->getTable())->upsert($chunk, [$deduplicateColumn], $updateColumns); } } flash(trans('core::core.import_finished', ['imported' => $imported, 'not_imported' => $notImported, 'updated' => $updated]))->info(); return redirect()->route($this->routes['index']); } else { flash(trans('core::core.cannot_process_import'))->error(); return redirect()->route($this->routes['index']); } } }