update
This commit is contained in:
		
							parent
							
								
									9b630fe1e1
								
							
						
					
					
						commit
						8cc13276f0
					
				| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Contact;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\ContactRequest;
 | 
			
		||||
 | 
			
		||||
class ContactController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
 | 
			
		||||
    public function get(ContactRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $contact = new Contact;
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($contact, $request);
 | 
			
		||||
 | 
			
		||||
        $this->searchRequest(
 | 
			
		||||
            builder: $contact,
 | 
			
		||||
            value: $request->get('search'),
 | 
			
		||||
            fields: [
 | 
			
		||||
                'name',
 | 
			
		||||
                'phone',
 | 
			
		||||
                'company',
 | 
			
		||||
                'email',
 | 
			
		||||
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $contact->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,133 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use App\Traits\HasSearchRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\DiscountRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Discount;
 | 
			
		||||
 | 
			
		||||
class DiscountController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    use HasSearchRequest;
 | 
			
		||||
 | 
			
		||||
    public function get(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discount = new Discount;
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($discount, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $discount,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'active_date' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                'expiry' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                'date_used' => self::F_IN_DATETIME,
 | 
			
		||||
                'code' => self::F_TEXT,
 | 
			
		||||
                'value' => self::F_TEXT,
 | 
			
		||||
                'email' => self::F_TEXT,
 | 
			
		||||
                'discount_type_id' => self::F_NOT_CONTAIN,
 | 
			
		||||
                'status' => self::F_BOOLEAN,
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $this->searchRequest(
 | 
			
		||||
            builder: $discount,
 | 
			
		||||
            value: $request->get('search'),
 | 
			
		||||
            fields: [
 | 
			
		||||
                'code',
 | 
			
		||||
                'email',
 | 
			
		||||
                'value'
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $discount->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function create(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $payload = $request->all();
 | 
			
		||||
 | 
			
		||||
        $discount = Discount::createWithDefault($payload);
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $discount,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        $discount = Discount::find($id);
 | 
			
		||||
        $payload = $request->all();
 | 
			
		||||
 | 
			
		||||
        if ($discount) {
 | 
			
		||||
            $discount->update($payload);
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $discount,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function delete(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        Discount::destroy($id);
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete multiple discounts
 | 
			
		||||
    public function deletes(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discounts = $request->get('discounts');
 | 
			
		||||
        $ids = collect($discounts)->pluck('id');
 | 
			
		||||
        Discount::whereIn('id', $ids)->delete();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $ids,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update multiple discounts
 | 
			
		||||
    public function updates(DiscountRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $discounts = $request->get('discounts');
 | 
			
		||||
        $ids = collect($discounts)->pluck('id');
 | 
			
		||||
 | 
			
		||||
        foreach ($discounts as $discountRequest) {
 | 
			
		||||
            // convert to object|array to array
 | 
			
		||||
            $discountRequest = collect($discountRequest)->toArray();
 | 
			
		||||
            // handle array
 | 
			
		||||
            $discount = Discount::find($discountRequest['id']);
 | 
			
		||||
            if ($discount) {
 | 
			
		||||
                // exclude id field
 | 
			
		||||
                unset($discount['id']);
 | 
			
		||||
 | 
			
		||||
                $discount->update($discountRequest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => Discount::whereIn('id', $ids)->get(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\DiscountTypeRequest;
 | 
			
		||||
use Modules\Admin\app\Models\DiscountType;
 | 
			
		||||
 | 
			
		||||
class DiscountTypeController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function all(DiscountTypeRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => DiscountType::all(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,156 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Events\PaymentCanceled;
 | 
			
		||||
use App\Events\PaymentCompleted;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Order;
 | 
			
		||||
use App\Models\Package;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use JsonException;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\OrderRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Discount;
 | 
			
		||||
use Modules\Paypal\app\Models\HistoryPayment;
 | 
			
		||||
 | 
			
		||||
class OrderController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
 | 
			
		||||
    const ORDER_STATUS_COMPLETE = 'COMPLETED';
 | 
			
		||||
    const ORDER_STATUS_PENDING = 'PENDING';
 | 
			
		||||
    const ORDER_STATUS_CANCEL = 'CANCELED';
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        // module check model exist and table
 | 
			
		||||
        if (!class_exists(Order::class)) {
 | 
			
		||||
            throw new JsonException("Order table not exist" );
 | 
			
		||||
        }
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $order = Order::getOrdersWithDiscountAndPackage();
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($order, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $order,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'payment_id' => self::F_TEXT,
 | 
			
		||||
                'discount' => self::F_TEXT,
 | 
			
		||||
                'email' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'users.email'
 | 
			
		||||
                ],
 | 
			
		||||
                'status' => [
 | 
			
		||||
                    'type' => self::F_NOT_CONTAIN,
 | 
			
		||||
                    'column' => 'orders.status'
 | 
			
		||||
                ],
 | 
			
		||||
                'from_date' => [
 | 
			
		||||
                    'type' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'orders.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
                'to_date' => [
 | 
			
		||||
                    'type' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'orders.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $order->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(OrderRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->input('id');
 | 
			
		||||
        $order = Order::find($id);
 | 
			
		||||
        $client = Client::find($order['user_id']);
 | 
			
		||||
        $package = Package::find($order['package_id']);
 | 
			
		||||
 | 
			
		||||
        $order['status'] = $request->input('status');
 | 
			
		||||
 | 
			
		||||
        if ($request->input('status') == self::ORDER_STATUS_COMPLETE) {
 | 
			
		||||
            if ($order['discount']) {
 | 
			
		||||
                // Update discount
 | 
			
		||||
                $discount = Discount::where('code', $order['discount'])->first();
 | 
			
		||||
                if ($discount != null) {
 | 
			
		||||
                    $discount['user_id'] = $client->id;
 | 
			
		||||
                    $discount['email'] = $client->email;
 | 
			
		||||
                    $discount['date_used'] = now();
 | 
			
		||||
                    $discount->save();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // Update point for client
 | 
			
		||||
            $client->point += (int) $order['point'];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $status = -1;
 | 
			
		||||
        if ($request->input('status') == self::ORDER_STATUS_COMPLETE) {
 | 
			
		||||
            $status = 1;
 | 
			
		||||
            event(
 | 
			
		||||
                new PaymentCompleted(
 | 
			
		||||
                    payment_id: $order['payment_id'],
 | 
			
		||||
                    email: $client->email,
 | 
			
		||||
                    name: $client->name,
 | 
			
		||||
                    type: "PAYPAL",
 | 
			
		||||
                    product_name: $package->title,
 | 
			
		||||
                    point: $order->point,
 | 
			
		||||
                    discount_value: view_price((float) $package->price - (float) $order['total_price']),
 | 
			
		||||
                    total_price: $package->price
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        } elseif ($request->input('status') == self::ORDER_STATUS_CANCEL) {
 | 
			
		||||
            $status = 0;
 | 
			
		||||
            if ($order['discount']) {
 | 
			
		||||
                $discount = Discount::where('code', $order['discount'])->first();
 | 
			
		||||
                $discount['status'] = 1;
 | 
			
		||||
                $discount->save();
 | 
			
		||||
            }
 | 
			
		||||
            event(
 | 
			
		||||
                new PaymentCanceled(
 | 
			
		||||
                    payment_id: $order['payment_id'],
 | 
			
		||||
                    email: $client->email,
 | 
			
		||||
                    name: $client->name
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            $status = 2;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create history
 | 
			
		||||
        HistoryPayment::create([
 | 
			
		||||
            'payment_id' => $order['payment_id'],
 | 
			
		||||
            'status' => $status,
 | 
			
		||||
            'payload' => $request->all(),
 | 
			
		||||
            'response' =>
 | 
			
		||||
                [
 | 
			
		||||
                    'order' => $order,
 | 
			
		||||
                    'client' => $client,
 | 
			
		||||
                    'discount' => $discount ?? [],
 | 
			
		||||
                    'message' => "Change by Admin"
 | 
			
		||||
                ]
 | 
			
		||||
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $order->save();
 | 
			
		||||
        $client->save();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $order,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,94 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Helper\Cache\PackagesCacheHelper;
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use Modules\Admin\app\Http\Requests\PackageRequest;
 | 
			
		||||
use Modules\Admin\app\Models\Package;
 | 
			
		||||
 | 
			
		||||
class PackageController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    public function all(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $package = new Package;
 | 
			
		||||
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package->get(),
 | 
			
		||||
            'status' => true,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function create(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $package = Package::create($request->all());
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function update(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        $package = Package::find($id);
 | 
			
		||||
        $package->update($request->all());
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $package,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function delete(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->get('id');
 | 
			
		||||
 | 
			
		||||
        Package::destroy($id);
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete multiple packages
 | 
			
		||||
    public function deletes(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $packages = $request->get('packages');
 | 
			
		||||
        $ids = collect($packages)->pluck('id');
 | 
			
		||||
        Package::whereIn('id', $ids)->delete();
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => $ids,
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update multiple packages
 | 
			
		||||
    public function updates(PackageRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $packages = $request->get('packages');
 | 
			
		||||
        $ids = collect($packages)->pluck('id');
 | 
			
		||||
 | 
			
		||||
        foreach ($packages as $packageRequest) {
 | 
			
		||||
            // convert to object|array to array
 | 
			
		||||
            $packageRequest = collect($packageRequest)->toArray();
 | 
			
		||||
            // handle array
 | 
			
		||||
            $package = Package::find($packageRequest['id']);
 | 
			
		||||
            if ($package) {
 | 
			
		||||
                // exclude id field
 | 
			
		||||
                unset($package['id']);
 | 
			
		||||
                $package->update($packageRequest);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        PackagesCacheHelper::cleanCachePackages();
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'data' => Package::whereIn('id', $ids)->get(),
 | 
			
		||||
            'status' => true
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Modules\Admin\app\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Controllers\Controller;
 | 
			
		||||
use App\Models\SerialNumberCheck;
 | 
			
		||||
use Illuminate\Http\RedirectResponse;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Http\Response;
 | 
			
		||||
use App\Traits\HasFilterRequest;
 | 
			
		||||
use App\Traits\HasOrderByRequest;
 | 
			
		||||
use JsonException;
 | 
			
		||||
 | 
			
		||||
class SNCheckController extends Controller
 | 
			
		||||
{
 | 
			
		||||
    use HasOrderByRequest;
 | 
			
		||||
    use HasFilterRequest;
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        // module check model exist and table
 | 
			
		||||
        if (!class_exists(SerialNumberCheck::class)) {
 | 
			
		||||
            throw new JsonException("SerialNumberCheck table not exist");
 | 
			
		||||
        }
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    public function get(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $history = SerialNumberCheck::getHistoryWithUserInfo();
 | 
			
		||||
 | 
			
		||||
        // Order by
 | 
			
		||||
        $this->orderByRequest($history, $request);
 | 
			
		||||
 | 
			
		||||
        // Filter
 | 
			
		||||
        $this->filterRequest(
 | 
			
		||||
            builder: $history,
 | 
			
		||||
            request: $request,
 | 
			
		||||
            filterKeys: [
 | 
			
		||||
                'keyword' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'serial_number_check.keyword'
 | 
			
		||||
                ],
 | 
			
		||||
                'email' => [
 | 
			
		||||
                    'type' => self::F_TEXT,
 | 
			
		||||
                    'column' => 'users.email'
 | 
			
		||||
                ],
 | 
			
		||||
                'status' => [
 | 
			
		||||
                    'type' => self::F_NOT_CONTAIN,
 | 
			
		||||
                    'column' => 'serial_number_check.status'
 | 
			
		||||
                ],
 | 
			
		||||
                'from_date' => [
 | 
			
		||||
                    'type' => self::F_THAN_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'serial_number_check.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
                'to_date' => [
 | 
			
		||||
                    'type' => self::F_LESS_EQ_DATETIME,
 | 
			
		||||
                    'column' => 'serial_number_check.created_at'
 | 
			
		||||
                ],
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseData = array_merge(
 | 
			
		||||
            $history->paginate($request->get('per_page'))->toArray(),
 | 
			
		||||
            ['status' => true]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        return response()->json($responseData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function showDetail(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $id = $request->input('id');
 | 
			
		||||
        $searchRow = SerialNumberCheck::find($id);
 | 
			
		||||
        if ($searchRow) {
 | 
			
		||||
            $user = $searchRow->user()->get();
 | 
			
		||||
            $tracking = $searchRow->tracking()->get();
 | 
			
		||||
            $trackingDetail = $tracking->map(function ($item) {
 | 
			
		||||
                return [
 | 
			
		||||
                    'current_point' => $item->current_point,
 | 
			
		||||
                    'use_point' => $item->use_point,
 | 
			
		||||
                    'created_at' => $item->created_at
 | 
			
		||||
                ];
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            $response = [
 | 
			
		||||
                'data_search' => $searchRow,
 | 
			
		||||
                'user' => $user[0],
 | 
			
		||||
                'tracking' => $trackingDetail
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            return response()->json(['data' => $response, 'status' => true]);
 | 
			
		||||
        }else{
 | 
			
		||||
            return response()->json(['data' => [], 'status' => false]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Store a newly created resource in storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function store(Request $request): RedirectResponse
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show the specified resource.
 | 
			
		||||
     */
 | 
			
		||||
    public function show($id)
 | 
			
		||||
    {
 | 
			
		||||
        return view('admin::show');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show the form for editing the specified resource.
 | 
			
		||||
     */
 | 
			
		||||
    public function edit($id)
 | 
			
		||||
    {
 | 
			
		||||
        return view('admin::edit');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the specified resource in storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function update(Request $request, $id): RedirectResponse
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Remove the specified resource from storage.
 | 
			
		||||
     */
 | 
			
		||||
    public function destroy($id)
 | 
			
		||||
    {
 | 
			
		||||
        //
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ class Admin extends Authenticatable implements JWTSubject
 | 
			
		|||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->table = 'admin';
 | 
			
		||||
        $this->table = 'users';
 | 
			
		||||
        $this->guarded = [];
 | 
			
		||||
        $this->hidden = [
 | 
			
		||||
            'password',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,108 +0,0 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Run the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function up(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::create('admin', function (Blueprint $table) {
 | 
			
		||||
            $table->id();
 | 
			
		||||
            $table->string('name');
 | 
			
		||||
            $table->string('email')->unique();
 | 
			
		||||
            $table->timestamp('email_verified_at')->nullable();
 | 
			
		||||
            $table->string('forgot_code')->nullable();
 | 
			
		||||
            $table->string('password');
 | 
			
		||||
            $table->rememberToken();
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DB::table('admin')->insert([
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'BIEN CONG NHUT TRUONG',
 | 
			
		||||
                'email' => 'roger.b@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAN QUOC BAO',
 | 
			
		||||
                'email' => 'ryder.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM VAN HUYNH',
 | 
			
		||||
                'email' => 'jon.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO MINH TRUONG',
 | 
			
		||||
                'email' => 'vincent.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN HUU PHUC',
 | 
			
		||||
                'email' => 'jason.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN VO TINH',
 | 
			
		||||
                'email' => 'alex.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'DANG TRUNG KIEN',
 | 
			
		||||
                'email' => 'kevin.dang@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'HUYNH THI HONG GAM',
 | 
			
		||||
                'email' => 'rose.h@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN TRUNG THAT',
 | 
			
		||||
                'email' => 'andrew.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'LE TAN LUAN',
 | 
			
		||||
                'email' => 'joseph.le@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO VAN MINH',
 | 
			
		||||
                'email' => 'michael.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'TON GIA KHANH',
 | 
			
		||||
                'email' => 'kai.t@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM QUOC HY',
 | 
			
		||||
                'email' => 'asher.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'Admin',
 | 
			
		||||
                'email' => 'admin@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reverse the migrations.
 | 
			
		||||
     */
 | 
			
		||||
    public function down(): void
 | 
			
		||||
    {
 | 
			
		||||
        Schema::dropIfExists('admin');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
 | 
			
		||||
use Illuminate\Database\Migrations\Migration;
 | 
			
		||||
use Illuminate\Database\Schema\Blueprint;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Schema;
 | 
			
		||||
 | 
			
		||||
return new class extends Migration
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +17,86 @@ return new class extends Migration
 | 
			
		|||
            $table->string('name');
 | 
			
		||||
            $table->string('email')->unique();
 | 
			
		||||
            $table->timestamp('email_verified_at')->nullable();
 | 
			
		||||
            $table->string('forgot_code')->nullable();
 | 
			
		||||
            $table->string('password');
 | 
			
		||||
            $table->string('permission')->default('staff');
 | 
			
		||||
            $table->rememberToken();
 | 
			
		||||
            $table->timestamps();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DB::table('users')->insert([
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'BIEN CONG NHUT TRUONG',
 | 
			
		||||
                'email' => 'roger.b@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAN QUOC BAO',
 | 
			
		||||
                'email' => 'ryder.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM VAN HUYNH',
 | 
			
		||||
                'email' => 'jon.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO MINH TRUONG',
 | 
			
		||||
                'email' => 'vincent.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN HUU PHUC',
 | 
			
		||||
                'email' => 'jason.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN VO TINH',
 | 
			
		||||
                'email' => 'alex.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'DANG TRUNG KIEN',
 | 
			
		||||
                'email' => 'kevin.dang@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'HUYNH THI HONG GAM',
 | 
			
		||||
                'email' => 'rose.h@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'NGUYEN TRUNG THAT',
 | 
			
		||||
                'email' => 'andrew.ng@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'LE TAN LUAN',
 | 
			
		||||
                'email' => 'joseph.le@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'VO VAN MINH',
 | 
			
		||||
                'email' => 'michael.vo@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'TON GIA KHANH',
 | 
			
		||||
                'email' => 'kai.t@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'PHAM QUOC HY',
 | 
			
		||||
                'email' => 'asher.ph@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                'name' => 'Admin',
 | 
			
		||||
                'email' => 'admin@apactech.io',
 | 
			
		||||
                'password' => bcrypt('Work1234'),
 | 
			
		||||
            ],
 | 
			
		||||
            
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,14 @@
 | 
			
		|||
import { getAllUserWorklogs } from '@/api/Admin'
 | 
			
		||||
import { get } from '@/rtk/helpers/apiService'
 | 
			
		||||
import { Avatar, Box, Button, Loader, Text } from '@mantine/core'
 | 
			
		||||
import {
 | 
			
		||||
  Avatar,
 | 
			
		||||
  Badge,
 | 
			
		||||
  Box,
 | 
			
		||||
  Button,
 | 
			
		||||
  Loader,
 | 
			
		||||
  Text,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from '@mantine/core'
 | 
			
		||||
import { DateInput } from '@mantine/dates'
 | 
			
		||||
import moment from 'moment'
 | 
			
		||||
import { useEffect, useState } from 'react'
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +125,7 @@ const Worklogs = () => {
 | 
			
		|||
    startDate:
 | 
			
		||||
      localStorage.getItem('data') !== null
 | 
			
		||||
        ? JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
			
		||||
        : moment(Date.now()-604800000).format('YYYY-MM-DD'),
 | 
			
		||||
        : moment(Date.now() - 604800000).format('YYYY-MM-DD'),
 | 
			
		||||
    endDate:
 | 
			
		||||
      localStorage.getItem('data') !== null
 | 
			
		||||
        ? JSON.parse(localStorage.getItem('data')!).date.endDate
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +199,9 @@ const Worklogs = () => {
 | 
			
		|||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Text fz={12} fs={'italic'} c={'red'} fw={600} mt={'md'}>
 | 
			
		||||
        {`* The current data is from ${JSON.parse(localStorage.getItem('data')!).date.startDate} to ${JSON.parse(localStorage.getItem('data')!).date.endDate}`}
 | 
			
		||||
          {`* The current data is from ${
 | 
			
		||||
            JSON.parse(localStorage.getItem('data')!).date.startDate
 | 
			
		||||
          } to ${JSON.parse(localStorage.getItem('data')!).date.endDate}`}
 | 
			
		||||
        </Text>
 | 
			
		||||
        <Text fz={12} fs={'italic'} c={'red'} fw={600}>
 | 
			
		||||
          {`* If you need data outside this time period, please select a date and click "Search" to update the latest data.`}
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +223,7 @@ const Worklogs = () => {
 | 
			
		|||
              w={'20%'}
 | 
			
		||||
              clearable
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
              setDate({ ...date, startDate: moment(e).format('YYYY-MM-DD') });
 | 
			
		||||
                setDate({ ...date, startDate: moment(e).format('YYYY-MM-DD') })
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
            <DateInput
 | 
			
		||||
| 
						 | 
				
			
			@ -221,16 +231,16 @@ const Worklogs = () => {
 | 
			
		|||
              label="To date:"
 | 
			
		||||
              value={new Date(date.endDate)}
 | 
			
		||||
              clearable
 | 
			
		||||
            m={"0 10px"}
 | 
			
		||||
              m={'0 10px'}
 | 
			
		||||
              w={'20%'}
 | 
			
		||||
              onChange={(e) => {
 | 
			
		||||
              setDate({ ...date, endDate: moment(e).format('YYYY-MM-DD') });
 | 
			
		||||
                setDate({ ...date, endDate: moment(e).format('YYYY-MM-DD') })
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
            <Button
 | 
			
		||||
              size="xs"
 | 
			
		||||
              onClick={() => {
 | 
			
		||||
              getAllWorklogs();
 | 
			
		||||
                getAllWorklogs()
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              Search
 | 
			
		||||
| 
						 | 
				
			
			@ -293,36 +303,48 @@ const Worklogs = () => {
 | 
			
		|||
                borderRadius: '5px',
 | 
			
		||||
                borderColor: '#afafaf',
 | 
			
		||||
                marginBottom: '10px',
 | 
			
		||||
              backgroundColor: index % 2 === 0 ? 'rgb(201 201 201 / 28%)' : 'white',
 | 
			
		||||
                backgroundColor:
 | 
			
		||||
                  index % 2 === 0 ? 'rgb(201 201 201 / 28%)' : 'white',
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              <Text ta={'left'} mb={'xs'} fw={800} display={'flex'}>
 | 
			
		||||
              <Avatar src={user.user.avatarUrls['48x48']} size={'sm'} m={'0 5px'} />
 | 
			
		||||
                <Avatar
 | 
			
		||||
                  src={user.user.avatarUrls['48x48']}
 | 
			
		||||
                  size={'sm'}
 | 
			
		||||
                  m={'0 5px'}
 | 
			
		||||
                />
 | 
			
		||||
                {user.username}(
 | 
			
		||||
                {user?.information.issues.reduce((total, issue) => {
 | 
			
		||||
                  const totalSpent = issue.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                    (accumulator, currentValue) => {
 | 
			
		||||
                      if (
 | 
			
		||||
                        parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                        parseInt(moment(currentValue.started).format('YYYYMMDD')) &&
 | 
			
		||||
                      parseInt(moment(currentValue.started).format('YYYYMMDD')) <=
 | 
			
		||||
                          parseInt(
 | 
			
		||||
                            moment(currentValue.started).format('YYYYMMDD'),
 | 
			
		||||
                          ) &&
 | 
			
		||||
                        parseInt(
 | 
			
		||||
                          moment(currentValue.started).format('YYYYMMDD'),
 | 
			
		||||
                        ) <=
 | 
			
		||||
                          parseInt(moment(date.endDate).format('YYYYMMDD')) &&
 | 
			
		||||
                        currentValue.updateAuthor.displayName === user.username
 | 
			
		||||
                      ) {
 | 
			
		||||
                      return accumulator + currentValue.timeSpentSeconds;
 | 
			
		||||
                        return accumulator + currentValue.timeSpentSeconds
 | 
			
		||||
                      }
 | 
			
		||||
                    return accumulator;
 | 
			
		||||
                      return accumulator
 | 
			
		||||
                    },
 | 
			
		||||
                    0,
 | 
			
		||||
                );
 | 
			
		||||
                return total + totalSpent;
 | 
			
		||||
                  )
 | 
			
		||||
                  return total + totalSpent
 | 
			
		||||
                }, 0) /
 | 
			
		||||
                  60 /
 | 
			
		||||
                  60}
 | 
			
		||||
                h)
 | 
			
		||||
              </Text>
 | 
			
		||||
              {/* Box issue-todo */}
 | 
			
		||||
            <Box display={'flex'} style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
 | 
			
		||||
              <Box
 | 
			
		||||
                display={'flex'}
 | 
			
		||||
                style={{ justifyContent: 'space-between', flexWrap: 'wrap' }}
 | 
			
		||||
              >
 | 
			
		||||
                {/* Box issue */}
 | 
			
		||||
                <Box
 | 
			
		||||
                  w={{ base: '100%', md: '50%' }}
 | 
			
		||||
| 
						 | 
				
			
			@ -367,30 +389,50 @@ const Worklogs = () => {
 | 
			
		|||
                        >
 | 
			
		||||
                          {/* Box information issue */}
 | 
			
		||||
                          <Box>
 | 
			
		||||
                          <Text fz={14} c={iss.fields.status.statusCategory.colorName}>
 | 
			
		||||
                            <Text
 | 
			
		||||
                              fz={14}
 | 
			
		||||
                              c={iss.fields.status.statusCategory.colorName}
 | 
			
		||||
                            >
 | 
			
		||||
                              <b>{iss.fields.status.name}</b>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                          <Text fz={14} display={'flex'} style={{ alignItems: 'start' }}>
 | 
			
		||||
                            <b>Summary:</b>{' '}
 | 
			
		||||
                            <Box display={'flex'} style={{ alignItems: 'center' }}>
 | 
			
		||||
                            <Badge color="#6140c0e0">
 | 
			
		||||
                              <Box
 | 
			
		||||
                                display={'flex'}
 | 
			
		||||
                                style={{ alignItems: 'center' }}
 | 
			
		||||
                              >
 | 
			
		||||
                                <Avatar
 | 
			
		||||
                                  src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                                  size={'xs'}
 | 
			
		||||
                                m={'0 5px'}
 | 
			
		||||
                                  m={'0 5px 0 0'}
 | 
			
		||||
                                />
 | 
			
		||||
                              <Text fz={14} mr={'xs'}>
 | 
			
		||||
                                {iss.fields.project.name}
 | 
			
		||||
                              </Text>
 | 
			
		||||
                              </Box>
 | 
			
		||||
                            <a href={`https://apactechvn.atlassian.net/browse/${iss.key}`} target="_blank">
 | 
			
		||||
                              {iss.fields.summary}
 | 
			
		||||
                            </Badge>
 | 
			
		||||
                            <Text
 | 
			
		||||
                              fz={14}
 | 
			
		||||
                              display={'flex'}
 | 
			
		||||
                              style={{ alignItems: 'start' }}
 | 
			
		||||
                            >
 | 
			
		||||
                              <b>Summary:</b>{' '}
 | 
			
		||||
                              <Tooltip label={iss.fields.summary}>
 | 
			
		||||
                                <Badge color="#228be64f" fz={12}>
 | 
			
		||||
                                  <a
 | 
			
		||||
                                    href={`https://apactechvn.atlassian.net/browse/${iss.key}`}
 | 
			
		||||
                                    target="_blank"
 | 
			
		||||
                                    style={{textDecoration:"none"}}
 | 
			
		||||
                                  >
 | 
			
		||||
                                    [{iss.key}]{` ${iss.fields.summary}`}
 | 
			
		||||
                                  </a>
 | 
			
		||||
                                </Badge>
 | 
			
		||||
                              </Tooltip>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                            <b>Estimate:</b> {iss.fields.timeoriginalestimate / 60 / 60}h
 | 
			
		||||
                              <b>Estimate:</b>{' '}
 | 
			
		||||
                              <Badge color='red' size='sm'>{iss.fields.timeoriginalestimate / 60 / 60}h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                            <b>Total time spent:</b> {iss.fields.timespent / 60 / 60}h
 | 
			
		||||
                              <b>Total time spent:</b>{' '}
 | 
			
		||||
                              <Badge color='orange' size='sm'>{iss.fields.timespent / 60 / 60}h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                            <Text fz={14}>
 | 
			
		||||
                              <b>
 | 
			
		||||
| 
						 | 
				
			
			@ -403,31 +445,49 @@ const Worklogs = () => {
 | 
			
		|||
                                  )
 | 
			
		||||
                                </span>
 | 
			
		||||
                                :
 | 
			
		||||
                            </b>{' '}
 | 
			
		||||
                              </b>{' '}<Badge color='green' size='sm' mb={'xs'}>
 | 
			
		||||
                              {iss.fields.worklog.worklogs?.reduce(
 | 
			
		||||
                                (accumulator, currentValue) => {
 | 
			
		||||
                                  if (
 | 
			
		||||
                                  parseInt(moment(date.startDate).format('YYYYMMDD')) <=
 | 
			
		||||
                                    parseInt(moment(currentValue.started).format('YYYYMMDD')) &&
 | 
			
		||||
                                  parseInt(moment(currentValue.started).format('YYYYMMDD')) <=
 | 
			
		||||
                                    parseInt(moment(date.endDate).format('YYYYMMDD')) &&
 | 
			
		||||
                                  currentValue.updateAuthor.displayName === user.username
 | 
			
		||||
                                    parseInt(
 | 
			
		||||
                                      moment(date.startDate).format('YYYYMMDD'),
 | 
			
		||||
                                    ) <=
 | 
			
		||||
                                      parseInt(
 | 
			
		||||
                                        moment(currentValue.started).format(
 | 
			
		||||
                                          'YYYYMMDD',
 | 
			
		||||
                                        ),
 | 
			
		||||
                                      ) &&
 | 
			
		||||
                                    parseInt(
 | 
			
		||||
                                      moment(currentValue.started).format(
 | 
			
		||||
                                        'YYYYMMDD',
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    ) <=
 | 
			
		||||
                                      parseInt(
 | 
			
		||||
                                        moment(date.endDate).format('YYYYMMDD'),
 | 
			
		||||
                                      ) &&
 | 
			
		||||
                                    currentValue.updateAuthor.displayName ===
 | 
			
		||||
                                      user.username
 | 
			
		||||
                                  ) {
 | 
			
		||||
                                  return accumulator + currentValue.timeSpentSeconds;
 | 
			
		||||
                                    return (
 | 
			
		||||
                                      accumulator +
 | 
			
		||||
                                      currentValue.timeSpentSeconds
 | 
			
		||||
                                    )
 | 
			
		||||
                                  }
 | 
			
		||||
                                return accumulator;
 | 
			
		||||
                                  return accumulator
 | 
			
		||||
                                },
 | 
			
		||||
                                0,
 | 
			
		||||
                              ) /
 | 
			
		||||
                                60 /
 | 
			
		||||
                                60}
 | 
			
		||||
                            h
 | 
			
		||||
                              h</Badge>
 | 
			
		||||
                            </Text>
 | 
			
		||||
                          </Box>
 | 
			
		||||
                          {iss.fields.worklog.worklogs?.map((log, index) => {
 | 
			
		||||
                            if (
 | 
			
		||||
                            moment(date.startDate).format('YYYYMMDD') <= moment(log.started).format('YYYYMMDD') &&
 | 
			
		||||
                            moment(log.started).format('YYYYMMDD') <= moment(date.endDate).format('YYYYMMDD') &&
 | 
			
		||||
                              moment(date.startDate).format('YYYYMMDD') <=
 | 
			
		||||
                                moment(log.started).format('YYYYMMDD') &&
 | 
			
		||||
                              moment(log.started).format('YYYYMMDD') <=
 | 
			
		||||
                                moment(date.endDate).format('YYYYMMDD') &&
 | 
			
		||||
                              log.updateAuthor.displayName === user.username
 | 
			
		||||
                            ) {
 | 
			
		||||
                              return (
 | 
			
		||||
| 
						 | 
				
			
			@ -442,22 +502,31 @@ const Worklogs = () => {
 | 
			
		|||
                                  }}
 | 
			
		||||
                                >
 | 
			
		||||
                                  <Text fz={13}>
 | 
			
		||||
                                  <b>Start date:</b> {moment(log.started).format('HH:mm YYYY/MM/DD')}
 | 
			
		||||
                                    <b>Start date:</b>{' '}
 | 
			
		||||
                                    {moment(log.started).format(
 | 
			
		||||
                                      'HH:mm YYYY/MM/DD',
 | 
			
		||||
                                    )}
 | 
			
		||||
                                  </Text>
 | 
			
		||||
                                  <Text fz={13}>
 | 
			
		||||
                                    <b>Time spent:</b> {log.timeSpent}
 | 
			
		||||
                                  </Text>
 | 
			
		||||
                                {log?.comment && log?.comment?.content[0]?.content[0]?.text && (
 | 
			
		||||
                                  {log?.comment &&
 | 
			
		||||
                                    log?.comment?.content[0]?.content[0]
 | 
			
		||||
                                      ?.text && (
 | 
			
		||||
                                      <Text fz={13}>
 | 
			
		||||
                                    <b>Comment:</b> {log?.comment?.content[0]?.content[0]?.text}
 | 
			
		||||
                                        <b>Comment:</b>{' '}
 | 
			
		||||
                                        {
 | 
			
		||||
                                          log?.comment?.content[0]?.content[0]
 | 
			
		||||
                                            ?.text
 | 
			
		||||
                                        }
 | 
			
		||||
                                      </Text>
 | 
			
		||||
                                    )}
 | 
			
		||||
                                </Box>
 | 
			
		||||
                            );
 | 
			
		||||
                              )
 | 
			
		||||
                            }
 | 
			
		||||
                          })}
 | 
			
		||||
                        </Box>
 | 
			
		||||
                    );
 | 
			
		||||
                      )
 | 
			
		||||
                    }
 | 
			
		||||
                  })}
 | 
			
		||||
                </Box>
 | 
			
		||||
| 
						 | 
				
			
			@ -492,33 +561,52 @@ const Worklogs = () => {
 | 
			
		|||
                          backgroundColor: 'white',
 | 
			
		||||
                        }}
 | 
			
		||||
                      >
 | 
			
		||||
                      <Box display={'flex'} style={{ alignItems: 'center' }}>
 | 
			
		||||
                        <Text
 | 
			
		||||
                          fz={14}
 | 
			
		||||
                          c={iss.fields.status.statusCategory.colorName}
 | 
			
		||||
                        >
 | 
			
		||||
                          <b>{iss.fields.status.name}</b>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Badge color="#6140c0e0">
 | 
			
		||||
                          <Box
 | 
			
		||||
                            display={'flex'}
 | 
			
		||||
                            style={{ alignItems: 'center' }}
 | 
			
		||||
                          >
 | 
			
		||||
                            <Avatar
 | 
			
		||||
                              src={iss.fields.project?.avatarUrls['16x16']}
 | 
			
		||||
                              size={'xs'}
 | 
			
		||||
                              m={'0 5px 0 0'}
 | 
			
		||||
                            />
 | 
			
		||||
                        <Text fz={14} mr={'xs'}>
 | 
			
		||||
                            {iss.fields.project.name}
 | 
			
		||||
                        </Text>
 | 
			
		||||
                          </Box>
 | 
			
		||||
                      <Text fz={14} display={'flex'} style={{ alignItems: 'start' }}>
 | 
			
		||||
                        <b style={{ marginRight: '5px' }}>Summary:</b>
 | 
			
		||||
                        <a href={`https://apactechvn.atlassian.net/browse/${iss.key}`} target="_blank">
 | 
			
		||||
                          {iss.fields.summary}
 | 
			
		||||
                        </Badge>
 | 
			
		||||
                        <Text
 | 
			
		||||
                          fz={14}
 | 
			
		||||
                          display={'flex'}
 | 
			
		||||
                          style={{ alignItems: 'start' }}
 | 
			
		||||
                        >
 | 
			
		||||
                          <b>Summary:</b>{' '}
 | 
			
		||||
                          <Tooltip label={iss.fields.summary}>
 | 
			
		||||
                            <Badge color="#228be64f" fz={12}>
 | 
			
		||||
                              <a
 | 
			
		||||
                                href={`https://apactechvn.atlassian.net/browse/${iss.key}`}
 | 
			
		||||
                                target="_blank"
 | 
			
		||||
                                style={{textDecoration:"none"}}
 | 
			
		||||
                              >
 | 
			
		||||
                                [{iss.key}]{` ${iss.fields.summary}`}
 | 
			
		||||
                              </a>
 | 
			
		||||
                            </Badge>
 | 
			
		||||
                          </Tooltip>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Text fz={13}>
 | 
			
		||||
                        <b>Time spent:</b> {iss.fields.timespent / 60 / 60}h
 | 
			
		||||
                          <b>Time spent:</b> <Badge color='orange' size='sm'>{iss.fields.timespent / 60 / 60}h</Badge>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                        <Text fz={13}>
 | 
			
		||||
                        <b>Estimate:</b> {iss.fields.timeoriginalestimate / 60 / 60}h
 | 
			
		||||
                      </Text>
 | 
			
		||||
                      <Text fz={14} c={iss.fields.status.statusCategory.colorName}>
 | 
			
		||||
                        <b>{iss.fields.status.name}</b>
 | 
			
		||||
                          <b>Estimate:</b>{' '}
 | 
			
		||||
                          <Badge color='red' size='sm'>{iss.fields.timeoriginalestimate / 60 / 60}h</Badge>
 | 
			
		||||
                        </Text>
 | 
			
		||||
                      </Box>
 | 
			
		||||
                  );
 | 
			
		||||
                    )
 | 
			
		||||
                  })}
 | 
			
		||||
                </Box>
 | 
			
		||||
              </Box>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue