diff --git a/app/GraphQL/Social/Builders/Messages/MessageBuilder.php b/app/GraphQL/Social/Builders/Messages/MessageBuilder.php index 4d0178a2c..ef1ca2b29 100644 --- a/app/GraphQL/Social/Builders/Messages/MessageBuilder.php +++ b/app/GraphQL/Social/Builders/Messages/MessageBuilder.php @@ -22,4 +22,19 @@ public function getAll( */ return Message::fromApp(); } + + public function getChannelMessages( + mixed $root, + array $args, + GraphQLContext $context, + ResolveInfo $resolveInfo + ): Builder { + return Message::fromApp()->whereHas('channels', function ($query) use ($args) { + $query->where('channels.uuid', $args['channel_uuid']); + }) + ->when(! auth()->user()->isAdmin(), function ($query) { + $query->where('companies_id', auth()->user()->currentCompanyId()); + }) + ->select('messages.*'); + } } diff --git a/app/GraphQL/Social/Mutations/Channels/ChannelsManagementMutation.php b/app/GraphQL/Social/Mutations/Channels/ChannelsManagementMutation.php index 4efe36ee2..cb7bda3d6 100644 --- a/app/GraphQL/Social/Mutations/Channels/ChannelsManagementMutation.php +++ b/app/GraphQL/Social/Mutations/Channels/ChannelsManagementMutation.php @@ -12,6 +12,7 @@ use Kanvas\Social\Channels\Repositories\ChannelRepository; use Kanvas\SystemModules\Repositories\SystemModulesRepository; use Kanvas\Users\Models\Users; +use Baka\Support\Str; class ChannelsManagementMutation { @@ -26,6 +27,7 @@ public function createChannel(mixed $rootValue, array $request): Channel description: $request['input']['description'], entity_id: $request['input']['entity_id'], entity_namespace: $systemModule->uuid, + slug: $request['input']['slug'] ?? Str::slug($request['input']['name']) ); $createChannel = new CreateChannelAction($channelDto); diff --git a/database/migrations/Social/2024_02_12_172534_uuid_channel.php b/database/migrations/Social/2024_02_12_172534_uuid_channel.php new file mode 100644 index 000000000..7082c3522 --- /dev/null +++ b/database/migrations/Social/2024_02_12_172534_uuid_channel.php @@ -0,0 +1,27 @@ +uuid('uuid')->after('id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('channels', function (Blueprint $table) { + $table->dropColumn('uuid'); + }); + } +}; diff --git a/database/seeders/SystemModuleSeeder.php b/database/seeders/SystemModuleSeeder.php index d2f565943..871be5015 100755 --- a/database/seeders/SystemModuleSeeder.php +++ b/database/seeders/SystemModuleSeeder.php @@ -5,6 +5,7 @@ use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; +use Kanvas\Guild\Leads\Models\Lead; class SystemModuleSeeder extends Seeder { @@ -195,6 +196,24 @@ public function run() 'mobile_component_type' => null, 'mobile_navigation_type' => null, 'mobile_tab_index' => '0', + ], + [ + 'name' => 'Leads', + 'slug' => 'leads', + 'model_name' => Lead::class, + 'uuid' => (string) Str::uuid(), + 'apps_id' => '1', + 'parents_id' => '0', + 'menu_order' => null, + 'show' => '0', + 'use_elastic' => '0', + 'browse_fields' => '[{"name":"name","title":"Name","sortField":"name","filterable":true,"searchable":true},{"name":"email","title":"Email","sortField":"email","filterable":true,"searchable":true},{"name":"phone","title":"Phone","sortField":"phone","filterable":true,"searchable":true},{"name":"status","title":"Status","sortField":"status","filterable":true,"searchable":true},{"name":"created_at","title":"Created At","sortField":"created_at","filterable":true,"searchable":true}]', + 'created_at' => date('Y-m-d H:i:s'), + 'updated_at' => null, + 'is_deleted' => '0', + 'mobile_component_type' => null, + 'mobile_navigation_type' => null, + 'mobile_tab_index' => '0', ] ); } diff --git a/graphql/schemas/Guild/lead.graphql b/graphql/schemas/Guild/lead.graphql index 8110fb9b2..6d4bce2f6 100644 --- a/graphql/schemas/Guild/lead.graphql +++ b/graphql/schemas/Guild/lead.graphql @@ -21,12 +21,13 @@ type Lead { pipeline: LeadPipeline @belongsTo stage: LeadPipelineStage @belongsTo(relation: "stage") participants: [LeadsParticipants!]! @hasMany + channels: [SocialChannel]! @hasMany files: [Filesystem!]! @paginate( defaultCount: 25 builder: "App\\GraphQL\\Ecosystem\\Queries\\Filesystem\\FilesystemQuery@getFileByGraphType" ) - followers: [User!]! + followers: [User!]! @paginate( defaultCount: 25 builder: "App\\GraphQL\\Social\\Builders\\Follows\\FollowBuilder@getEntityFollowers" @@ -180,7 +181,21 @@ extend type Query @guard { "status" ] ) - orderBy: _ @orderBy(columns: ["id", "created_at", "updated_at", "title", "status", "pipeline_stage_id", "firstname", "lastname", "email", "phone"]) + orderBy: _ + @orderBy( + columns: [ + "id" + "created_at" + "updated_at" + "title" + "status" + "pipeline_stage_id" + "firstname" + "lastname" + "email" + "phone" + ] + ) ): [Lead!]! @paginate( model: "Kanvas\\Guild\\Leads\\Models\\Lead" diff --git a/graphql/schemas/Social/channels.graphql b/graphql/schemas/Social/channels.graphql index 6e6534365..3fbce1a82 100644 --- a/graphql/schemas/Social/channels.graphql +++ b/graphql/schemas/Social/channels.graphql @@ -5,6 +5,7 @@ extend type User { type SocialChannel { id: ID! name: String! + uuid: String slug: String description: String! entity_namespace: String! diff --git a/graphql/schemas/Social/message.graphql b/graphql/schemas/Social/message.graphql index f226b2577..05d5fc3c6 100644 --- a/graphql/schemas/Social/message.graphql +++ b/graphql/schemas/Social/message.graphql @@ -109,4 +109,30 @@ extend type Query @guard { builder: "App\\GraphQL\\Social\\Builders\\Messages\\MessageBuilder@getAll" scopes: ["fromApp"] ) + + channelMessages( + channel_uuid: String! + where: _ + @whereConditions( + columns: [ + "id" + "parent_id" + "parent_unique_id" + "companies_id" + "uuid" + "message_types_id" + "message" + "reactions_count" + "comments_count" + "total_liked" + "total_saved" + "total_shared" + ] + ) + ): [Message!]! + @paginate( + defaultCount: 25 + builder: "App\\GraphQL\\Social\\Builders\\Messages\\MessageBuilder@getChannelMessages" + scopes: ["fromApp"] + ) } diff --git a/src/Domains/Guild/Leads/Models/Lead.php b/src/Domains/Guild/Leads/Models/Lead.php index 1ad08e724..9a0e209f0 100644 --- a/src/Domains/Guild/Leads/Models/Lead.php +++ b/src/Domains/Guild/Leads/Models/Lead.php @@ -10,6 +10,7 @@ use Baka\Users\Contracts\UserInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Kanvas\Apps\Models\Apps; use Kanvas\Guild\Customers\Models\People; @@ -19,6 +20,7 @@ use Kanvas\Guild\Organizations\Models\Organization; use Kanvas\Guild\Pipelines\Models\Pipeline; use Kanvas\Guild\Pipelines\Models\PipelineStage; +use Kanvas\Social\Channels\Models\Channel; use Kanvas\Social\Follows\Traits\FollowersTrait; use Kanvas\Users\Models\Users; use Kanvas\Workflow\Traits\CanUseWorkflow; @@ -105,6 +107,11 @@ public function owner(): BelongsTo return $this->belongsTo(Users::class, 'leads_owner_id', 'id'); } + public function socialChannels(): HasMany + { + return $this->hasMany(Channel::class, 'entity_id', 'id')->where('entity_namespace', self::class); + } + public function receiver(): BelongsTo { return $this->belongsTo(LeadReceiver::class, 'leads_receivers_id', 'id'); diff --git a/src/Domains/Guild/Leads/Observers/LeadObserver.php b/src/Domains/Guild/Leads/Observers/LeadObserver.php index ba3cbd810..a7b29bf01 100644 --- a/src/Domains/Guild/Leads/Observers/LeadObserver.php +++ b/src/Domains/Guild/Leads/Observers/LeadObserver.php @@ -5,11 +5,14 @@ namespace Kanvas\Guild\Leads\Observers; use Baka\Support\Str; +use Kanvas\Apps\Models\Apps; use Kanvas\Guild\Customers\Repositories\PeoplesRepository; use Kanvas\Guild\Leads\Models\Lead; use Kanvas\Guild\Leads\Models\LeadReceiver; use Kanvas\Guild\Leads\Models\LeadStatus; use Kanvas\Guild\Pipelines\Models\Pipeline; +use Kanvas\Social\Channels\Actions\CreateChannelAction; +use Kanvas\Social\Channels\DataTransferObject\Channel; use Kanvas\Workflow\Enums\WorkflowEnum; class LeadObserver @@ -64,6 +67,22 @@ public function creating(Lead $lead): void public function created(Lead $lead): void { $lead->fireWorkflow(WorkflowEnum::CREATED->value); + if ($lead->user) { + ( + new CreateChannelAction( + new Channel( + app(Apps::class), + $lead->company, + $lead->user, + (string)$lead->id, + Lead::class, + 'Default Channel', + $lead->description ?? '', + $lead->uuid->toString() + ) + ) + )->execute(); + } } public function updated(Lead $lead): void diff --git a/src/Domains/Social/Channels/Actions/CreateChannelAction.php b/src/Domains/Social/Channels/Actions/CreateChannelAction.php index dbbf2909c..539e5bc76 100644 --- a/src/Domains/Social/Channels/Actions/CreateChannelAction.php +++ b/src/Domains/Social/Channels/Actions/CreateChannelAction.php @@ -21,7 +21,7 @@ public function execute(): Channel 'apps_id' => $this->channelDto->apps->id, 'companies_id' => $this->channelDto->companies->id, 'name' => $this->channelDto->name, - 'slug' => Str::slug($this->channelDto->name), + 'slug' => $this->channelDto->slug ?? Str::slug($this->channelDto->name), 'description' => $this->channelDto->description, 'entity_id' => $this->channelDto->entity_id, 'entity_namespace' => $this->channelDto->entity_namespace, diff --git a/src/Domains/Social/Channels/DataTransferObject/Channel.php b/src/Domains/Social/Channels/DataTransferObject/Channel.php index 47216521d..cb3455e5b 100644 --- a/src/Domains/Social/Channels/DataTransferObject/Channel.php +++ b/src/Domains/Social/Channels/DataTransferObject/Channel.php @@ -19,6 +19,7 @@ public function __construct( public string $entity_namespace, public string $name = '', public string $description = '', + public ?string $slug = null ) { } } diff --git a/src/Domains/Social/Channels/Models/Channel.php b/src/Domains/Social/Channels/Models/Channel.php index 8f5066e7b..b1a49be63 100644 --- a/src/Domains/Social/Channels/Models/Channel.php +++ b/src/Domains/Social/Channels/Models/Channel.php @@ -4,6 +4,7 @@ namespace Kanvas\Social\Channels\Models; +use Baka\Traits\UuidTrait; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Kanvas\Social\Messages\Models\Message; @@ -24,6 +25,8 @@ */ class Channel extends BaseModel { + use UuidTrait; + protected $table = 'channels'; protected $guarded = []; diff --git a/src/Domains/Social/Messages/Models/Message.php b/src/Domains/Social/Messages/Models/Message.php index 42e078901..35d5119b7 100644 --- a/src/Domains/Social/Messages/Models/Message.php +++ b/src/Domains/Social/Messages/Models/Message.php @@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; use Kanvas\Apps\Models\Apps; +use Kanvas\Social\Channels\Models\Channel; use Kanvas\Social\Messages\Factories\MessageFactory; use Kanvas\Social\MessagesComments\Models\MessageComment; use Kanvas\Social\MessagesTypes\Models\MessageType; @@ -85,6 +86,14 @@ public function topics(): BelongsToMany ->where('entity_namespace', self::class); } + /** + * The roles that belong to the Message + */ + public function channels(): BelongsToMany + { + return $this->belongsToMany(Channel::class, 'channel_messages', 'messages_id', 'channel_id'); + } + /** * messageType */ diff --git a/tests/GraphQL/Guild/LeadTest.php b/tests/GraphQL/Guild/LeadTest.php index 933167bb0..4f2ba363e 100644 --- a/tests/GraphQL/Guild/LeadTest.php +++ b/tests/GraphQL/Guild/LeadTest.php @@ -4,6 +4,9 @@ namespace Tests\GraphQL\Guild; +use Kanvas\Guild\Leads\Models\Lead; +use Kanvas\Social\MessagesTypes\Models\MessageType; +use Kanvas\SystemModules\Models\SystemModules; use Tests\TestCase; class LeadTest extends TestCase @@ -524,4 +527,96 @@ public function testUnFollowLead() ], ]); } + + public function testChannelMessage() + { + $lead = $this->createLeadAndGetResponse(); + $systemModule = SystemModules::where('name', Lead::class)->first(); + $channel = $this->graphQL(' + query socialChannels($where: QuerySocialChannelsWhereWhereConditions) { + socialChannels(where: $where) { + data { + id + uuid + slug + } + } + } + ', ['where' => ['column' => 'SLUG', 'operator' => 'EQ', 'value' => $lead['data']['createLead']['uuid']]]); + $channel->assertJson([ + 'data' => [ + 'socialChannels' => [ + 'data' => [ + [ + 'slug' => $lead['data']['createLead']['uuid'], + ], + ], + ], + + ], + ]); + $channel = $channel->json()['data']['socialChannels']['data'][0]; + $messageType = MessageType::factory()->create(); + $messageInput = [ + 'message' => json_encode($lead['data']['createLead']), + 'message_types_id' => $messageType->id, + 'system_modules_id' => 1, + 'entity_id' => $lead['data']['createLead']['id'], + 'distribution' => [ + 'distributionType' => 'Channels', + 'channels' => [ + $channel['id'], + ], + 'followers' => [], + ], + ]; + + + $this->graphQL( + ' + mutation createMessage($input: MessageInput!) { + createMessage(input: $input) { + message + } + } + ', + [ + 'input' => $messageInput, + ] + )->assertJson([ + 'data' => [ + 'createMessage' => [ + 'message' => json_encode($lead['data']['createLead']), + ], + ], + ]); + + $message = $this->graphQL( + ' + query($channel_uuid: String!) { + channelMessages( + channel_uuid: $channel_uuid + ) { + data { + message + } + } + } + ', + [ + 'channel_uuid' => $channel['uuid'], + ] + ); + $message->assertJsonStructure([ + 'data' => [ + 'channelMessages' => [ + 'data' => [ + '*' => [ + 'message', + ], + ], + ], + ], + ]); + } }