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 @@
新年快乐!
+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.
+$123,123
+$123,123
+$123,123
+