Files
a.montask/app/Http/Controllers/TaskController.php
T

561 lines
21 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers;
use App\Models\App;
use App\Models\TaskComment;
use App\Models\TaskDuration;
use http\Env\Response;
use http\Message;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Request;
use App\Models\Pivot_Tasks;
use App\Models\Attendance;
use GuzzleHttp\Client;
use App\Models\Tasks;
use App\Models\User;
use Carbon\Carbon;
use Morilog\Jalali\Jalalian;
use Carbon\CarbonInterval;
class TaskController extends Controller
{
private function taskChangeMessage(Tasks $task, array $before, array $after, ?User $actor): string
{
$lines = [];
$actorName = $actor?->name ?? 'نامشخص';
$titleBefore = (string)($before['title'] ?? '');
$titleAfter = (string)($after['title'] ?? $task->title ?? '');
$lines[] = "ویرایش تسک: «{$titleAfter}»";
$lines[] = "توسط: {$actorName}";
$appBefore = $before['app'] ?? null;
$appAfter = $after['app'] ?? $task->app ?? null;
$a1 = App::find($appBefore)?->name_fa ?? ($appBefore ?? '-');
$a2 = App::find($appAfter)?->name_fa ?? ($appAfter ?? '-');
$lines[] = ($appBefore != $appAfter) ? "اپ: {$a1} ← {$a2}" : "اپ: {$a2}";
$lines[] = (($before['title'] ?? null) !== ($after['title'] ?? null))
? "عنوان: {$titleBefore} ← {$titleAfter}"
: "عنوان: {$titleAfter}";
$priorityFa = [
'none' => 'ندارد',
'low' => 'کم',
'medium' => 'عادی',
'high' => 'زیاد',
'urgent' => 'فوری',
];
$p1 = $before['priority'] ?? null;
$p2 = $after['priority'] ?? null;
$lines[] = ($p1 !== $p2)
? "اولویت: " . ($priorityFa[$p1] ?? ($p1 ?? '-')) . " ← " . ($priorityFa[$p2] ?? ($p2 ?? '-'))
: "اولویت: " . ($priorityFa[$p2] ?? ($p2 ?? '-'));
$stateFa = [
1 => 'انباشته',
2 => 'برای انجام',
3 => 'درحال انجام',
4 => 'پایان یافته',
];
$s1 = (int)($before['state'] ?? 0);
$s2 = (int)($after['state'] ?? 0);
$lines[] = ($s1 !== $s2 && $s2)
? "وضعیت: " . ($stateFa[$s1] ?? ($before['state'] ?? '-')) . " ← " . ($stateFa[$s2] ?? ($after['state'] ?? '-'))
: "وضعیت: " . ($stateFa[$s2] ?? ($after['state'] ?? '-'));
$d1 = $before['start_date'] ?? null;
$d2 = $after['start_date'] ?? null;
$lines[] = ($d1 !== $d2)
? "شروع: " . ($d1 ?: '-') . " ← " . ($d2 ?: '-')
: "شروع: " . ($d2 ?: '-');
$t1 = $before['target_date'] ?? null;
$t2 = $after['target_date'] ?? null;
$lines[] = ($t1 !== $t2)
? "ددلاین: " . ($t1 ?: '-') . " ← " . ($t2 ?: '-')
: "ددلاین: " . ($t2 ?: '-');
$desc1 = trim((string)($before['description'] ?? ''));
$desc2 = trim((string)($after['description'] ?? ''));
$lines[] = ($desc1 !== $desc2)
? "توضیحات: " . (!empty($desc2) ? 'تغییر کرد' : 'پاک شد')
: "توضیحات: بدون تغییر";
$aBefore = $before['assignees'] ?? null;
$aAfter = $after['assignees'] ?? null;
$arr1 = is_string($aBefore) ? json_decode($aBefore, true) : $aBefore;
$arr2 = is_string($aAfter) ? json_decode($aAfter, true) : $aAfter;
$arr1 = is_array($arr1) ? array_map('strval', $arr1) : [];
$arr2 = is_array($arr2) ? array_map('strval', $arr2) : [];
sort($arr1);
sort($arr2);
$names1 = User::whereIn('id', $arr1)->pluck('name')->all();
$names2 = User::whereIn('id', $arr2)->pluck('name')->all();
$lines[] = ($arr1 !== $arr2)
? "مسئولین: " . (!empty($names1) ? implode('، ', $names1) : '-') . " ← " . (!empty($names2) ? implode('، ', $names2) : '-')
: "مسئولین: " . (!empty($names2) ? implode('، ', $names2) : '-');
return implode("\n", $lines);
}
// public function tasks()
// {
// $user = User::where('user_name', $_COOKIE['user_identity'])->first();
// $tasks = $user->tasks;
// $users = User::get();
//
// $state_order = [
// "c73c2044-ea14-42cb-b08d-cecf3d1fdfb5",
// "a9ce312f-cfca-491e-8e3d-1975aa6ebc10",
// "dea1fb57-a281-4fe7-8f3e-ee5567637e35",
// "770fbe42-99f6-41db-9b9e-773d9cced1a5",
// "b0e464e1-34eb-41ea-b2f7-3ef7483bc9f0",
// "d61d14a3-72f7-4f44-894b-efe8b2a75be1",
// ];
//
// $work_item = $tasks->whereNull('parent')->sortBy(fn($t) => array_search($t->state, $state_order));
// $sub_work_items = $tasks->whereNotNull('parent')->sortBy(fn($t) => array_search($t->state, $state_order));
//
// foreach ($work_item as $w) {
// foreach ($sub_work_items as $t) {
// foreach ($users as $u) {
// if ($t->created_by == $u->plain_id)
// $t->created_by = $u->name;
// if ($w->created_by == $u->plain_id)
// $w->created_by = $u->name;
// }
// }
// }
//
// return view('tasks.tasks', compact('tasks', 'work_item', 'sub_work_items'));
// }
public function tasks()
{
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
if ($user) {
if ($user->is_admin == 1) {
$tasks = Tasks::with(['duration', 'comments.user', 'appName'])
->orderByRaw('target_date IS NULL')
->orderBy('target_date', 'asc')
->orderBy('updated_at', 'desc')
->get();
// dd($tasks);
foreach ($tasks as $task) {
$totalSeconds = 0;
foreach ($task->duration as $item) {
if ($item->duration !== null) {
$totalSeconds += CarbonInterval::createFromFormat('H:i:s', $item->duration)->totalSeconds;
}
}
$task->totalDuration = CarbonInterval::seconds($totalSeconds)->cascade()->format('%H:%I:%S');
$active_task = TaskDuration::where('task_id', $task->id)->orderBy('start', 'desc')->first();
$task->active = !empty($active_task) && $active_task->end == null;
}
} else {
$tasks = Tasks::with(['duration', 'comments.user'])->where('created_by', $user->id)
->orWhereJsonContains('assignees', (string)$user->id)
// ->orderByRaw('target_date IS NULL')
// ->orderBy('target_date', 'asc')
->orderBy('updated_at', 'desc')
->get();
// dd($tasks);
foreach ($tasks as $task) {
$totalSeconds = 0;
foreach ($task->duration as $item) {
if ($user->id == $item->user_id && $item->duration !== null) {
$totalSeconds += CarbonInterval::createFromFormat('H:i:s', $item->duration)->totalSeconds;
}
}
$task->totalDuration = CarbonInterval::seconds($totalSeconds)->cascade()->format('%H:%I:%S');
$active_task = TaskDuration::where('task_id', $task->id)->where('user_id', $user->id)->orderBy('start', 'desc')->first();
$task->active = !empty($active_task) && $active_task->end == null;
}
}
$count = count($tasks);
// dd((new Tasks())->filterByState($tasks)['backlog'][0], 'count ='.$count);
return view('tasks.tasks', [
'tasks' => (new Tasks())->filterByState($tasks),
'count' => $count,
'user_id' => $user->id,
'isAdminLevel1' => $user->is_admin == 1,
'mentionUsers' => User::select('id', 'name', 'user_name')->get(),
'appsList' => App::select('id', 'name_fa')->get(),
'priorityLabels' => [
'urgent' => 'فوری',
'high' => 'بالا',
'medium' => 'متوسط',
'low' => 'پایین'
],
'priorityColors' => [
'urgent' => 'bg-red-100 text-red-800',
'high' => 'bg-orange-100 text-orange-800',
'medium' => 'bg-yellow-100 text-yellow-800',
'low' => 'bg-green-100 text-green-800'
],
]);
} else {
return back()->with('message', [
'color' => 'red',
'text' => 'کاربر یافت نشد!'
]);
}
}
public function showTask($id)
{
$task = Tasks::with(['comments.user'])->find($id ?? null);
return view('tasks.create', ['task' => $task]);
}
public function editTask(Request $request)
{
// dd($request->all());
if (!isset($_COOKIE['user_identity'])) {
return back()->with('message', [
'color' => 'red',
'text' => 'ابتدا باید وارد شوید!'
]);
}
$actor = User::where('user_name', $_COOKIE['user_identity'])->first();
$data = $request->all();
$task = Tasks::find($data['id'] ?? null);
if (!$task) {
return back()->with('message', [
'color' => 'red',
'text' => 'وظیفه یافت نشد!'
]);
}
$before = $task->toArray();
$data['updated_by'] = $actor?->id;
if (array_key_exists('assignees', $data)) {
$data['assignees'] = !empty($data['assignees']) ? json_encode($data['assignees']) : null;
} else {
unset($data['assignees']);
}
unset($data['_token'], $data['id'], $data['start_date_display'], $data['target_date_display']);
$task->update($data);
$after = $task->toArray();
$title = $task->title;
$message = "تسک «{$title}» برای شما به‌روزرسانی شد.";
$message_admin = $this->taskChangeMessage($task, $before, $after, $actor);
if (!empty($request->assignees)) {
foreach ($request->assignees as $assignee) {
$assigneeUser = User::where('id', $assignee)->first();
if ($assigneeUser && $assigneeUser->bale !== null) {
$this->send_bale($assigneeUser->bale, $message);
}
}
}
// dd($data, $message, $message_admin);
$this->send_level1_admins($message_admin);
return back()->with('message', [
'color' => 'green',
'text' => $message
]);
}
public function createTask()
{
return view('tasks.create');
}
public function deleteTask($id)
{
Tasks::destroy($id);
return response()->json([
"success" => true,
"message" => "Task deleted successfully.",
"task_id" => 45
]);
}
public function storeTask(Request $request)
{
// dd($request->all());
if (!isset($_COOKIE['user_identity'])) {
return back()->with('message', [
'color' => 'red',
'text' => 'ابتدا باید وارد شوید!'
]);
}
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
$data = $request->all();
$data['created_by'] = $user->id;
$data['assignees'] = !empty($data['assignees']) ? json_encode($data['assignees']) : null;
$task = Tasks::create($data);
$message = "تسک جدیدی با عنوان {$data['title']} برای شما ایجاد شد.";
$deadline = !empty($data['target_date']) ? Jalalian::fromCarbon(Carbon::parse($data['target_date']))->format('Y-m-d') : null;
$app = App::find($data['app']);
$message_admin = "ایجاد تسک: «{$data['title']}»";
$message_admin .= !empty($app) ? "\nاپ {$app->name_fa}" : null;
$message_admin .= !empty($deadline) ? "\nددلاین {$deadline}" : null;
$message_admin .= !empty($data['start_date']) ? "\nتاریخ شروع {$data['start_date']}" : null;
$message_admin .= !empty($data['state_fa']) ? "\nوضعیت: {$data['state_fa']}" : null;
$message_admin .= !empty($data['description']) ? "\nبا توضیحات:\n" . $data['description'] : null;
$message_admin .= !empty($data['assignees']) ? "\nتوسط " . $user->name . " ساخته شد و به" : null;
if (!empty($data['assignees'])) {
foreach ($request->assignees as $assignee) {
$user = User::where('id', $assignee)->first();
$message_admin .= "\n$user->name";
if ($user && $user->bale !== null) {
$this->send_bale($user->bale, $message);
}
}
$message_admin .= "\nاختصاص یافت.";
} else {
$message_admin .= "\nتوسط " . $user->name . " ساخته شد";
}
// dd($data, $message, $message_admin);
$this->send_level1_admins($message_admin);
return redirect('/tasks')->with('message', [
'color' => 'green',
'text' => $message
]);
}
public function activeTask(Request $request)
{
// dd($request);
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
$task = Tasks::find($request->task_id);
if (!$task) {
return response()->json([
'action' => 'not_found',
'status' => false
]);
}
$taskDU = TaskDuration::where('user_id', $user->id)
->where('task_id', $request->task_id)
->orderBy('id', 'desc')
->first();
// اگر رکورد باز داریم => پایان
if (!empty($taskDU) && ($taskDU->start !== null && $taskDU->end == null)) {
// dd('in if');
$attendance = new Attendance();
$s = Carbon::parse($taskDU->start)->format('H:i:s');
$e = Carbon::parse(now())->format('H:i:s');
$duration = $taskDU->duration;
if ($e > $s) {
$diff = $attendance->duration($s, $e);
if ($duration !== null) {
[$h1, $m1, $s1] = explode(':', $duration);
$durationSeconds = $h1 * 3600 + $m1 * 60 + $s1;
[$h2, $m2, $s2] = explode(':', $diff);
$diffSeconds = $h2 * 3600 + $m2 * 60 + $s2;
$totalSeconds = $durationSeconds + $diffSeconds;
$hours = floor($totalSeconds / 3600);
$minutes = floor(($totalSeconds % 3600) / 60);
$seconds = $totalSeconds % 60;
$duration = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
} else {
$duration = $diff;
}
$taskDU->end = now();
$taskDU->duration = $duration;
$user->active_task = null;
$taskDU->save();
$user->save();
$this->send_level1_admins("پایان تسک: «{$task->title}»\nتوسط: {$user->name}\nمدت این نوبت: {$duration}");
return response()->json([
'action' => 'ended',
'status' => true,
'duration' => $duration,
'start' => $taskDU->start,
'end' => $taskDU->end,
]);
} else
return response()->json([
'action' => 'end',
'status' => false
]);
} else {
// شروع => همیشه یک رکورد جدید بساز
$new_task_duration = TaskDuration::create([
'task_id' => $task->id,
'user_id' => $user->id,
'start' => now(),
'end' => null,
]);
$user->active_task = $task->title;
$user->save();
$this->send_level1_admins("شروع تسک: «{$task->title}»\nتوسط: {$user->name}");
return response()->json([
'action' => 'start',
'status' => true,
'start' => $new_task_duration->start,
'id' => $new_task_duration->id,
]);
}
return back()->with('message', ['color' => 'red',
'text' => 'وظیفه یافت نشد✖️']);
}
public function addTask(Request $request)
{
if (isset($_COOKIE['user_identity'])) {
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
} else {
return back()->with('message', [
'color' => 'red',
'text' => 'auth failed!'
]);
}
$request->validate([
'title' => 'required',
'description' => 'required',
'assignees' => 'required',
'start_date' => 'required',
'target_date' => 'required',
'priority' => 'required',
'description_html' => 'required',
'completed_at' => 'required',
'state' => 'required',
'created_at' => 'required',
'updated_at' => 'required',
'app' => 'required',
'task_type' => 'required',
]);
$data = $request->all();
$data['user_id'] = $user->id;
Tasks::create([$data]);
return back()->with('message', [
'color' => 'green',
'text' => 'وظیفه ایجاد شد.'
]);
}
public function storeComment(Request $request, $id)
{
if (!isset($_COOKIE['user_identity'])) {
return back()->with('message', [
'color' => 'red',
'text' => 'ابتدا باید وارد شوید!'
]);
}
$actor = User::where('user_name', $_COOKIE['user_identity'])->first();
$task = Tasks::find($id ?? null);
if (!$task) {
return back()->with('message', [
'color' => 'red',
'text' => 'وظیفه یافت نشد!'
]);
}
$request->validate([
'body' => 'required|string',
]);
$body = trim((string)$request->input('body'));
preg_match_all('/@([\p{L}\p{N}_.-]+)/u', $body, $matches);
$usernames = array_values(array_unique($matches[1] ?? []));
$mentionedUsers = !empty($usernames)
? User::whereIn('user_name', $usernames)->get()
: collect();
$mentionedIds = $mentionedUsers->pluck('id')->values()->all();
TaskComment::create([
'task_id' => $task->id,
'user_id' => $actor->id,
'body' => $body,
'mentioned_user_ids' => !empty($mentionedIds) ? $mentionedIds : null,
]);
$text = "کامنت جدید روی تسک «{$task->title}»\n"
. "توسط: {$actor->name}\n\n"
. $body;
foreach ($mentionedUsers as $mu) {
if ($mu->id === $actor->id) {
continue;
}
if ($mu->bale) {
$this->send_bale($mu->bale, $text);
}
}
$this->send_level1_admins($text);
return back()->with('message', [
'color' => 'green',
'text' => 'کامنت ثبت شد.'
]);
}
public function webhookPlane(Request $request)
{
$d = $request->all();
// فقط وقتی تغییر state هست
if (isset($d['event'], $d['action'], $d['data']['name'], $d['data']['state']['name'])) {
$msg = "Event: {$d['event']}\nAction: {$d['action']}\nName: {$d['data']['name']}\nNew Status: {$d['data']['state']['name']}";
// ارسال به تلگرام
Http::get("https://api.wwwapp.ir/telegran_send.php", [
'botToken' => "7467099619:AAF2V6yYcbAb8oSIRSCyH5i2GKfdWVO3a7k",
'chatId' => "-4742642674",
'message' => $msg,
]);
}
// اگر خواستی ثبت در دیتابیس هم اضافه کنی
// DB::table('tst')->insert([
// 'data' => json_encode($d, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
// ]);
return response()->json(['status' => 'ok'], 200);
}
private function send_bale($chat_id, $message)
{
try {
Http::withoutVerifying()->post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
"chat_id" => $chat_id,
'text' => $message,
]);
} catch (\Exception $e) {
}
}
}