diff --git a/app/Classes/General/Eloquent/Filters/HasActiveReward.php b/app/Classes/General/Eloquent/Filters/HasActiveReward.php index 5770ca6e..26385b96 100644 --- a/app/Classes/General/Eloquent/Filters/HasActiveReward.php +++ b/app/Classes/General/Eloquent/Filters/HasActiveReward.php @@ -2,7 +2,6 @@ namespace App\Classes\General\Eloquent\Filters; -use App\Classes\ValueObjects\Constants\RoleTypes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; @@ -12,33 +11,17 @@ class HasActiveReward implements Filter /** * @param Builder $builder * @param $value - * @return mixed + * @return Builder|mixed */ public static function apply(Builder $builder, $value) { - if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){ - // $userId = $value !== 1 ? $value : Auth::user()->id; - $userId = $value; - return $builder->where('user_id', $userId) - ->where(function ($query) { - $query->whereHas('reward', function ($subquery) { - $subquery->where('is_active', true); - }) - ->orWhereDoesntHave('reward'); - }) - ->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) { - $query->where('user_id', $userId); + return $builder->where('user_id', Auth::user()->id) //cief todo: should not use Auth::user()->id + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); }); - } - else{ - return $builder->where('user_id', Auth::user()->id) - ->where(function ($query) { - $query->whereHas('reward', function ($subquery) { - $subquery->where('is_active', true); - }) - ->orWhereDoesntHave('reward'); - }) - ->whereDoesntHave('voucher.redemptions.transaction.owner'); - } + // ->orWhereDoesntHave('reward'); + }); } + } diff --git a/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php b/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php new file mode 100644 index 00000000..5d69aa4b --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasActiveRewardForAdmin.php @@ -0,0 +1,26 @@ +where('user_id', $value) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }); + // ->orWhereDoesntHave('reward'); + }); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php new file mode 100644 index 00000000..be4d335b --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithCompany.php @@ -0,0 +1,53 @@ +type, RoleTypes::ADMIN_ROLES)){ + // $userId = $value !== 1 ? $value : Auth::user()->id; + $userId = $value; + $user = User::where('id', $userId)->first(); + $users = $user->company()->first()->employees; + $userIds = $users->pluck('id'); + + return $builder->whereIn('user_id', $userIds) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) { + $query->where('user_id', $userId); + }); + } + else{ + $user = User::where('id', Auth::user()->id)->first(); + $users = $user->company()->first()->employees; + $userIds = $users->pluck('id'); + + return $builder->whereIn('user_id', $userIds) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.owner'); + } + } +} diff --git a/app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php new file mode 100644 index 00000000..79a02914 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasVouchersAllWithUser.php @@ -0,0 +1,44 @@ +type, RoleTypes::ADMIN_ROLES)){ + // $userId = $value !== 1 ? $value : Auth::user()->id; + $userId = $value; + return $builder->where('user_id', $userId) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) { + $query->where('user_id', $userId); + }); + } + else{ + return $builder->where('user_id', Auth::user()->id) + ->where(function ($query) { + $query->whereHas('reward', function ($subquery) { + $subquery->where('is_active', true); + }) + ->orWhereDoesntHave('reward'); + }) + ->whereDoesntHave('voucher.redemptions.transaction.owner'); + } + } +} diff --git a/app/Classes/General/Eloquent/Filters/RandomName.php b/app/Classes/General/Eloquent/Filters/RandomName.php deleted file mode 100644 index 54024e96..00000000 --- a/app/Classes/General/Eloquent/Filters/RandomName.php +++ /dev/null @@ -1,20 +0,0 @@ -where('is_active', $value); - } - -} diff --git a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php index 3b05ac63..1bf9dede 100644 --- a/app/Classes/Jobs/UpdatePerfexCRMPrelude.php +++ b/app/Classes/Jobs/UpdatePerfexCRMPrelude.php @@ -41,7 +41,11 @@ class UpdatePerfexCRMPrelude implements ShouldQueue { $serviceTypeName = $this->transaction->owner->company->services()->where('id', $this->transaction->owner->service_id)->first()->name; $booking = $this->transaction->booking; - $bankDetails = $this->generateBankDetails($booking->bank); + $bank = $booking->bank; //cief todo: 66 + if($this->transaction->bank){ + $bank = $this->transaction->bank; + } + $bankDetails = $this->generateBankDetails($bank); $data = [ 'amount' => number_format($this->transaction->amount, 2, '.', ''), diff --git a/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php b/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php new file mode 100644 index 00000000..a52288af --- /dev/null +++ b/app/Classes/Modules/Accounts/Services/DeletesKeyValuePair.php @@ -0,0 +1,19 @@ +handler($model); + } +} diff --git a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php index 8509ed6b..88172f47 100644 --- a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php +++ b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankLogic.php @@ -3,21 +3,17 @@ namespace App\Classes\Modules\Banks\ControllersLogic; use App\Http\Resources\BankResource; - use App\Classes\General\Abstracts\AbstractControllerLogic; - use App\Classes\Modules\Banks\Services\FetchesBank; - use App\Classes\Modules\Banks\Standards\Rules\CanUpdateBank; use App\Classes\Modules\Banks\Services\UpdatesBank; +use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank; use App\Classes\Modules\Banks\Services\CreatesBankLog; - +use App\Classes\Modules\Banks\Processors\UpdateBankProcessor; use App\Classes\Modules\Banks\DataTransferObjects\BankObject; - -use ErrorException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; + class UpdateBankLogic extends AbstractControllerLogic { @@ -44,24 +40,36 @@ class UpdateBankLogic extends AbstractControllerLogic /** @var CreatesBankLog */ private $createsBankLog; + /** @var CreatesOrUpdateBank */ + private $createsOrUpdateBank; + + /** @var UpdateBankProcessor */ + private $updateBankProcessor; + /** * UpdateBankLogic constructor. * @param CanUpdateBank $canUpdateBank * @param UpdatesBank $updatesBank * @param FetchesBank $fetchesBank * @param CreatesBankLog $createsBankLog + * @param CreatesOrUpdateBank $createsOrUpdateBank + * @param UpdateBankProcessor $updateBankProcessor */ public function __construct( CanUpdateBank $canUpdateBank, UpdatesBank $updatesBank, FetchesBank $fetchesBank, - CreatesBankLog $createsBankLog + CreatesBankLog $createsBankLog, + CreatesOrUpdateBank $createsOrUpdateBank, + UpdateBankProcessor $updateBankProcessor ) { $this->canUpdateBank = $canUpdateBank; $this->updatesBank = $updatesBank; $this->fetchesBank = $fetchesBank; $this->createsBankLog = $createsBankLog; + $this->createsOrUpdateBank = $createsOrUpdateBank; + $this->updateBankProcessor = $updateBankProcessor; } /** @@ -74,15 +82,15 @@ class UpdateBankLogic extends AbstractControllerLogic public function logic(Request $request) : JsonResponse { $bankObject = new BankObject( - $request->input('company_id'), + $request->input('company_id'), $request->input('account_type'), $request->input('bank_name'), - $request->input('holder_name'), + $request->input('holder_name'), $request->input('account_no'), - $request->input('bank_branch'), - $request->input('swift'), + $request->input('bank_branch'), + $request->input('swift'), $request->input('snap'), - $request->input('country_id'), + $request->input('country_id'), $request->input('reference') ); @@ -90,12 +98,10 @@ class UpdateBankLogic extends AbstractControllerLogic $this->canUpdateBank->passes($bankObject); - $bank_query = $this->updatesBank->execute($bank, $bankObject); - -// $bankLog = $this->createsBankLog->execute($bank_query); + $bank_query = $this->updateBankProcessor->execute($bankObject, $bank, $request->input('bill_no') ?? '', (int) $request->input('transaction_id') ?? 0 ); return $this->resourceResponse(new BankResource($bank_query)); } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php new file mode 100644 index 00000000..e73d051a --- /dev/null +++ b/app/Classes/Modules/Banks/ControllersLogic/UpdateBankMetadataLogic.php @@ -0,0 +1,67 @@ + 'Update Bank Metadata', + 'message' => 'You have successfully updated the Bank metadata' + ]; + } + + /** @var CanUpdateBankMetadata */ + private $canUpdateBankMetadata; + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** + * UpdateBankMetadataLogic constructor. + * @param CanUpdateBankMetadata $canUpdateBankMetadata + * @param FetchesTransaction $fetchesTransaction + */ + public function __construct( + CanUpdateBankMetadata $canUpdateBankMetadata, + FetchesTransaction $fetchesTransaction + ) + { + $this->canUpdateBankMetadata = $canUpdateBankMetadata; + $this->fetchesTransaction = $fetchesTransaction; + } + + /** + * @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 + { + $bankMetadataObject = new BankMetadataObject( + $request->input('transactionId'), + ); + + $this->canUpdateBankMetadata->passes($bankMetadataObject); + + $transaction = $this->fetchesTransaction->execute(['id' => $request->input('transactionId')]); + $transaction->attributesKVP()->delete(); + + return $this->response([]); + } + +} diff --git a/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php b/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php new file mode 100644 index 00000000..dae7a61e --- /dev/null +++ b/app/Classes/Modules/Banks/DataTransferObjects/BankMetadataObject.php @@ -0,0 +1,29 @@ +transaction_id = $transaction_id; + } + + /** + * @return int + */ + public function getTransactionId(): int + { + return $this->transaction_id; + } +} diff --git a/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php new file mode 100644 index 00000000..6030c11d --- /dev/null +++ b/app/Classes/Modules/Banks/Processors/UpdateBankProcessor.php @@ -0,0 +1,97 @@ +updatesBank = $updatesBank; + $this->createsOrUpdateBank = $createsOrUpdateBank; + $this->createsKeyValuePair = $createsKeyValuePair; + $this->fetchesTransaction = $fetchesTransaction; + } + + /** + * @param BankObject $bankObject + * @param Bank $bank + * @param string $billNo + * @param int $transactionId + * @return Model + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\JobResourceNotFoundException + */ + public function execute(BankObject $bankObject, Bank $bank, string $billNo, int $transactionId) { + $result = null; + if($billNo && $transactionId){ + $transaction = $this->fetchesTransaction->execute(['id' => $transactionId]); + //If payment transaction do not have a bank yet, create one + if(!$transaction->bank){ + $result = $this->createsOrUpdateBank->execute($bankObject); + + // if ($result->wasRecentlyCreated) { + //Key #1 for Bank + $kvp = $bank->attributesKVP()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first(); + if(!$kvp){ + $keyValuePairObject = new KeyValuePairObject( + "App\Models\Bank", + $result->id + ); + $this->createsKeyValuePair->execute($bank, $keyValuePairObject); + } + + //Key #2 for Payment Transaction (owner type: booking) + $keyValuePairObject = new KeyValuePairObject( + "App\Models\Bank", + $result->id + ); + $this->createsKeyValuePair->execute($transaction, $keyValuePairObject); + // } + + } + else{ + $result = $this->updatesBank->execute($transaction->bank, $bankObject); + } + } + else{ + $result = $this->updatesBank->execute($bank, $bankObject); + } + + return $result; + } +} diff --git a/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php b/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php new file mode 100644 index 00000000..1c582229 --- /dev/null +++ b/app/Classes/Modules/Banks/Services/CreatesOrUpdateBank.php @@ -0,0 +1,44 @@ + $object->getCompanyId(), + 'account_no' => $object->getAccountNo(), + 'reference' => $object->getReference(), + 'bank_name' => $object->getBankName(), + 'holder_name' => $object->getHolderName(), + 'bank_branch' => $object->getBankBranch(), + 'type' => $object->getType(), + 'country_id' => $object->getCountryId(), + 'created_by' => Auth::id(), + 'creator_type' => in_array($user->type, RoleTypes::ADMIN_ROLES) ? RoleTypes::ADMIN : RoleTypes::USER, + ]; + + $values = [ + 'swift' => $object->getSwift(), + 'snap' => $object->getSnap(), + ]; + + $model = Bank::updateOrCreate($attributes, $values); //Bank::firstOrCreate($attributes, $values); + + return $model; + } +} diff --git a/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php new file mode 100644 index 00000000..d102a763 --- /dev/null +++ b/app/Classes/Modules/Banks/Standards/Rules/CanUpdateBankMetadata.php @@ -0,0 +1,66 @@ +validation = $validation; + } + + /** + * @return bool + */ + protected function authorized($object): bool + { + //cief todo: 66 - temporary workaround + // if (!Auth::user()->can('update bank_metadata')) { + // return false; + // } + + // return true; + + if (in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)) { + return true; + } + + return false; + } + + /** + * @param BankMetadataObject $object + * @return bool + * @throws \App\Classes\Exceptions\RequestValidationException + */ + protected function validators($object): bool + { + return $this->validation->validate($object); + } + + /** + * @param BankMetadataObject $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php b/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php new file mode 100644 index 00000000..37e134c4 --- /dev/null +++ b/app/Classes/Modules/Banks/Standards/Validators/BankMetadataValidation.php @@ -0,0 +1,38 @@ + $object->getTransactionId(), + ]; + } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'transaction_id' => 'required', + ]; + } + + /** + * @return array + */ + protected function messages(): array + { + return []; + } +} diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php index 8c492eb1..e6bf4f1c 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingRefundLogic.php @@ -108,29 +108,36 @@ class CreateBookingRefundLogic extends AbstractControllerLogic // $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount')); // $transactionRefundCalculationObject->init(); - $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); + if ((float)$request->input('amount') === (float)$transaction->original_amount) { + $refundAmount = $transaction->original_amount / $transaction->currency_rate; + $service_charges_to_refund = $transaction->service_charge; + } else { + $refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7); - $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; - - $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); - - $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; - - $voucherCode = null; - - if ($transaction->voucherRedemption) { - $voucherCode = $transaction->voucherRedemption->voucher->code; + $bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending; + + $bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount'); + + $isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount; + + $voucherCode = null; + $redemptionId = null; + + if ($transaction->voucherRedemption) { + // $voucherCode = $transaction->voucherRedemption->voucher->code; + $redemptionId = $transaction->voucherRedemption->redemption_id; + } + + $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); + + $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId); + + $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId); + + $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); } - - $conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method); - - $quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode); - - $quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode); - - $service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge(); // refund service charges if booking is not E2E $refundTotal = $refundAmount; diff --git a/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php new file mode 100644 index 00000000..8bdee9e3 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/UpdateBookingRecipientLogic.php @@ -0,0 +1,94 @@ + 'Updated Booking', + 'message' => 'You have successfully updated the Booking' + ]; + } + + /** @var CanUpdateBooking */ + private $canUpdateBooking; + + /** @var UpdatesBooking */ + private $updatesBooking; + + /** @var FetchesBooking */ + private $fetchesBooking; + + + /** + * UpdateBookingRecipientLogic constructor. + * @param CanUpdateBooking $canUpdateBooking + * @param UpdatesBooking $updatesBooking + * @param FetchesBooking $fetchesBooking + */ + public function __construct( + CanUpdateBooking $canUpdateBooking, + UpdatesBooking $updatesBooking, + FetchesBooking $fetchesBooking + ) + { + $this->canUpdateBooking = $canUpdateBooking; + $this->updatesBooking = $updatesBooking; + $this->fetchesBooking = $fetchesBooking; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws ErrorException + */ + public function logic(Request $request) : JsonResponse + { + try { + DB::beginTransaction(); + + $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); + + + $booking_object = new BookingObject( + $booking->service_id, + $request->input('transferable_bank_id', $booking->transferable_bank_id), + $booking->marking, + $booking->fix_amount, + $booking->fix_currency_id, + $booking->convertible_currency_id, + $booking->conversion_currency_id + ); + $this->canUpdateBooking->passes($booking_object); + $booking = $this->updatesBooking->execute($booking, $booking_object); + + DB::commit(); + + return $this->resourceResponse(new BookingResource($booking)); + + } catch (\Exception $exception){ + throw new ErrorException($exception->getMessage(), $exception->getCode()); + } + } + +} diff --git a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php index 1d3d7acc..feafba19 100644 --- a/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php +++ b/app/Classes/Modules/Bookings/Services/FetchesBookingQuotation.php @@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidatedVoucherObject; use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherObject; use App\Classes\Modules\Currencies\Services\FetchesCurrency; use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher; +use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyRedemption; use App\Models\Company; use App\Models\Currency; use Illuminate\Support\Facades\Log; @@ -27,27 +28,34 @@ class FetchesBookingQuotation /** @var ValidatesVoucherifyVoucher */ private $validatesVoucherifyVoucher; + /** @var FetchesVoucherifyRedemption */ + private $fetchesVoucherifyRedemption; + /** * FetchesBookingQuotation constructor. * @param FetchesCompanyServiceSettings $fetchesCompanyServiceSettings * @param FetchesCurrency $fetchesCurrency + * @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher + * @param FetchesVoucherifyRedemption $fetchesVoucherifyRedemption */ - public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher) + public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, FetchesVoucherifyRedemption $fetchesVoucherifyRedemption) { $this->fetchesCompanyServiceSettings = $fetchesCompanyServiceSettings; $this->fetchesCurrency = $fetchesCurrency; $this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher; + $this->fetchesVoucherifyRedemption = $fetchesVoucherifyRedemption; } /** * @param Company $company * @param CurrencyConversionObject $conversionObject - * @param string $voucherCode + * @param null|string $voucherCode + * @param null|string $redemptionId * @return CalculationObject * @throws MalformedRequestException */ - public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null){ + public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null, ?string $redemptionId = null){ if($conversionObject->getAmount() <= 0) throw new MalformedRequestException('Your transfer must be greater than zero.'); $configurations = $this->fetchesCompanyServiceSettings->execute($company, $conversionObject); @@ -58,27 +66,53 @@ class FetchesBookingQuotation $calculationObject = new CalculationObject($conversionObject, $configurations, null); + $voucher = null; + //Voucherify if($voucherCode){ - $employee = $company->employees()->first(); - $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employee); + $employeeWhoOwnsTheVoucher = null; + + $employees = $company->first()->employees; + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $voucherCode) { + Log::info('1. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $company->employees()->first(); + } + + $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employeeWhoOwnsTheVoucher); $result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject); - - // //A minimum charge of RM5 applies when voucher used make price to be paid by customer RM0 - // if(isset($result->order->total_amount) && $result->order->total_amount === 0){ - // // $result->order->cief_original_total_amount = $result->order->total_amount; - // $result->order->total_amount = 500; - // $result->order->total_discount_amount = $result->order->total_discount_amount - $result->order->total_amount; - // Log::info('FetchesBookingQuotation order total_amount RM0 (voucher applied) for company id ' . $company->id. ' with original amount ' . $calculationObject->getSubTotal()); - // } - $voucher = [ "code" => $result->code, "discount" => property_exists($result, 'discount') ? $result->discount : null, "metadata" => $result->metadata, "order" => $result->order, ]; - $validatedVoucherObject = new ValidatedVoucherObject(isset($voucher['metadata']->name) ? $voucher['metadata']->name: "", $voucher['code'], $voucher['discount']->type ?? 'AMOUNT', $voucher['order']->total_discount_amount, $voucher['order']->total_amount); + } + else if($redemptionId){ + $result = $this->fetchesVoucherifyRedemption->execute($redemptionId); + $voucher = [ + "code" => $result->voucher->code ?? null, + "discount" => null, + "metadata" => null, + "order" => $result->order ?? null, + ]; + } + + if($voucher){ + $validatedVoucherObject = new ValidatedVoucherObject( + isset($voucher['metadata']->name) ? $voucher['metadata']->name : "", + $voucher['code'], + $voucher['discount']->type ?? 'AMOUNT', + $voucher['order']->total_discount_amount, + $voucher['order']->total_amount); $calculationObject = new CalculationObject($conversionObject, $configurations, $validatedVoucherObject); } diff --git a/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php b/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php index af4c88c4..d368574f 100644 --- a/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php +++ b/app/Classes/Modules/Exports/Services/ExportsAnalyticBillingTransactions.php @@ -65,8 +65,12 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings $bill = $transaction; $payment = $transaction->owner; $booking = $payment->owner; + $bank = $booking->bank; //cief todo: 66 + if($payment->bank){ + $bank = $payment->bank; + } $company = $booking->company; - $ecommerce = str::contains($booking->bank->bank_name, ['浙江网商银行']); + $ecommerce = str::contains($bank->bank_name, ['浙江网商银行']); return [ $booking->id, @@ -88,4 +92,4 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings $bill->created_at ]; } -} \ No newline at end of file +} diff --git a/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php new file mode 100644 index 00000000..65446adf --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/DeleteRefundTransactionLogic.php @@ -0,0 +1,112 @@ + 'Deleted Refund Transaction', + 'message' => 'You have successfully deleted a transaction' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var DeletesTransaction */ + private $deletesTransaction; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** @var CalculatesBookingRefundAmount */ + private $calculatesBookingRefundAmount; + + /** @var CalculatesBookingPaidAmount */ + private $calculatesBookingPaidAmount; + + /** @var UpdateBookingAmountLogic */ + private $updateBookingAmountLogic; + + /** + * CreatePaymentVerificationDocumentLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param DeletesTransaction $deletesTransaction + * @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount + * @param UpdateBookingAmountLogic $updateBookingAmountLogic + * @param calculatesBookingPaidAmount $calculatesBookingPaidAmount + */ + public function __construct(FetchesTransaction $fetchesTransaction, DeletesTransaction $deletesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic, CalculatesBookingPaidAmount $calculatesBookingPaidAmount) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->deletesTransaction = $deletesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount; + $this->updateBookingAmountLogic = $updateBookingAmountLogic; + $this->calculatesBookingPaidAmount = $calculatesBookingPaidAmount; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request): JsonResponse + { + // delete refund transaction + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + $this->deletesTransaction->execute($transaction); + + // Update payment_transaction status + $payment_transaction = $transaction->owner; + $this->updatesTransactionStatus->execute($payment_transaction, ApprovalStatus::APPROVED); + + // delete wallet top up transaction + $booking = $transaction->owner->owner; + Transaction::where('type', TransactionType::CREDIT_NOTE) + ->where('amount', $transaction->amount) + ->where('payment_reference', 'like', '%' . $booking->marking . '%') + ->delete(); + + // update back the latest booking amount + $request['fix_amount'] = $this->calculatesBookingPaidAmount->execute($booking); + $request->route()->setParameter('id', $booking->id); + $this->updateBookingAmountLogic->execute($request); + + // if have SUPPLIER_REFUND transaction + $bookingInWhiteForm = $payment_transaction->transactions()->bills()->first(); + if ($bookingInWhiteForm) { + + $whiteFormTransaction = Transaction::where('type', TransactionType::SUPPLIER_REFUND) + ->where('payment_reference', $transaction->payment_reference) + ->first(); + + // Log::info($whiteFormTransaction->id); + + $whiteFormTransaction->delete(); + } + + return $this->response([]); + } +} diff --git a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php index 8dab2d24..28a34057 100644 --- a/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php +++ b/app/Classes/Modules/Transactions/Processors/CreateProformaInvoiceTransactionProcessor.php @@ -24,6 +24,7 @@ use App\Classes\ValueObjects\Constants\DocumentType; use App\Models\Booking; use App\Models\Document; use Carbon\Carbon; +use Illuminate\Support\Facades\Log; use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf; class CreateProformaInvoiceTransactionProcessor @@ -102,37 +103,55 @@ class CreateProformaInvoiceTransactionProcessor */ public function execute(Booking $booking) { - $po_order_transaction = $booking->transactions() ->where('type', TransactionType::PURCHASE_ORDER) ->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]) ->first(); - $outstanding = $this->calculatesBookingOutstanding->execute($booking); + $transaction = $booking->transactions() + ->where('type', TransactionType::PAYMENT) + ->first(); - $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::CASH); + if (!$transaction) { + $outstanding = $this->calculatesBookingOutstanding->execute($booking); - $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject); + $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0 : 1, PaymentMethodType::CASH); + + $configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject); + + $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); + + $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); - $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); + $object = new TransactionObject( + $billNumber, + TransactionType::PAYMENT, + 1, + $booking->company->id, + $configurations->getConfigurations()->getBankId(), + $configurations->getConversionObject()->getPaymentMethod(), + $configurations->getTotal(), + $configurations->getForeignTotal(), + 1, + $configurations->getConversionObject()->getCurrencyId(), + $configurations->getConfigurations()->getRate(), + $configurations->getTax(), + $configurations->getServiceCharge(), + Carbon::now()->addMinutes($paymentAttemptLimit), + ApprovalStatus::PENDING_SUBMISSION, + [], + isset($billPlzBill) ? $billPlzBill->id : NULL + ); - $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); - - - $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, - $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), - $configurations->getTotal(), $configurations->getForeignTotal(), 1, - $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL); - - $this->createsTransaction->execute($booking, $object); + $this->createsTransaction->execute($booking, $object); + } $billNumber = $this->generatesTransactionBillNumber->execute('PROFORMA-'); - $payable_amount = $booking->transactions()->payments()->where(function($query){ - return $query->where(function($query){ + $payable_amount = $booking->transactions()->payments()->where(function ($query) { + return $query->where(function ($query) { return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString()); - })->orWhere(function($query){ + })->orWhere(function ($query) { return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); })->sum('amount'); @@ -142,14 +161,16 @@ class CreateProformaInvoiceTransactionProcessor ->where('type', TransactionType::PAYMENT) ->first(); - $booking_currency_average_rate = $booking_amount / $booking->transactions()->payments()->where(function($query){ - return $query->where(function($query){ + $paymentAmount = $booking->transactions()->payments()->where(function ($query) { + return $query->where(function ($query) { return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString()); - })->orWhere(function($query){ + })->orWhere(function ($query) { return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); }); })->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total'); + $booking_currency_average_rate = $booking_amount / $paymentAmount; + $total_service_charge = $booking->transactions() ->where('type', TransactionType::PAYMENT) ->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED]) @@ -160,6 +181,11 @@ class CreateProformaInvoiceTransactionProcessor ->whereIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED]) ->sum('tax'); + // delete prev proforma transactions + $booking->transactions() + ->where('type', TransactionType::PROFORMA) + ->delete(); + $transaction_object = new TransactionObject( $billNumber, TransactionType::PROFORMA, @@ -178,14 +204,14 @@ class CreateProformaInvoiceTransactionProcessor ApprovalStatus::APPROVED ); - $perofrma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object); + $proforma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object); $supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]); - $purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $perofrma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]); + $purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $proforma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]); $document_object = new DocumentObject( DocumentType::PROFORMA_INVOICE, - [chunk_split('data:application/pdf;base64,'.base64_encode($purchase_order_pdf->output()))], + [chunk_split('data:application/pdf;base64,' . base64_encode($purchase_order_pdf->output()))], '', ApprovalStatus::COMPLETED, 'proforma_invoices' @@ -194,7 +220,5 @@ class CreateProformaInvoiceTransactionProcessor /** @var Document $document */ $document = $this->createsDocument->execute($po_order_transaction->booking, $document_object); $this->createsFile->execute($document, $document_object); - - } } diff --git a/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php b/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php index 5c85895a..e345ebcf 100644 --- a/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php +++ b/app/Classes/Modules/Vouchers/ControllersLogic/CreateVoucherLogic.php @@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher; use App\Classes\Modules\Vouchers\Services\Voucherify\CreatesVoucherifyVoucherInACampaign; use App\Classes\Modules\Vouchers\Services\Voucherify\ListsVoucherifyVouchers; use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyCampaign; +use App\Classes\Modules\Vouchers\Processors\Voucherify\NewCustomerToVoucherifyProcessor; use App\Classes\Modules\Vouchers\Services\CreatesVoucher; use App\Classes\Modules\Vouchers\Services\FetchesVoucher; use App\Classes\Modules\Vouchers\Services\UpdatesVoucherCampaign; @@ -75,6 +76,9 @@ class CreateVoucherLogic extends AbstractControllerLogic /** @var UpdatesVoucherCampaign */ private $updatesVoucherCampaign; + /** @var NewCustomerToVoucherifyProcessor */ + private $newCustomerToVoucherifyProcessor; + /** * CreateVoucherLogic constructor. * @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher @@ -87,8 +91,9 @@ class CreateVoucherLogic extends AbstractControllerLogic * @param CreatesKeyValuePair $createsKeyValuePair * @param UpdatesKeyValuePair $updatesKeyValuePair * @param UpdatesVoucherCampaign $updatesVoucherCampaign + * @param NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor */ - public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign) + public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor) { $this->createsUserReward = $createsUserReward; $this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher; @@ -100,6 +105,7 @@ class CreateVoucherLogic extends AbstractControllerLogic $this->createsKeyValuePair = $createsKeyValuePair; $this->updatesKeyValuePair = $updatesKeyValuePair; $this->updatesVoucherCampaign = $updatesVoucherCampaign; + $this->newCustomerToVoucherifyProcessor = $newCustomerToVoucherifyProcessor; } /** @@ -129,6 +135,12 @@ class CreateVoucherLogic extends AbstractControllerLogic $user = $userParam ? $userParam : $user; } + //Voucherify - To check if user exist at Voucherify, create if not exist + $voucherify_entity = $user->voucherifyEntities()->first(); + if(!$voucherify_entity){ + $this->newCustomerToVoucherifyProcessor->execute($user->company()->first()->id, $user, false); + } + //Voucherify - creates new voucher at voucherify if ($voucherCodeInput === Vouchers::SORRY_50 || $voucherCodeInput === Vouchers::SORRY_100 || $voucherCodeInput === Vouchers::SORRY_200 ) { $result = $this->newVoucherifyVoucherIssuanceHandler($voucherCodeInput); diff --git a/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php b/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php index 30e7fe12..4530292f 100644 --- a/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php +++ b/app/Classes/Modules/Vouchers/ControllersLogic/ValidateVoucherLogic.php @@ -10,6 +10,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherOb use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Models\Booking; +use Illuminate\Support\Facades\Log; class ValidateVoucherLogic extends AbstractControllerLogic { @@ -42,11 +43,27 @@ class ValidateVoucherLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + $employeeWhoOwnsTheVoucher = null; $booking = Booking::find($request->input('itemId')); - $employee = $booking->company->employees()->first(); + $employees = $booking->company->employees()->get(); + + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $request->input('voucherCode')) { + Log::info('2. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $request->input('voucherCode')); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $booking->company->employees()->first(); + } + $amount = $this->floatvalue($request->input('amount')); - $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employee); + $validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employeeWhoOwnsTheVoucher); $result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject); return $this->response(['data' => $result]); } diff --git a/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php b/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php index 9678dafe..e61d1d00 100644 --- a/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php +++ b/app/Classes/Modules/Vouchers/DataTransferObjects/CreateVoucherifyCustomerObject.php @@ -65,9 +65,9 @@ class CreateVoucherifyCustomerObject implements DataTransferObject */ public function getAcquisitionChannel(): string { - if(!$this->isNew){ - return ""; - } + // if(!$this->isNew){ + // return ""; + // } return $this->acquisitionChannel; } diff --git a/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php b/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php index b48bee16..956afc00 100644 --- a/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php +++ b/app/Classes/Modules/Vouchers/DataTransferObjects/ValidateVoucherifyVoucherObject.php @@ -17,8 +17,8 @@ class ValidateVoucherifyVoucherObject implements DataTransferObject /** @var float */ private $amount; - /** @var User */ - private $user; + /** @var User */ + private $user; //this will affect certain voucher that limit user redemption e.g. one user one redemption per campaign /** * ValidateVoucherifyVoucherObject constructor. diff --git a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php index dd17e76c..90fba55a 100644 --- a/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php +++ b/app/Classes/Modules/Vouchers/Processors/Voucherify/BookingToVoucherifyProcessor.php @@ -18,6 +18,7 @@ use App\Classes\ValueObjects\Constants\VoucherifyEntityType; use App\Models\User; use App\Models\Transaction; use App\Models\Voucher; +use App\Models\VoucherCampaign; use Illuminate\Support\Facades\Log; class BookingToVoucherifyProcessor @@ -82,7 +83,24 @@ class BookingToVoucherifyProcessor $voucherify_customer_id = ""; $voucherify_order_id = ""; if($voucherCode){ - $redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $user); + $employeeWhoOwnsTheVoucher = null; + + $employees = $user->company()->first()->employees; + foreach($employees as $singleEmployee){ + $userRewards = $singleEmployee->rewards; + foreach($userRewards as $userReward){ + if ($userReward->voucher && $userReward->voucher->code === $voucherCode) { + Log::info('3. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode); + $employeeWhoOwnsTheVoucher = $singleEmployee; + } + } + } + + if(!$employeeWhoOwnsTheVoucher){ + $employeeWhoOwnsTheVoucher = $user; + } + + $redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $employeeWhoOwnsTheVoucher); $redeemVoucherResult = $this->redeemsVoucherifyVoucher->execute($redeemVoucherifyVoucherObject); // Log::info('redeemVoucherResult: '.json_encode($redeemVoucherResult)); @@ -98,9 +116,9 @@ class BookingToVoucherifyProcessor $voucherify_customer_id = $redeemVoucherResult->customer->id; } - $voucher = $this->recordVoucherInfo($redeemedVoucher, $transaction); + $voucher = $this->recordVoucherInfo($redeemedVoucher); $this->createsVoucherRedemption->execute($transaction, $voucher, $redemptionId, $voucherDiscountAmount); - $this->recordVoucherForUserInfo($user, $voucher); + $this->recordVoucherForUserInfo($employeeWhoOwnsTheVoucher, $voucher); } else{ $createVoucherifyOrderObject = new CreateVoucherifyOrderObject($user, $companyId, $transaction->id, $amount, true, $transaction->type == TransactionType::TOP_UP); @@ -126,9 +144,14 @@ class BookingToVoucherifyProcessor //Create records at 3 tables $voucherValue = isset($redeemedVoucher->discount->amount_off) ? $redeemedVoucher->discount->amount_off : $redeemedVoucher->discount->percent_off; $voucherType = $redeemedVoucher->discount ? $redeemedVoucher->discount->type : null; - $voucherCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null; + $voucherifyCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null; - $voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->name) ? $redeemedVoucher->metadata->name : "", $voucherType, $voucherValue, $voucherCampaignId); + $voucherCampaign = null; + if($voucherifyCampaignId){ + $voucherCampaign = VoucherCampaign::where('campaign_id', $voucherifyCampaignId)->first(); + } + + $voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->displayname) ? $redeemedVoucher->metadata->displayname : "", $voucherType, $voucherValue, $voucherCampaign ? $voucherCampaign->id : null); $voucher = $this->createsVoucher->execute($voucherObject); if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]); diff --git a/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php b/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php index 006bcd94..3fd2ccee 100644 --- a/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php +++ b/app/Classes/Modules/Vouchers/Processors/Voucherify/NewCustomerToVoucherifyProcessor.php @@ -44,7 +44,9 @@ class NewCustomerToVoucherifyProcessor $createVoucherifyCustomerObject = new CreateVoucherifyCustomerObject($companyId, $user, $isNew); $result = $this->createsVoucherifyCustomer->execute($createVoucherifyCustomerObject); - if($result && isset($result->id)){ + $voucherify_entity = $user->voucherifyEntities()->get(); + + if($result && isset($result->id) && count($voucherify_entity) === 0){ $voucherEntityObject = new VoucherEntityObject($result->id, VoucherifyEntityType::CUSTOMER); $this->createsVoucherEntityMapping->execute($createVoucherifyCustomerObject->getUser(), $voucherEntityObject); } diff --git a/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php b/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php new file mode 100644 index 00000000..03966926 --- /dev/null +++ b/app/Classes/Modules/Vouchers/Services/Voucherify/FetchesVoucherifyRedemption.php @@ -0,0 +1,38 @@ +voucherifyClient = createVoucherifyClient(); + } + + /** + * @param string $redemptionId + * @return null|object + * @throws \Voucherify\ClientException + */ + public function execute(string $redemptionId) + { + try { + $result = $this->voucherifyClient->redemptions->get($redemptionId); + return $result; + } catch (\Voucherify\ClientException $e) { + Log::error('FetchesVoucherifyRedemption '.$e); + return null; + } + } +} diff --git a/app/Console/Commands/UpdateWrongGroupCurrencyRate.php b/app/Console/Commands/UpdateWrongGroupCurrencyRate.php new file mode 100644 index 00000000..fbe7245b --- /dev/null +++ b/app/Console/Commands/UpdateWrongGroupCurrencyRate.php @@ -0,0 +1,126 @@ +createsDocument = $createsDocument; + $this->createsFile = $createsFile; + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $groups = Group::where('currency_rate', '>', 100)->get(); + + foreach ($groups as $group) { + $transactions = $group->transactions()->get(); + + $rate = DB::table('transaction_logs')->where('transaction_id', $transactions->first()->id)->latest('updated_at')->first()->currency_rate; + + $supplier = $group->issuerCompany; + + foreach ($transactions as $transaction) { + $transaction->currency_rate = $rate; + $transaction->amount = $transaction->original_amount / $rate; + $transaction->save(); + + $supplierRefundTransactions = $transaction->owner->transactions()->supplierRefunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->get(); + + foreach ($supplierRefundTransactions as $supplierRefundTransaction) { + $claimBefore = $supplierRefundTransaction->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->exists(); + + if (!$claimBefore) { + $supplierRefundTransaction->currency_rate = $rate; + $supplierRefundTransaction->amount = $supplierRefundTransaction->original_amount / $rate; + $supplierRefundTransaction->save(); + } + } + } + + $group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first(); + + $group_transfer_fee_original_amount = 0; + + if ($group_transfer_fee) { + $group_transfer_fee_original_amount = $group_transfer_fee->original_amount; + } + + $transferFeeTransactions = $group->transactions()->with([ + 'transactions' => function ($transaction) { + return $transaction->where('type', TransactionType::TRANSFER_FEE); + } + ])->get()->pluck('transactions')->flatten(); + + $group->original_amount = $group->transactions()->sum('original_amount') + ((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount); + $group->amount = $group->transactions()->sum('amount') + (((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount) / $rate) + $group->transactions()->sum('service_charge'); + $group->currency_rate = $rate; + $group->tax = $group->transactions()->sum('tax'); + $group->service_charge = $group->transactions()->sum('service_charge'); + + $group->save(); + + $group->documents()->delete(); + + $pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $group->transactions, 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier, 'groupTransferFeeOriginalAmount' => $group_transfer_fee_original_amount]); + + $object = new DocumentObject( + DocumentType::CURRENCY_VENDOR_ORDER, + [chunk_split('data:application/pdf;base64,' . base64_encode($pdf->output()))], + '', + ApprovalStatus::COMPLETED, + 'currency_vendor_order' + ); + + /** @var Document $document */ + $document = $this->createsDocument->execute($group, $object); + $this->createsFile->execute($document, $object); + + $this->info("Group ID: {$group->id} updated to currency rate {$rate}"); + } + } +} diff --git a/app/Http/Controllers/Banks/UpdateBankMetadataController.php b/app/Http/Controllers/Banks/UpdateBankMetadataController.php new file mode 100644 index 00000000..3b89c1ff --- /dev/null +++ b/app/Http/Controllers/Banks/UpdateBankMetadataController.php @@ -0,0 +1,19 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php new file mode 100644 index 00000000..670db6da --- /dev/null +++ b/app/Http/Controllers/Bookings/UpdateBookingRecipientController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} diff --git a/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php b/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php new file mode 100644 index 00000000..0940ce49 --- /dev/null +++ b/app/Http/Controllers/Transactions/DeleteRefundTransactionController.php @@ -0,0 +1,14 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index a8103e8b..82b4cf3e 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -56,7 +56,7 @@ class CompanyResource extends JsonResource 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', 'personal_banks' => BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), 'recipient_banks' => [ - 'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])), + 'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])->whereIn('creator_type', [null])), 'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) ], 'segments' => SegmentResource::collection($this->segments), diff --git a/app/Http/Resources/ListTransactionJobResource.php b/app/Http/Resources/ListTransactionJobResource.php index 6c4c0ece..1547c09e 100644 --- a/app/Http/Resources/ListTransactionJobResource.php +++ b/app/Http/Resources/ListTransactionJobResource.php @@ -16,8 +16,18 @@ class ListTransactionJobResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank ?? $booking->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank ?? $booking->bank; + } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ @@ -27,7 +37,7 @@ class ListTransactionJobResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, diff --git a/app/Http/Resources/PaymentTransactionResource.php b/app/Http/Resources/PaymentTransactionResource.php index 456ece3d..01da84b2 100644 --- a/app/Http/Resources/PaymentTransactionResource.php +++ b/app/Http/Resources/PaymentTransactionResource.php @@ -18,8 +18,18 @@ class PaymentTransactionResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank ?? $booking->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank ?? $booking->bank; + } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $booking_marking = ''; switch ($this->owner_type) { @@ -38,7 +48,7 @@ class PaymentTransactionResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) $this->amount, diff --git a/app/Http/Resources/TransactionResource.php b/app/Http/Resources/TransactionResource.php index d259d777..e14c32c0 100644 --- a/app/Http/Resources/TransactionResource.php +++ b/app/Http/Resources/TransactionResource.php @@ -19,8 +19,18 @@ class TransactionResource extends JsonResource */ public function toArray($request) { - - $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])? $this->owner->owner : $this->owner; + $booking = null; //cief todo: 66 + $bank = null; + //Check if Transaction of type PAYMENT has an override for recipient bank - starts + if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){ + $booking = $this->owner->owner; + $bank = $this->owner->bank ?? $booking->bank; + } + else{ + $booking = $this->owner; + $bank = $this->bank ?? $booking->bank; + } + //Check if Transaction of type PAYMENT has an override for recipient bank - ends $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1); return [ @@ -30,7 +40,7 @@ class TransactionResource extends JsonResource 'bill_no' => $this->bill_no, 'payment_reference' => $this->payment_reference, 'payment_method' => (float) $this->payment_method, - 'recipient_bank_account' => new BankResource($booking->bank), + 'recipient_bank_account' => new BankResource($bank), 'issuer_name' => $this->issuerCompany->name, 'issuer_id' => $this->issuerCompany->id, 'amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('amount') : $this->amount), @@ -54,7 +64,8 @@ class TransactionResource extends JsonResource 'duration' => $days->diff(Carbon::now())->format('%d'), ], 'remarks' => RemarkResource::collection($this->remarks), - 'redemption' => new VoucherRedemptionResource($this->voucherRedemption) + 'redemption' => new VoucherRedemptionResource($this->voucherRedemption), + 'bank' => ((int) $this->type === TransactionType::PAYMENT) ? new BankResource($bank) : null, //When a transaction (of type payment) has an override recipient bank details on booking, this is NOT null ]; } } diff --git a/app/Http/Resources/V2/CompanyV2Resource.php b/app/Http/Resources/V2/CompanyV2Resource.php index 64fca7c7..3f2cb4c2 100644 --- a/app/Http/Resources/V2/CompanyV2Resource.php +++ b/app/Http/Resources/V2/CompanyV2Resource.php @@ -82,7 +82,7 @@ class CompanyV2Resource extends JsonResource 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', 'personal_banks' => V1\BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), 'recipient_banks' => [ - 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)), + 'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)->whereIn('creator_type', [null])), 'default' => new V1\BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first()) ], 'segments' => V1\SegmentResource::collection($this->segments), diff --git a/app/Http/Resources/VoucherResource.php b/app/Http/Resources/VoucherResource.php index 3f3112bb..55cc2b56 100644 --- a/app/Http/Resources/VoucherResource.php +++ b/app/Http/Resources/VoucherResource.php @@ -4,6 +4,7 @@ namespace App\Http\Resources; use ArrayObject; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Facades\Log; class VoucherResource extends JsonResource { @@ -16,7 +17,8 @@ class VoucherResource extends JsonResource public function toArray($request) { $filteredRedemptions = new ArrayObject([]); - if ($request->has('filters') && str_contains($request->input('filters'), "has_active_reward")) { + if ($request->has('filters') && (str_contains($request->input('filters'), "has_vouchers_all_with_user") )) { + //|| str_contains($request->input('filters'), "has_vouchers_all_with_company") $filteredRedemptions = new ArrayObject([]); } else{ diff --git a/app/Models/Bank.php b/app/Models/Bank.php index 3b0bb915..42cdf3df 100644 --- a/app/Models/Bank.php +++ b/app/Models/Bank.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\MorphMany; +use App\Classes\General\Interfaces\KeyValueInterface; /** * Class Bank @@ -21,10 +23,29 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property int default * @property int status */ -class Bank extends AbstractModel +class Bank extends AbstractModel implements KeyValueInterface { use SoftDeletes; - + + /** + * + * @var array + */ + protected $fillable = [ + 'company_id', + 'reference', + 'bank_name', + 'holder_name', + 'account_no', + 'bank_branch', + 'swift', + 'snap', + 'type', + 'country_id', + 'created_by', + 'creator_type', + ]; + protected $table = 'banks'; /** @@ -42,7 +63,7 @@ class Bank extends AbstractModel { return $this->BelongsTo(Company::class, 'company_id', 'id'); } - + /** * @return HasMany */ @@ -50,4 +71,12 @@ class Bank extends AbstractModel { return $this->HasMany(Transaction::class, 'recipient_bank_account_id'); } + + /** + * @return MorphMany + */ + public function attributesKVP(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } } diff --git a/app/Models/KeyValuePair.php b/app/Models/KeyValuePair.php index 3ad6d6cd..8f8ddec8 100644 --- a/app/Models/KeyValuePair.php +++ b/app/Models/KeyValuePair.php @@ -2,10 +2,14 @@ namespace App\Models; use Illuminate\Database\Eloquent\Relations\MorphTo; - +use Illuminate\Database\Eloquent\SoftDeletes; class KeyValuePair extends AbstractModel { + use SoftDeletes; + + protected $dates = ['deleted_at']; + protected $table = 'key_value_pairs'; public function owner(): MorphTo diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index 31b67e69..c84c0238 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Classes\General\Interfaces\Documentable; +use App\Classes\General\Interfaces\KeyValueInterface; use App\Classes\General\Interfaces\Remarkable; use App\Classes\General\Interfaces\Transactionable; use App\Classes\General\Interfaces\Voucherifiable; @@ -22,7 +23,7 @@ use Staudenmeir\EloquentHasManyDeep\HasTableAlias; use App\Models\StatementTransactionOwner; -class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable +class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable, KeyValueInterface { use HasTableAlias; use SoftDeletes; @@ -268,4 +269,25 @@ class Transaction extends AbstractModel implements Documentable, Transactionable return $this->morphMany(Remark::class, 'owner'); } + /** + * @return MorphMany + */ + public function attributesKVP(): MorphMany + { + return $this->morphMany(KeyValuePair::class, 'owner'); + } + + /** + * + * @return Model|null + */ + public function getBankAttribute() + { + $keyValuePairs = $this->attributesKVP()->where('key', 'App\Models\Bank')->latest()->first(); + if($keyValuePairs){ + $bank = Bank::where('id', $keyValuePairs->value)->first(); + return $bank; + } + return null; + } } diff --git a/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php b/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php new file mode 100644 index 00000000..1d99906f --- /dev/null +++ b/database/migrations/2024_07_25_205651_add_created_by_and_creator_type_to_banks_table.php @@ -0,0 +1,35 @@ +unsignedBigInteger('created_by')->nullable()->after('country_id'); + $table->unsignedInteger('creator_type')->nullable()->after('created_by'); // 'admin' or 'customer', see RoleTypes.php for more + $table->foreign('created_by')->references('id')->on('users')->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('banks', function (Blueprint $table) { + $table->dropForeign(['created_by']); + $table->dropColumn(['created_by', 'creator_type']); + }); + } +} diff --git a/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php b/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php new file mode 100644 index 00000000..df64b4a8 --- /dev/null +++ b/database/migrations/2024_07_31_212359_add_deleted_at_to_key_value_pairs.php @@ -0,0 +1,32 @@ +softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('key_value_pairs', function (Blueprint $table) { + $table->dropSoftDeletes(); + }); + } +} diff --git a/database/seeds/AdminUserPermissionsTableSeeder.php b/database/seeds/AdminUserPermissionsTableSeeder.php index aa47596d..ee86dc8a 100644 --- a/database/seeds/AdminUserPermissionsTableSeeder.php +++ b/database/seeds/AdminUserPermissionsTableSeeder.php @@ -73,6 +73,8 @@ class AdminUserPermissionsTableSeeder extends Seeder ['name' => 'add voucher', 'guard_name' => 'web'], ['name' => 'list voucher campaigns', 'guard_name' => 'web'], + + ['name' => 'update bank_metadata', 'guard_name' => 'web'], ]; foreach ($permissions as $permission){ diff --git a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue index 17be80c6..3bf4f46a 100644 --- a/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue +++ b/resources/assets/vue/components/banks/forms/BankAccountFormComponent.vue @@ -133,12 +133,15 @@
{{ isEditRecipientBankDetailsCollapsed ? '< Back' : 'Change recipient bank details' }}
{{ isEditRecipientBankDetailsCollapsed ? '< Back' : 'Show edited recipient bank details on payment' }}
| No | -Stock Code | -Description | -Quantity | -Unit Price (RM) | -Total Amount (RM) |
-
|---|---|---|---|---|---|
| {{ $key + 1 }} | -{{ $transaction_detail->product_code }} | -{{ $transaction_detail->product_name }} | -{{ $transaction_detail->quantity }} | -- @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2) }} - @else - {{ number_format($transaction_detail->price, 2) }} - @endif - | -- @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) + - {{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }} + + @include('pages.pdfs.purchase_order_table') - @php - $subtotal += number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.',''); - @endphp - @else - {{ number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }} - - @php - $subtotal += number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.',''); - @endphp - @endif - | -
| - | Subtotal | -- {{ number_format($subtotal, 2) }} - | -|||
| - | Service Charges | -- {{ number_format($invoice_transaction->service_charge, 2) }} - | -|||
| - | Adjustment | -- @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }} - @else - {{ number_format((float)number_format($invoice_transaction->amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }} - @endif - | -|||
| - | Tax | -{{ number_format($invoice_transaction->tax, 2) }} | -|||
| - | Total | -- @if($invoice_transaction->booking()->first()->fix_currency_id !== 1) - {{ number_format( ((1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount) + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }} - @else - {{ number_format($invoice_transaction->amount + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }} - @endif - | -|||
| '.$payment->updated_at->format('d-M-y').' | '; + echo ''.$booking->marking.' | '; echo ''.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].' | '; - echo ''.$booking->company->reference.' | '; echo ''.$payment->currency->short_code.' | '; echo ''.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').' | '; - echo ''.$booking->marking.' | '; + echo ''.$booking->company->reference.' | '; echo ''; echo ' | '.$payment->original_currency->short_code.' | '; echo ''.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').' | '; @@ -510,14 +512,16 @@ Route::get('/approve_refunds', function(Request $request){ foreach ($approve_refunds->orderBy('created_at', 'DESC')->get() as $index => $refund){ $payment = $refund->owner; $booking = $refund->owner->owner; + $bank = $payment->bank ?? $booking->bank; //cief todo: 66 + if(!$booking instanceof Booking){ dd($refund); } - $bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str::length($bank->holder_name) > 4 ? 'Company' : 'Personal'; - if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name)) + if (!preg_match('/[^A-Za-z0-9]/', $bank->holder_name)) { - $bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal'; + $bankType = str_word_count($bank->holder_name) > 4 ? 'Company' : 'Personal'; } $remark = $refund->original_amount === $refund->owner->original_amount ? 'Fully Refund' : 'Partial Refund'; @@ -546,7 +550,7 @@ Route::get('/approve_refunds', function(Request $request){ echo ''.$booking->service->name.' | '; echo ''.$payment->updated_at->diffForHumans().' | '; echo ''.$bankType.' | '; - echo ''.$booking->bank->holder_name.' | '; + echo ''.$bank->holder_name.' | '; echo ''.$noteRemark.' | '; echo '
| $result->owner_type | "; echo "$result->owner_id | "; @@ -1205,7 +1211,7 @@ Route::get('check-duplicate-refunds', function () { echo "" . ($refund ? $refund : '') . " | "; echo '