app.component('v-configuration-search', {
template: '#v-configuration-search-template',
-
+
data() {
return {
isDropdownOpen: false,
@@ -169,7 +170,7 @@ class="p-4 text-sm font-semibold text-gray-600 dark:text-gray-300"
this.isDropdownOpen = true;
this.isLoading = true;
-
+
this.$axios.get("{{ route('admin.configuration.search') }}", {
params: {query: this.searchTerm}
})
diff --git a/packages/Webkul/Admin/src/Resources/views/products/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/products/edit.blade.php
index b0e00c931..a77bc8b31 100644
--- a/packages/Webkul/Admin/src/Resources/views/products/edit.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/products/edit.blade.php
@@ -30,7 +30,7 @@
{!! view_render_event('admin.products.edit.create_button.before', ['product' => $product]) !!}
-
+
-{!! view_render_event('admin.products.view.attributes.before', ['product' => $product]) !!}
\ No newline at end of file
+{!! view_render_event('admin.products.view.attributes.before', ['product' => $product]) !!}
diff --git a/packages/Webkul/Attribute/src/Traits/CustomAttribute.php b/packages/Webkul/Attribute/src/Traits/CustomAttribute.php
index acb3830dd..7d862ec9e 100644
--- a/packages/Webkul/Attribute/src/Traits/CustomAttribute.php
+++ b/packages/Webkul/Attribute/src/Traits/CustomAttribute.php
@@ -56,6 +56,13 @@ public function getAttribute($key)
}
}
+ // check key === 'price' and return the price attribute value
+ if (isset($this->id) && $key === 'price') {
+ $attribute = app(AttributeRepository::class)->getAttributeByCode($key);
+
+ return $this->getCustomAttributeValue($attribute);
+ }
+
return parent::getAttribute($key);
}
@@ -112,7 +119,15 @@ public function getCustomAttributeValue($attribute)
$attributeValue = $this->attribute_values->where('attribute_id', $attribute->id)->first();
- return $attributeValue[self::$attributeTypeFields[$attribute->type]] ?? null;
+ $value = $attributeValue[self::$attributeTypeFields[$attribute->type]] ?? null;
+
+ // Custom handling for price attribute
+ if ($attribute->code === 'price') {
+ // Format price, e.g., add currency symbol and format decimal places
+ $value = round($value, 2);
+ }
+
+ return $value;
}
/**
diff --git a/packages/Webkul/Category/package.json b/packages/Webkul/Category/package.json
new file mode 100644
index 000000000..5f0b6e27f
--- /dev/null
+++ b/packages/Webkul/Category/package.json
@@ -0,0 +1,26 @@
+{
+ "private": true,
+ "scripts": {
+ "dev": "npm run development",
+ "development": "mix",
+ "watch": "mix watch",
+ "watch-poll": "mix watch -- --watch-options-poll=1000",
+ "hot": "mix watch --hot",
+ "prod": "npm run production",
+ "production": "mix --production"
+ },
+ "devDependencies": {
+ "cross-env": "^7.0.3",
+ "laravel-mix": "^6.0.6",
+ "laravel-mix-merge-manifest": "^2.0.0",
+ "lodash": "^4.17.19",
+ "postcss": "^8.1.14",
+ "sass": "^1.32.8",
+ "sass-loader": "^11.0.1",
+ "vue": "^2.6.12",
+ "vue-loader": "^15.9.6",
+ "vue-template-compiler": "^2.6.12"
+ },
+ "dependencies": {
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Category/publishable/assets/css/admin.css b/packages/Webkul/Category/publishable/assets/css/admin.css
new file mode 100644
index 000000000..1a17a0493
--- /dev/null
+++ b/packages/Webkul/Category/publishable/assets/css/admin.css
@@ -0,0 +1 @@
+.temp-icon{width:48px;height:48px;display:inline-block;background-size:cover;background-image:url(../images/Icon-Temp.svg)}.active.temp-icon,.active .temp-icon{background-image:url(../images/Icon-Temp-Active.svg)}
\ No newline at end of file
diff --git a/packages/Webkul/Category/publishable/assets/images/Icon-Temp-Active.svg b/packages/Webkul/Category/publishable/assets/images/Icon-Temp-Active.svg
new file mode 100644
index 000000000..d4c61687b
--- /dev/null
+++ b/packages/Webkul/Category/publishable/assets/images/Icon-Temp-Active.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/packages/Webkul/Category/publishable/assets/images/Icon-Temp.svg b/packages/Webkul/Category/publishable/assets/images/Icon-Temp.svg
new file mode 100644
index 000000000..7dba04b31
--- /dev/null
+++ b/packages/Webkul/Category/publishable/assets/images/Icon-Temp.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/packages/Webkul/Category/publishable/assets/js/app.js b/packages/Webkul/Category/publishable/assets/js/app.js
new file mode 100644
index 000000000..9fa3a9151
--- /dev/null
+++ b/packages/Webkul/Category/publishable/assets/js/app.js
@@ -0,0 +1 @@
+!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=0)}({0:function(e,t,n){n("uPOf"),n("y62a"),n("jTz4"),e.exports=n("WyvX")},WyvX:function(e,t){},jTz4:function(e,t){},uPOf:function(e,t){},y62a:function(e,t){}});
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Config/acl.php b/packages/Webkul/Category/src/Config/acl.php
new file mode 100644
index 000000000..a21977e04
--- /dev/null
+++ b/packages/Webkul/Category/src/Config/acl.php
@@ -0,0 +1,10 @@
+ 'category',
+ 'name' => 'Category',
+ 'route' => 'admin.category.index',
+ 'sort' => 2
+ ]
+];
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Config/menu.php b/packages/Webkul/Category/src/Config/menu.php
new file mode 100644
index 000000000..5ae7aed77
--- /dev/null
+++ b/packages/Webkul/Category/src/Config/menu.php
@@ -0,0 +1,11 @@
+ 'category',
+ 'name' => 'Category',
+ 'route' => 'admin.category.index',
+ 'sort' => 2,
+ 'icon-class' => 'temp-icon',
+ ]
+];
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Http/Controllers/CategoryController.php b/packages/Webkul/Category/src/Http/Controllers/CategoryController.php
new file mode 100644
index 000000000..f45e0cad4
--- /dev/null
+++ b/packages/Webkul/Category/src/Http/Controllers/CategoryController.php
@@ -0,0 +1,76 @@
+ 'admin/category',
+ 'middleware' => ['web', 'user']
+ ], function () {
+
+ Route::get('', 'Webkul\Category\Http\Controllers\CategoryController@index')->name('admin.category.index');
+
+});
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Providers/CategoryServiceProvider.php b/packages/Webkul/Category/src/Providers/CategoryServiceProvider.php
new file mode 100644
index 000000000..e7b6a3a3c
--- /dev/null
+++ b/packages/Webkul/Category/src/Providers/CategoryServiceProvider.php
@@ -0,0 +1,59 @@
+loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
+
+ $this->loadRoutesFrom(__DIR__ . '/../Http/routes.php');
+
+ $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'category');
+
+ $this->publishes([
+ __DIR__ . '/../../publishable/assets' => public_path('category/assets'),
+ ], 'public');
+
+ $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'category');
+
+ Event::listen('admin.layout.head', function($viewRenderEventManager) {
+ $viewRenderEventManager->addTemplate('category::layouts.style');
+ });
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ $this->registerConfig();
+ }
+
+ /**
+ * Register package config.
+ *
+ * @return void
+ */
+ protected function registerConfig()
+ {
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/menu.php', 'menu.admin'
+ );
+
+ $this->mergeConfigFrom(
+ dirname(__DIR__) . '/Config/acl.php', 'acl'
+ );
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Providers/ModuleServiceProvider.php b/packages/Webkul/Category/src/Providers/ModuleServiceProvider.php
new file mode 100644
index 000000000..c5008463d
--- /dev/null
+++ b/packages/Webkul/Category/src/Providers/ModuleServiceProvider.php
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Resources/assets/images/Icon-Temp.svg b/packages/Webkul/Category/src/Resources/assets/images/Icon-Temp.svg
new file mode 100644
index 000000000..7dba04b31
--- /dev/null
+++ b/packages/Webkul/Category/src/Resources/assets/images/Icon-Temp.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Resources/assets/js/app.js b/packages/Webkul/Category/src/Resources/assets/js/app.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/Webkul/Category/src/Resources/assets/sass/admin.scss b/packages/Webkul/Category/src/Resources/assets/sass/admin.scss
new file mode 100644
index 000000000..f9cde7eaf
--- /dev/null
+++ b/packages/Webkul/Category/src/Resources/assets/sass/admin.scss
@@ -0,0 +1,17 @@
+.temp-icon {
+ width: 48px;
+ height: 48px;
+ display: inline-block;
+ background-size: cover;
+ background-image: url("../images/Icon-Temp.svg");
+}
+
+.active {
+ .temp-icon {
+ background-image: url("../images/Icon-Temp-Active.svg");
+ }
+
+ &.temp-icon {
+ background-image: url("../images/Icon-Temp-Active.svg");
+ }
+}
diff --git a/packages/Webkul/Category/src/Resources/views/index.blade.php b/packages/Webkul/Category/src/Resources/views/index.blade.php
new file mode 100644
index 000000000..fb491843a
--- /dev/null
+++ b/packages/Webkul/Category/src/Resources/views/index.blade.php
@@ -0,0 +1,23 @@
+@extends('admin::layouts.master')
+
+@section('page_title')
+ Package Category
+@stop
+
+@section('content-wrapper')
+
+
+
+@stop
\ No newline at end of file
diff --git a/packages/Webkul/Category/src/Resources/views/layouts/style.blade.php b/packages/Webkul/Category/src/Resources/views/layouts/style.blade.php
new file mode 100644
index 000000000..c1a24aa83
--- /dev/null
+++ b/packages/Webkul/Category/src/Resources/views/layouts/style.blade.php
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/Webkul/Category/webpack.mix.js b/packages/Webkul/Category/webpack.mix.js
new file mode 100644
index 000000000..db90f4262
--- /dev/null
+++ b/packages/Webkul/Category/webpack.mix.js
@@ -0,0 +1,39 @@
+const mix = require("laravel-mix");
+
+if (mix == 'undefined') {
+ const { mix } = require("laravel-mix");
+}
+
+require("laravel-mix-merge-manifest");
+
+if (mix.inProduction()) {
+ var publicPath = 'publishable/assets';
+} else {
+ var publicPath = "../../../public/vendor/category/assets";
+}
+
+mix.setPublicPath(publicPath).mergeManifest();
+mix.disableNotifications();
+
+mix.js(__dirname + "/src/Resources/assets/js/app.js", "js/admin.js")
+ .copy(__dirname + "/src/Resources/assets/images", publicPath + "/images")
+ .sass(__dirname + "/src/Resources/assets/sass/app.scss", "css/admin.css")
+ .options({
+ processCssUrls: false
+ }).vue();
+
+mix.webpackConfig({
+ resolve: {
+ alias: {
+ 'vue$': 'vue/dist/vue.runtime.js'
+ }
+ }
+});
+
+if (! mix.inProduction()) {
+ mix.sourceMaps();
+}
+
+if (mix.inProduction()) {
+ mix.version();
+}
\ No newline at end of file
diff --git a/packages/Webkul/Core/src/Core.php b/packages/Webkul/Core/src/Core.php
index e66d5e0b8..b0761c15b 100644
--- a/packages/Webkul/Core/src/Core.php
+++ b/packages/Webkul/Core/src/Core.php
@@ -68,6 +68,25 @@ public function locales(): array
return $options;
}
+ /**
+ * Retrieve all currencies.
+ */
+ public function retrieveCurrencies(): array
+ {
+ $options = [];
+
+ foreach (config('app.available_currencies') as $key => $title) {
+ $formattedTitle = ucwords(str_replace('-', ' ', $title));
+
+ $options[] = [
+ 'title' => $formattedTitle,
+ 'value' => $key,
+ ];
+ }
+
+ return $options;
+ }
+
/**
* Retrieve all countries.
*
@@ -197,10 +216,10 @@ public function xWeekRange($date, $day)
/**
* Return currency symbol from currency code.
*
- * @param float $price
+ * @param $code
* @return string
*/
- public function currencySymbol($code)
+ public function currencySymbol($code): string
{
$formatter = new \NumberFormatter(app()->getLocale().'@currency='.$code, \NumberFormatter::CURRENCY);
@@ -211,18 +230,16 @@ public function currencySymbol($code)
* Format price with base currency symbol. This method also give ability to encode
* the base currency symbol and its optional.
*
- * @param float $price
+ * @param float $price
* @return string
*/
- public function formatBasePrice($price)
+ public function formatBasePrice(float $price)
{
- if (is_null($price)) {
- $price = 0;
- }
-
$formatter = new \NumberFormatter(app()->getLocale(), \NumberFormatter::CURRENCY);
- return $formatter->formatCurrency($price, config('app.currency'));
+ return $formatter->formatCurrency($price,
+ system_config()->getConfigData('general.general.currency-settings.currency')
+ ?? config('app.currency'));
}
/**
diff --git a/tests/Feature/ConfigurationTest.php b/tests/Feature/ConfigurationTest.php
new file mode 100644
index 000000000..fbf901bd0
--- /dev/null
+++ b/tests/Feature/ConfigurationTest.php
@@ -0,0 +1,31 @@
+actingAs($admin)
+ ->get(route('admin.configuration.index'))
+ ->assertOK();
+});
+
+it('Test display price configuration page', function () {
+ $admin = getDefaultAdmin();
+
+ test()->actingAs($admin)
+ ->get(route('admin.configuration.index', ['slug' => 'price']))
+ ->assertOK();
+});
+
+it('Test format currency', function () {
+ // example of price value
+ $price = 1000.00;
+
+ // output: ₫1,000
+ test()->assertEquals('₫1,000', core()->formatBasePrice($price));
+
+ // same currency, but different value
+ // Example: 1000000.00
+ // Thai Baht: ฿1,000,000
+ // Vietnamese Dong: ₫1,000,000
+ // US Dollar: $1,000,000
+});