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 @@
+
+ A Tax Rebate QR Code allows suppliers to claim tax rebates. List Of Tax Rebate QR Code
+
+
+
{{ i[field] }}
+ Are you sure you want to create a Tax Rebate QR Code?
+
We need some additional information for this
+ service.
+ Create Tax Rebate QR Code?
+
+
供应商: {{$supplierTaxRebate['supplier_name']}}
+联络号码: {{$supplierTaxRebate['supplier_contact_number']}}
+ +
+
|
+
+
|
+