diff --git a/README.md b/README.md index 40f76bf26..d1fc1f1d3 100644 --- a/README.md +++ b/README.md @@ -129,3 +129,7 @@ Krayin CRM is a fully open-source CRM framework which will always be free under ### Security Vulnerabilities Please don't disclose security vulnerabilities publicly. If you find any security vulnerability in Krayin CRM then please email us: sales@krayincrm.com. +``` +php artisan app:clear-all-cache +``` + diff --git a/app/Console/Commands/ClearAllCache.php b/app/Console/Commands/ClearAllCache.php new file mode 100644 index 000000000..6dc159c08 --- /dev/null +++ b/app/Console/Commands/ClearAllCache.php @@ -0,0 +1,45 @@ +info('Clearing all cache...'); + + Artisan::call('cache:clear'); + $this->info('Application cache cleared.'); + + Artisan::call('route:clear'); + $this->info('Route cache cleared.'); + + Artisan::call('config:clear'); + $this->info('Config cache cleared.'); + + Artisan::call('view:clear'); + $this->info('View cache cleared.'); + + $this->info('All caches cleared successfully.'); + } +} diff --git a/composer.json b/composer.json index 8ad16850f..9a0d2e1a8 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "diglactic/laravel-breadcrumbs": "^8.0", "doctrine/dbal": "^3.0", "guzzlehttp/guzzle": "^7.0.1", + "intervention/image": "^3.11", "khaled.alshamaa/ar-php": "^6.3", "konekt/concord": "^1.10", "laravel/framework": "^10.0", @@ -22,6 +23,8 @@ "maatwebsite/excel": "^3.1", "mpdf/mpdf": "^8.2", "prettus/l5-repository": "^2.7.9", + "setasign/fpdf": "^1.8", + "setasign/fpdi": "^2.6", "smalot/pdfparser": "^2.11", "webklex/laravel-imap": "^5.3" }, diff --git a/composer.lock b/composer.lock index ad1b9af0d..9f6e086dc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d2180cfea5efd3787ff96f24c0185624", + "content-hash": "1b2c256498f96e3b99231e663b6ceebf", "packages": [ { "name": "barryvdh/laravel-dompdf", @@ -1878,6 +1878,150 @@ ], "time": "2025-02-03T10:55:03+00:00" }, + { + "name": "intervention/gif", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/Intervention/gif.git", + "reference": "5999eac6a39aa760fb803bc809e8909ee67b451a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/gif/zipball/5999eac6a39aa760fb803bc809e8909ee67b451a", + "reference": "5999eac6a39aa760fb803bc809e8909ee67b451a", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Gif\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Native PHP GIF Encoder/Decoder", + "homepage": "https://github.com/intervention/gif", + "keywords": [ + "animation", + "gd", + "gif", + "image" + ], + "support": { + "issues": "https://github.com/Intervention/gif/issues", + "source": "https://github.com/Intervention/gif/tree/4.2.2" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-03-29T07:46:21+00:00" + }, + { + "name": "intervention/image", + "version": "3.11.3", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "d0f097b8a3fa8fb758efc9440b513aa3833cda17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/d0f097b8a3fa8fb758efc9440b513aa3833cda17", + "reference": "d0f097b8a3fa8fb758efc9440b513aa3833cda17", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "intervention/gif": "^4.2", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "ext-exif": "Recommended to be able to read EXIF data properly." + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "PHP image manipulation", + "homepage": "https://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "resize", + "thumbnail", + "watermark" + ], + "support": { + "issues": "https://github.com/Intervention/image/issues", + "source": "https://github.com/Intervention/image/tree/3.11.3" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-05-22T17:26:23+00:00" + }, { "name": "khaled.alshamaa/ar-php", "version": "v6.3.4", @@ -5350,6 +5494,52 @@ }, "time": "2024-10-27T17:38:32+00:00" }, + { + "name": "setasign/fpdf", + "version": "1.8.6", + "source": { + "type": "git", + "url": "https://github.com/Setasign/FPDF.git", + "reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Setasign/FPDF/zipball/0838e0ee4925716fcbbc50ad9e1799b5edfae0a0", + "reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "ext-zlib": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "fpdf.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Olivier Plathey", + "email": "oliver@fpdf.org", + "homepage": "http://fpdf.org/" + } + ], + "description": "FPDF is a PHP class which allows to generate PDF files with pure PHP. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.", + "homepage": "http://www.fpdf.org", + "keywords": [ + "fpdf", + "pdf" + ], + "support": { + "source": "https://github.com/Setasign/FPDF/tree/1.8.6" + }, + "time": "2023-06-26T14:44:25+00:00" + }, { "name": "setasign/fpdi", "version": "v2.6.3", diff --git a/database/migrations/2025_05_03_111731_add_issue_and_expiry_date_to_files_table.php b/database/migrations/2025_05_03_111731_add_issue_and_expiry_date_to_files_table.php new file mode 100644 index 000000000..3852a7819 --- /dev/null +++ b/database/migrations/2025_05_03_111731_add_issue_and_expiry_date_to_files_table.php @@ -0,0 +1,29 @@ +date('issue_date')->nullable(); + $table->date('expiry_date')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('activity_files', function (Blueprint $table) { + $table->dropColumn(['issue_date', 'expiry_date']); + }); + } +}; diff --git a/database/migrations/2025_06_06_130944_create_role_field_permissions_table.php b/database/migrations/2025_06_06_130944_create_role_field_permissions_table.php new file mode 100644 index 000000000..945904796 --- /dev/null +++ b/database/migrations/2025_06_06_130944_create_role_field_permissions_table.php @@ -0,0 +1,28 @@ +json('visible_person_fields')->nullable()->after('name'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('roles', function (Blueprint $table) { + $table->dropColumn('visible_person_fields'); + }); + } +}; diff --git a/database/migrations/2025_06_28_212411_create_contacts_table.php b/database/migrations/2025_06_28_212411_create_contacts_table.php new file mode 100644 index 000000000..6463ccd8c --- /dev/null +++ b/database/migrations/2025_06_28_212411_create_contacts_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('name'); + $table->string('type'); + $table->json('mobile_numbers')->nullable(); + $table->json('emails')->nullable(); + $table->date('eid_expiry')->nullable(); + $table->unsignedBigInteger('person_id'); + $table->timestamps(); + + $table->foreign('person_id')->references('id')->on('persons')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('related_contacts'); + } +}; diff --git a/database/migrations/2025_06_29_110355_create_related_contacts_table.php b/database/migrations/2025_06_29_110355_create_related_contacts_table.php new file mode 100644 index 000000000..227696551 --- /dev/null +++ b/database/migrations/2025_06_29_110355_create_related_contacts_table.php @@ -0,0 +1,27 @@ +id(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('related_contacts'); + } +}; diff --git a/database/migrations/2025_07_09_121717_create_related_contact_repositories_table.php b/database/migrations/2025_07_09_121717_create_related_contact_repositories_table.php new file mode 100644 index 000000000..108258592 --- /dev/null +++ b/database/migrations/2025_07_09_121717_create_related_contact_repositories_table.php @@ -0,0 +1,31 @@ +increments('id'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('related_contact_repositories'); + } +}; diff --git a/database/migrations/2025_07_12_151903_make_person_id_nullable_in_related_contacts_table.php b/database/migrations/2025_07_12_151903_make_person_id_nullable_in_related_contacts_table.php new file mode 100644 index 000000000..0810889bd --- /dev/null +++ b/database/migrations/2025_07_12_151903_make_person_id_nullable_in_related_contacts_table.php @@ -0,0 +1,28 @@ +unsignedBigInteger('person_id')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('related_contacts', function (Blueprint $table) { + $table->unsignedBigInteger('person_id')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2025_07_25_111556_add_entityt_id_to_files_table.php b/database/migrations/2025_07_25_111556_add_entityt_id_to_files_table.php new file mode 100644 index 000000000..7c0cd4c68 --- /dev/null +++ b/database/migrations/2025_07_25_111556_add_entityt_id_to_files_table.php @@ -0,0 +1,29 @@ +string('file_code')->nullable()->after('id'); + $table->unsignedBigInteger('entity_id')->nullable()->after('file_code'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('files', function (Blueprint $table) { + $table->dropColumn(['file_code', 'entity_id']); + }); + } +}; diff --git a/packages/Webkul/Activity/src/Models/File.php b/packages/Webkul/Activity/src/Models/File.php index efbf90c5b..e17c0c2c3 100644 --- a/packages/Webkul/Activity/src/Models/File.php +++ b/packages/Webkul/Activity/src/Models/File.php @@ -31,6 +31,10 @@ class File extends Model implements FileContract 'name', 'path', 'activity_id', + 'issue_date', + 'expiry_date', + 'file_code', + 'entity_id', ]; /** diff --git a/packages/Webkul/Activity/src/Repositories/ActivityRepository.php b/packages/Webkul/Activity/src/Repositories/ActivityRepository.php index 3b4d6a4f8..c0271375e 100755 --- a/packages/Webkul/Activity/src/Repositories/ActivityRepository.php +++ b/packages/Webkul/Activity/src/Repositories/ActivityRepository.php @@ -14,8 +14,9 @@ class ActivityRepository extends Repository */ public function __construct( protected FileRepository $fileRepository, - Container $container - ) { + Container $container + ) + { parent::__construct($container); } @@ -40,13 +41,17 @@ public function create(array $data) if (isset($data['file'])) { $this->fileRepository->create([ - 'name' => $data['name'] ?? $data['file']->getClientOriginalName(), - 'path' => $data['file']->store('activities/'.$activity->id), + 'file_code' => $data['file_code'] ?? null, + 'entity_id' => $data['entity_id'] ?? null, + 'issue_date' => $data['issue_date'] ?? null, + 'expiry_date' => $data['expiry_date'] ?? null, + 'name' => $data['name'] ?? $data['file']->getClientOriginalName(), + 'path' => $data['file']->store('activities/' . $activity->id), 'activity_id' => $activity->id, ]); } - if (! isset($data['participants'])) { + if (!isset($data['participants'])) { return $activity; } @@ -68,8 +73,8 @@ public function create(array $data) /** * Update pipeline. * - * @param int $id - * @param string $attribute + * @param int $id + * @param string $attribute * @return \Webkul\Activity\Contracts\Activity */ public function update(array $data, $id, $attribute = 'id') @@ -114,7 +119,7 @@ public function update(array $data, $id, $attribute = 'id') } /** - * @param string $dateRange + * @param string $dateRange * @return mixed */ public function getActivities($dateRange) @@ -143,10 +148,10 @@ public function getActivities($dateRange) } /** - * @param string $startFrom - * @param string $endFrom - * @param array $participants - * @param int $id + * @param string $startFrom + * @param string $endFrom + * @param array $participants + * @param int $id * @return bool */ public function isDurationOverlapping($startFrom, $endFrom, $participants, $id) @@ -176,7 +181,7 @@ public function isDurationOverlapping($startFrom, $endFrom, $participants, $id) }) ->groupBy('activities.id'); - if (! is_null($id)) { + if (!is_null($id)) { $queryBuilder->where('activities.id', '!=', $id); } diff --git a/packages/Webkul/Admin/src/Config/acl.php b/packages/Webkul/Admin/src/Config/acl.php index bb164d2b8..16e677f37 100644 --- a/packages/Webkul/Admin/src/Config/acl.php +++ b/packages/Webkul/Admin/src/Config/acl.php @@ -156,6 +156,36 @@ 'name' => 'admin::app.acl.view', 'route' => 'admin.contacts.persons.view', 'sort' => 5, + ],[ + 'key' => 'contacts.relatedContact', + 'name' => 'admin::app.acl.relatedContact', + 'route' => 'admin.contacts.related-contacts.index', + 'sort' => 6, + ], [ + 'key' => 'contacts.relatedContact.create', + 'name' => 'admin::app.acl.create', + 'route' => ['admin.contacts.related-contacts.create', 'admin.contacts.related-contacts.store'], + 'sort' => 7, + ], [ + 'key' => 'contacts.relatedContact.edit', + 'name' => 'admin::app.acl.edit', + 'route' => ['admin.contacts.related-contacts.edit', 'admin.contacts.related-contacts.update'], + 'sort' => 8, + ], [ + 'key' => 'contacts.relatedContact.delete', + 'name' => 'admin::app.acl.delete', + 'route' => ['admin.contacts.related-contacts.delete', 'admin.contacts.related-contacts.mass_delete'], + 'sort' => 9, + ], [ + 'key' => 'contacts.relatedContact.view', + 'name' => 'admin::app.acl.view', + 'route' => 'admin.contacts.persons.view', + 'sort' => 10, + ], [ + 'key' => 'contacts.persons.export', + 'name' => 'admin::app.acl.export', + 'route' => 'admin.contacts.persons.export', + 'sort' => 11, ], [ 'key' => 'contacts.organizations', 'name' => 'admin::app.acl.organizations', diff --git a/packages/Webkul/Admin/src/Config/core_config.php b/packages/Webkul/Admin/src/Config/core_config.php index 9c843daec..6829a9cdc 100644 --- a/packages/Webkul/Admin/src/Config/core_config.php +++ b/packages/Webkul/Admin/src/Config/core_config.php @@ -138,7 +138,7 @@ 'name' => 'contacts.persons', 'title' => 'admin::app.configuration.index.general.settings.menu.persons', 'type' => 'text', - 'default' => 'Persons', + 'default' => 'Companies', 'validation' => 'max:20', ], [ 'name' => 'contacts.organizations', diff --git a/packages/Webkul/Admin/src/Config/menu.php b/packages/Webkul/Admin/src/Config/menu.php index cab5a37e8..070361143 100644 --- a/packages/Webkul/Admin/src/Config/menu.php +++ b/packages/Webkul/Admin/src/Config/menu.php @@ -108,17 +108,24 @@ 'route' => 'admin.contacts.persons.index', 'sort' => 6, 'icon-class' => 'icon-contact', + ], [ + 'key' => 'contacts.relatedContact', + 'name' => 'admin::app.layouts.relatedContact', + 'route' => 'admin.contacts.related-contacts.index', + 'sort' => 1, + 'icon-class' => '', ], [ 'key' => 'contacts.persons', 'name' => 'admin::app.layouts.persons', 'route' => 'admin.contacts.persons.index', - 'sort' => 1, + 'sort' => 2, 'icon-class' => '', - ], [ + ], + [ 'key' => 'contacts.organizations', 'name' => 'admin::app.layouts.organizations', 'route' => 'admin.contacts.organizations.index', - 'sort' => 2, + 'sort' => 3, 'icon-class' => '', ], diff --git a/packages/Webkul/Admin/src/DataGrids/Contact/PersonDataGrid.php b/packages/Webkul/Admin/src/DataGrids/Contact/PersonDataGrid.php index 3ddf66c16..2a35d78c0 100644 --- a/packages/Webkul/Admin/src/DataGrids/Contact/PersonDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/Contact/PersonDataGrid.php @@ -4,6 +4,7 @@ use Illuminate\Database\Query\Builder; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Webkul\Contact\Repositories\OrganizationRepository; use Webkul\DataGrid\DataGrid; @@ -22,27 +23,106 @@ public function __construct(protected OrganizationRepository $organizationReposi public function prepareQueryBuilder(): Builder { $queryBuilder = DB::table('persons') + ->distinct() ->addSelect( - 'persons.id', - 'persons.name as person_name', + 'persons.crm as id', + 'persons.id as person_id', + DB::raw("CASE WHEN related_contacts.type = 'Manager' THEN related_contacts.name ELSE NULL END as person_name"), + 'related_contacts.name as person_name', + // 'related_contacts.name as manager_name', 'persons.emails', 'persons.contact_numbers', 'organizations.name as organization', 'organizations.id as organization_id' ) - ->leftJoin('organizations', 'persons.organization_id', '=', 'organizations.id'); + ->leftJoin('organizations', 'persons.organization_id', '=', 'organizations.id') + ->leftJoin('related_contacts', 'related_contacts.person_id', '=', 'persons.id') + ->leftJoin('attribute_values', function ($join) { + $join->on('attribute_values.entity_id', '=', 'persons.id') + ->where('attribute_values.entity_type', '=', 'persons'); + }); + if ($userIds = bouncer()->getAuthorizedUserIds()) { $queryBuilder->whereIn('persons.user_id', $userIds); } + if (isset(request()->input('filters')['crm_code'][0])) { + // dd(request()->input('filters')); + $crm_code = request()->input('filters')['crm_code'][0]; + $filters = request()->input('filters', []); + if (isset($filters['crm_code'])) { + unset($filters['crm_code']); + $filters['all']=['']; + } + request()->merge([ + 'filters' => $filters + ]); + + if (intval($crm_code)>0){ + + $queryBuilder + ->where('attribute_values.text_value','=', $crm_code) + ->where('attribute_values.attribute_id','=', 74); + + + } + + } + + if (isset(request()->input('filters')['all'][0])) { + $term = request()->input('filters')['all'][0]; + + if (!empty($term)) { + [$persian, $arabic] = $this->normalizeSearchVariants($term); + + $queryBuilder->whereExists(function ($query) use ($persian, $arabic) { + $query->select(DB::raw(1)) + ->from('related_contacts') + ->whereColumn('related_contacts.person_id', 'persons.id') + ->where(function ($q) use ($persian, $arabic) { + $q->where('related_contacts.name', 'like', "%{$persian}%") + ->orWhere('related_contacts.name', 'like', "%{$arabic}%") + ->orWhere('related_contacts.mobile_numbers', 'like', "%{$persian}%") + ->orWhere('related_contacts.mobile_numbers', 'like', "%{$arabic}%") + ->orWhere('related_contacts.emails', 'like', "%{$persian}%") + ->orWhere('related_contacts.emails', 'like', "%{$arabic}%") + ->orWhere('attribute_values.text_value', 'like', "%{$persian}%") + ->orWhere('attribute_values.text_value', 'like', "%{$arabic}%"); + }); + }); + } + } + $this->addFilter('id', 'persons.id'); + $this->addFilter('emails', 'persons.emails'); $this->addFilter('person_name', 'persons.name'); $this->addFilter('organization', 'organizations.name'); + // dd($queryBuilder); + + Log::info( + vsprintf(str_replace('?', "'%s'", $queryBuilder->toSql()), $queryBuilder->getBindings()) + ); + // dd($queryBuilder->get()); + return $queryBuilder; } + + protected function normalizeSearchVariants($string): array + { + $normalized = trim($string); + + // Arabic → Persian + $persian = str_replace(['ي', 'ك'], ['ی', 'ک'], $normalized); + + // Persian → Arabic + $arabic = str_replace(['ی', 'ک'], ['ي', 'ك'], $normalized); + + return [$persian, $arabic]; + } + /** * Add columns. */ @@ -50,13 +130,14 @@ public function prepareColumns(): void { $this->addColumn([ 'index' => 'id', - 'label' => trans('admin::app.contacts.persons.index.datagrid.id'), + 'label' => "CRM CODE", 'type' => 'integer', 'filterable' => true, 'sortable' => true, 'searchable' => true, ]); + $this->addColumn([ 'index' => 'person_name', 'label' => trans('admin::app.contacts.persons.index.datagrid.name'), @@ -66,6 +147,7 @@ public function prepareColumns(): void 'searchable' => true, ]); + $this->addColumn([ 'index' => 'emails', 'label' => trans('admin::app.contacts.persons.index.datagrid.emails'), diff --git a/packages/Webkul/Admin/src/DataGrids/Contact/RelatedContactDataGrid.php b/packages/Webkul/Admin/src/DataGrids/Contact/RelatedContactDataGrid.php new file mode 100644 index 000000000..30ca8c01a --- /dev/null +++ b/packages/Webkul/Admin/src/DataGrids/Contact/RelatedContactDataGrid.php @@ -0,0 +1,149 @@ +select('id', 'name','type', 'emails', 'mobile_numbers', 'eid_expiry') + ->whereNotNull(['name']) + ->whereNot('name','=',''); + + $this->addFilter('id', 'related_contacts.id'); + $this->addFilter('name', 'related_contacts.name'); + + $this->setQueryBuilder($queryBuilder); + + return $queryBuilder; + } + + /** + * Add columns. + */ + public function prepareColumns(): void + { + $this->addColumn([ + 'index' => 'id', + 'label' => "ID", + 'type' => 'integer', + 'filterable' => true, + 'sortable' => true, + 'searchable' => true, + ]); + + $this->addColumn([ + 'index' => 'name', + 'label' => "Name", + 'type' => 'string', + 'sortable' => true, + 'filterable' => true, + 'searchable' => true, + ]); + + $this->addColumn([ + 'index' => 'type', + 'label' => "Type", + 'type' => 'string', + 'sortable' => true, + 'filterable' => true, + 'searchable' => true, + ]); + + $this->addColumn([ + 'index' => 'emails', + 'label' => "Emails", + 'type' => 'string', + 'sortable' => false, + 'filterable' => true, + 'searchable' => true, + 'closure' => fn($row) => collect(json_decode(json_decode($row->emails, true) ?? '[]'))->join(', '), + ]); + + $this->addColumn([ + 'index' => 'mobile_numbers', + 'label' => "Contact Numbers", + 'type' => 'string', + 'sortable' => true, + 'filterable' => true, + 'searchable' => true, + 'closure' => fn($row) => collect(json_decode(json_decode($row->mobile_numbers, true) ?? '[]'))->join(', '), + + ]); + + } + + /** + * Prepare actions. + */ + public function prepareActions(): void + { + + // if (bouncer()->hasPermission('contacts.relatedContact.view')) { + $this->addAction([ + 'icon' => 'icon-eye', + 'title' => trans('admin::app.contacts.relatedContact.index.datagrid.view'), + 'method' => 'GET', + 'url' => function ($row) { + return route('admin.contacts.related-contacts.view', $row->id); + }, + ]); + // } + + // if (bouncer()->hasPermission('contacts.relatedContact.edit')) { + $this->addAction([ + 'icon' => 'icon-edit', + 'title' => trans('admin::app.contacts.persons.index.datagrid.edit'), + 'method' => 'GET', + 'url' => function ($row) { + return route('admin.contacts.related-contacts.edit', $row->id); + }, + ]); + // } + + // if (bouncer()->hasPermission('contacts.relatedContact.delete')) { + $this->addAction([ + 'icon' => 'icon-delete', + 'title' => trans('admin::app.contacts.persons.index.datagrid.delete'), + 'method' => 'DELETE', + 'url' => function ($row) { + return route('admin.contacts.related-contacts.delete', $row->id); + }, + ]); + // } + + } + + /** + * Prepare mass actions. + */ + public function prepareMassActions(): void + { + /* + if (bouncer()->hasPermission('contacts.persons.delete')) { + $this->addMassAction([ + 'icon' => 'icon-delete', + 'title' => trans('admin::app.contacts.persons.index.datagrid.delete'), + 'method' => 'POST', + 'url' => route('admin.contacts.persons.mass_delete'), + ]); + } + */ + } +} diff --git a/packages/Webkul/Admin/src/DataGrids/Settings/AttributeDataGrid.php b/packages/Webkul/Admin/src/DataGrids/Settings/AttributeDataGrid.php index bbbeeb9cd..c07ed3d60 100644 --- a/packages/Webkul/Admin/src/DataGrids/Settings/AttributeDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/Settings/AttributeDataGrid.php @@ -28,6 +28,7 @@ public function prepareQueryBuilder(): Builder $this->addFilter('id', 'attributes.id'); $this->addFilter('type', 'attributes.type'); $this->addFilter('attribute_type', 'attributes.is_user_defined'); + $queryBuilder->orderBy('attributes.sort_order', 'asc'); return $queryBuilder; } diff --git a/packages/Webkul/Admin/src/Http/Controllers/Activity/ActivityController.php b/packages/Webkul/Admin/src/Http/Controllers/Activity/ActivityController.php index 02a7369fa..016ff2ff9 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Activity/ActivityController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Activity/ActivityController.php @@ -17,7 +17,10 @@ use Webkul\Admin\Http\Requests\MassUpdateRequest; use Webkul\Admin\Http\Resources\ActivityResource; use Webkul\Attribute\Repositories\AttributeRepository; - +use Intervention\Image\ImageManager; +use Intervention\Image\Drivers\Gd\Driver; +use function Laravel\Prompts\error; +use setasign\Fpdi\Fpdi; class ActivityController extends Controller { /** @@ -203,12 +206,177 @@ public function download(int $id): StreamedResponse try { $file = $this->fileRepository->findOrFail($id); + if (!empty($file->file_code)){ + abort(404); + } + $extension = pathinfo($file->path, PATHINFO_EXTENSION); + + if (!empty($file->name)) { + $customName = $file->name . '_' . $file->activity->title . '.' . $extension; + return Storage::download($file->path, $customName); + } + return Storage::download($file->path); } catch (\Exception $exception) { abort(404); } } + + public function preview(int $id): StreamedResponse + { + try { + $file = $this->fileRepository->findOrFail($id); + $path = $file->path; + $mimeType = Storage::mimeType($path); + + + + if (str_starts_with($mimeType, 'image/')) { + return response()->stream(function () use ($file) { + // Get the image content from storage + $imageData = Storage::get($file->path); + $manager = new ImageManager(new Driver()); + + // Load main image and watermark + $image = $manager->read($imageData); + $watermark = $manager->read(public_path('images/watermark.png')); + + $imgWidth = $image->width(); + $imgHeight = $image->height(); + $wmWidth = $watermark->width(); + $wmHeight = $watermark->height(); + + $spacingX = 120; // spacing between watermark X + $spacingY = 120; // spacing between watermark Y + + for ($y = 0; $y < $imgHeight; $y += $wmHeight + $spacingY) { + for ($x = 0; $x < $imgWidth; $x += $wmWidth + $spacingX) { + $image->place($watermark, 'top-left', $x, $y, 40); + } + } + + + // Insert watermark at bottom-right corner with 10px offset + + // Output the image directly to the browser + echo $image->encode(); + }, 200, [ + 'Content-Type' => $mimeType, + 'Content-Disposition' => 'inline; filename="' . basename($file->path) . '"', + ]); + }; + +// if ($mimeType === 'application/pdf') { +// return response()->stream(function () use ($path) { +// $stream = Storage::readStream($path); +// fpassthru($stream); +// fclose($stream); +// }, 200, [ +// 'Content-Type' => $mimeType, +// 'Content-Disposition' => 'inline; filename="' . basename($path) . '"', +// ]); +// } + + if ($mimeType === 'application/pdf') { + + $pdf = new Fpdi(); + try { + + $absolutePath = public_path('storage/' . $path); + + $pageCount = $pdf->setSourceFile($absolutePath); + }catch (\Exception $e){ + dd($e); + } + + + + + for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) { + $templateId = $pdf->importPage($pageNo); + $size = $pdf->getTemplateSize($templateId); + + $pdf->AddPage($size['orientation'], [$size['width'], $size['height']]); + $pdf->useTemplate($templateId); + + // بارگذاری تصویر واترمارک + $watermarkPath = public_path('images/watermark-pdf.png'); + + // اندازه واترمارک (می‌توانید برحسب نیاز تغییر دهید) + $wmWidth = 50; // عرض واترمارک بر حسب واحد PDF (نقطه یا میلیمتر) + $wmHeight = 70; // ارتفاع واترمارک + + // فاصله بین هر واترمارک در محور X و Y + $spacingX = 10; + $spacingY = 5; + + // ابعاد صفحه + $pageWidth = $size['width']; + $pageHeight = $size['height']; + + // حلقه برای تکرار واترمارک افقی و عمودی + for ($y = 0; $y < $pageHeight; $y += $wmHeight + $spacingY) { + for ($x = 0; $x < $pageWidth; $x += $wmWidth + $spacingX) { + $pdf->Image( + $watermarkPath, // مسیر تصویر + $x, // موقعیت X + $y, // موقعیت Y + $wmWidth, // عرض + $wmHeight, // ارتفاع + 'PNG', + '', + '', + false, + 300, + '', + false, + false, + 0, + 0, + false, + true + ); + } + } + } + + // ذخیره فایل خروجی + return response()->stream(function () use ($pdf) { + + $pdfContent = $pdf->Output('S'); + echo $pdfContent; + }, 200, [ + 'Content-Type' => 'application/pdf', + 'Content-Disposition' => 'inline; filename="watermarked.pdf"', + ]); + } + + // Unsupported file type + abort(415, 'Unsupported media type.'); + } catch (\Exception $e) { + abort(404); + } + } + + public function previewOld(int $id): StreamedResponse + { + try { + $file = $this->fileRepository->findOrFail($id); + + $mimeType = Storage::mimeType($file->path); + + return response()->stream(function () use ($file) { + echo Storage::get($file->path); + }, 200, [ + 'Content-Type' => $mimeType, + 'Content-Disposition' => 'inline; filename="' . basename($file->path) . '"', + ]); + } catch (\Exception $e) { + abort(404); + } + } + /* * Remove the specified resource from storage. */ diff --git a/packages/Webkul/Admin/src/Http/Controllers/Contact/Persons/PersonController.php b/packages/Webkul/Admin/src/Http/Controllers/Contact/Persons/PersonController.php index 9ad1d4e3e..c95e07dbf 100644 --- a/packages/Webkul/Admin/src/Http/Controllers/Contact/Persons/PersonController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Contact/Persons/PersonController.php @@ -5,6 +5,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; use Illuminate\View\View; use Prettus\Repository\Criteria\RequestCriteria; @@ -13,6 +14,7 @@ use Webkul\Admin\Http\Requests\AttributeForm; use Webkul\Admin\Http\Requests\MassDestroyRequest; use Webkul\Admin\Http\Resources\PersonResource; +use Webkul\Contact\Models\RelatedContact; use Webkul\Contact\Repositories\PersonRepository; class PersonController extends Controller @@ -33,12 +35,40 @@ public function __construct(protected PersonRepository $personRepository) public function index() { if (request()->ajax()) { + return datagrid(PersonDataGrid::class)->process(); } return view('admin::contacts.persons.index'); } + public function nextCrmCode($return_number=false){ + +// $maxId = DB::table('persons')->max('id') ?? 0; +// return response()->json(['next_crm_code' => $maxId + 1]); + + $nextCrm = DB::selectOne(" + SELECT + COALESCE( + ( + SELECT MIN(p1.crm + 1) + FROM persons p1 + LEFT JOIN persons p2 + ON p2.crm = p1.crm + 1 + WHERE p2.crm IS NULL + AND p1.crm >= 1 + ), + COALESCE((SELECT MAX(crm) + 1 FROM persons), 1) + ) AS next_crm +"); + +// Access the value: + $maxId = $nextCrm->next_crm; + if ($return_number) { + return $maxId; + } + return response()->json(['next_crm_code' => $maxId ]); + } /** * Show the form for creating a new resource. */ @@ -52,12 +82,94 @@ public function create(): View */ public function store(AttributeForm $request): RedirectResponse|JsonResponse { + + $data = $request->all(); + $relatedContacts=[]; + if ($request->has('related_contacts')) { + $relatedContacts = $request->input('related_contacts'); + + // Remove 'related_contacts' from the request instance + $request->request->remove('related_contacts'); + + // Now $relatedContacts holds the data, and it's no longer in $request + // dd($relatedContacts); + + + foreach ($relatedContacts as $index =>$relatedContact) { + if($request->has("mobile_number_$index")){ + if ($request->get("mobile_number_$index") !=="+971"){ + + $mobile_numbers = $this->ensureJsonArr($relatedContact['mobile_numbers']); + + $mobile_numbers[]=$request->get("mobile_number_$index"); + + $relatedContacts[$index]['mobile_numbers']=json_encode($mobile_numbers,true); + + unset($data["mobile_number_$index"]); + } + } + if($request->has("email_$index")){ + if (!empty($request->get("email_$index") )){ + + $emails = $this->ensureJsonArr($relatedContact['emails']); + + $emails[]=$request->get("email_$index"); + + $relatedContacts[$index]['emails']=json_encode($emails,true); + + + unset($data["email_$index"]); + } + } + + + } + } + Event::dispatch('contacts.person.create.before'); - $person = $this->personRepository->create($request->all()); + $person = $this->personRepository->create($data); + + if (empty($request->get('crm'))) { + $crm_code = $this->nextCrmCode(true); + + }else{ + $crm_code =$request->get('crm'); + } + $person->crm = $crm_code; + $person->save(); Event::dispatch('contacts.person.create.after', $person); + + foreach ($relatedContacts as $index => $contactData) { + if (!empty($contactData['id'])) { + // Update existing + $existingContact = RelatedContact::find($contactData['id']); + if ($existingContact) { + $existingContact->update([ + 'name' => $contactData['name'], + 'person_id' => $person->id, + 'type' => $contactData['type'], + 'eid_expiry' => $contactData['eid_expiry'], + 'mobile_numbers' => $contactData['mobile_numbers'], + 'emails' => $contactData['emails'], + ]); + } + } else { + // Create new + RelatedContact::create([ + 'name' => $contactData['name'], + 'person_id' => $person->id, + 'type' => $contactData['type'], + 'eid_expiry' => $contactData['eid_expiry'], + 'mobile_numbers' => $contactData['mobile_numbers'], + 'emails' => $contactData['emails'], + ]); + } + } + + if (request()->ajax()) { return response()->json([ 'data' => $person, @@ -75,9 +187,25 @@ public function store(AttributeForm $request): RedirectResponse|JsonResponse */ public function show(int $id): View { - $person = $this->personRepository->findOrFail($id); - return view('admin::contacts.persons.view', compact('person')); +// $person = $this->personRepository->findOrFail($id); + $person = $this->personRepository->where('crm','=',$id)->first(); + + $user = auth()->user(); + $allowedFields = $user->role->visible_person_fields ?? []; + + // Always include 'id' for routing/model logic + if (!in_array('id', $allowedFields)) { + $allowedFields[] = 'id'; + } + + // $person = $this->personRepository->getModel()->select($allowedFields)->findOrFail($id); + + + + return view('admin::contacts.persons.view', [ + 'person' => (object) $person, + ]); } /** @@ -85,20 +213,92 @@ public function show(int $id): View */ public function edit(int $id): View { - $person = $this->personRepository->findOrFail($id); + +// $person = $this->personRepository->findOrFail($id); + $person = $this->personRepository->where('crm','=',$id)->first(); return view('admin::contacts.persons.edit', compact('person')); } + private function ensureJsonArr($input) { + // If input is already an array or object, return as is + if (is_array($input) || is_object($input)) { + return $input; + } + + // If input is a string, check if it's valid JSON + if (is_string($input)) { + $decoded = json_decode($input, true); + if (json_last_error() === JSON_ERROR_NONE) { + // Valid JSON string, return decoded array/object + return $decoded; + } else { + // Not valid JSON, treat as plain string: wrap in array + return []; + } + } + + // For anything else, return as is (or you can customize) + return []; + } + /** * Update the specified resource in storage. */ public function update(AttributeForm $request, int $id): RedirectResponse|JsonResponse { - Event::dispatch('contacts.person.update.before', $id); - $person = $this->personRepository->update($request->all(), $id); + $data= $request->all(); + $relatedContacts=$request->related_contacts; + + foreach ($relatedContacts as $index =>$relatedContact) { + if($request->has("mobile_number_$index")){ + if ($request->get("mobile_number_$index") !=="+971"){ + + $mobile_numbers = $this->ensureJsonArr($relatedContact['mobile_numbers']); + + $mobile_numbers[]=$request->get("mobile_number_$index"); + + $rc = RelatedContact::findorfail($relatedContact['id']); + $rc->mobile_numbers=json_encode($mobile_numbers,true); + $rc->save(); + + unset($data["mobile_number_$index"]); + } + } + if($request->has("email_$index")){ + if (!empty($request->get("email_$index") )){ + + $emails = $this->ensureJsonArr($relatedContact['emails']); + + $emails[]=$request->get("email_$index"); + + $rc = RelatedContact::findorfail($relatedContact['id']); + $rc->emails=json_encode($emails,true); + $rc->save(); + + unset($data["email_$index"]); + } + } + + + } + $person = $this->personRepository->where('crm','=',$id)->first(); + + Event::dispatch('contacts.person.update.before', $person->id); + + + //$person = $this->personRepository->update($data, $id); + $person = $this->personRepository->update($data,$person->id); + if (empty($request->get('crm'))) { + $crm_code = $this->nextCrmCode(true); + + }else{ + $crm_code =$request->get('crm'); + } + $person->crm = $crm_code; + $person->save(); Event::dispatch('contacts.person.update.after', $person); if (request()->ajax()) { @@ -136,14 +336,15 @@ public function search(): JsonResource */ public function destroy(int $id): JsonResponse { - $person = $this->personRepository->findOrFail($id); + //$person = $this->personRepository->findOrFail($id); + $person = $this->personRepository->where('crm','=',$id)->first(); try { - Event::dispatch('contacts.person.delete.before', $id); + Event::dispatch('contacts.person.delete.before', $person->id); - $person->delete($id); + $person->delete($person->id); - Event::dispatch('contacts.person.delete.after', $id); + Event::dispatch('contacts.person.delete.after', $person->id); return response()->json([ 'message' => trans('admin::app.contacts.persons.index.delete-success'), diff --git a/packages/Webkul/Admin/src/Http/Controllers/Contact/Related/RelatedContactController.php b/packages/Webkul/Admin/src/Http/Controllers/Contact/Related/RelatedContactController.php new file mode 100644 index 000000000..ab9de9992 --- /dev/null +++ b/packages/Webkul/Admin/src/Http/Controllers/Contact/Related/RelatedContactController.php @@ -0,0 +1,172 @@ +request->add(['entity_type' => 'relatedContact']); + } + public function index() + { + if (request()->ajax()) { + return datagrid(RelatedContactDataGrid::class)->process(); + } + return view('admin::contacts.related.index'); + + } + private function ensureJsonArr($input) { + // If input is already an array or object, return as is + if (is_array($input) || is_object($input)) { + return $input; + } + + // If input is a string, check if it's valid JSON + if (is_string($input)) { + $decoded = json_decode($input, true); + if (json_last_error() === JSON_ERROR_NONE) { + // Valid JSON string, return decoded array/object + return $decoded; + } else { + // Not valid JSON, treat as plain string: wrap in array + return []; + } + } + + // For anything else, return as is (or you can customize) + return []; + } + + public function store(Request $request) + { + $redirect = $request->boolean('redirect'); + + if(!empty($request->mobile_number) && empty($request->mobile_numbers)){ + $request->mobile_numbers=[$request->mobile_number]; + } + + if(!empty($request->email) && empty($request->emails)){ + $request->emails=[$request->email]; + } + + $mobile_numbers =$this->ensureJsonArr($request->mobile_numbers); + $emails =$this->ensureJsonArr($request->emails); + + + + + $relatedContact = RelatedContact::create([ + 'person_id' => $request->person_id, + 'name' => $request->name, + 'type' => $request->type ?? null, + 'eid_expiry' =>$request->eid_expiry ?? null, + 'mobile_numbers' => json_encode($mobile_numbers), + 'emails' => json_encode($emails), + ]); + + if ($redirect) { + return redirect()->route('admin.contacts.related-contacts.index') + ->with('success', 'Related contact created successfully.'); + } + + return response()->json([ + 'message' => 'Related contact created successfully.', + 'relatedContact' => $relatedContact, + ]); + } + + public function update(Request $request, RelatedContact $relatedContact) + { + $redirect = $request->boolean('redirect'); + + $validated = $request->validate([ + 'name' => 'required|string|max:255', + 'type' => 'string', + ]); + + if( !empty($request->mobile_number) && $request->mobile_number !=="+971" && (empty($request->mobile_numbers) || $request->mobile_numbers="[]")){ + $request->mobile_numbers=[$request->mobile_number]; + } + + if(!empty($request->email) && ( empty($request->emails) || $request->emails="[]")){ + $request->emails=[$request->email]; + } + + $mobile_numbers =$this->ensureJsonArr($request->mobile_numbers); + $emails =$this->ensureJsonArr($request->emails); + + + $relatedContact->update([ + 'name' => $validated['name'], + 'type' => $validated['type'] ?? null, + 'eid_expiry' => $request->eid_expiry ?? null, + 'mobile_numbers' => json_encode($mobile_numbers ?? []), + 'emails' => json_encode($emails ?? []), + ]); + + + if ($redirect) { + return redirect()->route('admin.contacts.related-contacts.edit',[$relatedContact->id]) + ->with('success', 'Updated successfully.'); + } + + return response()->json(['message' => 'Updated successfully.']); + } + + public function destroy(RelatedContact $relatedContact) + { + $relatedContact->delete(); + + return response()->json(['message' => 'Related contact deleted successfully.']); + } + + public function show(int $id): View + { + $relatedContact = $this->relatedContactRepository->findOrFail($id); + +// $user = auth()->user(); +// $allowedFields = $user->role->visible_person_fields ?? []; +// +// // Always include 'id' for routing/model logic +// if (!in_array('id', $allowedFields)) { +// $allowedFields[] = 'id'; +// } + + + return view('admin::contacts.related.view', [ + 'relatedContact' => (object) $relatedContact, + ]); + } + + + public function create(): View + { + return view('admin::contacts.related.create'); + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(int $id): View + { + + $relatedContact = $this->relatedContactRepository->findOrFail($id); + + return view('admin::contacts.related.edit', compact('relatedContact')); + } + + +} diff --git a/packages/Webkul/Admin/src/Http/Controllers/Settings/RoleController.php b/packages/Webkul/Admin/src/Http/Controllers/Settings/RoleController.php index cc703ca62..e95c4013a 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Settings/RoleController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Settings/RoleController.php @@ -44,6 +44,7 @@ public function create(): View */ public function store(): RedirectResponse { + $this->validate(request(), [ 'name' => 'required', 'permission_type' => 'required|in:all,custom', @@ -89,6 +90,7 @@ public function edit(int $id): View */ public function update(int $id): RedirectResponse { + $this->validate(request(), [ 'name' => 'required', 'permission_type' => 'required|in:all,custom', @@ -109,7 +111,17 @@ public function update(int $id): RedirectResponse $role = $this->roleRepository->update($data, $id); Event::dispatch('settings.role.update.after', $role); + $list = []; + foreach (request()->keys() as $key) { + if (str_starts_with($key,"field_")){ + if ( request()->get($key) === "1") { + $list[]=str_replace("field_","",$key); + } + } + } + $role->visible_person_fields=$list; + $role->save(); session()->flash('success', trans('admin::app.settings.roles.index.update-success')); return redirect()->back(); diff --git a/packages/Webkul/Admin/src/Http/Resources/ActivityFileResource.php b/packages/Webkul/Admin/src/Http/Resources/ActivityFileResource.php index abfdc0d31..96ed47a9b 100644 --- a/packages/Webkul/Admin/src/Http/Resources/ActivityFileResource.php +++ b/packages/Webkul/Admin/src/Http/Resources/ActivityFileResource.php @@ -15,12 +15,16 @@ class ActivityFileResource extends JsonResource public function toArray($request) { return [ - 'id' => $this->id, - 'name' => $this->name, - 'path' => $this->path, - 'url' => $this->url, - 'created_at' => $this->created_at, - 'updated_at' => $this->updated_at, + 'id' => $this->id, + 'name' => $this->name, + 'path' => $this->path, + 'url' => $this->url, + 'issue_date' => $this->issue_date, + 'expiry_date' => $this->expiry_date, + 'file_code' => $this->file_code, + 'entity_id' => $this->entity_id, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, ]; } } diff --git a/packages/Webkul/Admin/src/Resources/assets/images/logo.svg b/packages/Webkul/Admin/src/Resources/assets/images/logo.svg index 50755ec62..ef4708bc5 100644 --- a/packages/Webkul/Admin/src/Resources/assets/images/logo.svg +++ b/packages/Webkul/Admin/src/Resources/assets/images/logo.svg @@ -1,6 +1,36 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index 7bb10634a..e61f3733a 100644 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -14,7 +14,7 @@ 'activities' => 'Activities', 'webhook' => 'Webhook', 'contacts' => 'Contacts', - 'persons' => 'Persons', + 'persons' => 'Companies', 'organizations' => 'Organizations', 'products' => 'Products', 'settings' => 'Settings', @@ -44,6 +44,7 @@ 'import' => 'Import', 'event' => 'Event', 'campaigns' => 'Campaigns', + 'relatedContact' => 'Persons', ], 'users' => [ @@ -116,13 +117,15 @@ ], 'file' => [ - 'btn' => 'File', - 'title' => 'Add File', - 'title-control' => 'Title', - 'name' => 'Name', - 'description' => 'Description', - 'file' => 'File', - 'save-btn' => 'Save File', + 'btn' => 'File', + 'title' => 'Add File', + 'title-control' => 'Title', + 'name' => 'Name', + 'description' => 'Description', + 'file' => 'File', + 'save-btn' => 'Save File', + 'issue-date' => 'Issue Date', + 'expiry-date' => 'Expiry Date', ], 'note' => [ @@ -149,7 +152,7 @@ 'title' => 'Participants', 'placeholder' => 'Type to search participants', 'users' => 'Users', - 'persons' => 'Persons', + 'persons' => 'Companies', 'no-results' => 'No result found...', ], ], @@ -377,7 +380,7 @@ 'tabs' => [ 'leads' => 'Leads', 'quotes' => 'Quotes', - 'persons' => 'Persons', + 'persons' => 'Companies', 'products' => 'Products', ], @@ -432,11 +435,11 @@ 'datagrid' => [ 'subject' => 'Subject', - 'sales-person' => 'Sales Person', + 'sales-person' => 'Sales Company', 'expired-at' => 'Expired At', 'created-at' => 'Created At', 'expired-quotes' => 'Expired Quote', - 'person' => 'Person', + 'person' => 'Company', 'subtotal' => 'Subtotal', 'discount' => 'Discount', 'tax' => 'Tax', @@ -455,12 +458,12 @@ 'discount' => 'Discount', 'expired-at' => 'Expired At', 'grand-total' => 'Grand Total', - 'person' => 'Person', + 'person' => 'Company', 'price' => 'Price', 'product-name' => 'Product Name', 'quantity' => 'Quantity', 'quote-id' => 'Quote ID', - 'sales-person' => 'Sales Person', + 'sales-person' => 'Sales Company', 'shipping-address' => 'Shipping Address', 'sku' => 'SKU', 'sub-total' => 'Sub Total', @@ -535,13 +538,114 @@ 'contacts' => [ 'persons' => [ + 'index' => [ + 'title' => 'Companies', + 'create-btn' => 'Create Company', + 'create-success' => 'Company created successfully.', + 'update-success' => 'Company updated successfully.', + 'delete-success' => 'Company deleted successfully.', + 'delete-failed' => 'Company can not be deleted.', + + 'datagrid' => [ + 'contact-numbers' => 'Contact Numbers', + 'delete' => 'Delete', + 'edit' => 'Edit', + 'emails' => 'Emails', + 'id' => 'ID', + 'view' => 'View', + 'name' => 'Name', + 'organization-name' => 'Organization Name', + ], + ], + + 'view' => [ + 'title' => ':name', + 'about-person' => 'About Company', + 'about-organization' => 'About Organization', + + 'activities' => [ + 'index' => [ + 'all' => 'All', + 'calls' => 'Calls', + 'meetings' => 'Meetings', + 'lunches' => 'Lunches', + 'files' => 'Files', + 'quotes' => 'Quotes', + 'notes' => 'Notes', + 'emails' => 'Emails', + 'by-user' => 'By :user', + 'scheduled-on' => 'Scheduled on', + 'location' => 'Location', + 'participants' => 'Participants', + 'mark-as-done' => 'Mark as Done', + 'delete' => 'Delete', + 'edit' => 'Edit', + ], + + 'actions' => [ + 'mail' => [ + 'btn' => 'Mail', + 'title' => 'Compose Mail', + 'to' => 'To', + 'cc' => 'CC', + 'bcc' => 'BCC', + 'subject' => 'Subject', + 'send-btn' => 'Send', + 'message' => 'Message', + ], + + 'file' => [ + 'btn' => 'File', + 'title' => 'Add File', + 'title-control' => 'Title', + 'name' => 'File Name', + 'description' => 'Description', + 'file' => 'File', + 'save-btn' => 'Save File', + ], + + 'note' => [ + 'btn' => 'Note', + 'title' => 'Add Note', + 'comment' => 'Comment', + 'save-btn' => 'Save Note', + ], + + 'activity' => [ + 'btn' => 'Activity', + 'title' => 'Add Activity', + 'title-control' => 'Title', + 'description' => 'Description', + 'schedule-from' => 'Schedule From', + 'schedule-to' => 'Schedule To', + 'location' => 'Location', + 'call' => 'Call', + 'meeting' => 'Meeting', + 'lunch' => 'Lunch', + 'save-btn' => 'Save Activity', + ], + ], + ], + ], + + 'create' => [ + 'title' => 'Create Company', + 'save-btn' => 'Save Company', + ], + + 'edit' => [ + 'title' => 'Edit Company', + 'save-btn' => 'Save Company', + ], + ], + 'relatedContact' => [ 'index' => [ 'title' => 'Persons', 'create-btn' => 'Create Person', - 'create-success' => 'Person created successfully.', - 'update-success' => 'Person updated successfully.', - 'delete-success' => 'Person deleted successfully.', - 'delete-failed' => 'Person can not be deleted.', + 'create-success' => 'Company created successfully.', + 'update-success' => 'Company updated successfully.', + 'delete-success' => 'Company deleted successfully.', + 'delete-failed' => 'Company can not be deleted.', 'datagrid' => [ 'contact-numbers' => 'Contact Numbers', @@ -557,7 +661,7 @@ 'view' => [ 'title' => ':name', - 'about-person' => 'About Person', + 'about-person' => 'About Company', 'about-organization' => 'About Organization', 'activities' => [ @@ -632,7 +736,7 @@ 'edit' => [ 'title' => 'Edit Person', - 'save-btn' => 'Save Person', + 'save-btn' => 'Save Company', ], ], @@ -650,7 +754,7 @@ 'edit' => 'Edit', 'id' => 'ID', 'name' => 'Name', - 'persons-count' => 'Person Count', + 'persons-count' => 'Company Count', ], ], @@ -896,7 +1000,7 @@ 'send-email-to-participants' => 'Send email to participants', 'add-webhook' => 'Add Webhook', 'update-lead' => 'Update Lead', - 'update-person' => 'Update Person', + 'update-person' => 'Update Company', 'send-email-to-person' => 'Send email to person', 'add-tag' => 'Add Tag', 'add-note-as-activity' => 'Add Note as Activity', @@ -1009,7 +1113,7 @@ 'form-title-color' => 'Form Title Color', 'general' => 'General', 'leads' => 'Leads', - 'person' => 'Person', + 'person' => 'Company', 'save-btn' => 'Save Webform', 'submit-button-label' => 'Submit Button Label', 'submit-success-action' => 'Submit Success Action', @@ -1043,7 +1147,7 @@ 'form-title-color' => 'Form Title Color', 'general' => 'General', 'leads' => 'Leads', - 'person' => 'Person', + 'person' => 'Company', 'preview' => 'Preview', 'public-url' => 'Public URL', 'redirect-to-url' => 'Redirect To URL', @@ -1487,7 +1591,7 @@ 'entity-types' => [ 'leads' => 'Leads', 'organizations' => 'Organizations', - 'persons' => 'Persons', + 'persons' => 'Companies', 'products' => 'Products', 'quotes' => 'Quotes', 'warehouses' => 'Warehouses', @@ -1745,7 +1849,7 @@ 'lead' => 'Lead', 'participants' => 'Participants', 'general' => 'General', - 'persons' => 'Persons', + 'persons' => 'Companies', 'no-result-found' => 'Records not found.', 'users' => 'Users', ], @@ -1839,7 +1943,7 @@ 'link-to-lead' => 'Link To Lead', 'linked-lead' => 'Linked Lead', 'lead-details' => 'Lead Details', - 'contact-person' => 'Contact Person', + 'contact-person' => 'Contact Company', 'product' => 'Product', 'tags' => [ @@ -1897,13 +2001,13 @@ 'datagrid' => [ 'id' => 'ID', - 'sales-person' => 'Sales Person', + 'sales-person' => 'Sales Company', 'subject' => 'Subject', 'source' => 'Source', 'lead-value' => 'Lead Value', 'lead-type' => 'Lead Type', 'tag-name' => 'Tag Name', - 'contact-person' => 'Contact Person', + 'contact-person' => 'Contact Company', 'stage' => 'Stage', 'rotten-lead' => 'Rotten Lead', 'date-to' => 'Date To', @@ -1922,11 +2026,11 @@ 'create-lead-btn' => 'Create Lead', 'columns' => [ - 'contact-person' => 'Contact Person', + 'contact-person' => 'Contact Company', 'id' => 'ID', 'lead-type' => 'Lead Type', 'lead-value' => 'Lead Value', - 'sales-person' => 'Sales Person', + 'sales-person' => 'Sales Company', 'source' => 'Source', 'title' => 'Title', 'tags' => 'Tags', @@ -1971,8 +2075,8 @@ 'save-btn' => 'Save', 'details' => 'Details', 'details-info' => 'Put The Basic Information of the Lead', - 'contact-person' => 'Contact Person', - 'contact-info' => 'Information About the Contact Person', + 'contact-person' => 'Contact Company', + 'contact-info' => 'Information About the Contact Company', 'products' => 'Products', 'products-info' => 'Information About the Products', ], @@ -1982,8 +2086,8 @@ 'save-btn' => 'Save', 'details' => 'Details', 'details-info' => 'Put The Basic Information of the Lead', - 'contact-person' => 'Contact Person', - 'contact-info' => 'Information About the Contact Person', + 'contact-person' => 'Contact Company', + 'contact-info' => 'Information About the Contact Company', 'products' => 'Products', 'products-info' => 'Information About the Products', ], @@ -2052,7 +2156,7 @@ ], 'persons' => [ - 'title' => 'About Persons', + 'title' => 'About Companies', 'job-title' => ':job_title at :organization', ], @@ -2126,7 +2230,7 @@ 'mail' => 'Mail', 'organizations' => 'Organizations', 'outbox' => 'Outbox', - 'persons' => 'Persons', + 'persons' => 'Companies', 'products' => 'Products', 'quotes' => 'Quotes', 'sent' => 'Sent', @@ -2207,7 +2311,7 @@ 'total-leads' => 'Total Leads', 'average-leads-per-day' => 'Average Leads Per Day', 'total-quotations' => 'Total Quotations', - 'total-persons' => 'Total Persons', + 'total-persons' => 'Total Companies', 'total-organizations' => 'Total Organizations', ], @@ -2237,8 +2341,8 @@ ], 'top-persons' => [ - 'title' => 'Top Persons', - 'empty-title' => 'No Persons Found', + 'title' => 'Top Companies', + 'empty-title' => 'No Companies Found', 'empty-info' => 'No persons available for selected interval', ], @@ -2268,8 +2372,9 @@ ], 'activities' => 'Activities', 'contacts' => 'Contacts', - 'persons' => 'Persons', - 'person' => 'Person', + 'persons' => 'Companies', + 'relatedContact' => 'Person', + 'person' => 'Company', 'organizations' => 'Organizations', 'organization' => 'Organization', 'products' => 'Products', diff --git a/packages/Webkul/Admin/src/Resources/views/activities/index.blade.php b/packages/Webkul/Admin/src/Resources/views/activities/index.blade.php index bb370e2e6..3e3bed79b 100644 --- a/packages/Webkul/Admin/src/Resources/views/activities/index.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/activities/index.blade.php @@ -11,7 +11,7 @@
- +
@lang('admin::app.activities.index.title')
@@ -19,7 +19,7 @@
- +
@@ -37,7 +37,7 @@ {!! view_render_event('admin.activities.index.activities.after') !!} @pushOnce('scripts') - -@endPushOnce \ No newline at end of file +@endPushOnce diff --git a/packages/Webkul/Admin/src/Resources/views/components/activities/actions/file.blade.php b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/file.blade.php index 413a27571..f7d13ef34 100644 --- a/packages/Webkul/Admin/src/Resources/views/components/activities/actions/file.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/file.blade.php @@ -66,7 +66,7 @@ class="flex h-[74px] w-[84px] flex-col items-center justify-center gap-1 rounded name="type" value="file" /> - + - + @@ -115,7 +115,7 @@ class="flex h-[74px] w-[84px] flex-col items-center justify-center gap-1 rounded @lang('admin::app.components.activities.actions.file.file') - + + + + + @lang('admin::app.components.activities.actions.file.issue-date') + + + + + + + + + @lang('admin::app.components.activities.actions.file.expiry-date') + + + + + {!! view_render_event('admin.components.activities.actions.file.form_controls.modal.content.controls.after') !!} @@ -213,4 +237,4 @@ class="primary-button" }, }); -@endPushOnce \ No newline at end of file +@endPushOnce diff --git a/packages/Webkul/Admin/src/Resources/views/components/activities/actions/mail.blade.php b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/mail.blade.php index 34451d68f..0112478c1 100644 --- a/packages/Webkul/Admin/src/Resources/views/components/activities/actions/mail.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/mail.blade.php @@ -69,14 +69,14 @@ class="flex h-[74px] w-[84px] flex-col items-center justify-center gap-1 rounded name="type" value="email" /> - + - + @@ -290,4 +290,4 @@ class="primary-button" }, }); -@endPushOnce \ No newline at end of file +@endPushOnce diff --git a/packages/Webkul/Admin/src/Resources/views/components/activities/actions/related.blade.php b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/related.blade.php new file mode 100644 index 000000000..0d3a30e21 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/components/activities/actions/related.blade.php @@ -0,0 +1,144 @@ +@props([ + 'entity' => null, + 'entityControlName' => null, +]) + + +
+ + + +
+ +@pushOnce('scripts') + + + +@endPushOnce diff --git a/packages/Webkul/Admin/src/Resources/views/components/activities/index.blade.php b/packages/Webkul/Admin/src/Resources/views/components/activities/index.blade.php index 7413c42cb..7491555f7 100644 --- a/packages/Webkul/Admin/src/Resources/views/components/activities/index.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/components/activities/index.blade.php @@ -1,3 +1,4 @@ +@php use Webkul\Contact\Models\Person; @endphp @props([ 'endpoint', 'emailDetachEndpoint' => null, @@ -9,6 +10,15 @@ {!! view_render_event('admin.components.activities.before') !!} +@php + $crm_id = request()->route('id'); + $person = Person::where('crm','=',$crm_id)->first(); + $person_id = $person->id; + $relateds = \Webkul\Contact\Models\RelatedContact::where('person_id','=',$person_id)->get(); + + +@endphp + +

+ - + - {!! view_render_event('admin.persons.create.create_button.after') !!}
- - -
+
{!! view_render_event('admin.persons.create.form_controls.before') !!} + @php + $attributes = app('Webkul\Attribute\Repositories\AttributeRepository')->findWhere([ + 'entity_type' => 'persons', + ]); + $should_remove_fields=[]; + foreach ($attributes as $attribute){ + if($attribute->code==='person_type'){ + $attributeValues = app('Webkul\Attribute\Repositories\AttributeValueRepository')->findWhere([ + 'entity_type' => 'persons', + 'attribute_id'=>$attribute->id + ])->first(); + switch($attributeValues->integer_value){ + case 1: + break; + case 2: + $should_remove_fields=['company_name_en','company_name_ar','license_no', + 'company_issue_date','company_expiry_date','partner_2','partner_3','local_agent' + ]; + break; + case 3: + $should_remove_fields=['company_name_en','company_name_ar','license_no', + 'company_issue_date','company_expiry_date','partner_2','partner_3','local_agent' + ]; + break; + } + } + } + array_push($should_remove_fields,'rate'); + $rate=0; + $attributes = $attributes->reject(function ($attribute) use ($should_remove_fields) { + return in_array($attribute->code, $should_remove_fields); + }); + $rate = intval($rate); + @endphp +
+
+ id="star5" name="rate" + value="5"/> + + id="star4" name="rate" + value="4"/> + + id="star3" name="rate" + value="3"/> + + id="star2" name="rate" + value="2"/> + + id="star1" name="rate" + value="1"/> + + + + + +
+
- + + + + @pushOnce('scripts') + + + + @endPushOnce {!! view_render_event('admin.persons.create.form_controls.after') !!}
- {!! view_render_event('admin.persons.create.form.after') !!} + diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/persons/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/persons/edit.blade.php index 4367c4780..1fd460291 100644 --- a/packages/Webkul/Admin/src/Resources/views/contacts/persons/edit.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/contacts/persons/edit.blade.php @@ -1,4 +1,3 @@ - @@ -13,12 +12,13 @@ enctype="multipart/form-data" >
-
+
{!! view_render_event('admin.persons.edit.breadcrumbs.before') !!} - @@ -46,13 +46,121 @@ class="primary-button"
-
+ +
{!! view_render_event('admin.contacts.persons.edit.form_controls.before') !!} + @php + $attributes = app('Webkul\Attribute\Repositories\AttributeRepository')->findWhere([ + 'entity_type' => 'persons', + ]); + + $should_remove_fields=[]; + + foreach ($attributes as $attribute){ + if($attribute->code==='person_type'){ + + $attributeValues = app('Webkul\Attribute\Repositories\AttributeValueRepository')->findWhere([ + 'entity_type' => 'persons', + 'attribute_id'=>$attribute->id + ])->first(); + + + switch($attributeValues->integer_value){ + case 1: + + break; + case 2: + + $should_remove_fields=['company_name_en','company_name_ar','license_no', + 'company_issue_date','company_expiry_date','partner_2','partner_3','local_agent' + ]; + + break; + case 3: + $should_remove_fields=['company_name_en','company_name_ar','license_no', + 'company_issue_date','company_expiry_date','partner_2','partner_3','local_agent' + ]; + + break; + + } + + } + } + + + array_push($should_remove_fields,'rate'); + + $rate=0; + + foreach($attributes as $attribute){ + if($attribute->code === 'rate'){ + + $attributeValues = app('Webkul\Attribute\Repositories\AttributeValueRepository')->findWhere([ + 'entity_type' => 'persons', + 'entity_id' => $person->id, + 'attribute_id' => $attribute->id, + ]); + + if ($attributeValues->isEmpty()) { + // It's empty – no attribute values found + } else { + $rate = $attributeValues[0]->text_value; + } + + + } + + } + + + + //dump($attributeValues); + + $attributes = $attributes->reject(function ($attribute) use ($should_remove_fields) { + return in_array($attribute->code, $should_remove_fields); + }); + + $rate = intval($rate); + + @endphp + +
+ +
+ + + id="star5" name="rate" + value="5"/> + + id="star4" name="rate" + value="4"/> + + id="star3" name="rate" + value="3"/> + + id="star2" name="rate" + value="2"/> + + id="star1" name="rate" + value="1"/> + + + + + + + +
+
+ - + + + + @php + $arrayData= $person->relatedContacts->map(function ($contact) { + return [ + 'id' => $contact->id, + 'name' => $contact->name, + 'type' => $contact->type, + 'eid_expiry' => optional($contact->eid_expiry)->format('Y-m-d'), + 'mobile_numbers' => json_decode($contact->mobile_numbers ?? '[]'), + 'emails' => json_decode($contact->emails ?? '[]'), + ]; + })->values(); + + + + @endphp + + + + + @pushOnce('scripts') + + + + + + + @endPushOnce + {!! view_render_event('admin.contacts.persons.edit.form_controls.after') !!}
+
{!! view_render_event('admin.persons.edit.form.after') !!} diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/persons/view.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/persons/view.blade.php index 4348dc7cc..257076f0a 100644 --- a/packages/Webkul/Admin/src/Resources/views/contacts/persons/view.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/contacts/persons/view.blade.php @@ -30,7 +30,7 @@ {!! view_render_event('admin.contact.persons.view.tags.after', ['person' => $person]) !!} - +
{!! view_render_event('admin.contact.persons.view.title.before', ['person' => $person]) !!} @@ -45,16 +45,20 @@ {!! view_render_event('admin.contact.persons.view.title.after', ['person' => $person]) !!}
- +
{!! view_render_event('admin.contact.persons.view.actions.before', ['person' => $person]) !!} - - + +{{-- --}}
{!! view_render_event('admin.contacts.persons.view.attributes.form_controls.attributes_view.before', ['person' => $person]) !!} - + id)" :allow-edit="true" /> - + {!! view_render_event('admin.contacts.persons.view.attributes.form_controls.attributes_view.after', ['person' => $person]) !!} - + {!! view_render_event('admin.contacts.persons.view.attributes.form_controls.after', ['person' => $person]) !!} diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/related/create.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/related/create.blade.php new file mode 100644 index 000000000..401582a57 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/contacts/related/create.blade.php @@ -0,0 +1,176 @@ + + + + + @lang('admin::app.contacts.relatedContact.create.title') + + + {!! view_render_event('admin.relatedContact.create.form.before') !!} + + + +
+
+
+ {!! view_render_event('admin.relatedContact.create.breadcrumbs.before') !!} + + + + + {!! view_render_event('admin.relatedContact.create.breadcrumbs.before') !!} + +
+ @lang('admin::app.contacts.relatedContact.create.title') +
+
+ +
+
+ {!! view_render_event('admin.relatedContact.create.save_buttons.before') !!} + + + + + {!! view_render_event('admin.relatedContact.create.save_buttons.before') !!} +
+
+
+ +
+ {!! view_render_event('admin.contacts.relatedContact.create.form_controls.before') !!} + +
+ +
+ + +
+ +
+ + +
+ + +
+ +
+ +
+ + +
+ + +
+ + +
+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + {!! view_render_event('admin.contacts.relatedContact.edit.form_controls.after') !!} +
+
+ + @pushOnce('scripts') + + @endPushOnce + + + + +
+ + {!! view_render_event('admin.relatedContact.create.form.after') !!} +
diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/related/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/related/edit.blade.php new file mode 100644 index 000000000..a1698dce6 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/contacts/related/edit.blade.php @@ -0,0 +1,271 @@ + + + + + @lang('admin::app.contacts.relatedContact.edit.title') + + + @php + + $types=[ + ['val'=>'','label'=>'-- Select Type --'], + ['val'=>'Manager','label'=>'Manager'], + ['val'=>'Partner','label'=>'Partner'], + ['val'=>'Family Visa','label'=>'Family Visa'], + ['val'=>'Local Agent','label'=>'Local Agent'], + ]; + + + +@endphp + + + +
+
+
+ {!! view_render_event('admin.relatedContact.edit.breadcrumbs.before') !!} + + + + + {!! view_render_event('admin.relatedContact.edit.breadcrumbs.before') !!} + +
+ @lang('admin::app.contacts.relatedContact.edit.title') +
+
+ +
+
+ {!! view_render_event('admin.relatedContact.create.save_buttons.before') !!} + + + + + {!! view_render_event('admin.relatedContact.create.save_buttons.before') !!} +
+
+
+ +
+ {!! view_render_event('admin.contacts.relatedContact.create.form_controls.before') !!} + +
+ +
+ + +
+ +
+ + +
+ + +
+ +
+ +
+ +
+ + +
+ + +
+ + +
+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + {!! view_render_event('admin.contacts.relatedContact.edit.form_controls.after') !!} +
+
+ + @pushOnce('scripts') + + @endPushOnce +
+
+ +
diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/related/index.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/related/index.blade.php new file mode 100644 index 000000000..bbb4a93be --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/contacts/related/index.blade.php @@ -0,0 +1,338 @@ + + + @lang('admin::app.contacts.persons.index.title') + + +
+ + + {!! view_render_event('admin.persons.index.datagrid.before') !!} + + + + + + + {!! view_render_event('admin.persons.index.datagrid.after') !!} +
+ + @pushOnce('scripts') + + + + @endPushOnce + diff --git a/packages/Webkul/Admin/src/Resources/views/contacts/related/view.blade.php b/packages/Webkul/Admin/src/Resources/views/contacts/related/view.blade.php new file mode 100644 index 000000000..6d90cddad --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/contacts/related/view.blade.php @@ -0,0 +1,155 @@ + + + + + @lang('admin::app.contacts.organizations.edit.title') + + + {!! view_render_event('admin.organizations.edit.form.before') !!} + + + @php + + if (!function_exists('formatDateWithRemaining')) { + function formatDateWithRemaining(?string $dateStr): string{ + if (empty($dateStr)) { + return ''; + } + + try { + $date = new DateTime($dateStr); + } catch (Exception $e) { + return '-'; + } + + if ((int) $date->format('Y') <= 2000) { + return '-'; + } + + $now = new DateTime(); + + // Format: "29 Jun 2025" + $formattedDate = $date->format('d M Y'); + + $interval = $now->diff($date); + $diffDays = (int) $interval->format('%r%a'); // signed days + + if ($diffDays > 0) { + $remainText = "(in {$diffDays} day" . ($diffDays > 1 ? 's' : '') . ")"; + } elseif ($diffDays === 0) { + $remainText = "(today)"; + } else { + $remainText = "(" . abs($diffDays) . " day" . (abs($diffDays) > 1 ? 's' : '') . " ago)"; + } + + return "{$formattedDate} {$remainText}"; + } + } + + + if(!empty($relatedContact->emails)){ + $relatedContact->emails = implode(',',json_decode($relatedContact->emails, true)); + } + if(!empty($relatedContact->mobile_numbers)){ + $relatedContact->mobile_numbers = implode(',',json_decode($relatedContact->mobile_numbers, true)); + } + + + @endphp +
+
+
+ {!! view_render_event('admin.organizations.edit.breadcrumbs.before', ['relatedContact' => $relatedContact]) !!} + + + + {!! view_render_event('admin.organizations.edit.breadcrumbs.before', ['relatedContact' => $relatedContact]) !!} + +
+ +
+ +
+ +
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+ @if(formatDateWithRemaining($relatedContact->eid_expiry)!=='-') +
+ + +
+ @endif + @if(!empty($relatedContact->person_id)) + + @endif + + + +
+
+
+ + {!! view_render_event('admin.organizations.edit.form.after') !!} +
diff --git a/packages/Webkul/Admin/src/Resources/views/errors/index.blade.php b/packages/Webkul/Admin/src/Resources/views/errors/index.blade.php index 0c73cc6f3..2d8f83042 100644 --- a/packages/Webkul/Admin/src/Resources/views/errors/index.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/errors/index.blade.php @@ -9,10 +9,10 @@
cookie('dark_mode') + ? vite()->asset('images/dark-logo.svg') + : vite()->asset('images/logo.svg') }}" class="w-40 ltr:pr-16 rtl:pl-16" > @@ -39,18 +39,18 @@ class="cursor-pointer text-sm font-semibold text-blue-600 transition-all hover:u - - @lang('admin::app.errors.dashboard') - +{{-- --}} +{{-- @lang('admin::app.errors.dashboard')--}} +{{-- --}}

@lang('admin::app.errors.support', [ - 'link' => 'mailto:support@example.com', - 'email' => 'support@example.com', + 'link' => 'mailto:alireza2756@gmail.com', + 'email' => 'alireza2756@gmail.com', 'class' => 'font-semibold text-blue-600 transition-all hover:underline', ])

diff --git a/packages/Webkul/Admin/src/Resources/views/leads/common/contact.blade.php b/packages/Webkul/Admin/src/Resources/views/leads/common/contact.blade.php index 6f89f8d3b..7ab239454 100644 --- a/packages/Webkul/Admin/src/Resources/views/leads/common/contact.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/leads/common/contact.blade.php @@ -138,4 +138,4 @@ } }); -@endPushOnce \ No newline at end of file +@endPushOnce diff --git a/packages/Webkul/Admin/src/Resources/views/leads/index/upload.blade.php b/packages/Webkul/Admin/src/Resources/views/leads/index/upload.blade.php index e6d598d71..25cb79bec 100644 --- a/packages/Webkul/Admin/src/Resources/views/leads/index/upload.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/leads/index/upload.blade.php @@ -26,7 +26,7 @@ class="secondary-button" as="div" ref="modalForm" > -
-
-
+