diff --git a/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php new file mode 100644 index 00000000..ed9ec6d8 --- /dev/null +++ b/app/Classes/Modules/Bookings/ControllersLogic/AutoPurchaseOrderFillLogic.php @@ -0,0 +1,113 @@ +generatesPurchaseOrderProducts = $generatesPurchaseOrderProducts; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } + + + /** + * @return array + */ + protected function notification():array { + return [ + 'title' => 'Purchase Order Approval', + 'message' => 'You have successfully updated the Purchase order status' + ]; + } + + /** @var GeneratesPurchaseOrderProducts */ + private $generatesPurchaseOrderProducts; + + /** @var GeneratesTransactionBillNumber */ + private $generatesTransactionBillNumber; + + /** @var CreatePurchaseOrderTransactionProcessor */ + private $createPurchaseOrderTransactionProcessor; + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $bookings = Booking::whereMonth('created_at', 7) + ->whereYear('created_at', 2021) + ->whereDoesntHave('transactions', function($q){ + $q->where('type', TransactionType::PURCHASE_ORDER); + $q->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]); + })->get(); + foreach ($bookings as $booking) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id) + ->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + + + if (!$po) { + $po = Transaction::where('type', TransactionType::PURCHASE_ORDER) + ->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first(); + } + + $products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount); + + $deference = $booking->fix_amount - $products->sum('total'); + + if($deference > -150 && $deference < 150 && $deference != 0) { + + $products->push([ + 'description' => $deference < 0 ? 'Discount':'Shipping Fee', + 'quantity' => 1, + 'stockCode' => '', + 'total' => $deference, + 'unit_price' => $deference + ]); + } + + $billNumber = $this->generatesTransactionBillNumber->execute('XPO-'); + + $total = $products->sum('total'); + + $object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1, + 1, PaymentMethodType::CASH, + $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, + 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray()); + + $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); + } + + return $this->response([]); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Exports/Services/ExportsProducts.php b/app/Classes/Modules/Exports/Services/ExportsProducts.php new file mode 100644 index 00000000..541f1d21 --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsProducts.php @@ -0,0 +1,51 @@ +whereHas('transaction', function($query){ + return $query->where('type', \App\Classes\ValueObjects\Constants\TransactionType::PURCHASE_ORDER)->where('status', ApprovalStatus::APPROVED); + })->limit(50); + } + + /** + * @param $product + * @return array + */ + public function map($product): array + { + + return [ + $product->product_code, + $product->product_name, + $product->price, + ]; + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php index aa4c6f4d..9bab107f 100644 --- a/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php +++ b/app/Classes/Modules/Transactions/ControllersLogic/CreatePurchaseOrderTransactionLogic.php @@ -7,6 +7,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic; use App\Classes\Modules\Bookings\Services\FetchesBooking; use App\Classes\Modules\Companies\Services\FetchesCompany; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; +use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor; use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail; use App\Classes\Modules\Transactions\Services\DeletesTransactionDetails; @@ -25,26 +26,6 @@ use Illuminate\Http\Request; class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic { - /** - * CreatePurchaseOrderTransactionLogic constructor. - * @param FetchesBooking $fetchesBooking - * @param UpdatesTransactionStatus $updatesTransactionStatus - * @param CreatesTransaction $createsTransaction - * @param CreatesTransactionDetail $createsTransactionDetail - * @param UpdatesTransaction $updatesTransaction - * @param DeletesTransactionDetails $deletesTransactionDetails - * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber - */ - public function __construct(FetchesBooking $fetchesBooking, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, DeletesTransactionDetails $deletesTransactionDetails, GeneratesTransactionBillNumber $generatesTransactionBillNumber) - { - $this->fetchesBooking = $fetchesBooking; - $this->updatesTransactionStatus = $updatesTransactionStatus; - $this->createsTransaction = $createsTransaction; - $this->createsTransactionDetail = $createsTransactionDetail; - $this->updatesTransaction = $updatesTransaction; - $this->deletesTransactionDetails = $deletesTransactionDetails; - $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; - } /** * @return array @@ -59,37 +40,35 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic /** @var FetchesBooking */ private $fetchesBooking; - /** @var UpdatesTransactionStatus */ - private $updatesTransactionStatus; - - /** @var CreatesTransaction */ - private $createsTransaction; - - /** @var CreatesTransactionDetail */ - private $createsTransactionDetail; - - /** @var UpdatesTransaction */ - private $updatesTransaction; - - /** @var DeletesTransactionDetails */ - private $deletesTransactionDetails; - /** @var GeneratesTransactionBillNumber */ private $generatesTransactionBillNumber; + /** @var CreatePurchaseOrderTransactionProcessor */ + private $createPurchaseOrderTransactionProcessor; + + /** + * CreatePurchaseOrderTransactionLogic constructor. + * @param FetchesBooking $fetchesBooking + * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber + * @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor + */ + public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor) + { + $this->fetchesBooking = $fetchesBooking; + $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; + $this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor; + } /** * @param Request $request + * @param string $id * @return JsonResponse * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function logic(Request $request) : JsonResponse + public function logic(Request $request, $id = '') : JsonResponse { /** @var Booking $booking */ - $booking = $this->fetchesBooking->execute(['id' => $request->route('id')]); - - /** @var Transaction $transaction */ - $transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); + $booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]); $billNumber = $this->generatesTransactionBillNumber->execute('PO-'); @@ -102,15 +81,8 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic $total, $total, $booking->fix_currency_id, $booking->fix_currency_id, 1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $request->input('products')); - !$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object); - $this->updatesTransactionStatus->execute($transaction, (float) number_format($total, 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); - - $this->deletesTransactionDetails->execute($transaction); - - foreach ($object->getDetails() as $product){ - $this->createsTransactionDetail->execute($transaction, $product); - } + $transaction = $this->createPurchaseOrderTransactionProcessor->execute($booking, $object); return $this->resourceResponse(new TransactionResource($transaction)); diff --git a/app/Classes/Modules/Transactions/ControllersLogic/UpdatePaymentTransactionStatusLogic.php b/app/Classes/Modules/Transactions/ControllersLogic/UpdatePaymentTransactionStatusLogic.php new file mode 100644 index 00000000..11f0a377 --- /dev/null +++ b/app/Classes/Modules/Transactions/ControllersLogic/UpdatePaymentTransactionStatusLogic.php @@ -0,0 +1,76 @@ + 'Updated Transaction', + 'message' => 'You have successfully updated a transaction' + ]; + } + + /** @var FetchesTransaction */ + private $fetchesTransaction; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + /** @var DeletesDocument */ + private $deletesDocument; + + /** + * CreatePaymentVerificationDocumentLogic constructor. + * @param FetchesTransaction $fetchesTransaction + * @param UpdatesTransactionStatus $updatesTransactionStatus + * @param DeletesDocument $deletesDocument + */ + public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument) + { + $this->fetchesTransaction = $fetchesTransaction; + $this->updatesTransactionStatus = $updatesTransactionStatus; + $this->deletesDocument = $deletesDocument; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request) : JsonResponse + { + $transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]); + $status = $request->route('status'); + + $this->updatesTransactionStatus->execute($transaction, $status === 'pending' ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::COMPLETED); + + if ($status == 'pending') { + $document = $transaction->documents()->first(); + if ($document) { + $this->deletesDocument->execute($document); + } + } + + return $this->response([]); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php b/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php new file mode 100644 index 00000000..76773c75 --- /dev/null +++ b/app/Classes/Modules/Transactions/Processors/CreatePurchaseOrderTransactionProcessor.php @@ -0,0 +1,76 @@ +updatesTransactionStatus = $updatesTransactionStatus; + $this->createsTransaction = $createsTransaction; + $this->createsTransactionDetail = $createsTransactionDetail; + $this->updatesTransaction = $updatesTransaction; + $this->deletesTransactionDetails = $deletesTransactionDetails; + } + + + /** + * @param Booking $booking + * @param TransactionObject $object + * @return Transaction|\Illuminate\Database\Eloquent\Model + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function execute(Booking $booking, TransactionObject $object){ + /** @var Transaction $transaction */ + $transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(); + + !$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object); + + $this->updatesTransactionStatus->execute($transaction, (float) number_format($object->getAmount(), 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION); + + $this->deletesTransactionDetails->execute($transaction); + + foreach ($object->getDetails() as $product){ + $this->createsTransactionDetail->execute($transaction, $product); + } + + return $transaction; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php b/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php new file mode 100644 index 00000000..16d162eb --- /dev/null +++ b/app/Classes/Modules/Transactions/Services/GeneratesPurchaseOrderProducts.php @@ -0,0 +1,72 @@ +products = $products; + } + + + public function execute(Transaction $transaction, float $amount){ + + $products = collect(); + + $amountDifference = $amount - $transaction->amount; + $transactionDetails = $transaction->transactionDetails()->select('*', DB::raw('abs(price - '.abs($amountDifference).') as nearest_price'))->orderBy('nearest_price')->get(); + foreach ($transactionDetails as $product) { + $units = floor(abs($amountDifference) / $product->price); + $quantity = $product->quantity; + + if($product->price <= 0){ + $amountDifference = $amountDifference + ($product->price * $product->quantity); + continue; + } + + if($amountDifference > 0){ + $quantity = $product->quantity + $units; + $amountDifference = $amountDifference - ($product->price * $units); + } + + if($amountDifference < 0) { + $units = ceil(abs($amountDifference) / $product->price); + $quantity = $product->quantity - $units; + + if($quantity <= 0){ + $amountDifference = $amountDifference + ($product->price * $product->quantity); + continue; + } + + $amountDifference = $amountDifference + ($product->price * $quantity); + } + + $products->push([ + 'description' => $product->product_name, + 'quantity' => (int) $quantity, + 'stockCode' => $product->product_code, + 'total' => $product->price * $quantity, + 'unit_price' => (float) $product->price, + ]); + + } + + return $products; + + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php b/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php new file mode 100644 index 00000000..c92900bd --- /dev/null +++ b/app/Http/Controllers/Bookings/AutoPurchaseOrderFillController.php @@ -0,0 +1,25 @@ +login(User::find(1)); + return $logic->execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Controllers/Transactions/UpdatePaymentTransactionStatusController.php b/app/Http/Controllers/Transactions/UpdatePaymentTransactionStatusController.php new file mode 100644 index 00000000..047bc1dc --- /dev/null +++ b/app/Http/Controllers/Transactions/UpdatePaymentTransactionStatusController.php @@ -0,0 +1,14 @@ +execute($request); + } +} \ No newline at end of file diff --git a/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg b/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg new file mode 100644 index 00000000..dd7ceda3 Binary files /dev/null and b/resources/assets/images/—Pngtree—2019 chinese new year lantern_951828.jpg differ diff --git a/resources/assets/vue/components/bookings/elements/PaymentProofComponent.vue b/resources/assets/vue/components/bookings/elements/PaymentProofComponent.vue index 494427cb..e197ab6a 100644 --- a/resources/assets/vue/components/bookings/elements/PaymentProofComponent.vue +++ b/resources/assets/vue/components/bookings/elements/PaymentProofComponent.vue @@ -41,6 +41,14 @@ +
+
+ Cancel this order? +
+
+ + + @@ -61,6 +69,20 @@ +
+ + + + + + + + +
diff --git a/resources/assets/vue/components/bookings/forms/ApprovePaymentTransactionFormComponent.vue b/resources/assets/vue/components/bookings/forms/ApprovePaymentTransactionFormComponent.vue new file mode 100644 index 00000000..7be579f2 --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/ApprovePaymentTransactionFormComponent.vue @@ -0,0 +1,33 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/forms/DeleteTransactionFormComponent.vue b/resources/assets/vue/components/bookings/forms/DeleteTransactionFormComponent.vue new file mode 100644 index 00000000..8ba13dba --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/DeleteTransactionFormComponent.vue @@ -0,0 +1,33 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/bookings/forms/RejectPaymentTransactionFormComponent.vue b/resources/assets/vue/components/bookings/forms/RejectPaymentTransactionFormComponent.vue new file mode 100644 index 00000000..ad43890c --- /dev/null +++ b/resources/assets/vue/components/bookings/forms/RejectPaymentTransactionFormComponent.vue @@ -0,0 +1,33 @@ + + \ No newline at end of file diff --git a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue index 09876b9b..85502c97 100644 --- a/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/CustomerProfileSectionComponent.vue @@ -139,6 +139,11 @@
+
+
+ +
+
diff --git a/resources/assets/vue/components/companies/sections/WalletBalanceComponent.vue b/resources/assets/vue/components/companies/sections/WalletBalanceComponent.vue new file mode 100644 index 00000000..dd100288 --- /dev/null +++ b/resources/assets/vue/components/companies/sections/WalletBalanceComponent.vue @@ -0,0 +1,104 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/companies/sections/customerDashboardSectionComponent.vue b/resources/assets/vue/components/companies/sections/customerDashboardSectionComponent.vue index 8d48fc7e..35b1d0a9 100644 --- a/resources/assets/vue/components/companies/sections/customerDashboardSectionComponent.vue +++ b/resources/assets/vue/components/companies/sections/customerDashboardSectionComponent.vue @@ -3,6 +3,40 @@
+
+
+
+
+
+
+
+
+
+
+
+

新年快乐!

+

CIEF祝您春节快乐,万事如意,财运亨通,虎虎生威!
在此想通知您公司复工日期如下 :-

+

客服团队 : 2022年2月7日

+

* 假期期间 Exchange 照常可以下单,人民币复工之后就可以安排汇款

+
+
+
+
+

Happy Chinese New Year!

+

CIEF wishes you a successful & prosperous Chinese New Year.. may your business prosper with every opportunity that comes your way.
We would like to also update you about our company's operation resume dates as below :-

+

Customer Service : 07 February 2022

+

* EXCHANGE bookings can be placed as usual during the holidays , RMB transfers will be arranged after operation resume.

+
+
+
+
+
+
+
+
+
+
+