Merge branch 'development' into laravel-dusk

This commit is contained in:
Fairuz
2022-04-23 16:18:10 +08:00
60 changed files with 1542 additions and 71 deletions
@@ -0,0 +1,15 @@
<?php
namespace App\Classes\General\Interfaces;
use Illuminate\Database\Eloquent\Relations\MorphTo;
interface Notifiable
{
public function subject(): MorphTo;
public function target(): MorphTo;
public function causer(): MorphTo;
}
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Billplzs\Services;
use Illuminate\Support\Facades\Http;
use App\Classes\Exceptions\MalformedRequestException;
use Illuminate\Support\Facades\Log;
class CreatesBillplzBill
{
@@ -43,6 +44,7 @@ class CreatesBillplzBill
return (object) $data;
}else{
Log::error($response);
return null;
}
}catch(\Exception $exception){
@@ -121,7 +121,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$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'));
$billPlzBill = $this->createsBillplzBill->execute($booking->company->name, $request->user()->email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $request->input('bank_code'));
$paymentReference = $billPlzBill->id;
}
@@ -84,12 +84,14 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
$billNumber = $this->generatesTransactionBillNumber->execute('RFD-');
$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, $transaction, $request->input('amount'));
$amount = $transaction->booking->fix_currency_id == 1 ? $request->input('amount') : $request->input('amount') / $transaction->currency_rate;
$transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $amount);
$transactionRefundCalculationObject->init();
$object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id,
@@ -13,6 +13,9 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Documents\Services\FetchesDocument;
use App\Classes\Modules\Documents\Services\ApprovesDocument;
use App\Classes\Modules\Notifications\DataTransferObjects\NotificationObject;
Use App\Classes\Modules\Notifications\Processors\CreateNotificationProcessor;
use App\Classes\General\Interfaces\Notifiable;
use App\Models\Document;
use Illuminate\Http\JsonResponse;
@@ -46,6 +49,9 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic
/** @var UpdatesCompanyStatus */
private $updatesCompanyStatus;
/** @var CreateNotificationProcessor */
private $createNotificationProcessor;
/**
* ApproveIdentificationDocumentLogic constructor.
* @param CanApproveDocument $canApproveDocument
@@ -53,14 +59,16 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic
* @param RejectsDocument $rejectsDocument
* @param FetchesDocument $fetchesDocument
* @param UpdatesCompanyStatus $updatesCompanyStatus
* @param CreateNotificationProcessor $createNotificationProcessor
*/
public function __construct(CanApproveDocument $canApproveDocument, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, UpdatesCompanyStatus $updatesCompanyStatus)
public function __construct(CanApproveDocument $canApproveDocument, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, UpdatesCompanyStatus $updatesCompanyStatus, CreateNotificationProcessor $createNotificationProcessor)
{
$this->canApproveDocument = $canApproveDocument;
$this->approvesDocument = $approvesDocument;
$this->rejectsDocument = $rejectsDocument;
$this->fetchesDocument = $fetchesDocument;
$this->updatesCompanyStatus = $updatesCompanyStatus;
$this->createNotificationProcessor = $createNotificationProcessor;
}
/**
@@ -84,6 +92,16 @@ class ApproveIdentificationDocumentLogic extends AbstractControllerLogic
$this->updatesCompanyStatus->execute($document->owner, $status === 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
$object = new NotificationObject(
'ID Verification ' . ( $status === 'approve' ? 'Approved' : 'Rejected' ),
( $status === 'approve' ? 'Dear user, congratulations that your ' : 'Dear user, we are sorry to inform you that your ' ) . ( $document->type === 'IDENTITY_CARD' ? 'IC' : 'SSM' ) . ( $status === 'approve' ? ' has been approved. Start your first order now!' : ' has been rejected due to ' . ( $request->input('rejectRemark') ?? '' ) . ', please resubmit it for further action.' ),
$document->owner,
$document->owner->employees()->first(),
$document,
);
$this->createNotificationProcessor->execute($object);
return $this->resourceResponse(new DocumentResource($document));
}
@@ -0,0 +1,62 @@
<?php
namespace App\Classes\Modules\Companies\ControllersLogic;
use App\Http\Resources\CompanyResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Company Account Status',
'message' => 'You have successfully updated the Company Account Status'
];
}
/** @var FetchesCompany */
private $fetchesCompany;
/** @var UpdatesCompanyStatus */
private $updatesCompanyStatus;
/**
* UpdateCompanyStatusLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param UpdatesCompanyStatus $updatesCompanyStatus
*/
public function __construct(
FetchesCompany $fetchesCompany,
UpdatesCompanyStatus $updatesCompanyStatus
)
{
$this->fetchesCompany = $fetchesCompany;
$this->updatesCompanyStatus = $updatesCompanyStatus;
}
/**
* @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
{
$company = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$company_query = $this->updatesCompanyStatus->execute($company, $request->input('status'));
return $this->resourceResponse(new CompanyResource($company_query));
}
}
@@ -26,7 +26,6 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
'Code',
'DebtorControlAcc',
'ControlAccount',
'AccNo',
'CompanyName',
'Desc2',
'DebtorType',
@@ -56,8 +55,12 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
{
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]);
})->whereNotIn('id', [2207, 2248, 2029])->where('business_type', BusinessType::IMPORTER)->where('status', ApprovalStatus::APPROVED)->where(function($query){
$query->whereHas('transactions', function($query){
return $query->whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP])->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::PENDING_VERIFICATION]);
})->orWhereHas('wallets', function($query){
return $query->whereHas('transactions');
});
});
}
@@ -72,7 +75,6 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
'<<New>>',
'300-0000',
'300-0000',
'300-0000',
$company->name.' (PURCHASE)',
$company->reference,
'',
@@ -39,7 +39,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
'DetailDescription',
'Qty',
'UnitPrice',
'AccNo'
'AccNo',
'DeptNo'
];
}
@@ -100,7 +101,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
'PLEASE REFER TO THE ATTACHED APPENDIX REF ' . $booking->marking,
1,
$transaction->amount,
'500-0000'
'500-0000',
'CIEF'
];
}
}
@@ -11,8 +11,9 @@ use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
@@ -58,6 +59,20 @@ class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
6 => 'EXPIRED'
];
switch ($transaction->owner_type) {
case "App\Models\Booking":
$marking = $transaction->booking->company->reference;
break;
case "App\Models\Transaction":
$marking = $transaction->transactions()->first()->booking->company->reference;
break;
case "App\Models\Wallet":
$marking = $transaction->owner->owner->reference;
break;
default:
$marking = '';
}
return [
$transaction->bill_no,
$transaction->owner_id,
@@ -75,6 +90,7 @@ class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
$transactionStatus[$transaction->status],
\PhpOffice\PhpSpreadsheet\Shared\Date::dateTimeToExcel($transaction->created_at),
\PhpOffice\PhpSpreadsheet\Shared\Date::dateTimeToExcel($transaction->updated_at),
$marking
];
}
}
@@ -39,7 +39,8 @@ class ExportsWalletTransactions implements FromQuery, WithHeadings, WithHeadingR
'DetailDescription',
'Qty',
'UnitPrice',
'AccNo'
'AccNo',
'DeptNo'
];
}
@@ -80,7 +81,7 @@ class ExportsWalletTransactions implements FromQuery, WithHeadings, WithHeadingR
}
/**
* @param Company $transaction
* @param Transaction $transaction
*
* @return array
*/
@@ -99,7 +100,8 @@ class ExportsWalletTransactions implements FromQuery, WithHeadings, WithHeadingR
'CREDIT SALES',
1,
$transaction->amount,
'500-0000'
'500-0000',
'WALLET'
];
}
}
@@ -0,0 +1,61 @@
<?php
namespace App\Classes\Modules\Notifications\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Notifications\Services\ListsNotification;
use App\Http\Resources\NotificationResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListNotificationsLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieve Notifications',
'message' => 'You have successfully retrieved a list of Notifications'
];
}
/** @var ListsNotification */
private $listsNotification;
/**
* ListNotificationsLogic constructor.
* @param ListsNotification $listsNotification
*/
public function __construct(
ListsNotification $listsNotification
)
{
$this->listsNotification = $listsNotification;
}
/**
* @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
{
$filters = [
// 'target_id'=>auth()->user()->id,
// 'per_page'=>$request->route('per_page')
];
$notifications = $this->listsNotification->execute($filters);
return $this->collectionResponse(NotificationResource::collection($notifications));
}
}
@@ -0,0 +1,101 @@
<?php
namespace App\Classes\Modules\Notifications\DataTransferObjects;
use App\Classes\General\Interfaces\Notifiable;
use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
class NotificationObject implements DataTransferObject
{
/** @var string */
private $title;
/** @var string */
private $description;
/** @var Notifiable */
private $subject;
/** @var Notifiable */
private $target;
/** @var Notifiable */
private $causer;
/** @var int|null */
private $status;
/**
* OrderObject constructor.
* @param string $reference
* @param int $type
* @param int|null $status
*/
public function __construct(
string $title,
string $description,
Notifiable $subject,
Notifiable $target,
Notifiable $causer,
?int $status = ApprovalStatus::PENDING_VERIFICATION
)
{
$this->title = $title;
$this->description = $description;
$this->subject = $subject;
$this->target = $target;
$this->causer = $causer;
$this->status = $status;
}
/**
* @return int
*/
public function getTitle(): string
{
return $this->title;
}
/**
* @return int
*/
public function getDescription(): string
{
return $this->description;
}
/**
* @return Notifiable
*/
public function getSubject(): Notifiable
{
return $this->subject;
}
/**
* @return Notifiable
*/
public function getTarget(): Notifiable
{
return $this->target;
}
/**
* @return Notifiable
*/
public function getCauser(): Notifiable
{
return $this->causer;
}
/**
* @return int
*/
public function getStatus(): int
{
return $this->status;
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Classes\Modules\Notifications\Processors;
use App\Classes\Modules\Notifications\DataTransferObjects\NotificationObject;
use App\Classes\Modules\Notifications\Services\CreatesNotification;
class CreateNotificationProcessor
{
/** @var CreatesNotification */
private $createsNotification;
/**
* CreateNotificationProcessor constructor.
* @param CreatesNotification $createsNotification
*/
public function __construct(CreatesNotification $createsNotification)
{
$this->createsNotification = $createsNotification;
}
public function execute(NotificationObject $object)
{
$notification = $this->createsNotification->execute($object);
return $notification;
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Classes\Modules\Notifications\Services;
use App\Classes\Modules\Notifications\DataTransferObjects\NotificationObject;
use App\Models\Notification;
class CreatesNotification
{
/**
* @param NotificationObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(NotificationObject $object) {
$model = new Notification();
$model->title = $object->getTitle();
$model->description = $object->getDescription();
$model->status = $object->getStatus();
$model->subject_type = get_class($object->getSubject());
$model->subject_id = $object->getSubject()->id;
$model->target_type = get_class($object->getTarget());
$model->target_id = $object->getTarget()->id;
$model->causer_type = get_class($object->getCauser());
$model->causer_id = $object->getCauser()->id;
$model->save();
return $model;
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Notifications\Services;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Notification;
class ListsNotification extends AbstractListRecord
{
/** @var Bank */
private $repository;
/**
* ListsBank constructor.
* @param Notification $repository
*/
public function __construct(Notification $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -87,7 +87,7 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
$service_charge = 0;
foreach ($this->createSupplierTransactionProcessor->getBills() as $key => $row) {
$group->transaction()->sync($row->id, false);
$group->transactions()->sync($row->id, false);
$issuer = $row->issuer;
$receiver = $row->receiver;
$amount += $row->amount;
@@ -0,0 +1,72 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesGroup;
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
use App\Classes\Modules\Transactions\Services\updatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Http\Resources\GroupResource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeleteGroupLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Delete Group Transaction',
'message' => 'You have successfully deleted this Group Transaction'
];
}
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var FetchesGroup */
private $fetchesGroup;
/** @var DeletesTransaction */
private $deletesTransaction;
public function __construct(
UpdatesTransactionStatus $updatesTransactionStatus,
FetchesGroup $fetchesGroup,
DeletesTransaction $deletesTransaction
)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->fetchesGroup = $fetchesGroup;
$this->deletesTransaction = $deletesTransaction;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$group = $this->fetchesGroup->execute(['id' => $request->route('id')]);
$items = $group->transactions()->get();
foreach($items as $item) {
$bill = $item;
$payment = $bill->owner;
$group->transactions()->detach($bill->id);
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::APPROVED);
$this->deletesTransaction->execute($bill);
}
$group->delete();
return $this->resourceResponse(new GroupResource($group));
}
}
@@ -0,0 +1,42 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Http\Resources\GroupResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListGroupsLogic extends AbstractControllerLogic
{
/**
* ListTransactionsLogic constructor.
* @param ListsGroups $listsGroups
*/
public function __construct(ListsGroups $listsGroups)
{
$this->listsGroups = $listsGroups;
}
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Groups',
'message' => 'You have successfully retrieved a list of groups'
];
}
/** @var ListsGroups */
private $listsGroups;
public function logic(Request $request) : JsonResponse
{
$query = $this->listsGroups->execute($this->listsGroups->deserializeFilters($request->input('filters')));
return $this->collectionResponse(GroupResource::collection($query));
}
}
@@ -0,0 +1,141 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Http\Resources\GroupResource;
use App\Models\SegmentConstant;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionServiceCharge;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\FetchesGroup;
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionTransferFee;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use ErrorException;
class UpdateGroupLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Group Transaction',
'message' => 'You have successfully updated this Group Transaction'
];
}
/** @var FetchesGroup */
private $fetchesGroup;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var CalculatesTransactionServiceCharge */
private $calculatesTransactionServiceCharge;
/** @var UpdatesTransaction */
private $updatesTransaction;
/** @var CalculatesTransactionTransferFee */
private $calculatesTransactionTransferFee;
public function __construct(
FetchesGroup $fetchesGroup,
FetchesCompany $fetchesCompany,
CalculatesTransactionServiceCharge $calculatesTransactionServiceCharge,
UpdatesTransaction $updatesTransaction,
CalculatesTransactionTransferFee $calculatesTransactionTransferFee
)
{
$this->fetchesGroup = $fetchesGroup;
$this->fetchesCompany = $fetchesCompany;
$this->calculatesTransactionServiceCharge = $calculatesTransactionServiceCharge;
$this->updatesTransaction = $updatesTransaction;
$this->calculatesTransactionTransferFee = $calculatesTransactionTransferFee;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$group = $this->fetchesGroup->execute(['id' => $request->route('id')]);
$transactions = $group->transactions()->get();
$rate = $request->input('rate');
$supplier = $this->fetchesCompany->execute(['id' => $request->input('supplier_id')]);
foreach($transactions as $transaction) {
$constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first();
$serviceCharge = $this->calculatesTransactionServiceCharge->execute($transaction->original_amount, $rate, $constant);
$object = new TransactionObject(
$transaction->bill_no,
TransactionType::BILL,
$supplier->id,
1,
$supplier->banks()->where('default', true)->first()->id,
PaymentMethodType::CASH,
$transaction->original_amount * (1 / $rate),
$transaction->original_amount,
1,
$transaction->original_currency_id,
$rate,
0,
$serviceCharge,
null,
ApprovalStatus::PENDING_VERIFICATION
);
$billTransaction = $this->updatesTransaction->execute($transaction, $object);
$transferTransaction = $transaction->transactions()->where('type', TransactionType::TRANSFER_FEE)->first();
$transferFee = $this->calculatesTransactionTransferFee->execute($billTransaction->amount, $constant);
$object = new TransactionObject(
$transferTransaction->bill_no,
TransactionType::TRANSFER_FEE,
1,
$supplier->id,
$supplier->banks()->where('default', true)->first()->id,
PaymentMethodType::CASH,
$transaction->original_amount,
$transaction->original_amount,
$transaction->original_currency_id,
$transaction->original_currency_id,
1,
0,
$transferFee,
null,
ApprovalStatus::PENDING_VERIFICATION
);
$this->updatesTransaction->execute($transferTransaction, $object);
}
$group->issuer = $supplier;
$group->amount = $group->transactions()->sum('amount');
$group->currency_rate = $rate;
$group->tax = $group->transactions()->sum('tax');
$group->service_charge = $group->transactions()->sum('service_charge');
$group->save();
return $this->resourceResponse(new GroupResource($group));
}
}
@@ -97,7 +97,7 @@ class CreateSupplierTransactionProcessor
$this->pushBill($billTransaction);
$transferFeeNumber = $this->generatesTransactionBillNumber->execute('TRFR-');
$transferFee = $this->calculatesTransactionTransferFee->execute($payment->original_amount, $constant);
$transferFee = $this->calculatesTransactionTransferFee->execute($billTransaction->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,
@@ -31,7 +31,7 @@ class CalculatesTransactionServiceCharge
return 0;
}
$transfer_fee = $this->calculatesTransactionTransferFee->execute($amount, $service_charge);
$transfer_fee = $this->calculatesTransactionTransferFee->execute(($amount * (1 / $rate)), $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,31 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use App\Models\Group;
use Illuminate\Database\Eloquent\Builder;
use App\Classes\General\Eloquent\AbstractFetchRecord;
class FetchesGroup extends AbstractFetchRecord
{
/** @var Group */
private $repository;
/**
* ListsBookings constructor.
* @param Group $repository
*/
public function __construct(Group $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,31 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
use App\Models\Group;
use Illuminate\Database\Eloquent\Builder;
use App\Classes\General\Eloquent\AbstractListRecord;
class ListsGroups extends AbstractListRecord
{
/** @var Group */
private $repository;
/**
* ListsBookings constructor.
* @param Group $repository
*/
public function __construct(Group $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -102,7 +102,7 @@ class TopUpWalletLogic extends AbstractControllerLogic
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);
$billPlzBill = $this->createsBillplzBill->execute($company->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);
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Companies;
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyStatusLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyStatusController
{
/**
* @param Request $request
* @param UpdateCompanyStatusLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateCompanyStatusLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\Notifications;
use App\Classes\Modules\Notifications\ControllersLogic\ListNotificationsLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListNotificationsController
{
/**
* @param Request $request
* @param ListNotificationsLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListNotificationsLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\DeleteGroupLogic;
class DeleteGroupController
{
/**
* @param Request $request
* @param DeleteGroupTransactionLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, DeleteGroupLogic $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\ListGroupsLogic;
class ListGroupsController
{
/**
* @param Request $request
* @param ListGroupsLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListGroupsLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\UpdateGroupLogic;
class UpdateGroupController
{
/**
* @param Request $request
* @param DeleteGroupTransactionLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateGroupLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+1
View File
@@ -31,6 +31,7 @@ class BookingResource extends JsonResource
'service' => new ServiceTypeResource($this->service),
'marking' => $this->marking,
'amount' => $this->fix_amount,
'amount' => $this->fix_amount,
'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace App\Http\Resources;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class GroupResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'original_amount' => (double) $this->original_amount,
'original_currency' => new CurrencyResource($this->original_currency),
'amount' => (double) $this->amount,
'currency' => new CurrencyResource($this->currency),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
'currency_rate' => (float) $this->currency_rate,
'transactions' => TransactionResource::collection($this->transactions()->get()),
];
}
}
@@ -0,0 +1,30 @@
<?php
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
use App\Classes\ValueObjects\Constants\DocumentType;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Crypt;
class NotificationResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'long_ago' => $this->created_at->diffForHumans(),
'created_at' => $this->created_at->format('d-m-Y')
];
}
}
@@ -30,6 +30,7 @@ class TransactionResource extends JsonResource
'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($booking->bank),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (double) $this->amount,
'original_amount' => (double) $this->original_amount,
'currency' => new CurrencyResource($this->currency),
+27 -1
View File
@@ -3,11 +3,37 @@
namespace App\Models;
use App\Classes\General\Interfaces\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class AbstractModel extends Model
class AbstractModel extends Model implements Notifiable
{
use LogsActivity;
protected static $logFillable = true;
/**
* @return MorphTo
*/
public function subject(): MorphTo
{
return $this->MorphTo('subject');
}
/**
* @return MorphTo
*/
public function target(): MorphTo
{
return $this->MorphTo('target');
}
/**
* @return MorphTo
*/
public function causer(): MorphTo
{
return $this->MorphTo('causer');
}
}
+19 -2
View File
@@ -3,11 +3,28 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Group extends Model
{
public function transaction()
public function transactions()
{
return $this->belongsToMany('App\Models\Transaction', 'group_transaction');
return $this->belongsToMany(Transaction::class, GroupTransaction::class);
}
/**
* @return BelongsTo
*/
public function currency(): BelongsTo
{
return $this->BelongsTo(Currency::class, 'currency_id', 'id');
}
/**
* @return BelongsTo
*/
public function original_currency(): BelongsTo
{
return $this->BelongsTo(Currency::class, 'original_currency_id', 'id');
}
}
+18 -1
View File
@@ -3,8 +3,25 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class GroupTransaction extends Model
{
//
protected $table = 'group_transactions';
/**
* @return BelongsTo
*/
public function group(): BelongsTo
{
return $this->BelongsTo(Group::class, 'group_id', 'id');
}
/**
* @return BelongsTo
*/
public function transaction(): BelongsTo
{
return $this->BelongsTo(Transaction::class, 'transaction_id', 'id');
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class Notification extends AbstractModel
{
use SoftDeletes;
protected $table = 'notifications';
public function package(): BelongsTo
{
return $this->BelongsTo(Package::class, 'package_id', 'id');
}
}
@@ -13,7 +13,8 @@ class CreateGroupTransactionsTable extends Migration
*/
public function up()
{
Schema::create('group_transaction', function (Blueprint $table) {
Schema::create('group_transactions', function (Blueprint $table) {
$table->id();
$table->foreignId('group_id')->unsigned();
$table->foreignId('transaction_id')->unsigned();
});
@@ -26,6 +27,6 @@ class CreateGroupTransactionsTable extends Migration
*/
public function down()
{
Schema::dropIfExists('group_transaction');
Schema::dropIfExists('group_transactions');
}
}
@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
class CreateNotificationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->morphs('subject');
$table->morphs('target');
$table->morphs('causer');
$table->integer('status')->default(ApprovalStatus::APPROVED);
$table->softDeletes();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('notifications');
}
}
+6
View File
@@ -316,6 +316,12 @@ hr{
background-color: $color-primary-lighter !important;
}
.bg-primary-lighter-hover {
&:hover {
background-color: $color-primary-lighter !important;
}
}
/* Complete
------------------------------------
*/
@@ -148,7 +148,6 @@
</div>
<div class="row" v-show="createBank">
<div class="col">
{{ data.company.id }}
<bank-account-form-component v-if="data.serviceType.id !== 4" section="customerProfileSection" :disabled="formDisabled" :data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}" :company_id="data.company.id" :country_id="2" :type="2" v-on:createdBank="updateBank($event)" :serviceType="data.serviceType" :closable=false v-on:close="clearAccount()"></bank-account-form-component>
<phone-account-form-component v-if="data.serviceType.id === 4" section="customerProfileSection" :disabled="formDisabled" :data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}" :company_id="data.company.id" :country_id="2" :type="2" v-on:createdBank="updateBank($event)" :serviceType="data.serviceType" :closable=false v-on:close="clearAccount()"></phone-account-form-component>
</div>
@@ -40,7 +40,7 @@
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Currency Order Placed</h5>
<div class="fs-11">Are you sure you that the currency order has been placed with the supplier?</div>
<div class="fs-11">Are you sure that the currency order has been placed with the supplier?</div>
</div>
</div>
<div class="row">
@@ -219,7 +219,7 @@
</div>
</div>
</div>
<div class="row m-t-10" v-show="[2, 3].includes(item.status) && totalRequestedRefund < data.booking.amount">
<div class="row m-t-10" v-show="[2, 3].includes(item.status) && totalRequestedConvertRefund < data.booking.amount">
<div class="col hide">
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="transferSummary">Request Refund</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="transferSummary" size="large">
@@ -249,12 +249,25 @@
},
computed: {
totalRequestedRefund() {
let vm = this;
var TotalRequestedRefund = 0;
this.data.transaction_refunds.forEach(function(refunds) {
TotalRequestedRefund += refunds.status === 1 ? refunds.original_amount : 0;
});
return TotalRequestedRefund;
},
totalRequestedConvertRefund() {
let vm = this;
var TotalRequestedRefund = 0;
this.data.transaction_refunds.forEach(function(refunds) {
TotalRequestedRefund += refunds.status === 1 ? refunds.original_amount : 0;
});
if (vm.data.booking.fixed_currency.id != 1 && this.data.transaction_refunds[0]) {
TotalRequestedRefund = (TotalRequestedRefund * this.data.transaction_refunds[0].currency_rate);
}
return ((Math.round((TotalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
},
totalRefunds() {
var TotalRequestedRefund = 0;
this.data.transaction_refunds.forEach(function(refunds) {
@@ -1,5 +1,5 @@
<template>
<div class="row m-b-10">
<div class="row m-b-10 p-b-10 b-b" style="border-bottom-width: 3px;">
<div class="col">
<div class="row">
<div class="col">
@@ -0,0 +1,98 @@
<template>
<div class="row m-b-10 parentContainer">
<div class="col">
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
<div class="row p-b-5 b-b b-grey" v-show="!isLoading">
<div class="col">
<div class="row m-b-10">
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">Date</div>
<div class="font-heading fs-10">
{{item.created_at}}
</div>
</div>
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">Currency Rate</div>
<div class="font-heading fs-10">
{{item.currency_rate}}
</div>
</div>
<div class="col text-right">
<div class="font-heading fs-10 muted all-caps">Amount</div>
<div class="font-heading fs-14 text-success bold">
{{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="font-heading fs-10 muted all-caps">reference</div>
<span class="font-heading fs-10" v-for="transaction in item.transactions">
<a :href="route('booking.details', transaction.booking.marking)">{{transaction.booking.marking}}&nbsp;</a>
</span>
</div>
<div class="col-auto">
<div class="row parentContainer">
<div class="col p-l-0">
<button class="btn btn-xs btn-default bg-warning b-rad-none no-border requestModal" data-type="editTransactionGroup">
<i class="fa fa-pencil text-white"></i>
</button>
<modal-component small type="editTransactionGroup">
<edit-transaction-group-form-component :section="section" :currency_rate="item.currency_rate" :supplier_id ="data.transactions[0].issuer_id" :id="item.id"></edit-transaction-group-form-component>
</modal-component>
<button class="btn btn-xs btn-default bg-danger b-rad-none no-border requestModal" data-type="deleteTransactionGroup">
<i class="fa fa-times text-white"></i>
</button>
<modal-component small type="deleteTransactionGroup">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col text-center">
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Delete Transaction Group</h5>
<div class="fs-11">Are you sure that you want to delete this transaction group?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div data-dismiss="modal" class="btn btn-sm btn-danger btn-block b-rad-none" @click="deleteGroupTransaction()">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</modal-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import staticFormHandler from '../../../general/mixins/staticFormHandler'
export default {
props: {
section:{
type: String,
required: true
}
},
methods: {
deleteGroupTransaction() {
this.isLoading = true;
this.submit(this.route('api.transaction.group.delete', this.item.id), 'delete', this.section, true, true);
}
},
mixins: [componentHandler, staticFormHandler]
}
</script>
@@ -0,0 +1,92 @@
<template>
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="row m-b-10">
<div class="col">
<h5 class="all-caps m-b-5 bold no-margin">Edit Transaction Group</h5>
</div>
</div>
<div class="row m-b-5 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
<div class="col">
<small class="bold fs-10 text-danger">{{error}}</small>
</div>
</div>
<div class="row m-b-10">
<div class="col">
<validation-wrapper-component selectable :validator="$v.parameters.supplier_id">
<label>Supplier</label>
<selectable-component :endpoint="route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [2, 0]})" section="supplierListSection" valueColumn="id" :labelColumn="['name']" v-model="parameters.supplier_id"></selectable-component>
</validation-wrapper-component>
</div>
</div>
<div class="row m-b-10">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.rate">
<label class="all-caps">Purchase Rate</label>
<input type="text" class="form-control" v-model.lazy="parameters.rate" v-money="exchangeRate">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-default bg-master-lightest btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Update</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
props: {
currency_rate:{
type: Number,
required: true
},
supplier_id: {
type: Number,
required: true
},
id: {
type: Number,
required: true
}
},
data(){
return {
error: '',
suppliers: [],
selectedSupplier: {
id: '',
name: '',
status: false
},
parameters: {
supplier_id: this.supplier_id,
rate: (Math.round((this.currency_rate + Number.EPSILON) * 10000) / 10000).toFixed(5)
},
}
},
validations: {
parameters: {
supplier_id: { },
rate: { },
},
},
methods: {
submitForm() {
this.submit(route('api.transaction.group.update', this.id), 'put', this.section, true, true);
}
},
mixins: [ModalFormHandler]
}
</script>
@@ -123,28 +123,7 @@
</button>
</div>
<modal-component small type="rejectDocument">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col text-center">
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Reject Document</h5>
<div class="fs-11">Are you sure you want to reject this customer's identification?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div data-dismiss="modal" class="btn btn-sm btn-danger btn-block b-rad-none" @click="approveDocument('reject')">Reject</div>
</div>
</div>
</div>
</div>
</div>
</div>
<reject-identification-verification-form-component :section="section" :data="item"></reject-identification-verification-form-component>
</modal-component>
<div class="col no-padding ml-auto">
<button class="btn btn-md btn-block btn-success b-rad-none p-t-10 p-b-10 requestModal" data-type="approveDocument">
@@ -0,0 +1,78 @@
<template>
<div class="row">
<div class="col">
<div class="row justify-content-center">
<div class="col-auto text-center">
<div class="row">
<div class="col text-center">
<div class="row">
<div class="col">
<h5 class="all-caps">Reject Document</h5>
<div class="fs-11">Are you sure you want to reject this customer's identification?</div>
</div>
</div>
<div class="row text-left margin-auto m-t-10 m-b-10">
<div class="col">
<span class="text-danger fs-9">{{ error }}</span>
<div class="fs-11">Reason: </div>
<div class="row">
<div class="col fs-11">
<div class="b-a padding-5 w-100 m-b-5 pointer b-grey muted" :class="{'b-primary': rejectRemark === rejectRemarkItem, 'text-primary': rejectRemark === rejectRemarkItem}" v-for="rejectRemarkItem in rejectRemarkArray" @click="chooseRejectRemark(rejectRemarkItem)">{{ rejectRemarkItem }}</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div data-dismiss="modal" class="btn btn-sm btn-default bg-master-lighter btn-block b-rad-none">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="approveDocument('reject')">Reject</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required } from "vuelidate/lib/validators";
export default {
data(){
return {
rejectRemark: null,
rejectRemarkArray: null,
documentType: this.data.document_type === 'IDENTITY_CARD' ? 'IC' : 'SSM',
error: null,
}
},
validations: {
rejectRemark: { required },
},
created(){
this.rejectRemarkArray = [
this.documentType + ' not clear',
this.documentType + ' name different with registration name',
'Wrong Document uploaded',
'Non-Malaysian ' + this.documentType + ' Uploaded',
this.documentType + ' not Genuine'
];
},
methods: {
approveDocument(status){
this.rejectRemark === null ? this.error = 'Please choose a remark.' : null;
this.isLoading = true;
this.submit(this.route('api.company.identification.approval', this.item.owner.id, this.item.id, status), 'put', 'identificationVerificationSection', true, true);
},
chooseRejectRemark(remark) {
this.rejectRemark = remark;
}
},
mixins: [componentHandler, modalFormHandler]
}
</script>
@@ -61,6 +61,18 @@
<div class="col-auto">
<div class="row">
<div class="col">
<button class="btn btn-xs btn-outline-primary b-rad-none m-r-5 requestModal" data-type="activateSupplierModal" v-if="item.status === 5">
Activate
</button>
<modal-component type="activateSupplierModal">
<activate-supplier-form-component :data="item" section="suppliersSection"></activate-supplier-form-component>
</modal-component>
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="suspendSupplierModal" v-if="item.status !== 5">
Suspend
</button>
<modal-component type="suspendSupplierModal">
<suspend-supplier-form-component :data="item" section="suppliersSection"></suspend-supplier-form-component>
</modal-component>
<button class="btn btn-xs btn-outline-warning b-rad-none m-r-5 requestModal" data-type="editServiceCharge">
<i class="fa fa-pencil"></i>
</button>
@@ -0,0 +1,45 @@
<template>
<div class="row text-center">
<div class="col">
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
<div class="row justify-content-center" v-show="!isLoading">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h3 class="all-caps">Are you Sure?</h3>
<div class="fs-11">Are you sure you want to activate this Supplier?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submitForm()">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
props: {
section: {
default: 'suppliersSection'
}
},
methods: {
submitForm() {
this.parameters.status = 1;
this.submit(this.route('api.company.status.update', this.data.id), 'put', this.section, true, false);
}
},
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -0,0 +1,45 @@
<template>
<div class="row text-center">
<div class="col">
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
<div class="row justify-content-center" v-show="!isLoading">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h3 class="all-caps">Are you Sure?</h3>
<div class="fs-11">Are you sure you want to suspend this Supplier?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submitForm()">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
props: {
section: {
default: 'suppliersSection'
}
},
methods: {
submitForm() {
this.parameters.status = 5;
this.submit(this.route('api.company.status.update', this.data.id), 'put', this.section, true, false);
}
},
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -0,0 +1,105 @@
<template>
<div class="row h-100">
<div class="col">
<div class="btn-group h-100">
<div class="d-none d-md-flex row align-items-center justify-content-center b-a b-thick h-100 pointer" :class="{'b-info' : isClicked}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @click="openNotification()" style="border-color: #ffffff3d">
<div class="col p-r-10 p-l-10">
<i class="fa fa-bell fs-12" :class="{'text-info' : isClicked, 'text-primary-lighter' : !isClicked}"></i>
</div>
</div>
<i class="fa fa-bell fs-18 d-md-none" :class="{'text-info' : isClicked, 'text-white' : !isClicked}" style="margin-right: -10px;" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @click="openNotification()"></i>
<div class="b-rad-md dropdown-menu dropdown-menu-right p-l-15 p-b-15 p-r-15 p-t-0" style="height: 100vh; width:100vw; background: transparent !important; box-shadow: none!important;" @click="openNotification()">
<div class="container-fluid container-fixed-lg" style="position: relative; background: transparent; height: 100vh; left: 0;">
<div class="row shadow" style="width: 320px; position: absolute; top: 50px; right: 30px; background: white!important;">
<div class="col">
<div class="row">
<div class="bg-master-lighter col p-l-10 p-l-10 p-t-10 bg-white text-center">
<p>Notification Center</p>
</div>
</div>
<loading-component style="height: 200px; top: 0;" key="1" color="primary" v-show="isLoading"></loading-component>
<div class="row" :class="{'h-100' : notificationsLength >= 5}" v-show="!isLoading" style="max-height: 400px; ">
<div class="col page-container overflow-hidden">
<div class="row b-b b-grey bg-primary-lighter-hover pointer w-100 m-l-0 m-r-0" v-for="(notification, index) in notifications">
<div class="col-auto justify-content-center align-items-center d-flex hide">
<div>
<i class="fa fa-check-circle fs-20 p-l-5 text-success"></i>
</div>
</div>
<div class="col padding-10 p-l-15 p-r-15">
<p class="bold m-b-5 lh-16">{{ notification.title }}</p>
<p class="fs-9 m-b-0 lh-10">{{ notification.description }}</p>
<p class="fs-9 m-b-0 m-t-10 lh-10">{{ notification.long_ago }}</p>
</div>
<div class="col-auto justify-content-center align-items-center d-none" :class="{'d-flex' : index === 0}">
<div>
<i class="fa fa-circle fs-10 text-primary"></i>
</div>
</div>
</div>
</div>
</div>
<div class="row text-center m-t-50 m-b-50" v-if="notificationsLength === 0" v-show="!isLoading">
<div class="col">
<div class="row align-items-center justify-content-center hint-text">
<div class="col-4 hint-text"><img src="/images/not-found-illustration.png" class="w-100 hint-text"/></div>
</div>
<div class="row text-center">
<div class="col">
<div class="row m-t-20">
<div class="col">
<p class="all-caps no-margin fs-11" style="letter-spacing: 2px;">Nothing To Show Here</p>
</div>
</div>
<div class="row m-t-5 align-items-center justify-content-center hide">
<div class="col">
<small class="fs-9 muted all-caps font-lato" style="letter-spacing: 2px">There is no results found.</small>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row b-t muted">
<div class="col p-l-10 p-l-10 p-t-10 m-b-10 bg-white text-center">
<a href="#">View All Notifications</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
data(){
return {
isLoading: true,
error: '',
notifications: null,
isClicked: false,
notificationsLength: 0,
}
},
methods: {
openNotification(){
this.isClicked === false ? this.fetchNotification() : '';
this.isClicked = !this.isClicked;
},
fetchNotification(){
this.isLoading = true;
this.submit(route('notifications.list'), 'get', this.section, false, false)
},
successHandler(response){
this.isLoading = false;
this.notifications = response.payload.data;
this.notificationsLength = response.payload.data.length;
},
},
mixins: [ModalFormHandler]
}
</script>
@@ -35,7 +35,7 @@
<div class="col bg-white padding-25">
<div class="row tabsContainer tabContent active" tab-name="complete">
<div class="col">
<list-component section="CompletePaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status_in: [2, 3], type: 3, issuer_not_in: [2185, 1970, 1921]}">
<list-component section="CompletePaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status_in: [2, 3], type: 3, issuer_not_in: [1921, 1970, 2185, 2327, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
@@ -125,7 +125,7 @@
<div class="col bg-white padding-25">
<div class="row tabsContainer tabContent active" tab-name="paymentProof">
<div class="col">
<list-component ref="paymentProofList" section="jackPaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 1, type: 3, issuer_in: [2185, 1970, 1921]}">
<list-component ref="paymentProofList" section="jackPaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 1, type: 3, issuer_in: [1921, 1970, 2185, 2327, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
@@ -134,7 +134,7 @@
</div>
<div class="row tabsContainer tabContent hide" tab-name="paymentProofVerification">
<div class="col">
<list-component ref="paymentProofList" section="jackPaymentProofVerificationSection" :endpoint="route('api.transaction.list')" :options="{status: 2, type: 3, issuer_in: [2185, 1970, 1921]}">
<list-component ref="paymentProofList" section="jackPaymentProofVerificationSection" :endpoint="route('api.transaction.list')" :options="{status: 2, type: 3, issuer_in: [1921, 1970, 2185, 2327, 2351, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
@@ -143,7 +143,7 @@
</div>
<div class="row tabsContainer tabContent hide" tab-name="complete">
<div class="col">
<list-component section="jackCompletePaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 3, type: 3, issuer_in: [2185, 1970, 1921]}">
<list-component section="jackCompletePaymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 3, type: 3, issuer_in: [1921, 1970, 2185, 2327, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
@@ -2,14 +2,14 @@
<div class="col">
<div class="row">
<div class="col col-md-5 bg-white padding-25">
<list-component ref="paymentProofList" section="paymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 1, type: 3, issuer_in: [1921, 1970, 2185]}">
<list-component ref="paymentProofList" section="paymentProofSection" :endpoint="route('api.transaction.list')" :options="{status: 1, type: 3, issuer_in: [1921, 1970, 2185, 2327, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
</list-component>
</div>
<div class="col col-md-5 bg-white padding-25">
<list-component ref="paymentProofList" section="paymentProofHistorySection" :endpoint="route('api.transaction.list')" :options="{status_in: [2, 3], type: 3, issuer_in: [1921, 1970, 2185]}">
<list-component ref="paymentProofList" section="paymentProofHistorySection" :endpoint="route('api.transaction.list')" :options="{status_in: [2, 3], type: 3, issuer_in: [1921, 1970, 2185, 2327, 2351]}">
<template slot="list" slot-scope="{data}">
<payment-proof-component :data="data" class="m-b-15 m-r-0"></payment-proof-component>
</template>
+16
View File
@@ -40,6 +40,22 @@
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="row m-b-15 p-b-10 b-b b-grey">
<div class="col">
<small class="all-caps muted fs-10">Transaction Groups</small>
</div>
</div>
<div class="row">
<div class="col">
<list-component key="2" section="transactionGroupsListSection" :options="{'per_page': 5}" :endpoint="route('api.transaction.group.list')">
<template slot="list" slot-scope="{data}">
<transaction-group-component section="transactionGroupsListSection" :data="data"></transaction-group-component>
</template>
</list-component>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -10,10 +10,13 @@
Atvantic Import & Export Snd. Bhd (1309816-P)
@endif
@if(in_array($supplier_deliver_order_transaction->issuer, [1937, 1970]))
BK Gemilang Sdn Bhd (1403513-U)
BK Gemilang Sdn Bhd (1403513-U)
@endif
@if(in_array($supplier_deliver_order_transaction->issuer, [2165, 2185]))
YSN SOLUTION TRADING SDN BHD (1393892-D)
YSN SOLUTION TRADING SDN BHD (1393892-D)
@endif
@if(in_array($supplier_deliver_order_transaction->issuer, [2210]))
RACK SOLUTION INDUSTRIES SDN BHD (954723-W)
@endif
</td>
</tr>
+8 -11
View File
@@ -65,15 +65,8 @@
</div>
</div>
</div>
<div class="col-auto p-r-30">
<div class="col-auto pr-1 pr-md-4">
<div class="row no-margin">
<div class="col-auto m-r-5 hide">
<div class="row align-items-center justify-content-center b-a b-thick h-100" style="border-color: #ffffff3d">
<div class="col p-r-10 p-l-10">
<i class="fa fa-bell fs-12 text-primary-lighter"></i>
</div>
</div>
</div>
<div class="col-auto m-r-20 d-none d-md-inline">
<div class="row align-items-center p-t-5 p-b-5 b-a b-thick d-inline-flex h-100" style="border-color: #ffffff3d">
<div class="col-auto">
@@ -86,6 +79,9 @@
</div>
</div>
</div>
<div class="col-auto m-r-5">
<notification-section-component section="section"></notification-section-component>
</div>
<div class="col-auto m-r-5 d-none d-md-inline">
<a href="{{route('settings')}}">
<div class="row align-items-center justify-content-center b-a b-thick h-100" style="border-color: #ffffff3d">
@@ -98,11 +94,12 @@
<div class="col-12 col-md-auto text-right d-none d-md-inline">
<log-out-form-component></log-out-form-component>
</div>
<div class="col-auto d-md-none pointer" @click="$store.dispatch('toggleSection', {name: 'sideMenu', status: true})">
<i class="fa fa-bars fs-18 text-white"></i>
</div>
</div>
</div>
<div class="col-auto d-md-none pointer" @click="$store.dispatch('toggleSection', {name: 'sideMenu', status: true})">
<i class="fa fa-bars fs-18 text-white"></i>
</div>
</div>
</div>
</div>
+1
View File
@@ -7,6 +7,7 @@ Route::group(['prefix' => 'company', 'as' => 'company.', 'namespace' => 'Compani
Route::get('/list', 'ListCompaniesController@list')->name('list');
Route::post('/create', 'CreateCompanyController@create')->name('create');
Route::put('/update/{id}', 'UpdateCompanyController@update')->name('update');
Route::put('update/{id}/status', 'UpdateCompanyStatusController@update')->name('status.update');
Route::delete('/delete/{id}', 'DeleteCompanyController@destroy')->name('delete');
Route::put('/update/debtor/{id}', 'UpdateCompanyDebtorController@update')->name('delete');
+6
View File
@@ -22,4 +22,10 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::get('/company/{id}/account/balance', 'FetchCompanyAccountBalanceController@fetch')->name('company.account.balance');
Route::get('/bank/{id}/account/balance', 'FetchBankAccountBalanceController@fetch')->name('bank.account.balance');
Route::group(['prefix' => 'groups', 'as' => 'group.'], function () {
Route::get('/list', 'ListGroupsController@list')->name('list');
Route::delete('/{id}/delete', 'DeleteGroupController@delete')->name('delete');
Route::put('/{id}/update', 'UpdateGroupController@update')->name('update');
});
});
+8 -2
View File
@@ -100,7 +100,11 @@ Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsP
Route::get('/fix_bills', function () {
ini_set('max_execution_time', '1000000');
Auth()->login(User::find(1));
$bookings = \App\Models\Booking::whereIn('id', [11257, 11268, 11281, 11287, 11288, 11290, 11292, 11293, 11296, 11298, 11299, 11302, 11303, 11307, 11314, 11324, 11345, 11346])->get();
$bookings = \App\Models\Booking::where('status', 3)->whereHas('transactions', function ($query){
return $query->where('type', 1)->whereHas('transactions', function($query){
return $query->where('type', 3)->where('issuer', 2210);
});
})->get();
foreach ($bookings as $booking){
$booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->delete();
$po = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
@@ -180,4 +184,6 @@ Route::get('purchase/sensitive/', function(Request $request){
}
});
Route::get('/transactions/supplier/{id}/mock_up', 'Transactions\DownloadMockUpWhiteFormPdfController@download')->name('whiteForm.mockUp');
Route::get('/transactions/supplier/{id}/mock_up', 'Transactions\DownloadMockUpWhiteFormPdfController@download')->name('whiteForm.mockUp');
Route::get('/notifications/list', 'Notifications\ListNotificationsController@list')->name('notifications.list');