diff --git a/app/Classes/General/Eloquent/Filters/AmountExceed.php b/app/Classes/General/Eloquent/Filters/AmountExceed.php
new file mode 100644
index 00000000..a3e353fa
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/AmountExceed.php
@@ -0,0 +1,19 @@
+where('amount', '>', $value);
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/AmountShort.php b/app/Classes/General/Eloquent/Filters/AmountShort.php
new file mode 100644
index 00000000..7406fc47
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/AmountShort.php
@@ -0,0 +1,19 @@
+where('amount', '<', $value);
+ }
+}
diff --git a/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php b/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php
new file mode 100644
index 00000000..7e563aee
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/CreatedAfterOrEqual.php
@@ -0,0 +1,21 @@
+where('created_at', '>=', Carbon::parse($value));
+ }
+}
\ No newline at end of file
diff --git a/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php b/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php
new file mode 100644
index 00000000..ed97b48f
--- /dev/null
+++ b/app/Classes/General/Eloquent/Filters/CreatedBeforeOrEqual.php
@@ -0,0 +1,20 @@
+where('created_at', '<=', Carbon::parse($value));
+ }
+}
diff --git a/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php
index a3c876d7..164546c3 100644
--- a/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php
+++ b/app/Classes/Modules/Accounting/Processors/CreateBankStatementTransactionOwnersProcessor.php
@@ -13,6 +13,8 @@ use App\Models\StatementTransaction;
use App\Models\Transaction;
use App\Models\Wallet;
use Carbon\Carbon;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
class CreateBankStatementTransactionOwnersProcessor
@@ -48,7 +50,7 @@ class CreateBankStatementTransactionOwnersProcessor
// Shipping Portal Sales
- $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2);
+ $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2, PaymentMethodType::WALLET);
foreach ($creditTransactions as $creditTransaction) {
if($creditTransaction['owner_type'] === Wallet::class) continue;
$transaction->owners()->firstOrCreate([
@@ -72,7 +74,7 @@ class CreateBankStatementTransactionOwnersProcessor
]);
}
- $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5);
+ $creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5, null);
foreach ($creditTransactions as $creditTransaction) {
$transaction->owners()->firstOrCreate([
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
@@ -191,25 +193,26 @@ class CreateBankStatementTransactionOwnersProcessor
}
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
- $dateRange = $this->getDateRange($date, 4);
- $query = $model::whereIn('status', $statuses)
- ->where(function ($query) use ($ownerType, $paymentMethod, $type) {
- if ($ownerType) {
- $query->where('owner_type', $ownerType);
- }
+ $dateRange = $this->getDateRange($date, 4);
+ if (App::environment(['production'])) {
+ $query = $model::whereIn('status', $statuses)
+ ->where(function ($query) use ($ownerType, $paymentMethod, $type) {
+ if ($ownerType) {
+ $query->where('owner_type', $ownerType);
+ }
- if ($paymentMethod) {
- $query->where('payment_method', '!=', $paymentMethod);
- }
+ if ($paymentMethod) {
+ $query->where('payment_method', '!=', $paymentMethod);
+ }
- if ($type) {
- $query->where('type', $type);
- }
- })
- ->whereDate('created_at', '>=', $dateRange['start_date'])
- ->whereDate('created_at', '<=', $dateRange['end_date'])
- ->where('amount', '>', ($amount - 0.05))
- ->where('amount', '<', ($amount + 0.05));
+ if ($type) {
+ $query->where('type', $type);
+ }
+ })
+ ->whereDate('created_at', '>=', $dateRange['start_date'])
+ ->whereDate('created_at', '<=', $dateRange['end_date'])
+ ->where('amount', '>', ($amount - 0.05))
+ ->where('amount', '<', ($amount + 0.05));
if ($query->count() > 1) {
$transactions = clone $query;
@@ -241,7 +244,6 @@ class CreateBankStatementTransactionOwnersProcessor
});
}
-
if ($ownerType === Wallet::class) {
$transactions = $transactions->whereHasMorph('owner', [Wallet::class], function ($q1) use ($keywords) {
return $q1->whereHasMorph('owner', [Company::class], function ($company) use($keywords) {
@@ -266,24 +268,60 @@ class CreateBankStatementTransactionOwnersProcessor
}
}
- return $query->get();
+ return $query->get();
+ } else {
+ $result = $this->getTransactionsFromExchange($amount, $dateRange, $type, $ownerType, $paymentMethod);
+ $transactionsId = Arr::pluck($result, 'owner_id');
+ $query = $model::whereIn('id', $transactionsId);
+
+ return $query->get();
+ }
}
- private function getTransactionsFromShippingPortal($amount, $dateRange, $type){
+ private function getTransactionsFromExchange($amount, $dateRange, $type, $ownerType, $paymentMethod){
+ $url = 'https://exchange.cief-malaysia.com/public/api/v1/transactions/mappable/query';
+ return $this->getFromExchange($url, $amount, $dateRange, $type, $ownerType, $paymentMethod);
+ }
+
+ private function getFromExchange($url, $amount, $dateRange, $type, $ownerType, $paymentMethod){
+ $paymentMethodFilter = "";
+ if ($paymentMethod) {
+ $paymentMethodFilter = ',"payment_method_not_in":['.$paymentMethod.']';
+ }
+ $ownerType = addslashes($ownerType);
+ try{
+ $client = new \GuzzleHttp\Client(['verify' => false]);
+ $response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2,3],"owner_type":"'. $ownerType . '"' . $paymentMethodFilter.',"type":'.$type.',"created_after_or_equal":"'.$dateRange['start_date'].'","created_before_or_equal":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).'}');
+ $body = $response->getBody();
+ $data = json_decode($body, true);
+ $payload = $data['payload'];
+ $transactions2 = $payload['data'];
+ return $transactions2;
+ }catch(\Exception $exception){
+ Log::error($exception);
+ return [];
+ }
+ }
+
+ private function getTransactionsFromShippingPortal($amount, $dateRange, $type, $paymentMethod){
$url = 'https://izyim.cief-malaysia.com/public/api/v1/transactions/mappable/query';
- return $this->getFromShippingPortal($amount, $dateRange, $url, $type);
+ return $this->getFromShippingPortal($amount, $dateRange, $url, $type, $paymentMethod);
}
- private function getGroupsFromShippingPortal($amount, $dateRange, $type){
+ private function getGroupsFromShippingPortal($amount, $dateRange, $type, $paymentMethod){
$url = 'https://izyim.cief-malaysia.com/public/api/v1/groups/query';
- return $this->getFromShippingPortal($amount, $dateRange, $url, $type);
+ return $this->getFromShippingPortal($amount, $dateRange, $url, $type, $paymentMethod);
}
- private function getFromShippingPortal($amount, $dateRange, $url, $type){
+ private function getFromShippingPortal($amount, $dateRange, $url, $type, $paymentMethod){
+ $paymentMethodFilter = "";
+ if ($paymentMethod) {
+ $paymentMethodFilter = ',"payment_method_not_in":['.$paymentMethod.']';
+ }
try{
$client = new \GuzzleHttp\Client(['verify' => false]);
- $response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2],"type":2,"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in:"['.$type.']}');
+ $response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":['.$type.']}');
$body = $response->getBody();
$data = json_decode($body, true);
$payload = $data['payload'];
diff --git a/app/Classes/Modules/Transactions/ControllersLogic/ListMappableTransactionsLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/ListMappableTransactionsLogic.php
new file mode 100644
index 00000000..fe2e7909
--- /dev/null
+++ b/app/Classes/Modules/Transactions/ControllersLogic/ListMappableTransactionsLogic.php
@@ -0,0 +1,49 @@
+ 'Retrieved Transactions',
+ 'message' => 'You have successfully retrieved a list of transactions'
+ ];
+ }
+
+
+ /** @var ListsTransactions */
+ private $listsTransactions;
+
+ /**
+ * ListTransactionsLogic constructor.
+ * @param ListsTransactions $listsTransactions
+ */
+ public function __construct(ListsTransactions $listsTransactions)
+ {
+ $this->listsTransactions = $listsTransactions;
+ }
+
+
+
+ public function logic(Request $request) : JsonResponse
+ {
+ $query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
+
+ return $this->collectionResponse(MappableTransactionResource::collection($query));
+ }
+
+
+
+}
diff --git a/app/Http/Controllers/Transactions/ListMappableTransactionsController.php b/app/Http/Controllers/Transactions/ListMappableTransactionsController.php
new file mode 100644
index 00000000..abf83758
--- /dev/null
+++ b/app/Http/Controllers/Transactions/ListMappableTransactionsController.php
@@ -0,0 +1,20 @@
+execute($request);
+ }
+}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 801c6ec0..25aeaf38 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -53,6 +53,10 @@ class Kernel extends HttpKernel
\Illuminate\Routing\Middleware\SubstituteBindings::class,
// \App\Http\Middleware\ApiRouteLogs::class,
],
+
+ 'apipub' => [
+ \Illuminate\Routing\Middleware\SubstituteBindings::class,
+ ],
];
/**
@@ -73,6 +77,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,
];
}
diff --git a/app/Http/Middleware/TokenCheckerMiddleware.php b/app/Http/Middleware/TokenCheckerMiddleware.php
new file mode 100644
index 00000000..480ea348
--- /dev/null
+++ b/app/Http/Middleware/TokenCheckerMiddleware.php
@@ -0,0 +1,56 @@
+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);
+ */
+ }
+}
diff --git a/app/Http/Resources/MappableTransactionResource.php b/app/Http/Resources/MappableTransactionResource.php
new file mode 100644
index 00000000..22104839
--- /dev/null
+++ b/app/Http/Resources/MappableTransactionResource.php
@@ -0,0 +1,37 @@
+type === TransactionType::TOP_UP) {
+ $reference = $this->owner->owner->reference;
+ }
+
+ if($this->type === TransactionType::PAYMENT && $this->owner !== Wallet::class){
+ $reference = $this->owner->marking;
+ }
+
+ return [
+ 'status' => 'success',
+ 'system' => 'EXCHANGE',
+ 'type' => $this->type,
+ 'owner_type' => $this->owner_type,
+ 'owner_id'=> $this->id,
+ 'owner_reference'=> $reference,
+ ];
+ }
+}
diff --git a/app/Models/PersonalAccessTokens.php b/app/Models/PersonalAccessTokens.php
new file mode 100644
index 00000000..5efc331d
--- /dev/null
+++ b/app/Models/PersonalAccessTokens.php
@@ -0,0 +1,9 @@
+mapWebRoutes();
+ $this->mapApiPubRoutes();
+
//
}
@@ -77,4 +79,19 @@ class RouteServiceProvider extends ServiceProvider
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
+
+ /**
+ * Define the "apipub" routes for the application.
+ *
+ * These routes are typically stateless.
+ *
+ * @return void
+ */
+ protected function mapApiPubRoutes()
+ {
+ Route::prefix('public/api')
+ ->middleware('apipub')
+ ->namespace($this->namespace)
+ ->group(base_path('routes/apipub.php'));
+ }
}
diff --git a/database/migrations/2023_09_13_161941_create_personal_access_tokens_table.php b/database/migrations/2023_09_13_161941_create_personal_access_tokens_table.php
new file mode 100644
index 00000000..691a4bf8
--- /dev/null
+++ b/database/migrations/2023_09_13_161941_create_personal_access_tokens_table.php
@@ -0,0 +1,36 @@
+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');
+ }
+}
diff --git a/resources/assets/vue/components/wallets/elements/CustomerTransactionPreciseSectionComponent.vue b/resources/assets/vue/components/wallets/elements/CustomerTransactionPreciseSectionComponent.vue
new file mode 100644
index 00000000..85868a2b
--- /dev/null
+++ b/resources/assets/vue/components/wallets/elements/CustomerTransactionPreciseSectionComponent.vue
@@ -0,0 +1,174 @@
+
+ Nothing To Show
+ Here Nothing
+ To Show HereTransaction History
+ 
