update cache, table cache mothly
This commit is contained in:
parent
728e967049
commit
b9fa0f8c3e
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
namespace Modules\Admin\app\Http\Controllers;
|
namespace Modules\Admin\app\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Helper\Cache\CurrentMonthTimekeeping;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Traits\AnalyzeData;
|
||||||
use App\Traits\HasFilterRequest;
|
use App\Traits\HasFilterRequest;
|
||||||
use App\Traits\HasOrderByRequest;
|
use App\Traits\HasOrderByRequest;
|
||||||
use App\Traits\HasSearchRequest;
|
use App\Traits\HasSearchRequest;
|
||||||
|
|
@ -10,6 +12,7 @@ use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Modules\Admin\app\Models\Admin;
|
use Modules\Admin\app\Models\Admin;
|
||||||
|
use Modules\Admin\app\Models\MonthlyTimekeeping;
|
||||||
use Modules\Admin\app\Models\Tracking;
|
use Modules\Admin\app\Models\Tracking;
|
||||||
|
|
||||||
use function PHPSTORM_META\type;
|
use function PHPSTORM_META\type;
|
||||||
|
|
@ -19,59 +22,39 @@ class TimekeepingController extends Controller
|
||||||
use HasOrderByRequest;
|
use HasOrderByRequest;
|
||||||
use HasFilterRequest;
|
use HasFilterRequest;
|
||||||
use HasSearchRequest;
|
use HasSearchRequest;
|
||||||
|
use AnalyzeData;
|
||||||
|
|
||||||
public function get(Request $request)
|
public function get(Request $request)
|
||||||
{
|
{
|
||||||
// dd($request->date);
|
$currentDate = Carbon::now();
|
||||||
$now = Carbon::create($request->year, $request->month);
|
$currentMonth = $currentDate->month;
|
||||||
// $now = Carbon::create(2024, 5, 30); // Nếu muốn khởi tạo với một ngày cụ thể
|
$currentYear = $currentDate->year;
|
||||||
$daysInMonth = $now->daysInMonth;
|
$data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first();
|
||||||
// return response()->json(['status'=> true, 'data'=>$request->all()]);
|
if ($currentMonth == (int)$request->month && $currentYear == (int)$request->year) {
|
||||||
// Lấy ngày đầu tháng
|
$cacheData = CurrentMonthTimekeeping::getCacheCurrentMonthTimekeeping();
|
||||||
$startOfMonth = $now->startOfMonth()->toDateString();
|
if ($cacheData) {
|
||||||
// Lấy ngày cuối tháng
|
$cacheData->data = json_decode($cacheData->data, true);
|
||||||
$endOfMonth = $now->endOfMonth()->toDateString();
|
return response()->json(['status' => true, 'data' => $cacheData->data, 'working_days'=> $cacheData->working_days, 'message' => 'Get from cache']);
|
||||||
$admins = Admin::all();
|
} else {
|
||||||
$history = DB::table('tracking')->select('*')
|
$result = $this->analyzeCurrentMonthTimeKeepingData($currentMonth, $currentYear);
|
||||||
->whereBetween('tracking.created_at', [$startOfMonth, $endOfMonth])->orderBy('tracking.created_at', 'asc')->get();
|
if ($data) {
|
||||||
$history = collect($history);
|
$data->update(['data' => json_encode($result)]);
|
||||||
$result = [];
|
return response()->json(['status' => true, 'data' => $result, 'message' => 'Get from analyzeCurrentMonthTimeKeepingData + update record']);
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
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']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$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)
|
public function addWorkingTimeForMultipleUser(Request $request)
|
||||||
|
|
@ -81,7 +64,7 @@ class TimekeepingController extends Controller
|
||||||
$month = $request->month;
|
$month = $request->month;
|
||||||
$day = $request->day;
|
$day = $request->day;
|
||||||
$type = $request->type;
|
$type = $request->type;
|
||||||
foreach($user_ids as $id){
|
foreach ($user_ids as $id) {
|
||||||
$user = Admin::find($id);
|
$user = Admin::find($id);
|
||||||
$date = Carbon::create($year, $month, $day)->setTimezone(env('TIME_ZONE'));
|
$date = Carbon::create($year, $month, $day)->setTimezone(env('TIME_ZONE'));
|
||||||
$start = $date->copy()->setTime(7, 31, 11);
|
$start = $date->copy()->setTime(7, 31, 11);
|
||||||
|
|
@ -91,7 +74,7 @@ class TimekeepingController extends Controller
|
||||||
'name' => $user->name,
|
'name' => $user->name,
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'status' => 'check in',
|
'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')
|
'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;
|
namespace Modules\Admin\app\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Helper\Cache\CurrentMonthTimekeeping;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Traits\AnalyzeData;
|
||||||
use App\Traits\HasFilterRequest;
|
use App\Traits\HasFilterRequest;
|
||||||
use App\Traits\HasOrderByRequest;
|
use App\Traits\HasOrderByRequest;
|
||||||
use App\Traits\HasSearchRequest;
|
use App\Traits\HasSearchRequest;
|
||||||
|
|
@ -11,6 +13,7 @@ use DateTime;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Modules\Admin\app\Models\Admin;
|
use Modules\Admin\app\Models\Admin;
|
||||||
|
use Modules\Admin\app\Models\MonthlyTimekeeping;
|
||||||
use Modules\Admin\app\Models\Tracking;
|
use Modules\Admin\app\Models\Tracking;
|
||||||
|
|
||||||
class TrackingController extends Controller
|
class TrackingController extends Controller
|
||||||
|
|
@ -18,7 +21,8 @@ class TrackingController extends Controller
|
||||||
use HasOrderByRequest;
|
use HasOrderByRequest;
|
||||||
use HasFilterRequest;
|
use HasFilterRequest;
|
||||||
use HasSearchRequest;
|
use HasSearchRequest;
|
||||||
|
use AnalyzeData;
|
||||||
|
|
||||||
private $CHECK_IN = 'check in';
|
private $CHECK_IN = 'check in';
|
||||||
private $CHECK_OUT = 'check out';
|
private $CHECK_OUT = 'check out';
|
||||||
|
|
||||||
|
|
@ -96,6 +100,7 @@ class TrackingController extends Controller
|
||||||
$payload['status'] = $this->CHECK_IN;
|
$payload['status'] = $this->CHECK_IN;
|
||||||
}
|
}
|
||||||
$tracking = Tracking::create($payload);
|
$tracking = Tracking::create($payload);
|
||||||
|
$this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'data' => $tracking,
|
'data' => $tracking,
|
||||||
'check_status' => $payload['status'],
|
'check_status' => $payload['status'],
|
||||||
|
|
@ -109,6 +114,7 @@ class TrackingController extends Controller
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$tracking = Tracking::create($payload);
|
$tracking = Tracking::create($payload);
|
||||||
|
$this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'data' => $tracking,
|
'data' => $tracking,
|
||||||
'check_status' => $this->CHECK_IN,
|
'check_status' => $this->CHECK_IN,
|
||||||
|
|
@ -142,6 +148,7 @@ class TrackingController extends Controller
|
||||||
}
|
}
|
||||||
if ($tracking) {
|
if ($tracking) {
|
||||||
$tracking->update($payload);
|
$tracking->update($payload);
|
||||||
|
$this->createOrUpdateRecordForCurrentMonth($payload['created_at']->month, $payload['created_at']->year);
|
||||||
}
|
}
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'data' => $tracking,
|
'data' => $tracking,
|
||||||
|
|
@ -174,6 +181,8 @@ class TrackingController extends Controller
|
||||||
$tracking->image = $path;
|
$tracking->image = $path;
|
||||||
|
|
||||||
$tracking->save();
|
$tracking->save();
|
||||||
|
$date = Carbon::create(new DateTime())->setTimezone(env('TIME_ZONE'));
|
||||||
|
$this->createOrUpdateRecordForCurrentMonth($date->month, $date->year);
|
||||||
}
|
}
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'data' => $tracking,
|
'data' => $tracking,
|
||||||
|
|
@ -186,6 +195,8 @@ class TrackingController extends Controller
|
||||||
$id = $request->get('id');
|
$id = $request->get('id');
|
||||||
|
|
||||||
Tracking::destroy($id);
|
Tracking::destroy($id);
|
||||||
|
$date = Carbon::create(new DateTime())->setTimezone(env('TIME_ZONE'));
|
||||||
|
$this->createOrUpdateRecordForCurrentMonth($date->month, $date->year);
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true
|
'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 () {
|
], function () {
|
||||||
Route::get('/', [TimekeepingController::class, 'get'])->middleware('check.permission:admin.hr.staff');
|
Route::get('/', [TimekeepingController::class, 'get'])->middleware('check.permission:admin.hr.staff');
|
||||||
Route::post('/addMutilple', [TimekeepingController::class, 'addWorkingTimeForMultipleUser'])->middleware('check.permission:admin.hr');
|
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([
|
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');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -66,4 +66,5 @@ export const getAllUserWorklogs = API_URL + 'v1/admin/jira/worklogs'
|
||||||
|
|
||||||
//Timekeeping
|
//Timekeeping
|
||||||
export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
|
export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
|
||||||
export const updateMultipleUserWorkingTime = API_URL + 'v1/admin/timekeeping/addMutilple'
|
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 { update } from '@/rtk/helpers/CRUD'
|
||||||
import { get } from '@/rtk/helpers/apiService'
|
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 { notifications } from '@mantine/notifications'
|
||||||
import { IconCheck, IconExclamationMark, IconX } from '@tabler/icons-react'
|
import { IconCheck, IconExclamationMark, IconX } from '@tabler/icons-react'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import classes from './Timekeeping.module.css'
|
import classes from './Timekeeping.module.css'
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
interface User {
|
interface User {
|
||||||
id: number
|
id: number
|
||||||
|
|
@ -67,7 +68,7 @@ const Timekeeping = () => {
|
||||||
Array.from({ length: getDaysInMonth() }, (_, index) => index + 1),
|
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) {
|
} catch (error: any) {
|
||||||
console.log(error)
|
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(() => {
|
useEffect(() => {
|
||||||
getTimeSheet()
|
getTimeSheet()
|
||||||
}, [date])
|
}, [date])
|
||||||
|
|
@ -136,7 +149,14 @@ const Timekeeping = () => {
|
||||||
size="xs"
|
size="xs"
|
||||||
label="Month"
|
label="Month"
|
||||||
data={Array.from({ length: 12 }, (_, index) =>
|
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) => {
|
onChange={(e) => {
|
||||||
setDate({ ...date, month: e! })
|
setDate({ ...date, month: e! })
|
||||||
|
|
@ -148,19 +168,25 @@ const Timekeeping = () => {
|
||||||
size="xs"
|
size="xs"
|
||||||
ml={'sm'}
|
ml={'sm'}
|
||||||
label="Year"
|
label="Year"
|
||||||
data={Array.from({ length: 20 }, (_, index) =>
|
data={Array.from({ length: 10 }, (_, index) =>
|
||||||
(2023 + 1 + index).toString(),
|
{
|
||||||
|
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) => {
|
onChange={(e) => {
|
||||||
setDate({ ...date, year: e! })
|
setDate({ ...date, year: e! })
|
||||||
}}
|
}}
|
||||||
></Select>
|
></Select>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box display={'flex'} style={{alignItems:'end'}}>
|
||||||
<TextInput type='number' size='xs' label="Working days" w={"20%"} value={workingDays} onChange={(e)=>{
|
<TextInput type='number' size='xs' label="Working days" w={"20%"} value={workingDays} onChange={(e)=>{
|
||||||
setWorkingDays(parseFloat(e.target.value))
|
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>
|
</Box>
|
||||||
<Box w="70%" pl={200} style={{display:'flex', alignItems:'end', justifyContent:"space-evenly"}}>
|
<Box w="70%" pl={200} style={{display:'flex', alignItems:'end', justifyContent:"space-evenly"}}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue