Compare commits

...

10 Commits

Author SHA1 Message Date
edmondlang 76193eeb9f update order v2 2023-04-13 16:09:18 +08:00
edmondlang a696e1dab9 change all order to v2 link 2023-04-13 16:05:20 +08:00
edmondlang c9642bd8f5 update order v2 page 2023-04-13 16:01:12 +08:00
DESKTOP-5I7S92L\nicho a3d26bfb63 uncomment order package code 2023-04-13 12:20:49 +08:00
DESKTOP-5I7S92L\nicho 094f995dcf orde v2 include packages 2023-04-13 12:18:22 +08:00
edmondlang 1a5db25285 update show duplicated invoice logic 2023-04-12 12:15:06 +08:00
edmondlang 2bb4afe426 update show duplicated invoice logic 2023-04-12 11:58:10 +08:00
edmondlang f7a9b2332c enable customer 769SMC summary in 2 different year 2022 and 2023 2023-04-11 11:39:22 +08:00
Dillon Ngo fa0c97b1da Merge branch 'dillon/accounting-bank-mapping' into 'master'
New route, middleware, token table, filters for query to allow  third party to access api

See merge request CIEFWorldwideSdnBhd/shipping-portal!161
2023-04-06 15:19:15 +00:00
Dillon 43cd6f35be New route, middleware, token table, filters for query to allow third party to access api 2023-04-06 22:57:50 +08:00
15 changed files with 708 additions and 9 deletions
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class AmountExceed implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('amount', '>', $value);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class AmountShort implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('amount', '<', $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
class CreatedBefore implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('created_at', '<', Carbon::parse($value));
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class PaymentMethod implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('payment_method', $value);
}
}
+7 -1
View File
@@ -44,6 +44,11 @@ class Kernel extends HttpKernel
'throttle:300,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'apipub' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
@@ -63,6 +68,7 @@ class Kernel extends HttpKernel
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'valid.token' => ValidateToken::class
'valid.token' => ValidateToken::class,
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
];
}
@@ -0,0 +1,56 @@
<?php
namespace App\Http\Middleware;
use App\Models\PersonalAccessTokens;
use Closure;
use Illuminate\Http\Request;
class TokenCheckerMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
//Method 1: Token pass via query parameter
// Check if the api_key query parameter is present
if (!$request->query('api-key')) {
return response()->json(['message' => 'Invalid API key.'], 401);
}
// Check if the api_key is valid
$apiKey = $request->query('api-key');
$personalAccessToken = PersonalAccessTokens::where('token', $apiKey)->first();
if (!$personalAccessToken) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $next($request);
//Method 2: Token pass via request header
/*
$authHeader = $request->header('Authorization');
if (preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
$token = $matches[1];
// validate the token here
$personalAccessToken = PersonalAccessToken::where('token', $token)->first();
if (!$personalAccessToken) {
return response()->json(['error' => 'Unauthorized'], 401);
}
// if the token is valid, you can attach it to the request
$request->attributes->add(['bearerToken' => $token]);
return $next($request);
}
return response()->json(['error' => 'Unauthorized'], 401);
*/
}
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace App\Models;
class PersonalAccessTokens extends AbstractModel
{
protected $table = 'personal_access_tokens';
}
+5
View File
@@ -43,6 +43,11 @@ class RouteServiceProvider extends ServiceProvider
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::prefix('public/api')
->middleware('apipub')
->namespace($this->namespace)
->group(base_path('routes/apipub.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
// $table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
}
@@ -0,0 +1,126 @@
<template>
<div class="row align-items-center justify-content-center w-100">
<div class="col">
<div class='tetrominos'>
<div class='tetromino box1'></div>
<div class='tetromino box2'></div>
<div class='tetromino box3'></div>
<div class='tetromino box4'></div>
</div>
</div>
</div>
</template>
<style>
.tetrominos {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-112px, -96px);
}
.tetromino {
width: 96px;
height: 112px;
position: absolute;
transition: all ease 0.3s;
background: url('data:image/svg+xml;utf-8,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 684"%3E%3Cpath fill="%23010101" d="M305.7 0L0 170.9v342.3L305.7 684 612 513.2V170.9L305.7 0z"/%3E%3Cpath fill="%23fff" d="M305.7 80.1l-233.6 131 233.6 131 234.2-131-234.2-131"/%3E%3C/svg%3E') no-repeat top center;
}
.box1 {
animation: tetromino1 1.5s ease-out infinite;
}
.box2 {
animation: tetromino2 1.5s ease-out infinite;
}
.box3 {
animation: tetromino3 1.5s ease-out infinite;
z-index: 2;
}
.box4 {
animation: tetromino4 1.5s ease-out infinite;
}
@keyframes tetromino1 {
/* compose logo */
/* 1 on 3 */
/* L-shape */
0%,
40% {
transform: translate(0, 0);
}
50% {
/* pre-box */
transform: translate(48px, -27px);
}
60%,
100% {
/* box */
/* compose logo */
transform: translate(96px, 0);
}
}
@keyframes tetromino2 {
/* compose logo */
/* 1 on 3 */
0%,
20% {
transform: translate(96px, 0px);
}
40%,
100% {
/* L-shape */
/* box */
/* compose logo */
transform: translate(144px, 27px);
}
}
@keyframes tetromino3 {
/* compose logo */
0% {
transform: translate(144px, 27px);
}
20%,
60% {
/* 1 on 3 */
/* L-shape */
/* box */
transform: translate(96px, 54px);
}
90%,
100% {
/* compose logo */
transform: translate(48px, 27px);
}
}
@keyframes tetromino4 {
/* compose logo */
/* 1 on 3 */
/* L-shape */
/* box */
0%,
60% {
transform: translate(48px, 27px);
}
90%,
100% {
/* compose logo */
transform: translate(0, 0);
}
}
</style>
@@ -74,7 +74,7 @@ export default {
},
search() {
if (this.parameters.orderNo) {
window.location.href = this.route('order.v2.show', this.parameters.orderNo);
window.location.href = this.route('order.show', this.parameters.orderNo);
return;
}
}
File diff suppressed because one or more lines are too long
@@ -152,6 +152,8 @@
</div>
</div>
</div>
<order-package-v2-section-component v-if="!isLoading" :order_number="order_number"></order-package-v2-section-component>
</div>
</div>
</template>
+9
View File
@@ -0,0 +1,9 @@
<?php
use Illuminate\Support\Facades\Route;
Route::group(['middleware' => 'apipub', 'prefix' => 'v1', 'as' => 'apipub.'], function () {
Route::group(['middleware' => 'token.check'], function () {
Route::get('/list', 'Transactions\ListTransactionsController@list')->name('list');
});
});
+28 -7
View File
@@ -161,7 +161,7 @@ Route::post('/support', function (Request $request) {
if ($orderNo) {
if (Order::where('reference', $orderNo)->count()) {
return redirect(route('order.v2.show', $orderNo));
return redirect(route('order.show', $orderNo));
} else {
$orderNoNotFound = true;
}
@@ -195,7 +195,8 @@ Route::get('/orders-table', function () {
})->name('ordersTable');
Route::get('/order/show/{order_number}', function ($orderNumber) {
return view('pages.orders.profile', ['id' => $orderNumber]);
// return view('pages.orders.profile', ['id' => $orderNumber]);
return view('pages.orders.profile_v2', ['id' => $orderNumber]);
})->name('order.show');
Route::get('/order/v2/show/{order_number}', function ($orderNumber) {
@@ -431,10 +432,21 @@ Route::get('/settings', function () {
Route::get('/customer/{company_module_id}/summary', 'Exports\ExportCompanyModuleSummaryController@export')->name('customer.summary.export');
Route::get('/export-customer-order/{marking}', 'Exports\ExportCompanyModuleSummaryController@exportorderSummaryByMarking')->name('customer.orderSummary.export');
Route::get('/customer/summary/monthly', function () {
Route::get('/customer/summary/{year}/monthly', function ($year) {
if (!in_array($year, [2022, 2023])) {
return 'Year Error!';
}
// $containers = Container::whereMonth('loading_date', '>=', ((float)Carbon::now()->format('m') - 2))->whereYear('loading_date', (float)Carbon::now()->format('Y'))->get();
// $containers = Container::whereMonth('loading_date', '>=', 1)->whereYear('loading_date', 2023)->get();
$containers = Container::whereMonth('loading_date', '>=', 9)->whereYear('loading_date', 2022)->get();
if ($year == 2022) {
$containers = Container::whereMonth('loading_date', '>=', 9)->whereYear('loading_date', 2022)->get();
}
if ($year == 2023) {
$containers = Container::whereMonth('loading_date', '>=', 1)->whereYear('loading_date', 2023)->get();
}
$marking = '769SMC';
$connection = CompanyConnection::where('invitee_reference', $marking)->first();
$companyModuleId = $connection->invitee->id;
@@ -859,7 +871,7 @@ Route::get('/invoices/approve', function(Request $request){
Route::get('/invoices/show-duplicated', function(Request $request){
$transactionWithMultipleInvoice = DB::table('transactions')
->where('type', TransactionType::SHIPPING_INVOICE)
->where('status', '!=' , ApprovalStatus::EXPIRED)
->whereNotIn('status', [ApprovalStatus::EXPIRED, ApprovalStatus::SUSPENDED])
->where('deleted_at', null)
->select('owner_id', DB::raw('count(*) as count'))
->groupBy('owner_id')
@@ -888,9 +900,18 @@ Route::get('/invoices/show-duplicated', function(Request $request){
foreach($duplicatedInvoice as $invoice) {
$order = $invoice->owner->owner;
$billplzPaymentId = '';
if ($invoice->status == ApprovalStatus::COMPLETED) {
if ($invoice->transactions->first()->type == TransactionType::PAYMENT) {
$billplzPaymentId = $invoice->transactions->first()->payment_reference ;
}
}
echo "<tr>";
echo '<td style="border:1px solid"><a target="_blank" href="'.route('order.show', $order->reference).'">'. $order->reference.' - </a>' . $order->created_at . '</td>';
echo "<td style='border:1px solid'>".ApprovalStatus::APPROVAL_STATUS_ID[$invoice->status]."</td>";
echo "<td style='border:1px solid'>".ApprovalStatus::APPROVAL_STATUS_ID[$invoice->status]. ' Billplz reference: ' . $billplzPaymentId . "</td>";
echo "<td style='border:1px solid'>$invoice->owner_id</td>";
echo "<td style='border:1px solid'>$invoice->amount</td>";
echo "<td style='border:1px solid'>".$duplicatedOrderArray[$invoice->owner_id]."</td>";