Compare commits

...

134 Commits

Author SHA1 Message Date
Dillon Ngo 1bcad555a0 Second high priority queue through database 2024-02-13 22:06:38 +08:00
Dillon Ngo f83c89b5f3 Second high priority queue through database 2024-01-26 04:03:06 +08:00
Dillon Ngo 8fc3ac1b55 Vue Polling - Solve a problem where query of packing list with contaienrs and packages data is taking too long to complete 2024-01-26 03:18:58 +08:00
Dillon Ngo b6c9c8843d Vue Polling - Solve a problem where query of packing list with contaienrs and packages data is taking too long to complete 2024-01-26 02:19:31 +08:00
Dillon Ngo e2b378e197 Vue Polling - Solve a problem where query of packing list with contaienrs and packages data is taking too long to complete 2024-01-21 22:48:48 +08:00
Dillon Ngo d034a285fc Vue Polling - Solve a problem where query of packing list with contaienrs and packages data is taking too long to complete 2024-01-21 22:31:16 +08:00
Dillon Ngo a9e89a45bd Experimental solution (Vue Polling) to solve an AWS API Gateway problem limitation for Laravel Vapor in the event of a emergency rollback to Google 2024-01-21 10:53:23 +08:00
Dillon Ngo 9b9057ea81 Experimental solution (Vue Polling) to solve an AWS API Gateway problem limitation for Laravel Vapor in the event of a emergency rollback to Google 2024-01-21 10:31:39 +08:00
Dillon Ngo 33d2d02cb0 Merge branch 'dillon/51-vue-polling-experimental-2' into 'master'
Undo Experimental solution (Vue Polling)

See merge request CIEFWorldwideSdnBhd/shipping-portal!190
2024-01-20 19:16:33 +00:00
Dillon Ngo e5be6eaceb Undo Experimental solution (Vue Polling) 2024-01-21 03:15:46 +08:00
edmondlang a545e6bad6 add bill_no in transaction details page 2024-01-17 17:19:37 +08:00
Dillon Ngo ee17ac0b0c Merge branch 'dillon/51-vue-polling-experimental-2' into 'master'
Experimental solution (Vue Polling) to solve an AWS API Gateway problem limitation for Laravel Vapor in the event of a emergency rollback to Google

See merge request CIEFWorldwideSdnBhd/shipping-portal!189
2024-01-15 16:43:45 +00:00
Dillon Ngo 26742a7335 Merge branch 'dillon/46.3.1-warehouse-storage-charges-fixes' into 'master'
Fix a problem with manual payment options not available when paying for invoices with warehouse storage charges

See merge request CIEFWorldwideSdnBhd/shipping-portal!188
2024-01-15 16:28:47 +00:00
Dillon Ngo 0e822ff1dd UI/UX amendment for order page when paying with storage invoice 2024-01-15 08:38:13 +08:00
Dillon Ngo 085b8b349f UI/UX amendment for order page when paying with storage invoice 2024-01-15 06:41:41 +08:00
edmondlang c1164397e8 fix errors diplaying in console in settings - warehouse 2024-01-14 22:56:45 +08:00
Dillon Ngo 3c16253795 Fix manual payment not showing in single order page when storage invoice is present 2024-01-14 09:33:31 +08:00
edmondlang 18a201611e add bind key for postcode array 2024-01-11 17:50:43 +08:00
edmondlang 7e754a9c7b add search postcode 2024-01-11 17:37:01 +08:00
edmondlang beb200fd6a Merge branch 'steve/account-mapping' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal 2024-01-11 10:59:40 +08:00
Steve Ng f0cb7828c3 invoice date for shipping portal when export invoice to autocount 2024-01-10 19:10:21 +08:00
Dillon Ngo 1956a4095d Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2024-01-08 17:49:42 +08:00
Dillon Ngo 71559701f4 Merge branch 'dillon/46.3-warehouse-storage-charges-fixes' into 'master'
Fix attempt on storage invoice pdf not able to be downloaded by user

See merge request CIEFWorldwideSdnBhd/shipping-portal!187
2024-01-05 21:55:59 +00:00
Dillon Ngo 9ceba30680 Fix attempt on storage invoice pdf not able to be downloaded by user 2024-01-06 05:53:59 +08:00
Dillon Ngo 3b2d06ed8f Fix attempt on storage invoice pdf not able to be downloaded by user 2024-01-06 05:52:55 +08:00
Dillon Ngo 81e04e9cb0 Fix attempt on storage invoice pdf not able to be downloaded by user 2024-01-06 05:52:26 +08:00
Dillon Ngo 286ca64413 Merge branch 'dillon/46.3-warehouse-storage-charges-fixes' into 'master'
Fix attempt on storage invoice pdf not able to be downloaded by user

See merge request CIEFWorldwideSdnBhd/shipping-portal!186
2024-01-05 21:11:33 +00:00
Dillon Ngo 51a96812fd Fix attempt on storage invoice pdf not able to be downloaded by user 2024-01-06 05:10:50 +08:00
Dillon Ngo 07459b9a1b Merge branch 'dillon/46.3-warehouse-storage-charges-fixes' into 'master'
Fix attempt on storage invoice pdf not able to be downloaded by user

See merge request CIEFWorldwideSdnBhd/shipping-portal!185
2024-01-05 21:08:00 +00:00
Dillon Ngo ee69f9123c Fix attempt on storage invoice pdf not able to be downloaded by user 2024-01-06 05:05:59 +08:00
Steve Ng 7a2ed92147 change posting date to invoice date for shipping portal when export invoice to autocount 2024-01-05 11:10:42 +08:00
Dillon Ngo 894481591d Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2024-01-04 13:52:11 +08:00
Dillon Ngo e5580c2abd Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2024-01-04 02:50:55 +08:00
Dillon Ngo 47ee304da1 Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2024-01-04 02:10:04 +08:00
Steve Ng 6427e2996f change posting date to invoice date for shipping portal when export invoice to autocount 2024-01-03 09:05:07 +08:00
Dillon Ngo f54aae5dc9 Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2024-01-03 05:39:43 +08:00
Dillon Ngo f0ef9a5602 Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2023-12-30 19:13:40 +08:00
Dillon Ngo 4d682c2ac6 Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2023-12-26 04:21:46 +08:00
Dillon Ngo 8ea00e0383 Proof of concept - Vue Polling - Performance Improvement and tweaking for better user experience 2023-12-24 21:59:41 +08:00
Dillon Ngo e0805a9601 Merge branch 'dillon/46-warehouse-storage-charges-2-merge-conflict' into 'master'
Emergency fix problem with group payment (reported by Eileen)

See merge request CIEFWorldwideSdnBhd/shipping-portal!184
2023-12-20 18:19:08 +00:00
Dillon Ngo 6f36c4b7ee Emergency fix problem with group payment (reported by Eileen) 2023-12-21 02:17:04 +08:00
Dillon Ngo 87194794f2 Merge branch 'dillon/46-warehouse-storage-charges-2-merge-conflict' into 'master'
Emergency fix problem with group payment (reported by Eileen)

See merge request CIEFWorldwideSdnBhd/shipping-portal!183
2023-12-20 16:06:34 +00:00
Dillon Ngo b4eca67a2f Emergency fix problem with group payment (reported by Eileen) 2023-12-20 23:58:56 +08:00
Dillon Ngo 1770b06498 Merge branch 'dillon/46-warehouse-storage-charges-2-merge-conflict' into 'master'
Emergency fix problem with group payment (reported by Eileen)

See merge request CIEFWorldwideSdnBhd/shipping-portal!182
2023-12-20 12:58:32 +00:00
Dillon Ngo 5c9fd6e2a6 Emergency fix problem with group payment (reported by Eileen) 2023-12-20 20:52:24 +08:00
Dillon Ngo 18df1c0c7b Proof of concept - Vue Polling a workaround for AWS API Gateway limitation 2023-12-20 14:47:56 +08:00
Dillon Ngo 359c103d01 Code sync from Exchange 2023-12-17 17:23:04 +08:00
Dillon Ngo ed7a636a18 Merge branch 'dillon/46-warehouse-storage-charges-2-merge-conflict' into 'master'
Fix a typo error

See merge request CIEFWorldwideSdnBhd/shipping-portal!181
2023-12-11 17:08:06 +00:00
Dillon Ngo 19bd548127 Fix a typo error 2023-12-12 01:07:06 +08:00
Dillon Ngo 55ac8064b1 Merge branch 'dillon/46-warehouse-storage-charges-2-merge-conflict' into 'master'
Warehouse Storage Charges - Effective From 11/12/2023 onwards

See merge request CIEFWorldwideSdnBhd/shipping-portal!180
2023-12-11 13:36:41 +00:00
Dillon Ngo e7279ec4d0 Merge branch 'master' into dillon/46-warehouse-storage-charges-2-merge-conflict 2023-12-11 21:29:06 +08:00
Dillon Ngo a7d4299897 Fix a typo error 2023-12-10 22:59:49 +08:00
Dillon Ngo 2b507d1006 Fix a typo error 2023-12-10 22:56:05 +08:00
Dillon Ngo 782a5c33ad Merge branch 'dillon/48-feedback-form-improvement' into 'master'
Update title for public feedback form page requested by Omair

See merge request CIEFWorldwideSdnBhd/shipping-portal!179
2023-12-09 04:54:15 +00:00
Dillon Ngo 6d3a2d9259 Update title for public feedback form page requested by Omair 2023-12-09 12:50:12 +08:00
Dillon Ngo 730b3d439a Merge branch 'dillon/48-feedback-form-improvement' into 'master'
Feedback form improvement

See merge request CIEFWorldwideSdnBhd/shipping-portal!178
2023-12-08 12:23:51 +00:00
Dillon Ngo 6b09d5facc Minor update on question text 2023-12-08 13:41:00 +08:00
Dillon Ngo 138a4f1cf6 Deleted some lines of codes 2023-12-07 17:17:39 +08:00
Dillon Ngo b54d897060 Remove <br> from payment transaction exported to excel file 2023-12-07 16:50:05 +08:00
Dillon Ngo c12959b4a8 Deleted some lines of codes 2023-12-07 16:44:06 +08:00
Dillon Ngo f94f380c16 Deleted some lines of codes 2023-12-07 16:42:52 +08:00
Dillon Ngo f46ec19f01 Update effective date for warehouse storage charges + commands to check for storage invoices 2023-12-07 16:35:51 +08:00
Omair Saleh c7a6a5b020 remove the 2 days delay for the ETA 2023-12-06 16:42:22 +08:00
Omair Saleh 8f64769214 remove the 2 days delay for the ETA 2023-12-06 16:38:57 +08:00
Dillon Ngo cb74228a68 Fix a problem reported by Yien where storage invoice number of days kept updated even though storage invoice already paid 2023-12-05 13:19:45 +08:00
Dillon Ngo b22cc0f7e3 Yien requested for some text description in invoice to be updated 2023-11-30 16:00:43 +08:00
Dillon Ngo 2e8ba4f630 Fix an error to export payment transaction in excel file 2023-11-30 13:56:35 +08:00
Dillon Ngo e987838d5a Fix 2 problem with generating storage invoice and export payment transaction in excel by date range 2023-11-30 13:36:38 +08:00
Omair Saleh 4c532deb4d debug yd address update 2023-11-28 22:44:36 +08:00
edmondlang 12f05b7aa6 add paymentUnknownOrderLog 2023-11-28 22:15:36 +08:00
Dillon Ngo 48fa67ae8c Fix a problem with starting date should be done on arrival date of goods to china warehouse 2023-11-27 19:29:13 +08:00
Dillon Ngo 1e9e94b581 Fix a problem with starting date should be done on arrival date of goods to china warehouse 2023-11-27 19:20:45 +08:00
Dillon Ngo 67653b60fb Fix a problem with starting date should be done on arrival date of goods to china warehouse 2023-11-27 19:14:32 +08:00
Dillon Ngo 26fffb8af1 Fix decimal number to lengthy 2023-11-27 09:35:34 +08:00
edmondlang 5cdbc09c5b update packinglist measurement - add order number 2023-11-26 23:45:32 +08:00
edmondlang c9877bb53e update packinglist measurement - change from order number to packinglist number 2023-11-26 22:21:02 +08:00
edmondlang 0bf84fa7b1 update combined invoice and packinglist measurement 2023-11-26 22:01:02 +08:00
Dillon Ngo fb0c74d645 Handling of dispute for warehouse storage fee 2023-11-24 13:44:28 +08:00
Dillon Ngo 53293f26d6 Amendment for Yien to do testing at dev environment 2023-11-24 02:29:05 +08:00
Dillon Ngo 56fe5520ad Amendment for Yien to do testing at dev environment 2023-11-24 00:33:07 +08:00
Dillon Ngo 4c9235cc53 Fix a tiny spelling mistake 2023-11-22 03:22:39 +08:00
Dillon Ngo babd492caa Questions should have order by just like answers 2023-11-22 03:14:36 +08:00
Dillon Ngo 3d1d1cce11 Fix feedback answer text not displaying correctly at admin dashboard 2023-11-21 19:41:30 +08:00
Dillon Ngo 820d96858f Feedback Form Improvement 2023-11-21 19:29:40 +08:00
Dillon Ngo 058ba592bf Merge branch 'dillon/48-feedback-form-improvement' into 'master'
Quick fix for feedback form entries cannot be downloaded

See merge request CIEFWorldwideSdnBhd/shipping-portal!177
2023-11-21 08:41:54 +00:00
Dillon Ngo d950ee3d68 Quick fix for feedback form entries cannot be downloaded 2023-11-21 16:34:32 +08:00
Dillon Ngo 61c801e216 Fix storage invoice with outdated info 2023-11-17 14:43:22 +08:00
Dillon Ngo 6f0acec390 Rename file, function + disable delete function for expired group payment 2023-11-17 14:16:02 +08:00
Dillon Ngo 76e3668563 20231109 Meeting Feedback 1 Fixes for warehouse storage charges 2023-11-16 22:40:26 +08:00
Dillon Ngo ce94dd1393 Fix for invoice status update using common function 2023-11-09 12:08:43 +08:00
Dillon Ngo c1ea087c58 Fix for storage invoice get to be generated even when the packingList not yet have APPROVED status 2023-11-09 08:34:03 +08:00
Dillon Ngo 8595d0987f Typo fix 2023-11-04 17:12:42 +08:00
Dillon Ngo 48d0460eef Debug billplz callback 2023-11-04 16:41:23 +08:00
Dillon Ngo 06751fdc78 New Warehouse Storage Fee 2023-11-04 14:58:50 +08:00
edmondlang da6ec00dbd cleanup 2023-10-27 16:13:43 +08:00
edmondlang 412dbd64d5 fix-payment-status-updated-but-failed-update-invoice 2023-10-27 16:12:31 +08:00
edmondlang 496df549f6 remove code 2023-10-27 10:10:02 +08:00
edmondlang 97eaefa45a regenerate single invoice 2023-10-27 09:16:23 +08:00
edmondlang 68c9e0451a update admin geenrate invoice view 2023-10-27 08:55:54 +08:00
Dillon Ngo b5bcd5c553 Quick test on dev server 2023-10-27 04:18:39 +08:00
JiaSheng 671c7a54fb fix delivery order in shipping invoice 2023-10-26 22:31:10 +08:00
edmondlang 2a28183426 hide wallet result not found 2023-10-24 01:04:41 +08:00
edmondlang 0ebea79750 Merge branch 'wallet-new-feature' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal 2023-10-24 00:51:16 +08:00
edmondlang a701242646 fix wallet audit 2023-10-24 00:49:07 +08:00
edmondlang 4bdeae997d Merge branch 'wallet-audit' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal 2023-10-23 23:54:19 +08:00
edmondlang 36809f34cc Merge branch 'steve/aging-listing' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal 2023-10-23 23:53:35 +08:00
edmondlang 032171bb18 update aging listing 2023-10-23 23:53:10 +08:00
JiaSheng d41bd3db39 fix bug when packing list is deleted 2023-10-23 22:00:31 +08:00
JiaSheng 56bba0eaaf wallet pagination, export 2023-10-22 23:46:09 +08:00
edmondlang af8444e0d9 Merge branch 'wallet-audit' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal 2023-10-20 16:30:33 +08:00
edmondlang b2a7d1f73d update group payment 2023-10-20 16:26:18 +08:00
edmondlang 9d2ff3fafa update cash payment method 2023-10-20 16:22:19 +08:00
edmondlang 487d07e28c update design for approve payment 2023-10-20 16:02:04 +08:00
edmondlang 4176e09ea3 fix bug upload receipt modal not showing 2023-10-20 15:46:59 +08:00
edmondlang c44bf46a42 update web route for active wallet 2023-10-20 15:14:29 +08:00
edmondlang e687dd2b9a deletes payment 2023-10-19 22:54:21 +08:00
edmondlang 59951c4efd updater delete group transaction 2023-10-19 22:02:14 +08:00
edmondlang c00a4712a0 revert 2023-10-19 21:41:48 +08:00
edmondlang 1bb07e9402 revert 2023-10-19 21:38:24 +08:00
edmondlang 683bdec1f7 revert 2023-10-19 21:27:19 +08:00
edmondlang ee53a9438a temporary show all invoice 2023-10-19 21:25:44 +08:00
edmondlang 2e2087f16e temporary show all invoice 2023-10-19 21:23:15 +08:00
edmondlang 998b0b4da5 update delete group transaction 2023-10-19 20:48:22 +08:00
edmondlang dcf5c2e455 show billplz failed callback command 2023-10-19 20:14:59 +08:00
edmondlang 156b1dee07 update logic, for group payment, wallet must be credited first, then make group payment 2023-10-19 13:50:59 +08:00
edmondlang 544d7907c3 Merge branch 'master' of https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal into wallet-audit 2023-10-19 13:43:53 +08:00
edmondlang 5b77f7baa6 add group payment in top up history 2023-10-19 11:44:25 +08:00
Jia Sheng Lee b33016aac4 only super admin can use the manual transfer for group payment 2023-10-18 15:28:12 +08:00
Jia Sheng Lee 2788e349ae manual transfer for admin to upload for bulk invoice payment 2023-10-18 15:06:46 +08:00
Steve Ng 04af87f640 csv download aging report 2023-10-18 08:48:30 +08:00
edmondlang 5b190d5334 revert ExportPendingArrangementPackingListV2Controller 2023-10-16 13:48:58 +08:00
Dillon Ngo 8f32769656 Merge branch 'dillon/44-quick-undo' into 'master'
Quick undo experimental security check

See merge request CIEFWorldwideSdnBhd/shipping-portal!176
2023-10-16 05:33:40 +00:00
Jia Sheng Lee 2d175f4acc recalculate wallet balance 2023-10-14 15:57:22 +08:00
Jia Sheng Lee 782aed06e4 add callback processor 2023-10-09 13:51:15 +08:00
167 changed files with 6524 additions and 449 deletions
@@ -0,0 +1,11 @@
<?php
namespace App\Classes\Exceptions;
use App\Classes\ValueObjects\Constants\HttpStatus;
final class JobResourceNotFoundException extends ServiceApiException {
public function __construct(?string $message = null) {
parent::__construct($message ?? 'Unable to find the requested resource', HttpStatus::RESOURCE_NOT_FOUND);
}
}
@@ -15,6 +15,8 @@ use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Facades\DB;
use App\Classes\Exceptions\JobResourceNotFoundException;
use Illuminate\Support\Facades\Log;
abstract class AbstractControllerLogic
{
@@ -62,6 +64,19 @@ abstract class AbstractControllerLogic
return $response;
} catch (ErrorException|GeneralExceptions|TypeError $exception){
if ($exception instanceof JobResourceNotFoundException) {
Log::error(sprintf(
"Uncaught exception '%s' with message '%s' in %s:%d",
get_class($exception),
$exception->getMessage(),
$exception->getTrace()[0]['file'],
$exception->getTrace()[0]['line']
));
}
else{
Log::error($exception);
}
return (new ApiResponseObject($this->getNotificationTitle().' failed', $exception->getMessage(),
!in_array($exception->getCode(), [0, 42000]) ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler();
@@ -6,6 +6,8 @@ namespace App\Classes\General\Eloquent;
use App\Classes\Exceptions\ResourceNotFoundException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use App\Classes\Exceptions\JobResourceNotFoundException;
abstract class AbstractFetchRecord extends AbstractGetRecord
{
@@ -26,12 +28,18 @@ abstract class AbstractFetchRecord extends AbstractGetRecord
* @return Model
* @throws ResourceNotFoundException
*/
public function getResults(Builder $query): Model {
public function getResults(Builder $query, array $param = []): Model {
if(!$query->exists()){
throw new ResourceNotFoundException('Unable to find any record based on the criteria provided');
$table = $query->getModel()->getTable();
if($table ==='job_results'){
throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided');
}
else{
throw new ResourceNotFoundException('Unable to find any record based on the criteria provided');
}
}
return $query->first();
}
}
}
@@ -50,9 +50,9 @@ abstract class AbstractGetRecord
* @param array $filters
* @return mixed
*/
public function handler(array $filters){
public function handler(array $filters, array $params = []){
$this->filters = collect($filters);
return $this->getResults($this->applyFiltersToQuery());
return $this->getResults($this->applyFiltersToQuery(), $params);
}
@@ -65,6 +65,6 @@ abstract class AbstractGetRecord
* @param Builder $query
* @return mixed
*/
abstract function getResults(Builder $query);
abstract function getResults(Builder $query, array $params = []);
}
}
@@ -16,11 +16,10 @@ abstract class AbstractListRecord extends AbstractGetRecord
* @return mixed
* @throws MalformedRequestException
*/
public function execute(array $filters = []){
public function execute(array $filters = [], array $param = []){
try{
return $this->handler($filters);
return $this->handler($filters, $param);
} catch (QueryException $exception){
throw new MalformedRequestException('Unable to fetch the list of records due to unexpected error');
@@ -32,7 +31,7 @@ abstract class AbstractListRecord extends AbstractGetRecord
* @param Builder $query
* @return mixed
*/
public function getResults(Builder $query) {
public function getResults(Builder $query, array $param = []) {
$filters = $this->getDecorationFilters();
if($filters->has('order_by')){
@@ -44,8 +43,12 @@ abstract class AbstractListRecord extends AbstractGetRecord
}
//dd($query->toSql());
return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get();
if(!empty($param)){
return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get(); //page data from query parameters e.g ?page=1
}
else{
return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get();
}
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
class CreatedAfterOrEqual implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
$table = $builder->getModel()->getTable();
$startDate = Carbon::createFromFormat('d-m-Y', $value)->startOfDay();
return $builder->where("{$table}.created_at", '>=', $startDate);
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
class CreatedBeforeOrEqual implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
$table = $builder->getModel()->getTable();
$endDate = Carbon::createFromFormat('d-m-Y', $value)->endOfDay();
return $builder->where("{$table}.created_at", '<=', $endDate);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class JobId implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('job_id', $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OrderByIdDesc implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->orderBy('id', 'desc');
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OrderByUpdatedAtDesc implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->orderBy('updated_at', 'desc');
}
}
@@ -14,7 +14,8 @@ class OwnerId implements Filter
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('owner_id', $value);
$table = $builder->getModel()->getTable();
return $builder->where("{$table}.owner_id", $value);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class OwnerType implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
$table = $builder->getModel()->getTable();
return $builder->where("{$table}.owner_type", $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class PostcodeLike implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('postcode', 'LIKE', '%'.$value.'%');
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class RequestSignature implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('request_signature', $value);
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class ResultNotNull implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereNotNull('result');
}
}
@@ -14,7 +14,8 @@ class StatusIn implements Filter
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereIn('status', $value);
$table = $builder->getModel()->getTable();
return $builder->whereIn("{$table}.status", $value);
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Builder;
class WithAgingColumn implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
$today = Carbon::now();
return $builder->select('packing_lists.*')
->addSelect(DB::raw("DATEDIFF('$today', transactions.updated_at) as days_over_duedate"))
->addSelect(DB::raw("CASE
WHEN DATEDIFF('$today', transactions.updated_at) <= 0 THEN 0
WHEN DATEDIFF('$today', transactions.updated_at) > 0 AND DATEDIFF('$today', transactions.updated_at) <= 30 THEN 1
WHEN DATEDIFF('$today', transactions.updated_at) > 30 AND DATEDIFF('$today', transactions.updated_at) <= 60 THEN 2
WHEN DATEDIFF('$today', transactions.updated_at) > 60 AND DATEDIFF('$today', transactions.updated_at) <= 90 THEN 3
ELSE 4
END AS due_date_number"));
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithContainersPackages implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->with(['containers', 'packages']);
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithOrderReferenceLike implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->join('transactions as t2', 't2.payment_reference', '=', 'transactions.bill_no')
->join('transactions as t3', 't3.id', '=', 't2.owner_id')
->join('packing_lists', 'packing_lists.id', '=', 't3.owner_id')
->join('orders', function ($join) use ($value) {
$join->on('orders.id', '=', 'packing_lists.owner_id')
->where('orders.reference', 'LIKE', '%'.$value.'%');
})
->addSelect(['transactions.*', 't2.id as paymentTransactionId', 't3.id as invoiceTransactionId', 'packing_lists.id as packingListId', 'orders.reference as orderReference']);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithTrashed implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->withTrashed();
}
}
+9
View File
@@ -2,6 +2,7 @@
namespace App\Classes\General;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
@@ -40,4 +41,12 @@ class Helper
}
}
}
/**
* @param ResourceCollection $collection
* @return array
*/
static function collectionResponse(ResourceCollection $collection){
return json_decode($collection->response()->getContent(), true);
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\PackingLists\Processors\ListPackingListsJobProcessor;
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ListPackingListsJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
/** @var ListGenericJobObject */
private $listGenericJobObject;
/**
* ListPackingListsJob constructor.
* @param ListGenericJobObject $listGenericJobObject
*/
public function __construct(ListGenericJobObject $listGenericJobObject)
{
$this->listGenericJobObject = $listGenericJobObject;
}
public function handle()
{
$rawPayload = $this->job->payload();
if(isset($rawPayload['data']['commandName'])){
$this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']);
}
if(isset($rawPayload['data']['command'])){
$this->listGenericJobObject->setJobCommand($rawPayload['data']['command']);
}
$result = (App()->make(ListPackingListsJobProcessor::class))->execute($this->listGenericJobObject);
}
}
@@ -14,14 +14,17 @@ use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Group;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class CallbackBillplzLogic
{
@@ -46,6 +49,12 @@ class CallbackBillplzLogic
/** @var CreatePaymentTransactionProcessor */
private $createPaymentTransactionProcessor;
/** @var CallbackBillplzProcessor */
private $callbackBillplzProcessor;
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/**
* CallbackBillplzLogic constructor.
* @param GetBillplzBill $getBillplzBill
@@ -54,8 +63,10 @@ class CallbackBillplzLogic
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
* @param CallbackBillplzProcessor $callbackBillplzProcessor
* @param CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor
*/
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor)
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, CallbackBillplzProcessor $callbackBillplzProcessor, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
{
$this->getBillplzBill = $getBillplzBill;
$this->fetchesTransaction = $fetchesTransaction;
@@ -64,6 +75,8 @@ class CallbackBillplzLogic
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->updatesWalletBalance = $updatesWalletBalance;
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
$this->callbackBillplzProcessor = $callbackBillplzProcessor;
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
}
@@ -103,44 +116,13 @@ class CallbackBillplzLogic
$status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
}
Log::info('Debug billPlz status: '.$status);
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
// check if is wallet top up
if($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED &&!in_array($transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) {
$this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);
}
// group payment
if ($transaction->type == TransactionType::GROUP_PAYMENT && $status === ApprovalStatus::APPROVED &&!in_array($transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) {
$group = Group::where('reference', $billplzXSignatureObject->getBillPlzId())->first();
foreach($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null);
}
$group->status = $status;
$group->save();
}
$this->updatesTransactionStatus->execute($transaction, $status);
if (!$transaction->owner instanceof Wallet) {
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if(($invoice->amount - $totalPaidAmount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
}
}
$this->storageInvoiceBackDoorPreventionCheck($transaction, $status);
$result = $this->callbackBillplzProcessor->execute($transaction, $status);
$company_module_marking = $transaction->owner->owner->connections? $transaction->owner->owner->connections->first()->invitee_reference: null;
@@ -151,6 +133,22 @@ class CallbackBillplzLogic
$company_module_marking = $order->companyModule->connections? $order->companyModule->connections->first()->invitee_reference: null;
}
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $order->reference ?? null, 'company_module_marking' => $company_module_marking ?? null, 'transaction' => $transaction, 'status' => $status]);
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $order->reference ?? null, 'company_module_marking' => $company_module_marking ?? null, 'transaction' => $transaction, 'status' => $status, 'result' => $result]);
}
private function storageInvoiceBackDoorPreventionCheck($transaction, $status){
if ($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) {
$group = Group::where('reference', $transaction->payment_reference)->first();
if ($group) {
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$pL = $invoice->owner;
$order = $pL->owner;
if($order){
$this->storageInvoiceTransactionProcessor->executeOrder($order, false); //original was set true here so that no group is soft deleted or billplz bill got deleted
}
}
}
}
}
}
@@ -0,0 +1,128 @@
<?php
namespace App\Classes\Modules\Billplzs\Processors;
use Illuminate\Http\Request;
use App\Models\Wallet;
use App\Models\Group;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use Illuminate\Support\Facades\Log;
class CallbackBillplzProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor;
/** @var UpdatesWalletBalance */
private $updatesWalletBalance;
/** @var CreatePaymentTransactionProcessor */
private $createPaymentTransactionProcessor;
/** @var ReleaseGoodsToCustomerProcessor */
private $releaseGoodsToCustomerProcessor;
/**
* CreateUserProcessor constructor.
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
* @param UpdatesWalletBalance $updatesWalletBalance
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
* @param ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->updatesWalletBalance = $updatesWalletBalance;
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
}
/**
* @param Request $request
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute($transaction, $status)
{
$invoice = $transaction->owner;
$packingList = $invoice->owner;
$proceed = $this->checkForGroupPayment($transaction);
if(!$proceed) return false;
$this->updatesTransactionStatus->execute($transaction, $status);
// check if is wallet top up
if ($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) {
$this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);
$group = Group::where('reference', $transaction->payment_reference)->first();
// check if is group payment
if ($group) {
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null, false);
if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){
$pL = $invoice->owner;
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
}
}
$group->status = $status;
$group->save();
}
}
if (!$transaction->owner instanceof Wallet) {
$this->releaseGoodsToCustomerProcessor->execute($packingList, $invoice);
}
return true;
}
private function checkForGroupPayment($transaction){
//This check is targetting group payment that expired and soft deleted
//command:check-storage-invoices must already run for this part of the code to work properly
$group = Group::withTrashed()->where('reference', $transaction->payment_reference)->first();
if ($group) {
$totalAmountToBePaid = 0;
$actualAmountPaid = $transaction->amount;
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$totalAmountToBePaid += $invoice->amount;
}
if(($totalAmountToBePaid - $actualAmountPaid) < 0.01){
}
else{
Log::channel('storage_invoices')->info('Total amount from current transaction: '.$totalAmountToBePaid); //cief todo: to be removed
Log::channel('storage_invoices')->info('Total amount from paid transaction: '.$transaction->amount); //cief todo: to be removed
return false;
}
}
return true;
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Billplzs\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
class DeletesBillplzBill
{
/**
* @param string $billID
* @throws MalformedRequestException
*/
public function execute(string $billID) {
try{
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->delete(config('billplz.base_url').'/api/v3/bills/'.$billID);
Log::channel('storage_invoices')->info('DeletesBillplzBill response: '.json_encode($response));
if($response->successful()){
$data = $response->json();
// $data['url'] = $data['url'].'?auto_submit=true';
return (object) $data;
}else{
return null;
}
}catch(\Exception $exception){
throw new MalformedRequestException('Unable to get correct response from billplz server: ' . $exception->getMessage());
}
}
}
@@ -0,0 +1,98 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Models\Order;
use App\Models\PackingList;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use App\Classes\General\Eloquent\ApplyFiltersToQuery;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use DateTime;
class ExportsAgingList implements WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, FromQuery
{
use Exportable;
private $filters;
public function __construct()
{
$this->filters = [
"has_invoice_status_in" => [2],
"packing_list_ordered_by_invoice_date" => true,
"with_aging_column" => true
];
}
public function headings(): array
{
return [
'Company Name',
'Customer Marking',
'Order Number',
'Invoice No',
'Invoice Date',
'Days',
'Amount',
];
}
public function query()
{
return (new ApplyFiltersToQuery())->execute(PackingList::query(), $this->filters);
}
public function map($list): array
{
$marking = null;
$orderNo = null;
$name = null;
$invDate = 'n/a';
$invNo = 'n/a';
$days = 'n/a';
if ($list->owner instanceof Order) {
$inviterPivotInviteeReference = $list->owner->companyModule->inviters()->withPivot('invitee_reference')->first();
if ($inviterPivotInviteeReference) {
$marking = $inviterPivotInviteeReference->pivot->invitee_reference;
$orderNo = $list->owner->reference;
}
$name = $list->owner->companyModule->company->name;
}
$transaction = $list->transactions()->whereIn('status', [ApprovalStatus::APPROVED])->first();
if ($transaction) {
$invoiceDate = $transaction->created_at;
$invDate = date_format($invoiceDate, 'd-m-Y');
$invNo = $transaction->bill_no;
$amt = number_format($transaction->amount, 2);
$currentDate = new DateTime();
$interval = $currentDate->diff($invoiceDate);
$days = $interval->format('%a');
}
return [
$name,
$marking,
$orderNo,
$invNo,
$invDate,
$days,
$amt,
];
}
private function dueDateColumn($colNum, $dueDateNumber, $amt)
{
if ($colNum == $dueDateNumber) return $amt;
return null;
}
}
@@ -0,0 +1,108 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use App\Models\Company;
use App\Models\Wallet;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class ExportsCustomersWalletTransactionHistory implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
private $request;
private $runningBalance = 0;
public function __construct(Request $request)
{
$this->request = $request;
}
public function headings(): array
{
return [
'Date',
'Description',
'Incoming',
'Outgoing',
'Balance',
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
$wallet = Wallet::find($this->request->route('wallet_id'));
$transactions = $wallet->transactions()->whereIn('transactions.status', [2, 3])->orderBy('id');
return $transactions;
}
/**
* @param Transaction $transaction
*
* @return array
*/
public function map($transaction): array
{
$decimals = $this->request->route('is_precise') == 'true' ? 5 : 2;
$description = '';
switch ((int) $transaction->type) {
case TransactionType::TOP_UP:
$description = (float) $transaction->amount . ' Credit Top up';
break;
case TransactionType::GROUP_PAYMENT:
$description = (float) $transaction->amount . ' Credit Top up';
break;
case TransactionType::CREDIT_NOTE:
$description = 'Credit Voucher for ' . $transaction->payment_reference;
break;
case TransactionType::PAYMENT:
$booking = Transaction::where('payment_reference', $transaction->bill_no)->first()->owner;
if (!$booking) {
$description = 'Payment for unknown booking, please contact tech support.';
break;
}
$marking = $booking->marking;
$description = 'Payment For booking refs' . $marking;
break;
case TransactionType::DEBIT_NOTE:
$description = 'Debit Voucher for ' . $transaction->payment_reference;
break;
}
$incoming = $outgoing = '';
if (in_array($transaction->type, [TransactionType::TOP_UP, TransactionType::CREDIT_NOTE, TransactionType::GROUP_PAYMENT])) {
$incoming = number_format($transaction->amount, $decimals, '.', ',');
$this->runningBalance += $transaction->amount;
}
if (in_array($transaction->type, [TransactionType::PAYMENT, TransactionType::DEBIT_NOTE])) {
$outgoing = number_format($transaction->amount, $decimals, '.', ',');
$this->runningBalance -= $transaction->amount;
}
return [
Carbon::parse($transaction->created_at)->format('d-m-Y h:i:s A'),
$description,
$incoming,
$outgoing,
number_format($this->runningBalance, $decimals, '.', ',')
];
}
}
@@ -20,9 +20,11 @@ class ExportsFeedback implements FromQuery, WithHeadings, WithHeadingRow, WithMa
public function headings(): array
{
return [
'Version',
'Question Set',
'Question Text',
'Answer',
'Answer Text',
'Answer Value',
'Source System',
'Source Marking',
'Source Email',
@@ -38,7 +40,7 @@ class ExportsFeedback implements FromQuery, WithHeadings, WithHeadingRow, WithMa
return QAUserAnswerSelected::whereHas('question', function ($query) {
$query->whereHas('questionnaire', function ($innerQuery) {
$innerQuery->where('group', 'feedback');
})->where('created_at', '>', Carbon::now()->subMonths(1));
}); //->where('created_at', '>', Carbon::now()->subMonths(1));
})->orderBy('created_at', 'desc');
}
@@ -56,11 +58,14 @@ class ExportsFeedback implements FromQuery, WithHeadings, WithHeadingRow, WithMa
$companyModule = $user->companyModule()->first();
$user_marking = $companyModule ? $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference : "";
}
$answer = $userAnswer->answer;
return [
$userAnswer->question->questionnaire->version,
$userAnswer->question->questionnaire->description,
$userAnswer->question->question_text,
$userAnswer->free_text_answer,
$answer->display_text,
$answer->value,
$user ? QASystemSourceType::getText(QASystemSourceType::IZYIM) : QASystemSourceType::getText($source->system),
$user ? $user_marking : $source->marking,
$user ? $user->email : $source->email,
@@ -74,7 +74,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
$approvalStatus = ApprovalStatus::APPROVED;
}
$query->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [$approvalStatus]);
// $query->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [$approvalStatus]);
$query->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->whereIn('status', [$approvalStatus]);
if($start_date && $end_date) {
$query->whereBetween('updated_at', [
@@ -102,7 +103,12 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
$container = $transaction->owner->containers()->first();
$order = $transaction->owner->owner;
$company = $order->companyModule->company;
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'SHIPPING_FEE')->first();
if($transaction->type === TransactionType::STORAGE_INVOICE){
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'STORAGE_FEE')->first();
}
else{
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'SHIPPING_FEE')->first();
}
$marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$contact = $order->companyModule->company->contacts->first();
$userName = $order->companyModule->employees()->first();
@@ -118,6 +124,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
$furtherDescription .= $item->name.' '.$item->quantity.' CBM'."\n";
elseif($item->reference === 'MIN_CBM_CHARGES')
$furtherDescription .= $item->name.' '.$item->quantity.' CBM'."\n";
elseif($item->reference === 'STORAGE_FEE')
$furtherDescription .= str_replace('<br>', ' | ', $item->name).' '."\n";
else
$furtherDescription .= $item->name.' '.$item->quantity.' X '.$item->price."\n";
}
@@ -59,7 +59,7 @@ class ListQuestionsQALogic extends AbstractControllerLogic
$delimiter = "|";
$parts = explode($delimiter, $decriptedToken);
$questionSet = $parts[3];
$query = $this->listsHelpMenuQuestions->execute(['questionnaire_set_id' => $questionSet]);
$query = $this->listsHelpMenuQuestions->execute(['questionnaire_set_id' => $questionSet, 'order_by' => (object)['column' => 'order','DESC' => false]]);
return $this->collectionResponse(HelpMenuQuestionResource::collection($query));
}
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Modules\Jobs\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Jobs\Processors\FetchesJobResultProcessor;
use App\Http\Resources\JobResultResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchJobResultLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Data',
'message' => 'You have successfully retrieved data'
];
}
/** @var FetchesJobResultProcessor */
private $fetchesJobResultProcessor;
/**
* FetchJobResultLogic constructor.
* @param FetchesJobResultProcessor $fetchesJobResultProcessor
*/
public function __construct(FetchesJobResultProcessor $fetchesJobResultProcessor)
{
$this->fetchesJobResultProcessor = $fetchesJobResultProcessor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
$query = $this->fetchesJobResultProcessor->execute($request);
return $this->resourceResponse(new JobResultResource($query));
}
}
@@ -0,0 +1,118 @@
<?php
namespace App\Classes\Modules\Jobs\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class ListGenericJobObject implements DataTransferObject
{
/** @var string */
private $name;
/** @var array */
private $payload;
/** @var string */
private $jobId;
/** @var string */
private $requestSignature;
/** @var string */
private $resultSignature;
/** @var object */
private $userInfo;
/** @var string */
private $jobCommandName;
/** @var string */
private $jobCommand;
public function __construct(string $name, array $payload, string $requestSignature, ?string $resultSignature, string $jobId, object $userInfo = null)
{
$this->name = $name;
$this->payload = $payload;
$this->jobId = $jobId;
$this->requestSignature = $requestSignature;
$this->resultSignature = $resultSignature;
$this->userInfo = $userInfo;
}
/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @return array
*/
public function getPayload(): array
{
return $this->payload;
}
/**
* @return string
*/
public function getJobId(): string
{
return $this->jobId;
}
/**
* @return string
*/
public function getRequestSignature(): string
{
return $this->requestSignature;
}
/**
* @return string
*/
public function getResultSignature(): ?string
{
return $this->resultSignature;
}
/**
* @return object
*/
public function getUserInfo(): object
{
return $this->userInfo;
}
/**
* @return string
*/
public function getJobCommandName(): string
{
return $this->jobCommandName;
}
/**
* @return string
*/
public function getJobCommand(): string
{
return $this->jobCommand;
}
public function setJobCommandName(string $jobCommandName)
{
$this->jobCommandName = $jobCommandName;
}
public function setJobCommand(string $jobCommand)
{
$this->jobCommand = $jobCommand;
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Classes\Modules\Jobs\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class UpdateJobResultObject implements DataTransferObject
{
/** @var string */
private $result;
/** @var string */
private $resultSignature;
/** @var string */
private $jobCommandName;
/** @var string */
private $jobCommand;
public function __construct(string $result, string $resultSignature, string $jobCommandName, string $jobCommand)
{
$this->result = $result;
$this->resultSignature = $resultSignature;
$this->jobCommandName = $jobCommandName;
$this->jobCommand = $jobCommand;
}
/**
* @return string
*/
public function getResult(): string
{
return $this->result;
}
/**
* @return array
*/
public function getResultSignature(): string
{
return $this->resultSignature;
}
/**
* @return string
*/
public function getJobCommandName(): string
{
return $this->jobCommandName;
}
/**
* @return string
*/
public function getJobCommand(): string
{
return $this->jobCommand;
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Classes\Modules\Jobs\Processors;
use App\Classes\Exceptions\JobResourceNotFoundException;
use App\Classes\Modules\Jobs\Services\FetchesJobResult;
use Illuminate\Http\Request;
class FetchesJobResultProcessor
{
/** @var FetchesJobResult */
private $fetchesJobResult;
/**
* FetchesJobResultProcessor constructor.
* @param FetchesJobResult $fetchesJobResult
*/
public function __construct(FetchesJobResult $fetchesJobResult)
{
$this->fetchesJobResult = $fetchesJobResult;
}
/**
* @param Request $request
* @return Model
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
* @throws \App\Classes\Exceptions\ResourceNotFoundException
*/
public function execute(Request $request){
$res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]);
if($request->route('is_last')){
$res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
return $res2;
}
if(!$res1->result){
throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided');
}
return $res1;
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Classes\Modules\Jobs\Processors;
use App\Classes\Modules\Jobs\Services\UpdatesJobResult;
use App\Classes\Modules\Jobs\Services\FetchesJobResult;
use App\Classes\Exceptions\JobResourceNotFoundException;
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
use App\Classes\Modules\Jobs\DataTransferObjects\UpdateJobResultObject;
class UpdateJobResultProcessor
{
/** @var FetchesJobResult */
private $fetchesJobResult;
/** @var UpdatesJobResult */
private $updatesJobResult;
/**
* UpdateJobResultProcessor constructor.
* @param FetchesJobResult $fetchesJobResult
* @param UpdatesJobResult $updatesJobResult
*/
public function __construct(FetchesJobResult $fetchesJobResult, UpdatesJobResult $updatesJobResult)
{
$this->fetchesJobResult = $fetchesJobResult;
$this->updatesJobResult = $updatesJobResult;
}
/**
* @param ListGenericJobObject $listGenericJobObject
* @param array $resultCurrent
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
*/
public function execute(ListGenericJobObject $listGenericJobObject, $resultCurrent) {
$jobResultCurrent = $this->fetchesJobResult->execute(['job_id' => $listGenericJobObject->getJobId()]);
$resultCurrentJson = json_encode($resultCurrent);
$resultSignatureCurrent = md5($resultCurrentJson);
try{
$jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
$resultSignatureExisting = $jobResultExisting->result_signature;
//if($resultSignatureExisting != $resultSignatureCurrent){
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
//}
} catch (JobResourceNotFoundException $exception){
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
}
}
private function updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $jobCommandName, $jobCommand){
$updateJobResultObject = new UpdateJobResultObject(
$resultCurrentJson,
$resultSignatureCurrent,
$jobCommandName,
$jobCommand
);
$create = $this->updatesJobResult->execute($jobResultCurrent, $updateJobResultObject);
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\Modules\Jobs\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\JobResult;
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
class CreatesJobResult extends AbstractUpdateRecord
{
/**
* @param ListGenericJobObject $listGenericJobObject
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(ListGenericJobObject $listGenericJobObject)
{
$model = new JobResult();
$model->job_id = $listGenericJobObject->getJobId();
$model->request_signature = $listGenericJobObject->getRequestSignature();
$model->result_signature = $listGenericJobObject->getResultSignature();
$model->url = $listGenericJobObject->getName();
return $this->handler($model);
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Jobs\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\JobResult;
class FetchesJobResult extends AbstractFetchRecord
{
/** @var JobResult */
private $repository;
/**
* FetchesJobResult constructor.
* @param JobResult $repository
*/
public function __construct(JobResult $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Jobs\Services;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\JobResult;
class ListsJobResult extends AbstractListRecord
{
/** @var JobResult */
private $repository;
/**
* ListsJobResult constructor.
* @param JobResult $repository
*/
public function __construct(JobResult $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Classes\Modules\Jobs\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Jobs\DataTransferObjects\UpdateJobResultObject;
use App\Models\JobResult;
class UpdatesJobResult extends AbstractUpdateRecord
{
/**
* @param JobResult $model
* @param UpdateJobResultObject $updateJobResultObject
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(JobResult $model, UpdateJobResultObject $updateJobResultObject) {
$model->result = $updateJobResultObject->getResult();
$model->result_signature = $updateJobResultObject->getResultSignature();
$model->job_command_name = $updateJobResultObject->getJobCommandName();
$model->job_command = $updateJobResultObject->getJobCommand();
return $this->handler($model);
}
}
@@ -53,8 +53,12 @@ class FetchOrderV2Logic extends AbstractControllerLogic
$query = $this->fetchesOrder->execute(['reference' => $request->route('id'), 'with_packing_lists' => true]);
if($request->input('storages')){
$query->storages = $request->input('storages'); //from middleware
}
return $this->resourceResponse(new OrderV2Resource($query));
}
}
}
@@ -9,6 +9,8 @@ use App\Classes\Modules\Addresses\Services\FetchesAddress;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\PackingList;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
class UpdateDoFromVTPortalProcessor
{
/** @var FetchesDataFromVTPortal */
@@ -36,6 +38,8 @@ class UpdateDoFromVTPortalProcessor
*/
public function execute(PackingList $packing_list) {
Log::info('Trying to Call UpdateDoFromVTPortalProcessor');
if(!app()->environment(['production'])){
return [];
}
@@ -37,6 +37,9 @@ class UpdateDoFromYDPortalProcessor
* @throws InternalServerErrorException
*/
public function execute(PackingList $packingList) {
Log::info('Trying to Call UpdateDoFromYDPortalProcessor');
Log::channel('storage_invoices')->info('UpdateDoFromYDPortalProcessor: '.json_encode($packingList));
if(!app()->environment(['production'])){
return;
}
@@ -70,6 +73,7 @@ class UpdateDoFromYDPortalProcessor
} catch (\Exception $exception){
log::debug($exception);
throw new InternalServerErrorException('failed to approve address due to an error related to YD portal');
}
}
@@ -0,0 +1,78 @@
<?php
namespace App\Classes\Modules\PackingLists\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Jobs\ListPackingListsJob;
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Classes\Modules\Jobs\Services\CreatesJobResult;
class ListPackingListsJobLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Job Retrieving PackingLists',
'message' => 'You have successfully submit a job to retrieve a list of PackingLists'
];
}
/** @var CreatesJobResult */
private $createsJobResult;
/**
* ListPackingListsJobLogic constructor.
* @param CreatesJobResult $createsJobResult
*/
public function __construct(CreatesJobResult $createsJobResult)
{
$this->createsJobResult = $createsJobResult;
}
/**
* @param Request $request
* @return JsonResponse
*/
public function logic(Request $request) : JsonResponse
{
$jobId = uniqid();
$user = Auth::user();
$userInfo = (object) [
// 'email' => $user->email,
'type' => $user->type,
];
$userInfoJson = json_encode($userInfo);
$requestSignature = md5($userInfoJson . $request->fullUrl());
$listGenericJobObject = new ListGenericJobObject(
$request->fullUrl(),
$request->all(),
$requestSignature,
null,
$jobId,
$userInfo
);
ListPackingListsJob::dispatch($listGenericJobObject)->onQueue('high_priority');
$result = [];
$result['job_id'] = $jobId;
$this->createsJobResult->execute($listGenericJobObject);
return $this->response(['data' => $result]);
}
}
@@ -121,7 +121,7 @@ class FetchContainersFromYdPortalProcessor
$containerReference = explode('预计到港时间', $tracking[1])[0];
$loadingDate = Carbon::parse($trackingRow->trackingtime);
$etd = Carbon::parse($tracking[2])->subDays(5);
$eta = Carbon::parse($tracking[2])->addDays(2);
$eta = Carbon::parse($tracking[2]);
}
}
@@ -147,7 +147,6 @@ class FetchContainersUpdatesFromYdPortalProcessor
if($delayDate){
$delayDate = $delayDate->addDays(2);
$transport = $container->transports()->first();
if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) {
@@ -162,7 +162,7 @@ class FetchLoadedContainersFromVTPortalProcessor
$container = $this->createContainerProcessor->execute($containerObject, $originWarehouse);
}
$eta = Carbon::parse($containerInfo[4])->addDays(2);
$eta = Carbon::parse($containerInfo[4]);
$etd = Carbon::parse($eta)->subDays(7);
$delayDate = $containerInfo[7];
@@ -183,7 +183,7 @@ class FetchLoadedContainersFromVTPortalProcessor
}
if($delayDate){
$delayDate = Carbon::parse($delayDate)->addDays(2);
$delayDate = Carbon::parse($delayDate);
$transport = $container->transports()->first();
if(!$transport->schedules()->where('eta', '=', $delayDate)->first()) {
@@ -199,7 +199,7 @@ class FetchOrderListsFromYdPortalProcessor
$containerReference = explode('预计到港时间', $tracking[1])[0];
$loadingDate = Carbon::parse($trackingRow->trackingtime);
$etd = Carbon::parse($tracking[2])->subDays(5);
$eta = Carbon::parse($tracking[2])->addDays(2);
$eta = Carbon::parse($tracking[2]);
}
$rescheduleETD = strpos($trackingRow->remark, '开') || strpos($trackingRow->remark, '到港');
@@ -415,7 +415,7 @@ class FetchOrderListsFromYdPortalProcessor
}
if($delayDate){
$delayDate = $delayDate->addDays(2);
$delayDate = $delayDate;
$transport = $container->transports()->first();
if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) {
@@ -0,0 +1,50 @@
<?php
namespace App\Classes\Modules\PackingLists\Processors;
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor;
use App\Classes\General\Helper;
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
use App\Http\Resources\ListPackingListJobResource;
class ListPackingListsJobProcessor
{
/** @var ListsPackingLists */
private $listsPackingLists;
/** @var UpdateJobResultProcessor */
private $updateJobResultProcessor;
/**
* ListPackingListsJobProcessor constructor.
* @param ListsPackingLists $listsPackingLists
* @param UpdateJobResultProcessor $updateJobResultProcessor
*/
public function __construct(ListsPackingLists $listsPackingLists, UpdateJobResultProcessor $updateJobResultProcessor)
{
$this->listsPackingLists = $listsPackingLists;
$this->updateJobResultProcessor = $updateJobResultProcessor;
}
/**
* @param ListGenericJobObject $listGenericJobObject
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
*/
public function execute(ListGenericJobObject $listGenericJobObject) {
// $query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true]);
$query = $this->listsPackingLists->execute(array_merge($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true]));
foreach ($query->items() as &$item) {
$item['userInfo'] = $listGenericJobObject->getUserInfo();
}
$resultCurrent = Helper::collectionResponse(ListPackingListJobResource::collection($query));
$this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent);
}
}
@@ -4,18 +4,15 @@ namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor;
use App\Classes\Modules\Documents\Services\ApprovesDocument;
use App\Classes\Modules\Documents\Services\FetchesDocument;
use App\Classes\Modules\Documents\Services\RejectsDocument;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -29,15 +26,15 @@ class ApprovePaymentTransactionLogic extends AbstractControllerLogic
* @param RejectsDocument $rejectsDocument
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, CallbackBillplzProcessor $callbackBillplzProcessor)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->approvesDocument = $approvesDocument;
$this->rejectsDocument = $rejectsDocument;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->callbackBillplzProcessor = $callbackBillplzProcessor;
}
/**
@@ -62,11 +59,8 @@ class ApprovePaymentTransactionLogic extends AbstractControllerLogic
/** @var RejectsDocument */
private $rejectsDocument;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor ;
/** @var CallbackBillplzProcessor */
private $callbackBillplzProcessor;
/**
* @param Request $request
@@ -82,29 +76,14 @@ class ApprovePaymentTransactionLogic extends AbstractControllerLogic
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('transaction_id')]);
$status === 'approve' ? $this->approvesDocument->execute($transaction->documents()->first()) : $this->rejectsDocument->execute($transaction->documents()->first());
$status === 'approve' ? $this->approvesDocument->execute($transaction->documents()->where('status', ApprovalStatus::PENDING_VERIFICATION)->first()) : $this->rejectsDocument->execute($transaction->documents()->where('status', ApprovalStatus::PENDING_VERIFICATION)->first());
$this->updatesTransactionStatus->execute($transaction, $status === 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
if($transaction->status === ApprovalStatus::APPROVED){
$invoice = $transaction->owner;
$packingList = $invoice->owner;
if(($invoice->amount - $transaction->amount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
}
if ($status === 'approve') {
$this->callbackBillplzProcessor->execute($transaction, ApprovalStatus::APPROVED);
}
return $this->response([]);
}
@@ -21,6 +21,8 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\GroupTransaction;
use App\Http\Resources\WalletTransactionResource;
use App\Models\Wallet;
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
class CreateGroupsLogic extends AbstractControllerLogic
{
@@ -55,13 +57,18 @@ class CreateGroupsLogic extends AbstractControllerLogic
/** @var CreatesGroup */
private $createsGroup;
/** @var ReleaseGoodsToCustomerProcessor */
private $releaseGoodsToCustomerProcessor;
public function __construct(
FetchesTransaction $fetchesTransaction,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
FetchesTransaction $fetchesTransaction,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
FetchesCompanyModule $fetchesCompanyModule,
CreateWalletTopUpTransactionProcessor $createWalletTopUpTransactionProcessor,
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor,
CreatesGroup $createsGroup
CreatesGroup $createsGroup,
ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
)
{
$this->fetchesTransaction = $fetchesTransaction;
@@ -70,6 +77,7 @@ class CreateGroupsLogic extends AbstractControllerLogic
$this->createWalletTopUpTransactionProcessor = $createWalletTopUpTransactionProcessor;
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
$this->createsGroup = $createsGroup;
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
}
public function logic(Request $request) : JsonResponse
@@ -84,6 +92,25 @@ class CreateGroupsLogic extends AbstractControllerLogic
// $invoices = $this->fetchesTransaction->execute(['id_in' => $invoice_ids]);
$invoices = Transaction::whereIn('id', $invoice_ids)->get();
foreach ($invoices as $invoice) {
$order = null;
if ($invoice->owner instanceof Transaction) {
if ($invoice->owner) {
if ($invoice->owner->owner) {
$order = $invoice->owner->owner->owner;
}
}
} else if (!($invoice->owner instanceof Transaction) && !($invoice->owner instanceof Wallet)) {
if ($invoice->owner) {
$order = $invoice->owner->owner;
}
}
if (!$order) {
throw new MalformedRequestException("There is an error while paying for invoice {$invoice->bill_no}");
}
}
if ($payment_method == PaymentMethodType::WALLET) {
$companyModuleId = $invoices->first()->receiver;
@@ -127,7 +154,12 @@ class CreateGroupsLogic extends AbstractControllerLogic
foreach ($invoices as $invoice) {
if ($payment_method == PaymentMethodType::WALLET) {
$this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $request->input('bank_code'));
$paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $request->input('bank_code'), false);
if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){
$pL = $invoice->owner;
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
}
}
$issuer = $invoice->issuer;
@@ -153,7 +185,7 @@ class CreateGroupsLogic extends AbstractControllerLogic
$companyModuleId = $invoice->receiver;
$companyModule = $this->fetchesCompanyModule->execute(['id' => $companyModuleId]);
$topUpTransaction = $this->createWalletTopUpTransactionProcessor->execute($companyModule, $amount, $request->input('bank_code'), true, $payment_method);
$topUpTransaction = $this->createWalletTopUpTransactionProcessor->execute($companyModule, $amount, $request->input('bank_code'), $payment_method, $billNumber, true);
}
$group->issuer = $issuer;
@@ -10,6 +10,8 @@ use App\Http\Resources\TransactionResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
class CreatePaymentTransactionLogic extends AbstractControllerLogic
{
@@ -30,13 +32,18 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
/** @var CreatePaymentTransactionProcessor */
private $createPaymentTransactionProcessor;
/** @var ReleaseGoodsToCustomerProcessor */
private $releaseGoodsToCustomerProcessor;
public function __construct(
FetchesTransaction $fetchesTransaction,
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor,
ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
}
public function logic(Request $request) : JsonResponse
@@ -45,7 +52,12 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
$invoice_transaction = $this->fetchesTransaction->execute(['id' => $request->input('transaction_id')]);
$payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'));
$payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'), false);
if($payment_transaction && $payment_transaction->status == ApprovalStatus::APPROVED){
$pL = $invoice_transaction->owner;
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice_transaction);
}
//cief todo: at exchange there is a transition step - starts
// if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){
@@ -63,4 +75,7 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
return $this->resourceResponse(new TransactionResource($payment_transaction));
}
}
@@ -50,6 +50,11 @@ class DeleteGroupLogic extends AbstractControllerLogic
{
$group = $this->fetchesGroup->execute(['id' => $request->route('id')]);
foreach ($group->groupTransactions as $groupTransaction) {
// $groupTransaction->transaction->delete();
$groupTransaction->delete();
}
$this->deletesGroup->execute($group);
return $this->response([]);
@@ -0,0 +1,57 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeletePaymentTransactionLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Delete Payment Transaction',
'message' => 'You have successfully deleted the payment transaction'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/**
* SuspendTransactionLogic constructor.
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
}
public function logic(Request $request) : JsonResponse
{
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$transaction->delete();
$invoice = $transaction->owner;
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::APPROVED);
return $this->response([]);
}
}
@@ -5,10 +5,11 @@ namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Http\Resources\BookingResource;
use App\Http\Resources\TransactionResource;
use App\Http\Resources\TransactionWithStorageResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class ListTransactionsLogic extends AbstractControllerLogic
{
@@ -38,13 +39,18 @@ class ListTransactionsLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
return $this->collectionResponse(TransactionResource::collection($query));
if($request->input('storages')){
foreach ($query->items() as &$item) {
$transactionId = $item['id'];
$filteredStorages = array_filter($request->input('storages'), function ($storage) use ($transactionId) {
return isset($storage['parentInvoiceId']) && $storage['parentInvoiceId'] == $transactionId;
});
$item['storages'] = $filteredStorages;
}
}
return $this->collectionResponse(TransactionWithStorageResource::collection($query));
}
}
@@ -0,0 +1,79 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Http\Resources\WalletTransactionResource ;
use App\Models\Transaction;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListWalletTransactionsLogic extends AbstractControllerLogic
{
/**
* ListTransactionsLogic constructor.
* @param ListsTransactions $listsTransactions
*/
public function __construct(ListsTransactions $listsTransactions)
{
$this->listsTransactions = $listsTransactions;
}
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Wallet Transactions',
'message' => 'You have successfully retrieved a list of transactions'
];
}
/** @var ListsTransactions */
private $listsTransactions;
public function logic(Request $request) : JsonResponse
{
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
if (str_contains($request->input('filters'), "owner_id") && $query->count() > 0) {
$wallet_total_incoming = Transaction::where('owner_type', $query->first()->owner_type)
->where('owner_id', $query->first()->owner_id)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->whereIn('type', [TransactionType::TOP_UP, TransactionType::CREDIT_NOTE, TransactionType::GROUP_PAYMENT])
->sum('amount');
$wallet_total_outgoing = Transaction::where('owner_type', $query->first()->owner_type)
->where('owner_id', $query->first()->owner_id)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->whereIn('type', [TransactionType::PAYMENT, TransactionType::DEBIT_NOTE])
->sum('amount');
$currentWalletBalance = $wallet_total_incoming - $wallet_total_outgoing;
$incoming = Transaction::where('owner_type', $query->first()->owner_type)
->where('owner_id', $query->first()->owner_id)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->whereIn('type', [TransactionType::TOP_UP, TransactionType::CREDIT_NOTE, TransactionType::GROUP_PAYMENT])
->where('id', '>', $query->first()->id)
->sum('amount');
$outgoing = Transaction::where('owner_type', $query->first()->owner_type)
->where('owner_id', $query->first()->owner_id)
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
->whereIn('type', [TransactionType::PAYMENT, TransactionType::DEBIT_NOTE])
->where('id', '>', $query->first()->id)
->sum('amount');
$runningBalanceInReverse = $currentWalletBalance - $incoming + $outgoing;
$request['running_balance'] = $runningBalanceInReverse;
}
return $this->collectionResponse(WalletTransactionResource::collection($query));
}
}
@@ -0,0 +1,76 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Models\Document;
class RegenerateSingleShippingInvoiceTransactionLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Regenerate Shipping Invoice',
'message' => 'You have successfully regenerated shipping invoice'
];
}
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/** @var FetchesTransaction */
private $fetchesTransaction;
/**
* @param CreatesDocument $createsDocument
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles, FetchesTransaction $fetchesTransaction)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
$this->fetchesTransaction = $fetchesTransaction;
}
public function logic(Request $request) : JsonResponse
{
$invoice = $this->fetchesTransaction->execute(['id' => $request->route('invoice_id')]);
$invoice->documents()->delete();
$transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
$document =$this->createsDocument->execute($invoice, $document_object);
$this->createsFiles->execute($document, $document_object);
// dump($document);
return $this->response([]);
}
}
@@ -17,6 +17,8 @@ use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Jobs\CreatePerfexCRMInvoice;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Models\Order;
class ApproveShippingInvoiceTransactionProcessor
{
@@ -30,17 +32,21 @@ class ApproveShippingInvoiceTransactionProcessor
/** @var CreatesFiles */
private $createsFiles;
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/**
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
}
@@ -50,7 +56,6 @@ class ApproveShippingInvoiceTransactionProcessor
*/
public function execute(PackingList $packingList)
{
/** @var Transaction $invoice_transaction */
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::PENDING_SUBMISSION])->first();
@@ -75,6 +80,11 @@ class ApproveShippingInvoiceTransactionProcessor
$user->notify(new InvoiceIssuedEmail($user, $packingList));
}
$order = $packingList->owner()->first();
if($order instanceof Order){
$this->storageInvoiceTransactionProcessor->executeOrder($order);
}
return;
}
@@ -0,0 +1,360 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail;
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionDetail;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Transactions\Services\DeletesGroup;
use App\Classes\Modules\Billplzs\Services\DeletesBillplzBill;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionDetailObject;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransactionDetailType;
use App\Http\Resources\TransactionWithStorageResource;
use App\Models\Order;
use App\Models\PackingList;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class CheckStorageInvoiceTransactionProcessor
{
/** @var FetchesOrder */
private $fetchesOrder;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var CreatesTransaction */
private $createsTransaction;
/** @var CreatesTransactionDetail */
private $createsTransactionDetail;
/** @var UpdatesTransaction */
private $updatesTransaction;
/** @var UpdatesTransactionDetail */
private $updatesTransactionDetail;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var DeletesGroup */
private $deletesGroup;
/** @var DeletesBillplzBill */
private $deletesBillplzBill;
/**
* @param FetchesOrder $fetchesOrder
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param FetchesTransaction $fetchesTransaction
* @param CreatesTransaction $createsTransaction
* @param CreatesTransactionDetail $createsTransactionDetail
* @param UpdatesTransaction $updatesTransaction
* @param UpdatesTransactionDetail $updatesTransactionDetail
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesGroup $deletesGroup
* @param DeletesBillplzBill $deletesBillplzBill
*/
public function __construct(FetchesOrder $fetchesOrder, GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesTransaction $fetchesTransaction, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, UpdatesTransactionDetail $updatesTransactionDetail, UpdatesTransactionStatus $updatesTransactionStatus, DeletesGroup $deletesGroup, DeletesBillplzBill $deletesBillplzBill)
{
$this->fetchesOrder = $fetchesOrder;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->fetchesTransaction = $fetchesTransaction;
$this->createsTransaction = $createsTransaction;
$this->createsTransactionDetail = $createsTransactionDetail;
$this->updatesTransaction = $updatesTransaction;
$this->updatesTransactionDetail = $updatesTransactionDetail;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesGroup = $deletesGroup;
$this->deletesBillplzBill = $deletesBillplzBill;
}
/**
* @throws MalformedRequestException
*/
public function execute(int $orderReference)
{
$order = $this->fetchesOrder->execute(['reference' => $orderReference, 'with_packing_lists' => true]);
return $this->executeOrder($order);
}
public function executeOrder(Order $order, bool $isBackDoorCheck = false){
$results = [];
$marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
$is_credit_term = $order->companyModule->inviters()->withPivot('is_credit_term')->first()->pivot->is_credit_term;
if(!$is_credit_term){
Log::channel('storage_invoices')->info('orderId: '.$order->id.', orderReference: '.$order->reference.', marking: '.$marking.', is_credit_term: '.$is_credit_term);
$packingLists = $order->destinationWarehousePackages;
foreach ($packingLists as $packingList){
$arrivalDateAtChinaWarehouse = $this->getArrivalDateAtChinaWarehoue($packingList);
Log::channel('storage_invoices')->info('arrivalDateAtChinaWarehouse: '.json_encode($arrivalDateAtChinaWarehouse));
Log::channel('storage_invoices')->info('destinationWarehousePackage: '.json_encode($packingList));
$eta = $this->getEtaFromPackingList($packingList);
if($arrivalDateAtChinaWarehouse && $eta){
$transactions = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
// $transactions = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->where('transactions.status', ApprovalStatus::APPROVED)->get();
/** @var Transaction $invoice_transaction */
foreach ($transactions as $invoice_transaction){
$result = $this->processSingleTransactionOfTypeShippingInvoice($invoice_transaction, $packingList, $order->company_module_id, $eta, $isBackDoorCheck);
if($result){
$results[] = $result;
}
}
}
}
}
return $results;
}
private function getArrivalDateAtChinaWarehoue($packingList){
if($packingList->type === PackingListType::SHIPPING_PACKING_LIST){
$receive_packing_list = PackingList::where('reference', $packingList->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first();
Log::channel('storage_invoices')->info('receive_packing_list: '.json_encode($receive_packing_list->transports));
$transport = $receive_packing_list->transports->first();
if ($transport) {
$arrivalDateAtChinaWarehouse = Carbon::parse($transport->drop_date);
$dateToCompare = Carbon::parse(env('STORAGE_FEE_LAUNCH_DATE', '2023-12-11 00:00:00'));
// dd($dateToCompare);
if ($arrivalDateAtChinaWarehouse->isAfter($dateToCompare)) {
Log::channel('storage_invoices')->info('transport: '.json_encode($transport));
Log::channel('storage_invoices')->info('dateToCompare: '.$dateToCompare.', arrivalDateAtChinaWarehouse: '.$arrivalDateAtChinaWarehouse);
return $arrivalDateAtChinaWarehouse;
}
}
}
return null;
}
private function getEtaFromPackingList($packingList){
if ($packingList) {
$package = $packingList->packages->first();
if ($package) {
$container = $package->container()->first();
if ($container) {
$transport = $container->transports->first();
if ($transport) {
$schedule = $transport->schedules->last();
if ($schedule) {
return $schedule->eta;
}
}
}
}
}
return null;
}
private function processSingleTransactionOfTypeShippingInvoice($transaction, $destinationWarehousePackage, $company_module_id, $eta, $isBackDoorCheck){
$pricePerCBM = 3;
$resultNumberOfDaysFree = 10;
$dt1 = $eta->copy()->addDay()->startOfDay();
$resultStartDate = $dt1->format('Y-m-d');
$currentDatetime = Carbon::now();
$dt2 = $currentDatetime->copy()->addDay()->startOfDay();
$resultCurrentDate = $dt2->format('Y-m-d H:i:s');
$interval = Carbon::parse($dt2)->diff($dt1);
$resultNumberOfDaysExceeded = $interval->days - $resultNumberOfDaysFree;
$storageInvoice = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->first();
$storageInvoiceId = 0;
$transactionDetailsItems = $transaction->transactionDetails()->get();
$cbm = 0.00;
foreach ($transactionDetailsItems as $tdItem){
$quantity = $tdItem->quantity;
if($tdItem->price < 0.00){
$quantity = $quantity * -1;
}
$cbm = $cbm + $quantity;
}
$price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded;
Log::channel('storage_invoices')->info('storageInvoice: '.json_encode($storageInvoice).', $transaction->status: '.$transaction->status);
if(!$storageInvoice && $resultNumberOfDaysExceeded > 0 && $transaction->status != ApprovalStatus::COMPLETED){
Log::channel('storage_invoices')->info('Created $transaction->id: '.$transaction->id);
$billNumber = $this->generatesTransactionBillNumber->execute('STOR-');
$storageInvoice = $this->createStorageInvoiceTransaction($destinationWarehousePackage, $billNumber, $company_module_id, $price_cbm);
$storageInvoiceId = $storageInvoice->id;
$this->createStorageInvoiceTransactionDetails($storageInvoice, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded);
}
else if($storageInvoice){
//Additional handling for calculation of numberOfDaysExceeded in the event of the storage already paid
$paymentStorageTransaction = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::APPROVED)->first();
if($paymentStorageTransaction){
$dateStorageInvoicePaid = $paymentStorageTransaction->created_at->copy()->addDay()->startOfDay();
Log::channel('storage_invoices')->info('dateStorageInvoicePaid: '.$dateStorageInvoicePaid.', resultCurrentDate: '.$resultCurrentDate);
$intervalRecalculate = Carbon::parse($dateStorageInvoicePaid)->diff($dt1);
$resultNumberOfDaysExceeded = $intervalRecalculate->days - $resultNumberOfDaysFree;
$price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded;
}
$amount = $storageInvoice->amount;
$epsilon = 0.0001; // Tolerance for the comparison
Log::channel('storage_invoices')->info('Update $transaction->id: '.$transaction->id);
Log::channel('storage_invoices')->info('$storageInvoice->status: '.$storageInvoice->status);
Log::channel('storage_invoices')->info('price_cbm: '.$price_cbm."-".gettype($price_cbm));
if(abs($price_cbm - $amount) > $epsilon && $storageInvoice->status !== ApprovalStatus::COMPLETED){
$paymentTransactions = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::PENDING_SUBMISSION)->get();
if(!$isBackDoorCheck){
if(count($paymentTransactions) > 0){
$this->updatePaymentTransactionViaNonGroupPayment($paymentTransactions);
}
else{
$this->updatePaymentTransactionViaGroupPayment($storageInvoice);
}
}
$storageInvoice = $this->updateStorageInvoiceTransaction($storageInvoice, $price_cbm);
$invoiceTransactionDetails = $storageInvoice->transactionDetails()->first();
$this->updateStorageInvoiceTransactionDetails($invoiceTransactionDetails, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded);
}
$storageInvoiceId = $storageInvoice->id;
}
if($storageInvoiceId !== 0){
$result = [
'parentInvoiceId' => $transaction->id,
'storageInvoiceId' => $storageInvoiceId,
'numberOfDaysExceeded' => $resultNumberOfDaysExceeded,
'numberOfDaysFree' => $resultNumberOfDaysFree,
'startDate' => $resultStartDate,
'currentDate' => $resultCurrentDate,
'cbm' => $cbm,
'pricePerCBM' => $pricePerCBM,
'storageInvoice' => new TransactionWithStorageResource($storageInvoice)
];
return $result;
}
}
private function updatePaymentTransactionViaGroupPayment($storageInvoice){
Log::channel('storage_invoices')->info('updatePaymentTransactionViaGroupPayment');
$groups = $storageInvoice->groups()->get();
foreach ($groups as $grp){
$groupReference = $grp->reference;
$walletTransaction = $this->fetchesTransaction->execute(['payment_reference' => $groupReference]);
if($walletTransaction->status === ApprovalStatus::PENDING_SUBMISSION || $walletTransaction->status === ApprovalStatus::PENDING_VERIFICATION){
$grp->status = ApprovalStatus::EXPIRED;
$grp->save();
$this->deletesGroup->execute($grp);
$this->updatesTransactionStatus->execute($walletTransaction, ApprovalStatus::EXPIRED);
if($walletTransaction->payment_reference){
$deletedBillplzBill = $this->deletesBillplzBill->execute($walletTransaction->payment_reference);
Log::channel('storage_invoices')->info('deletedBillplzBill TransactionType::WALLET: '.json_encode($deletedBillplzBill));
}
}
}
}
private function updatePaymentTransactionViaNonGroupPayment($paymentTransactions){
Log::channel('storage_invoices')->info('updatePaymentTransactionViaNonGroupPayment');
foreach ($paymentTransactions as $paymentTransaction){
$this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::EXPIRED);
if($paymentTransaction->payment_reference){
$deletedBillplzBill = $this->deletesBillplzBill->execute($paymentTransaction->payment_reference);
Log::channel('storage_invoices')->info('deletedBillplzBill TransactionType::WALLET: '.json_encode($deletedBillplzBill));
}
}
}
private function updateStorageInvoiceTransaction(Transaction $transaction, float $totalAmount){
$object = new TransactionObject(
$transaction->bill_no,
TransactionType::STORAGE_INVOICE,
1,
$transaction->receiver,
1,
PaymentMethodType::CASH,
$totalAmount,
$totalAmount,
1,
1,
0,
0,
0,
null,
ApprovalStatus::APPROVED
);
/** @var Transaction $invoice_transaction */
$invoice_transaction = $this->updatesTransaction->execute($transaction, $object);
return $invoice_transaction;
}
private function updateStorageInvoiceTransactionDetails($invoice_transaction_details, PackingList $packing_list, $cbm, $pricePerCBM, $numberOfDays){
$object_detail = new TransactionDetailObject(
'STORAGE_FEE',
TransactionDetailType::STORAGE_FEE.' for '.$numberOfDays. ' days * RM'.$pricePerCBM.'<br>'.round($packing_list->packages->where('type', '!=', PackageType::OVER_WEIGHT)->sum('quantity'), 3).' CTNS - '.round($cbm, 3).' CBM',
$cbm,
$pricePerCBM * $numberOfDays
);
$this->updatesTransactionDetail->execute($invoice_transaction_details, $object_detail);
}
private function createStorageInvoiceTransaction(PackingList $packing_list, string $billNumber, int $companyModuleId, float $totalAmount){
$object = new TransactionObject(
$billNumber,
TransactionType::STORAGE_INVOICE,
1,
$companyModuleId,
1,
PaymentMethodType::CASH,
$totalAmount,
$totalAmount,
1,
1,
0,
0,
0,
null,
ApprovalStatus::APPROVED
);
/** @var Transaction $invoice_transaction */
$invoice_transaction = $this->createsTransaction->execute($packing_list, $object);
return $invoice_transaction;
}
private function createStorageInvoiceTransactionDetails($invoice_transaction, PackingList $packing_list, $cbm, $pricePerCBM, $numberOfDays){
$object_detail = new TransactionDetailObject(
'STORAGE_FEE',
TransactionDetailType::STORAGE_FEE.' for '.$numberOfDays. ' days * RM'.$pricePerCBM.'<br>'.round($packing_list->packages->where('type', '!=', PackageType::OVER_WEIGHT)->sum('quantity'), 3).' CTNS - '.round($cbm, 3).' CBM',
$cbm,
$pricePerCBM * $numberOfDays
);
$this->createsTransactionDetail->execute($invoice_transaction, $object_detail);
}
}
@@ -85,7 +85,7 @@ class CreatePaymentTransactionProcessor
/**
* @throws MalformedRequestException
*/
public function execute(Transaction $invoice, $payment_method, $bank_code)
public function execute(Transaction $invoice, $payment_method, $bank_code, $run = true)
{
$amount = $invoice->amount;
Log::info($invoice->owner);
@@ -127,22 +127,26 @@ class CreatePaymentTransactionProcessor
$this->updatesWalletBalance->execute($wallet, ($amount * -1));
$packingList = $invoice->owner;
$order = $packingList->owner;
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if($run)
{
$packingList = $invoice->owner;
$order = $packingList->owner;
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
}
// later use this variabke to create a approved payment transaction
$approvalStatus = ApprovalStatus::APPROVED;
// update invoice to completed
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
if($run){
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
}
}
else {
$payment_method = PaymentMethodType::CASH;
@@ -0,0 +1,79 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Notifications\InvoiceIssuedEmail;
use App\Models\Document;
use App\Models\PackingList;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
class CreateStorageInvoiceDocTransactionFixProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/**
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
}
/**
* @throws MalformedRequestException
*/
public function execute(PackingList $packingList)
{
/** @var Transaction $invoice_transaction */
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('status', [ApprovalStatus::COMPLETED])->first();
// $this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED);
$transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice_transaction]);
$document_object = new DocumentObject(
DocumentType::STORAGE_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'storage_invoice'
);
// $invouce_transaction_document = $invoice_transaction->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->first();
// if(!$invouce_transaction_document){
/** @var Document $document */
$document = $this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
// $user = $packingList->owner->companyModule->employees()->first();
// if(app()->environment(['production'])) {
// $user->notify(new InvoiceIssuedEmail($user, $packingList));
// }
// }
}
}
@@ -0,0 +1,79 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Notifications\InvoiceIssuedEmail;
use App\Models\Document;
use App\Models\PackingList;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
class CreateStorageInvoiceDocTransactionProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/**
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
}
/**
* @throws MalformedRequestException
*/
public function execute(PackingList $packingList)
{
/** @var Transaction $invoice_transaction */
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('status', [ApprovalStatus::COMPLETED])->first();
// $this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED);
$transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice_transaction]);
$document_object = new DocumentObject(
DocumentType::STORAGE_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'storage_invoice'
);
$invouce_transaction_document = $invoice_transaction->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->first();
if(!$invouce_transaction_document){
/** @var Document $document */
$document = $this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
$user = $packingList->owner->companyModule->employees()->first();
if(app()->environment(['production'])) {
$user->notify(new InvoiceIssuedEmail($user, $packingList));
}
}
}
}
@@ -0,0 +1,94 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use Illuminate\Http\Request;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
use Illuminate\Support\Facades\Log;
class ReleaseGoodsToCustomerProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var UpdateDoFromVTPortalProcessor */
private $updateDoFromVTPortalProcessor;
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor;
/** @var CreateStorageInvoiceDocTransactionProcessor */
private $createStorageInvoiceDocTransactionProcessor;
/**
* ReleaseGoodsToCustomerProcessor constructor.
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
* @param CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor;
}
/**
* @param $packingList
* @param $invoice
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute($packingList, $invoice = null)
{
$result = false;
$totalInvoicesAmountPaid = 0.00;
$totalInvoicesAmount = 0.00;
$invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();
//Part 1: Process each single invoice type and get the total of all invoices
foreach($invoiceTransactions as $invoiceTransaction){
$totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if ($invoice && $invoice->type == $invoiceTransaction->type) {
if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
if($invoice->type == TransactionType::STORAGE_INVOICE){
$this->createStorageInvoiceDocTransactionProcessor->execute($packingList);
}
}
}
$totalInvoicesAmount = $totalInvoicesAmount + $invoiceTransaction->amount;
$totalInvoicesAmountPaid = $totalInvoicesAmountPaid + $totalInvoiceAmountPaid;
}
Log::channel('storage_invoices')->info('Total invoice amount paid 1: '.$totalInvoicesAmount); //cief todo: to be removed
Log::channel('storage_invoices')->info('Total invoice amount paid 2: '.$totalInvoicesAmountPaid); //cief todo: to be removed
//Part 2: Based on the collected info for all the total of all invoices
if (($totalInvoicesAmount - $totalInvoicesAmountPaid) < 0.01 && $totalInvoicesAmountPaid > 0.01) {
Log::channel('storage_invoices')->info('Total invoice amount paid 3: '.$totalInvoicesAmountPaid); //cief todo: to be removed
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if (app()->environment('production')) {
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
$result = true;
}
return $result;
}
}
@@ -61,7 +61,7 @@ class CreateWalletTopUpTransactionProcessor
/**
* @throws MalformedRequestException
*/
public function execute(CompanyModule $companyModule, $amount, $bank_code, ?bool $groupTransaction = false)
public function execute(CompanyModule $companyModule, $amount, $bank_code, ?int $payment_method = PaymentMethodType::PAYMENT_GATEWAY, ?string $payment_reference = null, ?bool $groupTransaction = false)
{
/** @var Wallet $wallet */
$wallet = $companyModule->wallets()->first();
@@ -82,7 +82,9 @@ class CreateWalletTopUpTransactionProcessor
$billPlzBill = $this->createsBillplzBill->execute($companyModule->name, $user->email, 'This payment is credit topup for company ref. ' . $companyModule->reference, $amount, $billNumber, $bank_code, true);
// IF $groupTransaction, transaction type is GROUP_PAYMENT
$transaction_object = new TransactionObject($billNumber, $groupTransaction? TransactionType::GROUP_PAYMENT: TransactionType::TOP_UP, 1, $companyModule->id, 1, PaymentMethodType::PAYMENT_GATEWAY, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], $billPlzBill->id);
// $transaction_object = new TransactionObject($billNumber, $groupTransaction? TransactionType::GROUP_PAYMENT: TransactionType::TOP_UP, 1, $companyModule->id, 1, PaymentMethodType::PAYMENT_GATEWAY, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], $billPlzBill->id);
// no more group payment
$transaction_object = new TransactionObject($billNumber, TransactionType::TOP_UP, 1, $companyModule->id, 1, $payment_method, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], $payment_method === PaymentMethodType::PAYMENT_GATEWAY ? $billPlzBill->id : $payment_reference);
$transaction = $this->createsTransactionableTransaction->execute($wallet, $transaction_object);
@@ -5,6 +5,8 @@ namespace App\Classes\Modules\Wallets\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Wallet;
use App\Models\Company;
@@ -16,10 +18,24 @@ class UpdatesWalletBalance extends AbstractUpdateRecord
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Wallet $model, $amount) {
public function execute(Wallet $model, $amount)
{
$topups = 0;
$credit = 0;
$payments = 0;
$debit = 0;
$model->amount = $model->amount + $amount;
foreach ($model->transactions as $transaction) {
if (!in_array((int) $transaction->status, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])) continue;
if ((int) $transaction->type === TransactionType::TOP_UP) $topups += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::GROUP_PAYMENT) $topups += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::CREDIT_NOTE) $credit += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::PAYMENT) $payments += (float) $transaction->amount;
if ((int) $transaction->type === TransactionType::DEBIT_NOTE) $debit += (float) $transaction->amount;
}
$auditBalance = ($topups + $credit) - ($payments + $debit);
$model->amount = $auditBalance;
return $this->handler($model);
}
}
@@ -24,5 +24,6 @@ final class DocumentType {
public const SHIPPING_INVOICE = 'SHIPPING_INVOICE';
public const STORAGE_INVOICE = 'STORAGE_INVOICE';
}
@@ -11,4 +11,6 @@ final class TransactionDetailType {
public const MIN_CBM_CHARGES = 'Minimum Charge for 0.3 CBM Per Container';
public const CUSTOM_CHARGES = 'Custom charges';
public const STORAGE_FEE = 'Malaysia Warehouse Storage Fee';
}
@@ -5,9 +5,9 @@ namespace App\Classes\ValueObjects\Constants;
final class TransactionType {
// public const PAYMENT_ATTEMPT = 0;
public const SHIPPING_INVOICE = 1;
public const PAYMENT = 2;
// public const BILL = 3;
@@ -35,10 +35,11 @@ final class TransactionType {
// public const SHIPPING_COST = 14;
public const GROUP_PAYMENT = 15;
public const TRANSACTION_TYPE_ID = [
self::SHIPPING_INVOICE => "Shipping Invoice",
self::PAYMENT => "Payment",
];
public const STORAGE_INVOICE = 16;
}
@@ -0,0 +1,85 @@
<?php
namespace App\Console\Commands;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Models\Order;
use Carbon\Carbon;
use Illuminate\Console\Command;
class CheckStorageInvoicesGroupTransactions extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'check-storage-invoices-group-transactions';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all storage invoices due to make sure that they are up to date daily, prevent \'back door\' cases';
/** @var ListsGroups */
private $listsGroups;
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(ListsGroups $listsGroups, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
{
parent::__construct();
$this->listsGroups = $listsGroups;
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ': Start Check all pending group payment with storage invoice is valid.');
$start = new Carbon();
$newfilters['order_by_updated_at_desc'] = true;
$newfilters['status_in'] = [0, 1];
$groups = $this->listsGroups->execute($newfilters);
foreach ($groups as $group){
$this->info('CheckForStorageInvoiceByTransactions group: '.json_encode($group));
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$packingList = $invoice->owner()->first();
if($packingList){
$order = $packingList->owner()->first();
if($order instanceof Order){
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
}
}
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ': Done Check all pending group payment with storage invoice is valid. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,82 @@
<?php
namespace App\Console\Commands;
use App\Classes\Modules\Orders\Services\ListsOrders;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\ValueObjects\Constants\OrderType;
use App\Models\Order;
use Carbon\Carbon;
use Illuminate\Console\Command;
class CheckStorageInvoicesOrders extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'check-storage-invoices-orders';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Check all storage invoices due to make sure that they are up to date daily, prevent \'back door\' cases';
/** @var ListsOrders */
private $listsOrders;
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(ListsOrders $listsOrders, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
{
parent::__construct();
$this->listsOrders = $listsOrders;
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ': Start Check all orders for storage invoice.');
$start = new Carbon();
$orders = $this->listsOrders->execute(['with_parcels' => true, 'type_in' => [OrderType::SHARED_CONTAINER, OrderType::DEDICATED_CONTAINER]]);
$count = 0;
foreach ($orders as $order){
try{
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
$count = $count + 1;
$this->info('Order '.$count);
}
catch(\Exception $ex){
$this->info('Exception '.$ex->getMessage());
break;
}
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ': Done Check all orders for storage invoice. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -4,6 +4,7 @@ namespace App\Console\Commands;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor;
use App\Classes\Modules\Billplzs\Services\GetBillplzBill;
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
@@ -53,12 +54,15 @@ class FixBillplzFailedCallbackPayment extends Command
/** @var UpdateDoFromYDPortalProcessor */
private $updateDoFromYDPortalProcessor ;
/** @var CallbackBillplzProcessor */
private $callbackBillplzProcessor;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor)
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, CallbackBillplzProcessor $callbackBillplzProcessor)
{
parent::__construct();
$this->getBillplzBill = $getBillplzBill;
@@ -66,6 +70,7 @@ class FixBillplzFailedCallbackPayment extends Command
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
$this->callbackBillplzProcessor = $callbackBillplzProcessor;
}
/**
@@ -82,7 +87,7 @@ class FixBillplzFailedCallbackPayment extends Command
$approvalStatusArray = ApprovalStatus::APPROVAL_STATUS_ID;
$transactions = Transaction::whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP])->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
$transactions = Transaction::whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP, TransactionType::GROUP_PAYMENT])->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
$totalTransactions = count($transactions);
if ($totalTransactions) {
@@ -96,84 +101,15 @@ class FixBillplzFailedCallbackPayment extends Command
if($response->successful()){
$data = $response->json();
if($data['paid']){
$totalAmount += $transaction->amount;
$invoiceStatus = null;
if($data['paid']) {
$status = ApprovalStatus::PENDING_VERIFICATION;
switch($transaction->owner->status) {
case 3:
$invoiceStatus = 'Payment Completed';
break;
case 5:
$invoiceStatus = 'Dispute in progress';
break;
case 6:
$invoiceStatus = 'Cancelled Invoice';
break;
default:
$invoiceStatus = 'Pending Payment';
if($data['state'] === 'paid') {
$status = ApprovalStatus::APPROVED;
}
$order = $transaction->owner->owner->owner;
if (in_array($invoiceStatus , ['Pending Payment', 'Payment Completed'])) {
// code here
// $billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId());
// if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.');
// $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]);
$invoice = $transaction->owner;
$packingList = $invoice->owner;
$order = $packingList->owner;
$status = ApprovalStatus::PENDING_VERIFICATION;
if($data['state'] === 'paid') {
$status = ApprovalStatus::APPROVED;
}
// if($data->state === 'due') {
// $status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
// }
// $token = Auth::fromUser(User::find(1));
// $request->headers->set('Authorization', 'Bearer '.$token);
$this->updatesTransactionStatus->execute($transaction, $status);
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
if(($invoice->amount - $totalPaidAmount) < 0.01) {
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
$packingList->status = ApprovalStatus::APPROVED;
$packingList->save();
if(app()->environment('production')){
$this->updateDoFromVTPortalProcessor->execute($packingList);
$this->updateDoFromYDPortalProcessor->execute($packingList);
}
$this->info('Updated invoice ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
} else {
$this->info('Failed to update invoice due to unsufficeint payment ' . $counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
}
} else {
if(!$order instanceof Order) {
$this->info("Error transaction id:" . $transaction->id . 'Type: ' . get_class($order));
} else {
$this->info($counter . ' of ' . $totalTransactions . '. Order: '. $order->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount . '. Status: ' . $approvalStatusArray[$transaction->status] . '. Invoice Status: ' . $invoiceStatus);
}
}
} else {
// $totalAmount += $transaction->amount;
// $this->appendToOutput($counter . ' of ' . $totalTransactions . '. Order: '. $transaction->owner->owner->owner->reference . ' - Date: '.$transaction->owner->created_at->format('d-m-Y').' - Amount: '. $transaction->amount);
$this->info(Carbon::now() . ' : Fixing ' . $transaction->payment_reference);
$this->callbackBillplzProcessor->execute($transaction, $status);
}
}else{
$this->info("billplz error</br>");
@@ -0,0 +1,95 @@
<?php
namespace App\Console\Commands;
use App\Classes\Modules\Transactions\Services\FetchesGroup;
use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionFixProcessor;
use Carbon\Carbon;
use Illuminate\Console\Command;
class FixGroupPaymentProblem extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fix-group-payment-problem';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This is a one time data patch for a problem result from Storage Invoice Implementation';
/** @var FetchesGroup */
private $fetchesGroup;
/** @var ReleaseGoodsToCustomerProcessor */
private $releaseGoodsToCustomerProcessor;
/** @var FetchesOrder */
private $fetchesOrder;
/** @var CreateStorageInvoiceDocTransactionFixProcessor */
private $createStorageInvoiceDocTransactionProcessor;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(FetchesGroup $fetchesGroup, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor, FetchesOrder $fetchesOrder, CreateStorageInvoiceDocTransactionFixProcessor $createStorageInvoiceDocTransactionProcessor)
{
parent::__construct();
$this->fetchesGroup = $fetchesGroup;
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
$this->fetchesOrder = $fetchesOrder;
$this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$this->info(Carbon::now() . ': Start data patch.');
$start = new Carbon();
/*
$group = $this->fetchesGroup->execute(['id' => 325]);
$this->info('FixGroupPaymentProblem group: '.json_encode($group));
if ($group) {
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$this->info('FixGroupPaymentProblem group: '.json_encode($invoice));
$pL = $invoice->owner;
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
}
}
*/
$order = $this->fetchesOrder->execute(['reference' => '729251424']);
$packingLists = $order->destinationWarehousePackages;
foreach ($packingLists as $packingList){
$this->createStorageInvoiceDocTransactionProcessor->execute($packingList, true);
dd(json_encode($packingList));
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
$this->info(Carbon::now() . ': Done data patch. ElapsedTime: ' . $elapsedTime . '.');
}
}
@@ -0,0 +1,84 @@
<?php
namespace App\Console\Commands;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class ShowFailediBllplzCallback extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'show-failed-billplz-callback';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show all failled callback from billplz';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
ini_set('memory_limit', '-1');
$start = new Carbon();
$transactions = Transaction::whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP, TransactionType::GROUP_PAYMENT])->where('payment_method', PaymentMethodType::PAYMENT_GATEWAY)->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
$totalTransactions = count($transactions);
if ($totalTransactions) {
$this->info(Carbon::now() . ' : ' . $this->description);
}
$counter = 1;
$totalAmount = 0;
foreach ($transactions as $transaction){
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->get(config('billplz.base_url').'/api/v3/bills/'.$transaction->payment_reference);
if($response->successful()){
$data = $response->json();
if($data['paid']){
dump($transaction->payment_reference);
dump($transaction->id);
}
}else{
$this->info("billplz error</br>");
}
$counter++;
}
$end = new Carbon();
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
if ($totalTransactions) {
$this->info(Carbon::now() . ' : Done Billplz Failled Callback. ElapsedTime: ' . $elapsedTime . '. Total: ' . $totalAmount);
}
}
}
+5
View File
@@ -62,6 +62,11 @@ class Kernel extends ConsoleKernel
->hourly()
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/fix_failed_callback_from_billplz.log');
$schedule->command('check-storage-invoices-group-transactions')
->dailyAt('0:01')
->withoutOverlapping()
->appendOutputTo(storage_path().'/logs/check_storage_invoices.log');
}
/**
@@ -9,6 +9,7 @@ use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Excel;
use App\Classes\Modules\Exports\Services\ExportsAgingList;
class ExportArrivedParcelController
{
@@ -46,4 +47,11 @@ class ExportArrivedParcelController
ob_end_clean();
return $response;
}
public function aging(Request $request) {
$data = new ExportsAgingList();
$response = $data->download('aging_report.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
ob_end_clean();
return $response;
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Http\Controllers\Exports;
use App\Classes\Modules\Exports\Services\ExportsCustomersWalletTransactionHistory;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Excel;
class ExportCustomersWalletTransactionToExcelController
{
/**
* ExportCustomersWalletTransactionToExcelController constructor.
* @param Request $request
*/
public function __construct(Request $request)
{
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer ' . $token);
}
public function export(Request $request)
{
$exportsTransactions = new ExportsCustomersWalletTransactionHistory($request);
$wallet = Wallet::find($request->route('wallet_id'));
$company_marking = $wallet->owner->connections->first()->invitee_reference;
$filename = $company_marking . '-wallet-' . ($request->route('is_precise') == 'true' ? 'precise-' : '') . 'transaction-history.xls';
$response = $exportsTransactions->download($filename, Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
ob_end_clean();
return $response;
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\Jobs;
use App\Classes\Modules\Jobs\ControllersLogic\FetchJobResultLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchJobResultController
{
/**
* @param Request $request
* @param FetchJobResultLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, FetchJobResultLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\PackingLists;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\PackingLists\ControllersLogic\ListPackingListsJobLogic;
class ListPackingListsJobController
{
/**
* @param Request $request
* @param ListPackingListsJobLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListPackingListsJobLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\DeletePaymentTransactionLogic;
class DeletePaymentTransactionController
{
/**
* @param Request $request
* @param DeletePaymentTransactionLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, DeletePaymentTransactionLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use App\Classes\Modules\Transactions\ControllersLogic\ListWalletTransactionsLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListWalletTransactionsController
{
/**
* @param Request $request
* @param ListWalletTransactionsLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListWalletTransactionsLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\RegenerateSingleShippingInvoiceTransactionLogic;
class RegenerateSingleShippingInvoiceTransactionController
{
/**
* @param Request $request
* @param RegenerateShippingInvoiceTransactionLogic $logic
* @return JsonResponse
*/
public function regenerate(Request $request, RegenerateSingleShippingInvoiceTransactionLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+3
View File
@@ -70,5 +70,8 @@ class Kernel extends HttpKernel
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'valid.token' => ValidateToken::class,
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
'storage.invoice.check.byorder' => \App\Http\Middleware\CheckForStorageInvoiceByOrderId::class,
'storage.invoice.check.bytransactions' => \App\Http\Middleware\CheckForStorageInvoiceByTransactions::class,
'storage.invoice.check.bygroup' => \App\Http\Middleware\CheckForStorageInvoiceByGroup::class,
];
}
@@ -0,0 +1,64 @@
<?php
namespace App\Http\Middleware;
use Closure;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class CheckForStorageInvoiceByGroup
{
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/** @var ListsGroups */
private $listsGroups;
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, ListsGroups $listsGroups)
{
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
$this->listsGroups = $listsGroups;
}
/**
* Handle an incoming request.
*
* @param 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)
{
// :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [0, 1], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"
$filters = json_decode($request->input('filters'), true);
if(json_encode($filters['order_by']) == '{"column":"updated_at","DESC":true}'){
$filters['order_by_updated_at_desc'] = true;
}
unset($filters['order_by']);
$groups = $this->listsGroups->execute($filters);
if(isset($filters['check_for_storage_invoice'])){
foreach ($groups as $group){
foreach ($group->groupTransactions as $groupTransaction) {
$invoice = $groupTransaction->transaction;
$packingList = $invoice->owner()->first();
if($packingList){
$order = $packingList->owner()->first();
if($order instanceof Order){
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
}
}
}
}
}
return $next($request);
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Http\Middleware;
use Closure;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use Illuminate\Http\Request;
class CheckForStorageInvoiceByOrderId
{
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
{
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
}
/**
* Handle an incoming request.
*
* @param 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)
{
$orderId = $request->route('id');
$storages = $this->storageInvoiceTransactionProcessor->execute($orderId);
$request->merge(['storages' => $storages]);
return $next($request);
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Http\Middleware;
use Closure;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\CompanyConnection;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class CheckForStorageInvoiceByTransactions
{
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/** @var ListsTransactions */
private $listsTransactions;
/** @var ListsGroups */
private $listsGroups;
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, ListsTransactions $listsTransactions, ListsGroups $listsGroups)
{
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
$this->listsTransactions = $listsTransactions;
$this->listsGroups = $listsGroups;
}
/**
* Handle an incoming request.
*
* @param 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)
{
$results = [];
$transactions = null;
$marking = $request->route('marking');
if($marking){ //for web route /customer/{marking}/payment-and-billing
$connection = CompanyConnection::where('invitee_reference', $marking)->first();
$company_module_id = $connection->invitee->id;
$filters = [
'per_page' => 999,
'status_in' => [2],
'receiver' => $company_module_id,
'type_in' => [TransactionType::SHIPPING_INVOICE]
];
$transactions = $this->listsTransactions->execute($filters);
}
else{ //for api route /transactions/list
$filters = json_decode($request->input('filters'), true);
$filters['type_in'] = [TransactionType::SHIPPING_INVOICE];
if(json_encode($filters['order_by']) == '{"column":"id","DESC":true}'){
$filters['order_by_id_desc'] = true;
}
unset($filters['order_by']);
$transactions = $this->listsTransactions->execute($filters);
}
if(isset($filters['check_for_storage_invoice'])){
foreach($transactions as $transaction){
$packingList = $transaction->owner()->first();
if($packingList){
$order = $packingList->owner()->first();
if($order instanceof Order){
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
if($storages){
$results = array_merge($results, $storages);
}
}
}
}
}
$filteredResults = array_values(array_filter($results, function($item, $key) {
static $seen = array();
$hash = md5($item['parentInvoiceId'] . $item['storageInvoiceId']);
return !isset($seen[$hash]) && ($seen[$hash] = true);
}, ARRAY_FILTER_USE_BOTH));
$request->merge(['storages' => $filteredResults]);
return $next($request);
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class GroupForOrderV2Resource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$payment_transaction = Transaction::where('payment_reference', $this->reference)->first();
return [
'id' => $this->id,
'original_amount' => (float) $this->original_amount,
'original_currency' => new CurrencyResource($this->original_currency),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (float) $this->amount,
'service_charge' => (float) $this->amount,
'currency' => new CurrencyResource($this->currency),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
'currency_rate' => (float) $this->currency_rate,
'status' => $this->status,
'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$this->status],
'payment_method' => (int)$this->payment_method,
'payment_method_name' => ucwords(PaymentMethodType::PAYMENT_METHODS_ID[$this->payment_method]),
'payment_reference' => $this->reference,
'transactions_ids' => GroupTransactionsForOrderV2Resource::collection($this->groupTransactions),
'payment_transaction' => $payment_transaction ? [
'id' => $payment_transaction->id,
'status' => $payment_transaction->status,
'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$payment_transaction->status]
] : []
];
}
}
+8
View File
@@ -4,6 +4,7 @@ namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -19,6 +20,7 @@ class GroupResource extends JsonResource
{
// dd($this->groupTransactions);
$payment_transaction = Transaction::where('payment_reference', $this->reference)->first();
return [
'id' => $this->id,
@@ -37,6 +39,12 @@ class GroupResource extends JsonResource
'payment_method_name' => ucwords(PaymentMethodType::PAYMENT_METHODS_ID[$this->payment_method]),
'invoices' => GroupTransactionResource::collection($this->groupTransactions),
'reference' => $this->reference,
'payment_transaction' => $payment_transaction ? [
'id' => $payment_transaction->id,
'status' => $payment_transaction->status,
'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$payment_transaction->status],
'documents' => $this->status === ApprovalStatus::APPROVED ? DocumentResource::collection($payment_transaction->documents->where('status', ApprovalStatus::APPROVED)) : DocumentResource::collection($payment_transaction->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)),
] : []
];
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class GroupTransactionsForOrderV2Resource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
// 'id' => $this->id,
'group_id' => $this->group_id,
'transaction_id' => $this->transaction_id,
];
}
}
@@ -34,7 +34,7 @@ class HelpMenuQuestionResource extends JsonResource
'question_number' => $q->question_number,
'question_text' => $q->question_text,
'question_type' => $q->question_type,
'question_answers' => HelpMenuAnswerOptionsResource::collection(QAAnswerOptions::where('question_number', $q->question_number)->where('questionnaire_set_id', $q->questionnaire_set_id)->get()),
'question_answers' => HelpMenuAnswerOptionsResource::collection(QAAnswerOptions::where('question_number', $q->question_number)->where('questionnaire_set_id', $q->questionnaire_set_id)->orderBy('order', 'ASC')->get()),
'questionnaire_set_id' => $q->questionnaire_set_id,
'next_nested_question' => $q->next_nested_question,
'next_main_question' => $q->next_main_question,
@@ -18,6 +18,7 @@ class HelpMenuQuestionnaireSetsResource extends JsonResource
'name' => $this->name,
'description' => $this->description,
'group' => $this->group,
'version' => $this->version,
];
}
}
@@ -4,6 +4,7 @@ namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Classes\ValueObjects\Constants\QASystemSourceType;
use App\Models\QAAnswerOptions;
use App\Models\QAQuestions;
use Carbon\Carbon;
@@ -20,6 +21,7 @@ class HelpMenuQuestionsAnswersResource extends JsonResource
$question = QAQuestions::where('id', $this->question_id)->first();
$source = new HelpMenuUserSourceResource($this->userSource);
$user = $this->source_id === 0 ? new UserResource($this->user) : null;
$answerOption = QAAnswerOptions::where('id', $this->answer_option_id)->first();
$user_marking = '';
if($user){
@@ -31,7 +33,8 @@ class HelpMenuQuestionsAnswersResource extends JsonResource
'question_id' => $this->question_id,
'questionnaire' => new HelpMenuQuestionnaireSetsResource($this->question->questionnaire),
'question_text' => $question ? $question->question_text : null,
'free_text_answer' => $this->free_text_answer,
'free_text_answer' => $answerOption ? $answerOption->display_text : null,
'answer_value' => $answerOption ? $answerOption->value : null,
'source_system' => $user ? QASystemSourceType::getText(QASystemSourceType::IZYIM) : QASystemSourceType::getText($source->system),
'source_marking' => $user ? $user_marking : $source->marking,
'source_email' => $user ? $user->email : $source->email,
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class JobResultResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'job_id' => $this->job_id,
'result' => $this->result,
];
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Order;
use App\Models\PackingList;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\V2\PackingListV2Resource;
class ListPackingListJobResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$exceptionUsers = in_array($this->userInfo ? $this->userInfo->type : Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages;
return [
'id' => $this->id,
'claimant_id' => $this->claimant_id,
'reference' => $this->reference,
'status' => $this->status,
'transport' => new TransportResource($this->transports()->first()),
'type' => $this->type,
'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)),
// 'packages' => PackageResource::collection($packages),
// $this->mergeWhen($this->owner instanceof Order, [
// 'order' => New OrderResource($this->owner)
// ]),
'container' => new ContainerResource($this->containers->first()),
'packages' => PackageWithoutOrderResource::collection($packages),
$this->mergeWhen($this->owner instanceof Order, [ 'order' => New OrderResource($this->owner) ]),
'shipping_transaction' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()),
'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()),
// 'suspended_invoices' => TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()),
];
}
}
@@ -37,6 +37,7 @@ class MappableTransactionResource extends JsonResource
'owner_type' => Transaction::class,
'owner_id'=> $this->id,
'owner_reference'=> $reference,
'created_at'=> $this->created_at, // invoice date
];
}
}
@@ -27,16 +27,19 @@ class MappableTransactionWithDetailsResource extends JsonResource
'order_reference' => null,
'bill_no' => null,
'marking' => null,
'created_at' => null
];
if ($this->type === TransactionType::PAYMENT) {
$order = $this->owner->owner->owner;
$data['order_reference'] = $order->reference;
$data['debtor_code'] = $order->companyModule->company->debtor;
$data['created_at'] = $this->owner->created_at; // invoice date
} elseif (in_array($this->type, [TransactionType::GROUP_PAYMENT, TransactionType::TOP_UP])) {
$connection = $this->owner->owner->inviters()->withPivot('invitee_reference')->first();
$data['marking'] = $connection ? $connection->pivot->invitee_reference : '';
$data['bill_no'] = $this->bill_no;
$data['created_at'] = $this->created_at;
} else {
$payments = $this->transactions()
->payments()->where('status', ApprovalStatus::APPROVED)
@@ -54,6 +57,7 @@ class MappableTransactionWithDetailsResource extends JsonResource
'type' => $payment->type,
'marking' => null,
'amount' => $payment->amount,
'created_at' => $this->created_at
];
})->toArray();
} else {
@@ -61,6 +65,7 @@ class MappableTransactionWithDetailsResource extends JsonResource
$data['amount'] = 'Transaction Type not allowed';
$data['transaction_type'] = $this->type;
$data['payment_transactions'] = null;
$data['created_at'] = null;
}
}
+2 -1
View File
@@ -31,8 +31,9 @@ class OrderV2Resource extends JsonResource
'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()),
'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()),
'invoices' => $this->whenLoaded('packingLists', function() {
return TransactionResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->where('transactions.type', TransactionType::SHIPPING_INVOICE)->get());
return TransactionWithStorageResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get());
}),
'storages' => $this->storages ? $this->storages : null, //from middleware
'remarks' => RemarkResource::collection($this->remarks),
'created_at' => $this->created_at->format('d-m-Y')
];
@@ -0,0 +1,38 @@
<?php
namespace App\Http\Resources;
use App\Models\Order;
use App\Models\PackingList;
use Illuminate\Http\Resources\Json\JsonResource;
class PackageWithoutOrderResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'type' => $this->type,
'description' => $this->description,
'width' => floatval($this->width),
'height' => floatval($this->height),
'length' => floatval($this->length),
'weight' => $this->weight,
'quantity' => $this->quantity,
'cbm' => (($this->width / 100) * ($this->height / 100) * ($this->length / 100)) * $this->quantity,
'reference' => $this->packingList->reference,
'status' => $this->status,
// $this->mergeWhen($originalPackingList->owner instanceof Order, [
// 'order' => New OrderResource($originalPackingList->owner)
// ]),
// 'container' => new ContainerResource($originalPackingList->containers()->first()),
// 'transport' => new TransportResource($originalPackingList->transports()->first())
];
}
}
+27 -2
View File
@@ -5,8 +5,10 @@ namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Group;
use App\Models\Order;
use App\Models\Transaction;
use App\Models\Wallet;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -20,11 +22,34 @@ class TransactionResource extends JsonResource
*/
public function toArray($request)
{
$order = null;
$groupTransactions = null;
if ($this->owner instanceof Transaction) {
if ($this->owner) {
if ($this->owner->owner) {
$order = new OrderResource($this->owner->owner->owner);
}
}
} else if (!($this->owner instanceof Transaction) && !($this->owner instanceof Wallet)) {
if ($this->owner) {
$order = new OrderResource($this->owner->owner);
}
} else {
$group = Group::where('reference', $this->payment_reference)->first();
if ($group) {
$groupTransactions = GroupTransactionResource::collection($group->groupTransactions);
}
}
return [
'id' => $this->id,
'owner_type' => $this->owner_type,
'order' => ($this->owner instanceof Transaction) ? new OrderResource($this->owner->owner->owner) : new OrderResource($this->owner->owner),
'documents' => DocumentResource::collection($this->documents),
'order' => $order,
'group_transactions' => $groupTransactions,
'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null,
'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents),
'type' => (int) $this->type,
'bill_no' => $this->bill_no,
'amount' => (double) $this->amount,
@@ -0,0 +1,128 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Group;
use App\Models\Transaction;
use App\Models\Wallet;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Log;
class TransactionWithStorageResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$order = null;
$groupTransactions = null;
$group_payment_attempts = null;
$groupPaymentAttemptsFiltered = [];
$group_payment_expired = null;
$group_payment_history = null;
$groupTotalAmount = 0;
if ($this->owner instanceof Transaction) {
if ($this->owner) {
if ($this->owner->owner) {
$order = new OrderResource($this->owner->owner->owner);
}
}
} else if (!($this->owner instanceof Transaction) && !($this->owner instanceof Wallet)) {
if ($this->owner) {
$order = new OrderResource($this->owner->owner);
}
if($this->groups){
$group_payment_attempts = GroupForOrderV2Resource::collection($this->groups->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]));
$group_payment_expired = GroupForOrderV2Resource::collection($this->groupsWithTrashed->whereIn('status', [ApprovalStatus::EXPIRED]));
$group_payment_history = GroupForOrderV2Resource::collection($this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED]));
}
} else {
$group = Group::where('reference', $this->payment_reference)->first();
if ($group) {
$groupTransactions = GroupTransactionResource::collection($group->groupTransactions);
}
}
$ts = $this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->last();
if ($ts) {
$paymentTransaction = Transaction::where('payment_reference', $ts->reference)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION])->first();
if($paymentTransaction){
$groupTotalAmount = (double) $this->amount;
foreach ($group_payment_history as $key => $value) {
if ($value->id === $ts->id && $value->reference === $ts->reference) {
unset($group_payment_history[$key]);
}
}
foreach ($group_payment_attempts as $key => $value) {
if ($value->id === $ts->id && $value->reference == $ts->reference) {
$groupPaymentAttemptsFiltered[$key] = $value;
}
}
}
}
return [
'id' => $this->id,
'owner_type' => $this->owner_type,
'order' => $order,
'group_transactions' => $groupTransactions,
'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null,
'groups_payment_attempts' => $groupPaymentAttemptsFiltered,
'groups_payment_expired' => $group_payment_expired,
'groups_payment_history' => $group_payment_history,
'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents),
'type' => (int) $this->type,
'bill_no' => $this->bill_no,
'amount' => (double) $this->amount,
'payment_method' => (int) $this->payment_method,
'payment_reference' => $this->payment_reference,
'outstanding' => (double) $this->amount - ($this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount')),
'floating' => $group_payment_attempts ? $groupTotalAmount : (double) $this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount'),
'service_charge' => (double) $this->service_charge,
'tax' => (double) $this->tax,
'original_amount' => (double) $this->original_amount,
'currency' => new CurrencyResource($this->currency),
'original_currency' => new CurrencyResource($this->original_currency),
'currency_rate' => (double) $this->currency_rate,
'status' => (int) $this->status,
'details' => TransactionDetailResource::collection($this->transactionDetails),
'transactions' => TransactionResource::collection($this->transactions),
'payment_attempts' => TransactionResource::collection(
$this->transactions()
->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
->get()
),
'payments_expired' => TransactionResource::collection(
$this->transactions()
->payments()->where('status', ApprovalStatus::EXPIRED)
->get()
),
'payment_history' => TransactionResource::collection(
$this->transactions()
->payments()
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED])
->get()
),
'remarks' => RemarkResource::collection($this->remarks),
'storages' => $this->storages ? $this->storages : null, //from middleware
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:s:i'),
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y'),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y')
];
}
}
@@ -0,0 +1,54 @@
<?php
namespace App\Http\Resources\V2;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Order;
use App\Models\PackingList;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources as V1;
class PackingListV2Resource extends JsonResource
{
private $userInfo;
public function __construct($resource, $userInfo = null)
{
parent::__construct($resource);
$this->userInfo = $userInfo;
}
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$user = $this->userInfo ? $this->userInfo : Auth()->user();
$exceptionUsers = in_array($user->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages;
return [
'id' => $this->id,
'claimant_id' => $this->claimant_id,
'reference' => $this->reference,
'status' => $this->status,
'transport' => new V1\TransportResource($this->transports()->first()),
'type' => $this->type,
'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $user)),
'packages' => V1\PackageResource::collection($packages),
$this->mergeWhen($this->owner instanceof Order, [
'order' => New V1\OrderResource($this->owner)
]),
'shipping_transaction' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()),
'suspended_invoice' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()),
// 'suspended_invoices' => V1\TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()),
];
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ class WalletResource extends JsonResource
'amount' => (double) $this->amount,
'company_id' => (int) $this->owner->id,
'transactions' => $this->whenLoaded('transactions', WalletTransactionResource::collection($this->transactions()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->get()), []),
'top_up_records' => $this->whenLoaded('transactions', WalletTransactionResource::collection($this->transactions()->whereIn('type', [TransactionType::TOP_UP])->orderBy('id', 'DESC')->get()), []),
'top_up_records' => $this->whenLoaded('transactions', WalletTransactionResource::collection($this->transactions()->whereIn('type', [TransactionType::TOP_UP, TransactionType::GROUP_PAYMENT])->orderBy('id', 'DESC')->get()), []),
'company_module_marking' => $this->owner->connections->first()->invitee_reference,
];
}

Some files were not shown because too many files have changed in this diff Show More