diff --git a/app/Classes/Modules/Orders/ControllersLogic/CreateSupplierTaxRebateLogic.php b/app/Classes/Modules/Orders/ControllersLogic/CreateSupplierTaxRebateLogic.php new file mode 100644 index 00000000..e3eb1e2a --- /dev/null +++ b/app/Classes/Modules/Orders/ControllersLogic/CreateSupplierTaxRebateLogic.php @@ -0,0 +1,89 @@ + 'Create Supplier Tax Rebate', + 'message' => 'You have successfully created a Supplier Tax Rebate' + ]; + } + + /** @var RestoresOrder */ + private $restoresOrder; + + /** @var FetchesOrder */ + private $fetchesOrder; + + /** @var ChecksIfOrderNumberExists */ + private $checkIfOrderNumberExists; + + /** + * CancelOrderLogic constructor. + * @param RestoresOrder $restoresOrder + * @param FetchesOrder $fetchesOrder + */ + public function __construct(RestoresOrder $restoresOrder, FetchesOrder $fetchesOrder, ChecksIfOrderNumberExists $checkIfOrderNumberExists) + { + $this->restoresOrder = $restoresOrder; + $this->fetchesOrder = $fetchesOrder; + $this->checkIfOrderNumberExists = $checkIfOrderNumberExists; + } + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\MalformedRequestException + */ + public function logic(Request $request): JsonResponse + { + Log::info('finding order'); + + /** @var Order $order */ + $order = $this->fetchesOrder->execute(['id' => $request->route('id')]); + + Log::info('taxRebate'); + + $taxRebate = SupplierTaxRebate::create([ + 'order_id' => $order->id, + 'supplier_name' => $request->input('supplier_name'), + 'supplier_contact_number' => $request->input('supplier_contact_number'), + 'reference_number' => $this->generateUniqueReferenceNumber(), + ]); + + return $this->resourceResponse(new OrderResource($order)); + } + + public function generateUniqueReferenceNumber(?string $prefix = '', ?int $length = 9): string + { + Log::info('generating unique reference number'); + // regenerate new reference number until a new unique reference is found + do { + $reference = $prefix . rand((int)('1' . str_repeat('0', $length - 2) . '1'), (int) str_repeat('9', $length)); + } while ( + SupplierTaxRebate::where('reference_number', $reference)->exists() || $this->checkIfOrderNumberExists->execute($reference) + ); + + return $reference; + } +} diff --git a/app/Http/Controllers/Orders/CreateSupplierTaxRebateController.php b/app/Http/Controllers/Orders/CreateSupplierTaxRebateController.php new file mode 100644 index 00000000..7cd2ebdd --- /dev/null +++ b/app/Http/Controllers/Orders/CreateSupplierTaxRebateController.php @@ -0,0 +1,20 @@ +execute($request); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Orders/DownloadTaxRebateQrPdfController.php b/app/Http/Controllers/Orders/DownloadTaxRebateQrPdfController.php new file mode 100644 index 00000000..c91b056b --- /dev/null +++ b/app/Http/Controllers/Orders/DownloadTaxRebateQrPdfController.php @@ -0,0 +1,99 @@ +route('id')); + $deliveryAddress = $order->addresses()->where('status', ApprovalStatus::APPROVED)->first(); + $warehouse= $order->orderRoles()->where('role_id', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee; + + $warehouseAddress = $warehouse->addresses()->first(); + $warehouseContacts = $warehouse->contacts; + + $warehousePrefix = ''; + $deliveryPrefix = ''; + $customerMarking = ''; + $remark = $warehouse->remarks()->first(); + + if($warehouse->reference === WarehouseReferences::VT_GUANG_ZHOU || $warehouse->reference === WarehouseReferences::VT_YIWU) { + $customerMarking = $order->companyModule->connections()->first()->invitee_reference.'/'; + if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan') { + $deliveryPrefix = 'SB/'; + } + + if(strtolower($deliveryAddress->state->name) === 'sarawak') { + $deliveryPrefix = 'SRW/'; + } + } + + if($warehouse->reference === WarehouseReferences::YD_YIWU){ + $warehousePrefix = 'YW/'; + } + + if(in_array($warehouse->reference,[WarehouseReferences::YD_GUANG_ZHOU, WarehouseReferences::YD_GUANG_ZHOU_2, WarehouseReferences::YD_FS_EAST_MALAYSIA, WarehouseReferences::YD_FS_WEST_MALAYSIA])){ + $warehousePrefix = 'YD/'; + + if(strtolower($deliveryAddress->state->name) === 'sabah' || strtolower($deliveryAddress->state->name) === 'labuan' || in_array(strtolower($deliveryAddress->district->name), ['limbang', 'lawas'])) { + $warehousePrefix = 'KK/'; + } + + if(strtolower($deliveryAddress->state->name) === 'sarawak' && !in_array(strtolower($deliveryAddress->district->name), ['limbang', 'lawas'])) { + $warehousePrefix = 'KU/'; + } + + if(strtolower($deliveryAddress->state->name) === 'johor') { + $warehousePrefix = 'NX/'; + } + } + + // tax rebate data + $tax_rebate_refeerence = $request->query('tax_rebate_refeerence'); + $supplierTaxRebate = SupplierTaxRebate::where('reference_number', $tax_rebate_refeerence)->first(); + if (!$supplierTaxRebate) { + // If not found, throw an error + abort(404, 'Supplier Tax Rebate not found'); + } + + $data = [ + 'order' => $order, + 'marking' => $warehousePrefix.$deliveryPrefix.'CIEF/'.$customerMarking, + 'delivery_address' => $deliveryAddress, + 'warehouse_address' => $warehouseAddress, + 'warehouse_contacts' => $warehouseContacts, + 'remark' => $remark ? $remark->content : '', + 'supplierTaxRebate' => $supplierTaxRebate + ]; + + $pdf = LaravelMpdf::loadView('pdfs.tax_rebate_qr', $data, [], [ + 'title' => 'CIEF_ORDER_NO_'.$order->reference, + 'format' => 'A4-L', + 'orientation' => 'L', + 'margin_top' => '40px', + ]); + + $exportFileName = 'CIEF_ORDER_NO_'.$order->reference.'.pdf'; + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + $pdfContent = $pdf->output(); + return response([ 'src' => AWSS3Helper::S3PDF($exportFileName, $pdfContent) ]); + } + else{ + return $pdf->stream($exportFileName); + } + } + +} diff --git a/app/Http/Resources/OrderV2Resource.php b/app/Http/Resources/OrderV2Resource.php index 8b83d14f..4e5f751a 100644 --- a/app/Http/Resources/OrderV2Resource.php +++ b/app/Http/Resources/OrderV2Resource.php @@ -35,6 +35,7 @@ class OrderV2Resource extends JsonResource }), 'storages' => $this->storages ? $this->storages : null, //from middleware 'remarks' => RemarkResource::collection($this->remarks), + 'supplier_tax_rebate' => SupplierTaxRebateResource::collection($this->supplierTaxRebate), 'created_at' => $this->created_at->format('d-m-Y') ]; diff --git a/app/Http/Resources/SupplierTaxRebateResource.php b/app/Http/Resources/SupplierTaxRebateResource.php new file mode 100644 index 00000000..12e3ce8b --- /dev/null +++ b/app/Http/Resources/SupplierTaxRebateResource.php @@ -0,0 +1,28 @@ +id; + + return [ + 'id' => $this->id, + 'supplier_name' => $this->supplier_name, + 'supplier_contact_number' => $this->supplier_contact_number, + 'reference_number' => $this->reference_number, + 'created_at' => $this->created_at->format('d-m-Y'), + 'updated_at' => $this->updated_at->format('d-m-Y'), + ]; + } +} diff --git a/app/Models/Order.php b/app/Models/Order.php index 312cd244..e1c0da50 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -169,4 +169,13 @@ class Order extends AbstractModel implements Addressable, Packable, Remarkable, { return $this->hasManyDeep(Transaction::class, [PackingList::class], ['owner_id', 'owner_id'], ['id', 'id']); } + + /** + * @return HasMany + */ + public function supplierTaxRebate(): HasMany + { + return $this->HasMany(SupplierTaxRebate::class, 'order_id'); + } + } diff --git a/app/Models/SupplierTaxRebate.php b/app/Models/SupplierTaxRebate.php new file mode 100644 index 00000000..71a05b43 --- /dev/null +++ b/app/Models/SupplierTaxRebate.php @@ -0,0 +1,24 @@ +belongsTo(Order::class); + } +} diff --git a/config/qr.php b/config/qr.php index ec1c801f..cd2d2347 100644 --- a/config/qr.php +++ b/config/qr.php @@ -1,8 +1,9 @@ 'https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=', // not working - 'qr_code_img_url' => 'https://qrcode.tec-it.com/API/QRCode?data=', + // 'qr_code_img_url' => 'https://qrcode.tec-it.com/API/QRCode?data=', + 'qr_code_img_url' => 'https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=', // backup ]; diff --git a/database/migrations/2024_10_23_012847_create_supplier_qr_codes_table.php b/database/migrations/2024_10_23_012847_create_supplier_qr_codes_table.php new file mode 100644 index 00000000..da333897 --- /dev/null +++ b/database/migrations/2024_10_23_012847_create_supplier_qr_codes_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('order_id')->references('id')->on('orders')->onDelete('cascade'); + $table->string('supplier_name'); + $table->string('supplier_contact_number'); + $table->string('reference_number'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('supplier_tax_rebates'); + } +} diff --git a/resources/assets/vue/app.js b/resources/assets/vue/app.js index aa1668a2..4c75db1f 100644 --- a/resources/assets/vue/app.js +++ b/resources/assets/vue/app.js @@ -28,7 +28,7 @@ import Vapor from 'laravel-vapor'; window.Vapor = Vapor; // define global variable -Vue.prototype.$qr_code_img_url = 'https://qrcode.tec-it.com/API/QRCode?data='; +Vue.prototype.$qr_code_img_url = 'https://api.qrserver.com/v1/create-qr-code/?size=150x150&data='; /** Application Injections */ Vue.use(vuelidate); diff --git a/resources/assets/vue/components/orders/forms/TaxRebateQrCodeFormComponent.vue b/resources/assets/vue/components/orders/forms/TaxRebateQrCodeFormComponent.vue new file mode 100644 index 00000000..c1a86c45 --- /dev/null +++ b/resources/assets/vue/components/orders/forms/TaxRebateQrCodeFormComponent.vue @@ -0,0 +1,167 @@ + + + \ No newline at end of file diff --git a/resources/assets/vue/components/orders/sections/OrderProfileV2SectionComponent.vue b/resources/assets/vue/components/orders/sections/OrderProfileV2SectionComponent.vue index 8e4b9638..8f570d19 100644 --- a/resources/assets/vue/components/orders/sections/OrderProfileV2SectionComponent.vue +++ b/resources/assets/vue/components/orders/sections/OrderProfileV2SectionComponent.vue @@ -13,7 +13,7 @@
- +
@@ -138,6 +138,10 @@ +
Tax Rebate QR Code
+ + + diff --git a/resources/views/pdfs/tax_rebate_qr.blade.php b/resources/views/pdfs/tax_rebate_qr.blade.php new file mode 100644 index 00000000..7259e535 --- /dev/null +++ b/resources/views/pdfs/tax_rebate_qr.blade.php @@ -0,0 +1,65 @@ +@extends('layouts.base_pdf') + +@section('inner_content') + + +
+

Tax Rebate Order

+

供应商: {{$supplierTaxRebate['supplier_name']}}

+

联络号码: {{$supplierTaxRebate['supplier_contact_number']}}

+ +
+ + + + + + + + +
+ + + + + + + + + +
+ +
+

#{{$order->reference}}

+
+
+ + + + + + + + + +
+

{{$marking}}{{$order->reference}}

+
+

仓库地址:

+

{{$warehouse_address->state->name.' '.$warehouse_address->district->name.' '.$warehouse_address->street_one.' '.$warehouse_address->street_two}}

+

邮编:{{$warehouse_address->postcode}}

+

联系:@foreach($warehouse_contacts as $contact){{ $loop->first ? '' : ' / ' }}{{ $contact->phone.' '.$contact->reference }}@endforeach

+

{!! $remark !!}

+
+
+@endsection \ No newline at end of file diff --git a/routes/order.php b/routes/order.php index 27c67ec0..52ac0805 100644 --- a/routes/order.php +++ b/routes/order.php @@ -22,4 +22,7 @@ Route::group(['prefix' => 'order', 'as' => 'order.', 'namespace' => 'Orders'], f Route::put('/assign-remark/{id}', 'AssignOrderRemarkController@create')->name('assign.remark'); Route::get('/{id}/shipping-cost', 'ShippingCostController@calculate')->name('shipping.cost'); Route::get('/packages/{id}', 'FetchOrderPackagesController@fetch')->name('packages'); + + Route::post('/{id}/supplier-tax-rebate/create', 'CreateSupplierTaxRebateController@create')->name('tax_rebate.create'); + }); diff --git a/routes/web.php b/routes/web.php index 1e129201..44b4eacf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -299,6 +299,7 @@ Route::get('/deliveries/refresh', function(){ })->name('deliveries.refresh'); Route::get('/order/{id}/download', 'Orders\DownloadOrderQrPdfController@download')->name('order.qr.download'); +Route::get('/tax-rebate-order/{id}/download', 'Orders\DownloadTaxRebateQrPdfController@download')->name('order.taxt_rebate_qr.download'); Route::get('/report/customclearance/{orderid}', 'Reports\CustomcClearanceReportController@download')->name('report.customclearance');