Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into payment-billing-document

# Conflicts:
#	resources/assets/vue/components/bookings/elements/CurrencyOrderComponent.vue
#	resources/assets/vue/components/companies/elements/IdentificationVerificationComponent.vue
This commit is contained in:
edmondlang
2022-04-08 20:19:19 +08:00
208 changed files with 7440 additions and 2631 deletions
+4 -3
View File
@@ -53,6 +53,7 @@ JWT_TTL=1440
IS_PRODUCTION=false
BILLPLZ_BASE_URL="https://www.billplz-sandbox.com"
BILLPLZ_API_KEY="0fa4c710-761b-4a7a-a501-c2c2d02643d5"
BILLPLZ_X_SIGNATURE_KEY="S-pbNVthVRsvnPfZlgLwqqOg"
BILLPLZ_COLLECTION_ID="hev2wdjy"
BILLPLZ_API_KEY="d25c6170-dc00-45cd-b226-d702b957870c"
BILLPLZ_X_SIGNATURE_KEY="S-HdAU6QDubUrMErxJ-PCpgw"
BILLPLZ_COLLECTION_ID="t0cggbdd"
BILLPLZ_WALLET_COLLECTION_ID="t0cggbdd"
+4 -1
View File
@@ -24,4 +24,7 @@ db/*
docker-compose.yml
package-lock.json
public/*
/public/*
/public/*
/storage/app/public
public
/storage/framework/laravel-excel
@@ -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
{
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class Frequency implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('bookings', function ($query){}, '>=', $value);
}
}
@@ -0,0 +1,25 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class Monetary implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereHas('transactions', function ($query) use ($value){
$query->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
$query->havingRaw('SUM(amount) >= ' . $value);
});
}
}
@@ -0,0 +1,20 @@
<?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)
{
return $builder->where('owner_type', $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class PaymentMethodNotIn implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereNotIn('payment_method', $value);
}
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
class Recency implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('transactions.created_at', '>=', $value);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use Illuminate\Database\Eloquent\Builder;
class ServiceCharge implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $value);
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Models\Booking;
use Illuminate\Database\Eloquent\Builder;
class TransactionServiceId implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('owner_type', Booking::class)->whereHas('booking', function ($query) use($value) {
$query->where('service_id', $value);
});
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class WithOwner implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->with('owner');
}
}
@@ -19,8 +19,18 @@ class WithTotalPayments implements Filter
*/
public static function apply(Builder $builder, $value)
{
return $builder->leftJoin('bookings', 'companies.id', '=', 'bookings.company_id')->rightJoin('transactions', function ($join) {
$join->on('bookings.id', '=', 'transactions.owner_id')->where('owner_type', '=', Booking::class)->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->addSelect(['companies.*', DB::raw('SUM(transactions.amount) as total_payments'), DB::raw('SUM(transactions.amount / DATEDIFF(companies.created_at, CURRENT_DATE)) as spending_average_per_day'), DB::raw('SUM(transactions.amount) / count(distinct bookings.id) as spending_average_booking')])->groupBy(['companies.id']);
return $builder->leftJoin('bookings', 'companies.id', '=', 'bookings.company_id')
->rightJoin('transactions', function ($join) {
$join->on('bookings.id', '=', 'transactions.owner_id')
->where('owner_type', '=', Booking::class)
->where('transactions.type', TransactionType::PAYMENT)
->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->addSelect([
'companies.*',
DB::raw('SUM(transactions.amount) as total_payments'),
DB::raw('SUM(transactions.amount / DATEDIFF(companies.created_at, CURRENT_DATE)) as spending_average_per_day'),
DB::raw('SUM(transactions.amount) / count(distinct bookings.id) as spending_average_booking')
])
->groupBy(['companies.id']);
}
}
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace App\Classes\General;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Cache;
class ExcelHandel
{
function __construct()
{
}
public static function generateFolder($path = '')
{
$folder = \Storage::disk('public')->makeDirectory($path);
return $folder;
}
public static function insertExcel($path = '', $base64Set = [])
{
$file_info = [];
$folder_path = ExcelHandel::generateFolder('excels/' . $path);
foreach ($base64Set as $key => $row) {
$exceldata = $row;
$filename = (string) Str::uuid();
$f = finfo_open();
$mime_type = finfo_file($f, $exceldata, FILEINFO_MIME_TYPE);
$extension = 'xls';
switch ($mime_type) {
case 'application/vnd.ms-excel':
$extension = 'xls';
break;
case 'application/zip':
$extension = 'xlsx';
break;
}
if (empty($extension)) {
return false;
}
$exceldata = explode('base64,', $exceldata);
$exceldata = base64_decode($exceldata[1]);
$filename_with_ext = $filename . '.' . $extension;
$file = ExcelHandel::generateExcel($path, $exceldata, $filename, $extension);
$file_info[] = [
'path' => $path,
'filename' => $filename_with_ext,
'mime_type' => $mime_type,
'extension' => $extension,
'file_info' => empty($file) ? [] : $file,
];
}
return $file_info;
}
public static function generateExcel($path = '', $exceldata = '', $filename = '', $extension = '')
{
$file_info = [];
$file = \Storage::disk('public')->put('excels/' . $path . '/' . $filename . '.' . $extension, $exceldata);
$file_info['original']['file'] = storage_path('app/public/excels/' . $path . '/' . $filename . '.' . $extension);
return $file_info;
}
public static function removeExcel($excel_info = [])
{
$excel_info = json_decode(json_encode($excel_info), true);
foreach ($excel_info as $key => $row) {
if (!empty($row['path'])) {
\File::delete([$row['file_info']['original']['file']]);
}
}
return true;
}
}
@@ -39,7 +39,6 @@ class UpdateBankLogic extends AbstractControllerLogic
/** @var FetchesBank */
private $fetchesBank;
/**
* UpdateBankLogic constructor.
* @param CanUpdateBank $canUpdateBank
@@ -66,11 +65,18 @@ class UpdateBankLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$bankObject = new BankObject($request->input('company_id'), $request->input('country_id'),
$request->input('reference'), $request->input('bank_name'), $request->input('holder_name'),
$request->input('account_no'));
$bankObject = new BankObject(
$request->input('company_id'),
$request->input('account_type'),
$request->input('bank_name'),
$request->input('holder_name'),
$request->input('account_no'),
$request->input('bank_branch'),
$request->input('swift'),
$request->input('snap'),
$request->input('country_id'),
$request->input('reference')
);
$bank = $this->fetchesBank->execute(['id' => $request->route('id')]);
@@ -0,0 +1,62 @@
<?php
namespace App\Classes\Modules\Banks\ControllersLogic;
use App\Http\Resources\BankResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Banks\Services\FetchesBank;
use App\Classes\Modules\Banks\Services\UpdatesBankStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateBankStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Bank Account Status',
'message' => 'You have successfully updated the Bank Account Status'
];
}
/** @var FetchesBank */
private $fetchesBank;
/** @var UpdatesBankStatus */
private $updatesBankStatus;
/**
* UpdateBankStatusLogic constructor.
* @param FetchesBank $fetchesBank
* @param UpdatesBankStatus $updatesBankStatus
*/
public function __construct(
FetchesBank $fetchesBank,
UpdatesBankStatus $updatesBankStatus
)
{
$this->fetchesBank = $fetchesBank;
$this->updatesBankStatus = $updatesBankStatus;
}
/**
* @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
{
$bank = $this->fetchesBank->execute(['id' => $request->route('id')]);
$bank_query = $this->updatesBankStatus->execute($bank, $request->input('status'));
return $this->resourceResponse(new BankResource($bank_query));
}
}
@@ -23,7 +23,7 @@ class UpdatesBank extends AbstractUpdateRecord
$model->bank_branch = $object->getBankBranch();
$model->swift = $object->getSwift();
$model->snap = $object->getSnap();
$model->default = $object->getDefault();
$model->reference = $object->getReference();
return $this->handler($model);
}
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\Modules\Banks\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Models\Bank;
class UpdatesBankStatus extends AbstractUpdateRecord
{
/**
* @param Bank $model
* @param int $status
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Bank $model, int $status)
{
$model->status = $status;
return $this->handler($model);
}
}
@@ -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]);
}
}
@@ -15,14 +15,15 @@ class CreatesBillplzBill
* @param float $amount
* @param string $billNumber
* @param null|string $bankCode
* @param null|Boolean $wallet
* @return null|object
* @throws MalformedRequestException
*/
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null) {
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null, ?bool $wallet = null) {
try{
// config('billplz.maybank')
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [
'collection_id' => config('billplz.collection_id'),
'collection_id' => $wallet ? config('billplz.wallet_collection_id') : config('billplz.collection_id'),
'name' => $name,
'email' => $email,
'description' => $description,
@@ -0,0 +1,114 @@
<?php
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
*/
protected function notification():array {
return [
'title' => 'Purchase Order Approval',
'message' => 'You have successfully updated the Purchase order status'
];
}
/** @var GeneratesPurchaseOrderProducts */
private $generatesPurchaseOrderProducts;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CreatePurchaseOrderTransactionProcessor */
private $createPurchaseOrderTransactionProcessor;
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$bookings = Booking::where(function($query){
return $query->whereMonth('created_at', 11)->orWhereMonth('created_at', 12);
})->whereDoesntHave('transactions', function($q){
$q->where('type', TransactionType::PURCHASE_ORDER);
$q->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]);
})->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 (!$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();
}
$products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount);
$deference = $booking->fix_amount - $products->sum('total');
if($deference > -150 && $deference < 150 && $deference != 0) {
$products->push([
'description' => $deference < 0 ? 'Discount':'Shipping Fee',
'quantity' => 1,
'stockCode' => '',
'total' => $deference,
'unit_price' => $deference
]);
}
$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([]);
}
}
@@ -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(round($wallet->amount) < round($amount, 2)){
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));
}
@@ -78,31 +78,27 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$booking = Booking::find($request->route('id'));
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('payment_id')]);
$booking = $transaction->owner;
$billNumber = $this->generatesTransactionBillNumber->execute('RFD-');
if((int) $transaction->type === TransactionType::BILL){
$customerBooking = $booking->transactions()->payments()->complete()->where('original_amount', '=', $transaction->original_amount)->where('id', '<', $transaction->id)->orderByDesc('id')->first();
}
$refund = $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id, $transaction->bill_no);
dd($refund);
$refund = $transaction->transactions()->refunds()->sum('amount');
if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.');
$transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, (int) $transaction->type === TransactionType::BILL ? $customerBooking : $transaction, $request->input('amount'));
$transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount'));
$transactionRefundCalculationObject->init();
$object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id,
$request->input('bank_id'),$transactionRefundCalculationObject->getConversionObject()->getPaymentMethod(),
1, $transactionRefundCalculationObject->getConversionObject()->getPaymentMethod(),
$transactionRefundCalculationObject->getRefundTotalAmount(), $transactionRefundCalculationObject->getAmount(), 1,
$transactionRefundCalculationObject->getConversionObject()->getCurrencyId(), $transactionRefundCalculationObject->getTransaction()->currency_rate,
$transactionRefundCalculationObject->getRefundTax(), $transactionRefundCalculationObject->getRefundServiceCharge(), null, ApprovalStatus::PENDING_VERIFICATION, [], $transaction->bill_no);
$transaction = $this->createsTransaction->execute($booking, $object);
$transaction = $this->createsTransaction->execute($transaction, $object);
return $this->resourceResponse(new TransactionResource($transaction));
}
@@ -0,0 +1,78 @@
<?php
namespace App\Classes\Modules\Bookings\ControllersLogic;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\File;
use ZipArchive;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Booking;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
class DownloadBookingDocumentLogic
{
/**
* @param Request $request
* @return void
* @throws MalformedRequestException
*/
public function execute(Request $request)
{
Auth::login(User::findOrFail(1));
$zip_file = $request->input('type').'.zip';
$attachment = storage_path().'/app/documents/collections/' . $zip_file;
$zip = new ZipArchive();
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)
->whereDate('created_at', '>=', Carbon::parse($request->input('startDate')))
->whereDate('created_at', '<=', Carbon::parse($request->input('endDate')))->whereHas('transactions', function ($query) use ($request){
return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query) use ($request){
return $query->where('type', TransactionType::BILL)->where('issuer', $request->input('supplier'));
});
})->get();
if (!count($bookings)) throw new MalformedRequestException('No available file to download');
foreach ($bookings as $booking) {
$file = $booking->documents()->where('document_type', $request->input('type'))->first()->files()->first();
$zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');
}
$zip->close();
while (ob_get_level()) {
ob_end_clean();
}
ob_start();
header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: " . filesize($attachment));
header('Pragma: no-cache');
header("Content-Disposition: attachment; filename=\"" . basename($attachment) . "\"");
ob_flush();
ob_clean();
readfile($attachment);
File::delete($attachment);
exit;
// header('Content-Type: application/zip');
// header('Content-Length: ' . filesize($attachment));
// readfile($attachment);
// unlink($attachment);
}
}
}
@@ -72,7 +72,8 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
return $this->response(['data' => $this->generatesBookingQuotation->execute(
$this->fetchBookingQuotation->execute($booking->company, $conversionObject),
$this->fetchesCompanyPaymentAttemptLimit->execute($booking->company)
$this->fetchesCompanyPaymentAttemptLimit->execute($booking->company),
$conversionObject
)]);
}
@@ -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
@@ -31,7 +31,7 @@ class CalculatesBookingCurrencyAverageRate
}
else if ($type == TransactionType::BILL) {
return $booking->transactions()->bills()->complete()->sum('original_amount') / $booking->transactions()->bills()->complete()->sum('amount');
return $booking->bills->sum('original_amount') / $booking->bills->sum('amount');
}
}
@@ -12,7 +12,9 @@ class CalculatesBookingTransferredAmount
{
public function execute(Booking $booking){
return $booking->transactions()->bills()->complete()->sum('original_amount');
return $booking->transactions()->payments()->complete()->whereHas('transactions', function($query){
return $query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->sum('original_amount');
}
}
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Bookings\Services;
use App\Classes\Modules\Bookings\DataTransferObjects\CalculationObject;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Http\Resources\BankResource;
use App\Models\Bank;
use Carbon\Carbon;
@@ -12,12 +13,14 @@ use Carbon\CarbonInterval;
class GeneratesBookingQuotation
{
public function execute(CalculationObject $calculationObject, ?int $paymentAttemptLimit = 0){
public function execute(CalculationObject $calculationObject, ?int $paymentAttemptLimit = 0, ?CurrencyConversionObject $currencyConversionObject = null){
$date = Carbon::now();
$days = $date->diffInDays($date->copy()->addMinutes($paymentAttemptLimit));
$hours = $date->diffInHours($date->copy()->addMinutes($paymentAttemptLimit)->subDays($days)) ;
$minutes = $date->diffInMinutes($date->copy()->addMinutes($paymentAttemptLimit)->subDays($days)->subHours($hours));
$receive_date = $currencyConversionObject ? Carbon::now()->endOfDay()->addWeekdays($currencyConversionObject->getServiceId() === 3 ? 3 : 1)->timezone('Asia/Singapore')->format('4:00 \P\M, jS M, Y \G\M\T T') : null;
return [
'bank' => new BankResource(Bank::find($calculationObject->getConfigurations()->getBankId())),
'rate' => $calculationObject->getConfigurations()->getRate(),
@@ -30,6 +33,7 @@ class GeneratesBookingQuotation
'sub_total' => $calculationObject->getSubTotal(),
'total' => $calculationObject->getTotal(),
'date' => Carbon::now()->timezone('Asia/Singapore')->format('h:i a, jS M, Y \G\M\T T'),
'receive_date' => $receive_date,
'payment_attempt_limit' => CarbonInterval::days($days)->hours($hours)->minutes($minutes)->forHumans()
];
}
@@ -14,6 +14,7 @@ use App\Models\Company;
use App\Models\Currency;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;
class FetchCompanyBookingQuotationLogic extends AbstractControllerLogic
{
@@ -71,7 +72,7 @@ class FetchCompanyBookingQuotationLogic extends AbstractControllerLogic
if($calculationObject->getConvertibleTotal() < $calculationObject->getConfigurations()->getMinLimit()) throw new RequestValidationException('Your transfer is below the minimum amount allowed of '.$calculationObject->getConfigurations()->getMinLimit().' '.$currency->short_code);
//TODO add po limit validation
return $this->response(['data' => $this->generatesBookingQuotation->execute($calculationObject)]);
return $this->response(['data' => $this->generatesBookingQuotation->execute($calculationObject, 0, $conversionObject)]);
}
@@ -53,9 +53,12 @@ class ListCompaniesLogic extends AbstractControllerLogic
{
$this->canListCompanies->passes();
// dd($request->input('filters'));
// frequency = active bookings
// monetary = total spending/payment
$query = $this->listsCompanies->execute($this->listsCompanies->deserializeFilters($request->input('filters')));
// dd($query);
return $this->collectionResponse(CompanyResource::collection($query));
}
}
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\Companies\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\UpdatesCompanyDebtor;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Companies\Standards\Rules\CanUpdateCompany;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
use App\Http\Resources\CompanyResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyDebtorLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Company',
'message' => 'You have successfully updated the Company'
];
}
/** @var CanUpdateCompany */
private $canUpdateCompany;
/** @var UpdatesCompanyDebtor */
private $updatesCompanyDebtor;
/** @var FetchesCompany */
private $fetchesCompany;
/**
* UpdateCompanyControllersLogic constructor.
* @param CanUpdateCompany $canUpdateCompany
* @param UpdatesCompanyDebtor $updatesCompanyDebtor
* @param FetchesCompany $fetchesCompany
*/
public function __construct(CanUpdateCompany $canUpdateCompany, UpdatesCompanyDebtor $updatesCompanyDebtor, FetchesCompany $fetchesCompany)
{
$this->canUpdateCompany = $canUpdateCompany;
$this->updatesCompanyDebtor = $updatesCompanyDebtor;
$this->fetchesCompany = $fetchesCompany;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$debtor = $request->input('debtor');
$query = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$query = $this->updatesCompanyDebtor->execute($query, $debtor);
return $this->resourceResponse(new CompanyResource($query));
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Classes\Modules\Companies\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
use App\Models\Company;
class UpdatesCompanyDebtor extends AbstractUpdateRecord
{
/**
* @param Company $model
* @param string $debtor
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Company $model, string $debtor)
{
$model->debtor = $debtor;
return $this->handler($model);
}
}
@@ -28,7 +28,7 @@ class FileObject implements DataTransferObject
*/
public function getData()
{
return $this->getExtension() === 'pdf' ? $this->data : (new imageManager())->make($this->data);
return in_array($this->getExtension(), ['pdf', 'excel']) ? $this->data : (new imageManager())->make($this->data);
}
/**
@@ -66,7 +66,7 @@ class FileObject implements DataTransferObject
*/
public function getDecodedData(): string
{
return $this->getExtension() === 'pdf' ?
return in_array($this->getExtension(), ['pdf', 'excel']) ?
base64_decode((explode('base64,', $this->getData()))[1]):
$this->getData()->encode('data-url')->encoded;
}
@@ -36,7 +36,7 @@ class ConvertsBase64ToFile
foreach ($files as $file) {
$object = new FileObject($file);
$object->getExtension() === 'pdf' ? $this->generatePDF($object) : $this->generateImage($object);
in_array($object->getExtension(), ['pdf', 'excel']) ? $this->generatePDF($object) : $this->generateImage($object);
}
@@ -0,0 +1,97 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Company;
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;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
public function headings(): array
{
return [
'Code',
'DebtorControlAcc',
'ControlAccount',
'AccNo',
'CompanyName',
'Desc2',
'DebtorType',
'DisplayTerm',
'CurrencyCode',
'RegisterNo',
'Address1',
'Address2',
'Address3',
'PostCode',
'DeliverAddr1',
'DeliverAddr2',
'DeliverAddr3',
'DeliverPostCode',
'EmailAddress',
'Attention',
'Phone1',
'Phone2',
'Fax1'
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
return Company::where(function($query){
$query->whereNull('debtor')->orWhere('debtor', '');
})->whereNotIn('id', [2207, 2248, 2029])->where('business_type', BusinessType::IMPORTER)->where('status', ApprovalStatus::APPROVED)->whereHas('transactions', function($query){
return $query->whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP])->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::PENDING_VERIFICATION]);
});
}
/**
* @param Company $company
*
* @return array
*/
public function map($company): array
{
return [
'<<New>>',
'300-0000',
'300-0000',
'300-0000',
$company->name.' (PURCHASE)',
$company->reference,
'',
'PIA',
'MYR',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',//EmailAddress
'',
'',
'',
''
];
}
}
@@ -0,0 +1,106 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Transaction;
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;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
private $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function headings(): array
{
return [
'DocNo',
'DocDate',
'DebtorCode',
'DebtorName',
'CurrencyCode',
'ShipInfo',
'ItemCode',
'DetailDescription',
'Qty',
'UnitPrice',
'AccNo'
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
$start_date = $this->request->input('start_date', null);
if ($start_date) {
$start_date = Carbon::parse($this->request->input('start_date'))->format('Y-m-d');
}
$end_date = $this->request->input('end_date', null);
if ($end_date) {
$end_date = Carbon::parse($this->request->input('end_date'))->format('Y-m-d');
}
$query = Transaction::query();
$query->where('type', TransactionType::PAYMENT)->where('payment_method', '!=', PaymentMethodType::WALLET);
$query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
if($start_date && $end_date) {
$query->whereBetween('created_at', [
Carbon::parse($start_date)->format('Y-m-d 0:00:00'),
Carbon::parse($end_date)->format('Y-m-d 23:59:59')
]);
}
elseif($start_date && !$end_date) {
$query->where('created_at', '>=', Carbon::parse($start_date)->format('Y-m-d 0:00:00'));
}
elseif(!$start_date && $end_date) {
$query->where('created_at', '<=', Carbon::parse($end_date)->format('Y-m-d 23:59:59'));
}
return $query;
}
/**
* @param Company $transaction
*
* @return array
*/
public function map($transaction): array
{
$booking = $transaction->owner()->first();
$company = $booking->company()->first();
return [
'<<New>>',
$transaction->updated_at->format('d/m/Y'),
$company->debtor,
'',
'MYR',
$booking->marking,
'',
'PLEASE REFER TO THE ATTACHED APPENDIX REF ' . $booking->marking,
1,
$transaction->amount,
'500-0000'
];
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\CompanyType;
use App\Models\Company;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
class ExportsProducts implements FromQuery, WithHeadingRow, WithMapping
{
use Exportable;
public function headings(): array
{
return [
'HS Code',
'Name',
'price'
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
return \App\Models\TransactionDetail::inRandomOrder()->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,
];
}
}
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\CompanyType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Company;
use App\Models\Transaction;
use Maatwebsite\Excel\Concerns\Exportable;
@@ -41,6 +42,10 @@ class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
6 => 'REFUND',
7 => 'PURCHASE_ORDER',
8 => 'SUPPLIER_DELIVER',
9 => 'CREDIT_NOTE',
10 => 'WITHDRAW',
11 => 'DEBIT_NOTE',
12 => 'TRANSFER_FEE'
];
$transactionStatus = [
@@ -55,9 +60,11 @@ class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
return [
$transaction->bill_no,
$transaction->booking->marking,
$transaction->booking->company->reference,
$transaction->owner_id,
$transaction->owner_type,
$transactionTypes[$transaction->type],
$transaction->issuer,
$transaction->reciver,
$transaction->currency_id === 1 ? 'MYR' : 'RMB',
$transaction->amount,
$transaction->original_currency_id === 1 ? 'MYR' : 'RMB',
@@ -0,0 +1,105 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\Transaction;
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;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ExportsWalletTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
private $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function headings(): array
{
return [
'DocNo',
'DocDate',
'DebtorCode',
'DebtorName',
'CurrencyCode',
'ShipInfo',
'ItemCode',
'DetailDescription',
'Qty',
'UnitPrice',
'AccNo'
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
$start_date = $this->request->input('start_date', null);
if ($start_date) {
$start_date = Carbon::parse($this->request->input('start_date'))->format('Y-m-d');
}
$end_date = $this->request->input('end_date', null);
if ($end_date) {
$end_date = Carbon::parse($this->request->input('end_date'))->format('Y-m-d');
}
$query = Transaction::query();
$query->where('type', TransactionType::TOP_UP);
$query->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
if($start_date && $end_date) {
$query->whereBetween('created_at', [
Carbon::parse($start_date)->format('Y-m-d 0:00:00'),
Carbon::parse($end_date)->format('Y-m-d 23:59:59')
]);
}
elseif($start_date && !$end_date) {
$query->where('created_at', '>=', Carbon::parse($start_date)->format('Y-m-d 0:00:00'));
}
elseif(!$start_date && $end_date) {
$query->where('created_at', '<=', Carbon::parse($end_date)->format('Y-m-d 23:59:59'));
}
return $query;
}
/**
* @param Company $transaction
*
* @return array
*/
public function map($transaction): array
{
$company = $transaction->owner->owner;
return [
'<<New>>',
$transaction->updated_at->format('d/m/Y'),
$company->debtor,
'',
'MYR',
$transaction->bill_no,
'W1',
'CREDIT SALES',
1,
$transaction->amount,
'500-0000'
];
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Modules\Imports\Services;
use App\Models\Company;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithValidation;
class ImportsDebtor implements ToModel, WithHeadingRow, WithBatchInserts, WithValidation
{
public function __construct() {
}
public function model($row = [])
{
try {
preg_match_all('/([0-9]{3,4}[a-zA-Z]{3,4})/', $row['desc2'], $matches);
foreach ($matches[0] as $match){
$reference = $match;
$debtor = $row['code'];
$company = Company::where('reference', $reference)->whereNull('debtor')->first();
if ($company) {
$company->debtor = $debtor;
$company->update();
}
}
} catch (\Exception $exception){
dd($exception);
}
}
public function batchSize(): int
{
return 100;
}
public function rules(): array
{
return [
];
}
}
@@ -0,0 +1,70 @@
<?php
namespace App\Classes\Modules\SegmentConstants\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Standards\Rules\CanCreateConstant;
use App\Classes\Modules\Segments\Services\CreatesConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Http\Resources\ConstantResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateSegmentConstantLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Created Segment Constant',
'message' => 'You have successfully created a new Segment Constant'
];
}
/** @var CanCreateConstant */
private $canCreateConstant;
/** @var CreatesConstant */
private $createsConstant;
/** @var FetchesSegment */
private $fetchesSegment;
/**
* CreateSegmentLogic constructor.
* @param CanCreateConstant $canCreateConstant
* @param CreatesConstant $createsConstant
*/
public function __construct(CanCreateConstant $canCreateConstant, CreatesConstant $createsConstant, FetchesSegment $fetchesSegment)
{
$this->canCreateConstant = $canCreateConstant;
$this->createsConstant = $createsConstant;
$this->fetchesSegment = $fetchesSegment;
}
/**
* @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
{
$constant_object = new ConstantObject($request->input('name'), $request->input('reference'), $request->input('detail'));
$segment = $this->fetchesSegment->execute(['id' => $request->input('segment_id')]);
$this->canCreateConstant->passes($constant_object);
$constant = $this->createsConstant->execute($segment, $constant_object);
return $this->resourceResponse(new ConstantResource($constant));
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Modules\SegmentConstants\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Http\Resources\ConstantResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchSegmentConstantLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Segment Constant',
'message' => 'You have successfully retrieved a segment constant'
];
}
/** @var FetchesConstant */
private $fetchesConstant;
/**
* FetchSegmentLogic constructor.
* @param FetchesConstant $fetchesConstant
*/
public function __construct(FetchesConstant $fetchesConstant)
{
$this->fetchesConstant = $fetchesConstant;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\AccessForbiddenException
* @throws \App\Classes\Exceptions\RequestValidationException
*/
public function logic(Request $request) : JsonResponse
{
$query = $this->fetchesConstant->execute(['id' => $request->route('id')]);
return $this->resourceResponse(new ConstantResource($query));
}
}
@@ -0,0 +1,88 @@
<?php
namespace App\Classes\Modules\SegmentConstants\ControllersLogic;
use App\Http\Resources\ConstantResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Segments\Services\FetchesConstant;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateConstant;
use App\Classes\Modules\Segments\Services\UpdatesConstant;
use App\Classes\Modules\Segments\DataTransferObjects\ConstantObject;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UpdateSegmentConstantLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Segment Constant',
'message' => 'You have successfully updated the Segment Constant'
];
}
/** @var CanUpdateConstant */
private $canUpdateConstant;
/** @var UpdatesConstant */
private $updatesConstant;
/** @var FetchesConstant */
private $fetchesConstant;
/**
* UpdateSegmentLogic constructor.
* @param CanUpdateConstant $canUpdateConstant
* @param UpdatesConstant $updatesConstant
* @param FetchesConstant $fetchesConstant
*/
public function __construct(
CanUpdateConstant $canUpdateConstant,
UpdatesConstant $updatesConstant,
FetchesConstant $fetchesConstant
)
{
$this->canUpdateConstant = $canUpdateConstant;
$this->updatesConstant = $updatesConstant;
$this->fetchesConstant = $fetchesConstant;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
DB::beginTransaction();
$constant_query = $this->fetchesConstant->execute(['id' => $request->route('id')]);
$constant_object = new ConstantObject(
$request->input('name', $constant_query->name),
$request->input('reference', $constant_query->reference),
$request->input('detail', (array) $constant_query->detail));
$this->canUpdateConstant->passes($constant_object);
$constant_query = $this->updatesConstant->execute($constant_query, $constant_object);
DB::commit();
return $this->resourceResponse(new ConstantResource($constant_query));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -85,7 +85,7 @@ class CreatePaymentProofDocumentLogic extends AbstractControllerLogic
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
$this->createInvoiceTransactionProcessor->execute($transaction->booking);
$this->createInvoiceTransactionProcessor->execute($transaction->owner->booking);
return $this->response([]);
}
@@ -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,37 +40,35 @@ 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
*/
public function logic(Request $request) : JsonResponse
public function logic(Request $request, $id = '') : JsonResponse
{
/** @var Booking $booking */
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
/** @var Transaction $transaction */
$transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
$billNumber = $this->generatesTransactionBillNumber->execute('PO-');
@@ -102,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));
@@ -3,31 +3,19 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\Modules\Transactions\Processors\CreateSupplierTransactionProcessor;
use App\Models\Document;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Document;
use App\Models\Transaction;
use Barryvdh\DomPDF\PDF;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Meneses\LaravelLaravelMpdf\Facades\LaravelLaravelMpdf;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
class CreateSupplierTransactionLogic extends AbstractControllerLogic
{
@@ -46,14 +34,8 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
/** @var FetchesCompany */
private $fetchesCompany;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesTransaction */
private $createsTransaction;
/** @var CreateSupplierTransactionProcessor */
private $createSupplierTransactionProcessor;
/** @var CreatesDocument */
private $createsDocument;
@@ -61,64 +43,35 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
/** @var CreatesFiles */
private $createsFile;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var PDF */
private $pdf;
/**
* CreateSupplierTransactionLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesTransaction $createsTransaction
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param PDF $pdf
* @param CreateSupplierTransactionProcessor $createSupplierTransactionProcessor
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFile
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, PDF $pdf)
public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor, CreatesDocument $createsDocument, CreatesFiles $createsFile)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsTransaction = $createsTransaction;
$this->createSupplierTransactionProcessor = $createSupplierTransactionProcessor;
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->pdf = $pdf;
}
public function logic(Request $request) : JsonResponse
{
$supplier = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$rate = $request->input('rate');
$transactions = collect();
$payments = $request->input('payments');
foreach($request->input('payments') as $payment){
$this->createSupplierTransactionProcessor->execute($supplier, $rate, $payments);
/** @var Transaction $payment */
$payment = $this->fetchesTransaction->execute(['id' => $payment['id']]);
if($payment->status !== ApprovalStatus::APPROVED) continue;
if(!count($this->createSupplierTransactionProcessor->getBills())) return $this->response([]);
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED);
$billNumber = $this->generatesTransactionBillNumber->execute('SPLR-');
$object = new TransactionObject($billNumber, TransactionType::BILL, $supplier->id, 1,
$supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH,
$payment->original_amount * (1 / $rate), $payment->original_amount, 1, $payment->original_currency_id,
$rate, 0, 0, null, ApprovalStatus::PENDING_VERIFICATION);
$transactions[] = $this->createsTransaction->execute($payment->booking, $object);
}
if(!count($transactions)) return $this->response([]);
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $transactions, 'supplier' => $supplier]);
$path = Str::studly($supplier->name).'_'.Carbon::now()->format('Y_m_d_h_s_i').'.pdf';
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $this->createSupplierTransactionProcessor->getBills(), 'transferFeeTransactions' => $this->createSupplierTransactionProcessor->getTransferTransactions(), 'supplier' => $supplier]);
$object = new DocumentObject(
DocumentType::CURRENCY_VENDOR_ORDER,
@@ -0,0 +1,62 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\Modules\Transactions\Processors\CreateSupplierTransactionProcessor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use Meneses\LaravelLaravelMpdf\Facades\LaravelLaravelMpdf;
class DownloadMockUpWhiteFormPdfLogic
{
/** @var FetchesCompany */
private $fetchesCompany;
/** @var CreateSupplierTransactionProcessor */
private $createSupplierTransactionProcessor;
/**
* DownloadMockUpWhiteFormPdfLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param CreateSupplierTransactionProcessor $createSupplierTransactionProcessor
*/
public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor)
{
$this->fetchesCompany = $fetchesCompany;
$this->createSupplierTransactionProcessor = $createSupplierTransactionProcessor;
}
/**
* @param Request $request
* @return string|\Symfony\Component\HttpFoundation\Response
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Request $request)
{
$supplier = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$rate = $request->input('rate');
$payments = array_map(function($value){
return ['id' => $value];
}, json_decode($request->input('payments')));
DB::beginTransaction();
$this->createSupplierTransactionProcessor->execute($supplier, $rate, $payments);
if(!count($this->createSupplierTransactionProcessor->getBills())) return 'unexpected error';
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $this->createSupplierTransactionProcessor->getBills(), 'transferFeeTransactions' => $this->createSupplierTransactionProcessor->getTransferTransactions(), 'supplier' => $supplier]);
DB::rollBack();
return $pdf->stream('MockUpWhiteForm.pdf');
}
}
@@ -0,0 +1,46 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Models\Bank;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\GeneratesBankBalanceAccount;
class FetchBankAccountBalanceLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Bank Balance Account',
'message' => 'You have successfully retrieved bank balance account'
];
}
/** @var GeneratesBankBalanceAccount */
private $generatesBankBalanceAccount;
/**
* FetchCompanyAccountBalanceLogic constructor.
* @param GeneratesBankBalanceAccount $generatesBankBalanceAccount
*/
public function __construct(GeneratesBankBalanceAccount $generatesBankBalanceAccount)
{
$this->generatesBankBalanceAccount = $generatesBankBalanceAccount;
}
public function logic(Request $request) : JsonResponse
{
$bank = Bank::find($request->route('id'));
return $this->response(['data' => $this->generatesBankBalanceAccount->execute($bank)]);
}
}
@@ -0,0 +1,46 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Models\Company;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\GeneratesCompanyBalanceAccount;
class FetchCompanyAccountBalanceLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Company Balance Account',
'message' => 'You have successfully retrieved company balance account'
];
}
/** @var GeneratesCompanyBalanceAccount */
private $generatesCompanyBalanceAccount;
/**
* FetchCompanyAccountBalanceLogic constructor.
* @param GeneratesCompanyBalanceAccount $generatesCompanyBalanceAccount
*/
public function __construct(GeneratesCompanyBalanceAccount $generatesCompanyBalanceAccount)
{
$this->generatesCompanyBalanceAccount = $generatesCompanyBalanceAccount;
}
public function logic(Request $request) : JsonResponse
{
$company = Company::find($request->route('id'));
return $this->response(['data' => $this->generatesCompanyBalanceAccount->execute($company)]);
}
}
@@ -7,6 +7,7 @@ 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\WalletTransactionResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -0,0 +1,48 @@
<?php
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\WalletTransactionResource ;
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')));
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\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use App\Models\Company;
use App\Models\Document;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
class UpdatePaymentTransactionStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Transaction',
'message' => 'You have successfully updated a transaction'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var DeletesDocument */
private $deletesDocument;
/**
* CreatePaymentVerificationDocumentLogic constructor.
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesDocument $deletesDocument
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesDocument = $deletesDocument;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$status = $request->route('status');
$this->updatesTransactionStatus->execute($transaction, $status === 'pending' ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::COMPLETED);
if ($status == 'pending') {
$document = $transaction->documents()->first();
if ($document) {
$this->deletesDocument->execute($document);
}
}
return $this->response([]);
}
}
@@ -0,0 +1,86 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Transaction',
'message' => 'You have successfully updated a transaction'
];
}
/** @var FetchesCompany */
private $fetchesCompany;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var DeletesDocument */
private $deletesDocument;
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/**
* CreatePaymentVerificationDocumentLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesDocument $deletesDocument
* @param CreditWalletProcessor $creditWalletProcessor
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesDocument = $deletesDocument;
$this->creditWalletProcessor = $creditWalletProcessor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$transaction = $this->updatesTransactionStatus->execute($transaction, $request->input('status'));
$booking = $transaction->owner->owner;
$reference = 'Credit Voucher for Overpaid for Ref. '.$booking->marking;
if ($transaction->status == ApprovalStatus::APPROVED) {
$this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference);
}
return $this->response([]);
}
}
@@ -178,6 +178,7 @@ class CreateInvoiceTransactionProcessor
ApprovalStatus::COMPLETED,
'purchase_orders'
);
/** @var Document $document */
$document = $this->createsDocument->execute($po_order_transaction->booking, $document_object);
$this->createsFile->execute($document, $document_object);
@@ -210,6 +211,9 @@ class CreateInvoiceTransactionProcessor
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::BILL);
$transaction = $booking->transactions()->payments()->where('status', ApprovalStatus::COMPLETED)->first()
->transactions()->where('type', TransactionType::BILL)->first();
$transaction_object = new TransactionObject(
$billNumber,
TransactionType::SUPPLIER_DELIVER,
@@ -0,0 +1,76 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail;
use App\Classes\Modules\Transactions\Services\DeletesTransactionDetails;
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Transaction;
class CreatePurchaseOrderTransactionProcessor
{
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesTransaction */
private $createsTransaction;
/** @var CreatesTransactionDetail */
private $createsTransactionDetail;
/** @var UpdatesTransaction */
private $updatesTransaction;
/** @var DeletesTransactionDetails */
private $deletesTransactionDetails;
/**
* CreatePurchaseOrderTransactionProcessor constructor.
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesTransaction $createsTransaction
* @param CreatesTransactionDetail $createsTransactionDetail
* @param UpdatesTransaction $updatesTransaction
* @param DeletesTransactionDetails $deletesTransactionDetails
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, DeletesTransactionDetails $deletesTransactionDetails)
{
$this->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;
}
}
@@ -0,0 +1,143 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionServiceCharge;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionTransferFee;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Company;
use App\Models\SegmentConstant;
use App\Models\Transaction;
use Illuminate\Support\Collection;
class CreateSupplierTransactionProcessor
{
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesTransaction */
private $createsTransaction;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CalculatesTransactionServiceCharge */
private $calculatesTransactionServiceCharge;
/** @var CalculatesTransactionTransferFee */
private $calculatesTransactionTransferFee;
/** @var Collection */
private $bills;
/** @var Collection */
private $transferFee;
/**
* CreateSupplierTransactionProcessor constructor.
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesTransaction $createsTransaction
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CalculatesTransactionServiceCharge $calculatesTransactionServiceCharge
* @param CalculatesTransactionTransferFee $calculatesTransactionTransferFee
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesTransactionServiceCharge $calculatesTransactionServiceCharge, CalculatesTransactionTransferFee $calculatesTransactionTransferFee)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsTransaction = $createsTransaction;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->calculatesTransactionServiceCharge = $calculatesTransactionServiceCharge;
$this->calculatesTransactionTransferFee = $calculatesTransactionTransferFee;
$this->bills = collect();
$this->transferFee = collect();
}
/**
* @param Company $supplier
* @param String $rate
* @param array $payments
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Company $supplier, String $rate, Array $payments) {
foreach($payments as $payment){
/** @var Transaction $payment */
$payment = $this->fetchesTransaction->execute(['id' => $payment['id']]);
if($payment->status !== ApprovalStatus::APPROVED) continue;
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED);
$billNumber = $this->generatesTransactionBillNumber->execute('SPLR-');
$constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first();
$serviceCharge = $this->calculatesTransactionServiceCharge->execute($payment->original_amount, $rate, $constant);
$object = new TransactionObject($billNumber, TransactionType::BILL, $supplier->id, 1,
$supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH,
$payment->original_amount * (1 / $rate), $payment->original_amount, 1, $payment->original_currency_id,
$rate, 0, $serviceCharge, null, ApprovalStatus::PENDING_VERIFICATION);
/** @var Transaction $billTransaction */
$billTransaction = $this->createsTransaction->execute($payment, $object);
$this->pushBill($billTransaction);
$transferFeeNumber = $this->generatesTransactionBillNumber->execute('TRFR-');
$transferFee = $this->calculatesTransactionTransferFee->execute($payment->original_amount, $constant);
$object = new TransactionObject($transferFeeNumber, TransactionType::TRANSFER_FEE, 1, $supplier->id,
$supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH,
$payment->original_amount, $payment->original_amount, $payment->original_currency_id, $payment->original_currency_id,
1, 0, $transferFee, null, ApprovalStatus::PENDING_VERIFICATION);
$this->pushTransferFee($this->createsTransaction->execute($billTransaction, $object));
}
}
/**
* @return Collection
*/
public function getBills(): Collection
{
return $this->bills;
}
/**
* @return Collection
*/
public function getTransferTransactions(): Collection
{
return $this->transferFee;
}
/**
* @param $bill
*/
private function pushBill($bill): void
{
$this->bills->push($bill);
}
/**
* @param $transferFee
*/
private function pushTransferFee($transferFee): void
{
$this->transferFee->push($transferFee);
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use App\Models\SegmentConstant;
class CalculatesTransactionServiceCharge
{
/** @var CalculatesTransactionTransferFee */
private $calculatesTransactionTransferFee;
/**
* CalculatesTransactionServiceCharge constructor.
* @param CalculatesTransactionTransferFee $calculatesTransactionTransferFee
*/
public function __construct(CalculatesTransactionTransferFee $calculatesTransactionTransferFee)
{
$this->calculatesTransactionTransferFee = $calculatesTransactionTransferFee;
}
/**
* @param float $amount
* @param float $rate
* @param SegmentConstant|null $service_charge
* @return float
*/
public function execute(float $amount, float $rate, ?SegmentConstant $service_charge) {
if(!$service_charge) {
return 0;
}
$transfer_fee = $this->calculatesTransactionTransferFee->execute($amount, $service_charge);
return $service_charge->detail->amount->type === 'percentage' ? (($amount + $transfer_fee) * ( (float) $service_charge->detail->amount->value /100) * (1/$rate)) : (float) $service_charge->detail->amount->value;
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use App\Models\SegmentConstant;
class CalculatesTransactionTransferFee
{
/**
* @param float $amount
* @param SegmentConstant|null $service_charge
* @return float
*/
public function execute(float $amount, ?SegmentConstant $service_charge) {
if(!$service_charge) {
return 0;
}
return $service_charge->detail->transferFee->type === 'percentage' ? $amount * ((float) $service_charge->detail->transferFee->value /100) : (float) $service_charge->detail->transferFee->value;
}
}
@@ -0,0 +1,52 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use Carbon\Carbon;
use App\Models\Bank;
use App\Http\Resources\BankResource;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Transactions\Services\ChecksIfTransactionBillNumberExists;
use Illuminate\Database\Eloquent\Collection;
class GeneratesBankBalanceAccount
{
/** @var ChecksIfTransactionBillNumberExists */
private $checksIfTransactionBillNumberExists;
/**
* GeneratesTransactionBillNo constructor.
* @param ChecksIfTransactionBillNumberExists $checksIfTransactionBillNumberExists
*/
public function __construct(ChecksIfTransactionBillNumberExists $checksIfTransactionBillNumberExists)
{
$this->checksIfTransactionBillNumberExists = $checksIfTransactionBillNumberExists;
}
/**
* @param Bank $bank
*/
public function execute(Bank $bank) {
$floatTransactions = $bank->recipientTransactions()->where('transactions.type', TransactionType::BILL)->whereIn('transactions.status', [ApprovalStatus::APPROVED])->orderBy('id', 'DESC')->get();
$transferFeeTransactions = $bank->recipientTransactions()->where('transactions.type', TransactionType::TRANSFER_FEE)->whereIn('transactions.status', [ApprovalStatus::APPROVED])->orderBy('id', 'DESC')->get();
$creditNoteTransactions = [];
foreach($transferFeeTransactions as $transferFeeTransaction){
$creditNoteTransactions[] = $transferFeeTransaction->creditNoteTransaction;
}
$creditNoteTransactions = new Collection($creditNoteTransactions);
return [
'bank' => new BankResource($bank),
'floatTransactions' => $floatTransactions,
'transferFeeTransactions' => $transferFeeTransactions,
'creditNoteTransactions' => $creditNoteTransactions,
'account_balance' => $floatTransactions->sum('amount') + $transferFeeTransactions->sum('amount') - $creditNoteTransactions->sum('amount'),
];
}
}
@@ -0,0 +1,50 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use Carbon\Carbon;
use App\Models\Company;
use App\Http\Resources\CompanyResource;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Transactions\Services\ChecksIfTransactionBillNumberExists;
use Illuminate\Database\Eloquent\Collection;
class GeneratesCompanyBalanceAccount
{
/** @var ChecksIfTransactionBillNumberExists */
private $checksIfTransactionBillNumberExists;
/**
* GeneratesTransactionBillNo constructor.
* @param ChecksIfTransactionBillNumberExists $checksIfTransactionBillNumberExists
*/
public function __construct(ChecksIfTransactionBillNumberExists $checksIfTransactionBillNumberExists)
{
$this->checksIfTransactionBillNumberExists = $checksIfTransactionBillNumberExists;
}
/**
* @param Company $company
*/
public function execute(Company $company) {
$transferFeeTransactions = $company->issuerTransactions()->where('transactions.type', TransactionType::TRANSFER_FEE)->whereIn('transactions.status', [ApprovalStatus::APPROVED])->orderBy('id', 'DESC')->get();
$creditNoteTransactions = [];
foreach($transferFeeTransactions as $transferFeeTransaction){
$creditNoteTransactions[] = $transferFeeTransaction->creditNoteTransaction;
}
$creditNoteTransactions = new Collection($creditNoteTransactions);
return [
'company' => new CompanyResource($company),
'transferFeeTransactions' => $transferFeeTransactions,
'creditNoteTransactions' => $creditNoteTransactions,
'account_balance' => $transferFeeTransactions->sum('amount') - $creditNoteTransactions->sum('amount'),
];
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use App\Models\Transaction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
class GeneratesPurchaseOrderProducts
{
/** @var Collection */
private $products;
/**
* GeneratesPurchaseOrderProducts constructor.
* @param Collection $products
*/
public function __construct(Collection $products)
{
$this->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) {
if($product->price <= 0){
$amountDifference = $amountDifference + ($product->price * $product->quantity);
continue;
}
$units = floor(abs($amountDifference) / $product->price);
$quantity = $product->quantity;
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;
}
}
@@ -0,0 +1,101 @@
<?php
namespace App\Classes\Modules\Wallets\ControllersLogic;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Resources\WalletResource;
use App\Classes\Modules\Wallets\Services\CreatesWallet;
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Wallets\Services\GeneratesWalletCode;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
class CreditWalletLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => '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;
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/**
* CreateWalletLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param GeneratesWalletCode $generatesWalletCode
* @param CreatesWallet $createsWallet
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CreatesTransaction $createsTransaction
* @param UpdatesWallet $updatesWallet
* @param CreditWalletProcessor $creditWalletProcessor
*/
public function __construct(
FetchesCompany $fetchesCompany,
GeneratesWalletCode $generatesWalletCode,
CreatesWallet $createsWallet,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
CreatesTransaction $createsTransaction,
UpdatesWallet $updatesWallet,
CreditWalletProcessor $creditWalletProcessor
)
{
$this->fetchesCompany = $fetchesCompany;
$this->generatesWalletCode = $generatesWalletCode;
$this->createsWallet = $createsWallet;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->createsTransaction = $createsTransaction;
$this->updatesWallet = $updatesWallet;
$this->creditWalletProcessor = $creditWalletProcessor;
}
/**
* @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');
$wallet = $this->creditWalletProcessor->execute($company, $type, $amount, $reference);
return $this->resourceResponse(new WalletResource($wallet));
}
}
@@ -0,0 +1,117 @@
<?php
namespace App\Classes\Modules\Wallets\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Http\Resources\WalletResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class DebitWalletLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => '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));
}
}
@@ -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'), true);
$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));
}
}
@@ -0,0 +1,90 @@
<?php
namespace App\Classes\Modules\Wallets\Processors;
use App\Models\Wallet;
use App\Models\Company;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Wallets\Services\CreatesWallet;
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Wallets\Services\GeneratesWalletCode;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
class CreditWalletProcessor
{
/** @var GeneratesWalletCode */
private $generatesWalletCode;
/** @var CreatesWallet */
private $createsWallet;
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CreatesTransaction */
private $createsTransaction;
/** @var UpdatesWallet */
private $updatesWallet;
/**
* CreateWalletLogic constructor.
* @param GeneratesWalletCode $generatesWalletCode
* @param CreatesWallet $createsWallet
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CreatesTransaction $createsTransaction
* @param UpdatesWallet $updatesWallet
*/
public function __construct(
GeneratesWalletCode $generatesWalletCode,
CreatesWallet $createsWallet,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
CreatesTransaction $createsTransaction,
UpdatesWallet $updatesWallet
)
{
$this->generatesWalletCode = $generatesWalletCode;
$this->createsWallet = $createsWallet;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->createsTransaction = $createsTransaction;
$this->updatesWallet = $updatesWallet;
}
/**
* @param Company $company
* @param int $transactionType
* @param float $amount
* @param string $reference
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Company $company, int $transactionType, float $amount, string $reference)
{
if (!$company->wallets()->first()) {
$object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute());
$this->createsWallet->execute($object, $company);
}
/** @var Wallet $wallet */
$wallet = $company->wallets()->first();
$billNumber = $this->generatesTransactionBillNumber->execute($transactionType === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-');
$transaction_object = new TransactionObject($billNumber, $transactionType === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
$updateWalletAmount = $transactionType === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount);
$walletObject = new WalletObject($wallet->owner->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
$wallet = $this->updatesWallet->execute($wallet, $walletObject);
return $wallet;
}
}
@@ -21,8 +21,6 @@ class CreatesWallet extends AbstractUpdateRelationshipRecord
$model->code = $object->getCode();
$model->currency_id = $object->getCurrency();
return $this->handler($company->wallets(), $model);
}
}
@@ -0,0 +1,25 @@
<?php
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\Models\Wallet;
use App\Models\Company;
class UpdatesWalletBalance extends AbstractUpdateRecord
{
/**
* @param Wallet $model
* @param $amount
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Wallet $model, $amount) {
$model->amount = $model->amount + $amount;
return $this->handler($model);
}
}
@@ -8,4 +8,6 @@ final class BankAccountType {
public const EXTERNAL = 2;
public const ALIPAY= 3;
}
@@ -10,4 +10,6 @@ final class BusinessType {
public const CURRENCY_VENDOR = 3;
public const TRANSFER_AGENT = 4;
}
@@ -14,11 +14,15 @@ class FileType
public const PDF = 'application/pdf';
public const EXCEL = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
public const EXTENSION = [
'image/gif' => 'gif',
'image/png' => 'png',
'image/jpeg' => 'jpeg',
'application/pdf' => 'pdf',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'excel',
'application/vnd.ms-excel' => 'excel',
];
}
@@ -20,4 +20,8 @@ class SegmentConstants
public const CUSTOM_SERVICE_TYPE = 'CUSTOM_SERVICE_TYPE';
public const SERVICE_CHARGE = 'SERVICE_CHARGE';
public const TRANSFER_FEE = 'TRANSFER_FEE';
}
@@ -24,5 +24,9 @@ final class TransactionType {
public const CREDIT_NOTE = 9;
public const DEBIT_NOTE = 11;
public const WITHDRAW = 10;
public const TRANSFER_FEE = 12;
}
+13 -6
View File
@@ -11,8 +11,10 @@ use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Psy\Util\Json;
use ZipArchive;
class EmailDoToVTCommand extends Command
@@ -54,12 +56,17 @@ class EmailDoToVTCommand extends Command
$zip_file = 'do_'.Carbon::yesterday()->format('Y_m_d').'.zip';
$attachment = storage_path().'/'.$zip_file;
$startDate = Carbon::yesterday();
$endDate = Carbon::yesterday();
$zip = new ZipArchive();
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
$bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', Carbon::yesterday())
$bookings = \App\Models\Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $startDate)->whereDate('updated_at', '<=', $endDate)
->whereHas('transactions', function ($query){
return $query->where('type', TransactionType::BILL)->where('issuer', 2);
return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query){
return $query->where('issuer', 2);
});
})->get();
if(!count($bookings)){ return; }
@@ -72,20 +79,20 @@ class EmailDoToVTCommand extends Command
$zip->close();
Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".Carbon::yesterday()->format('d-m-Y').".\r\n\r\n**This is an automatically generated email please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment){
Mail::raw( "Attention to VT Admin team:\r\n\r\nKindly refer to the attachment for our DAILY DO COMPILATION ".$startDate->format('d-m-Y')." - ".$endDate->format('d-m-Y').".\r\n\r\n**This is an automatically generated email please do not reply to it. If you have any queries kindly contact our admin team through Wechat.\r\n\r\n\r\nCIEF WORLDWIDE SDN BHD", function($message) use ($attachment, $startDate, $endDate){
$message->from('exchange@cief-malaysia.com');
$message->to(['vtnation16@gmail.com', 'vtnation@gmail.com', 'atvantic04@gmail.com', 'vtnation2@gmail.com']);
$message->cc(['shafiqa_sukeri@cief-malaysia.com', 'frontendcief@gmail.com', 'pm@cief-malaysia.com', 'hasan@cief-malaysia.com', 'shipping_admin@cief-malaysia.com', 'hasanakbar27@gmail.com', 'pmwong2019@gmail.com', 'uldvstar@gmail.com']);
$message->subject('CIEF DO COMPILATION '.Carbon::yesterday()->format('d-m-Y'));
$message->subject('CIEF DO COMPILATION '.$startDate->format('d-m-Y').' - '.$endDate->format('d-m-Y'));
$message->attach($attachment);
});
File::delete($attachment);
echo 'success';
Log::info('success');
}
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Banks;
use App\Classes\Modules\Banks\ControllersLogic\UpdateBankStatusLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateBankStatusController
{
/**
* @param Request $request
* @param UpdateBankStatusLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateBankStatusLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,25 @@
<?php
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;
class AutoPurchaseOrderFillController
{
/**
* @param Request $request
* @param AutoPurchaseOrderFillLogic $logic
* @return JsonResponse
*/
public function auto(Request $request, AutoPurchaseOrderFillLogic $logic): JsonResponse {
Auth()->login(User::find(1));
return $logic->execute($request);
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Bookings;
use App\Classes\Modules\Bookings\ControllersLogic\DownloadBookingDocumentLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DownloadBookingDocumentController
{
/**
* @param Request $request
* @param DownloadBookingDocumentLogic $logic
* @return void
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function download(Request $request, DownloadBookingDocumentLogic $logic) {
$logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Companies;
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyDebtorLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyDebtorController
{
/**
* @param Request $request
* @param UpdateCompanyDebtorLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateCompanyDebtorLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -5,6 +5,10 @@ namespace App\Http\Controllers\Exports;
use App\Classes\Modules\Exports\Services\ExportsCustomers;
use App\Classes\Modules\Exports\Services\ExportsTransactions;
use App\Classes\Modules\Exports\Services\ExportsNullDebtors;
use App\Classes\Modules\Exports\Services\ExportsPaymentTransactions;
use App\Classes\Modules\Exports\Services\ExportsWalletTransactions;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -13,15 +17,41 @@ use Maatwebsite\Excel\Excel;
class ExportCustomersToExcelController
{
public function export(ExportsCustomers $exportsCustomers, Request $request){
/**
* ExportCustomersToExcelController constructor.
* @param Request $request
*/
public function __construct(Request $request)
{
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
}
public function export(ExportsCustomers $exportsCustomers, Request $request){
return $exportsCustomers->download('customers.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
}
public function transactions(ExportsTransactions $exportsTransactions, Request $request){
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
return $exportsTransactions->download('transactions.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
}
public function nullDebtor(ExportsNullDebtors $exportsNullDebtors, Request $request){
$response = $exportsNullDebtors->download('nullDebtor.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
ob_end_clean();
return $response;
}
public function paymentTransactions(Request $request){
$exportsTransactions = new ExportsPaymentTransactions($request);
$response = $exportsTransactions->download('payment-transactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
ob_end_clean();
return $response;
}
public function walletTransactions(Request $request){
$exportsTransactions = new ExportsWalletTransactions($request);
$response = $exportsTransactions->download('wallet-transactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
ob_end_clean();
return $response;
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Http\Controllers\Imports;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Imports\Services\ImportsDebtor;
use App\Classes\General\ExcelHandel;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
class ImportUpdateDebtorController
{
/**
* @param Request $request
* @return array
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function import(Request $request) {
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
Excel::import(new ImportsDebtor(), json_decode($object->getFiles()[0])->file_info->original->file);
return [];
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\SegmentConstants;
use App\Classes\Modules\SegmentConstants\ControllersLogic\CreateSegmentConstantLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreateSegmentConstantController
{
/**
* @param Request $request
* @param CreateSegmentConstantLogic $logic
* @return JsonResponse
*/
public function create(Request $request, CreateSegmentConstantLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\SegmentConstants;
use App\Classes\Modules\SegmentConstants\ControllersLogic\FetchSegmentConstantLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class FetchSegmentConstantController
{
/**
* @param Request $request
* @param FetchSegmentConstantLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, FetchSegmentConstantLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\SegmentConstants;
use App\Classes\Modules\SegmentConstants\ControllersLogic\UpdateSegmentConstantLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateSegmentConstantController
{
/**
* @param Request $request
* @param UpdateSegmentConstantLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateSegmentConstantLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\DownloadMockUpWhiteFormPdfLogic;
use Illuminate\Http\JsonResponse;
class DownloadMockUpWhiteFormPdfController
{
public function download(Request $request, DownloadMockUpWhiteFormPdfLogic $logic) {
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\FetchBankAccountBalanceLogic;
class FetchBankAccountBalanceController
{
/**
* @param Request $request
* @param FetchBankAccountBalanceLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, FetchBankAccountBalanceLogic $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\FetchCompanyAccountBalanceLogic;
class FetchCompanyAccountBalanceController
{
/**
* @param Request $request
* @param FetchCompanyAccountBalanceLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, FetchCompanyAccountBalanceLogic $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,14 @@
<?php
namespace App\Http\Controllers\Transactions;
use App\Classes\Modules\Transactions\ControllersLogic\UpdatePaymentTransactionStatusLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdatePaymentTransactionStatusController
{
public function update(Request $request, UpdatePaymentTransactionStatusLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers\Transactions;
use App\Classes\Modules\Transactions\ControllersLogic\UpdateRefundTransactionStatusLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateRefundTransactionStatusController
{
public function update(Request $request, UpdateRefundTransactionStatusLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Wallets;
use App\Classes\Modules\Wallets\ControllersLogic\CreditWalletLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CreditWalletController
{
public function credit(Request $request, CreditWalletLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\Wallets;
use App\Classes\Modules\Wallets\ControllersLogic\DebitWalletLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DebitWalletController
{
public function debit(Request $request, DebitWalletLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+2 -5
View File
@@ -46,6 +46,7 @@ class BookingResource extends JsonResource
],
'status' => $this->status,
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
$this->mergeWhen($this->relationLoaded('transactions'), [
'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
'payment_attempts' => TransactionResource::collection(
@@ -57,11 +58,7 @@ class BookingResource extends JsonResource
'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '<', Carbon::now())->get()),
'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
$query->where(function($query){
$query->where(function($query){
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED]);
})->orWhere(function($query){
$query->where('type', TransactionType::BILL)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
})->orWhere(function($query){
$query->where(function($query){
$query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
+11 -7
View File
@@ -15,6 +15,7 @@ use App\Models\SegmentConstant;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class CompanyResource extends JsonResource
{
@@ -28,6 +29,10 @@ class CompanyResource extends JsonResource
{
$lastPayment = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->first();
$totalPayments = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
$segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first();
$serviceCharge = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $this->id)->first();
return [
'id' => $this->id,
'name' => $this->name,
@@ -56,14 +61,13 @@ class CompanyResource extends JsonResource
],
'segments' => SegmentResource::collection($this->segments),
'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()),
'currencies' => $this->when($this->business_type === BusinessType::CURRENCY_VENDOR, function(){
$segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first();
return $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [];
}),
'created_at' => $this->created_at->format('d-m-Y')
'wallet' => new WalletResource($this->wallets()->first()),
'created_at' => $this->created_at->format('d-m-Y'),
$this->mergeWhen($this->business_type === BusinessType::CURRENCY_VENDOR, [
'currencies' => $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [],
'service_charge' => $serviceCharge
])
];
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Http\Resources;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Document;
use Carbon\Carbon;
@@ -23,7 +24,7 @@ class DocumentResource extends JsonResource
'reference' => $this->reference,
'status' => (int) $this->status,
'document_type' => $this->document_type,
'owner' => new CompanyResource($this->whenLoaded('owner')),
'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingResource($this->owner) : new CompanyResource($this->owner)) : null,
'files' => FileResource::collection($this->files),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A')
];
+14 -4
View File
@@ -3,6 +3,7 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -16,14 +17,18 @@ class TransactionResource extends JsonResource
*/
public function toArray($request)
{
$booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner;
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
return [
'id' => $this->id,
'booking' => new BookingResource($this->booking),
'booking' => new BookingResource($booking),
'type' => (int) $this->type,
'bill_no' => $this->bill_no,
'payment_reference' => $this->payment_reference,
'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($this->when((int) $this->type === TransactionType::BILL, $this->booking->bank)),
'recipient_bank_account' => new BankResource($booking->bank),
'issuer_name' => $this->issuerCompany->name,
'amount' => (double) $this->amount,
'original_amount' => (double) $this->original_amount,
@@ -35,9 +40,14 @@ class TransactionResource extends JsonResource
'status' => (int) $this->status,
'details' => TransactionDetailResource::collection($this->transactionDetails),
'documents' => new DocumentResource($this->documents()->first()),
'customer_booking' => new TransactionResource($this->when((int) $this->type === TransactionType::BILL, $this->booking->transactions()->payments()->complete()->where('original_amount', '=', $this->original_amount)->where('id', '<', $this->id)->orderByDesc('id')->first())),
'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())),
'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
'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' => $days->gt(Carbon::now()) ? '+' : '-',
'duration' => $days->diff(Carbon::now())->format('%d'),
]
];
}
}
+4 -1
View File
@@ -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())
];
}
}
@@ -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,39 @@ 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.'.'<a href="'.route('booking.details', $marking).'">'.$marking.'</a>';
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,
'marking' => $this->owner->owner->reference,
'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')
];
}
}
+11 -2
View File
@@ -2,11 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* Class Bank
* @package App\Models
@@ -41,4 +42,12 @@ class Bank extends AbstractModel
{
return $this->BelongsTo(Company::class, 'company_id', 'id');
}
/**
* @return HasMany
*/
public function recipientTransactions(): HasMany
{
return $this->HasMany(Transaction::class, 'recipient_bank_account_id');
}
}
+15 -2
View File
@@ -9,6 +9,8 @@ use App\Scopes\CustomerBookingsScope;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
/**
* Class Booking
@@ -24,6 +26,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
*/
class Booking extends AbstractModel implements Documentable, Transactionable
{
use HasRelationships;
use SoftDeletes;
protected $table = 'bookings';
@@ -94,10 +97,20 @@ class Booking extends AbstractModel implements Documentable, Transactionable
return $this->MorphMany(Transaction::class, 'owner');
}
/**
* @return hasManyDeep
*/
public function bills(): hasManyDeep
{
return $this->hasManyDeep(Transaction::class, [Transaction::class.' as alias'], [['owner_type', 'owner_id'], ['owner_type', 'owner_id']], [null, null]);
}
protected static function booted()
{
if (auth()->user()->type === RoleTypes::USER) {
static::addGlobalScope(new CustomerBookingsScope);
if (auth()->user()) {
if (auth()->user()->type === RoleTypes::USER) {
static::addGlobalScope(new CustomerBookingsScope);
}
}
}
+8
View File
@@ -101,6 +101,14 @@ class Company extends AbstractModel implements Documentable
{
return $this->hasManyDeep(Transaction::class, [Booking::class], ['company_id', 'owner_id'], ['id', 'id']);
}
/**
* @return HasMany
*/
public function issuerTransactions(): HasMany
{
return $this->HasMany(Transaction::class, 'issuer');
}
/**
* @return MorphMany
+4
View File
@@ -20,6 +20,10 @@ class SegmentConstant extends AbstractModel
protected $table = 'segment_constants';
protected $dates = ['deleted_at'];
// protected $casts = [
// 'detail' => 'array',
// ];
public function getDetailAttribute($value)
{

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