update cache, table cache mothly
This commit is contained in:
		
							parent
							
								
									728e967049
								
							
						
					
					
						commit
						b9fa0f8c3e
					
				| 
						 | 
				
			
			@ -2,7 +2,9 @@
 | 
			
		|||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Helper\Cache\CurrentMonthTimekeeping;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Traits\AnalyzeData;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +12,7 @@ use Carbon\Carbon;
 | 
			
		|||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Modules\Admin\app\Models\Admin;
 | 
			
		||||
use Modules\Admin\app\Models\MonthlyTimekeeping;
 | 
			
		||||
use Modules\Admin\app\Models\Tracking;
 | 
			
		||||
 | 
			
		||||
use function PHPSTORM_META\type;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,59 +22,39 @@ class TimekeepingController extends Controller
 | 
			
		|||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
    use AnalyzeData;
 | 
			
		||||
    
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        // dd($request->date);
 | 
			
		||||
        $now = Carbon::create($request->year, $request->month);
 | 
			
		||||
        // $now = Carbon::create(2024, 5, 30); // Nếu muốn khởi tạo với một ngày cụ thể
 | 
			
		||||
        $daysInMonth = $now->daysInMonth;
 | 
			
		||||
        // return response()->json(['status'=> true, 'data'=>$request->all()]);
 | 
			
		||||
        // Lấy ngày đầu tháng
 | 
			
		||||
        $startOfMonth = $now->startOfMonth()->toDateString();
 | 
			
		||||
        // Lấy ngày cuối tháng
 | 
			
		||||
        $endOfMonth = $now->endOfMonth()->toDateString();
 | 
			
		||||
        $admins = Admin::all();
 | 
			
		||||
        $history = DB::table('tracking')->select('*')
 | 
			
		||||
            ->whereBetween('tracking.created_at', [$startOfMonth, $endOfMonth])->orderBy('tracking.created_at', 'asc')->get();
 | 
			
		||||
        $history = collect($history);
 | 
			
		||||
        $result = [];
 | 
			
		||||
        foreach ($admins as $admin) {
 | 
			
		||||
            $user_data = [];
 | 
			
		||||
            for ($i = 1; $i <= $daysInMonth; $i++) {
 | 
			
		||||
                // Tạo ngày cụ thể trong tháng
 | 
			
		||||
                $date = Carbon::create($now->year, $now->month, $i)->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
			
		||||
                // Kiểm tra xem có mục nào trong $history có created_at trùng với $date
 | 
			
		||||
                $hasEntry = $history->filter(function ($entry) use ($date, $admin) {
 | 
			
		||||
                    // echo($hasEntry);
 | 
			
		||||
                    return Carbon::parse($entry->created_at)->setTimezone(env('TIME_ZONE'))->format('Y-m-d') === $date && $entry->user_id == $admin->id;
 | 
			
		||||
                    });
 | 
			
		||||
                // echo($hasEntry);
 | 
			
		||||
                    
 | 
			
		||||
                    if (count($hasEntry) > 0) {
 | 
			
		||||
                    $values = array_values($hasEntry->toArray());
 | 
			
		||||
                    $last_checkin = null;
 | 
			
		||||
                    $total = 0;
 | 
			
		||||
                    foreach ($values as $value) {
 | 
			
		||||
                        $createdAt = Carbon::parse($value->created_at)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                        if ($value->status == 'check out' && $last_checkin != null) {
 | 
			
		||||
                            $lastCheckInTime = Carbon::parse($last_checkin)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                            // Tính thời gian làm việc bằng hiệu của thời gian check out và check in
 | 
			
		||||
                            $workingTime = $createdAt->diffInSeconds($lastCheckInTime);
 | 
			
		||||
                            $total += $workingTime;
 | 
			
		||||
        $currentDate = Carbon::now();
 | 
			
		||||
        $currentMonth = $currentDate->month;
 | 
			
		||||
        $currentYear = $currentDate->year;
 | 
			
		||||
        $data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first();
 | 
			
		||||
        if ($currentMonth == (int)$request->month && $currentYear == (int)$request->year) {
 | 
			
		||||
            $cacheData = CurrentMonthTimekeeping::getCacheCurrentMonthTimekeeping();
 | 
			
		||||
            if ($cacheData) {
 | 
			
		||||
                $cacheData->data = json_decode($cacheData->data, true);
 | 
			
		||||
                return response()->json(['status' => true, 'data' => $cacheData->data, 'working_days'=> $cacheData->working_days, 'message' => 'Get from cache']);
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = $this->analyzeCurrentMonthTimeKeepingData($currentMonth, $currentYear);
 | 
			
		||||
                if ($data) {
 | 
			
		||||
                    $data->update(['data' => json_encode($result)]);
 | 
			
		||||
                    return response()->json(['status' => true, 'data' => $result, 'message' => 'Get from analyzeCurrentMonthTimeKeepingData + update record']);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                        if ($value->status == 'check in') {
 | 
			
		||||
                            $last_checkin = $createdAt;
 | 
			
		||||
                MonthlyTimekeeping::create(['month' => $currentMonth, 'year' => $currentYear, 'working_days' => $currentDate->daysInMonth, 'data' => json_encode($result)]);
 | 
			
		||||
                return response()->json(['status' => true, 'data' => $result, 'message' => 'Get from analyzeCurrentMonthTimeKeepingData + create record']);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if ($data) {
 | 
			
		||||
                $data['data'] = json_decode($data['data']);
 | 
			
		||||
                return response()->json(['status' => true, 'data' => $data['data'], 'working_days'=> $data['working_days'], 'message' => 'Get from DB']);
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = $this->analyzeCurrentMonthTimeKeepingData($request->month, $request->year);
 | 
			
		||||
                MonthlyTimekeeping::create(['month' => $request->month, 'year' => $request->year, 'working_days' => Carbon::create((int)$request->year, (int)$request->month)->daysInMonth, 'data' => json_encode($result)]);
 | 
			
		||||
                return response()->json(['status' => true, 'data' => $result, 'message' => 'Get from analyzeCurrentMonthTimeKeepingData']);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
                    $user_data[] = ['values'=>array_values($hasEntry->toArray()), 'total' => $total, 'day' => $i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $result[] = ['user' => $admin, 'history' => $user_data];
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json(['status'=> true, 'data'=>$result]);
 | 
			
		||||
        return response()->json(['status' => false, 'mewssage' => 'Get data failed!']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addWorkingTimeForMultipleUser(Request $request)
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +64,7 @@ class TimekeepingController extends Controller
 | 
			
		|||
        $month = $request->month;
 | 
			
		||||
        $day = $request->day;
 | 
			
		||||
        $type = $request->type;
 | 
			
		||||
        foreach($user_ids as $id){
 | 
			
		||||
        foreach ($user_ids as $id) {
 | 
			
		||||
            $user = Admin::find($id);
 | 
			
		||||
            $date = Carbon::create($year, $month, $day)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
            $start = $date->copy()->setTime(7, 31, 11);
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +74,7 @@ class TimekeepingController extends Controller
 | 
			
		|||
                    'name' => $user->name,
 | 
			
		||||
                    'user_id' => $user->id,
 | 
			
		||||
                    'status' => 'check in',
 | 
			
		||||
                    'time_string' => $start ->format('Y-m-d H:i:s'),
 | 
			
		||||
                    'time_string' => $start->format('Y-m-d H:i:s'),
 | 
			
		||||
                    'created_at' => $start->setTimezone('UTC')
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +87,18 @@ class TimekeepingController extends Controller
 | 
			
		|||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(['status'=> true, 'message'=> 'Add successfully']);
 | 
			
		||||
        return response()->json(['status' => true, 'message' => 'Add successfully']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function saveWorkingDays(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first();
 | 
			
		||||
        if($data){
 | 
			
		||||
            $data->update(['working_days'=>$request->working_days]);
 | 
			
		||||
            $this->createOrUpdateRecordForCurrentMonth($request->month, $request->year);
 | 
			
		||||
            return response()->json(['status' => true, 'message' => 'Update successful']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response()->json(['status' => false, 'message' => 'Update failed']);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,9 @@
 | 
			
		|||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Helper\Cache\CurrentMonthTimekeeping;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Traits\AnalyzeData;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +13,7 @@ use DateTime;
 | 
			
		|||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
use Modules\Admin\app\Models\Admin;
 | 
			
		||||
use Modules\Admin\app\Models\MonthlyTimekeeping;
 | 
			
		||||
use Modules\Admin\app\Models\Tracking;
 | 
			
		||||
 | 
			
		||||
class TrackingController extends Controller
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +21,7 @@ class TrackingController extends Controller
 | 
			
		|||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
    use AnalyzeData;
 | 
			
		||||
    
 | 
			
		||||
    private $CHECK_IN = 'check in';
 | 
			
		||||
    private $CHECK_OUT = 'check out';
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +100,7 @@ class TrackingController extends Controller
 | 
			
		|||
                            $payload['status'] = $this->CHECK_IN;
 | 
			
		||||
                        }
 | 
			
		||||
                        $tracking = Tracking::create($payload);
 | 
			
		||||
                        $this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
 | 
			
		||||
                        return response()->json([
 | 
			
		||||
                            'data' => $tracking,
 | 
			
		||||
                            'check_status' => $payload['status'],
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +114,7 @@ class TrackingController extends Controller
 | 
			
		|||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    $tracking = Tracking::create($payload);
 | 
			
		||||
                    $this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
 | 
			
		||||
                    return response()->json([
 | 
			
		||||
                        'data' => $tracking,
 | 
			
		||||
                        'check_status' => $this->CHECK_IN,
 | 
			
		||||
| 
						 | 
				
			
			@ -142,6 +148,7 @@ class TrackingController extends Controller
 | 
			
		|||
        }
 | 
			
		||||
        if ($tracking) {
 | 
			
		||||
            $tracking->update($payload);
 | 
			
		||||
            $this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $tracking,
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +181,8 @@ class TrackingController extends Controller
 | 
			
		|||
            $tracking->image = $path;
 | 
			
		||||
 | 
			
		||||
            $tracking->save();
 | 
			
		||||
            $date = Carbon::create(new DateTime())->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
            $this->createOrUpdateRecordForCurrentMonth($date->month, $date->year);
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $tracking,
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +195,8 @@ class TrackingController extends Controller
 | 
			
		|||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        Tracking::destroy($id);
 | 
			
		||||
        $date = Carbon::create(new DateTime())->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
        $this->createOrUpdateRecordForCurrentMonth($date->month, $date->year);
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Models;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Support\Facades\Event;
 | 
			
		||||
use App\Traits\HasCacheModel;
 | 
			
		||||
 | 
			
		||||
class MonthlyTimekeeping extends Model
 | 
			
		||||
{
 | 
			
		||||
    use HasFactory;
 | 
			
		||||
    use HasCacheModel;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->table = 'monthly_timekeeping';
 | 
			
		||||
        $this->guarded = [];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +107,7 @@ Route::middleware('api')
 | 
			
		|||
            ], function () {
 | 
			
		||||
                Route::get('/', [TimekeepingController::class, 'get'])->middleware('check.permission:admin.hr.staff');
 | 
			
		||||
                Route::post('/addMutilple', [TimekeepingController::class, 'addWorkingTimeForMultipleUser'])->middleware('check.permission:admin.hr');
 | 
			
		||||
                Route::post('/update-working-days', [TimekeepingController::class, 'saveWorkingDays'])->middleware('check.permission:admin.hr');
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            Route::group([
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Helper\Cache;
 | 
			
		||||
 | 
			
		||||
use Modules\Admin\app\Models\MonthlyTimekeeping;
 | 
			
		||||
use Illuminate\Support\Facades\Cache;
 | 
			
		||||
use App\Helper\Constant\CacheConstant;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
 | 
			
		||||
class CurrentMonthTimekeeping
 | 
			
		||||
{
 | 
			
		||||
    public static $globals = 'current-month-timekeeping-data';
 | 
			
		||||
    public static $key = 'current-month-timekeeping-data';
 | 
			
		||||
    public static function getCacheCurrentMonthTimekeeping()
 | 
			
		||||
    {
 | 
			
		||||
        $currentDate = Carbon::now();
 | 
			
		||||
        $currentMonth = $currentDate->month;
 | 
			
		||||
        $currentYear = $currentDate->year;
 | 
			
		||||
        $monthData = Cache::get(self::$key, null);
 | 
			
		||||
        if (isset($GLOBALS[self::$globals]) && $monthData != null)
 | 
			
		||||
            return $GLOBALS[self::$globals];
 | 
			
		||||
        if ($monthData == null) {
 | 
			
		||||
            $monthData = MonthlyTimekeeping::where('month', '=', $currentMonth)->where('year', '=', $currentYear)->first();
 | 
			
		||||
            if ($monthData) {
 | 
			
		||||
                Cache::put(self::$key, json_encode($monthData), (60 * CacheConstant::$expired));
 | 
			
		||||
                $monthData = json_encode($monthData);
 | 
			
		||||
            } else {
 | 
			
		||||
                $monthData = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if ($monthData == null) {
 | 
			
		||||
            $GLOBALS[self::$globals] = null;
 | 
			
		||||
        } else {
 | 
			
		||||
            $GLOBALS[self::$globals] = json_decode($monthData);
 | 
			
		||||
        }
 | 
			
		||||
        return $GLOBALS[self::$globals];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function cleanCacheCurrentMonthTimekeeping()
 | 
			
		||||
    {
 | 
			
		||||
        Cache::forget(self::$key);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Traits;
 | 
			
		||||
 | 
			
		||||
use App\Helper\Cache\CurrentMonthTimekeeping;
 | 
			
		||||
use Carbon\Carbon;
 | 
			
		||||
use Illuminate\Http\JsonResponse;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Modules\Admin\app\Models\Admin;
 | 
			
		||||
use Modules\Admin\app\Models\MonthlyTimekeeping;
 | 
			
		||||
 | 
			
		||||
trait AnalyzeData
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Return a JSON response.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  mixed  $data
 | 
			
		||||
     * @param  int  $status
 | 
			
		||||
     * @param  array  $headers
 | 
			
		||||
     * @param  int  $options
 | 
			
		||||
     * @return array $result
 | 
			
		||||
     */
 | 
			
		||||
    public function analyzeCurrentMonthTimeKeepingData($month, $year)
 | 
			
		||||
    {
 | 
			
		||||
        // dd((int)$month, (int)$year);
 | 
			
		||||
        $now = Carbon::create((int)$year, (int)$month);
 | 
			
		||||
        // $now = Carbon::create(2024, 5, 30); // Nếu muốn khởi tạo với một ngày cụ thể
 | 
			
		||||
        $daysInMonth = $now->daysInMonth;
 | 
			
		||||
        // Lấy ngày đầu tháng
 | 
			
		||||
        $startOfMonth = $now->startOfMonth()->toDateString();
 | 
			
		||||
        // Lấy ngày cuối tháng
 | 
			
		||||
        $endOfMonth = $now->endOfMonth()->toDateString();
 | 
			
		||||
        $admins = Admin::all();
 | 
			
		||||
        $history = DB::table('tracking')->select('*')
 | 
			
		||||
            ->whereBetween('tracking.created_at', [$startOfMonth, $endOfMonth])->orderBy('tracking.created_at', 'asc')->get();
 | 
			
		||||
        $history = collect($history);
 | 
			
		||||
        $result = [];
 | 
			
		||||
        foreach ($admins as $admin) {
 | 
			
		||||
            $user_data = [];
 | 
			
		||||
            for ($i = 1; $i <= $daysInMonth; $i++) {
 | 
			
		||||
                // Tạo ngày cụ thể trong tháng
 | 
			
		||||
                $date = Carbon::create($now->year, $now->month, $i)->setTimezone(env('TIME_ZONE'))->format('Y-m-d');
 | 
			
		||||
                // Kiểm tra xem có mục nào trong $history có created_at trùng với $date
 | 
			
		||||
                $hasEntry = $history->filter(function ($entry) use ($date, $admin) {
 | 
			
		||||
                    // echo($hasEntry);
 | 
			
		||||
                    return Carbon::parse($entry->created_at)->setTimezone(env('TIME_ZONE'))->format('Y-m-d') === $date && $entry->user_id == $admin->id;
 | 
			
		||||
                });
 | 
			
		||||
                // echo($hasEntry);
 | 
			
		||||
 | 
			
		||||
                if (count($hasEntry) > 0) {
 | 
			
		||||
                    $values = array_values($hasEntry->toArray());
 | 
			
		||||
                    $last_checkin = null;
 | 
			
		||||
                    $total = 0;
 | 
			
		||||
                    foreach ($values as $value) {
 | 
			
		||||
                        $createdAt = Carbon::parse($value->created_at)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                        if ($value->status == 'check out' && $last_checkin != null) {
 | 
			
		||||
                            $lastCheckInTime = Carbon::parse($last_checkin)->setTimezone(env('TIME_ZONE'));
 | 
			
		||||
                            // Tính thời gian làm việc bằng hiệu của thời gian check out và check in
 | 
			
		||||
                            $workingTime = $createdAt->diffInSeconds($lastCheckInTime);
 | 
			
		||||
                            $total += $workingTime;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if ($value->status == 'check in') {
 | 
			
		||||
                            $last_checkin = $createdAt;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    $user_data[] = ['values' => array_values($hasEntry->toArray()), 'total' => $total, 'day' => $i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $result[] = ['user' => $admin, 'history' => $user_data];
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function createOrUpdateRecordForCurrentMonth($month, $year)
 | 
			
		||||
    {
 | 
			
		||||
        $data = MonthlyTimekeeping::where('month', '=', $month)->where('year', '=', $year)->first();
 | 
			
		||||
        if ($data) {
 | 
			
		||||
            $result = $this->analyzeCurrentMonthTimeKeepingData($month, $year);
 | 
			
		||||
            $data->update(['data' => json_encode($result)]);
 | 
			
		||||
        } else {
 | 
			
		||||
            $result = $this->analyzeCurrentMonthTimeKeepingData($month, $year);
 | 
			
		||||
            MonthlyTimekeeping::create(['month' => $month, 'year' => $year, 'working_days' => Carbon::create((int)$year, (int)$month)->daysInMonth, 'data' => json_encode($result)]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CurrentMonthTimekeeping::cleanCacheCurrentMonthTimekeeping();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::create('monthly_timekeeping', function (Blueprint $table) {
 | 
			
		||||
            $table->id();
 | 
			
		||||
            $table->integer('month');
 | 
			
		||||
            $table->integer('year');
 | 
			
		||||
            $table->integer('working_days');
 | 
			
		||||
            $table->json('data');
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::dropIfExists('monthly_timekeeping');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -67,3 +67,4 @@ export const getAllUserWorklogs = API_URL + 'v1/admin/jira/worklogs'
 | 
			
		|||
//Timekeeping
 | 
			
		||||
export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
 | 
			
		||||
export const updateMultipleUserWorkingTime = API_URL + 'v1/admin/timekeeping/addMutilple'
 | 
			
		||||
export const updateWorkingDays = API_URL + 'v1/admin/timekeeping/update-working-days'
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,12 @@
 | 
			
		|||
import { getTheTimesheet, updateMultipleUserWorkingTime } from '@/api/Admin'
 | 
			
		||||
import { getTheTimesheet, updateMultipleUserWorkingTime, updateWorkingDays } from '@/api/Admin'
 | 
			
		||||
import { update } from '@/rtk/helpers/CRUD'
 | 
			
		||||
import { get } from '@/rtk/helpers/apiService'
 | 
			
		||||
import { Box, Image, Menu, Select, Table, Text, TextInput, Tooltip } from '@mantine/core'
 | 
			
		||||
import { Box, Button, Image, Menu, Select, Table, Text, TextInput, Tooltip } from '@mantine/core'
 | 
			
		||||
import { notifications } from '@mantine/notifications'
 | 
			
		||||
import { IconCheck, IconExclamationMark, IconX } from '@tabler/icons-react'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
import classes from './Timekeeping.module.css'
 | 
			
		||||
import moment from 'moment'
 | 
			
		||||
 | 
			
		||||
interface User {
 | 
			
		||||
  id: number
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +68,7 @@ const Timekeeping = () => {
 | 
			
		|||
          Array.from({ length: getDaysInMonth() }, (_, index) => index + 1),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        localStorage.getItem('workingdays') ? setWorkingDays(parseFloat(localStorage.getItem('workingdays')!)) : setWorkingDays(getDaysInMonth())
 | 
			
		||||
        setWorkingDays(res.working_days ?? 30)
 | 
			
		||||
      }
 | 
			
		||||
    } catch (error: any) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +116,18 @@ const Timekeeping = () => {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 const handleUpdateWorkingDays = async()=>{
 | 
			
		||||
    try {
 | 
			
		||||
      await update(updateWorkingDays, {
 | 
			
		||||
        working_days: workingDays, 
 | 
			
		||||
        year: date.year, 
 | 
			
		||||
        month: date.month
 | 
			
		||||
      }, getTimeSheet)
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.log(error)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    getTimeSheet()
 | 
			
		||||
  }, [date])
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +149,14 @@ const Timekeeping = () => {
 | 
			
		|||
              size="xs"
 | 
			
		||||
              label="Month"
 | 
			
		||||
              data={Array.from({ length: 12 }, (_, index) =>
 | 
			
		||||
                (1 + index).toString(),
 | 
			
		||||
                {
 | 
			
		||||
                  return {
 | 
			
		||||
                    value: (1 + index).toString(), 
 | 
			
		||||
                    label:(1 + index).toString(),
 | 
			
		||||
                    disabled: (1 + index) > parseInt(date.month)
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
              )}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setDate({ ...date, month: e! })
 | 
			
		||||
| 
						 | 
				
			
			@ -148,19 +168,25 @@ const Timekeeping = () => {
 | 
			
		|||
              size="xs"
 | 
			
		||||
              ml={'sm'}
 | 
			
		||||
              label="Year"
 | 
			
		||||
              data={Array.from({ length: 20 }, (_, index) =>
 | 
			
		||||
                (2023 + 1 + index).toString(),
 | 
			
		||||
              data={Array.from({ length: 10 }, (_, index) =>
 | 
			
		||||
                {
 | 
			
		||||
                  return {
 | 
			
		||||
                    value: (parseInt(moment(Date.now()).format('YYYY')) - 3 + index).toString(), 
 | 
			
		||||
                    label:(parseInt(moment(Date.now()).format('YYYY')) - 3 + index).toString(),
 | 
			
		||||
                    disabled: (parseInt(moment(Date.now()).format('YYYY')) - 3 + index) > parseInt(date.year)
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              )}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
                setDate({ ...date, year: e! })
 | 
			
		||||
              }}
 | 
			
		||||
            ></Select>
 | 
			
		||||
          </Box>
 | 
			
		||||
            <Box>
 | 
			
		||||
            <Box display={'flex'} style={{alignItems:'end'}}>
 | 
			
		||||
              <TextInput type='number' size='xs' label="Working days" w={"20%"} value={workingDays} onChange={(e)=>{
 | 
			
		||||
                setWorkingDays(parseFloat(e.target.value))
 | 
			
		||||
                localStorage.setItem('workingdays', e.target.value)
 | 
			
		||||
              }}/>
 | 
			
		||||
              <Tooltip label="Save working days"><Button size='xs' ml={'sm'} onClick={()=>handleUpdateWorkingDays()}>Save</Button></Tooltip>
 | 
			
		||||
            </Box>
 | 
			
		||||
        </Box>
 | 
			
		||||
        <Box w="70%" pl={200} style={{display:'flex', alignItems:'end', justifyContent:"space-evenly"}}>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue