Merge branch 'development' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into refund-ui-tab

This commit is contained in:
azumiru
2022-03-08 23:27:11 +08:00
57 changed files with 1702 additions and 383 deletions
+4 -4
View File
@@ -53,7 +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_WALLET_COLLECTION_ID="hev2wdjy"
BILLPLZ_API_KEY="c8a55af1-08ee-4ed6-bb18-6e5078300d9e"
BILLPLZ_X_SIGNATURE_KEY="S-hcT93TLVGAv9TYWfpTCcWQ"
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
@@ -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);
}
}
+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;
}
}
@@ -89,7 +89,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
}
$refund = $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id, $transaction->bill_no);
dd($refund);
// dd($refund);
if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.');
@@ -97,7 +97,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
$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);
@@ -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);
}
}
@@ -0,0 +1,100 @@
<?php
namespace App\Classes\Modules\Exports\Services;
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 ExportsNullDebtors implements FromQuery, WithHeadingRow, WithMapping
{
use Exportable;
public function headings(): array
{
return [
'Code',
'CompanyName',
'Desc2',
'AreaCode',
'SalesAgent',
'DebtorType',
'DisplayTerm',
'AgingOn',
'StatementType',
'CurrencyCode',
'RegisterNo',
'Address1',
'Address2',
'Address3',
'Address4',
'PostCode',
'DeliverAddr1',
'DeliverAddr2',
'DeliverAddr3',
'DeliverAddr4',
'DeliverPostCode',
'Attention',
'Phone1',
'Phone2',
'Fax1',
'Fax2',
'ExemptNo',
'ExpiryDate',
'PriceCategory',
];
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
return Company::where('debtor', '=', null);
}
/**
* @param Company $company
*
* @return array
*/
public function map($company): array
{
return [
$company->reference, //Code
$company->name, //CompanyName
'', //Desc2
'', //AreaCode
'', //SalesAgent
'', //DebtorType
'', //DisplayTerm
'', //AgingOn
'', //StatementType
'MYR', //CurrencyCode
$company->reference, //RegisterNo
'', //Address1
'', //Address2
'', //Address3
'', //Address4
'', //PostCode
'', //DeliverAddr1
'', //DeliverAddr2
'', //DeliverAddr3
'', //DeliverAddr4
'', //DeliverPostCode
'', //Attention
'', //Phone1
'', //Phone2
'', //Fax1
'', //Fax2
'', //ExemptNo
'', //ExpiryDate
'', //PriceCategory
];
}
}
@@ -0,0 +1,115 @@
<?php
namespace App\Classes\Modules\Exports\Services;
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\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ExportsPaymentTransactions implements FromQuery, WithHeadingRow, WithMapping
{
use Exportable;
private $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public function headings(): array
{
return [
'DocNo',
'DocDate',
'DebtorCode',
'Ref',
'Note',
'ShipInfo',
'Numbering',
'AccNo',
'DetailDescription',
'FutherDEscription',
'YourPONo',
'YourPODate',
'ProjNo',
'UOM',
'Qty',
'UnitPrice',
'SubTotal'
];
}
/**
* @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);
$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,
$company->debtor,
'',
'',
$booking->marking,
'',
'500-0000',
'PLEASE REFER TO THE ATTACHED APPENDIX REF ' . $booking->marking,
'',
'',
'',
'',
'',
1,
$transaction->amount,
$transaction->amount,
];
}
}
@@ -0,0 +1,44 @@
<?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 = [])
{
$reference = preg_split('(-|\(|\)|\/)', $row['2nd_description']);
$reference = $reference[array_key_last($reference)];
$debtor = $row['code'];
$company = Company::where('reference', $reference)->first();
if ($company) {
$company->debtor = $debtor;
$company->update();
}
return [];
}
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());
}
}
}
@@ -3,31 +3,37 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use DB;
use Carbon\Carbon;
use App\Models\Document;
use Barryvdh\DomPDF\PDF;
use App\Models\Transaction;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Models\SegmentConstant;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Storage;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\SegmentConstants;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
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 App\Classes\Modules\Segments\Services\FetchesConstant;
use Meneses\LaravelLaravelMpdf\Facades\LaravelLaravelMpdf;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionTransferFee;
use App\Classes\Modules\Transactions\Services\CalculatesTransactionServiceCharge;
class CreateSupplierTransactionLogic extends AbstractControllerLogic
{
@@ -64,6 +70,12 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
/** @var GeneratesTransactionBillNumber */
private $generatesTransactionBillNumber;
/** @var CalculatesTransactionServiceCharge */
private $calculatesTransactionServiceCharge;
/** @var CalculatesTransactionTransferFee */
private $calculatesTransactionTransferFee;
/** @var PDF */
private $pdf;
@@ -71,21 +83,27 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
* CreateSupplierTransactionLogic constructor.
* @param FetchesCompany $fetchesCompany
* @param FetchesTransaction $fetchesTransaction
* @param FetchesConstant $fetchesConstant
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesTransaction $createsTransaction
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CalculatesTransactionServiceCharge $calculatesTransactionServiceCharge
* @param CalculatesTransactionTransferFee $calculatesTransactionTransferFee
* @param PDF $pdf
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, PDF $pdf)
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, FetchesConstant $fetchesConstant, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesTransactionServiceCharge $calculatesTransactionServiceCharge, CalculatesTransactionTransferFee $calculatesTransactionTransferFee, PDF $pdf)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->fetchesConstant = $fetchesConstant;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsTransaction = $createsTransaction;
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->calculatesTransactionServiceCharge = $calculatesTransactionServiceCharge;
$this->calculatesTransactionTransferFee = $calculatesTransactionTransferFee;
$this->pdf = $pdf;
}
@@ -97,6 +115,7 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
$rate = $request->input('rate');
$transactions = collect();
$transferFeeTransactions = collect();
foreach($request->input('payments') as $payment){
@@ -107,17 +126,30 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED);
$billNumber = $this->generatesTransactionBillNumber->execute('SPLR-');
// $constant = $this->fetchesConstant->execute(['service_charge' => $supplier->id]);
$constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first();
$serviceCharge = $this->calculatesTransactionServiceCharge->execute($payment->original_amount, $rate, $constant ? $constant->detail->service_charge->amount : 0);
$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);
$rate, 0, $supplier->id == 2 ? 0 : $serviceCharge, null, ApprovalStatus::PENDING_VERIFICATION);
$transactions[] = $this->createsTransaction->execute($payment, $object);
$transactions[] = $billTransaction = $this->createsTransaction->execute($payment->booking, $object);
$transferFeeNumber = $this->generatesTransactionBillNumber->execute('TRFR-');
$trasferFee = $this->calculatesTransactionTransferFee->execute($payment->original_amount);
$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, $trasferFee, null, ApprovalStatus::PENDING_VERIFICATION);
$transferFeeTransactions[] = $this->createsTransaction->execute($billTransaction, $object);
}
if(!count($transactions)) return $this->response([]);
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $transactions, 'supplier' => $supplier]);
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $transactions, 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier]);
$path = Str::studly($supplier->name).'_'.Carbon::now()->format('Y_m_d_h_s_i').'.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)]);
}
}
@@ -0,0 +1,85 @@
<?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'));
$company = $this->fetchesCompany->execute(['id' => $transaction->booking->company_id]);
$reference = 'Refund for booking reference '.$transaction->booking->marking;
if ($transaction->status == ApprovalStatus::APPROVED) {
// add to credit wallet
$this->creditWalletProcessor->execute($company, $transaction->type, $transaction->amount, $reference);
}
return $this->response([]);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
class CalculatesTransactionServiceCharge
{
/**
* @param float $amount
* @param float $rate
* @param float $service_charge
* @param float $transfer_fee
* @return float
*/
public function execute(float $amount, float $rate, ?float $service_charge = 0.75, ?float $transfer_fee = 0.00) {
return (($amount + $transfer_fee) * (1/$rate)) * $service_charge / 100;
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Classes\Modules\Transactions\Services;
class CalculatesTransactionTransferFee
{
/**
* @param float $amount
* @param float $transfer_fee
* @return float
*/
public function execute(float $amount, ?float $transfer_fee = 0.002) {
return $amount * $transfer_fee/100;
}
}
@@ -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'),
];
}
}
@@ -2,25 +2,19 @@
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 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\GeneratesWalletCode;
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 App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Wallets\Services\GeneratesWalletCode;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
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
{
@@ -53,6 +47,9 @@ class CreditWalletLogic extends AbstractControllerLogic
/** @var UpdatesWallet */
private $updatesWallet;
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/**
* CreateWalletLogic constructor.
* @param FetchesCompany $fetchesCompany
@@ -61,6 +58,7 @@ class CreditWalletLogic extends AbstractControllerLogic
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CreatesTransaction $createsTransaction
* @param UpdatesWallet $updatesWallet
* @param CreditWalletProcessor $creditWalletProcessor
*/
public function __construct(
FetchesCompany $fetchesCompany,
@@ -68,7 +66,8 @@ class CreditWalletLogic extends AbstractControllerLogic
CreatesWallet $createsWallet,
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
CreatesTransaction $createsTransaction,
UpdatesWallet $updatesWallet
UpdatesWallet $updatesWallet,
CreditWalletProcessor $creditWalletProcessor
)
{
$this->fetchesCompany = $fetchesCompany;
@@ -77,6 +76,7 @@ class CreditWalletLogic extends AbstractControllerLogic
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->createsTransaction = $createsTransaction;
$this->updatesWallet = $updatesWallet;
$this->creditWalletProcessor = $creditWalletProcessor;
}
/**
@@ -94,23 +94,7 @@ class CreditWalletLogic extends AbstractControllerLogic
$type = $request->input('transaction_type');
if (!$company->wallets()->first()) {
$object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute());
$this->createsWallet->execute($object, $company);
}
$wallet = $company->wallets()->first();
$billNumber = $this->generatesTransactionBillNumber->execute($type === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-');
$transaction_object = new TransactionObject($billNumber, $type === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
$updateWalletAmount = $type === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount);
$walletObject = new WalletObject($wallet->owner->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
$wallet = $this->updatesWallet->execute($wallet, $walletObject);
$wallet = $this->creditWalletProcessor->execute($company, $type, $amount, $reference);
return $this->resourceResponse(new WalletResource($wallet));
}
@@ -0,0 +1,89 @@
<?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());
$wallet = $this->createsWallet->execute($object, $company);
}
$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;
}
}
@@ -10,4 +10,6 @@ final class BusinessType {
public const CURRENCY_VENDOR = 3;
public const TRANSFER_AGENT = 4;
}
@@ -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';
}
@@ -27,4 +27,6 @@ final class TransactionType {
public const DEBIT_NOTE = 11;
public const WITHDRAW = 10;
public const TRANSFER_FEE = 11;
}
@@ -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,9 @@ 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\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -12,7 +15,6 @@ use Maatwebsite\Excel\Excel;
class ExportCustomersToExcelController
{
public function export(ExportsCustomers $exportsCustomers, Request $request){
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
@@ -24,4 +26,17 @@ class ExportCustomersToExcelController
$request->headers->set('Authorization', 'Bearer '.$token);
return $exportsTransactions->download('transactions.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
}
public function nullDebtor(ExportsNullDebtors $exportsNullDebtors, Request $request){
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
return $exportsNullDebtors->download('nullDebtor.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
}
public function paymentTransactions(Request $request){
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
$exportsTransactions = new ExportsPaymentTransactions($request);
return $exportsTransactions->download('payment-transactions.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
}
}
@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Imports;
use App\Classes\Modules\Imports\Services\ImportsDebtor;
use App\Classes\General\ExcelHandel;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
class ImportUpdateDebtorController
{
public function import(Request $request) {
$token = Auth::fromUser(User::find(1));
$request->headers->set('Authorization', 'Bearer '.$token);
$excel_file = $request->input('excel_file');
$excel_file = ExcelHandel::insertExcel('debtor', $excel_file);
return $import = Excel::import(new ImportsDebtor(), $excel_file[0]['file_info']['original']['file']);
}
}
@@ -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,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,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);
}
}
+1
View File
@@ -57,6 +57,7 @@ class CompanyResource extends JsonResource
'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first())
],
'segments' => SegmentResource::collection($this->segments),
'service_charges' => SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $this->id)->first(),
'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();
+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');
}
}
+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)
{
+16 -8
View File
@@ -30,14 +30,6 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
return $this->morphTo();
}
/**
* @return MorphMany
*/
public function booking(): BelongsTo
{
return $this->BelongsTo(Booking::class, 'owner_id', 'id');
}
/**
* @return MorphMany
*/
@@ -46,6 +38,22 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
return $this->MorphMany(Transaction::class, 'owner');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
*/
public function creditNoteTransaction()
{
return $this->MorphOne(Transaction::class, 'owner')->where('type', TransactionType::CREDIT_NOTE);
}
/**
* @return BelongsTo
*/
public function booking(): BelongsTo
{
return $this->BelongsTo(Booking::class, 'owner_id', 'id');
}
/**
* @return BelongsTo
*/
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDebtorToCompaniesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('companies', function (Blueprint $table) {
$table->string('debtor')->nullable()->after('reference');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('companies', function (Blueprint $table) {
});
}
}
@@ -11,7 +11,7 @@
<div class="row h-100">
<div class="col fs-9 d-flex align-items-center flex-column" style="padding-top: 7px; padding-bottom: 4px;">
<label class="all-caps w-100 m-b-0" style="font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 500;">Document Type</label>
<span class="w-100 fs-14">{{parameters.type}}</span>
<span class="w-100 fs-14">{{parameters.type.replaceAll('_', ' ')}}</span>
</div>
<div class="col-auto b-l b-grey">
<div class="row h-100 align-items-center">
@@ -27,10 +27,10 @@
<div class="row text-left no-margin bg-white">
<div class="col no-padding">
<div class="row no-margin" v-for="document in documents" :key="document">
<div class="col b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10 b-a" @click="updateDocumentType(document)">
<div class="col b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10 b-a" :class="[{'bg-primary-light': document === parameters.type}, {'text-white': document === parameters.type}, {'b-primary': document === parameters.type}, {'hover-primary': document !== parameters.type}, {'pointer': document !== parameters.type}]" @click="updateDocumentType(document)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="font-heading fs-10">{{document}}</div>
<div class="font-heading fs-10">{{document.replaceAll('_', ' ')}}</div>
</div>
</div>
</div>
@@ -40,11 +40,15 @@
<div class="font-heading text-success bold">{{item.owner.amount}} {{item.owner.fixed_currency.short_code}}</div>
</div>
<div class="col">
<document-file-viewer-component :file="item.files[0]">
<template slot="button">
<button class="btn btn-success">Download</button>
</template>
</document-file-viewer-component>
<div class="row">
<div class="col-auto">
<document-file-viewer-component :file="item.files[0]">
<template slot="button">
<button class="btn btn-success w-100">Download</button>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
</div>
</div>
@@ -176,9 +176,9 @@
</div>
</div>
</div>
<div class="row m-t-10 hide">
<div class="row m-t-10">
<div class="col">
<button class="btn btn-xs all-caps b-rad-none btn-success btn-block requestModal" data-type="transferSummary">Request Refund</button>
<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">
<refund-confirmation-component :data="data" :section="section"></refund-confirmation-component>
</modal-component>
@@ -294,7 +294,7 @@
expandPaymentDetails: false,
expandRefund: false,
refundMethod: {
name: 'Fully Refund',
name: 'Partially Refund',
status: false
},
amount: (Math.round(1000 * 100) / 100).toFixed(2),
@@ -10,7 +10,7 @@
</div>
</div>
</div>
<div class="row p-b-20 b-b b-dashed b-grey m-b-20">
<div class="row">
<div class="col">
<div class="row">
<div class="col">
@@ -23,61 +23,21 @@
<div class="row m-b-10">
<div class="col">
<div class="font-heading all-caps fs-10 m-b-5">Refund Type: </div>
<!-- <div class="btn btn-xs btn-complete no-border btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="refundMethod.status = !refundMethod.status">
<div class="row">
<div class="col p-t-10 p-b-10">
{{refundMethod.name}}
</div>
<div class="col-auto bg-complete-light">
<div class="row h-100 align-items-center">
<div class="col">
<i class="fa" :class="[{'fa-angle-down': !refundMethod.status}, {'fa-angle-up': refundMethod.status}]"></i>
</div>
</div>
</div>
</div>
</div> -->
<!-- <div class="relative w-100">
<div class="absolute w-100 b-l b-b b-r b-complete" :class="[{'hide': !refundMethod.status}]" style="top: 100%; right: 0; z-index: 1;">
<div class="row text-left no-margin bg-white">
<div class="col no-padding">
<div class="row no-margin" :class="[{'bg-complete-light': refundMethod.name === 'Fully Refund'}, {'text-white': refundMethod.name === 'Fully Refund'}, {'hover-complete': refundMethod.name !== 'Fully Refund'}]" @click="updateRefundType({name: 'Fully Refund'})">
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="font-heading fs-10">Fully Refund</div>
</div>
</div>
</div>
</div>
<div class="row no-margin" :class="[{'bg-complete-light': refundMethod.name === 'Partially Refund'}, {'text-white': refundMethod.name === 'Partially Refund'}, {'hover-complete': refundMethod.name !== 'Partially Refund'}]" @click="updateRefundType({name: 'Partially Refund'})">
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="font-heading fs-10">Partially Refund</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> -->
<div class="row">
<div class="col-auto b-a m-l-15 padding-5 p-l-10 p-r-10 rounded b-grey pointer" :class="[{'b-complete': refundMethod.name === 'Fully Refund'}]" @click="updateRefundType({name: 'Fully Refund'})">
Fully Refund
</div>
<div class="col-auto b-a m-l-10 padding-5 p-l-10 p-r-10 rounded b-grey pointer" :class="[{'b-complete': refundMethod.name === 'Partially Refund'}]" @click="updateRefundType({name: 'Partially Refund'})">
<div class="row p-l-15">
<div class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey" :class="[{'bg-complete': refundMethod.name === 'Partially Refund'}, {'text-white': refundMethod.name === 'Partially Refund'}]" @click="updateRefundType({name: 'Partially Refund'})">
Partially Refund
</div>
<div class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey" :class="[{'bg-complete': refundMethod.name === 'Fully Refund'}, {'text-white': refundMethod.name === 'Fully Refund'}]" @click="updateRefundType({name: 'Fully Refund'})">
Fully Refund
</div>
</div>
</div>
</div>
<div class="row m-r-0 m-b-10" v-if="refundMethod.name == 'Partially Refund'">
<div class="row m-r-0 m-b-10">
<div class="col p-r-0">
<validation-wrapper-component :validator="$v.parameters.refundAmount">
<label>Amount</label>
<input class="form-control disabled" name="amount" v-model="data.booking.amount">
<input class="form-control" name="amount" v-model="refundAmount" :disabled="refundMethod.name == 'Fully Refund'">
</validation-wrapper-component>
</div>
<div class="col-auto b-r b-t b-b b-grey">
@@ -90,61 +50,6 @@
</div>
</div>
</div>
<div class="row" v-show="!createBank">
<div class="col-7 p-r-0">
<div class="row">
<div class="col">
<div class="form-group no-margin form-group-default">
<label>Account No.</label>
<input type="text" class="form-control" v-model="account_no" @keyup="parameters.bankAccount = {}" @focus="dropdownStatus = true">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="relative w-100">
<div class="absolute w-100 b-l b-b b-r b-grey" :class="[{'hide': !dropdownStatus}]" style="top: 100%; right: 0; z-index: 1;">
<div class="row text-left no-margin bg-white">
<div class="col no-padding">
<div class="row no-margin" v-for="bank in data.booking.company.personal_banks.accounts" v-bind:key="bank.id" >
<!-- <div class="col b-b b-grey p-t-10 p-b-10 pointer p-t-10 p-b-10" :class="[{'bg-master-lightest': parameters.bankAccount.id === bank.id}, {'text-master': parameters.bankAccount.id === bank.id}, {'hover-primary': parameters.bankAccount.id !== bank.id}, {'pointer': parameters.bankAccount.id !== bank.id}]" @click="selectBank(bank)"> -->
<div class="col b-b b-grey p-t-10 p-b-10 pointer p-t-10 p-b-10" @click="selectBank(bank)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="row">
<div class="col">
<div class="font-heading bold lh-15 fs-13">{{bank.reference ? bank.reference + ' - ':''}}{{bank.holder_name}}</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="font-heading all-caps fs-13 muted"><b class="m-r-5 text-primary">{{bank.account_no}}</b> {{bank.bank_name}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-auto p-l-0" v-show="!createBank && account_no && !Object.keys(parameters.bankAccount).length">
<button class="btn btn-sm h-100 btn-primary b-rad-none all-caps" @click="createBank = !createBank; dropdownStatus = false">
<i class="fa fa-plus m-r-5"></i>
Create New
</button>
</div>
</div>
<div class="row" v-show="createBank">
<div class="col">
<!-- <bank-account-form-component section="customerProfileSection" :company_id="data.booking.company.id" :data="{account_no: account_no, company_id: data.booking.company.id, country_id: 1, account_type: 1}" :type='1'></bank-account-form-component> -->
<bank-account-form-component section="customerProfileSection" :company_id="data.booking.company.id" :data="{account_no: account_no, company_id: data.booking.company.id, country_id: 1, account_type: 1}" :type='2'></bank-account-form-component>
</div>
</div>
</div>
</div>
</div>
@@ -153,95 +58,11 @@
</div>
</div>
</div>
<div class="row m-b-20" v-show="createBank">
<div class="col">
<div class="row align-items-end no-margin">
<div class="col">
<div class="row align-items-end bg-master-lightest p-t-10 p-b-10">
<div class="col">
<div class="font-heading fs-10 all-caps">Amount you are Transferring</div>
</div>
<div class="col-1 no-padding text-center">
<!-- <div class="font-heading fs-10 bold">{{this.parameters.type === 0 ? 'MYR': parameters.serviceType.selectedCurrency.short_code}}</div> -->
<div class="font-heading fs-10 bold">short_code</div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading fs-10 bold">{{(Math.round((parseFloat(this.parameters.amount.replace(",", ""))+ Number.EPSILON) * 100) / 100).toFixed(2)}}</div> -->
<div class="font-heading fs-10 bold">amount</div>
</div>
</div>
<div class="row align-items-end p-t-10 p-b-10">
<div class="col">
<div class="font-heading fs-10 all-caps text-primary">Exchange Rate</div>
</div>
<div class="col-1 no-padding text-center">
<div class="font-heading fs-10"></div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading fs-10 text-primary bold">{{(Math.round((this.parameters.calculation.rate + Number.EPSILON) * 100000) / 100000).toFixed(5)}}</div> -->
<div class="font-heading fs-10 text-primary bold">rate</div>
</div>
</div>
<div class="row align-items-end bg-master-lightest p-t-10 p-b-10">
<div class="col">
<div class="font-heading fs-10 all-caps">Money Transfer Fee</div>
</div>
<div class="col-1 no-padding text-center">
<div class="font-heading fs-10">MYR</div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading fs-10">{{(Math.round((this.parameters.calculation.service_charge + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> -->
<div class="font-heading fs-10">amount</div>
</div>
</div>
<div class="row align-items-end p-t-10 p-b-10">
<div class="col text-right">
<div class="font-heading fs-10 all-caps">Sub-Total</div>
</div>
<div class="col-1 no-padding text-center">
<div class="font-heading fs-10">MYR</div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading fs-10">{{(Math.round((this.parameters.calculation.sub_total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> -->
<div class="font-heading fs-10">Sub-Total</div>
</div>
</div>
<div class="row align-items-end bg-master-lightest p-t-10 p-b-10">
<div class="col text-right">
<div class="font-heading fs-10 all-caps">Tax</div>
</div>
<div class="col-1 no-padding text-center">
<!-- <div class="font-heading fs-10">{{Math.round((this.parameters.calculation.tax + Number.EPSILON) * 100) / 100}}%</div> -->
<div class="font-heading fs-10">some%</div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading fs-10">{{(Math.round((this.parameters.calculation.tax_total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> -->
<div class="font-heading fs-10">some tax</div>
</div>
</div>
<div class="row align-items-end p-t-10 p-b-10">
<div class="col text-right">
<div class="font-heading all-caps bold">Amount you are Paying</div>
</div>
<div class="col-1 no-padding text-center">
<div class="font-heading bold">MYR</div>
</div>
<div class="col-3 text-right">
<!-- <div class="font-heading text-success bold">{{(Math.round((this.parameters.calculation.total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> -->
<div class="font-heading text-success bold">payming amount</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <confirm-booking-component :section="section" :data="data" v-if="parameters.bankAccount"></confirm-booking-component> -->
<div class="row">
<div class="col-auto">
<button class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12" data-dismiss="modal">Cancel</button>
</div>
<div class="col text-right">
<!-- <button class="btn btn-lg btn-success b-rad-none all-caps fs-12" v-if="Object.keys(data.bankAccount).length" @click="submitForm()">Confirm & Proceed</button> -->
<button class="btn btn-lg btn-success b-rad-none all-caps fs-12" @click="submitForm()">Confirm & Proceed</button>
</div>
</div>
@@ -251,86 +72,46 @@
<script>
import FormHandler from '../../../general/mixins/formHandler';
// import ConfirmBookingComponent from "../forms/confirmBookingComponent";
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
import { required } from "vuelidate/lib/validators";
import { required, maxValue } from "vuelidate/lib/validators";
export default {
// components: {ConfirmBookingComponent},
data(){
return {
createBank: false,
recipientBanks: [],
dropdownStatus: false,
account_no: '',
parameters: {
bankAccount: '',
refundAmount: this.data.booking.amount,
bank_id: '',
},
expandRefund: false,
refundAmount: this.data.booking.amount,
refundMethod: {
name: 'Fully Refund',
name: 'Partially Refund',
status: false
},
refundMaxValue: this.data.booking.amount
}
},
validations: {
parameters: {
bankAccount: { required },
refundAmount: { required },
validations() {
return {
parameters: {
refundAmount: {
// required,
// maxValue: maxValue(this.refundMaxValue)
},
}
}
},
computed: {
formDisabled(){
return !!Object.keys(this.parameters.bankAccount).length;
}
},
created(){
this.recipientBanks = this.data.recipientBanks;
},
methods: {
AccountNumber(bank){
return bank.account_no.startsWith(this.account_no)
},
updateBank(bank){
this.selectBank(bank);
this.recipientBanks.push(bank);
this.parameters.bankAccount = bank;
},
selectBank(bank){
console.log(bank);
this.account_no = bank.account_no;
this.createBank = true;
this.parameters.bankAccount = bank;
this.dropdownStatus = false;
},
clearAccount(){
this.createBank = false;
this.account_no = '';
this.parameters.bankAccount = {};
},
submitForm(){
// this.parameters = {
// company_id: this.data.company.id,
// type: this.data.type,
// fix_amount: this.data.amount,
// service_id: this.data.serviceType.id,
// transferable_bank_id: this.data.bankAccount.id,
// convertible_currency_id: this.data.serviceType.selectedCurrency.id,
// };
this.submit(route('api.booking.create'), 'post', this.section, true, true)
this.submit(this.route('api.booking.refund.create', this.data.booking.id, this.data.id), 'post', this.section, true, true)
},
updateRefundType(refund){
this.refundMethod = {
name: refund.name,
status: !this.refundMethod.status
}
this.refundAmount = this.refundMaxValue;
},
successHandler(response){
window.location.href = this.route('booking.details', response.payload.data.marking)
}
// successHandler(response){
// window.location.href = this.route('booking.details', response.payload.data.marking)
// }
},
mixins: [FormHandler, ModalFormHandler]
}
@@ -34,15 +34,33 @@
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading all-caps fs-8 muted">Service Charge</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="font-heading all-caps fs-10">0.00</div>
</div>
</div>
</div>
<div class="col-auto">
<div class="row">
<div class="col">
<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>
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="deleteSupplier">
<i class="fa fa-times"></i>
</button>
<button class="btn btn-xs btn-complete p-l-10 p-r-10 b-rad-none" @click="expanded = !expanded">
<i class="fa" :class="[{'fa-angle-up': expanded}, {'fa-angle-down': !expanded}]"></i>
</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="editServiceCharge">
<supplier-service-charge-form-component :details="item" :defaultCharge="null" section="suppliersServiceChargeSection"></supplier-service-charge-form-component>
</modal-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteSupplier">
<delete-supplier-form-component :data="item" section="suppliersSection" class="text-center"></delete-supplier-form-component>
</modal-component>
@@ -0,0 +1,83 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 50px; top: 0;" key="1" color="success" v-show="$store.getters.isLoading(section)"></loading-component>
<div class="row" v-show="!$store.getters.isLoading(section)">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h6 class="all-caps m-b-5 bold no-margiPsn">Edit Service Charge</h6>
</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 :validator="$v.parameters.amount">
<label>Service Charge %</label>
<input type="text" class="form-control" v-model="parameters.detail.service_charge.amount" 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()">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
import { required, requiredIf } from "vuelidate/lib/validators";
export default {
props: {
details: {
type: Object,
required: true
},
defaultCharge: {
type: Number,
required: false
}
},
data(){
return {
parameters: {
name: 'Service Charge',
reference: 'SERVICE_CHARGE',
detail: {
service_charge: {
id: this.details.id,
type: "percentage",
amount: this.defaultCharge,
},
},
segment_id: 1
},
}
},
validations: {
parameters: {
amount: {
required: true
}
}
},
methods: {
submitForm(){
this.submit(this.defaultCharge ? this.route('api.segment_constant.update', this.service_charges.id) : this.route('api.segment_constant.create'), 'post', this.section, true, true);
},
},
mixins: [ModalFormHandler]
}
</script>
@@ -16,20 +16,49 @@
<label class="all-caps">Bookings Frequency</label>
<input type="text" class="form-control" v-model.lazy="parameters.frequency">
</validation-wrapper-component>
<div class="row">
<div class="col p-r-0">
<validation-wrapper-component :validator="$v.parameters.frequency">
<label class="all-caps">Date From</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.frequencyDateFrom"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col p-l-0">
<validation-wrapper-component :validator="$v.parameters.frequency">
<label class="all-caps">Date To</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.frequencyDateTo"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
</div>
<div class="col-12 col-md mb-2 mb-md-0">
<validation-wrapper-component :validator="$v.parameters.monetary">
<label class="all-caps">Total Payments</label>
<input type="text" class="form-control" v-model.lazy="parameters.monetary">
</validation-wrapper-component>
<div class="row">
<div class="col p-r-0">
<validation-wrapper-component :validator="$v.parameters.frequency">
<label class="all-caps">Date From</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.monetaryDateFrom"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col p-l-0">
<validation-wrapper-component :validator="$v.parameters.frequency">
<label class="all-caps">Date To</label>
<date-picker-component :parameters="parameters" v-model.lazy="parameters.monetaryDateTo"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
</div>
<div class="col-12 col-md-auto d-flex justify-content-center align-items-center">
<button type="button" class="btn btn-lg btn-primary fs-11 w-100" @click="submitSearch()">Search</button>
<div class="col-12 col-md-auto d-flex align-items-center flex-md-column justify-content-center">
<button type="button" class="btn btn-lg btn-primary fs-11 w-100 d-block m-r-5 mr-md-0 mb-md-1 mb-0" @click="submitSearch()">Search</button>
<button type="button" class="btn btn-lg btn-secondary fs-11 w-100 d-block m-l-5 ml-md-0 mt-md-1 0t-0" @click="reserSearch()">Reset</button>
</div>
</div>
</div>
</div>
<div class="row no-margin" v-show="search">
<div class="row no-margin" v-show="search" :key="serachSectionKey">
<div class="col bg-white padding-25">
<list-component :section="section" :endpoint="route('api.company.list')" :options="{'with_total_payments': true, 'recency': recency, 'frequency': frequency, 'monetary': monetary, 'business_type': 2, with_bookings:true, order_by:{ column:'total_payments', DESC:true}}">
<template slot="list" slot-scope="{data}">
@@ -53,16 +82,32 @@ export default {
section: 'customerSectionComponent',
isLoading: false,
search: false,
serachSectionKey: 2,
parameters: {
recency: '2022-02-15',
frequency: 0,
frequencyDateFrom: '2021-01-01',
frequencyDateTo: '2022-01-01',
monetary : 0,
monetaryDateFrom: '2021-01-01',
monetaryDateTo: '2022-02-15',
}
}
},
methods: {
submitSearch(){
this.search = true;
this.serachSectionKey ++;
},
reserSearch() {
this.parameters.recency = '2022-02-15';
this.parameters.frequency = 0;
this.parameters.frequencyDateFrom ='2021-01-01';
this.parameters.frequencyDateTo = '2022-01-01';
this.parameters.monetary = 0;
this.parameters.monetaryDateFrom = '2021-01-01';
this.parameters.monetaryDateTo = '2022-02-15';
this.serachSectionKey ++;
}
},
validations: {
@@ -1,9 +1,10 @@
<template>
<div v-if="validator.$error" class="text-danger fs-10">
<small class="bold" v-for="(object, param) in validator.$params" v-if="!validator[param]">
{{errorMessages[param]}}
<span v-if="object.type === 'minLength'">{{object.min}} characters</span>
<span v-if="object.type === 'sameAs'">{{object.eq}} field</span>
<small class="bold" v-for="(object, param) in validator.$params">
<span class="btn-block" v-if="object.type === 'required'">{{errorMessages[param]}}</span>
<span class="btn-block" v-if="object.type === 'minLength'">{{errorMessages[param]}} {{object.min}} characters</span>
<span class="btn-block" v-if="object.type === 'sameAs'">{{errorMessages[param]}} {{object.eq}} field</span>
<span class="btn-block" v-if="object.type === 'maxValue'">{{errorMessages[param]}} {{object.max}}</span>
</small>
</div>
</template>
@@ -21,7 +22,8 @@
required: 'this field is required',
email: 'enter a valid email address',
minLength: 'this field must have at least',
sameAs: 'this field must match the'
sameAs: 'this field must match the',
maxValue: 'this value must not exceeds'
},
}
},
@@ -1,29 +1,33 @@
@extends('layouts.base_pdf')
@section('inner_content')
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 15px;
}
</style>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td {
padding: 15px;
}
</style>
<br>
<htmlpageheader name="page-header">
<br>
<htmlpageheader name="page-header">
<br>
<table style="margin-bottom: 25px; border: none;">
<tbody>
<table style="margin-bottom: 25px; border: none;">
<tbody>
<tr>
<td>{{$supplier->name}}</td>
<td>{{\Carbon\Carbon::now('Asia/Singapore')->format('d-m-Y h:s')}}</td>
</tr>
</tbody>
</table>
</htmlpageheader>
<br>
<table style="width:100%">
<tbody>
</tbody>
</table>
</htmlpageheader>
<br>
<table style="width:100%">
<tbody>
<tr>
<td>Reference</td>
<td>Marking</td>
@@ -41,21 +45,59 @@
<br>Branch: {{$transaction->owner()->first()->booking->bank->bank_branch}}<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}</td>
</tr>
@endforeach
</tbody>
</table>
<table style="margin-bottom: 25px; border: none;">
<tbody>
</tbody>
</table>
<table style="margin-bottom: 25px; border: none;">
<tbody>
<tr>
<td width="70%" style="text-align: right;">Sub total booking amount: </td>
@php
$sub_total_booking_amount = number_format((float)$transactions->sum('original_amount'), 2, '.', '');
@endphp
<td>RMB {{$sub_total_booking_amount}}</td>
</tr>
<tr>
<td width="70%" style="text-align: right;">Transfer fee (0.002%): </td>
@php
$transfer_fee = number_format((float)$transferFeeTransactions->sum('service_charge'), 2, '.', '');
@endphp
<td>RMB {{$transfer_fee}}</td>
</tr>
<tr>
<td width="70%" style="text-align: right;">Total booking amount: </td>
@php
$total_booking_amount = number_format((float) ($transactions->sum('original_amount') + $transfer_fee), 2, '.', '');
@endphp
<td>RMB {{$total_booking_amount}}</td>
</tr>
<tr>
<td width="70%" style="text-align: right;">Sub total amount: </td>
@php
$sub_total_amount = number_format((float)$transactions->sum('amount') + ($transfer_fee * 1/$transactions[0]->currency_rate), 2, '.', '');
@endphp
<td>MYR {{$sub_total_amount}}</td>
</tr>
<tr>
<td width="70%" style="text-align: right;">Service charge ({{ $supplier->id == 2 ? '0.00' : '0.75%' }}): </td>
@php
$service_charge = number_format((float)$sub_total_amount * 0.75 / 100, 2, '.', '');
@endphp
<td>MYR {{$service_charge}}</td>
</tr>
<tr>
<td width="70%" style="text-align: right;">Total amount: </td>
<td>MYR {{number_format((float)$transactions->sum('amount'), 2, '.', '')}}</td>
@php
$total_amount = number_format((float)$sub_total_amount + $service_charge, 2, '.', '');
@endphp
<td>MYR {{$total_amount}}</td>
</tr>
</tbody>
</table>
<htmlpagefooter name="page-footer">
<table width="100%" style="border: none;">
<tr>
<td style="text-align: right; ">Page {PAGENO} of {nbpg}</td>
</tr>
</tbody>
</table>
<htmlpagefooter name="page-footer">
<table width="100%" style="border: none;">
<tr>
<td style="text-align: right; ">Page {PAGENO} of {nbpg}</td>
</tr>
</table>
</htmlpagefooter>
</htmlpagefooter>
@endsection
+1 -1
View File
@@ -3,7 +3,7 @@
<div class="container-fluid">
<div class="row no-margin">
<div class="col p-l-0 p-t-20 p-b-20 sm-text-center">
<small class="small no-margin pull-left sm-pull-reset all-caps fs-10 muted" style=" letter-spacing: 1px; ">Copyright © 2021 CIEF Exchange. All rights reserved.</small>
<small class="small no-margin pull-left sm-pull-reset all-caps fs-10 muted" style=" letter-spacing: 1px; ">Copyright © {{ date('Y') }} CIEF Exchange. All rights reserved.</small>
</div>
</div>
</div>
+2
View File
@@ -35,6 +35,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
require __DIR__ . '/segment.php';
require __DIR__ . '/segment_constant.php';
require __DIR__ . '/currency.php';
require __DIR__ . '/bank.php';
+2
View File
@@ -9,6 +9,8 @@ Route::group(['prefix' => 'company', 'as' => 'company.', 'namespace' => 'Compani
Route::put('/update/{id}', 'UpdateCompanyController@update')->name('update');
Route::delete('/delete/{id}', 'DeleteCompanyController@destroy')->name('delete');
Route::put('/update/debtor/{id}', 'UpdateCompanyDebtorController@update')->name('delete');
Route::post('/team/create', 'AddNewMemberController@create')->name('team.create');
Route::group(['prefix' => '{id}/segment', 'as' => 'segment.'], function () {
+9 -8
View File
@@ -2,19 +2,20 @@
use Illuminate\Support\Facades\Route;
Route::group(['namespace' => 'StandardSegmentConstants'], function () {
Route::group(['middleware' => 'valid.token'], function () {
Route::group(['prefix' => 'standard-segment-constant'], function () {
Route::get('/list', 'ListStandardSegmentConstantsController@list')->name('standard_segment.update');
Route::put('/update/{id}', 'UpdateStandardSegmentConstantController@update')->name('standard_segment_constant.update');
});
});
});
// Route::group(['namespace' => 'StandardSegmentConstants'], function () {
// Route::group(['middleware' => 'valid.token'], function () {
// Route::group(['prefix' => 'standard-segment-constant'], function () {
// Route::get('/list', 'ListStandardSegmentConstantsController@list')->name('standard_segment.update');
// Route::put('/update/{id}', 'UpdateStandardSegmentConstantController@update')->name('standard_segment_constant.update');
// });
// });
// });
Route::group(['namespace' => 'SegmentConstants'], function () {
Route::group(['middleware' => 'valid.token'], function () {
Route::group(['prefix' => 'segment-constant'], function () {
Route::get('/{id}/show', 'FetchSegmentConstantController@fetch')->name('segment_constant.show');
Route::post('/create', 'CreateSegmentConstantController@create')->name('segment_constant.create');
Route::put('/update/{id}', 'UpdateSegmentConstantController@update')->name('segment_constant.update');
});
+4
View File
@@ -11,6 +11,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification');
route::post('{id}/bill/pay', 'CreatePaymentProofDocumentController@pay')->name('bill.pay');
Route::put('/{id}/bill/{status}', 'UpdatePaymentTransactionStatusController@update')->where('status', 'pending|complete')->name('bill.status');
Route::put('/{id}/refund/status/update', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update');
route::delete('{id}/bill/delete', 'DeletePaymentProofDocumentController@delete')->name('bill.delete');
@@ -18,4 +19,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::get('wallet/list', 'ListWalletTransactionsController@list')->name('wallet.list');
Route::get('/company/{id}/account/balance', 'FetchCompanyAccountBalanceController@fetch')->name('company.account.balance');
Route::get('/bank/{id}/account/balance', 'FetchBankAccountBalanceController@fetch')->name('bank.account.balance');
});
+4
View File
@@ -142,6 +142,10 @@ Route::get('billplz/bills/{bill_no}', function($bill_no){
Route::get('/export/customers/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@export');
Route::get('/export/transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@transactions');
Route::get('/export/null-debtor/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@nullDebtor');
Route::get('/export/payment-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@paymentTransactions');
Route::get('/import/update-debtor/f614e339d7058904a831aad742e24d55', 'Imports\ImportUpdateDebtorController@import');
Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) {
return $exportsProducts->download('products.csv', Excel::CSV, ['Content-Type' => 'text/csv']);
-2
View File
@@ -1,2 +0,0 @@
*
!.gitignore