diff --git a/app/Classes/General/Eloquent/AbstractFetchRecord.php b/app/Classes/General/Eloquent/AbstractFetchRecord.php index 1fbd39da..248deee7 100644 --- a/app/Classes/General/Eloquent/AbstractFetchRecord.php +++ b/app/Classes/General/Eloquent/AbstractFetchRecord.php @@ -6,6 +6,7 @@ namespace App\Classes\General\Eloquent; use App\Classes\Exceptions\ResourceNotFoundException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Psy\Exception\ErrorException; abstract class AbstractFetchRecord extends AbstractGetRecord { diff --git a/app/Classes/General/Eloquent/Filters/TransactionServiceId.php b/app/Classes/General/Eloquent/Filters/TransactionServiceId.php new file mode 100644 index 00000000..fa0cdba5 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/TransactionServiceId.php @@ -0,0 +1,23 @@ +where('owner_type', Booking::class)->whereHas('booking', function ($query) use($value) { + $query->where('service_id', $value); + }); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Accounts/ControllersLogic/DeleteUserLogic.php b/app/Classes/Modules/Accounts/ControllersLogic/DeleteUserLogic.php index 485e9cf3..e7aa57f8 100644 --- a/app/Classes/Modules/Accounts/ControllersLogic/DeleteUserLogic.php +++ b/app/Classes/Modules/Accounts/ControllersLogic/DeleteUserLogic.php @@ -53,24 +53,18 @@ class DeleteUserLogic extends AbstractControllerLogic /** * @param Request $request * @return JsonResponse - * @throws ErrorException + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException */ public function logic(Request $request) : JsonResponse { - try { - DB::beginTransaction(); + $user = $this->fetchesUser->execute(['id' => $request->route('id')]); + $this->canDeleteUser->passes(); + $this->deletesUser->execute($user); - $user = $this->fetchesUser->execute(['id' => $request->route('id')]); - $this->canDeleteUser->passes(); - $this->deletesUser->execute($user); - - DB::commit(); - return $this->resourceResponse(new UserResource($user)); - - } catch (\Exception $exception){ - throw new ErrorException($exception->getMessage(), $exception->getCode()); - } + return $this->resourceResponse(new UserResource($user)); } } \ No newline at end of file diff --git a/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php b/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php index 8c164317..48e3bb62 100644 --- a/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php +++ b/app/Classes/Modules/Addresses/DataTransferObjects/AddressObject.php @@ -22,7 +22,7 @@ class AddressObject implements DataTransferObject /** @var int */ private $districtId; - /** @var int */ + /** @var string */ private $postCode; /** @@ -32,9 +32,9 @@ class AddressObject implements DataTransferObject * @param int $countryId * @param int $stateId * @param int $districtId - * @param int $postCode + * @param string $postCode */ - public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, int $postCode) + public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, string $postCode) { $this->streetOne = $streetOne; $this->streetTwo = $streetTwo; @@ -85,9 +85,9 @@ class AddressObject implements DataTransferObject } /** - * @return int + * @return string */ - public function getPostCode(): int + public function getPostCode(): string { return $this->postCode; } diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index 7501bfd1..2230343f 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -2,10 +2,15 @@ namespace App\Classes\Modules\Billplzs\ControllersLogic; +use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject; +use App\Classes\Modules\Wallets\Services\UpdatesWallet; use App\Classes\Exceptions\ResourceNotFoundException; +use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Http\Resources\TransactionResource; +use App\Models\Booking; use App\Models\User; +use App\Models\Wallet; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; @@ -32,18 +37,22 @@ class CallbackBillplzLogic /** @var UpdatesTransactionStatus */ private $updatesTransactionStatus; + /** @var UpdatesWalletBalance */ + private $updatesWalletBalance; /** - * CreateBookingLogic constructor. + * CallbackBillplzLogic constructor. * @param GetBillplzBill $getBillplzBill * @param FetchesTransaction $fetchesTransaction * @param UpdatesTransactionStatus $updatesTransactionStatus + * @param UpdatesWalletBalance $updatesWalletBalance */ - public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus) + public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWalletBalance $updatesWalletBalance) { $this->getBillplzBill = $getBillplzBill; $this->fetchesTransaction = $fetchesTransaction; $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->updatesWalletBalance = $updatesWalletBalance; } @@ -55,7 +64,6 @@ class CallbackBillplzLogic */ public function execute(Request $request) { - $billplzXSignatureObject = new BillplzXSignatureObject($request); if(!$billplzXSignatureObject->isValidSignature()){ @@ -76,12 +84,22 @@ class CallbackBillplzLogic $status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION; } - $this->updatesTransactionStatus->execute($transaction, $status); + if($transaction->status !== ApprovalStatus::COMPLETED){ + + if($transaction->owner instanceof Wallet && $transaction->status !== ApprovalStatus::APPROVED && $status === ApprovalStatus::APPROVED) { + $this->updatesWalletBalance->execute($transaction->owner, $transaction->amount); + } + $this->updatesTransactionStatus->execute($transaction, $status); + + } + $token = Auth::fromUser(User::find(1)); $request->headers->set('Authorization', 'Bearer '.$token); - return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $transaction->booking->marking, 'payment_reference' => $transaction->payment_reference, 'status' => $status, 'amount' => $transaction->amount]); + $marking = $transaction->owner instanceof Booking ? $transaction->booking->marking : $transaction->owner->owner->bookings()->orderBy('id', 'DESC')->first()->marking; + + return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking, 'transaction' => $transaction, 'status' => $status]); } } \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php index 79f56916..ed9ec6d8 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php @@ -5,17 +5,37 @@ namespace App\Classes\Modules\Bookings\ControllersLogic; use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Transactions\ControllersLogic\CreatePurchaseOrderTransactionLogic; +use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor; +use App\Classes\Modules\Transactions\Services\GeneratesPurchaseOrderProducts; +use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Booking; use App\Models\Transaction; +use App\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; class AutoPurchaseOrderFillLogic extends AbstractControllerLogic { + /** + * AutoPurchaseOrderFillLogic constructor. + * @param GeneratesPurchaseOrderProducts $generatesPurchaseOrderProducts + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor + */ + public function __construct(GeneratesPurchaseOrderProducts $generatesPurchaseOrderProducts, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor) + { + $this->generatesPurchaseOrderProducts = $generatesPurchaseOrderProducts; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } + /** * @return array @@ -27,17 +47,15 @@ class AutoPurchaseOrderFillLogic extends AbstractControllerLogic ]; } - /** @var CreatePurchaseOrderTransactionLogic */ - private $createPurchaseOrderTransactionLogic; + /** @var GeneratesPurchaseOrderProducts */ + private $generatesPurchaseOrderProducts; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatePurchaseOrderTransactionProcessor */ + private $createPurchaseOrderTransactionProcessor; - /** - * AutoPackingListFillLogic constructor. - * @param CreatePurchaseOrderTransactionLogic $createPurchaseOrderTransactionLogic - */ - public function __construct(CreatePurchaseOrderTransactionLogic $createPurchaseOrderTransactionLogic) - { - $this->createPurchaseOrderTransactionLogic = $createPurchaseOrderTransactionLogic; - } /** * @param Request $request @@ -46,66 +64,48 @@ class AutoPurchaseOrderFillLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - $booking = Booking::whereMonth('created_at', 7) + $bookings = Booking::whereMonth('created_at', 7) ->whereYear('created_at', 2021) - ->whereDoesntHave('transactions', function($q){ + ->whereDoesntHave('transactions', function($q){ $q->where('type', TransactionType::PURCHASE_ORDER); $q->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); - })->limit(10)->get(); - - foreach ($booking as $key => $row) { - $amount = $row->fix_amount; - $other_transaction = Transaction:: - where('type', TransactionType::PURCHASE_ORDER) - ->where('status', ApprovalStatus::APPROVED) - ->where('amount', '<=', $amount) - ->where('issuer', $row->company_id) - ->first(); + })->get(); + foreach ($bookings as $booking) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id) + ->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); - if (!$other_transaction) { - $other_transaction = Transaction:: - where('type', TransactionType::PURCHASE_ORDER) - ->where('status', ApprovalStatus::APPROVED) - ->where('amount', '<=', $amount) - ->first(); + if (!$po) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); } - $other_transaction_detail = $other_transaction->transactionDetails()->get(); + $products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount); - $other_amount = 0; - foreach ($other_transaction_detail as $key_2 => $row_2) { + $deference = $booking->fix_amount - $products->sum('total'); - if ($amount > $other_amount) { - $other_amount += $row_2->amount; - $products[] = [ - 'description' => $row_2->product_name, - 'quantity' => (int) $row_2->quantity, - 'stockCode' => $row_2->product_code, - 'total' => $row_2->amount, - 'unit_price' => (int) $row_2->price, - ]; - } - } + if($deference > -150 && $deference < 150 && $deference != 0) { - $remain_amount = $amount - $other_amount; - - if ($remain_amount > 0) { - $remain = [ - 'description' => 'other service charge', + $products->push([ + 'description' => $deference < 0 ? 'Discount':'Shipping Fee', 'quantity' => 1, - 'stockCode' => 'OTHER_SERVICE_CHARGE', - 'total' => $remain_amount, - 'unit_price' => $remain_amount, - ]; - - $products = array_merge([$remain], $products); + 'stockCode' => '', + 'total' => $deference, + 'unit_price' => $deference + ]); } - $request->request->add([ - 'products' => $products - ]); - $this->createPurchaseOrderTransactionLogic->logic($request, $row->id); + $billNumber = $this->generatesTransactionBillNumber->execute('XPO-'); + + $total = $products->sum('total'); + + $object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1, + 1, PaymentMethodType::CASH, + $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, + 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray()); + + $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); } return $this->response([]); diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index a16be8d2..38080fff 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -14,11 +14,15 @@ use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\UpdatesTransaction; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill; +use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; +use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; use App\Http\Resources\TransactionResource; use App\Models\Booking; +use App\Models\Transaction; +use App\Models\Wallet; use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -48,15 +52,18 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic /** @var CreatesTransaction */ private $createsTransaction; - /** @var UpdatesTransaction */ - private $updatesTransaction; - /** @var CalculatesBookingOutstanding */ private $calculatesBookingOutstanding; /** @var CreatesBillplzBill */ private $createsBillplzBill; + /** @var UpdatesWalletBalance */ + private $updatesWalletBalance; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + /** * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -65,16 +72,19 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic * @param CreatesTransaction $createsTransaction * @param CalculatesBookingOutstanding $calculatesBookingOutstanding * @param CreatesBillplzBill $createsBillplzBill + * @param UpdatesWalletBalance $updatesWalletBalance + * @param UpdatesTransactionStatus $updatesTransactionStatus */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, UpdatesTransaction $updatesTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; - $this->updatesTransaction = $updatesTransaction; $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; $this->createsBillplzBill = $createsBillplzBill; + $this->updatesWalletBalance = $updatesWalletBalance; + $this->updatesTransactionStatus = $updatesTransactionStatus; } /** @@ -98,18 +108,47 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + $paymentReference = null; + + $amount = $configurations->getTotal(); + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ $billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $request->input('bank_code')); + $paymentReference = $billPlzBill->id; } + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){ + /** @var Wallet $wallet */ + $wallet = $booking->company->wallets()->first(); + + if($wallet->amount < $amount){ + throw new MalformedRequestException('Insufficient wallet balance. Please Top up your wallet.'); + } + + $transaction_object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, 1, PaymentMethodType::WALLET, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], ''); + $this->createsTransaction->execute($wallet, $transaction_object); + + $paymentReference = $billNumber; + + $this->updatesWalletBalance->execute($wallet, ($amount * -1)); + + } + + $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), $configurations->getTotal(), $configurations->getForeignTotal(), 1, $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL); + $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference); + /** @var Transaction $transaction */ $transaction = $this->createsTransaction->execute($booking, $object); + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){ + $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); + } + return $this->resourceResponse(new TransactionResource($transaction)); } diff --git a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php index d1cdbada..71ea7ba1 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/RegenerateInvoiceBookingLogic.php @@ -78,6 +78,7 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic * @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 diff --git a/app/Classes/Modules/Bookings/Standards/Rules/CanDeleteBooking.php b/app/Classes/Modules/Bookings/Standards/Rules/CanDeleteBooking.php index dfd307bc..d1fcfe15 100644 --- a/app/Classes/Modules/Bookings/Standards/Rules/CanDeleteBooking.php +++ b/app/Classes/Modules/Bookings/Standards/Rules/CanDeleteBooking.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Bookings\Standards\Rules; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject; +use Illuminate\Support\Facades\Auth; class CanDeleteBooking extends AbstractRule { @@ -14,7 +15,7 @@ class CanDeleteBooking extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('delete booking')) { + if (!Auth::user()->can('delete booking')) { return false; } diff --git a/app/Classes/Modules/Bookings/Standards/Rules/CanUpdateBooking.php b/app/Classes/Modules/Bookings/Standards/Rules/CanUpdateBooking.php index bf5c022c..7158a825 100644 --- a/app/Classes/Modules/Bookings/Standards/Rules/CanUpdateBooking.php +++ b/app/Classes/Modules/Bookings/Standards/Rules/CanUpdateBooking.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Bookings\Standards\Rules; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Bookings\Standards\Validators\BookingValidation; +use Illuminate\Support\Facades\Auth; class CanUpdateBooking extends AbstractRule { @@ -29,7 +30,7 @@ class CanUpdateBooking extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('edit booking')) { + if (!Auth::user()->can('edit booking')) { return false; } diff --git a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyLogic.php b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyLogic.php index c435dab4..23cf9561 100644 --- a/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyLogic.php +++ b/app/Classes/Modules/Companies/ControllersLogic/UpdateCompanyLogic.php @@ -56,23 +56,15 @@ class UpdateCompanyLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - try { + $object = new CompanyObject($request->input('name'), $request->input('reference'), $request->input('type')); - $object = new CompanyObject($request->input('reference_no'), $request->input('name'), $request->input('type')); + $this->canUpdateCompany->passes($object); - $this->canUpdateCompany->passes($object); + $query = $this->fetchesCompany->execute(['id' => $request->route('id')]); - $query = $this->fetchesCompany->execute(['id' => $request->route('id')]); - - $query = $this->updatesCompany->execute($query, $object); - - return $this->resourceResponse(new CompanyResource($query)); - - - } catch (\Exception $exception){ - throw new ErrorException($exception->getMessage(), $exception->getCode()); - } + $query = $this->updatesCompany->execute($query, $object); + return $this->resourceResponse(new CompanyResource($query)); } } \ No newline at end of file diff --git a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanCreateRate.php b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanCreateRate.php index 842a548b..cf63f89c 100644 --- a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanCreateRate.php +++ b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanCreateRate.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Currencies\Standards\Validators\Rates\RateValidation; use App\Classes\Modules\Currencies\DataTransferObjects\RateObject; +use Illuminate\Support\Facades\Auth; class CanCreateRate extends AbstractRule { @@ -27,7 +28,7 @@ class CanCreateRate extends AbstractRule protected function authorized(): bool { // TODO Set Authorization rules - if (!\Auth::user()->can('add currency_rate')) { + if (!Auth::user()->can('add currency_rate')) { return false; } diff --git a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanDeleteRate.php b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanDeleteRate.php index 4ebefb9e..37fff506 100644 --- a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanDeleteRate.php +++ b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanDeleteRate.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Currencies\DataTransferObjects\RateObject; +use Illuminate\Support\Facades\Auth; class CanDeleteRate extends AbstractRule { @@ -14,7 +15,7 @@ class CanDeleteRate extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('delete currency_rate')) { + if (!Auth::user()->can('delete currency_rate')) { return false; } diff --git a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanListRates.php b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanListRates.php index 496ba1e5..bd49c263 100644 --- a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanListRates.php +++ b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanListRates.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyObject; +use Illuminate\Support\Facades\Auth; class CanListRates extends AbstractRule { @@ -14,7 +15,7 @@ class CanListRates extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('view currency_rate')) { + if (!Auth::user()->can('view currency_rate')) { return false; } diff --git a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanUpdateRate.php b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanUpdateRate.php index 59564725..8a153c54 100644 --- a/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanUpdateRate.php +++ b/app/Classes/Modules/Currencies/Standards/Rules/Rates/CanUpdateRate.php @@ -6,6 +6,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Currencies\Standards\Validators\Rates\RateValidation; use App\Classes\Modules\Currencies\DataTransferObjects\RateObject; +use Illuminate\Support\Facades\Auth; class CanUpdateRate extends AbstractRule { @@ -29,7 +30,7 @@ class CanUpdateRate extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('view currency_rate')) { + if (!Auth::user()->can('view currency_rate')) { return false; } diff --git a/app/Classes/Modules/Documents/ControllersLogic/DeleteDocumentLogic.php b/app/Classes/Modules/Documents/ControllersLogic/DeleteDocumentLogic.php new file mode 100644 index 00000000..06419d87 --- /dev/null +++ b/app/Classes/Modules/Documents/ControllersLogic/DeleteDocumentLogic.php @@ -0,0 +1,70 @@ + 'Deleted Document', + 'message' => 'You have successfully deleted a document' + ]; + } + + /** @var FetchesDocument */ + private $fetchesDocument; + + /** @var DeletesDocument */ + private $deletesDocument; + + /** @var CanDeleteDocument */ + private $canDeleteDocument; + + /** + * DeleteDocumentLogic constructor. + * @param FetchesDocument $fetchesDocument + * @param DeletesDocument $deletesDocument + * @param CanDeleteDocument $canDeleteDocument + */ + public function __construct(FetchesDocument $fetchesDocument, DeletesDocument $deletesDocument, CanDeleteDocument $canDeleteDocument) + { + $this->fetchesDocument = $fetchesDocument; + $this->deletesDocument = $deletesDocument; + $this->canDeleteDocument = $canDeleteDocument; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $document = $this->fetchesDocument->execute(['id' => $request->route('id')]); + + $this->canDeleteDocument->passes(); + + $this->deletesDocument->execute($document); + + return $this->response([]); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Documents/ControllersLogic/UpdateDocumentReferenceLogic.php b/app/Classes/Modules/Documents/ControllersLogic/UpdateDocumentReferenceLogic.php new file mode 100644 index 00000000..1cea5eeb --- /dev/null +++ b/app/Classes/Modules/Documents/ControllersLogic/UpdateDocumentReferenceLogic.php @@ -0,0 +1,68 @@ + 'Update Document', + 'message' => 'You have successfully updated the Document' + ]; + } + + /** @var CanUpdateDocumentReference*/ + private $canUpdateDocumentReference; + + /** @var UpdatesDocumentReference */ + private $updatesDocumentReference; + + /** @var FetchesDocument */ + private $fetchesDocument; + + + /** + * RejectDocumentLogic constructor. + * @param CanApproveDocument $canApproveDocument + * @param ApprovesDocument $approvesDocument + * @param FetchesDocument $fetchesDocument + */ + public function __construct(CanUpdateDocumentReference $canUpdateDocumentReference, UpdatesDocumentReference $updatesDocumentReference, FetchesDocument $fetchesDocument) + { + $this->canUpdateDocumentReference = $canUpdateDocumentReference; + $this->updatesDocumentReference = $updatesDocumentReference; + $this->fetchesDocument = $fetchesDocument; + } + + /** + * @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 + { + $document = $this->fetchesDocument->execute(['id' => $request->route('id')]); + + $this->canUpdateDocumentReference->passes(); + + $document_query = $this->updatesDocumentReference->execute($document, $request->input('identification_number')); + + return $this->resourceResponse(new DocumentResource($document_query)); + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Documents/Services/UpdatesDocument.php b/app/Classes/Modules/Documents/Services/UpdatesDocument.php new file mode 100644 index 00000000..b825753f --- /dev/null +++ b/app/Classes/Modules/Documents/Services/UpdatesDocument.php @@ -0,0 +1,19 @@ +handler($model); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Documents/Services/UpdatesDocumentReference.php b/app/Classes/Modules/Documents/Services/UpdatesDocumentReference.php new file mode 100644 index 00000000..23a16e02 --- /dev/null +++ b/app/Classes/Modules/Documents/Services/UpdatesDocumentReference.php @@ -0,0 +1,20 @@ +reference = $reference; + return $this->handler($model); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Documents/Standards/Rules/CanDeleteDocument.php b/app/Classes/Modules/Documents/Standards/Rules/CanDeleteDocument.php new file mode 100644 index 00000000..e5bc4891 --- /dev/null +++ b/app/Classes/Modules/Documents/Standards/Rules/CanDeleteDocument.php @@ -0,0 +1,39 @@ +whereHas('transaction', function($query){ + return $query->where('type', \App\Classes\ValueObjects\Constants\TransactionType::PURCHASE_ORDER)->where('status', ApprovalStatus::APPROVED); + })->limit(50); + } + + /** + * @param $product + * @return array + */ + public function map($product): array + { + + return [ + $product->product_code, + $product->product_name, + $product->price, + ]; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Segments/Standards/Rules/CanCreateSegment.php b/app/Classes/Modules/Segments/Standards/Rules/CanCreateSegment.php index 50f7e81d..f7b05a10 100644 --- a/app/Classes/Modules/Segments/Standards/Rules/CanCreateSegment.php +++ b/app/Classes/Modules/Segments/Standards/Rules/CanCreateSegment.php @@ -5,6 +5,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject; use App\Classes\Modules\Segments\Standards\Validators\SegmentValidation; +use Illuminate\Support\Facades\Auth; class CanCreateSegment extends AbstractRule { @@ -27,7 +28,7 @@ class CanCreateSegment extends AbstractRule protected function authorized(): bool { // TODO Set Authorization rules - if (!\Auth::user()->can('add segment')) { + if (!Auth::user()->can('add segment')) { return false; } diff --git a/app/Classes/Modules/Segments/Standards/Rules/CanDeleteSegment.php b/app/Classes/Modules/Segments/Standards/Rules/CanDeleteSegment.php index 197b0a5f..9faf4da6 100644 --- a/app/Classes/Modules/Segments/Standards/Rules/CanDeleteSegment.php +++ b/app/Classes/Modules/Segments/Standards/Rules/CanDeleteSegment.php @@ -4,6 +4,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject; +use Illuminate\Support\Facades\Auth; class CanDeleteSegment extends AbstractRule { @@ -14,7 +15,7 @@ class CanDeleteSegment extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('delete segment')) { + if (!Auth::user()->can('delete segment')) { return false; } diff --git a/app/Classes/Modules/Segments/Standards/Rules/CanUpdateSegment.php b/app/Classes/Modules/Segments/Standards/Rules/CanUpdateSegment.php index 58a8c0ca..8287dfd6 100644 --- a/app/Classes/Modules/Segments/Standards/Rules/CanUpdateSegment.php +++ b/app/Classes/Modules/Segments/Standards/Rules/CanUpdateSegment.php @@ -6,6 +6,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules; use App\Classes\General\Abstracts\AbstractRule; use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject; use App\Classes\Modules\Segments\Standards\Validators\SegmentValidation; +use Illuminate\Support\Facades\Auth; class CanUpdateSegment extends AbstractRule { @@ -30,7 +31,7 @@ class CanUpdateSegment extends AbstractRule { // TODO Set Authorization rules - if (!\Auth::user()->can('edit segment')) { + if (!Auth::user()->can('edit segment')) { return false; } diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php index afd589c6..9bab107f 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php @@ -7,6 +7,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\Services\FetchesBooking; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor; use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail; use App\Classes\Modules\Transactions\Services\DeletesTransactionDetails; @@ -25,26 +26,6 @@ use Illuminate\Http\Request; class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic { - /** - * CreatePurchaseOrderTransactionLogic constructor. - * @param FetchesBooking $fetchesBooking - * @param UpdatesTransactionStatus $updatesTransactionStatus - * @param CreatesTransaction $createsTransaction - * @param CreatesTransactionDetail $createsTransactionDetail - * @param UpdatesTransaction $updatesTransaction - * @param DeletesTransactionDetails $deletesTransactionDetails - * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber - */ - public function __construct(FetchesBooking $fetchesBooking, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, DeletesTransactionDetails $deletesTransactionDetails, GeneratesTransactionBillNumber $generatesTransactionBillNumber) - { - $this->fetchesBooking = $fetchesBooking; - $this->updatesTransactionStatus = $updatesTransactionStatus; - $this->createsTransaction = $createsTransaction; - $this->createsTransactionDetail = $createsTransactionDetail; - $this->updatesTransaction = $updatesTransaction; - $this->deletesTransactionDetails = $deletesTransactionDetails; - $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; - } /** * @return array @@ -59,27 +40,28 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic /** @var FetchesBooking */ private $fetchesBooking; - /** @var UpdatesTransactionStatus */ - private $updatesTransactionStatus; - - /** @var CreatesTransaction */ - private $createsTransaction; - - /** @var CreatesTransactionDetail */ - private $createsTransactionDetail; - - /** @var UpdatesTransaction */ - private $updatesTransaction; - - /** @var DeletesTransactionDetails */ - private $deletesTransactionDetails; - /** @var GeneratesTransactionBillNumber */ private $generatesTransactionBillNumber; + /** @var CreatePurchaseOrderTransactionProcessor */ + private $createPurchaseOrderTransactionProcessor; + + /** + * CreatePurchaseOrderTransactionLogic constructor. + * @param FetchesBooking $fetchesBooking + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor + */ + public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor) + { + $this->fetchesBooking = $fetchesBooking; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } /** * @param Request $request + * @param string $id * @return JsonResponse * @throws \App\Classes\Exceptions\MalformedRequestException */ @@ -88,10 +70,8 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic /** @var Booking $booking */ $booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]); - /** @var Transaction $transaction */ - $transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); - $billNumber = $this->generatesTransactionBillNumber->execute('PO-'); + $total = collect($request->input('products'))->sum(function($product){ return $product['quantity'] * floatval(str_replace(',', '', $product['unit_price'])); }); @@ -101,15 +81,8 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $request->input('products')); - !$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object); - $this->updatesTransactionStatus->execute($transaction, (float) number_format($total, 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); - - $this->deletesTransactionDetails->execute($transaction); - - foreach ($object->getDetails() as $product){ - $this->createsTransactionDetail->execute($transaction, $product); - } + $transaction = $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); return $this->resourceResponse(new TransactionResource($transaction)); diff --git a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php index e583eaf9..bb022317 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateInvoiceTransactionProcessor.php @@ -210,6 +210,10 @@ class CreateInvoiceTransactionProcessor $booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL); + $transaction = $booking->transactions() + ->where('type', TransactionType::BILL) + ->first(); + $transaction_object = new TransactionObject( $billNumber, TransactionType::SUPPLIER_DELIVER, diff --git a/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php new file mode 100644 index 00000000..76773c75 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php @@ -0,0 +1,76 @@ +updatesTransactionStatus = $updatesTransactionStatus; + $this->createsTransaction = $createsTransaction; + $this->createsTransactionDetail = $createsTransactionDetail; + $this->updatesTransaction = $updatesTransaction; + $this->deletesTransactionDetails = $deletesTransactionDetails; + } + + + /** + * @param Booking $booking + * @param TransactionObject $object + * @return Transaction|\Illuminate\Database\Eloquent\Model + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(Booking $booking, TransactionObject $object){ + /** @var Transaction $transaction */ + $transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); + + !$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object); + + $this->updatesTransactionStatus->execute($transaction, (float) number_format($object->getAmount(), 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); + + $this->deletesTransactionDetails->execute($transaction); + + foreach ($object->getDetails() as $product){ + $this->createsTransactionDetail->execute($transaction, $product); + } + + return $transaction; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php b/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php new file mode 100644 index 00000000..16d162eb --- /dev/null +++ b/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php @@ -0,0 +1,72 @@ +products = $products; + } + + + public function execute(Transaction $transaction, float $amount){ + + $products = collect(); + + $amountDifference = $amount - $transaction->amount; + $transactionDetails = $transaction->transactionDetails()->select('*', DB::raw('abs(price - '.abs($amountDifference).') as nearest_price'))->orderBy('nearest_price')->get(); + foreach ($transactionDetails as $product) { + $units = floor(abs($amountDifference) / $product->price); + $quantity = $product->quantity; + + if($product->price <= 0){ + $amountDifference = $amountDifference + ($product->price * $product->quantity); + continue; + } + + if($amountDifference > 0){ + $quantity = $product->quantity + $units; + $amountDifference = $amountDifference - ($product->price * $units); + } + + if($amountDifference < 0) { + $units = ceil(abs($amountDifference) / $product->price); + $quantity = $product->quantity - $units; + + if($quantity <= 0){ + $amountDifference = $amountDifference + ($product->price * $product->quantity); + continue; + } + + $amountDifference = $amountDifference + ($product->price * $quantity); + } + + $products->push([ + 'description' => $product->product_name, + 'quantity' => (int) $quantity, + 'stockCode' => $product->product_code, + 'total' => $product->price * $quantity, + 'unit_price' => (float) $product->price, + ]); + + } + + return $products; + + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Wallets/ControllersLogic/CreditWalletLogic.php b/app/Classes/Modules/Wallets/ControllersLogic/CreditWalletLogic.php new file mode 100644 index 00000000..1e7b3ceb --- /dev/null +++ b/app/Classes/Modules/Wallets/ControllersLogic/CreditWalletLogic.php @@ -0,0 +1,117 @@ + 'Credit into Company Wallet', + 'message' => 'You have successfully credit company wallet' + ]; + } + + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var GeneratesWalletCode */ + private $generatesWalletCode; + + /** @var CreatesWallet */ + private $createsWallet; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatesTransaction */ + private $createsTransaction; + + /** @var UpdatesWallet */ + private $updatesWallet; + + /** + * CreateWalletLogic constructor. + * @param FetchesCompany $fetchesCompany + * @param GeneratesWalletCode $generatesWalletCode + * @param CreatesWallet $createsWallet + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatesTransaction $createsTransaction + * @param UpdatesWallet $updatesWallet + */ + public function __construct( + FetchesCompany $fetchesCompany, + GeneratesWalletCode $generatesWalletCode, + CreatesWallet $createsWallet, + GeneratesTransactionBillNumber $generatesTransactionBillNumber, + CreatesTransaction $createsTransaction, + UpdatesWallet $updatesWallet + ) + { + $this->fetchesCompany = $fetchesCompany; + $this->generatesWalletCode = $generatesWalletCode; + $this->createsWallet = $createsWallet; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createsTransaction = $createsTransaction; + $this->updatesWallet = $updatesWallet; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $amount = floatval(str_replace(',', '', $request->input('amount'))); + + $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); + + $reference = $request->input('reference'); + + $type = $request->input('transaction_type'); + + if (!$company->wallets()->first()) { + $object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute()); + $this->createsWallet->execute($object, $company); + } + + $wallet = $company->wallets()->first(); + + $billNumber = $this->generatesTransactionBillNumber->execute($type === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-'); + + $transaction_object = new TransactionObject($billNumber, $type === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->company->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference); + $transaction = $this->createsTransaction->execute($wallet, $transaction_object); + + $updateWalletAmount = $type === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount); + + $walletObject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount); + + $wallet = $this->updatesWallet->execute($wallet, $walletObject); + + return $this->resourceResponse(new WalletResource($wallet)); + } +} diff --git a/app/Classes/Modules/Wallets/ControllersLogic/DebitWalletLogic.php b/app/Classes/Modules/Wallets/ControllersLogic/DebitWalletLogic.php new file mode 100644 index 00000000..682065c0 --- /dev/null +++ b/app/Classes/Modules/Wallets/ControllersLogic/DebitWalletLogic.php @@ -0,0 +1,117 @@ + 'Debit into Company Wallet', + 'message' => 'You have successfully debit company wallet' + ]; + } + + + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatesTransaction */ + private $createsTransaction; + + /** @var UpdatesWallet */ + private $updatesWallet; + + /** + * CreateWalletLogic constructor. + * @param FetchesCompany $fetchesCompany + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatesTransaction $createsTransaction + * @param UpdatesWallet $updatesWallet + */ + public function __construct( + FetchesCompany $fetchesCompany, + GeneratesTransactionBillNumber $generatesTransactionBillNumber, + CreatesTransaction $createsTransaction, + UpdatesWallet $updatesWallet + ) + { + $this->fetchesCompany = $fetchesCompany; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createsTransaction = $createsTransaction; + $this->updatesWallet = $updatesWallet; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $amount = floatval(str_replace(',', '', $request->input('amount'))); + $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); + $reference = $request->input('reference'); + + if (!$company->wallets()->first()) { + $object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute()); + $wallet = $this->createsWallet->execute($object, $company); + } + + $wallet = $company->wallets()->first(); + + $billNumber = $this->generatesTransactionBillNumber->execute('DEBIT-NOTE-'); + + $transaction_object = new TransactionObject( + $billNumber, + TransactionType::DEBIT_NOTE, + 1, + $wallet->company->id, + 1, + PaymentMethodType::CASH, + $amount, + $amount, + 1, + 1, + 1, + 0, + 0, + null, + ApprovalStatus::APPROVED, + [], + $reference + ); + + $transaction = $this->createsTransaction->execute($wallet, $transaction_object); + $updateWalletAmount = $wallet->amount - $transaction->amount; + + $walletOject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount); + + $wallet = $this->updatesWallet->execute($wallet, $walletOject); + + return $this->resourceResponse(new WalletResource($wallet)); + } +} diff --git a/app/Classes/Modules/Wallets/ControllersLogic/TopUpWalletLogic.php b/app/Classes/Modules/Wallets/ControllersLogic/TopUpWalletLogic.php index 8497ec32..1c95225d 100644 --- a/app/Classes/Modules/Wallets/ControllersLogic/TopUpWalletLogic.php +++ b/app/Classes/Modules/Wallets/ControllersLogic/TopUpWalletLogic.php @@ -2,17 +2,23 @@ namespace App\Classes\Modules\Wallets\ControllersLogic; +use App\Classes\Exceptions\MalformedRequestException; use App\Classes\General\Abstracts\AbstractControllerLogic; - use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject; -use App\Classes\Modules\Wallets\Services\ListsWallet; -use App\Classes\Modules\Wallets\Services\FetchesWallet; +use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\Companies\Services\FetchesCompany; +use App\Classes\Modules\Wallets\Services\CreatesWallet; +use App\Classes\Modules\Wallets\Services\CreatesWalletTransaction; +use App\Classes\Modules\Wallets\Services\GeneratesWalletCode; +use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; +use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill; +use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\ValueObjects\Constants\TransactionType; - -use App\Classes\Modules\Wallets\Standards\Rules\CanTopUpWallet; +use App\Classes\ValueObjects\Constants\PaymentMethodType; +use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Http\Resources\WalletResource; -use App\Classes\Modules\Transactions\Processors\CreateWalletTransactionProcessor; - +use App\Http\Resources\WalletTransactionResource; +use App\Models\Wallet; use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -20,53 +26,88 @@ use Illuminate\Support\Facades\DB; class TopUpWalletLogic extends AbstractControllerLogic { + /** * @return array */ protected function notification():array { return [ 'title' => 'TopUp into Company Wallet', - 'message' => 'You have successfully topup company wallet' + 'message' => 'You have successfully created a topup request for company\'s wallet' ]; } - /** @var FetchesWallet */ - private $fetchesWallet; - /** @var CanTopUpWallet */ - private $canTopUpWallet; + /** @var FetchesCompany */ + private $fetchesCompany; + + /** @var GeneratesWalletCode */ + private $generatesWalletCode; + + /** @var CreatesWallet */ + private $createsWallet; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatesBillplzBill */ + private $createsBillplzBill; + + /** @var CreatesTransaction */ + private $createsTransaction; - /** @var CreateWalletTransactionProcessor */ - private $createWalletTransactionProcessor; /** - * CreateWalletLogic constructor. - * @param CreatesWallet $createsWallet + * TopUpWalletLogic constructor. + * @param FetchesCompany $fetchesCompany * @param GeneratesWalletCode $generatesWalletCode - * @param CanCreateCompanyWallet $canCreateCompanyWallet + * @param CreatesWallet $createsWallet + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatesBillplzBill $createsBillplzBill + * @param CreatesTransaction $createsTransaction */ - public function __construct(CanTopUpWallet $canTopUpWallet, FetchesWallet $fetchesWallet, CreateWalletTransactionProcessor $createWalletTransactionProcessor) + public function __construct(FetchesCompany $fetchesCompany, GeneratesWalletCode $generatesWalletCode, CreatesWallet $createsWallet, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesBillplzBill $createsBillplzBill, CreatesTransaction $createsTransaction) { - $this->canTopUpWallet = $canTopUpWallet; - $this->fetchesWallet = $fetchesWallet; - $this->createWalletTransactionProcessor = $createWalletTransactionProcessor; + $this->fetchesCompany = $fetchesCompany; + $this->generatesWalletCode = $generatesWalletCode; + $this->createsWallet = $createsWallet; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createsBillplzBill = $createsBillplzBill; + $this->createsTransaction = $createsTransaction; } /** * @param Request $request * @return JsonResponse - * @throws ErrorException + * @throws \App\Classes\Exceptions\MalformedRequestException */ public function logic(Request $request) : JsonResponse { - $wallet = $this->fetchesWallet->execute(['id' => $request->input('wallet_id')]); + $amount = floatval(str_replace(',', '', $request->input('amount'))); + $company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]); - $walletOject = new WalletObject( $wallet->company->id, $wallet->currency_id, $wallet->code, $request->input('amount')); + /** @var Wallet $wallet */ + $wallet = $company->wallets()->first(); - $this->canTopUpWallet->passes($walletOject); + if (!$wallet) { + $object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute()); + /** @var Wallet $wallet */ + $wallet = $this->createsWallet->execute($object, $company); + } - $transaction = $this->createWalletTransactionProcessor->execute($wallet, $walletOject, TransactionType::TOP_UP); + $user = $company->employees()->first(); + $billNumber = $this->generatesTransactionBillNumber->execute('TOPUP-'); - return $this->resourceResponse(new WalletResource($wallet)); + if($amount < 0) { + throw new MalformedRequestException('Top up credit value must be greater than zero.'); + } + + $billPlzBill = $this->createsBillplzBill->execute($user->name, $user->email, 'This payment is credit topup for company ref. ' . $company->reference, $amount, $billNumber, $request->input('bank_code')); + + $transaction_object = new TransactionObject($billNumber, TransactionType::TOP_UP, 1, $company->id, 1, PaymentMethodType::PAYMENT_GATEWAY, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, [], $billPlzBill->id); + + $transaction = $this->createsTransaction->execute($wallet, $transaction_object); + + return $this->resourceResponse(new WalletTransactionResource($transaction)); } } diff --git a/app/Classes/Modules/Wallets/Services/CreatesWallet.php b/app/Classes/Modules/Wallets/Services/CreatesWallet.php index c114b9de..2a927e6d 100644 --- a/app/Classes/Modules/Wallets/Services/CreatesWallet.php +++ b/app/Classes/Modules/Wallets/Services/CreatesWallet.php @@ -21,8 +21,6 @@ class CreatesWallet extends AbstractUpdateRelationshipRecord $model->code = $object->getCode(); $model->currency_id = $object->getCurrency(); - return $this->handler($company->wallets(), $model); - } } diff --git a/app/Classes/Modules/Wallets/Services/UpdatesWalletBalance.php b/app/Classes/Modules/Wallets/Services/UpdatesWalletBalance.php new file mode 100644 index 00000000..a724cf24 --- /dev/null +++ b/app/Classes/Modules/Wallets/Services/UpdatesWalletBalance.php @@ -0,0 +1,25 @@ +amount = $model->amount + $amount; + return $this->handler($model); + + } +} diff --git a/app/Classes/ValueObjects/Constants/TransactionType.php b/app/Classes/ValueObjects/Constants/TransactionType.php index 698abd76..040f63fa 100644 --- a/app/Classes/ValueObjects/Constants/TransactionType.php +++ b/app/Classes/ValueObjects/Constants/TransactionType.php @@ -24,5 +24,7 @@ final class TransactionType { public const CREDIT_NOTE = 9; + public const DEBIT_NOTE = 11; + public const WITHDRAW = 10; } diff --git a/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php b/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php index 45f5ebb1..c92900bd 100644 --- a/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php +++ b/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php @@ -3,6 +3,10 @@ namespace App\Http\Controllers\Bookings; use App\Classes\Modules\Bookings\ControllersLogic\AutoPurchaseOrderFillLogic; +use App\Classes\ValueObjects\Constants\ApprovalStatus; +use App\Classes\ValueObjects\Constants\TransactionType; +use App\Models\Booking; +use App\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -14,6 +18,7 @@ class AutoPurchaseOrderFillController * @return JsonResponse */ public function auto(Request $request, AutoPurchaseOrderFillLogic $logic): JsonResponse { + Auth()->login(User::find(1)); return $logic->execute($request); } diff --git a/app/Http/Controllers/Documents/ApproveDocumentController.php b/app/Http/Controllers/Documents/ApproveDocumentController.php index ae55f51c..c54b051e 100644 --- a/app/Http/Controllers/Documents/ApproveDocumentController.php +++ b/app/Http/Controllers/Documents/ApproveDocumentController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers\Documents; -use App\Classes\Modules\Documents\ControllersLogic\ApproveIdentificationDocumentLogic; +use App\Classes\Modules\Documents\ControllersLogic\ApproveDocumentLogic; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -13,7 +13,7 @@ class ApproveDocumentController * @param ApproveIdentificationDocumentLogic $logic * @return JsonResponse */ - public function approve(Request $request, ApproveIdentificationDocumentLogic $logic): JsonResponse { + public function approve(Request $request, ApproveDocumentLogic $logic): JsonResponse { return $logic->execute($request); } diff --git a/app/Http/Controllers/Documents/DeleteDocumentController.php b/app/Http/Controllers/Documents/DeleteDocumentController.php new file mode 100644 index 00000000..092f1d78 --- /dev/null +++ b/app/Http/Controllers/Documents/DeleteDocumentController.php @@ -0,0 +1,14 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Documents/UpdateDocumentReferenceController.php b/app/Http/Controllers/Documents/UpdateDocumentReferenceController.php new file mode 100644 index 00000000..f14d1b8b --- /dev/null +++ b/app/Http/Controllers/Documents/UpdateDocumentReferenceController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Wallets/CreditWalletController.php b/app/Http/Controllers/Wallets/CreditWalletController.php new file mode 100644 index 00000000..b3143588 --- /dev/null +++ b/app/Http/Controllers/Wallets/CreditWalletController.php @@ -0,0 +1,15 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Wallets/DebitWalletController.php b/app/Http/Controllers/Wallets/DebitWalletController.php new file mode 100644 index 00000000..7feafb39 --- /dev/null +++ b/app/Http/Controllers/Wallets/DebitWalletController.php @@ -0,0 +1,15 @@ +execute($request); + } +} diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 54ab047d..ee1b96a0 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -60,10 +60,8 @@ class CompanyResource extends JsonResource $segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first(); return $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : []; }), + 'wallet' => new WalletResource($this->wallets()->first()), 'created_at' => $this->created_at->format('d-m-Y') - - ]; - } } diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index b75aebe1..c95021cd 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -37,7 +37,11 @@ class TransactionResource extends JsonResource 'documents' => new DocumentResource($this->documents()->first()), 'customer_booking' => new TransactionResource($this->when((int) $this->type === TransactionType::BILL, $this->owner)), 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'), - 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A') + 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), + 'interval' => [ + 'value' => (Carbon::parse($this->created_at)->addDays(3)->gt(Carbon::now()) ) ? '+' : '-' , + 'duration' => Carbon::parse($this->created_at)->addDays(3)->diff(Carbon::now())->format('%d'), + ], ]; } } diff --git a/app/Http/Resources/WalletResource.php b/app/Http/Resources/WalletResource.php index 37ff5dbd..143af1c4 100644 --- a/app/Http/Resources/WalletResource.php +++ b/app/Http/Resources/WalletResource.php @@ -2,6 +2,7 @@ namespace App\Http\Resources; +use App\Classes\ValueObjects\Constants\TransactionType; use Illuminate\Http\Resources\Json\JsonResource; class WalletResource extends JsonResource @@ -19,7 +20,9 @@ class WalletResource extends JsonResource 'code' => $this->code, 'currency_id' => $this->currency_id, 'amount' => (double) $this->amount, - 'company_id' => (int) $this->company_id + 'company_id' => (int) $this->owner->id, + 'transactions' => WalletTransactionResource::collection($this->transactions()->whereIn('status', [2, 3])->orderBy('id', 'DESC')->get()), + 'top_up_records' => WalletTransactionResource::collection($this->transactions()->whereNotIn('status', [0])->where('type', TransactionType::TOP_UP)->orderBy('id', 'DESC')->get()) ]; } } diff --git a/app/Http/Resources/WalletTransactionResource.php b/app/Http/Resources/WalletTransactionResource.php index 1d0037fe..2384e695 100644 --- a/app/Http/Resources/WalletTransactionResource.php +++ b/app/Http/Resources/WalletTransactionResource.php @@ -2,6 +2,10 @@ namespace App\Http\Resources; +use App\Classes\General\Eloquent\Filters\TransactionServiceId; +use App\Classes\ValueObjects\Constants\TransactionType; +use App\Models\Transaction; +use Carbon\Carbon; use Illuminate\Http\Resources\Json\JsonResource; class WalletTransactionResource extends JsonResource @@ -14,16 +18,38 @@ class WalletTransactionResource extends JsonResource */ public function toArray($request) { + $description = ''; + switch((int) $this->type){ + case 5: + $description = (double) $this->amount.' Credit Top up'; + break; + case 9: + $description = 'Credit Voucher for '.$this->payment_reference; + break; + case 1: + $marking = Transaction::where('payment_reference', $this->bill_no)->first()->owner->marking; + $description = 'Payment For booking refs.'.''.$marking.''; + break; + case 11: + $description = 'Debit Voucher for '.$this->payment_reference; + break; + + } + return [ - 'id' => $this->id, - 'wallet_id' => (int) $this->wallet_id, - 'bill_no' => (int) $this->bill_no, - 'trans_type'=>(int) $this->trans_type, + 'type' => (int) $this->type, + 'bill_no' => $this->bill_no, + 'reference' => $this->payment_reference, + 'payment_method' => (float) $this->payment_method, + 'issuer_name' => $this->issuerCompany->name, 'amount' => (double) $this->amount, - 'currency_id' => (int) $this->currency_id, - 'original_amount' => (double) $this->original_amount, - 'original_currency_id' => (int) $this->original_currency_id, - 'currency_rate' => (double) $this->currency_rate + 'service_charge' => (double) $this->service_charge, + 'tax' => (double) $this->tax, + 'status' => (int) $this->status, + 'description' => $description, + 'details' => TransactionDetailResource::collection($this->transactionDetails), + 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'), + 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A') ]; } } diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 0428888d..1b70b02b 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -36,22 +36,6 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $this->BelongsTo(Booking::class, 'owner_id', 'id'); } - /** - * @return MorphMany - */ - public function wallets(): morphMany - { - return $this->morphMany(Wallet::class, 'owner'); - } - - /** - * @return BelongsTo - */ - public function wallet(): BelongsTo - { - return $this->BelongsTo(Wallet::class, 'owner_id', 'id'); - } - /** * @return MorphMany */ diff --git a/app/Models/User.php b/app/Models/User.php index d41cbb7f..6fd8b6b0 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\SoftDeletes; use Spatie\Permission\Traits\HasRoles; use Tymon\JWTAuth\Contracts\JWTSubject; @@ -23,7 +24,7 @@ class User extends AbstractModel implements AuthorizableContract, CanResetPasswordContract { - use HasRoles, Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail; + use HasRoles, Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail, SoftDeletes; /** diff --git a/app/Models/Wallet.php b/app/Models/Wallet.php index 52d8f718..29c3ddc9 100644 --- a/app/Models/Wallet.php +++ b/app/Models/Wallet.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Classes\General\Interfaces\Transactionable; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphMany; -class Wallet extends AbstractModel +class Wallet extends AbstractModel implements Transactionable { use SoftDeletes; diff --git a/resources/assets/images/fpx-logo-vector-01.png b/resources/assets/images/fpx-logo-vector-01.png new file mode 100644 index 00000000..e46fd21d Binary files /dev/null and b/resources/assets/images/fpx-logo-vector-01.png differ diff --git a/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg b/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg new file mode 100644 index 00000000..dd7ceda3 Binary files /dev/null and b/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg differ diff --git a/resources/assets/vue/components/accounts/forms/TopUpAccountComponent.vue b/resources/assets/vue/components/accounts/forms/TopUpAccountComponent.vue deleted file mode 100644 index af8a43b7..00000000 --- a/resources/assets/vue/components/accounts/forms/TopUpAccountComponent.vue +++ /dev/null @@ -1,196 +0,0 @@ - - \ No newline at end of file diff --git a/resources/assets/vue/components/address/elements/AddressListComponent.vue b/resources/assets/vue/components/address/elements/AddressListComponent.vue index c54efd95..d4efbc3d 100644 --- a/resources/assets/vue/components/address/elements/AddressListComponent.vue +++ b/resources/assets/vue/components/address/elements/AddressListComponent.vue @@ -1,22 +1,9 @@