mirror of
https://gitlab.com/uldvstar/exchange-2.0.git
synced 2026-08-19 04:24:16 +00:00
Merge branch 'merge_existing_booking' into 'master'
Merge existing booking See merge request CIEFWorldwideSdnBhd/exchange-2.0!38
This commit is contained in:
+12
-1
@@ -13,4 +13,15 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
/storage/file
|
||||
composer.lock
|
||||
yarn.lock
|
||||
yarn.lock
|
||||
.DS_Store
|
||||
public/.DS_Store
|
||||
public/images/.DS_Store
|
||||
gox.iml
|
||||
rebuild_docker.sh
|
||||
docker/*
|
||||
db/*
|
||||
docker-compose.yml
|
||||
package-lock.json
|
||||
public/*
|
||||
/public/*
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
abstract class AbstractDeleteMultipleRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @param array $ids
|
||||
* @return mixed
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function handler(Builder $query, array $ids){
|
||||
try{
|
||||
|
||||
$record_deleted = $query->whereIn('id',$ids)->delete();
|
||||
|
||||
return ($record_deleted == count($ids)) ? true : false;
|
||||
|
||||
} catch (QueryException|\Exception $exception){
|
||||
throw new MalformedRequestException('Unable to delete the record due to unexpected error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
abstract class AbstractUpdateMultipleRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @param array $ids
|
||||
* @param array $values
|
||||
* @return mixed
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function handler(Builder $query, array $ids, array $values){
|
||||
try{
|
||||
|
||||
$record_updated = $query->whereIn('id',$ids)->update($values);
|
||||
|
||||
return ($record_updated == count($ids)) ? true : false;
|
||||
|
||||
} catch (QueryException|\Exception $exception){
|
||||
throw new MalformedRequestException('Unable to update the record due to unexpected error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ConvertibleCurrencyId implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('convertible_currency_id', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class FixedCurrencyId implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('fix_currency_id', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class IdIn implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereIn('id', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\DeleteMultipleTransaction;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanMergeBooking;
|
||||
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject;
|
||||
use App\Classes\Modules\Bookings\Services\GetBookings;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingTransaction;
|
||||
use App\Classes\Modules\Bookings\Services\DeleteMultipleBooking;
|
||||
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransactionDetail;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MergeBookingLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Merge Booking',
|
||||
'message' => 'You have successfully merged Booking'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanMergeBooking */
|
||||
private $canMergeBooking;
|
||||
|
||||
/** @var GetBookings */
|
||||
private $getBookings;
|
||||
|
||||
/** @var FetchesTransactionDetail */
|
||||
private $fetchesTransactionDetail;
|
||||
|
||||
/** @var UpdatesBookingTransaction */
|
||||
private $updatesBookingTransaction;
|
||||
|
||||
/** @var DeleteMultipleBooking */
|
||||
private $deletesMultipleBooking;
|
||||
|
||||
/** @var DeleteMultipleTransaction */
|
||||
private $deletesMultipleTransaction;
|
||||
|
||||
/**
|
||||
* MergeBookingLogic constructor.
|
||||
* @param CanMergeBooking $canMergeBooking
|
||||
* @param GetBookings $getBookings
|
||||
* @param FetchesTransactionDetail $fetchesTransactionDetail
|
||||
* @param UpdatesBookingTransaction $updatesBookingTransaction
|
||||
* @param DeleteMultipleBooking $deletesMultipleBooking
|
||||
* @param DeleteMultipleTransaction $deletesMultipleTransaction
|
||||
*/
|
||||
public function __construct(CanMergeBooking $canMergeBooking, GetBookings $getBookings, FetchesTransactionDetail $fetchesTransactionDetail, UpdatesBookingTransaction $updatesBookingTransaction, DeleteMultipleBooking $deletesMultipleBooking, DeleteMultipleTransaction $deletesMultipleTransaction)
|
||||
{
|
||||
$this->canMergeBooking = $canMergeBooking;
|
||||
$this->getBookings = $getBookings;
|
||||
$this->updatesBookingTransaction = $updatesBookingTransaction;
|
||||
$this->deletesMultipleBooking = $deletesMultipleBooking;
|
||||
$this->deletesMultipleTransaction = $deletesMultipleTransaction;
|
||||
$this->fetchesTransactionDetail = $fetchesTransactionDetail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
$transaction_amount = null;
|
||||
$transaction_original_amount = null;
|
||||
|
||||
$booking_ids_to_merge = [];
|
||||
$booking_update_values = [];
|
||||
|
||||
$transaction_ids_to_merge = [];
|
||||
$transaction_update_values = [];
|
||||
$transaction_po_delete = [];
|
||||
|
||||
$transaction_details_ids = [];
|
||||
$transaction_details_values = [];
|
||||
|
||||
$booking_object = new BookingMergeObject($request->get('id'),$request->get('booking_ids'));
|
||||
|
||||
$this->canMergeBooking->passes($booking_object);
|
||||
|
||||
$booking_main = $this->getBookings->handler(['id'=> $booking_object->getId()])[0];
|
||||
$bookings_to_merge = $this->getBookings->handler(['id_in'=> $booking_object->getBookingIds()]);
|
||||
|
||||
$booking_amount = $booking_main->fix_amount;
|
||||
$booking_main_transaction = $booking_main->transactions()->first();
|
||||
|
||||
$transaction_amount = $booking_main_transaction->amount;
|
||||
$transaction_original_amount = $booking_main_transaction->original_amount;
|
||||
|
||||
foreach($bookings_to_merge as $booking)
|
||||
{
|
||||
$booking_amount += $booking->fix_amount;
|
||||
$bookings_to_merge_transaction = $booking->transactions()->first();
|
||||
|
||||
$transaction_update_values['booking_id']=$booking_main->id;
|
||||
$transaction_amount += $bookings_to_merge_transaction->amount;
|
||||
$transaction_original_amount += $bookings_to_merge_transaction->original_amount;
|
||||
$transaction_ids_to_merge[]=$bookings_to_merge_transaction->id;
|
||||
|
||||
if($bookings_to_merge_transaction->type==7) {
|
||||
$transaction_po_delete[] = $bookings_to_merge_transaction->id;
|
||||
}
|
||||
|
||||
$booking_ids_to_merge[]=$booking->id;
|
||||
|
||||
foreach($bookings_to_merge_transaction->transactionDetails()->get() as $transaction_detail){
|
||||
$transaction_details_ids[] = $transaction_detail->id;
|
||||
$transaction_details_values['transaction_id'] = $booking_main_transaction->id;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$booking_update_values['fix_amount']=$booking_amount;
|
||||
|
||||
//Update all transactions
|
||||
$this->updatesBookingTransaction->execute(
|
||||
$booking_main->id,$booking_update_values,
|
||||
$transaction_ids_to_merge, $transaction_update_values,
|
||||
$transaction_details_ids, $transaction_details_values
|
||||
);
|
||||
|
||||
//Soft delete merged booking
|
||||
$this->deletesMultipleBooking->execute($booking_ids_to_merge);
|
||||
|
||||
//Soft delete merged transaction with status 7 (purchase order)
|
||||
if(count($transaction_po_delete)>0) {
|
||||
$this->deletesMultipleTransaction->execute($transaction_po_delete);
|
||||
}
|
||||
|
||||
return $this->response();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class BookingMergeObject implements DataTransferObject
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
private $id;
|
||||
|
||||
/** @var array */
|
||||
private $bookingIds;
|
||||
|
||||
/** @var float */
|
||||
private $bookingAmount;
|
||||
|
||||
/** @var float */
|
||||
private $transactionAmount;
|
||||
|
||||
/**
|
||||
* BookingMergeObject constructor.
|
||||
* @param int $id
|
||||
* @param array $bookingIds
|
||||
*/
|
||||
public function __construct(int $id, array $bookingIds)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->bookingIds = $bookingIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getBookingIds(): array
|
||||
{
|
||||
return $this->bookingIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getBookingAmount(): float
|
||||
{
|
||||
return $this->bookingAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $amount
|
||||
* @return float
|
||||
*/
|
||||
public function setBookingAmount(float $amount)
|
||||
{
|
||||
$this->bookingAmount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getTransactionAmount(): float
|
||||
{
|
||||
return $this->transactionAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $amount
|
||||
* @return float
|
||||
*/
|
||||
public function setTransactionAmount(float $amount)
|
||||
{
|
||||
$this->transactionAmount = $amount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractDeleteMultipleRecord;
|
||||
use App\Models\Booking;
|
||||
|
||||
class DeleteMultipleBooking extends AbstractDeleteMultipleRecord
|
||||
{
|
||||
/**
|
||||
* @param array $ids
|
||||
* @return mixed
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(array $ids) {
|
||||
return $this->handler(Booking::query(), $ids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractDeleteMultipleRecord;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class DeleteMultipleTransaction extends AbstractDeleteMultipleRecord
|
||||
{
|
||||
/**
|
||||
* @param array $ids
|
||||
* @return mixed
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(array $ids) {
|
||||
return $this->handler(Transaction::query(), $ids);
|
||||
}
|
||||
}
|
||||
@@ -30,4 +30,5 @@ class FetchesBooking extends AbstractFetchRecord
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\General\Eloquent\AbstractGetRecord;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class GetBookings extends AbstractGetRecord
|
||||
{
|
||||
|
||||
/** @var Booking */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* FetchesUser constructor.
|
||||
* @param Booking $repository
|
||||
*/
|
||||
public function __construct(Booking $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @return Collection
|
||||
* @throws ResourceNotFoundException
|
||||
*/
|
||||
public function getResults(Builder $query):Collection
|
||||
{
|
||||
if (!$query->exists()) {
|
||||
throw new ResourceNotFoundException('Unable to find any record based on the criteria provided');
|
||||
}
|
||||
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateMultipleRecord;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\TransactionDetail;
|
||||
|
||||
class UpdatesBookingTransaction extends AbstractUpdateMultipleRecord
|
||||
{
|
||||
/**
|
||||
* @param int $booking_id
|
||||
* @param array $booking_values
|
||||
* @param array $transaction_ids
|
||||
* @param array $transaction_values
|
||||
* @param array $transaction_detail_ids
|
||||
* @param array $transaction_detail_values
|
||||
* @return mixed
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(int $booking_id, array $booking_values, array $transaction_ids, array $transaction_values, array $transaction_detail_ids, array $transaction_detail_values) {
|
||||
|
||||
$booking_update_success = $this->handler(Booking::query(),[$booking_id],$booking_values);
|
||||
if($booking_update_success) {
|
||||
$booking_update_success = $this->handler(Transaction::query(), $transaction_ids, $transaction_values);
|
||||
$booking_update_success = $this->handler(TransactionDetail::query(), $transaction_detail_ids, $transaction_detail_values);
|
||||
}
|
||||
|
||||
return $booking_update_success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Standards\Criterias;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\General\Eloquent\AbstractFetchRecord;
|
||||
use App\Classes\General\Eloquent\AbstractGetRecord;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Booking;
|
||||
|
||||
class BookingsAreMergeable
|
||||
{
|
||||
|
||||
/** @var Booking */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* BookingsAreMergeable constructor.
|
||||
* @param Booking $repository
|
||||
*/
|
||||
public function __construct(Booking $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param BookingMergeObject $object
|
||||
* @return bool
|
||||
* @throws ResourceNotFoundException
|
||||
*/
|
||||
public function execute(BookingMergeObject $object){
|
||||
|
||||
$bookingOriginal=$this->repository->where(['id'=> $object->getId(),'status' => ApprovalStatus::APPROVED,])->first();
|
||||
$bookingToMerge=$this->repository->whereIn('id', $object->getBookingIds())
|
||||
->where([
|
||||
'status' => ApprovalStatus::APPROVED,
|
||||
'service_id' => $bookingOriginal->service_id,
|
||||
'fix_currency_id' => $bookingOriginal->fix_currency_id,
|
||||
'convertible_currency_id' => $bookingOriginal->convertible_currency_id,
|
||||
])->get();
|
||||
|
||||
if($bookingOriginal===null || $bookingToMerge->count() !== count($object->getBookingIds())){
|
||||
throw new ResourceNotFoundException('The booking doesn\'t exist');
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Standards\Criterias\BookingsAreMergeable;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use App\Classes\Modules\Bookings\Standards\Validators\BookingMergeValidation;
|
||||
|
||||
class CanMergeBooking extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var BookingMergeValidation */
|
||||
private $bookingMergeValidation;
|
||||
|
||||
/** @var BookingsAreMergeable */
|
||||
private $bookingsAreMergeable;
|
||||
|
||||
|
||||
/**
|
||||
* CanCreateBooking constructor.
|
||||
* @param BookingMergeValidation $bookingMergeValidation
|
||||
* @param BookingsAreMergeable $bookingsAreMergeable
|
||||
*/
|
||||
public function __construct(BookingMergeValidation $bookingMergeValidation, BookingsAreMergeable $bookingsAreMergeable)
|
||||
{
|
||||
$this->bookingMergeValidation = $bookingMergeValidation;
|
||||
$this->bookingsAreMergeable = $bookingsAreMergeable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BookingObject $object
|
||||
* @return bool
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return $this->bookingMergeValidation->validate($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BookingMergeObject $object
|
||||
* @return bool
|
||||
* @throws ResourceNotFoundException
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
$this->bookingsAreMergeable->execute($object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Standards\Validators;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractValidation;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingMergeObject;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
|
||||
class BookingMergeValidation extends AbstractValidation
|
||||
{
|
||||
/**
|
||||
* @param BookingMergeObject $object
|
||||
* @return array
|
||||
*/
|
||||
protected function data($object): array
|
||||
{
|
||||
return [
|
||||
'id' => $object->getId(),
|
||||
'booking_ids' => $object->getBookingIds()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function rules(): array
|
||||
{
|
||||
return [
|
||||
'id' => 'required|integer',
|
||||
'booking_ids' => 'required|array|min:1',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function messages(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\MergeBookingLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MergeBookingController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param MergeBookingLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function merge(Request $request, MergeBookingLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Classes\ValueObjects\Constants as Constants;
|
||||
use App\Models as Models;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class FakeBookingTransactions extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if(App()->environment('local')) {
|
||||
//Add user to map company, and auth user for bookings
|
||||
$email = 'bookmaster@cief.com';
|
||||
$password = 'bo@k!ng$123';
|
||||
$booking_user = [
|
||||
'name' => 'Book Master',
|
||||
'email' => $email,
|
||||
'password' => bcrypt($password),
|
||||
'type' => Constants\RoleTypes::USER,
|
||||
'status' => Constants\ApprovalStatus::APPROVED,
|
||||
];
|
||||
$user = Models\User::updateOrCreate(['email' => $email], $booking_user);
|
||||
$user_id = $user->id;
|
||||
|
||||
//Add 3 Entity: 2 company + 1 individual
|
||||
$companies = [
|
||||
[
|
||||
'name' => 'Maersk Line SDN BHD',
|
||||
'reference' => 'MAERSK-123',
|
||||
'type' => Constants\CompanyType::COMPANY_BUSINESS,
|
||||
'business_type' => Constants\BusinessType::FREIGHT_FORWARDER,
|
||||
'status' => Constants\ApprovalStatus::APPROVED,
|
||||
],
|
||||
[
|
||||
'name' => 'Sunrise Importer SDN BHD',
|
||||
'reference' => 'SSMID-E',
|
||||
'type' => Constants\CompanyType::COMPANY_BUSINESS,
|
||||
'business_type' => Constants\BusinessType::IMPORTER,
|
||||
'status' => Constants\ApprovalStatus::APPROVED,
|
||||
],
|
||||
[
|
||||
'name' => 'Han Solo',
|
||||
'reference' => '880101-14-6541',
|
||||
'type' => Constants\CompanyType::PERSONAL_BUSINESS,
|
||||
'business_type' => Constants\BusinessType::IMPORTER,
|
||||
'status' => Constants\ApprovalStatus::APPROVED,
|
||||
]
|
||||
];
|
||||
|
||||
$addresses = [
|
||||
[
|
||||
'company_id' => null, //fill-up later
|
||||
'country_id' => 1,
|
||||
'state_id' => 15,
|
||||
'district_id' => 402,
|
||||
'postcode' => '63000',
|
||||
'street_one' => 'Vertex Tower, Cybersquare,',
|
||||
'street_two' => 'Jalan Teknorat 6, Cyber 5',
|
||||
'billing' => 1
|
||||
]
|
||||
];
|
||||
|
||||
$contacts = [
|
||||
[
|
||||
'company_id' => null, //fill-up later
|
||||
'country_id' => 1,
|
||||
'reference' => 'main',
|
||||
'phone' => '0123456789',
|
||||
'email' => 'email@edomain.com'
|
||||
]
|
||||
];
|
||||
|
||||
$banks = [
|
||||
[
|
||||
'company_id' => null, //fill-up later
|
||||
'reference' => 'CBB',
|
||||
'bank_name' => 'Citibank Berhad',
|
||||
'holder_name' => '', //fill-up later, use company name
|
||||
'account_no' => '0123456789',
|
||||
'bank_branch' => 'Menara Citibank Kuala Lumpur',
|
||||
'swift' => null,
|
||||
'snap' => null,
|
||||
'type' => Constants\BankAccountType::EXTERNAL,
|
||||
'default' => 0,
|
||||
'status' => 2,
|
||||
'country_id' => 2,
|
||||
]
|
||||
];
|
||||
|
||||
$company_ids = [];
|
||||
$address_ids = [];
|
||||
$contact_ids = [];
|
||||
$bank_ids = [];
|
||||
|
||||
foreach ($companies as $company) {
|
||||
$check = ['name' => $company['name']];
|
||||
$added = Models\Company::updateOrCreate($check, $company);
|
||||
$company_ids[] = $added->id;
|
||||
|
||||
//Add address
|
||||
foreach ($addresses as $address) {
|
||||
$address['company_id'] = $added->id;
|
||||
$address['street_one'] = $company['name'] . ", " . $address['street_one'];
|
||||
$check_address = ['street_one' => $address['street_one']];
|
||||
$added_address = Models\Address::updateOrCreate($check_address, $address);
|
||||
$address_ids[$added->id][] = $added_address->id;
|
||||
}
|
||||
|
||||
//Add contact
|
||||
foreach ($contacts as $contact) {
|
||||
$contact['company_id'] = $added->id;
|
||||
$contact['reference'] = $company['name'] . ", " . $contact['reference'];
|
||||
$check_contact = ['reference' => $contact['reference']];
|
||||
$added_contact = Models\Contact::updateOrCreate($check_contact, $contact);
|
||||
$contact_ids[$added->id][] = $added_contact->id;
|
||||
}
|
||||
|
||||
//Add bank
|
||||
foreach ($banks as $bank) {
|
||||
$bank['company_id'] = $added->id;
|
||||
$bank['reference'] = $company['name'] . ", " . $bank['reference'];
|
||||
$check_bank = ['reference' => $bank['reference']];
|
||||
$added_bank = Models\Bank::updateOrCreate($check_bank, $bank);
|
||||
$bank_ids[$added->id][] = $added_bank->id;
|
||||
}
|
||||
|
||||
//Model employee have issue: Unknown column 'updated_at' in 'field list'
|
||||
DB::table('employees')->updateOrInsert(
|
||||
['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2],
|
||||
['company_id' => $added->id, 'user_id' => $user_id, 'status' => 2]
|
||||
);
|
||||
|
||||
Models\Document::updateOrCreate(
|
||||
['owner_id' => $added->id, 'status' => 2],
|
||||
[
|
||||
'owner_type' => 'App\Models\Company',
|
||||
'owner_id' => $added->id,
|
||||
'status' => 2,
|
||||
'document_type' => ($company['type'] == Constants\CompanyType::COMPANY_BUSINESS) ? Constants\DocumentType::SSM_REGISTRATION : Constants\DocumentType::IDENTITY_CARD,
|
||||
'reference' => $company['reference'],
|
||||
]
|
||||
);
|
||||
|
||||
Models\SegmentCompany::updateOrCreate(
|
||||
['company_id' => $added->id, 'segment_id' => 1],
|
||||
['company_id' => $added->id, 'segment_id' => 1]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//Booking, Transactions require auth user
|
||||
$user = new Models\User;
|
||||
$user->email = $email;
|
||||
$user->password = $password;
|
||||
auth()->login($user);
|
||||
|
||||
$bookings = [
|
||||
[
|
||||
'company_id' => null, //fill-up later
|
||||
'marking' => null, //fill-up later
|
||||
'service_id' => 1,
|
||||
'bank_id' => null, //fill-up later
|
||||
'fix_amount' => null, //fill-up later
|
||||
'fix_currency_id' => 2,
|
||||
'convertible_currency_id' => 2,
|
||||
'conversion_currency_id' => 1,
|
||||
'status' => Constants\ApprovalStatus::APPROVED,
|
||||
],
|
||||
];
|
||||
|
||||
$transactions = [
|
||||
[
|
||||
'booking_id' => null, //fill-up later
|
||||
'type' => null, //fill-up later
|
||||
'issuer' => null, //fill-up later
|
||||
'receiver' => 1,
|
||||
'recipient_bank_account_id' => 1,
|
||||
'payment_method' => 2,
|
||||
'payment_reference' => 2,
|
||||
'bill_no' => null, //fill-up later
|
||||
'amount' => null, //fill-up later
|
||||
'original_amount' => null, //fill-up later
|
||||
'currency_id' => 2,
|
||||
'original_currency_id' => 2,
|
||||
'currency_rate' => 1.0,
|
||||
'tax' => 1.0,
|
||||
'service_charge' => 0.0,
|
||||
'expires_on' => null,
|
||||
'status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$transaction_details = [
|
||||
[
|
||||
'transaction_id' => null, //fill-up later
|
||||
'product_code' => 'MBP15',
|
||||
'product_name' => 'Macbook Pro 15"',
|
||||
'quantity' => 2,
|
||||
'price' => 1000,
|
||||
'amount' => 2000,
|
||||
],
|
||||
[
|
||||
'transaction_id' => null, //fill-up later
|
||||
'product_code' => 'IP12',
|
||||
'product_name' => 'iPad Pro 12"',
|
||||
'quantity' => 2,
|
||||
'price' => 1000,
|
||||
'amount' => 2000,
|
||||
],
|
||||
[
|
||||
'transaction_id' => null, //fill-up later
|
||||
'product_code' => 'IMC24',
|
||||
'product_name' => 'iMac',
|
||||
'quantity' => 2,
|
||||
'price' => 1000,
|
||||
'amount' => 2000,
|
||||
],
|
||||
];
|
||||
|
||||
$booking_ids = [];
|
||||
$transaction_ids = [];
|
||||
$transaction_types = [
|
||||
Constants\TransactionType::PAYMENT_ATTEMPT,
|
||||
Constants\TransactionType::PAYMENT,
|
||||
Constants\TransactionType::INVOICE,
|
||||
Constants\TransactionType::BILL,
|
||||
Constants\TransactionType::PERFORMA,
|
||||
Constants\TransactionType::TOP_UP,
|
||||
Constants\TransactionType::REFUND,
|
||||
Constants\TransactionType::PURCHASE_ORDER,
|
||||
Constants\TransactionType::SUPPLIER_DELIVER,
|
||||
];
|
||||
|
||||
foreach ($company_ids as $company_id) {
|
||||
foreach ($transaction_types as $transaction_type) {
|
||||
foreach ($bookings as $booking) {
|
||||
|
||||
$marking = mt_rand(20000, 20100); //Limit marking within 100 for easier to remember
|
||||
|
||||
$booking['company_id'] = $company_id;
|
||||
$booking['bank_id'] = $bank_ids[$company_id][0];
|
||||
$booking['marking'] = $marking;
|
||||
$fix_amount = [4000,8000];
|
||||
$booking['fix_amount'] = $fix_amount[array_rand($fix_amount)];;
|
||||
$booking['created_at'] = date('Y-m-d H:i:s');
|
||||
$booking['updated_at'] = date('Y-m-d H:i:s');
|
||||
|
||||
$check_booking = ['marking' => $booking['marking']];
|
||||
$added_booking = Models\Booking::updateOrCreate($check_booking, $booking);
|
||||
$booking_ids[] = $added_booking->id;
|
||||
$booking_id = $added_booking->id;
|
||||
|
||||
foreach ($transactions as $transaction) {
|
||||
|
||||
$bill_no = $code = mt_rand(100000001, 999999999);
|
||||
|
||||
$transaction['booking_id'] = $booking_id;
|
||||
$transaction['type'] = $transaction_type;
|
||||
$transaction['issuer'] = $company_id;
|
||||
|
||||
$transaction['bill_no'] = $bill_no;
|
||||
$transaction['amount'] = 6000;
|
||||
$transaction['original_amount'] = 6000;
|
||||
|
||||
$transaction['created_at'] = date('Y-m-d H:i:s');
|
||||
$transaction['updated_at'] = date('Y-m-d H:i:s');
|
||||
|
||||
$check_transaction = ['bill_no' => $transaction['bill_no']];
|
||||
$added_transaction = Models\Transaction::updateOrCreate($check_transaction, $transaction);
|
||||
$transaction_ids[] = $added_transaction->id;
|
||||
$transaction_id = $added_transaction->id;
|
||||
|
||||
foreach ($transaction_details as $transaction_detail) {
|
||||
$transaction_detail['transaction_id'] = $transaction_id;
|
||||
|
||||
$transaction_detail['created_at'] = date('Y-m-d H:i:s');
|
||||
$transaction_detail['updated_at'] = date('Y-m-d H:i:s');
|
||||
|
||||
$check_transaction_details = [
|
||||
'transaction_id' => $transaction_detail['transaction_id'],
|
||||
'product_code' => $transaction_detail['product_code']
|
||||
];
|
||||
Models\TransactionDetail::updateOrCreate($check_transaction_details,
|
||||
$transaction_detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="row m-b-10 parentContainer">
|
||||
<div class="col">
|
||||
<div class="row align-items-center">
|
||||
<div class="col p-t-5 p-b-5">
|
||||
<div class="col text-center">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h5 class="all-caps">Merge Transfers</h5>
|
||||
<div class="fs-11">Are you sure you want to merge? This action is undoable.</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-success btn-block b-rad-none" @click="mergeTransfer()">Merge</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,
|
||||
},
|
||||
'booking': {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
'bookingToMerge': {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
parameters:null,
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
mergeTransfer(){
|
||||
|
||||
this.$root.$emit('setLoading', true);
|
||||
|
||||
let bookings=[];
|
||||
this.bookingToMerge.forEach(function(booking) {
|
||||
bookings.push(booking.id);
|
||||
});
|
||||
this.parameters = {};
|
||||
|
||||
if(bookings.length>0) {
|
||||
this.$set(this.parameters, 'id', this.booking.id);
|
||||
this.$set(this.parameters, 'booking_ids', bookings);
|
||||
this.submit(route('api.booking.merge'), 'post', this.section, true, true);
|
||||
}
|
||||
},
|
||||
successHandler(){
|
||||
setTimeout(function(marking){
|
||||
window.location.href = this.route('booking.details', marking);
|
||||
}, 2000, this.booking.marking);
|
||||
},
|
||||
errorHandler() {
|
||||
this.$root.$emit('setLoading', false);
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler, staticFormHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div class="row align-items-center m-b-10 parentContainer">
|
||||
<div class="row w-100 m-0 p-0">
|
||||
<div class="col-auto hide" @click="showPurchaseDetails(item.id)">
|
||||
<div class="hint-text">
|
||||
<i class="fa fa-plus fs-8 muted hint-text"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto pt-1 pb-0 pr-1">
|
||||
<div class="font-heading fs-12" style="line-height: 0px;">
|
||||
<input type="checkbox" v-bind:data-id="this.item.id" @change="selectedBookings">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth">
|
||||
<div class="font-heading all-caps fs-11">{{this.item.created_at}}</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth">
|
||||
<div class="font-heading all-caps fs-11 bold">{{this.item.marking}}</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth">
|
||||
<div class="font-heading fs-11 bold">
|
||||
<span class="flag-icon fs-11" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth">
|
||||
<div class="font-heading fs-11">{{this.item.service.name}}</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth150">
|
||||
<div class="font-heading fs-11 text-success bold" v-if="item.purchase_order!==null">{{formatAmount(this.item.purchase_order.amount)}} {{this.item.purchase_order.original_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col-auto" :style="minWidth150">
|
||||
<div class="font-heading fs-11 text-success bold">{{formatAmount(this.item.amount)}} {{this.item.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-left no-margin bg-white hide" v-if="item.purchase_order!==null" v-for="po in (this.item.purchase_order ? this.item.purchase_order.details : [])" v-bind:key="po.id">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11 text-success bold">{{po.description}}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11 text-success bold">{{po.quantity}}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11 text-success bold">{{po.unit_price}}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11 text-success bold">{{po.total}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
minWidth:{
|
||||
minWidth:'100px',
|
||||
},
|
||||
minWidth150:{
|
||||
minWidth:'150px',
|
||||
},
|
||||
selected_id:0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectedBookings(e) {
|
||||
this.$root.$emit('selectedBookings', e.target, this.item);
|
||||
},
|
||||
showPurchaseDetails(id){
|
||||
console.log(this.selected_id);
|
||||
this.selected_id = id;
|
||||
},
|
||||
formatAmount(amount){
|
||||
return (Math.round((amount + Number.EPSILON) * 100) / 100).toFixed(2)
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -111,7 +111,8 @@
|
||||
<div class="font-heading fs-10">But don't worry you can always merge your transfer orders into one to complete your purchase order successfully and generate your invoice.</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-warning">Merge Transfer Orders</button>
|
||||
<!--link to merge: route('booking.merge',this.data.marking) -->
|
||||
<a class="btn btn-xs all-caps b-rad-none btn-warning" href="#">Merge Transfer Orders</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<transition-component group enter-class="animate__animated animate__fadeInUp animate__delay-1 animate__faster p-r-30" leave-class="animate__animated animate__fadeOutDown animate__faster p-r-30" style="min-height: 300px;">
|
||||
<transition-component group enter-class="animate__animated animate__fadeInUp animate__delay-1 animate__faster p-r-30" leave-class="animate__animated animate__fadeOutDown animate__faster p-r-30" style="min-height: 300px;width:100%">
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="$store.getters.isLoading(section)"></loading-component>
|
||||
<div class="row" key="2" v-show="!$store.getters.isLoading(section)">
|
||||
<div class="col">
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@extends('layouts.base_portal')
|
||||
@section('inner_content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<booking-merge-section-component :marking={{$marking}}></booking-merge-section-component>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -17,5 +17,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking
|
||||
});
|
||||
|
||||
Route::post('{id}/purchase_order/verification', 'ApprovePurchaseOrderController@approve')->name('po.approval');
|
||||
//Temporarily disabled
|
||||
//Route::post('/merge', 'MergeBookingController@merge')->name('merge');
|
||||
|
||||
});
|
||||
+3
-1
@@ -37,4 +37,6 @@ Route::get('/transfer/{marking}', function ($marking) {
|
||||
return view('pages.booking_details', ['marking' => $marking]);
|
||||
})->name('booking.details');
|
||||
|
||||
|
||||
Route::get('/transfer/merge/{marking}', function ($marking) {
|
||||
return view('pages.booking_merge', ['marking' => $marking]);
|
||||
})->name('booking.merge');
|
||||
|
||||
Reference in New Issue
Block a user